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 "llvieweruictrlfactory.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 #include "viewer.h"
00064
00065 #include "llassetuploadresponders.h"
00066
00070
00071 LLLinkedList<LLFloaterPostcard> 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.addData(this);
00102 }
00103
00104
00105 LLFloaterPostcard::~LLFloaterPostcard()
00106 {
00107 sInstances.removeData(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 childSetAction("publish_help_btn", onClickPublishHelp, this);
00118
00119 if (gAgent.isTeen())
00120 {
00121
00122 childDisable("allow_publish_check");
00123 childHide("allow_publish_check");
00124 childDisable("publish_help_btn");
00125 childHide("publish_help_btn");
00126 childDisable("mature_check");
00127 childHide("mature_check");
00128 }
00129
00130 LLString name_string;
00131 gAgent.buildFullname(name_string);
00132
00133 childSetValue("name_form", LLSD(name_string));
00134
00135 LLTextEditor *MsgField = LLUICtrlFactory::getTextEditorByName(this, "msg_form");
00136 if (MsgField)
00137 {
00138 MsgField->setWordWrap(TRUE);
00139
00140
00141 MsgField->setFocusChangedCallback(onMsgFormFocusRecieved);
00142 MsgField->setCallbackUserData(this);
00143 }
00144
00145 childSetFocus("to_form", TRUE);
00146
00147 return TRUE;
00148 }
00149
00150
00151
00152
00153 LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global)
00154 {
00155
00156
00157 LLFloaterPostcard *instance = new LLFloaterPostcard(jpeg, img, image_scale, pos_taken_global);
00158
00159 gUICtrlFactory->buildFloater(instance, "floater_postcard.xml");
00160
00161 S32 left, top;
00162 gFloaterView->getNewFloaterPosition(&left, &top);
00163 instance->setOrigin(left, top - instance->getRect().getHeight());
00164
00165 instance->open();
00166
00167 return instance;
00168 }
00169
00170 void LLFloaterPostcard::draw()
00171 {
00172 LLGLSUIDefault gls_ui;
00173 LLFloater::draw();
00174
00175 if(getVisible() && !mMinimized && mViewerImage.notNull() && mJPEGImage.notNull())
00176 {
00177 LLRect rect(mRect);
00178
00179
00180 rect.translate(-rect.mLeft, -rect.mBottom);
00181 rect.mLeft += 280;
00182 rect.mRight -= 10;
00183 rect.mTop -= 20;
00184 rect.mBottom = rect.mTop - 130;
00185
00186
00187 F32 ratio = (F32)mJPEGImage->getWidth() / (F32)mJPEGImage->getHeight();
00188 if ((F32)rect.getWidth() / (F32)rect.getHeight() >= ratio)
00189 {
00190 rect.mRight = (S32)((F32)rect.mLeft + ((F32)rect.getHeight() * ratio));
00191 }
00192 else
00193 {
00194 rect.mBottom = (S32)((F32)rect.mTop - ((F32)rect.getWidth() / ratio));
00195 }
00196 {
00197 LLGLSNoTexture gls_no_texture;
00198 gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
00199 rect.stretch(-1);
00200 }
00201 {
00202
00203 glMatrixMode(GL_TEXTURE);
00204 glPushMatrix();
00205 {
00206 glScalef(mImageScale.mV[VX], mImageScale.mV[VY], 1.f);
00207 glMatrixMode(GL_MODELVIEW);
00208 gl_draw_scaled_image(rect.mLeft,
00209 rect.mBottom,
00210 rect.getWidth(),
00211 rect.getHeight(),
00212 mViewerImage,
00213 LLColor4::white);
00214 }
00215 glMatrixMode(GL_TEXTURE);
00216 glPopMatrix();
00217 glMatrixMode(GL_MODELVIEW);
00218 }
00219 }
00220 }
00221
00222
00223 void LLFloaterPostcard::onClickCancel(void* data)
00224 {
00225 if (data)
00226 {
00227 LLFloaterPostcard *self = (LLFloaterPostcard *)data;
00228
00229 self->close(false);
00230 }
00231 }
00232
00233 class LLSendPostcardResponder : public LLAssetUploadResponder
00234 {
00235 public:
00236 LLSendPostcardResponder(const LLSD &post_data,
00237 const LLUUID& vfile_id,
00238 LLAssetType::EType asset_type):
00239 LLAssetUploadResponder(post_data, vfile_id, asset_type)
00240 {
00241 }
00242
00243 void uploadComplete(const LLSD& content)
00244 {
00245
00246 LLUploadDialog::modalUploadFinished();
00247 }
00248 };
00249
00250
00251 void LLFloaterPostcard::onClickSend(void* data)
00252 {
00253 if (data)
00254 {
00255 LLFloaterPostcard *self = (LLFloaterPostcard *)data;
00256
00257 LLString from(self->childGetValue("from_form").asString().c_str());
00258 LLString to(self->childGetValue("to_form").asString().c_str());
00259
00260 if (to.empty() || to.find('@') == std::string::npos)
00261 {
00262 gViewerWindow->alertXml("PromptRecipientEmail");
00263 return;
00264 }
00265
00266 if (from.empty() || from.find('@') == std::string::npos)
00267 {
00268 gViewerWindow->alertXml("PromptSelfEmail");
00269 return;
00270 }
00271
00272 LLString subject(self->childGetValue("subject_form").asString().c_str());
00273 if(subject.empty() || !self->mHasFirstMsgFocus)
00274 {
00275 gViewerWindow->alertXml("PromptMissingSubjMsg", missingSubjMsgAlertCallback, self);
00276 return;
00277 }
00278
00279 if (self->mJPEGImage.notNull())
00280 {
00281 self->sendPostcard();
00282 }
00283 else
00284 {
00285 gViewerWindow->alertXml("ErrorProcessingSnapshot");
00286 }
00287 }
00288 }
00289
00290
00291 void LLFloaterPostcard::onClickPublishHelp(void* data)
00292 {
00293 gViewerWindow->alertXml("ClickPublishHelpPostcard");
00294 }
00295
00296
00297 void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, S32 result, LLExtStat ext_status)
00298 {
00299 LLFloaterPostcard *self = (LLFloaterPostcard *)user_data;
00300
00301 LLUploadDialog::modalUploadFinished();
00302
00303 if (result)
00304 {
00305 LLStringBase<char>::format_map_t args;
00306 args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result));
00307 gViewerWindow->alertXml("ErrorUploadingPostcard", args);
00308 }
00309 else
00310 {
00311
00312
00313
00314 LLMessageSystem* msg = gMessageSystem;
00315 msg->newMessage("SendPostcard");
00316 msg->nextBlock("AgentData");
00317 msg->addUUID("AgentID", gAgent.getID());
00318 msg->addUUID("SessionID", gAgent.getSessionID());
00319 msg->addUUID("AssetID", self->mAssetID);
00320 msg->addVector3d("PosGlobal", self->mPosTakenGlobal);
00321 msg->addString("To", self->childGetValue("to_form").asString());
00322 msg->addString("From", self->childGetValue("from_form").asString());
00323 msg->addString("Name", self->childGetValue("name_form").asString());
00324 msg->addString("Subject", self->childGetValue("subject_form").asString());
00325 msg->addString("Msg", self->childGetValue("msg_form").asString());
00326 msg->addBOOL("AllowPublish", self->childGetValue("allow_publish_check").asBoolean());
00327 msg->addBOOL("MaturePublish", self->childGetValue("mature_check").asBoolean());
00328 gAgent.sendReliableMessage();
00329 }
00330
00331 self->close();
00332 }
00333
00334
00335 void LLFloaterPostcard::updateUserInfo(const char *email)
00336 {
00337 LLFloaterPostcard *instance;
00338
00339 sInstances.resetList();
00340 while ((instance = sInstances.getNextData()))
00341 {
00342 const LLString& text = instance->childGetValue("from_form").asString();
00343 if (text.empty())
00344 {
00345
00346 instance->childSetValue("from_form", LLSD(email));
00347 }
00348 }
00349 }
00350
00351 void LLFloaterPostcard::onMsgFormFocusRecieved(LLUICtrl* receiver, void* data)
00352 {
00353 LLFloaterPostcard* self = (LLFloaterPostcard *)data;
00354 if(self)
00355 {
00356 LLTextEditor* msgForm = LLUICtrlFactory::getTextEditorByName(self, "msg_form");
00357 if(msgForm && msgForm == receiver && msgForm->hasFocus() && !(self->mHasFirstMsgFocus))
00358 {
00359 self->mHasFirstMsgFocus = true;
00360 msgForm->setText(LLString::null);
00361 }
00362 }
00363 }
00364
00365 void LLFloaterPostcard::missingSubjMsgAlertCallback(S32 option, void* data)
00366 {
00367 if(data)
00368 {
00369 LLFloaterPostcard* self = static_cast<LLFloaterPostcard*>(data);
00370 if(0 == option)
00371 {
00372
00373 if((self->childGetValue("subject_form").asString()).empty())
00374 {
00375
00376 self->childSetValue("subject_form", self->childGetText("default_subject"));
00377 }
00378
00379 if(!self->mHasFirstMsgFocus)
00380 {
00381
00382
00383 self->childSetValue("msg_form", self->childGetText("default_message"));
00384 }
00385
00386 self->sendPostcard();
00387 }
00388 }
00389 }
00390
00391 void LLFloaterPostcard::sendPostcard()
00392 {
00393 mTransactionID.generate();
00394 mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
00395 LLVFile::writeFile(mJPEGImage->getData(), mJPEGImage->getDataSize(), gVFS, mAssetID, LLAssetType::AT_IMAGE_JPEG);
00396
00397
00398 std::string url = gAgent.getRegion()->getCapability("SendPostcard");
00399 if(!url.empty())
00400 {
00401 llinfos << "Send Postcard via capability" << llendl;
00402 LLSD body = LLSD::emptyMap();
00403
00404 body["pos-global"] = mPosTakenGlobal.getValue();
00405 body["to"] = childGetValue("to_form").asString();
00406 body["from"] = childGetValue("from_form").asString();
00407 body["name"] = childGetValue("name_form").asString();
00408 body["subject"] = childGetValue("subject_form").asString();
00409 body["msg"] = childGetValue("msg_form").asString();
00410 body["allow-publish"] = childGetValue("allow_publish_check").asBoolean();
00411 body["mature-publish"] = childGetValue("mature_check").asBoolean();
00412 LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, mAssetID, LLAssetType::AT_IMAGE_JPEG));
00413 }
00414 else
00415 {
00416 gAssetStorage->storeAssetData(mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)this, FALSE);
00417 }
00418
00419 LLUploadDialog::modalUploadDialog("Uploading...\n\nPostcard");
00420
00421
00422
00423 setVisible(FALSE);
00424
00425
00426
00427
00428 LLFloater* dependee = getDependee();
00429 if (dependee)
00430 dependee->removeDependentFloater(this);
00431 }