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"
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
00054
00055
00056 const F32 ANIMATION_TIME = 0.333f;
00057
00058 S32 LLGroupNotifyBox::sGroupNotifyBoxCount = 0;
00059
00060
00061
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
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
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
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];
00137 g_formatted_time(timestamp, time_buf);
00138
00139 setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
00140 setBackgroundVisible(TRUE);
00141 setBackgroundOpaque(TRUE);
00142
00143
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;
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
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
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
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
00226
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"));
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."));
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
00342 if (sGroupNotifyBoxCount == 1)
00343 {
00344 mNextBtn->setVisible(FALSE);
00345 }
00346 }
00347
00348
00349
00350 LLGroupNotifyBox::~LLGroupNotifyBox()
00351 {
00352 sGroupNotifyBoxCount--;
00353 }
00354
00355
00356 BOOL LLGroupNotifyBox::handleRightMouseDown(S32 x, S32 y, MASK mask)
00357 {
00358 moveToBack();
00359 return TRUE;
00360 }
00361
00362
00363
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
00394
00395
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
00409 gNotifyBoxView->removeChild(this);
00410 gNotifyBoxView->addChildAtEnd(this);
00411 mNextBtn->setVisible(FALSE);
00412
00413
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
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
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
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
00463 self->mInventoryOffer = NULL;
00464
00465 self->mSaveInventoryBtn->setEnabled(FALSE);
00466 }
00467
00468
00469 void LLGroupNotifyBox::onClickNext(void* data)
00470 {
00471 LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00472 self->moveToBack();
00473 }