diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llgroupnotify.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llgroupnotify.cpp')
-rw-r--r-- | linden/indra/newview/llgroupnotify.cpp | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/linden/indra/newview/llgroupnotify.cpp b/linden/indra/newview/llgroupnotify.cpp new file mode 100644 index 0000000..5d839f2 --- /dev/null +++ b/linden/indra/newview/llgroupnotify.cpp | |||
@@ -0,0 +1,475 @@ | |||
1 | /** | ||
2 | * @file llgroupnotify.cpp | ||
3 | * @brief Non-blocking notification that doesn't take keyboard focus. | ||
4 | * | ||
5 | * Copyright (c) 2006-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "llgroupnotify.h" | ||
31 | |||
32 | #include "llfocusmgr.h" | ||
33 | |||
34 | #include "llbutton.h" | ||
35 | #include "lliconctrl.h" | ||
36 | #include "llfloaterchat.h" // for add_chat_history() | ||
37 | #include "llnotify.h" | ||
38 | #include "lltextbox.h" | ||
39 | #include "llviewertexteditor.h" | ||
40 | #include "lluiconstants.h" | ||
41 | #include "llui.h" | ||
42 | #include "llviewercontrol.h" | ||
43 | #include "llfloatergroupinfo.h" | ||
44 | #include "llinventoryview.h" | ||
45 | #include "llinventory.h" | ||
46 | |||
47 | #include "llglheaders.h" | ||
48 | #include "llagent.h" | ||
49 | // Globals | ||
50 | //LLView* gGroupNotifyBoxView = NULL; | ||
51 | |||
52 | const F32 ANIMATION_TIME = 0.333f; | ||
53 | |||
54 | S32 LLGroupNotifyBox::sGroupNotifyBoxCount = 0; | ||
55 | |||
56 | //--------------------------------------------------------------------------- | ||
57 | // LLGroupNotifyBox | ||
58 | //--------------------------------------------------------------------------- | ||
59 | |||
60 | char* g_formatted_time(const time_t& the_time, char* buffer) | ||
61 | { | ||
62 | time_t t = the_time; | ||
63 | if (!t) time(&t); | ||
64 | LLString::copy(buffer, ctime(&t), 30); | ||
65 | buffer[24] = '\0'; | ||
66 | return buffer; | ||
67 | } | ||
68 | |||
69 | // static | ||
70 | LLGroupNotifyBox* LLGroupNotifyBox::show(const char* subject, | ||
71 | const char* message, | ||
72 | const char* from_name, | ||
73 | const LLUUID& group_id, | ||
74 | const U32& t, | ||
75 | const bool& has_inventory, | ||
76 | const char* inventory_name, | ||
77 | LLOfferInfo* inventory_offer) | ||
78 | { | ||
79 | // Get the group data | ||
80 | LLGroupData group_data; | ||
81 | if (!gAgent.getGroupData(group_id,group_data)) | ||
82 | { | ||
83 | llwarns << "Group notice for unkown group : " << group_id.getString() << llendl; | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | LLGroupNotifyBox* self; | ||
88 | self = new LLGroupNotifyBox(subject, message, from_name, group_id, group_data.mInsigniaID, group_data.mName.c_str(),t,has_inventory,inventory_name,inventory_offer); | ||
89 | gNotifyBoxView->addChild(self); | ||
90 | |||
91 | // TODO: play a sound | ||
92 | return self; | ||
93 | } | ||
94 | |||
95 | bool is_openable(LLAssetType::EType type) | ||
96 | { | ||
97 | switch(type) | ||
98 | { | ||
99 | case LLAssetType::AT_LANDMARK: | ||
100 | case LLAssetType::AT_NOTECARD: | ||
101 | case LLAssetType::AT_IMAGE_JPEG: | ||
102 | case LLAssetType::AT_IMAGE_TGA: | ||
103 | case LLAssetType::AT_TEXTURE: | ||
104 | case LLAssetType::AT_TEXTURE_TGA: | ||
105 | return true; | ||
106 | default: | ||
107 | return false; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, | ||
112 | const char* message, | ||
113 | const char* from_name, | ||
114 | const LLUUID& group_id, | ||
115 | const LLUUID& group_insignia, | ||
116 | const char* group_name, | ||
117 | const U32& t, | ||
118 | const bool& has_inventory, | ||
119 | const char* inventory_name, | ||
120 | LLOfferInfo* inventory_offer) | ||
121 | : LLPanel("groupnotify", LLGroupNotifyBox::getGroupNotifyRect(), BORDER_YES), | ||
122 | mAnimating(TRUE), | ||
123 | mTimer(), | ||
124 | mGroupID(group_id), | ||
125 | mHasInventory(has_inventory), | ||
126 | mInventoryOffer(inventory_offer) | ||
127 | { | ||
128 | mIsFocusRoot = TRUE; | ||
129 | |||
130 | time_t timestamp = (time_t)t; | ||
131 | |||
132 | char time_buf[30]; | ||
133 | g_formatted_time(timestamp, time_buf); | ||
134 | |||
135 | setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); | ||
136 | setBackgroundVisible(TRUE); | ||
137 | setBackgroundOpaque(TRUE); | ||
138 | |||
139 | // TODO: add a color for group notices | ||
140 | setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") ); | ||
141 | |||
142 | LLIconCtrl* icon; | ||
143 | LLTextEditor* text; | ||
144 | |||
145 | const S32 VPAD = 2; | ||
146 | const S32 TOP = mRect.getHeight() - 32; // Get past the top menu bar | ||
147 | const S32 BOTTOM_PAD = VPAD * 2; | ||
148 | const S32 BTN_TOP = BOTTOM_PAD + BTN_HEIGHT + VPAD; | ||
149 | const S32 RIGHT = mRect.getWidth() - HPAD - HPAD; | ||
150 | const S32 LINE_HEIGHT = 16; | ||
151 | |||
152 | const S32 LABEL_WIDTH = 64; | ||
153 | const S32 ICON_WIDTH = 64; | ||
154 | |||
155 | S32 y = TOP; | ||
156 | S32 x = HPAD + HPAD; | ||
157 | |||
158 | |||
159 | // Title | ||
160 | LLTextBox* line; | ||
161 | |||
162 | line = new LLTextBox("title",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),"Group Notice",LLFontGL::sSansSerifHuge); | ||
163 | line->setHAlign(LLFontGL::RIGHT); | ||
164 | line->setDropshadowVisible(true); | ||
165 | line->setBorderVisible(FALSE); | ||
166 | line->setColor(LLColor4::white); | ||
167 | line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") ); | ||
168 | |||
169 | addChild(line); | ||
170 | |||
171 | y -= llfloor(1.5f*LINE_HEIGHT); | ||
172 | |||
173 | x += HPAD + HPAD + ICON_WIDTH; | ||
174 | |||
175 | std::stringstream from; | ||
176 | from << "Sent by " << from_name << ", " << group_name; | ||
177 | |||
178 | line = new LLTextBox("group",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),from.str().c_str(),LLFontGL::sSansSerif); | ||
179 | line->setDropshadowVisible(true); | ||
180 | line->setHAlign(LLFontGL::RIGHT); | ||
181 | line->setBorderVisible(FALSE); | ||
182 | line->setColor(LLColor4::white); | ||
183 | line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") ); | ||
184 | addChild(line); | ||
185 | |||
186 | y -= (LINE_HEIGHT + VPAD); | ||
187 | |||
188 | LLUUID icon_id(gViewerArt.getString("notify_box_icon.tga")); | ||
189 | // TODO: change this to be the group icon. | ||
190 | if (!group_insignia.isNull()) | ||
191 | { | ||
192 | icon_id = group_insignia; | ||
193 | } | ||
194 | |||
195 | x = HPAD + HPAD; | ||
196 | |||
197 | icon = new LLIconCtrl("icon", | ||
198 | LLRect(x, y, x+ICON_WIDTH, y-ICON_WIDTH), | ||
199 | icon_id); | ||
200 | icon->setMouseOpaque(FALSE); | ||
201 | addChild(icon); | ||
202 | |||
203 | x += HPAD + HPAD + ICON_WIDTH; | ||
204 | // If we have inventory with this message, leave room for the name. | ||
205 | S32 box_bottom = BTN_TOP + (mHasInventory ? (LINE_HEIGHT + 2*VPAD) : 0); | ||
206 | |||
207 | text = new LLViewerTextEditor("box", | ||
208 | LLRect(x, y, RIGHT, box_bottom), | ||
209 | DB_GROUP_NOTICE_MSG_STR_LEN, | ||
210 | "", | ||
211 | LLFontGL::sSansSerif, | ||
212 | FALSE); | ||
213 | |||
214 | LLStyle headerstyle(true,LLColor4::black,"SansSerifBig"); | ||
215 | LLStyle datestyle(true,LLColor4::black,"serif"); | ||
216 | |||
217 | text->appendStyledText(subject,false,false,headerstyle); | ||
218 | text->appendStyledText(time_buf,false,false,datestyle); | ||
219 | // Sadly, our LLTextEditor can't handle both styled and unstyled text | ||
220 | // at the same time. Hence this space must be styled. JC | ||
221 | text->appendColoredText(" ",false,false,LLColor4::grey4); | ||
222 | text->appendColoredText(message,false,false,LLColor4::grey4); | ||
223 | |||
224 | LLColor4 semi_transparent(1.0f,1.0f,1.0f,0.8f); | ||
225 | text->setCursor(0,0); | ||
226 | text->setEnabled(FALSE); | ||
227 | text->setWordWrap(TRUE); | ||
228 | text->setTakesFocus(FALSE); | ||
229 | text->setTabToNextField(TRUE); | ||
230 | text->setMouseOpaque(TRUE); | ||
231 | text->setBorderVisible(TRUE); | ||
232 | text->setTakesNonScrollClicks(TRUE); | ||
233 | text->setHideScrollbarForShortDocs(TRUE); | ||
234 | text->setReadOnlyBgColor ( semi_transparent ); | ||
235 | text->setWriteableBgColor ( semi_transparent ); | ||
236 | |||
237 | addChild(text); | ||
238 | |||
239 | y = box_bottom - VPAD; | ||
240 | |||
241 | if (mHasInventory) | ||
242 | { | ||
243 | line = new LLTextBox("subjecttitle",LLRect(x,y,x + LABEL_WIDTH,y - LINE_HEIGHT),"Attached: ",LLFontGL::sSansSerif); | ||
244 | line->setBorderVisible(FALSE); | ||
245 | line->setColor(LLColor4::white); | ||
246 | line->setDropshadowVisible(TRUE); | ||
247 | line->setBackgroundColor( gColors.getColor("GroupNotifyBoxColor") ); | ||
248 | addChild(line); | ||
249 | |||
250 | LLViewerImage* item_icon = get_item_icon(mInventoryOffer->mType, | ||
251 | LLInventoryType::IT_TEXTURE, | ||
252 | 0); | ||
253 | |||
254 | |||
255 | x += LABEL_WIDTH + HPAD; | ||
256 | |||
257 | std::stringstream ss; | ||
258 | ss << " " << inventory_name; | ||
259 | line = new LLTextBox("object_name",LLRect(x,y,RIGHT - HPAD,y - LINE_HEIGHT),ss.str().c_str(),LLFontGL::sSansSerif); | ||
260 | line->setEnabled(FALSE); | ||
261 | line->setBorderVisible(TRUE); | ||
262 | line->setDisabledColor(LLColor4::blue4); | ||
263 | line->setDropshadowVisible(FALSE); | ||
264 | line->setBackgroundVisible(true); | ||
265 | line->setBackgroundColor( semi_transparent ); | ||
266 | addChild(line); | ||
267 | |||
268 | icon = new LLIconCtrl("icon", | ||
269 | LLRect(x, y, x+16, y-16), | ||
270 | item_icon->getID()); | ||
271 | icon->setMouseOpaque(FALSE); | ||
272 | addChild(icon); | ||
273 | } | ||
274 | |||
275 | LLButton* btn; | ||
276 | btn = new LLButton("next", | ||
277 | LLRect(mRect.getWidth()-24, BOTTOM_PAD+16, mRect.getWidth()-8, BOTTOM_PAD), | ||
278 | "notify_next.tga", | ||
279 | "notify_next.tga", | ||
280 | "", | ||
281 | onClickNext, | ||
282 | this, | ||
283 | LLFontGL::sSansSerif); | ||
284 | btn->setToolTip("Next"); | ||
285 | addChild(btn); | ||
286 | mNextBtn = btn; | ||
287 | |||
288 | S32 btn_width = 80; | ||
289 | S32 wide_btn_width = 120; | ||
290 | LLRect btn_rect; | ||
291 | x = 3 * HPAD; | ||
292 | |||
293 | btn_rect.setOriginAndSize(x, | ||
294 | BOTTOM_PAD, | ||
295 | btn_width, | ||
296 | BTN_HEIGHT); | ||
297 | |||
298 | btn = new LLButton("OK", btn_rect, "", onClickOk, this); | ||
299 | addChild(btn, -1); | ||
300 | setDefaultBtn(btn); | ||
301 | |||
302 | x += btn_width + HPAD; | ||
303 | |||
304 | |||
305 | btn_rect.setOriginAndSize(x, | ||
306 | BOTTOM_PAD, | ||
307 | wide_btn_width, | ||
308 | BTN_HEIGHT); | ||
309 | |||
310 | btn = new LLButton("Group Notices", btn_rect, "", onClickGroupInfo, this); | ||
311 | btn->setToolTip("View past notices or opt-out of receiving these messages here."); | ||
312 | addChild(btn, -1); | ||
313 | |||
314 | if (mHasInventory && mInventoryOffer) | ||
315 | { | ||
316 | x += wide_btn_width + HPAD; | ||
317 | |||
318 | btn_rect.setOriginAndSize(x, | ||
319 | BOTTOM_PAD, | ||
320 | wide_btn_width, | ||
321 | BTN_HEIGHT); | ||
322 | |||
323 | LLString btn_lbl(""); | ||
324 | if(is_openable(mInventoryOffer->mType)) | ||
325 | { | ||
326 | btn_lbl = "Open Attachment"; | ||
327 | } | ||
328 | else | ||
329 | { | ||
330 | btn_lbl = "Save Attachment"; | ||
331 | } | ||
332 | mSaveInventoryBtn = new LLButton(btn_lbl, btn_rect, "", onClickSaveInventory, this); | ||
333 | mSaveInventoryBtn->setVisible(mHasInventory); | ||
334 | addChild(mSaveInventoryBtn); | ||
335 | } | ||
336 | |||
337 | sGroupNotifyBoxCount++; | ||
338 | |||
339 | // If this is the only notify box, don't show the next button | ||
340 | if (sGroupNotifyBoxCount == 1) | ||
341 | { | ||
342 | mNextBtn->setVisible(FALSE); | ||
343 | } | ||
344 | } | ||
345 | |||
346 | |||
347 | // virtual | ||
348 | LLGroupNotifyBox::~LLGroupNotifyBox() | ||
349 | { | ||
350 | sGroupNotifyBoxCount--; | ||
351 | } | ||
352 | |||
353 | // virtual | ||
354 | BOOL LLGroupNotifyBox::handleRightMouseDown(S32 x, S32 y, MASK mask) | ||
355 | { | ||
356 | if (getVisible() && getEnabled() && pointInView(x,y)) | ||
357 | { | ||
358 | moveToBack(); | ||
359 | return TRUE; | ||
360 | } | ||
361 | |||
362 | return LLPanel::handleRightMouseDown(x, y, mask); | ||
363 | } | ||
364 | |||
365 | |||
366 | // virtual | ||
367 | void LLGroupNotifyBox::draw() | ||
368 | { | ||
369 | F32 display_time = mTimer.getElapsedTimeF32(); | ||
370 | |||
371 | if (mAnimating && display_time < ANIMATION_TIME) | ||
372 | { | ||
373 | glMatrixMode(GL_MODELVIEW); | ||
374 | glPushMatrix(); | ||
375 | |||
376 | S32 height = mRect.getHeight(); | ||
377 | F32 fraction = display_time / ANIMATION_TIME; | ||
378 | F32 voffset = (1.f - fraction) * height; | ||
379 | |||
380 | glTranslatef(0.f, voffset, 0.f); | ||
381 | |||
382 | LLPanel::draw(); | ||
383 | |||
384 | glPopMatrix(); | ||
385 | } | ||
386 | else | ||
387 | { | ||
388 | mAnimating = FALSE; | ||
389 | LLPanel::draw(); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | |||
394 | void LLGroupNotifyBox::close() | ||
395 | { | ||
396 | // The group notice dialog may be an inventory offer. | ||
397 | // If it has an inventory save button and that button is still enabled | ||
398 | // Then we need to send the inventory declined message | ||
399 | if(mHasInventory) | ||
400 | { | ||
401 | inventory_offer_callback( 1 , mInventoryOffer); | ||
402 | } | ||
403 | gNotifyBoxView->removeChild(this); | ||
404 | delete this; | ||
405 | } | ||
406 | |||
407 | |||
408 | void LLGroupNotifyBox::moveToBack() | ||
409 | { | ||
410 | // Move this dialog to the back. | ||
411 | gNotifyBoxView->removeChild(this); | ||
412 | gNotifyBoxView->addChildAtEnd(this); | ||
413 | mNextBtn->setVisible(FALSE); | ||
414 | |||
415 | // And enable the next button on the frontmost one, if there is one | ||
416 | if (sGroupNotifyBoxCount > 1) | ||
417 | { | ||
418 | LLView* view = gNotifyBoxView->getFirstChild(); | ||
419 | LLGroupNotifyBox* front = (LLGroupNotifyBox*)view; | ||
420 | front->mNextBtn->setVisible(TRUE); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | |||
425 | // static | ||
426 | LLRect LLGroupNotifyBox::getGroupNotifyRect() | ||
427 | { | ||
428 | S32 notify_height = gSavedSettings.getS32("GroupNotifyBoxHeight"); | ||
429 | const S32 NOTIFY_WIDTH = gSavedSettings.getS32("GroupNotifyBoxWidth"); | ||
430 | |||
431 | const S32 TOP = gNotifyBoxView->getRect().getHeight(); | ||
432 | const S32 RIGHT = gNotifyBoxView->getRect().getWidth(); | ||
433 | const S32 LEFT = RIGHT - NOTIFY_WIDTH; | ||
434 | |||
435 | return LLRect(LEFT, TOP, RIGHT, TOP-notify_height); | ||
436 | } | ||
437 | |||
438 | |||
439 | // static | ||
440 | void LLGroupNotifyBox::onClickOk(void* data) | ||
441 | { | ||
442 | LLGroupNotifyBox* self = (LLGroupNotifyBox*)data; | ||
443 | if (self) self->close(); | ||
444 | } | ||
445 | |||
446 | void LLGroupNotifyBox::onClickGroupInfo(void* data) | ||
447 | { | ||
448 | LLGroupNotifyBox* self = (LLGroupNotifyBox*)data; | ||
449 | |||
450 | if (self) | ||
451 | { | ||
452 | LLFloaterGroupInfo::showFromUUID(self->mGroupID, "notices_tab"); | ||
453 | } | ||
454 | |||
455 | //Leave notice open until explicitly closed | ||
456 | } | ||
457 | |||
458 | void LLGroupNotifyBox::onClickSaveInventory(void* data) | ||
459 | { | ||
460 | LLGroupNotifyBox* self = (LLGroupNotifyBox*)data; | ||
461 | |||
462 | inventory_offer_callback( 0 , self->mInventoryOffer); | ||
463 | |||
464 | // inventory_offer_callback will delete the offer, so make sure we aren't still pointing to it. | ||
465 | self->mInventoryOffer = NULL; | ||
466 | // Each item can only be received once, so disable the button. | ||
467 | self->mSaveInventoryBtn->setEnabled(FALSE); | ||
468 | } | ||
469 | |||
470 | // static | ||
471 | void LLGroupNotifyBox::onClickNext(void* data) | ||
472 | { | ||
473 | LLGroupNotifyBox* self = (LLGroupNotifyBox*)data; | ||
474 | self->moveToBack(); | ||
475 | } | ||