diff options
author | Jacek Antonelli | 2009-04-30 13:04:20 -0500 |
---|---|---|
committer | Jacek Antonelli | 2009-04-30 13:07:16 -0500 |
commit | ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch) | |
tree | 8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/llnotify.cpp | |
parent | Second Life viewer sources 1.22.11 (diff) | |
download | meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2 meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz |
Second Life viewer sources 1.23.0-RC
Diffstat (limited to 'linden/indra/newview/llnotify.cpp')
-rw-r--r-- | linden/indra/newview/llnotify.cpp | 550 |
1 files changed, 164 insertions, 386 deletions
diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp index 9e837a6..3c3f824 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, |
@@ -54,137 +55,88 @@ | |||
54 | #include "lloverlaybar.h" // for gOverlayBar | 55 | #include "lloverlaybar.h" // for gOverlayBar |
55 | #include "lluictrlfactory.h" | 56 | #include "lluictrlfactory.h" |
56 | 57 | ||
58 | |||
57 | // Globals | 59 | // Globals |
58 | LLNotifyBoxView* gNotifyBoxView = NULL; | 60 | LLNotifyBoxView* gNotifyBoxView = NULL; |
59 | 61 | ||
60 | const F32 ANIMATION_TIME = 0.333f; | 62 | const F32 ANIMATION_TIME = 0.333f; |
63 | const S32 BOTTOM_PAD = VPAD * 3; | ||
64 | |||
61 | 65 | ||
62 | // statics | 66 | // statics |
63 | S32 LLNotifyBox::sNotifyBoxCount = 0; | 67 | S32 LLNotifyBox::sNotifyBoxCount = 0; |
64 | const LLFontGL* LLNotifyBox::sFont = NULL; | 68 | const LLFontGL* LLNotifyBox::sFont = NULL; |
65 | const LLFontGL* LLNotifyBox::sFontSmall = NULL; | 69 | const LLFontGL* LLNotifyBox::sFontSmall = NULL; |
66 | std::map<std::string, LLNotifyBox*> LLNotifyBox::sOpenUniqueNotifyBoxes; | 70 | std::map<std::string, LLNotifyBox*> LLNotifyBox::sOpenUniqueNotifyBoxes; |
67 | LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate; | ||
68 | |||
69 | 71 | ||
70 | LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates; | ||
71 | |||
72 | LLNotifyBox::LLNotifyBehavior::LLNotifyBehavior(notify_callback_t callback, void* data) : | ||
73 | mCallback(callback), | ||
74 | mData(data) | ||
75 | { | ||
76 | } | ||
77 | 72 | ||
78 | //--------------------------------------------------------------------------- | 73 | //--------------------------------------------------------------------------- |
79 | // LLNotifyBox | 74 | // LLNotifyBox |
80 | //--------------------------------------------------------------------------- | 75 | //--------------------------------------------------------------------------- |
81 | 76 | ||
82 | //static | 77 | //static |
83 | LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, notify_callback_t callback, void *user_data) | 78 | void LLNotifyBox::initClass() |
84 | { | 79 | { |
85 | return showXml(xml_desc, LLStringUtil::format_map_t(), callback, user_data); | 80 | LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify")); |
86 | } | 81 | LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip")); |
87 | |||
88 | 82 | ||
89 | //static | 83 | LLNotifications::instance().getChannel("Notifications")->connectChanged(&LLNotifyBox::onNotification); |
90 | LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args, BOOL is_caution, | 84 | LLNotifications::instance().getChannel("NotificationTips")->connectChanged(&LLNotifyBox::onNotification); |
91 | notify_callback_t callback, void *user_data) | ||
92 | { | ||
93 | // for script permission prompts | ||
94 | LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc); | ||
95 | LLNotifyBox* notify = findExistingNotify(xml_template, args); | ||
96 | if (notify) | ||
97 | { | ||
98 | delete notify->mBehavior; | ||
99 | notify->mBehavior = new LLNotifyBehavior(callback, user_data); | ||
100 | } | ||
101 | else | ||
102 | { | ||
103 | notify = new LLNotifyBox(xml_template, args, callback, user_data, is_caution); | ||
104 | gNotifyBoxView->addChildAtEnd(notify); | ||
105 | notify->moveToBack(); | ||
106 | } | ||
107 | return notify; | ||
108 | } | 85 | } |
109 | 86 | ||
110 | //static | 87 | //static |
111 | LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args, | 88 | bool LLNotifyBox::onNotification(const LLSD& notify) |
112 | notify_callback_t callback, void *user_data) | ||
113 | { | 89 | { |
114 | LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc); | 90 | LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); |
115 | LLNotifyBox* notify = findExistingNotify(xml_template, args); | 91 | |
116 | if (notify) | 92 | if (!notification) return false; |
117 | { | ||
118 | delete notify->mBehavior; | ||
119 | notify->mBehavior = new LLNotifyBehavior(callback, user_data); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | notify = new LLNotifyBox(xml_template, args, callback, user_data); | ||
124 | gNotifyBoxView->addChildAtEnd(notify); | ||
125 | notify->moveToBack(); | ||
126 | } | ||
127 | return notify; | ||
128 | } | ||
129 | 93 | ||
130 | //static | 94 | if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") |
131 | LLNotifyBox* LLNotifyBox::showXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args, | ||
132 | notify_callback_t callback, void *user_data, | ||
133 | const option_list_t& options, | ||
134 | BOOL layout_script_dialog) | ||
135 | { | ||
136 | LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc); | ||
137 | LLNotifyBox* notify = findExistingNotify(xml_template, args); | ||
138 | if (notify) | ||
139 | { | ||
140 | delete notify->mBehavior; | ||
141 | notify->mBehavior = new LLNotifyBehavior(callback, user_data); | ||
142 | } | ||
143 | else | ||
144 | { | 95 | { |
145 | notify = new LLNotifyBox(xml_template, args, callback, user_data, FALSE, options, layout_script_dialog); | 96 | //bring existing notification to top |
146 | gNotifyBoxView->addChild(notify); | 97 | LLNotifyBox* boxp = LLNotifyBox::getInstance(notification->getID()); |
147 | } | 98 | if (boxp && !boxp->isDead()) |
148 | return notify; | 99 | { |
149 | } | 100 | gNotifyBoxView->showOnly(boxp); |
101 | } | ||
102 | else | ||
103 | { | ||
104 | bool is_script_dialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup"); | ||
105 | LLNotifyBox* notify_box = new LLNotifyBox( | ||
106 | notification, | ||
107 | is_script_dialog); //layout_script_dialog); | ||
150 | 108 | ||
151 | //static | 109 | gNotifyBoxView->addChild(notify_box); |
152 | LLNotifyBox* LLNotifyBox::findExistingNotify(LLPointer<LLNotifyBoxTemplate> notify_template, const LLStringUtil::format_map_t &args) | 110 | } |
153 | { | 111 | } |
154 | if(notify_template->mUnique) | 112 | else if (notify["sigtype"].asString() == "delete") |
155 | { | 113 | { |
156 | std::string message = notify_template->mMessage; | 114 | LLNotifyBox* boxp = LLNotifyBox::getInstance(notification->getID()); |
157 | format(message, args); | 115 | if (boxp && !boxp->isDead()) |
158 | unique_map_t::iterator found_it = sOpenUniqueNotifyBoxes.find(notify_template->mLabel + message); | ||
159 | if (found_it != sOpenUniqueNotifyBoxes.end()) | ||
160 | { | 116 | { |
161 | return found_it->second; | 117 | boxp->close(); |
162 | } | 118 | } |
163 | } | 119 | } |
164 | return NULL; | ||
165 | } | ||
166 | 120 | ||
167 | //static | 121 | return false; |
168 | void LLNotifyBox::cleanup() | ||
169 | { | ||
170 | sDefaultTemplate = NULL; | ||
171 | } | 122 | } |
172 | 123 | ||
173 | //--------------------------------------------------------------------------- | 124 | //--------------------------------------------------------------------------- |
174 | 125 | LLNotifyBox::LLNotifyBox(LLNotificationPtr notification, | |
175 | LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLStringUtil::format_map_t& args, | ||
176 | notify_callback_t callback, void* user_data, BOOL is_caution, | ||
177 | const option_list_t& extra_options, | ||
178 | BOOL layout_script_dialog) | 126 | BOOL layout_script_dialog) |
179 | : LLPanel(xml_template->mLabel, LLRect(), BORDER_NO), | 127 | : LLPanel(notification->getName(), LLRect(), BORDER_NO), |
180 | LLEventTimer(xml_template->mDuration), | 128 | LLEventTimer(notification->getExpiration() == LLDate() |
181 | mIsTip(FALSE), | 129 | ? LLDate(LLDate::now().secondsSinceEpoch() + (F64)gSavedSettings.getF32("NotifyTipDuration")) |
130 | : notification->getExpiration()), | ||
131 | LLInstanceTracker<LLNotifyBox, LLUUID>(notification->getID()), | ||
132 | mNotification(notification), | ||
133 | mIsTip(notification->getType() == "notifytip"), | ||
182 | mAnimating(TRUE), | 134 | mAnimating(TRUE), |
183 | mUnique(xml_template->mUnique), | ||
184 | mNextBtn(NULL), | 135 | mNextBtn(NULL), |
185 | mBehavior(new LLNotifyBehavior(callback, user_data)), | ||
186 | mNumOptions(0), | 136 | mNumOptions(0), |
187 | mDefaultOption(0) | 137 | mNumButtons(0), |
138 | mAddedDefaultBtn(FALSE), | ||
139 | mLayoutScriptDialog(layout_script_dialog) | ||
188 | { | 140 | { |
189 | // clicking on a button does not steal current focus | 141 | // clicking on a button does not steal current focus |
190 | setIsChrome(TRUE); | 142 | setIsChrome(TRUE); |
@@ -192,45 +144,33 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt | |||
192 | // class init | 144 | // class init |
193 | if (!sFont) | 145 | if (!sFont) |
194 | { | 146 | { |
195 | sFont = LLFontGL::sSansSerif; | 147 | sFont = LLFontGL::getFontSansSerif(); |
196 | sFontSmall = LLFontGL::sSansSerifSmall; | 148 | sFontSmall = LLFontGL::getFontSansSerifSmall(); |
197 | } | 149 | } |
198 | 150 | ||
199 | // setup paramaters | 151 | // setup paramaters |
200 | 152 | mMessage = notification->getMessage(); | |
201 | mMessage = xml_template->mMessage; | ||
202 | format(mMessage, args); | ||
203 | |||
204 | // use name + formatted text as unique key | ||
205 | if (mUnique) | ||
206 | { | ||
207 | sOpenUniqueNotifyBoxes[xml_template->mLabel + mMessage] = this; | ||
208 | } | ||
209 | |||
210 | option_list_t options = xml_template->mOptions; | ||
211 | options.insert(options.end(), extra_options.begin(), extra_options.end()); | ||
212 | 153 | ||
213 | // initialize | 154 | // initialize |
214 | |||
215 | mIsTip = xml_template->mIsTip; | ||
216 | setFocusRoot(!mIsTip); | 155 | setFocusRoot(!mIsTip); |
217 | 156 | ||
218 | // caution flag can be set explicitly by specifying it in the | 157 | // caution flag can be set explicitly by specifying it in the |
219 | // call to the c'tor, or it can be set implicitly if the | 158 | // notification payload, or it can be set implicitly if the |
220 | // notify xml template specifies that it is a caution | 159 | // notify xml template specifies that it is a caution |
221 | // | 160 | // |
222 | // tip-style notification handle 'caution' differently - | 161 | // tip-style notification handle 'caution' differently - |
223 | // they display the tip in a different color | 162 | // they display the tip in a different color |
224 | mIsCaution = (xml_template->mIsCaution || is_caution); | 163 | mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH; |
225 | 164 | ||
226 | // Don't animate if behind other windows | 165 | // Only animate first window |
227 | if( gNotifyBoxView->getChildCount() > 0 ) | 166 | if( gNotifyBoxView->getChildCount() > 0 ) |
228 | mAnimating = FALSE; | 167 | mAnimating = FALSE; |
229 | else | 168 | else |
230 | mAnimating = TRUE; | 169 | mAnimating = TRUE; |
231 | 170 | ||
232 | mNumOptions = options.size(); | 171 | LLNotificationFormPtr form(notification->getForm()); |
233 | mDefaultOption = xml_template->mDefaultOption; | 172 | |
173 | mNumOptions = form->getNumElements(); | ||
234 | 174 | ||
235 | LLRect rect = mIsTip ? getNotifyTipRect(mMessage) | 175 | LLRect rect = mIsTip ? getNotifyTipRect(mMessage) |
236 | : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution); | 176 | : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution); |
@@ -284,7 +224,7 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt | |||
284 | caution_box->setColor(gColors.getColor("NotifyCautionWarnColor")); | 224 | caution_box->setColor(gColors.getColor("NotifyCautionWarnColor")); |
285 | caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor")); | 225 | caution_box->setBackgroundColor(gColors.getColor("NotifyCautionBoxColor")); |
286 | caution_box->setBorderVisible(FALSE); | 226 | caution_box->setBorderVisible(FALSE); |
287 | caution_box->setWrappedText(LLNotifyBox::getTemplateMessage("ScriptQuestionCautionWarn")); | 227 | caution_box->setWrappedText(notification->getMessage()); |
288 | 228 | ||
289 | addChild(caution_box); | 229 | addChild(caution_box); |
290 | 230 | ||
@@ -292,36 +232,38 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt | |||
292 | // it appears below the caution textbox | 232 | // it appears below the caution textbox |
293 | y = y - caution_height; | 233 | y = y - caution_height; |
294 | } | 234 | } |
235 | else | ||
236 | { | ||
295 | 237 | ||
296 | const S32 BOTTOM_PAD = VPAD * 3; | 238 | const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD); |
297 | const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD); | 239 | |
298 | 240 | // Tokenization on \n is handled by LLTextBox | |
299 | // Tokenization on \n is handled by LLTextBox | 241 | |
300 | 242 | const S32 MAX_LENGTH = 512 + 20 + | |
301 | const S32 MAX_LENGTH = 512 + 20 + | 243 | DB_FIRST_NAME_BUF_SIZE + |
302 | DB_FIRST_NAME_BUF_SIZE + | 244 | DB_LAST_NAME_BUF_SIZE + |
303 | DB_LAST_NAME_BUF_SIZE + | 245 | DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title. |
304 | DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title. | 246 | |
305 | 247 | text = new LLTextEditor(std::string("box"), | |
306 | text = new LLTextEditor(std::string("box"), | 248 | LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), |
307 | LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), | 249 | MAX_LENGTH, |
308 | MAX_LENGTH, | 250 | mMessage, |
309 | mMessage, | 251 | sFont, |
310 | sFont, | 252 | FALSE); |
311 | FALSE); | 253 | text->setWordWrap(TRUE); |
312 | text->setWordWrap(TRUE); | 254 | text->setTabStop(FALSE); |
313 | text->setTabStop(FALSE); | 255 | text->setMouseOpaque(FALSE); |
314 | text->setMouseOpaque(FALSE); | 256 | text->setBorderVisible(FALSE); |
315 | text->setBorderVisible(FALSE); | 257 | text->setTakesNonScrollClicks(FALSE); |
316 | text->setTakesNonScrollClicks(FALSE); | 258 | text->setHideScrollbarForShortDocs(TRUE); |
317 | text->setHideScrollbarForShortDocs(TRUE); | 259 | text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually |
318 | text->setReadOnlyBgColor ( LLColor4::transparent ); // the background color of the box is manually | 260 | // rendered under the text box, therefore we want |
319 | // rendered under the text box, therefore we want | 261 | // the actual text box to be transparent |
320 | // the actual text box to be transparent | 262 | text->setReadOnlyFgColor ( gColors.getColor("NotifyTextColor") ); |
321 | text->setReadOnlyFgColor ( gColors.getColor("NotifyTextColor") ); | 263 | text->setEnabled(FALSE); // makes it read-only |
322 | text->setEnabled(FALSE); // makes it read-only | 264 | text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard) |
323 | text->setTabStop(FALSE); // can't tab to it (may be a problem for scrolling via keyboard) | 265 | addChild(text); |
324 | addChild(text); | 266 | } |
325 | 267 | ||
326 | if (mIsTip) | 268 | if (mIsTip) |
327 | { | 269 | { |
@@ -346,57 +288,22 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt | |||
346 | addChild(btn); | 288 | addChild(btn); |
347 | mNextBtn = btn; | 289 | mNextBtn = btn; |
348 | 290 | ||
349 | // make caution notification buttons slightly narrower | ||
350 | // so that 3 of them can fit without overlapping the "next" button | ||
351 | S32 btn_width = mIsCaution? 84 : 90; | ||
352 | LLRect btn_rect; | ||
353 | |||
354 | for (S32 i = 0; i < mNumOptions; i++) | 291 | for (S32 i = 0; i < mNumOptions; i++) |
355 | { | 292 | { |
356 | S32 index = i; | ||
357 | S32 btn_height= BTN_HEIGHT; | ||
358 | const LLFontGL* font = sFont; | ||
359 | S32 ignore_pad = 0; | ||
360 | 293 | ||
361 | if (layout_script_dialog) | 294 | LLSD form_element = form->getElement(i); |
295 | if (form_element["type"].asString() != "button") | ||
362 | { | 296 | { |
363 | // Add two "blank" option spaces, before the "Ignore" button | 297 | continue; |
364 | index = i + 2; | ||
365 | if (i == 0) | ||
366 | { | ||
367 | // Ignore button is smaller, less wide | ||
368 | btn_height = BTN_HEIGHT_SMALL; | ||
369 | font = sFontSmall; | ||
370 | ignore_pad = 10; | ||
371 | } | ||
372 | } | ||
373 | |||
374 | btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad, | ||
375 | BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD), | ||
376 | btn_width - 2*ignore_pad, | ||
377 | btn_height); | ||
378 | |||
379 | InstanceAndS32* userdata = new InstanceAndS32; | ||
380 | userdata->mSelf = this; | ||
381 | userdata->mButton = i; | ||
382 | |||
383 | mBtnCallbackData.push_back(userdata); | ||
384 | |||
385 | btn = new LLButton(options[i], btn_rect, LLStringUtil::null, onClickButton, userdata); | ||
386 | btn->setFont(font); | ||
387 | |||
388 | if (mIsCaution) | ||
389 | { | ||
390 | btn->setImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); | ||
391 | btn->setDisabledImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); | ||
392 | } | 298 | } |
393 | 299 | ||
394 | addChild(btn, -1); | 300 | addButton(form_element["name"].asString(), TRUE, form_element["default"].asBoolean()); |
301 | } | ||
395 | 302 | ||
396 | if (i == mDefaultOption) | 303 | if (mNumButtons == 0) |
397 | { | 304 | { |
398 | setDefaultBtn(btn); | 305 | addButton("OK", FALSE, TRUE); |
399 | } | 306 | mAddedDefaultBtn = TRUE; |
400 | } | 307 | } |
401 | 308 | ||
402 | sNotifyBoxCount++; | 309 | sNotifyBoxCount++; |
@@ -413,27 +320,76 @@ LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLSt | |||
413 | // virtual | 320 | // virtual |
414 | LLNotifyBox::~LLNotifyBox() | 321 | LLNotifyBox::~LLNotifyBox() |
415 | { | 322 | { |
416 | delete mBehavior; | ||
417 | mBehavior = NULL; | ||
418 | |||
419 | std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); | 323 | std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); |
324 | } | ||
325 | |||
326 | // virtual | ||
327 | LLButton* LLNotifyBox::addButton(const std::string& name, BOOL is_option, BOOL is_default) | ||
328 | { | ||
329 | // make caution notification buttons slightly narrower | ||
330 | // so that 3 of them can fit without overlapping the "next" button | ||
331 | S32 btn_width = mIsCaution? 84 : 90; | ||
332 | |||
333 | LLRect btn_rect; | ||
334 | LLButton* btn; | ||
335 | S32 btn_height= BTN_HEIGHT; | ||
336 | const LLFontGL* font = sFont; | ||
337 | S32 ignore_pad = 0; | ||
338 | S32 button_index = mNumButtons; | ||
339 | S32 index = button_index; | ||
340 | S32 x = (HPAD * 4) + 32; | ||
341 | |||
342 | if (mLayoutScriptDialog) | ||
343 | { | ||
344 | // Add two "blank" option spaces, before the "Ignore" button | ||
345 | index = button_index + 2; | ||
346 | if (button_index == 0) | ||
347 | { | ||
348 | // Ignore button is smaller, less wide | ||
349 | btn_height = BTN_HEIGHT_SMALL; | ||
350 | font = sFontSmall; | ||
351 | ignore_pad = 10; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad, | ||
356 | BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD), | ||
357 | btn_width - 2*ignore_pad, | ||
358 | btn_height); | ||
359 | |||
360 | InstanceAndS32* userdata = new InstanceAndS32; | ||
361 | userdata->mSelf = this; | ||
362 | userdata->mButtonName = is_option ? name : ""; | ||
363 | |||
364 | mBtnCallbackData.push_back(userdata); | ||
365 | |||
420 | 366 | ||
421 | if (mUnique) | 367 | btn = new LLButton(name, btn_rect, "", onClickButton, userdata); |
368 | btn->setFont(font); | ||
369 | |||
370 | if (mIsCaution) | ||
371 | { | ||
372 | btn->setImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); | ||
373 | btn->setDisabledImageColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); | ||
374 | } | ||
375 | |||
376 | addChild(btn, -1); | ||
377 | |||
378 | if (is_default) | ||
422 | { | 379 | { |
423 | sOpenUniqueNotifyBoxes.erase(getName() + mMessage); | 380 | setDefaultBtn(btn); |
424 | } | 381 | } |
382 | |||
383 | mNumButtons++; | ||
384 | return btn; | ||
425 | } | 385 | } |
426 | 386 | ||
427 | // virtual | ||
428 | BOOL LLNotifyBox::handleMouseUp(S32 x, S32 y, MASK mask) | 387 | BOOL LLNotifyBox::handleMouseUp(S32 x, S32 y, MASK mask) |
429 | { | 388 | { |
430 | if (mIsTip) | 389 | if (mIsTip) |
431 | { | 390 | { |
432 | if (mBehavior->mCallback) | 391 | mNotification->respond(mNotification->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON)); |
433 | { | 392 | |
434 | mBehavior->mCallback(0, mBehavior->mData); | ||
435 | mBehavior->mCallback = NULL; // Notification callbacks only expect to be called once ever | ||
436 | } | ||
437 | close(); | 393 | close(); |
438 | return TRUE; | 394 | return TRUE; |
439 | } | 395 | } |
@@ -758,24 +714,14 @@ void LLNotifyBox::onClickButton(void* data) | |||
758 | { | 714 | { |
759 | InstanceAndS32* self_and_button = (InstanceAndS32*)data; | 715 | InstanceAndS32* self_and_button = (InstanceAndS32*)data; |
760 | LLNotifyBox* self = self_and_button->mSelf; | 716 | LLNotifyBox* self = self_and_button->mSelf; |
761 | S32 button = self_and_button->mButton; | 717 | std::string button_name = self_and_button->mButtonName; |
762 | 718 | ||
763 | // for caution notifications, check if the last button in the prompt was clicked | 719 | LLSD response = self->mNotification->getResponseTemplate(); |
764 | // unless it is the only button, in which case it will just be an "OK" button | 720 | if (!self->mAddedDefaultBtn && !button_name.empty()) |
765 | if ((self->mIsCaution) && (button > 0) && (button == (self->mNumOptions - 1))) | ||
766 | { | 721 | { |
767 | // show an alert dialog containing more explanation about the debit permission | 722 | response[button_name] = true; |
768 | LLAlertDialog::showXml("DebitPermissionDetails"); | ||
769 | |||
770 | // keep this notification open | ||
771 | return; | ||
772 | } | ||
773 | |||
774 | if (self->mBehavior->mCallback) | ||
775 | { | ||
776 | self->mBehavior->mCallback(button, self->mBehavior->mData); | ||
777 | self->mBehavior->mCallback = NULL; // Notification callbacks only expect to be called once ever | ||
778 | } | 723 | } |
724 | self->mNotification->respond(response); | ||
779 | 725 | ||
780 | self->close(); | 726 | self->close(); |
781 | } | 727 | } |
@@ -788,174 +734,6 @@ void LLNotifyBox::onClickNext(void* data) | |||
788 | self->moveToBack(true); | 734 | self->moveToBack(true); |
789 | } | 735 | } |
790 | 736 | ||
791 | // static | ||
792 | LLPointer<LLNotifyBoxTemplate> LLNotifyBox::getTemplate(const std::string& xml_desc) | ||
793 | { | ||
794 | // get template | ||
795 | |||
796 | if (!sDefaultTemplate) | ||
797 | { | ||
798 | // default template is non-unique, of course | ||
799 | sDefaultTemplate = new LLNotifyBoxTemplate(FALSE, gSavedSettings.getF32("NotifyTipDuration")); | ||
800 | sDefaultTemplate->addOption("OK", FALSE); | ||
801 | } | ||
802 | |||
803 | LLPointer<LLNotifyBoxTemplate> xml_template; | ||
804 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | ||
805 | if (iter != sNotifyTemplates.end()) | ||
806 | { | ||
807 | xml_template = iter->second; | ||
808 | } | ||
809 | else | ||
810 | { | ||
811 | std::string tmsg = "[Notification template not found:\n " + xml_desc + " ]"; | ||
812 | sDefaultTemplate->setMessage(tmsg); | ||
813 | xml_template = sDefaultTemplate; | ||
814 | } | ||
815 | |||
816 | return xml_template; | ||
817 | } | ||
818 | |||
819 | //----------------------------------------------------------------------------- | ||
820 | |||
821 | //static | ||
822 | const std::string LLNotifyBox::getTemplateMessage(const std::string& xml_desc, const LLStringUtil::format_map_t& args) | ||
823 | { | ||
824 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | ||
825 | if (iter != sNotifyTemplates.end()) | ||
826 | { | ||
827 | std::string message = iter->second->mMessage; | ||
828 | format(message, args); | ||
829 | return message; | ||
830 | } | ||
831 | else | ||
832 | { | ||
833 | return xml_desc; | ||
834 | } | ||
835 | } | ||
836 | |||
837 | //static | ||
838 | const std::string LLNotifyBox::getTemplateMessage(const std::string& xml_desc) | ||
839 | { | ||
840 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | ||
841 | if (iter != sNotifyTemplates.end()) | ||
842 | { | ||
843 | return iter->second->mMessage; | ||
844 | } | ||
845 | else | ||
846 | { | ||
847 | return xml_desc; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | // method to check whether a given notify template show as a caution or not | ||
852 | BOOL LLNotifyBox::getTemplateIsCaution(const std::string& xml_desc) | ||
853 | { | ||
854 | BOOL is_caution = FALSE; | ||
855 | |||
856 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | ||
857 | if (iter != sNotifyTemplates.end()) | ||
858 | { | ||
859 | is_caution = iter->second->mIsCaution; | ||
860 | } | ||
861 | |||
862 | return is_caution; | ||
863 | } | ||
864 | |||
865 | //static | ||
866 | bool LLNotifyBox::parseNotify(const std::string& xml_filename) | ||
867 | { | ||
868 | LLXMLNodePtr root; | ||
869 | |||
870 | BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); | ||
871 | |||
872 | if (!success || root.isNull() || !root->hasName( "notifications" )) | ||
873 | { | ||
874 | llerrs << "Problem reading UI Notify file: " << xml_filename << llendl; | ||
875 | return false; | ||
876 | } | ||
877 | |||
878 | for (LLXMLNode* notify = root->getFirstChild(); | ||
879 | notify != NULL; notify = notify->getNextSibling()) | ||
880 | { | ||
881 | if (!notify->hasName("notify")) | ||
882 | { | ||
883 | continue; | ||
884 | } | ||
885 | |||
886 | BOOL unique = FALSE; | ||
887 | notify->getAttributeBOOL("unique", unique); | ||
888 | |||
889 | F32 duration = gSavedSettings.getF32("NotifyTipDuration"); | ||
890 | notify->getAttributeF32("duration", duration); | ||
891 | |||
892 | LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate(unique, duration); | ||
893 | |||
894 | // label= | ||
895 | std::string notify_name; | ||
896 | if (notify->getAttributeString("name", notify_name)) | ||
897 | { | ||
898 | xml_template->mLabel = notify_name; | ||
899 | } | ||
900 | else | ||
901 | { | ||
902 | llwarns << "Unable to parse notify with no name" << llendl; | ||
903 | continue; | ||
904 | } | ||
905 | // modal= | ||
906 | BOOL tip; | ||
907 | if (notify->getAttributeBOOL("tip", tip)) | ||
908 | { | ||
909 | xml_template->mIsTip = tip; | ||
910 | } | ||
911 | |||
912 | // parse a bool attribute named "caution" to determine | ||
913 | // whether this notification gets cautionary special handling | ||
914 | BOOL caution = FALSE; | ||
915 | if (notify->getAttributeBOOL("caution", caution)) | ||
916 | { | ||
917 | if (xml_template) | ||
918 | { | ||
919 | xml_template->mIsCaution = caution; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | |||
924 | S32 btn_idx = 0; | ||
925 | for (LLXMLNode* child = notify->getFirstChild(); | ||
926 | child != NULL; child = child->getNextSibling()) | ||
927 | { | ||
928 | // <message> | ||
929 | if (child->hasName("message")) | ||
930 | { | ||
931 | xml_template->mMessage = child->getTextContents(); | ||
932 | } | ||
933 | |||
934 | // <option> | ||
935 | if (child->hasName("option")) | ||
936 | { | ||
937 | std::string label = child->getValue(); | ||
938 | BOOL is_default = FALSE; | ||
939 | child->getAttributeBOOL("default", is_default); | ||
940 | std::string ignore_text; | ||
941 | if (!child->getAttributeString("ignore", ignore_text)) | ||
942 | { | ||
943 | ignore_text = label; | ||
944 | } | ||
945 | xml_template->addOption(label, is_default); | ||
946 | btn_idx++; | ||
947 | } | ||
948 | } | ||
949 | |||
950 | //*TODO:translate | ||
951 | if (xml_template->mOptions.empty()) | ||
952 | { | ||
953 | xml_template->addOption("OK", FALSE); | ||
954 | } | ||
955 | sNotifyTemplates[xml_template->mLabel] = xml_template; | ||
956 | } | ||
957 | return true; | ||
958 | } | ||
959 | 737 | ||
960 | LLNotifyBoxView::LLNotifyBoxView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows) | 738 | LLNotifyBoxView::LLNotifyBoxView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows) |
961 | : LLUICtrl(name,rect,mouse_opaque,NULL,NULL,follows) | 739 | : LLUICtrl(name,rect,mouse_opaque,NULL,NULL,follows) |
@@ -1032,7 +810,7 @@ void LLNotifyBoxView::purgeMessagesMatching(const Matcher& matcher) | |||
1032 | } | 810 | } |
1033 | 811 | ||
1034 | LLNotifyBox* notification = (LLNotifyBox*)*iter; | 812 | LLNotifyBox* notification = (LLNotifyBox*)*iter; |
1035 | if(matcher.matches(notification->getNotifyCallback(), notification->getUserData())) | 813 | if(matcher.matches(notification->getNotification())) |
1036 | { | 814 | { |
1037 | removeChild(notification); | 815 | removeChild(notification); |
1038 | } | 816 | } |