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 mIsFocusRoot = 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 = mRect.getHeight() - 32;
00151 const S32 BOTTOM_PAD = VPAD * 2;
00152 const S32 BTN_TOP = BOTTOM_PAD + BTN_HEIGHT + VPAD;
00153 const S32 RIGHT = mRect.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
00163
00164 LLTextBox* line;
00165
00166 line = new LLTextBox("title",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),"Group Notice",LLFontGL::sSansSerifHuge);
00167 line->setHAlign(LLFontGL::RIGHT);
00168 line->setFontStyle(LLFontGL::DROP_SHADOW_SOFT);
00169 line->setBorderVisible(FALSE);
00170 line->setColor(LLColor4::white);
00171 line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") );
00172
00173 addChild(line);
00174
00175 y -= llfloor(1.5f*LINE_HEIGHT);
00176
00177 x += HPAD + HPAD + ICON_WIDTH;
00178
00179 std::stringstream from;
00180 from << "Sent by " << from_name << ", " << group_name;
00181
00182 line = new LLTextBox("group",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),from.str().c_str(),LLFontGL::sSansSerif);
00183 line->setFontStyle(LLFontGL::DROP_SHADOW_SOFT);
00184 line->setHAlign(LLFontGL::RIGHT);
00185 line->setBorderVisible(FALSE);
00186 line->setColor(LLColor4::white);
00187 line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") );
00188 addChild(line);
00189
00190 y -= (LINE_HEIGHT + VPAD);
00191
00192 LLUUID icon_id(gViewerArt.getString("notify_box_icon.tga"));
00193
00194 if (!group_insignia.isNull())
00195 {
00196 icon_id = group_insignia;
00197 }
00198
00199 x = HPAD + HPAD;
00200
00201 icon = new LLIconCtrl("icon",
00202 LLRect(x, y, x+ICON_WIDTH, y-ICON_WIDTH),
00203 icon_id);
00204 icon->setMouseOpaque(FALSE);
00205 addChild(icon);
00206
00207 x += HPAD + HPAD + ICON_WIDTH;
00208
00209 S32 box_bottom = BTN_TOP + (mHasInventory ? (LINE_HEIGHT + 2*VPAD) : 0);
00210
00211 text = new LLViewerTextEditor("box",
00212 LLRect(x, y, RIGHT, box_bottom),
00213 DB_GROUP_NOTICE_MSG_STR_LEN,
00214 "",
00215 LLFontGL::sSansSerif,
00216 FALSE);
00217
00218 LLStyle headerstyle(true,LLColor4::black,"SansSerifBig");
00219 LLStyle datestyle(true,LLColor4::black,"serif");
00220
00221 text->appendStyledText(subject,false,false,&headerstyle);
00222 text->appendStyledText(time_buf,false,false,&datestyle);
00223
00224
00225 text->appendColoredText(" ",false,false,LLColor4::grey4);
00226 text->appendColoredText(message,false,false,LLColor4::grey4);
00227
00228 LLColor4 semi_transparent(1.0f,1.0f,1.0f,0.8f);
00229 text->setCursor(0,0);
00230 text->setEnabled(FALSE);
00231 text->setWordWrap(TRUE);
00232 text->setTakesFocus(TRUE);
00233 text->setTabToNextField(TRUE);
00234 text->setMouseOpaque(TRUE);
00235 text->setBorderVisible(TRUE);
00236 text->setTakesNonScrollClicks(TRUE);
00237 text->setHideScrollbarForShortDocs(TRUE);
00238 text->setReadOnlyBgColor ( semi_transparent );
00239 text->setWriteableBgColor ( semi_transparent );
00240
00241 addChild(text);
00242
00243 y = box_bottom - VPAD;
00244
00245 if (mHasInventory)
00246 {
00247 line = new LLTextBox("subjecttitle",LLRect(x,y,x + LABEL_WIDTH,y - LINE_HEIGHT),"Attached: ",LLFontGL::sSansSerif);
00248 line->setBorderVisible(FALSE);
00249 line->setColor(LLColor4::white);
00250 line->setFontStyle(LLFontGL::DROP_SHADOW_SOFT);
00251 line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") );
00252 addChild(line);
00253
00254 LLViewerImage* item_icon = get_item_icon(mInventoryOffer->mType,
00255 LLInventoryType::IT_TEXTURE,
00256 0, FALSE);
00257
00258
00259 x += LABEL_WIDTH + HPAD;
00260
00261 std::stringstream ss;
00262 ss << " " << inventory_name;
00263 line = new LLTextBox("object_name",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),ss.str().c_str(),LLFontGL::sSansSerif);
00264 line->setEnabled(FALSE);
00265 line->setBorderVisible(TRUE);
00266 line->setDisabledColor(LLColor4::blue4);
00267 line->setFontStyle(LLFontGL::NORMAL);
00268 line->setBackgroundVisible(true);
00269 line->setBackgroundColor( semi_transparent );
00270 addChild(line);
00271
00272 icon = new LLIconCtrl("icon",
00273 LLRect(x, y, x+16, y-16),
00274 item_icon->getID());
00275 icon->setMouseOpaque(FALSE);
00276 addChild(icon);
00277 }
00278
00279 LLButton* btn;
00280 btn = new LLButton("next",
00281 LLRect(mRect.getWidth()-24, BOTTOM_PAD+16, mRect.getWidth()-8, BOTTOM_PAD),
00282 "notify_next.tga",
00283 "notify_next.tga",
00284 "",
00285 onClickNext,
00286 this,
00287 LLFontGL::sSansSerif);
00288 btn->setToolTip("Next");
00289 addChild(btn);
00290 mNextBtn = btn;
00291
00292 S32 btn_width = 80;
00293 S32 wide_btn_width = 120;
00294 LLRect btn_rect;
00295 x = 3 * HPAD;
00296
00297 btn_rect.setOriginAndSize(x,
00298 BOTTOM_PAD,
00299 btn_width,
00300 BTN_HEIGHT);
00301
00302 btn = new LLButton("OK", btn_rect, "", onClickOk, this);
00303 addChild(btn, -1);
00304 setDefaultBtn(btn);
00305
00306 x += btn_width + HPAD;
00307
00308
00309 btn_rect.setOriginAndSize(x,
00310 BOTTOM_PAD,
00311 wide_btn_width,
00312 BTN_HEIGHT);
00313
00314 btn = new LLButton("Group Notices", btn_rect, "", onClickGroupInfo, this);
00315 btn->setToolTip("View past notices or opt-out of receiving these messages here.");
00316 addChild(btn, -1);
00317
00318 if (mHasInventory && mInventoryOffer)
00319 {
00320 x += wide_btn_width + HPAD;
00321
00322 btn_rect.setOriginAndSize(x,
00323 BOTTOM_PAD,
00324 wide_btn_width,
00325 BTN_HEIGHT);
00326
00327 LLString btn_lbl("");
00328 if(is_openable(mInventoryOffer->mType))
00329 {
00330 btn_lbl = "Open Attachment";
00331 }
00332 else
00333 {
00334 btn_lbl = "Save Attachment";
00335 }
00336 mSaveInventoryBtn = new LLButton(btn_lbl, btn_rect, "", onClickSaveInventory, this);
00337 mSaveInventoryBtn->setVisible(mHasInventory);
00338 addChild(mSaveInventoryBtn);
00339 }
00340
00341 sGroupNotifyBoxCount++;
00342
00343
00344 if (sGroupNotifyBoxCount == 1)
00345 {
00346 mNextBtn->setVisible(FALSE);
00347 }
00348 }
00349
00350
00351
00352 LLGroupNotifyBox::~LLGroupNotifyBox()
00353 {
00354 sGroupNotifyBoxCount--;
00355 }
00356
00357
00358 BOOL LLGroupNotifyBox::handleRightMouseDown(S32 x, S32 y, MASK mask)
00359 {
00360 if (getVisible() && getEnabled() && pointInView(x,y))
00361 {
00362 moveToBack();
00363 return TRUE;
00364 }
00365
00366 return LLPanel::handleRightMouseDown(x, y, mask);
00367 }
00368
00369
00370
00371 void LLGroupNotifyBox::draw()
00372 {
00373 F32 display_time = mTimer.getElapsedTimeF32();
00374
00375 if (mAnimating && display_time < ANIMATION_TIME)
00376 {
00377 glMatrixMode(GL_MODELVIEW);
00378 glPushMatrix();
00379
00380 S32 height = mRect.getHeight();
00381 F32 fraction = display_time / ANIMATION_TIME;
00382 F32 voffset = (1.f - fraction) * height;
00383
00384 glTranslatef(0.f, voffset, 0.f);
00385
00386 LLPanel::draw();
00387
00388 glPopMatrix();
00389 }
00390 else
00391 {
00392 mAnimating = FALSE;
00393 LLPanel::draw();
00394 }
00395 }
00396
00397
00398 void LLGroupNotifyBox::close()
00399 {
00400
00401
00402
00403 if(mHasInventory)
00404 {
00405 inventory_offer_callback(IOR_DECLINE , mInventoryOffer);
00406 }
00407 gNotifyBoxView->removeChild(this);
00408
00409 die();
00410 }
00411
00412
00413 void LLGroupNotifyBox::moveToBack()
00414 {
00415
00416 gNotifyBoxView->removeChild(this);
00417 gNotifyBoxView->addChildAtEnd(this);
00418 mNextBtn->setVisible(FALSE);
00419
00420
00421 if (sGroupNotifyBoxCount > 1)
00422 {
00423 LLView* view = gNotifyBoxView->getFirstChild();
00424 LLGroupNotifyBox* front = (LLGroupNotifyBox*)view;
00425 front->mNextBtn->setVisible(TRUE);
00426 }
00427 }
00428
00429
00430
00431 LLRect LLGroupNotifyBox::getGroupNotifyRect()
00432 {
00433 S32 notify_height = gSavedSettings.getS32("GroupNotifyBoxHeight");
00434 const S32 NOTIFY_WIDTH = gSavedSettings.getS32("GroupNotifyBoxWidth");
00435
00436 const S32 TOP = gNotifyBoxView->getRect().getHeight();
00437 const S32 RIGHT = gNotifyBoxView->getRect().getWidth();
00438 const S32 LEFT = RIGHT - NOTIFY_WIDTH;
00439
00440 return LLRect(LEFT, TOP, RIGHT, TOP-notify_height);
00441 }
00442
00443
00444
00445 void LLGroupNotifyBox::onClickOk(void* data)
00446 {
00447 LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00448 if (self) self->close();
00449 }
00450
00451 void LLGroupNotifyBox::onClickGroupInfo(void* data)
00452 {
00453 LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00454
00455 if (self)
00456 {
00457 LLFloaterGroupInfo::showFromUUID(self->mGroupID, "notices_tab");
00458 }
00459
00460
00461 }
00462
00463 void LLGroupNotifyBox::onClickSaveInventory(void* data)
00464 {
00465 LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00466
00467 inventory_offer_callback( IOR_ACCEPT , self->mInventoryOffer);
00468
00469
00470 self->mInventoryOffer = NULL;
00471
00472 self->mSaveInventoryBtn->setEnabled(FALSE);
00473 }
00474
00475
00476 void LLGroupNotifyBox::onClickNext(void* data)
00477 {
00478 LLGroupNotifyBox* self = (LLGroupNotifyBox*)data;
00479 self->moveToBack();
00480 }