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.cpp215
1 files changed, 159 insertions, 56 deletions
diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp
index 7822d00..4f5c64b 100644
--- a/linden/indra/newview/llnotify.cpp
+++ b/linden/indra/newview/llnotify.cpp
@@ -58,48 +58,106 @@ const F32 ANIMATION_TIME = 0.333f;
58S32 LLNotifyBox::sNotifyBoxCount = 0; 58S32 LLNotifyBox::sNotifyBoxCount = 0;
59const LLFontGL* LLNotifyBox::sFont = NULL; 59const LLFontGL* LLNotifyBox::sFont = NULL;
60const LLFontGL* LLNotifyBox::sFontSmall = NULL; 60const LLFontGL* LLNotifyBox::sFontSmall = NULL;
61std::map<LLString, LLNotifyBox*> LLNotifyBox::sOpenUniqueNotifyBoxes;
62LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate;
63
61 64
62LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates; 65LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates;
63 66
67LLNotifyBox::LLNotifyBehavior::LLNotifyBehavior(notify_callback_t callback, void* data) :
68 mCallback(callback),
69 mData(data)
70{
71}
72
64//--------------------------------------------------------------------------- 73//---------------------------------------------------------------------------
65// LLNotifyBox 74// LLNotifyBox
66//--------------------------------------------------------------------------- 75//---------------------------------------------------------------------------
67 76
68//static 77//static
69void LLNotifyBox::showXml( const LLString& xml_desc, notify_callback_t callback, void *user_data) 78LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, notify_callback_t callback, void *user_data)
70{ 79{
71 return showXml(xml_desc, LLString::format_map_t(), callback, user_data); 80 return showXml(xml_desc, LLString::format_map_t(), callback, user_data);
72} 81}
73 82
74 83
75//static 84//static
76void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution, 85LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution,
77 notify_callback_t callback, void *user_data) 86 notify_callback_t callback, void *user_data)
78{ 87{
79 // for script permission prompts 88 // for script permission prompts
80 LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data, is_caution); 89 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
81 gNotifyBoxView->addChild(notify); 90 LLNotifyBox* notify = findExistingNotify(xml_template, args);
91 if (notify)
92 {
93 delete notify->mBehavior;
94 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
95 }
96 else
97 {
98 LLNotifyBox* notify = new LLNotifyBox(xml_template, args, callback, user_data, is_caution);
99 gNotifyBoxView->addChildAtEnd(notify);
100 notify->moveToBack();
101 }
102 return notify;
82} 103}
83 104
84//static 105//static
85void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, 106LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args,
86 notify_callback_t callback, void *user_data) 107 notify_callback_t callback, void *user_data)
87{ 108{
88 LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data); 109 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
89 gNotifyBoxView->addChild(notify); 110 LLNotifyBox* notify = findExistingNotify(xml_template, args);
111 if (notify)
112 {
113 delete notify->mBehavior;
114 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
115 }
116 else
117 {
118 notify = new LLNotifyBox(xml_template, args, callback, user_data);
119 gNotifyBoxView->addChildAtEnd(notify);
120 notify->moveToBack();
121 }
122 return notify;
90} 123}
91 124
92//static 125//static
93void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, 126LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args,
94 notify_callback_t callback, void *user_data, 127 notify_callback_t callback, void *user_data,
95 const option_list_t& options, 128 const option_list_t& options,
96 BOOL layout_script_dialog) 129 BOOL layout_script_dialog)
97{ 130{
98 LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data, FALSE, options, layout_script_dialog); 131 LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc);
99 gNotifyBoxView->addChild(notify); 132 LLNotifyBox* notify = findExistingNotify(xml_template, args);
133 if (notify)
134 {
135 delete notify->mBehavior;
136 notify->mBehavior = new LLNotifyBehavior(callback, user_data);
137 }
138 else
139 {
140 notify = new LLNotifyBox(xml_template, args, callback, user_data, FALSE, options, layout_script_dialog);
141 gNotifyBoxView->addChild(notify);
142 }
143 return notify;
100} 144}
101 145
102LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate; 146//static
147LLNotifyBox* LLNotifyBox::findExistingNotify(LLPointer<LLNotifyBoxTemplate> notify_template, const LLString::format_map_t &args)
148{
149 if(notify_template->mUnique)
150 {
151 LLString message = notify_template->mMessage;
152 LLAlertDialog::format(message, args);
153 unique_map_t::iterator found_it = sOpenUniqueNotifyBoxes.find(notify_template->mLabel + message);
154 if (found_it != sOpenUniqueNotifyBoxes.end())
155 {
156 return found_it->second;
157 }
158 }
159 return NULL;
160}
103 161
104void LLNotifyBox::cleanup() 162void LLNotifyBox::cleanup()
105{ 163{
@@ -108,18 +166,17 @@ void LLNotifyBox::cleanup()
108 166
109//--------------------------------------------------------------------------- 167//---------------------------------------------------------------------------
110 168
111LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& args, 169LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLString::format_map_t& args,
112 notify_callback_t callback, void* user_data, BOOL is_caution, 170 notify_callback_t callback, void* user_data, BOOL is_caution,
113 const option_list_t& extra_options, 171 const option_list_t& extra_options,
114 BOOL layout_script_dialog) 172 BOOL layout_script_dialog)
115 : LLPanel("notify", LLRect(), BORDER_NO), 173 : LLPanel(xml_template->mLabel, LLRect(), BORDER_NO),
116 LLEventTimer(gSavedSettings.getF32("NotifyTipDuration")), 174 LLEventTimer(xml_template->mDuration),
117 mIsTip(FALSE), 175 mIsTip(FALSE),
118 mAnimating(TRUE), 176 mAnimating(TRUE),
119 mTimer(), 177 mUnique(xml_template->mUnique),
120 mNextBtn(NULL), 178 mNextBtn(NULL),
121 mCallback(callback), 179 mBehavior(new LLNotifyBehavior(callback, user_data)),
122 mData(user_data),
123 mNumOptions(0), 180 mNumOptions(0),
124 mDefaultOption(0) 181 mDefaultOption(0)
125{ 182{
@@ -133,31 +190,17 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
133 sFontSmall = LLFontGL::sSansSerifSmall; 190 sFontSmall = LLFontGL::sSansSerifSmall;
134 } 191 }
135 192
136 // get template 193 // setup paramaters
137
138 if (!sDefaultTemplate)
139 {
140 sDefaultTemplate = new LLNotifyBoxTemplate;
141 }
142 194
143 LLPointer<LLNotifyBoxTemplate> xml_template; 195 mMessage = xml_template->mMessage;
144 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); 196 LLAlertDialog::format(mMessage, args);
145 if (iter != sNotifyTemplates.end()) 197
146 { 198 // use name + formatted text as unique key
147 xml_template = iter->second; 199 if (mUnique)
148 }
149 else
150 { 200 {
151 LLString tmsg = "[Notification template not found:\n " + xml_desc + " ]"; 201 sOpenUniqueNotifyBoxes[xml_template->mLabel + mMessage] = this;
152 sDefaultTemplate->setMessage(tmsg);
153 xml_template = sDefaultTemplate;
154 } 202 }
155 203
156 // setup paramaters
157
158 LLString message = xml_template->mMessage;
159 LLAlertDialog::format(message, args);
160
161 option_list_t options = xml_template->mOptions; 204 option_list_t options = xml_template->mOptions;
162 options.insert(options.end(), extra_options.begin(), extra_options.end()); 205 options.insert(options.end(), extra_options.begin(), extra_options.end());
163 206
@@ -175,13 +218,16 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
175 // account for the special layout of a tip notification) 218 // account for the special layout of a tip notification)
176 mIsCaution = ((xml_template->mIsCaution | is_caution) && (!mIsTip)); 219 mIsCaution = ((xml_template->mIsCaution | is_caution) && (!mIsTip));
177 220
178 mAnimating = TRUE; 221 // Don't animate if behind other windows
179 mCallback = callback; 222 if( gNotifyBoxView->getChildCount() > 0 )
180 mData = user_data; 223 mAnimating = FALSE;
224 else
225 mAnimating = TRUE;
226
181 mNumOptions = options.size(); 227 mNumOptions = options.size();
182 mDefaultOption = xml_template->mDefaultOption; 228 mDefaultOption = xml_template->mDefaultOption;
183 229
184 LLRect rect = mIsTip ? getNotifyTipRect(message) 230 LLRect rect = mIsTip ? getNotifyTipRect(mMessage)
185 : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution); 231 : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution);
186 setRect(rect); 232 setRect(rect);
187 setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT)); 233 setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
@@ -255,7 +301,7 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
255 text = new LLTextEditor("box", 301 text = new LLTextEditor("box",
256 LLRect(x, y, mRect.getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), 302 LLRect(x, y, mRect.getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16),
257 MAX_LENGTH, 303 MAX_LENGTH,
258 message, 304 mMessage,
259 sFont, 305 sFont,
260 FALSE); 306 FALSE);
261 text->setWordWrap(TRUE); 307 text->setWordWrap(TRUE);
@@ -275,15 +321,15 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
275 if (mIsTip) 321 if (mIsTip)
276 { 322 {
277 // TODO: Make a separate archive for these. 323 // TODO: Make a separate archive for these.
278 LLChat chat(message); 324 LLChat chat(mMessage);
279 chat.mSourceType = CHAT_SOURCE_SYSTEM; 325 chat.mSourceType = CHAT_SOURCE_SYSTEM;
280 gFloaterChat->addChatHistory(chat); 326 LLFloaterChat::getInstance(LLSD())->addChatHistory(chat);
281 } 327 }
282 else 328 else
283 { 329 {
284 LLButton* btn; 330 LLButton* btn;
285 btn = new LLButton("next", 331 btn = new LLButton("next",
286 LLRect(mRect.getWidth()-24, BOTTOM_PAD+16, mRect.getWidth()-8, BOTTOM_PAD), 332 LLRect(mRect.getWidth()-18, BOTTOM_PAD+16, mRect.getWidth()-2, BOTTOM_PAD+2),
287 "notify_next.tga", 333 "notify_next.tga",
288 "notify_next.tga", 334 "notify_next.tga",
289 "", 335 "",
@@ -328,7 +374,7 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
328 userdata->mSelf = this; 374 userdata->mSelf = this;
329 userdata->mButton = i; 375 userdata->mButton = i;
330 376
331 mBtnCallbackData.put(userdata); 377 mBtnCallbackData.push_back(userdata);
332 378
333 btn = new LLButton(options[i], btn_rect, "", onClickButton, userdata); 379 btn = new LLButton(options[i], btn_rect, "", onClickButton, userdata);
334 btn->setFont(font); 380 btn->setFont(font);
@@ -361,10 +407,14 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t&
361// virtual 407// virtual
362LLNotifyBox::~LLNotifyBox() 408LLNotifyBox::~LLNotifyBox()
363{ 409{
364 S32 count = mBtnCallbackData.count(); 410 delete mBehavior;
365 for (S32 i = 0; i < count; i++) 411 mBehavior = NULL;
412
413 std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
414
415 if (mUnique)
366 { 416 {
367 delete mBtnCallbackData[i]; 417 sOpenUniqueNotifyBoxes.erase(mName + mMessage);
368 } 418 }
369} 419}
370 420
@@ -398,7 +448,7 @@ BOOL LLNotifyBox::handleRightMouseDown(S32 x, S32 y, MASK mask)
398// virtual 448// virtual
399void LLNotifyBox::draw() 449void LLNotifyBox::draw()
400{ 450{
401 F32 display_time = mTimer.getElapsedTimeF32(); 451 F32 display_time = mAnimateTimer.getElapsedTimeF32();
402 452
403 if (mAnimating && display_time < ANIMATION_TIME) 453 if (mAnimating && display_time < ANIMATION_TIME)
404 { 454 {
@@ -492,7 +542,10 @@ void LLNotifyBox::close()
492 gNotifyBoxView->showOnly(front); 542 gNotifyBoxView->showOnly(front);
493 // we're assuming that close is only called by user action (for non-tips), 543 // we're assuming that close is only called by user action (for non-tips),
494 // so we then give focus to the next close button 544 // so we then give focus to the next close button
495 front->mDefaultBtn->setFocus(TRUE); 545 if (front->mDefaultBtn)
546 {
547 front->mDefaultBtn->setFocus(TRUE);
548 }
496 gFocusMgr.triggerFocusFlash(); // TODO it's ugly to call this here 549 gFocusMgr.triggerFocusFlash(); // TODO it's ugly to call this here
497 } 550 }
498 } 551 }
@@ -681,9 +734,9 @@ void LLNotifyBox::onClickButton(void* data)
681 return; 734 return;
682 } 735 }
683 736
684 if (self->mCallback) 737 if (self->mBehavior->mCallback)
685 { 738 {
686 self->mCallback(button, self->mData); 739 self->mBehavior->mCallback(button, self->mBehavior->mData);
687 } 740 }
688 741
689 self->close(); 742 self->close();
@@ -697,10 +750,54 @@ void LLNotifyBox::onClickNext(void* data)
697 self->moveToBack(); 750 self->moveToBack();
698} 751}
699 752
753// static
754LLPointer<LLNotifyBoxTemplate> LLNotifyBox::getTemplate(const LLString& xml_desc)
755{
756 // get template
757
758 if (!sDefaultTemplate)
759 {
760 // default template is non-unique, of course
761 sDefaultTemplate = new LLNotifyBoxTemplate(FALSE, gSavedSettings.getF32("NotifyTipDuration"));
762 sDefaultTemplate->addOption("OK", FALSE);
763 }
764
765 LLPointer<LLNotifyBoxTemplate> xml_template;
766 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
767 if (iter != sNotifyTemplates.end())
768 {
769 xml_template = iter->second;
770 }
771 else
772 {
773 LLString tmsg = "[Notification template not found:\n " + xml_desc + " ]";
774 sDefaultTemplate->setMessage(tmsg);
775 xml_template = sDefaultTemplate;
776 }
777
778 return xml_template;
779}
780
700//----------------------------------------------------------------------------- 781//-----------------------------------------------------------------------------
701 782
702//static 783//static
703const LLString& LLNotifyBox::getTemplateMessage(const LLString& xml_desc) 784const LLString LLNotifyBox::getTemplateMessage(const LLString& xml_desc, const LLString::format_map_t& args)
785{
786 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
787 if (iter != sNotifyTemplates.end())
788 {
789 LLString message = iter->second->mMessage;
790 LLAlertDialog::format(message, args);
791 return message;
792 }
793 else
794 {
795 return xml_desc;
796 }
797}
798
799//static
800const LLString LLNotifyBox::getTemplateMessage(const LLString& xml_desc)
704{ 801{
705 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); 802 template_map_t::iterator iter = sNotifyTemplates.find(xml_desc);
706 if (iter != sNotifyTemplates.end()) 803 if (iter != sNotifyTemplates.end())
@@ -747,8 +844,14 @@ bool LLNotifyBox::parseNotify(const LLString& xml_filename)
747 { 844 {
748 continue; 845 continue;
749 } 846 }
847
848 BOOL unique = FALSE;
849 notify->getAttributeBOOL("unique", unique);
850
851 F32 duration = gSavedSettings.getF32("NotifyTipDuration");
852 notify->getAttributeF32("duration", duration);
750 853
751 LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate; 854 LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate(unique, duration);
752 855
753 // label= 856 // label=
754 LLString notify_name; 857 LLString notify_name;