llgroupnotify.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llgroupnotify.h"
00035 
00036 #include "llfocusmgr.h"
00037 
00038 #include "llbutton.h"
00039 #include "lliconctrl.h"
00040 #include "llfloaterchat.h"      // for add_chat_history()
00041 #include "llnotify.h"
00042 #include "lltextbox.h"
00043 #include "llviewertexteditor.h"
00044 #include "lluiconstants.h"
00045 #include "llui.h"
00046 #include "llviewercontrol.h"
00047 #include "llfloatergroupinfo.h"
00048 #include "llinventoryview.h"
00049 #include "llinventory.h"
00050 
00051 #include "llglheaders.h"
00052 #include "llagent.h"
00053 // Globals
00054 //LLView* gGroupNotifyBoxView = NULL;
00055 
00056 const F32 ANIMATION_TIME = 0.333f;
00057 
00058 S32 LLGroupNotifyBox::sGroupNotifyBoxCount = 0;
00059 
00060 //---------------------------------------------------------------------------
00061 // LLGroupNotifyBox
00062 //---------------------------------------------------------------------------
00063 
00064 char* g_formatted_time(const time_t& the_time, char* buffer)
00065 {
00066         time_t t = the_time;
00067         if (!t) time(&t);
00068         LLString::copy(buffer, ctime(&t), 30);
00069         buffer[24] = '\0';
00070         return buffer;
00071 }
00072 
00073 // static
00074 LLGroupNotifyBox* LLGroupNotifyBox::show(const char* subject,
00075                                                          const char* message,
00076                                                          const char* from_name,
00077                                                          const LLUUID& group_id,
00078                                                          const U32& t,
00079                                                          const bool& has_inventory,
00080                                                          const char* inventory_name,
00081                                                          LLOfferInfo* inventory_offer)
00082 {
00083         // Get the group data
00084         LLGroupData group_data;
00085         if (!gAgent.getGroupData(group_id,group_data))
00086         {
00087                 llwarns << "Group notice for unkown group: " << group_id << llendl;
00088                 return NULL;
00089         }
00090 
00091         LLGroupNotifyBox* self;
00092         self = new LLGroupNotifyBox(subject, message, from_name, group_id, group_data.mInsigniaID, group_data.mName.c_str(),t,has_inventory,inventory_name,inventory_offer);
00093         gNotifyBoxView->addChild(self);
00094 
00095         // TODO: play a sound
00096         return self;
00097 }
00098 
00099 bool is_openable(LLAssetType::EType type)
00100 {
00101         switch(type)
00102         {
00103         case LLAssetType::AT_LANDMARK:
00104         case LLAssetType::AT_NOTECARD:
00105         case LLAssetType::AT_IMAGE_JPEG:
00106         case LLAssetType::AT_IMAGE_TGA:
00107         case LLAssetType::AT_TEXTURE:
00108         case LLAssetType::AT_TEXTURE_TGA:
00109                 return true;
00110         default:
00111                 return false;
00112         }
00113 }
00114 
00115 LLGroupNotifyBox::LLGroupNotifyBox(const char* subject,
00116                                                          const char* message,
00117                                                          const char* from_name,
00118                                                          const LLUUID& group_id,
00119                                                          const LLUUID& group_insignia,
00120                                                          const char* group_name,
00121                                                          const U32& t,
00122                                                          const bool& has_inventory,
00123                                                          const char* inventory_name,
00124                                                          LLOfferInfo* inventory_offer)
00125 :       LLPanel("groupnotify", LLGroupNotifyBox::getGroupNotifyRect(), BORDER_YES),
00126         mAnimating(TRUE),
00127         mTimer(),
00128         mGroupID(group_id),
00129         mHasInventory(has_inventory),
00130         mInventoryOffer(inventory_offer)
00131 {
00132         setFocusRoot(TRUE);
00133 
00134         time_t timestamp = (time_t)t;
00135 
00136         char time_buf[30];              /*Flawfinder: ignore*/  
00137         g_formatted_time(timestamp, time_buf);
00138 
00139         setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
00140         setBackgroundVisible(TRUE);
00141         setBackgroundOpaque(TRUE);
00142 
00143         // TODO: add a color for group notices
00144         setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") );
00145 
00146         LLIconCtrl* icon;
00147         LLTextEditor* text;
00148 
00149         const S32 VPAD = 2;
00150         const S32 TOP = getRect().getHeight() - 32; // Get past the top menu bar
00151         const S32 BOTTOM_PAD = VPAD * 2;
00152         const S32 BTN_TOP = BOTTOM_PAD + BTN_HEIGHT + VPAD;
00153         const S32 RIGHT = getRect().getWidth() - HPAD - HPAD;
00154         const S32 LINE_HEIGHT = 16;
00155 
00156         const S32 LABEL_WIDTH = 64;
00157         const S32 ICON_WIDTH = 64;
00158 
00159         S32 y = TOP;
00160         S32 x = HPAD + HPAD;
00161 
00162         class NoticeText : public LLTextBox
00163         {
00164         public:
00165                 NoticeText(const LLString& name, const LLRect& rect, const LLString& text = LLString::null, const LLFontGL* font = NULL) 
00166                         : LLTextBox(name, rect, text, font)
00167                 {
00168                         setHAlign(LLFontGL::RIGHT);
00169                         setFontStyle(LLFontGL::DROP_SHADOW_SOFT);
00170                         setBorderVisible(FALSE);
00171                         setColor( gColors.getColor("GroupNotifyTextColor") );
00172                         setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") );
00173                 }
00174         };
00175 
00176 
00177         // Title
00178         addChild(new NoticeText("title",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),"Group Notice",LLFontGL::sSansSerifHuge));
00179 
00180         y -= llfloor(1.5f*LINE_HEIGHT);
00181 
00182         x += HPAD + HPAD + ICON_WIDTH;
00183 
00184         std::stringstream from;
00185         from << "Sent by " << from_name << ", " << group_name;
00186 
00187         addChild(new NoticeText("group",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),from.str().c_str(),LLFontGL::sSansSerif));
00188         
00189         y -= (LINE_HEIGHT + VPAD);
00190         x = HPAD + HPAD;
00191 
00192         // TODO: change this to be the group icon.
00193         if (!group_insignia.isNull())
00194         {
00195                 icon = new LLIconCtrl("icon",
00196                                                           LLRect(x, y, x+ICON_WIDTH, y-ICON_WIDTH),
00197                                                           group_insignia);
00198         }
00199         else
00200         {
00201                 icon = new LLIconCtrl("icon",
00202                                                           LLRect(x, y, x+ICON_WIDTH, y-ICON_WIDTH),
00203                                                           "notify_box_icon.tga");
00204         }
00205 
00206         icon->setMouseOpaque(FALSE);
00207         addChild(icon);
00208 
00209         x += HPAD + HPAD + ICON_WIDTH;
00210         // If we have inventory with this message, leave room for the name.
00211         S32 box_bottom = BTN_TOP + (mHasInventory ? (LINE_HEIGHT + 2*VPAD) : 0);
00212 
00213         text = new LLViewerTextEditor("box",
00214                 LLRect(x, y, RIGHT, box_bottom),
00215                 DB_GROUP_NOTICE_MSG_STR_LEN,
00216                 "",
00217                 LLFontGL::sSansSerif,
00218                 FALSE);
00219 
00220         static const LLStyleSP headerstyle(new LLStyle(true,LLColor4::black,"SansSerifBig"));
00221         static const LLStyleSP datestyle(new LLStyle(true,LLColor4::black,"serif"));
00222 
00223         text->appendStyledText(subject,false,false,&headerstyle);
00224         text->appendStyledText(time_buf,false,false,&datestyle);
00225         // Sadly, our LLTextEditor can't handle both styled and unstyled text
00226         // at the same time.  Hence this space must be styled. JC
00227         text->appendColoredText(" ",false,false,LLColor4::grey4);
00228         text->appendColoredText(message,false,false,LLColor4::grey4);
00229 
00230         LLColor4 semi_transparent(1.0f,1.0f,1.0f,0.8f);
00231         text->setCursor(0,0);
00232         text->setEnabled(FALSE);
00233         text->setWordWrap(TRUE);
00234         text->setTabStop(FALSE);
00235         text->setTabsToNextField(TRUE);
00236         text->setMouseOpaque(TRUE);
00237         text->setBorderVisible(TRUE);
00238         text->setTakesNonScrollClicks(TRUE);
00239         text->setHideScrollbarForShortDocs(TRUE);
00240         text->setReadOnlyBgColor ( semi_transparent );
00241         text->setWriteableBgColor ( semi_transparent );
00242         
00243         addChild(text);
00244 
00245         y = box_bottom - VPAD;
00246 
00247         if (mHasInventory)
00248         {
00249                         addChild(new NoticeText("subjecttitle",LLRect(x,y,x + LABEL_WIDTH,y - LINE_HEIGHT),"Attached: ",LLFontGL::sSansSerif));
00250 
00251                         LLUIImagePtr item_icon = get_item_icon(mInventoryOffer->mType,
00252                                                                                                         LLInventoryType::IT_TEXTURE,
00253                                                                                                         0, FALSE);
00254 
00255 
00256                         x += LABEL_WIDTH + HPAD;
00257 
00258                         std::stringstream ss;
00259                         ss << "        " << inventory_name;
00260                         LLTextBox *line = new LLTextBox("object_name",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),ss.str().c_str(),LLFontGL::sSansSerif);
00261                         line->setEnabled(FALSE);
00262                         line->setBorderVisible(TRUE);
00263                         line->setDisabledColor(LLColor4::blue4);
00264                         line->setFontStyle(LLFontGL::NORMAL);
00265                         line->setBackgroundVisible(true);
00266                         line->setBackgroundColor( semi_transparent );
00267                         addChild(line);
00268 
00269                         icon = new LLIconCtrl("icon",
00270                                                                         LLRect(x, y, x+16, y-16),
00271                                                                         item_icon->getName());
00272                         icon->setMouseOpaque(FALSE);
00273                         addChild(icon);
00274         }
00275 
00276         LLButton* btn;
00277         btn = new LLButton("next",
00278                                 LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD),
00279                                 "notify_next.png",
00280                                 "notify_next.png",
00281                                 "",
00282                                 onClickNext,
00283                                 this,
00284                                 LLFontGL::sSansSerif);
00285         btn->setToolTip(LLString("Next")); // *TODO: Translate
00286         btn->setScaleImage(TRUE);
00287         addChild(btn);
00288         mNextBtn = btn;
00289 
00290         S32 btn_width = 80;
00291         S32 wide_btn_width = 120;
00292         LLRect btn_rect;
00293         x = 3 * HPAD;
00294 
00295         btn_rect.setOriginAndSize(x,
00296                                                                 BOTTOM_PAD,
00297                                                                 btn_width,
00298                                                                 BTN_HEIGHT);
00299 
00300         btn = new LLButton("OK", btn_rect, "", onClickOk, this);
00301         addChild(btn, -1);
00302         setDefaultBtn(btn);
00303 
00304         x += btn_width + HPAD;
00305 
00306         
00307         btn_rect.setOriginAndSize(x,
00308                                                                 BOTTOM_PAD,
00309                                                                 wide_btn_width,
00310                                                                 BTN_HEIGHT);
00311 
00312         btn = new LLButton("Group Notices", btn_rect, "", onClickGroupInfo, this);
00313         btn->setToolTip(LLString("View past notices or opt-out of receiving these messages here.")); // TODO: Translate
00314         addChild(btn, -1);
00315 
00316         if (mHasInventory && mInventoryOffer)
00317         {
00318                 x += wide_btn_width + HPAD;
00319 
00320                 btn_rect.setOriginAndSize(x,
00321                                                                         BOTTOM_PAD,
00322                                                                         wide_btn_width,
00323                                                                         BTN_HEIGHT);
00324 
00325                 LLString btn_lbl("");
00326                 if(is_openable(mInventoryOffer->mType))
00327                 {
00328                         btn_lbl = "Open Attachment";
00329                 }
00330                 else
00331                 {
00332                         btn_lbl = "Save Attachment";
00333                 }
00334                 mSaveInventoryBtn = new LLButton(btn_lbl, btn_rect, "", onClickSaveInventory, this);
00335                 mSaveInventoryBtn->setVisible(mHasInventory);
00336                 addChild(mSaveInventoryBtn);
00337         }
00338 
00339         sGroupNotifyBoxCount++;
00340 
00341         // If this is the only notify box, don't show the next button
00342         if (sGroupNotifyBoxCount == 1)
00343         {
00344                 mNextBtn->setVisible(FALSE);
00345         }
00346 }
00347 
00348 
00349 // virtual
00350 LLGroupNotifyBox::~LLGroupNotifyBox()
00351 {
00352         sGroupNotifyBoxCount--;
00353 }
00354 
00355 // virtual
00356 BOOL LLGroupNotifyBox::handleRightMouseDown(S32 x, S32 y, MASK mask)
00357 {
00358         moveToBack();
00359         return TRUE;
00360 }
00361 
00362 
00363 // virtual
00364 void LLGroupNotifyBox::draw()
00365 {
00366         F32 display_time = mTimer.getElapsedTimeF32();
00367 
00368         if (mAnimating && display_time < ANIMATION_TIME)
00369         {
00370                 glMatrixMode(GL_MODELVIEW);
00371                 glPushMatrix();
00372 
00373                 S32 height = getRect().getHeight();
00374                 F32 fraction = display_time / ANIMATION_TIME;
00375                 F32 voffset = (1.f - fraction) * height;
00376 
00377                 glTranslatef(0.f, voffset, 0.f);
00378 
00379                 LLPanel::draw();
00380 
00381                 glPopMatrix();
00382         }
00383         else
00384         {
00385                 mAnimating = FALSE;
00386                 LLPanel::draw();
00387         }
00388 }
00389 
00390 
00391 void LLGroupNotifyBox::close()
00392 {
00393         // The group notice dialog may be an inventory offer.
00394         // If it has an inventory save button and that button is still enabled
00395         // Then we need to send the inventory declined message
00396         if(mHasInventory)
00397         {
00398                 inventory_offer_callback(IOR_DECLINE , mInventoryOffer); 
00399         }
00400         gNotifyBoxView->removeChild(this);
00401 
00402         die();
00403 }
00404 
00405 
00406 void LLGroupNotifyBox::moveToBack()
00407 {
00408         // Move this dialog to the back.
00409         gNotifyBoxView->removeChild(this);
00410         gNotifyBoxView->addChildAtEnd(this);
00411         mNextBtn->setVisible(FALSE);
00412 
00413         // And enable the next button on the frontmost one, if there is one
00414         if (sGroupNotifyBoxCount > 1)
00415         {
00416                 LLView* view = gNotifyBoxView->getFirstChild();
00417                 LLGroupNotifyBox* front = (LLGroupNotifyBox*)view;
00418                 front->mNextBtn->setVisible(TRUE);
00419         }
00420 }
00421 
00422 
00423 // static
00424 LLRect LLGroupNotifyBox::getGroupNotifyRect()
00425 {
00426         S32 notify_height = gSavedSettings.getS32("GroupNotifyBoxHeight");
00427         const S32 NOTIFY_WIDTH = gSavedSettings.getS32("GroupNotifyBoxWidth");
00428 
00429         const S32 TOP = gNotifyBoxView->getRect().getHeight();
00430         const S32 RIGHT = gNotifyBoxView->getRect().getWidth();
00431         const S32 LEFT = RIGHT - NOTIFY_WIDTH;
00432 
00433         return LLRect(LEFT, TOP, RIGHT, TOP-notify_height);
00434 }
00435 
00436 
00437 // static
00438 void LLGroupNotifyBox::onClickOk(void* data)
00439 {
00440         LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00441         if (self) self->close();
00442 }
00443 
00444 void LLGroupNotifyBox::onClickGroupInfo(void* data)
00445 {
00446         LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00447 
00448         if (self)
00449         {
00450                 LLFloaterGroupInfo::showFromUUID(self->mGroupID, "notices_tab");
00451         }
00452 
00453         //Leave notice open until explicitly closed
00454 }
00455 
00456 void LLGroupNotifyBox::onClickSaveInventory(void* data)
00457 {
00458         LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00459 
00460         inventory_offer_callback( IOR_ACCEPT , self->mInventoryOffer); 
00461 
00462         // inventory_offer_callback will delete the offer, so make sure we aren't still pointing to it.
00463         self->mInventoryOffer = NULL;
00464         // Each item can only be received once, so disable the button.
00465         self->mSaveInventoryBtn->setEnabled(FALSE);
00466 }
00467 
00468 // static
00469 void LLGroupNotifyBox::onClickNext(void* data)
00470 {
00471         LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00472         self->moveToBack();
00473 }

Generated on Fri May 16 08:33:38 2008 for SecondLife by  doxygen 1.5.5