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 }