aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llnotify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llnotify.cpp')
-rw-r--r--linden/indra/newview/llnotify.cpp573
1 files changed, 182 insertions, 391 deletions
diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp
index bd752af..a436d2d 100644
--- a/linden/indra/newview/llnotify.cpp
+++ b/linden/indra/newview/llnotify.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -55,6 +56,8 @@
55#include "lluictrlfactory.h" 56#include "lluictrlfactory.h"
56#include "llversionviewer.h" 57#include "llversionviewer.h"
57 58
59#include "hippoGridManager.h"
60
58// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0e) | Added: RLVa-0.2.0b 61// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0e) | Added: RLVa-0.2.0b
59#include "rlvhandler.h" 62#include "rlvhandler.h"
60// [/RLVa:KB] 63// [/RLVa:KB]
@@ -63,133 +66,83 @@
63LLNotifyBoxView* gNotifyBoxView = NULL; 66LLNotifyBoxView* gNotifyBoxView = NULL;
64 67
65const F32 ANIMATION_TIME = 0.333f; 68const F32 ANIMATION_TIME = 0.333f;
69const S32 BOTTOM_PAD = VPAD * 3;
70
66 71
67// statics 72// statics
68S32 LLNotifyBox::sNotifyBoxCount = 0; 73S32 LLNotifyBox::sNotifyBoxCount = 0;
69const LLFontGL* LLNotifyBox::sFont = NULL; 74const LLFontGL* LLNotifyBox::sFont = NULL;
70const LLFontGL* LLNotifyBox::sFontSmall = NULL; 75const LLFontGL* LLNotifyBox::sFontSmall = NULL;
71std::map<std::string, LLNotifyBox*> LLNotifyBox::sOpenUniqueNotifyBoxes; 76std::map<std::string, LLNotifyBox*> LLNotifyBox::sOpenUniqueNotifyBoxes;
72LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate;
73
74 77
75LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates;
76
77LLNotifyBox::LLNotifyBehavior::LLNotifyBehavior(notify_callback_t callback, void* data) :
78 mCallback(callback),
79 mData(data)
80{
81}
82 78
83//--------------------------------------------------------------------------- 79//---------------------------------------------------------------------------
84// LLNotifyBox 80// LLNotifyBox
85//--------------------------------------------------------------------------- 81//---------------------------------------------------------------------------
86 82
87//static 83//static
88LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, notify_callback_t callback, void *user_data) 84void LLNotifyBox::initClass()
89{ 85{
90 return showXml(xml_desc, LLStringUtil::format_map_t(), callback, user_data); 86 LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify"));
91} 87 LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip"));
92
93 88
94//static 89 LLNotifications::instance().getChannel("Notifications")->connectChanged(&LLNotifyBox::onNotification);
95LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args, BOOL is_caution, 90 LLNotifications::instance().getChannel("NotificationTips")->connectChanged(&LLNotifyBox::onNotification);
96 notify_callback_t callback, void *user_data)
97{
98 // for script permission prompts
99 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
100 LLNotifyBox* notify = findExistingNotify(xml_template, args);
101 if (notify)
102 {
103 delete notify->mBehavior;
104 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
105 }
106 else
107 {
108 notify = new LLNotifyBox(xml_template, args, callback, user_data, is_caution);
109 gNotifyBoxView->addChildAtEnd(notify);
110 notify->moveToBack();
111 }
112 return notify;
113} 91}
114 92
115//static 93//static
116LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args, 94bool LLNotifyBox::onNotification(const LLSD& notify)
117 notify_callback_t callback, void *user_data)
118{ 95{
119 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc); 96 LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
120 LLNotifyBox* notify = findExistingNotify(xml_template, args); 97
121 if (notify) 98 if (!notification) return false;
122 {
123 delete notify->mBehavior;
124 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
125 }
126 else
127 {
128 notify = new LLNotifyBox(xml_template, args, callback, user_data);
129 gNotifyBoxView->addChildAtEnd(notify);
130 notify->moveToBack();
131 }
132 return notify;
133}
134 99
135//static 100 if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
136LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args,
137 notify_callback_t callback, void *user_data,
138 const option_list_t& options,
139 BOOL layout_script_dialog)
140{
141 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
142 LLNotifyBox* notify = findExistingNotify(xml_template, args);
143 if (notify)
144 { 101 {
145 delete notify->mBehavior; 102 //bring existing notification to top
146 notify->mBehavior = new LLNotifyBehavior(callback, user_data); 103 LLNotifyBox* boxp = LLNotifyBox::getInstance(notification->getID());
147 } 104 if (boxp && !boxp->isDead())
148 else 105 {
149 { 106 gNotifyBoxView->showOnly(boxp);
150 notify = new LLNotifyBox(xml_template, args, callback, user_data, FALSE, options, layout_script_dialog); 107 }
151 gNotifyBoxView->addChild(notify); 108 else
152 } 109 {
153 return notify; 110 bool is_script_dialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
154} 111 LLNotifyBox* notify_box = new LLNotifyBox(
112 notification,
113 is_script_dialog); //layout_script_dialog);
155 114
156//static 115 gNotifyBoxView->addChild(notify_box);
157LLNotifyBox* LLNotifyBox::findExistingNotify(LLPointer<LLNotifyBoxTemplate> notify_template, const LLStringUtil::format_map_t &args) 116 }
158{ 117 }
159 if(notify_template->mUnique) 118 else if (notify["sigtype"].asString() == "delete")
160 { 119 {
161 std::string message = notify_template->mMessage; 120 LLNotifyBox* boxp = LLNotifyBox::getInstance(notification->getID());
162 format(message, args); 121 if (boxp && !boxp->isDead())
163 unique_map_t::iterator found_it = sOpenUniqueNotifyBoxes.find(notify_template->mLabel + message);
164 if (found_it != sOpenUniqueNotifyBoxes.end())
165 { 122 {
166 return found_it->second; 123 boxp->close();
167 } 124 }
168 } 125 }
169 return NULL;
170}
171 126
172//static 127 return false;
173void LLNotifyBox::cleanup()
174{
175 sDefaultTemplate = NULL;
176} 128}
177 129
178//--------------------------------------------------------------------------- 130//---------------------------------------------------------------------------
179 131LLNotifyBox::LLNotifyBox(LLNotificationPtr notification,
180LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLStringUtil::format_map_t& args,
181 notify_callback_t callback, void* user_data, BOOL is_caution,
182 const option_list_t& extra_options,
183 BOOL layout_script_dialog) 132 BOOL layout_script_dialog)
184 : LLPanel(xml_template->mLabel, LLRect(), BORDER_NO), 133 : LLPanel(notification->getName(), LLRect(), BORDER_NO),
185 LLEventTimer(xml_template->mDuration), 134 LLEventTimer(notification->getExpiration() == LLDate()
186 mIsTip(FALSE), 135 ? LLDate(LLDate::now().secondsSinceEpoch() + (F64)gSavedSettings.getF32("NotifyTipDuration"))
136 : notification->getExpiration()),
137 LLInstanceTracker<LLNotifyBox, LLUUID>(notification->getID()),
138 mNotification(notification),
139 mIsTip(notification->getType() == "notifytip"),
187 mAnimating(TRUE), 140 mAnimating(TRUE),
188 mUnique(xml_template->mUnique),
189 mNextBtn(NULL), 141 mNextBtn(NULL),
190 mBehavior(new LLNotifyBehavior(callback, user_data)),
191 mNumOptions(0), 142 mNumOptions(0),
192 mDefaultOption(0) 143 mNumButtons(0),
144 mAddedDefaultBtn(FALSE),
145 mLayoutScriptDialog(layout_script_dialog)
193{ 146{
194 // clicking on a button does not steal current focus 147 // clicking on a button does not steal current focus
195 setIsChrome(TRUE); 148 setIsChrome(TRUE);
@@ -197,45 +150,33 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt
197 // class init 150 // class init
198 if (!sFont) 151 if (!sFont)
199 { 152 {
200 sFont = LLFontGL::sSansSerif; 153 sFont = LLFontGL::getFontSansSerif();
201 sFontSmall = LLFontGL::sSansSerifSmall; 154 sFontSmall = LLFontGL::getFontSansSerifSmall();
202 } 155 }
203 156
204 // setup paramaters 157 // setup paramaters
205 158 mMessage = notification->getMessage();
206 mMessage = xml_template->mMessage;
207 format(mMessage, args);
208
209 // use name + formatted text as unique key
210 if (mUnique)
211 {
212 sOpenUniqueNotifyBoxes[xml_template->mLabel + mMessage] = this;
213 }
214
215 option_list_t options = xml_template->mOptions;
216 options.insert(options.end(), extra_options.begin(), extra_options.end());
217 159
218 // initialize 160 // initialize
219
220 mIsTip = xml_template->mIsTip;
221 setFocusRoot(!mIsTip); 161 setFocusRoot(!mIsTip);
222 162
223 // caution flag can be set explicitly by specifying it in the 163 // caution flag can be set explicitly by specifying it in the
224 // call to the c'tor, or it can be set implicitly if the 164 // notification payload, or it can be set implicitly if the
225 // notify xml template specifies that it is a caution 165 // notify xml template specifies that it is a caution
226 // 166 //
227 // tip-style notification handle 'caution' differently - 167 // tip-style notification handle 'caution' differently -
228 // they display the tip in a different color 168 // they display the tip in a different color
229 mIsCaution = (xml_template->mIsCaution || is_caution); 169 mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
230 170
231 // Don't animate if behind other windows 171 // Only animate first window
232 if( gNotifyBoxView->getChildCount() > 0 ) 172 if( gNotifyBoxView->getChildCount() > 0 )
233 mAnimating = FALSE; 173 mAnimating = FALSE;
234 else 174 else
235 mAnimating = TRUE; 175 mAnimating = TRUE;
236 176
237 mNumOptions = options.size(); 177 LLNotificationFormPtr form(notification->getForm());
238 mDefaultOption = xml_template->mDefaultOption; 178
179 mNumOptions = form->getNumElements();
239 180
240 LLRect rect = mIsTip ? getNotifyTipRect(mMessage) 181 LLRect rect = mIsTip ? getNotifyTipRect(mMessage)
241 : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution); 182 : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution);
@@ -289,7 +230,7 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt
289 caution_box->setColor(gColors.getColor("NotifyCautionWarnColor")); 230 caution_box->setColor(gColors.getColor("NotifyCautionWarnColor"));
290 caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor")); 231 caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor"));
291 caution_box->setBorderVisible(FALSE); 232 caution_box->setBorderVisible(FALSE);
292 caution_box->setWrappedText(LLNotifyBox::getTemplateMessage("ScriptQuestionCautionWarn")); 233 caution_box->setWrappedText(notification->getMessage());
293 234
294 addChild(caution_box); 235 addChild(caution_box);
295 236
@@ -297,36 +238,38 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt
297 // it appears below the caution textbox 238 // it appears below the caution textbox
298 y = y - caution_height; 239 y = y - caution_height;
299 } 240 }
241 else
242 {
300 243
301 const S32 BOTTOM_PAD = VPAD * 3; 244 const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);
302 const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD); 245
303 246 // Tokenization on \n is handled by LLTextBox
304 // Tokenization on \n is handled by LLTextBox 247
305 248 const S32 MAX_LENGTH = 512 + 20 +
306 const S32 MAX_LENGTH = 512 + 20 + 249 DB_FIRST_NAME_BUF_SIZE +
307 DB_FIRST_NAME_BUF_SIZE + 250 DB_LAST_NAME_BUF_SIZE +
308 DB_LAST_NAME_BUF_SIZE + 251 DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title.
309 DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title. 252
310 253 text = new LLTextEditor(std::string("box"),
311 text = new LLTextEditor(std::string("box"), 254 LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16),
312 LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), 255 MAX_LENGTH,
313 MAX_LENGTH, 256 mMessage,
314 mMessage, 257 sFont,
315 sFont, 258 FALSE);
316 FALSE); 259 text->setWordWrap(TRUE);
317 text->setWordWrap(TRUE); 260 text->setTabStop(FALSE);
318 text->setTabStop(FALSE); 261 text->setMouseOpaque(FALSE);
319 text->setMouseOpaque(FALSE); 262 text->setBorderVisible(FALSE);
320 text->setBorderVisible(FALSE); 263 text->setTakesNonScrollClicks(FALSE);
321 text->setTakesNonScrollClicks(FALSE); 264 text->setHideScrollbarForShortDocs(TRUE);
322 text->setHideScrollbarForShortDocs(TRUE); 265 text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually
323 text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually 266 // rendered under the text box, therefore we want
324 // rendered under the text box, therefore we want 267 // the actual text box to be transparent
325 // the actual text box to be transparent 268 text->setReadOnlyFgColor ( gColors.getColor("NotifyTextColor") );
326 text->setReadOnlyFgColor ( gColors.getColor("NotifyTextColor") ); 269 text->setEnabled(FALSE); // makes it read-only
327 text->setEnabled(FALSE); // makes it read-only 270 text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard)
328 text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard) 271 addChild(text);
329 addChild(text); 272 }
330 273
331 if (mIsTip) 274 if (mIsTip)
332 { 275 {
@@ -358,61 +301,31 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt
358 addChild(btn); 301 addChild(btn);
359 mNextBtn = btn; 302 mNextBtn = btn;
360 303
361 // make caution notification buttons slightly narrower
362 // so that 3 of them can fit without overlapping the "next" button
363 S32 btn_width = mIsCaution? 84 : 90;
364 LLRect btn_rect;
365
366 for (S32 i = 0; i < mNumOptions; i++) 304 for (S32 i = 0; i < mNumOptions; i++)
367 { 305 {
368 S32 index = i;
369 S32 btn_height= BTN_HEIGHT;
370 const LLFontGL* font = sFont;
371 S32 ignore_pad = 0;
372
373 if (layout_script_dialog)
374 {
375 // Add two "blank" option spaces, before the "Ignore" button
376 index = i + 2;
377 if (i == 0)
378 {
379 // Ignore button is smaller, less wide
380 btn_height = BTN_HEIGHT_SMALL;
381 font = sFontSmall;
382 ignore_pad = 10;
383 }
384 }
385
386 btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad,
387 BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD),
388 btn_width - 2*ignore_pad,
389 btn_height);
390 306
391 InstanceAndS32* userdata = new InstanceAndS32; 307 LLSD form_element = form->getElement(i);
392 userdata->mSelf = this; 308 if (form_element["type"].asString() != "button")
393 userdata->mButton = i;
394
395 mBtnCallbackData.push_back(userdata);
396
397 btn = new LLButton(options[i], btn_rect, LLStringUtil::null, onClickButton, userdata);
398 btn->setFont(font);
399
400 if (mIsCaution)
401 { 309 {
402 btn->setImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); 310 continue;
403 btn->setDisabledImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
404 } 311 }
405 312
406 addChild(btn, -1); 313 addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean());
314 }
407 315
408 if (i == mDefaultOption) 316 if (mNumButtons == 0)
409 { 317 {
410 setDefaultBtn(btn); 318 addButton("OK", "OK", FALSE, TRUE);
411 } 319 mAddedDefaultBtn = TRUE;
412 } 320 }
413 321
414 sNotifyBoxCount++; 322 sNotifyBoxCount++;
415 323
324 if (sNotifyBoxCount <= 0)
325 {
326 llwarns << "A notification was mishandled. sNotifyBoxCount = " << sNotifyBoxCount << llendl;
327 }
328
416 // If this is the only notify box, don't show the next button 329 // If this is the only notify box, don't show the next button
417 if (sNotifyBoxCount == 1 330 if (sNotifyBoxCount == 1
418 && mNextBtn) 331 && mNextBtn)
@@ -425,27 +338,77 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt
425// virtual 338// virtual
426LLNotifyBox::~LLNotifyBox() 339LLNotifyBox::~LLNotifyBox()
427{ 340{
428 delete mBehavior;
429 mBehavior = NULL;
430
431 std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); 341 std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
342}
343
344// virtual
345LLButton* LLNotifyBox::addButton(const std::string& name, const std::string& label, BOOL is_option, BOOL is_default)
346{
347 // make caution notification buttons slightly narrower
348 // so that 3 of them can fit without overlapping the "next" button
349 S32 btn_width = mIsCaution? 84 : 90;
350
351 LLRect btn_rect;
352 LLButton* btn;
353 S32 btn_height= BTN_HEIGHT;
354 const LLFontGL* font = sFont;
355 S32 ignore_pad = 0;
356 S32 button_index = mNumButtons;
357 S32 index = button_index;
358 S32 x = (HPAD * 4) + 32;
359
360 if (mLayoutScriptDialog)
361 {
362 // Add two "blank" option spaces, before the "Ignore" button
363 index = button_index + 2;
364 if (button_index == 0)
365 {
366 // Ignore button is smaller, less wide
367 btn_height = BTN_HEIGHT_SMALL;
368 font = sFontSmall;
369 ignore_pad = 10;
370 }
371 }
372
373 btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad,
374 BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD),
375 btn_width - 2*ignore_pad,
376 btn_height);
377
378 InstanceAndS32* userdata = new InstanceAndS32;
379 userdata->mSelf = this;
380 userdata->mButtonName = is_option ? name : "";
381
382 mBtnCallbackData.push_back(userdata);
383
432 384
433 if (mUnique) 385 btn = new LLButton(name, btn_rect, "", onClickButton, userdata);
386 btn->setLabel(label);
387 btn->setFont(font);
388
389 if (mIsCaution)
390 {
391 btn->setImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
392 btn->setDisabledImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
393 }
394
395 addChild(btn, -1);
396
397 if (is_default)
434 { 398 {
435 sOpenUniqueNotifyBoxes.erase(getName() + mMessage); 399 setDefaultBtn(btn);
436 } 400 }
401
402 mNumButtons++;
403 return btn;
437} 404}
438 405
439// virtual
440BOOL LLNotifyBox::handleMouseUp(S32 x, S32 y, MASK mask) 406BOOL LLNotifyBox::handleMouseUp(S32 x, S32 y, MASK mask)
441{ 407{
442 if (mIsTip) 408 if (mIsTip)
443 { 409 {
444 if (mBehavior->mCallback) 410 mNotification->respond(mNotification->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON));
445 { 411
446 mBehavior->mCallback(0, mBehavior->mData);
447 mBehavior->mCallback = NULL; // Notification callbacks only expect to be called once ever
448 }
449 close(); 412 close();
450 return TRUE; 413 return TRUE;
451 } 414 }
@@ -583,10 +546,18 @@ void LLNotifyBox::close()
583 546
584void LLNotifyBox::format(std::string& msg, const LLStringUtil::format_map_t& args) 547void LLNotifyBox::format(std::string& msg, const LLStringUtil::format_map_t& args)
585{ 548{
586 // XUI:translate!
587 LLStringUtil::format_map_t targs = args; 549 LLStringUtil::format_map_t targs = args;
588 targs["[SECOND_LIFE]"] = "Second Life"; 550
589 targs["[VIEWER]"] = IMP_VIEWER_NAME; 551 // These sort of things are actually set in llui/llnotifications.cpp
552 // so that they will affect all notifications, not just boxes.
553
554 // targs["[SECOND_LIFE]"] = LLNotifications::instance().getGlobalString("SECOND_LIFE");
555 // targs["[VIEWER_NAME]"] = LLNotifications::instance().getGlobalString("VIEWER_NAME");
556
557 //targs["[GRID_NAME]"] = gHippoGridManager->getConnectedGrid()->getGridName();
558 //targs["[GRID_SITE]"] = gHippoGridManager->getConnectedGrid()->getWebSite();
559 //targs["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol();
560
590 LLStringUtil::format(msg, targs); 561 LLStringUtil::format(msg, targs);
591} 562}
592 563
@@ -771,26 +742,14 @@ void LLNotifyBox::onClickButton(void* data)
771{ 742{
772 InstanceAndS32* self_and_button = (InstanceAndS32*)data; 743 InstanceAndS32* self_and_button = (InstanceAndS32*)data;
773 LLNotifyBox* self = self_and_button->mSelf; 744 LLNotifyBox* self = self_and_button->mSelf;
774 S32 button = self_and_button->mButton; 745 std::string button_name = self_and_button->mButtonName;
775 746
776 // for caution notifications, check if the last button in the prompt was clicked 747 LLSD response = self->mNotification->getResponseTemplate();
777 // unless it is the only button, in which case it will just be an "OK" button 748 if (!self->mAddedDefaultBtn && !button_name.empty())
778 if ((self->mIsCaution) && (button > 0) && (button == (self->mNumOptions - 1)))
779 { 749 {
780 // show an alert dialog containing more explanation about the debit permission 750 response[button_name] = true;
781 LLAlertDialog::showXml("DebitPermissionDetails");
782
783 // keep this notification open
784 return;
785 } 751 }
786 752 self->mNotification->respond(response);
787 if (self->mBehavior->mCallback)
788 {
789 self->mBehavior->mCallback(button, self->mBehavior->mData);
790 self->mBehavior->mCallback = NULL; // Notification callbacks only expect to be called once ever
791 }
792
793 self->close();
794} 753}
795 754
796 755
@@ -801,174 +760,6 @@ void LLNotifyBox::onClickNext(void* data)
801 self->moveToBack(true); 760 self->moveToBack(true);
802} 761}
803 762
804// static
805LLPointer<LLNotifyBoxTemplate> LLNotifyBox::getTemplate(const std::string& xml_desc)
806{
807 // get template
808
809 if (!sDefaultTemplate)
810 {
811 // default template is non-unique, of course
812 sDefaultTemplate = new LLNotifyBoxTemplate(FALSE, gSavedSettings.getF32("NotifyTipDuration"));
813 sDefaultTemplate->addOption("OK", FALSE);
814 }
815
816 LLPointer<LLNotifyBoxTemplate> xml_template;
817 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
818 if (iter != sNotifyTemplates.end())
819 {
820 xml_template = iter->second;
821 }
822 else
823 {
824 std::string tmsg = "[Notification template not found:\n " + xml_desc + " ]";
825 sDefaultTemplate->setMessage(tmsg);
826 xml_template = sDefaultTemplate;
827 }
828
829 return xml_template;
830}
831
832//-----------------------------------------------------------------------------
833
834//static
835const std::string LLNotifyBox::getTemplateMessage(const std::string& xml_desc, const LLStringUtil::format_map_t& args)
836{
837 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
838 if (iter != sNotifyTemplates.end())
839 {
840 std::string message = iter->second->mMessage;
841 format(message, args);
842 return message;
843 }
844 else
845 {
846 return xml_desc;
847 }
848}
849
850//static
851const std::string LLNotifyBox::getTemplateMessage(const std::string& xml_desc)
852{
853 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
854 if (iter != sNotifyTemplates.end())
855 {
856 return iter->second->mMessage;
857 }
858 else
859 {
860 return xml_desc;
861 }
862}
863
864// method to check whether a given notify template show as a caution or not
865BOOL LLNotifyBox::getTemplateIsCaution(const std::string& xml_desc)
866{
867 BOOL is_caution = FALSE;
868
869 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
870 if (iter != sNotifyTemplates.end())
871 {
872 is_caution = iter->second->mIsCaution;
873 }
874
875 return is_caution;
876}
877
878//static
879bool LLNotifyBox::parseNotify(const std::string& xml_filename)
880{
881 LLXMLNodePtr root;
882
883 BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
884
885 if (!success || root.isNull() || !root->hasName( "notifications" ))
886 {
887 llerrs << "Problem reading UI Notify file: " << xml_filename << llendl;
888 return false;
889 }
890
891 for (LLXMLNode* notify = root->getFirstChild();
892 notify != NULL; notify = notify->getNextSibling())
893 {
894 if (!notify->hasName("notify"))
895 {
896 continue;
897 }
898
899 BOOL unique = FALSE;
900 notify->getAttributeBOOL("unique", unique);
901
902 F32 duration = gSavedSettings.getF32("NotifyTipDuration");
903 notify->getAttributeF32("duration", duration);
904
905 LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate(unique, duration);
906
907 // label=
908 std::string notify_name;
909 if (notify->getAttributeString("name", notify_name))
910 {
911 xml_template->mLabel = notify_name;
912 }
913 else
914 {
915 llwarns << "Unable to parse notify with no name" << llendl;
916 continue;
917 }
918 // modal=
919 BOOL tip;
920 if (notify->getAttributeBOOL("tip", tip))
921 {
922 xml_template->mIsTip = tip;
923 }
924
925 // parse a bool attribute named "caution" to determine
926 // whether this notification gets cautionary special handling
927 BOOL caution = FALSE;
928 if (notify->getAttributeBOOL("caution", caution))
929 {
930 if (xml_template)
931 {
932 xml_template->mIsCaution = caution;
933 }
934 }
935
936
937 S32 btn_idx = 0;
938 for (LLXMLNode* child = notify->getFirstChild();
939 child != NULL; child = child->getNextSibling())
940 {
941 // <message>
942 if (child->hasName("message"))
943 {
944 xml_template->mMessage = child->getTextContents();
945 }
946
947 // <option>
948 if (child->hasName("option"))
949 {
950 std::string label = child->getValue();
951 BOOL is_default = FALSE;
952 child->getAttributeBOOL("default", is_default);
953 std::string ignore_text;
954 if (!child->getAttributeString("ignore", ignore_text))
955 {
956 ignore_text = label;
957 }
958 xml_template->addOption(label, is_default);
959 btn_idx++;
960 }
961 }
962
963 //*TODO:translate
964 if (xml_template->mOptions.empty())
965 {
966 xml_template->addOption("OK", FALSE);
967 }
968 sNotifyTemplates[xml_template->mLabel] = xml_template;
969 }
970 return true;
971}
972 763
973LLNotifyBoxView::LLNotifyBoxView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows) 764LLNotifyBoxView::LLNotifyBoxView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows)
974 : LLUICtrl(name,rect,mouse_opaque,NULL,NULL,follows) 765 : LLUICtrl(name,rect,mouse_opaque,NULL,NULL,follows)
@@ -1045,7 +836,7 @@ void LLNotifyBoxView::purgeMessagesMatching(const Matcher& matcher)
1045 } 836 }
1046 837
1047 LLNotifyBox* notification = (LLNotifyBox*)*iter; 838 LLNotifyBox* notification = (LLNotifyBox*)*iter;
1048 if(matcher.matches(notification->getNotifyCallback(), notification->getUserData())) 839 if(matcher.matches(notification->getNotification()))
1049 { 840 {
1050 removeChild(notification); 841 removeChild(notification);
1051 } 842 }