00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llfloaterpostcard.h"
00035
00036 #include "llfontgl.h"
00037 #include "llsys.h"
00038 #include "llgl.h"
00039 #include "v3dmath.h"
00040 #include "lldir.h"
00041
00042 #include "llagent.h"
00043 #include "llui.h"
00044 #include "lllineeditor.h"
00045 #include "llviewertexteditor.h"
00046 #include "llbutton.h"
00047 #include "llviewercontrol.h"
00048 #include "llviewernetwork.h"
00049 #include "lluictrlfactory.h"
00050 #include "lluploaddialog.h"
00051 #include "llviewerstats.h"
00052 #include "llviewerwindow.h"
00053 #include "llstatusbar.h"
00054 #include "llviewerregion.h"
00055 #include "lleconomy.h"
00056
00057 #include "llgl.h"
00058 #include "llglheaders.h"
00059 #include "llimagejpeg.h"
00060 #include "llimagej2c.h"
00061 #include "llvfile.h"
00062 #include "llvfs.h"
00063
00064 #include "llassetuploadresponders.h"
00065
00069
00070
00071 LLFloaterPostcard::instance_list_t LLFloaterPostcard::sInstances;
00072
00076
00077 LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global)
00078 : LLFloater("Postcard Floater"),
00079 mJPEGImage(jpeg),
00080 mViewerImage(img),
00081 mImageScale(img_scale),
00082 mPosTakenGlobal(pos_taken_global),
00083 mHasFirstMsgFocus(false)
00084 {
00085 init();
00086 }
00087
00088 void LLFloaterPostcard::init()
00089 {
00090
00091 if(!gAgent.getID().isNull())
00092 {
00093
00094 gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest);
00095 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
00096 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00097 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00098 gAgent.sendReliableMessage();
00099 }
00100
00101 sInstances.insert(this);
00102 }
00103
00104
00105 LLFloaterPostcard::~LLFloaterPostcard()
00106 {
00107 sInstances.erase(this);
00108 mJPEGImage = NULL;
00109 }
00110
00111 BOOL LLFloaterPostcard::postBuild()
00112 {
00113 childSetAction("cancel_btn", onClickCancel, this);
00114 childSetAction("send_btn", onClickSend, this);
00115
00116 childDisable("from_form");
00117
00118 std::string name_string;
00119 gAgent.buildFullname(name_string);
00120 childSetValue("name_form", LLSD(name_string));
00121
00122 LLTextEditor* MsgField = getChild<LLTextEditor>("msg_form");
00123 if (MsgField)
00124 {
00125 MsgField->setWordWrap(TRUE);
00126
00127
00128 MsgField->setFocusChangedCallback(onMsgFormFocusRecieved, this);
00129 }
00130
00131 childSetFocus("to_form", TRUE);
00132
00133 return TRUE;
00134 }
00135
00136
00137
00138
00139 LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global)
00140 {
00141
00142
00143 LLFloaterPostcard *instance = new LLFloaterPostcard(jpeg, img, image_scale, pos_taken_global);
00144
00145 LLUICtrlFactory::getInstance()->buildFloater(instance, "floater_postcard.xml");
00146
00147 S32 left, top;
00148 gFloaterView->getNewFloaterPosition(&left, &top);
00149 instance->setOrigin(left, top - instance->getRect().getHeight());
00150
00151 instance->open();
00152
00153 return instance;
00154 }
00155
00156 void LLFloaterPostcard::draw()
00157 {
00158 LLGLSUIDefault gls_ui;
00159 LLFloater::draw();
00160
00161 if(!isMinimized() && mViewerImage.notNull() && mJPEGImage.notNull())
00162 {
00163 LLRect rect(getRect());
00164
00165
00166 rect.translate(-rect.mLeft, -rect.mBottom);
00167 rect.mLeft += 280;
00168 rect.mRight -= 10;
00169 rect.mTop -= 20;
00170 rect.mBottom = rect.mTop - 130;
00171
00172
00173 F32 ratio = (F32)mJPEGImage->getWidth() / (F32)mJPEGImage->getHeight();
00174 if ((F32)rect.getWidth() / (F32)rect.getHeight() >= ratio)
00175 {
00176 rect.mRight = (S32)((F32)rect.mLeft + ((F32)rect.getHeight() * ratio));
00177 }
00178 else
00179 {
00180 rect.mBottom = (S32)((F32)rect.mTop - ((F32)rect.getWidth() / ratio));
00181 }
00182 {
00183 LLGLSNoTexture gls_no_texture;
00184 gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
00185 rect.stretch(-1);
00186 }
00187 {
00188
00189 glMatrixMode(GL_TEXTURE);
00190 glPushMatrix();
00191 {
00192 glScalef(mImageScale.mV[VX], mImageScale.mV[VY], 1.f);
00193 glMatrixMode(GL_MODELVIEW);
00194 gl_draw_scaled_image(rect.mLeft,
00195 rect.mBottom,
00196 rect.getWidth(),
00197 rect.getHeight(),
00198 mViewerImage,
00199 LLColor4::white);
00200 }
00201 glMatrixMode(GL_TEXTURE);
00202 glPopMatrix();
00203 glMatrixMode(GL_MODELVIEW);
00204 }
00205 }
00206 }
00207
00208
00209 void LLFloaterPostcard::onClickCancel(void* data)
00210 {
00211 if (data)
00212 {
00213 LLFloaterPostcard *self = (LLFloaterPostcard *)data;
00214
00215 self->close(false);
00216 }
00217 }
00218
00219 class LLSendPostcardResponder : public LLAssetUploadResponder
00220 {
00221 public:
00222 LLSendPostcardResponder(const LLSD &post_data,
00223 const LLUUID& vfile_id,
00224 LLAssetType::EType asset_type):
00225 LLAssetUploadResponder(post_data, vfile_id, asset_type)
00226 {
00227 }
00228
00229 void uploadComplete(const LLSD& content)
00230 {
00231
00232 LLUploadDialog::modalUploadFinished();
00233 }
00234 };
00235
00236
00237 void LLFloaterPostcard::onClickSend(void* data)
00238 {
00239 if (data)
00240 {
00241 LLFloaterPostcard *self = (LLFloaterPostcard *)data;
00242
00243 std::string from(self->childGetValue("from_form").asString());
00244 std::string to(self->childGetValue("to_form").asString());
00245
00246 if (to.empty() || to.find('@') == std::string::npos)
00247 {
00248 gViewerWindow->alertXml("PromptRecipientEmail");
00249 return;
00250 }
00251
00252 if (from.empty() || from.find('@') == std::string::npos)
00253 {
00254 gViewerWindow->alertXml("PromptSelfEmail");
00255 return;
00256 }
00257
00258 std::string subject(self->childGetValue("subject_form").asString());
00259 if(subject.empty() || !self->mHasFirstMsgFocus)
00260 {
00261 gViewerWindow->alertXml("PromptMissingSubjMsg", missingSubjMsgAlertCallback, self);
00262 return;
00263 }
00264
00265 if (self->mJPEGImage.notNull())
00266 {
00267 self->sendPostcard();
00268 }
00269 else
00270 {
00271 gViewerWindow->alertXml("ErrorProcessingSnapshot");
00272 }
00273 }
00274 }
00275
00276
00277 void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, S32 result, LLExtStat ext_status)
00278 {
00279 LLFloaterPostcard *self = (LLFloaterPostcard *)user_data;
00280
00281 LLUploadDialog::modalUploadFinished();
00282
00283 if (result)
00284 {
00285 LLStringBase<char>::format_map_t args;
00286 args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result));
00287 gViewerWindow->alertXml("ErrorUploadingPostcard", args);
00288 }
00289 else
00290 {
00291
00292
00293
00294 LLMessageSystem* msg = gMessageSystem;
00295 msg->newMessage("SendPostcard");
00296 msg->nextBlock("AgentData");
00297 msg->addUUID("AgentID", gAgent.getID());
00298 msg->addUUID("SessionID", gAgent.getSessionID());
00299 msg->addUUID("AssetID", self->mAssetID);
00300 msg->addVector3d("PosGlobal", self->mPosTakenGlobal);
00301 msg->addString("To", self->childGetValue("to_form").asString());
00302 msg->addString("From", self->childGetValue("from_form").asString());
00303 msg->addString("Name", self->childGetValue("name_form").asString());
00304 msg->addString("Subject", self->childGetValue("subject_form").asString());
00305 msg->addString("Msg", self->childGetValue("msg_form").asString());
00306 msg->addBOOL("AllowPublish", FALSE);
00307 msg->addBOOL("MaturePublish", FALSE);
00308 gAgent.sendReliableMessage();
00309 }
00310
00311 self->close();
00312 }
00313
00314
00315 void LLFloaterPostcard::updateUserInfo(const char *email)
00316 {
00317 for (instance_list_t::iterator iter = sInstances.begin();
00318 iter != sInstances.end(); ++iter)
00319 {
00320 LLFloaterPostcard *instance = *iter;
00321 const LLString& text = instance->childGetValue("from_form").asString();
00322 if (text.empty())
00323 {
00324
00325 instance->childSetValue("from_form", LLSD(email));
00326 }
00327 }
00328 }
00329
00330 void LLFloaterPostcard::onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data)
00331 {
00332 LLFloaterPostcard* self = (LLFloaterPostcard *)data;
00333 if(self)
00334 {
00335 LLTextEditor* msgForm = self->getChild<LLTextEditor>("msg_form");
00336 if(msgForm && msgForm == receiver && msgForm->hasFocus() && !(self->mHasFirstMsgFocus))
00337 {
00338 self->mHasFirstMsgFocus = true;
00339 msgForm->setText(LLString::null);
00340 }
00341 }
00342 }
00343
00344 void LLFloaterPostcard::missingSubjMsgAlertCallback(S32 option, void* data)
00345 {
00346 if(data)
00347 {
00348 LLFloaterPostcard* self = static_cast<LLFloaterPostcard*>(data);
00349 if(0 == option)
00350 {
00351
00352 if((self->childGetValue("subject_form").asString()).empty())
00353 {
00354
00355 self->childSetValue("subject_form", self->getString("default_subject"));
00356 }
00357
00358 if(!self->mHasFirstMsgFocus)
00359 {
00360
00361
00362 self->childSetValue("msg_form", self->getString("default_message"));
00363 }
00364
00365 self->sendPostcard();
00366 }
00367 }
00368 }
00369
00370 void LLFloaterPostcard::sendPostcard()
00371 {
00372 mTransactionID.generate();
00373 mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
00374 LLVFile::writeFile(mJPEGImage->getData(), mJPEGImage->getDataSize(), gVFS, mAssetID, LLAssetType::AT_IMAGE_JPEG);
00375
00376
00377 std::string url = gAgent.getRegion()->getCapability("SendPostcard");
00378 if(!url.empty())
00379 {
00380 llinfos << "Send Postcard via capability" << llendl;
00381 LLSD body = LLSD::emptyMap();
00382
00383 body["pos-global"] = mPosTakenGlobal.getValue();
00384 body["to"] = childGetValue("to_form").asString();
00385 body["from"] = childGetValue("from_form").asString();
00386 body["name"] = childGetValue("name_form").asString();
00387 body["subject"] = childGetValue("subject_form").asString();
00388 body["msg"] = childGetValue("msg_form").asString();
00389 LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, mAssetID, LLAssetType::AT_IMAGE_JPEG));
00390 }
00391 else
00392 {
00393 gAssetStorage->storeAssetData(mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)this, FALSE);
00394 }
00395
00396 LLUploadDialog::modalUploadDialog("Uploading...\n\nPostcard");
00397
00398
00399
00400 setVisible(FALSE);
00401
00402
00403
00404
00405 LLFloater* dependee = getDependee();
00406 if (dependee)
00407 dependee->removeDependentFloater(this);
00408 }