From ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Thu, 30 Apr 2009 13:04:20 -0500 Subject: Second Life viewer sources 1.23.0-RC --- linden/indra/llui/CMakeLists.txt | 10 + linden/indra/llui/llalertdialog.cpp | 766 ++++-------- linden/indra/llui/llalertdialog.h | 156 +-- linden/indra/llui/llbutton.cpp | 13 +- linden/indra/llui/llbutton.h | 5 +- linden/indra/llui/llcallbackmap.h | 3 +- linden/indra/llui/llcheckboxctrl.cpp | 9 +- linden/indra/llui/llcheckboxctrl.h | 3 +- linden/indra/llui/llclipboard.cpp | 3 +- linden/indra/llui/llclipboard.h | 3 +- linden/indra/llui/llcombobox.cpp | 39 +- linden/indra/llui/llcombobox.h | 4 +- linden/indra/llui/llctrlselectioninterface.cpp | 3 +- linden/indra/llui/llctrlselectioninterface.h | 3 +- linden/indra/llui/lldraghandle.cpp | 3 +- linden/indra/llui/lldraghandle.h | 3 +- linden/indra/llui/lleditmenuhandler.cpp | 3 +- linden/indra/llui/lleditmenuhandler.h | 3 +- linden/indra/llui/llfloater.cpp | 12 +- linden/indra/llui/llfloater.h | 29 +- linden/indra/llui/llfocusmgr.cpp | 3 +- linden/indra/llui/llfocusmgr.h | 3 +- linden/indra/llui/llfunctorregistry.cpp | 38 + linden/indra/llui/llfunctorregistry.h | 146 +++ linden/indra/llui/llhtmlhelp.h | 3 +- linden/indra/llui/lliconctrl.cpp | 3 +- linden/indra/llui/lliconctrl.h | 3 +- linden/indra/llui/llkeywords.cpp | 3 +- linden/indra/llui/llkeywords.h | 3 +- linden/indra/llui/lllineeditor.cpp | 7 +- linden/indra/llui/lllineeditor.h | 3 +- linden/indra/llui/llmemberlistener.h | 3 +- linden/indra/llui/llmenugl.cpp | 31 +- linden/indra/llui/llmenugl.h | 3 +- linden/indra/llui/llmodaldialog.cpp | 3 +- linden/indra/llui/llmodaldialog.h | 3 +- linden/indra/llui/llmultislider.cpp | 3 +- linden/indra/llui/llmultislider.h | 3 +- linden/indra/llui/llmultisliderctrl.cpp | 5 +- linden/indra/llui/llmultisliderctrl.h | 3 +- linden/indra/llui/llnotifications.cpp | 1487 ++++++++++++++++++++++++ linden/indra/llui/llnotifications.h | 903 ++++++++++++++ linden/indra/llui/llpanel.cpp | 142 ++- linden/indra/llui/llpanel.h | 33 +- linden/indra/llui/llprogressbar.cpp | 181 +++ linden/indra/llui/llprogressbar.h | 76 ++ linden/indra/llui/llradiogroup.cpp | 3 +- linden/indra/llui/llradiogroup.h | 3 +- linden/indra/llui/llresizebar.cpp | 3 +- linden/indra/llui/llresizebar.h | 3 +- linden/indra/llui/llresizehandle.cpp | 3 +- linden/indra/llui/llresizehandle.h | 3 +- linden/indra/llui/llresmgr.cpp | 13 +- linden/indra/llui/llresmgr.h | 3 +- linden/indra/llui/llrootview.cpp | 3 +- linden/indra/llui/llrootview.h | 3 +- linden/indra/llui/llscrollbar.cpp | 90 +- linden/indra/llui/llscrollbar.h | 5 +- linden/indra/llui/llscrollcontainer.cpp | 3 +- linden/indra/llui/llscrollcontainer.h | 3 +- linden/indra/llui/llscrollingpanellist.cpp | 3 +- linden/indra/llui/llscrollingpanellist.h | 3 +- linden/indra/llui/llscrolllistctrl.cpp | 353 ++++-- linden/indra/llui/llscrolllistctrl.h | 118 +- linden/indra/llui/llslider.cpp | 3 +- linden/indra/llui/llslider.h | 3 +- linden/indra/llui/llsliderctrl.cpp | 5 +- linden/indra/llui/llsliderctrl.h | 3 +- linden/indra/llui/llspinctrl.cpp | 7 +- linden/indra/llui/llspinctrl.h | 4 +- linden/indra/llui/llstyle.cpp | 3 +- linden/indra/llui/llstyle.h | 3 +- linden/indra/llui/lltabcontainer.cpp | 58 +- linden/indra/llui/lltabcontainer.h | 13 +- linden/indra/llui/lltabcontainervertical.cpp | 3 +- linden/indra/llui/lltabcontainervertical.h | 3 +- linden/indra/llui/lltextbox.cpp | 113 +- linden/indra/llui/lltextbox.h | 13 +- linden/indra/llui/lltexteditor.cpp | 109 +- linden/indra/llui/lltexteditor.h | 18 +- linden/indra/llui/lltextparser.cpp | 299 +++++ linden/indra/llui/lltextparser.h | 73 ++ linden/indra/llui/llui.cpp | 31 +- linden/indra/llui/llui.h | 241 +++- linden/indra/llui/lluiconstants.h | 3 +- linden/indra/llui/lluictrl.cpp | 27 +- linden/indra/llui/lluictrl.h | 9 +- linden/indra/llui/lluictrlfactory.cpp | 9 +- linden/indra/llui/lluictrlfactory.h | 6 +- linden/indra/llui/lluifwd.h | 3 +- linden/indra/llui/lluistring.cpp | 16 +- linden/indra/llui/lluistring.h | 9 +- linden/indra/llui/lluitrans.cpp | 101 ++ linden/indra/llui/lluitrans.h | 87 ++ linden/indra/llui/lluixmltags.h | 3 +- linden/indra/llui/llundo.cpp | 3 +- linden/indra/llui/llundo.h | 3 +- linden/indra/llui/llview.cpp | 63 +- linden/indra/llui/llview.h | 13 +- linden/indra/llui/llviewborder.cpp | 6 +- linden/indra/llui/llviewborder.h | 3 +- linden/indra/llui/llviewquery.cpp | 3 +- linden/indra/llui/llviewquery.h | 3 +- 103 files changed, 4873 insertions(+), 1287 deletions(-) create mode 100644 linden/indra/llui/llfunctorregistry.cpp create mode 100644 linden/indra/llui/llfunctorregistry.h create mode 100644 linden/indra/llui/llnotifications.cpp create mode 100644 linden/indra/llui/llnotifications.h create mode 100644 linden/indra/llui/llprogressbar.cpp create mode 100644 linden/indra/llui/llprogressbar.h create mode 100644 linden/indra/llui/lltextparser.cpp create mode 100644 linden/indra/llui/lltextparser.h create mode 100644 linden/indra/llui/lluitrans.cpp create mode 100644 linden/indra/llui/lluitrans.h (limited to 'linden/indra/llui') diff --git a/linden/indra/llui/CMakeLists.txt b/linden/indra/llui/CMakeLists.txt index 77efec5..32118e8 100644 --- a/linden/indra/llui/CMakeLists.txt +++ b/linden/indra/llui/CMakeLists.txt @@ -36,6 +36,7 @@ set(llui_SOURCE_FILES lleditmenuhandler.cpp llfloater.cpp llfocusmgr.cpp + llfunctorregistry.cpp lliconctrl.cpp llkeywords.cpp lllineeditor.cpp @@ -43,7 +44,9 @@ set(llui_SOURCE_FILES llmodaldialog.cpp llmultislider.cpp llmultisliderctrl.cpp + llnotifications.cpp llpanel.cpp + llprogressbar.cpp llradiogroup.cpp llresizebar.cpp llresizehandle.cpp @@ -61,10 +64,12 @@ set(llui_SOURCE_FILES lltabcontainervertical.cpp lltextbox.cpp lltexteditor.cpp + lltextparser.cpp llui.cpp lluictrl.cpp lluictrlfactory.cpp lluistring.cpp + lluitrans.cpp llundo.cpp llviewborder.cpp llview.cpp @@ -85,6 +90,7 @@ set(llui_HEADER_FILES lleditmenuhandler.h llfloater.h llfocusmgr.h + llfunctorregistry.h llhtmlhelp.h lliconctrl.h llkeywords.h @@ -94,7 +100,9 @@ set(llui_HEADER_FILES llmodaldialog.h llmultisliderctrl.h llmultislider.h + llnotifications.h llpanel.h + llprogressbar.h llradiogroup.h llresizebar.h llresizehandle.h @@ -112,12 +120,14 @@ set(llui_HEADER_FILES lltabcontainervertical.h lltextbox.h lltexteditor.h + lltextparser.h lluiconstants.h lluictrlfactory.h lluictrl.h lluifwd.h llui.h lluistring.h + lluitrans.h lluixmltags.h llundo.h llviewborder.h diff --git a/linden/indra/llui/llalertdialog.cpp b/linden/indra/llui/llalertdialog.cpp index 80e54b6..f321db8 100644 --- a/linden/indra/llui/llalertdialog.cpp +++ b/linden/indra/llui/llalertdialog.cpp @@ -1,5 +1,4 @@ -/** - * @file llalertdialog.cpp +/* @file llalertdialog.cpp * @brief LLAlertDialog base class * * $LicenseInfo:firstyear=2001&license=viewergpl$ @@ -17,7 +16,8 @@ * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, @@ -46,85 +46,55 @@ #include "llxmlnode.h" #include "lllineeditor.h" #include "lluictrlfactory.h" - +#include "llnotifications.h" +#include "llfunctorregistry.h" const S32 MAX_ALLOWED_MSG_WIDTH = 400; const F32 DEFAULT_BUTTON_DELAY = 0.5f; const S32 MSG_PAD = 8; -/*static*/ LLAlertDialog::template_map_t LLAlertDialog::sAlertTemplates; -/*static*/ LLAlertDialog::template_map_t LLAlertDialog::sIgnorableTemplates; /*static*/ LLControlGroup* LLAlertDialog::sSettings = NULL; -/*static*/ std::map LLAlertDialog::sUniqueActiveMap; -/*static*/ LLAlertDialog::display_callback_t LLAlertDialog::sDisplayCallback; -/*static*/ std::string LLAlertDialog::sStringSkipNextTime("Skip this dialog next time"); -/*static*/ std::string LLAlertDialog::sStringAlwaysChoose("Always choose this option"); /*static*/ LLAlertDialog::URLLoader* LLAlertDialog::sURLLoader; - //static -LLAlertDialog* LLAlertDialog::createXml( const std::string& xml_desc, - alert_callback_t callback, void *user_data) +void LLAlertDialog::initClass() { - LLStringUtil::format_map_t args; - return createXml(xml_desc, args, callback, user_data); + LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy(&LLNotification::getType, "alert")); + LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy(&LLNotification::getType, "alertmodal")); + LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&onNewNotification, _1, false)); + LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&onNewNotification, _1, true)); } -//static -LLAlertDialog* LLAlertDialog::createXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args, - alert_callback_t callback, void *user_data) +//static +bool LLAlertDialog::onNewNotification(const LLSD& notify, bool is_modal) { - template_map_t::iterator iter = sAlertTemplates.find(xml_desc); - if (iter != sAlertTemplates.end()) - { - LLAlertDialogTemplate* xml_template = iter->second; - // deletes itself - llwarns << "Alert: [" << xml_desc << "] " << llendl; - LLAlertDialog* dialog = new LLAlertDialog( xml_template, args, callback, user_data); - return dialog; - } - else + LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID()); + + if(notification) { - LLStringUtil::format_map_t args; - args["[ALERT_NAME]"] = xml_desc; - llwarns << "Missing Alert: [" << xml_desc << "]" << llendl; - LLAlertDialog* dialogp = LLAlertDialog::showXml("MissingAlert", args); - if (dialogp == NULL) + if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load") { - llerrs << "Bad or missing alerts.xml!" << llendl; + LLAlertDialog* dialog = new LLAlertDialog(notification, is_modal); + dialog->show(); + } + else if (notify["sigtype"].asString() == "change") + { + LLAlertDialog* dialog = getInstance(notification->getID()); + if (dialog) + { + dialog->show(); + } + else + { + LLAlertDialog* dialog = new LLAlertDialog(notification, is_modal); + dialog->show(); + } } - return NULL; } -} - -//static -LLAlertDialog* LLAlertDialog::showXml( const std::string& xml_desc, - alert_callback_t callback, void *user_data) -{ - LLStringUtil::format_map_t args; - return showXml(xml_desc, args, callback, user_data); -} -//static -LLAlertDialog* LLAlertDialog::showXml( const std::string& xml_desc, const LLStringUtil::format_map_t& args, - alert_callback_t callback, void *user_data) -{ - LLAlertDialog* dialog = createXml(xml_desc, args, callback, user_data); - return dialog && dialog->show() ? dialog : NULL; + return false; } -//static -LLAlertDialog* LLAlertDialog::showCritical( const std::string& desc, alert_callback_t callback, void *user_data) -{ - LLAlertDialogTemplate xml_template; - LLStringUtil::format_map_t args; - xml_template.mTitle = "Critical Error"; - xml_template.mMessage = desc; - xml_template.mModal = TRUE; - xml_template.mOptions.push_back("Quit"); - LLAlertDialog* dialog = new LLAlertDialog( &xml_template, args, callback, user_data); - return dialog && dialog->show() ? dialog : NULL; -} //----------------------------------------------------------------------------- // Private methods @@ -132,183 +102,110 @@ LLAlertDialog* LLAlertDialog::showCritical( const std::string& desc, alert_callb static const S32 VPAD = 16; static const S32 HPAD = 25; static const S32 BTN_HPAD = 8; -static const LLFONT_ID font_name = LLFONT_SANSSERIF; - -LLAlertDialog::LLAlertDialog( const LLAlertDialogTemplate* xml_template, - const LLStringUtil::format_map_t& args, - alert_callback_t callback, void *user_data) - : LLModalDialog( xml_template->mTitle, 100, 100, xml_template->mModal ), // dummy size. Will reshape below. - mCallback( callback ), - mUserData( user_data ), - mNumOptions( 0 ), +static const LLFONT_ID FONT_NAME = LLFONT_SANSSERIF; + +LLAlertDialog::LLAlertDialog( LLNotificationPtr notification, bool modal) + : LLModalDialog( notification->getLabel(), 100, 100, modal ), // dummy size. Will reshape below. + LLInstanceTracker(notification->getID()), mDefaultOption( 0 ), - mOptionChosen( -1 ), mCheck(NULL), - mCaution(xml_template->mCaution), - mUnique(xml_template->mUnique), - mIgnorable(xml_template->mIgnorable), - mLabel(xml_template->mLabel), - mIgnoreLabel(xml_template->mIgnoreLabel), - mButtonData(NULL), + mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH), + mLabel(notification->getName()), mLineEditor(NULL), - mTextCallback(NULL), - mURLOption(0) + mNote(notification) { - mURL = xml_template->mURL; - mURLOption = xml_template->mURLOption; - createDialog(xml_template->mOptions, xml_template->mDefaultOption, - xml_template->mMessage, args, - xml_template->mEditLineText); - setTitle(xml_template->mTitle); - if (xml_template->mIgnorable) - { - if (xml_template->mIgnorable == IGNORE_USE_DEFAULT) - { - setCheckBox(sStringSkipNextTime, xml_template->mIgnoreLabel); - } - else // xml_template->mIgnorable == IGNORE_USE_SAVED - { - setCheckBox(sStringAlwaysChoose, xml_template->mIgnoreLabel); - } - } -} + const LLFontGL* font = LLResMgr::getInstance()->getRes( FONT_NAME ); + const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); + const S32 EDITOR_HEIGHT = 20; -// All logic for deciding not to show an alert is done here, -// so that the alert is valid until show() is called. -bool LLAlertDialog::show() -{ - // If modal, check to see if we are not displaying alerts, - // and do any application logic before showing modal alerts - if (sDisplayCallback) - { - bool show = sDisplayCallback(isModal()); - if (show == false) - { - mOptionChosen = mDefaultOption; - llinfos << "Alert: " << mLabel << llendl; - close(); - return false; - } - } + LLNotificationFormPtr form = mNote->getForm(); + std::string edit_text_name; + std::string edit_text_contents; + bool is_password = false; + + setBackgroundVisible(TRUE); + setBackgroundOpaque(TRUE); - // Check to see if the user wants to ignore this alert - if (mIgnorable > 0) + + typedef std::vector > options_t; + options_t supplied_options; + + // for now, get LLSD to iterator over form elements + LLSD form_sd = form->asLLSD(); + + S32 option_index = 0; + for (LLSD::array_const_iterator it = form_sd.beginArray(); it != form_sd.endArray(); ++it) { - BOOL warn = sSettings->getWarning(mIgnoreLabel); - if (!warn) + std::string type = (*it)["type"].asString(); + if (type == "button") { - switch(mIgnorable) + if((*it)["default"]) { - case IGNORE_USE_DEFAULT: - mOptionChosen = mDefaultOption; - break; - case IGNORE_USE_SAVED: - mOptionChosen = sSettings->getS32("Default" + mIgnoreLabel); - break; - case IGNORE_SHOW_AGAIN: - break; + mDefaultOption = option_index; } - close(); - return false; - } - } - // If this is a caution message, change the color and add an icon. - if (mCaution) - { - setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertCautionBoxColor" ) ); - } - else - { - setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertBoxColor" ) ); - } + supplied_options.push_back(std::make_pair((*it)["name"].asString(), (*it)["text"].asString())); - // Check to see if we are already displaying the alert - if (mUnique) - { - std::map::iterator iter = sUniqueActiveMap.find(mLabel); - if (iter != sUniqueActiveMap.end()) + ButtonData data; + data.mSelf = this; + if (option_index == mNote->getURLOption()) + { + data.mURL = mNote->getURL(); + } + + mButtonData.push_back(data); + option_index++; + } + else if (type == "text") { - gFloaterView->bringToFront(iter->second); - mUnique = FALSE; // don't remove entry from map on destruction - close(); - return false; + edit_text_contents = (*it)["value"].asString(); + edit_text_name = (*it)["name"].asString(); + } + else if (type == "password") + { + edit_text_contents = (*it)["value"].asString(); + edit_text_name = (*it)["name"].asString(); + is_password = true; } - sUniqueActiveMap[mLabel] = this; - } - startModal(); - gFloaterView->adjustToFitScreen(this, FALSE); - open(); /* Flawfinder: ignore */ - setFocus(TRUE); - if (mLineEditor) - { - mLineEditor->setFocus(TRUE); - mLineEditor->selectAll(); - } - if(mDefaultOption >= 0) - { - // delay before enabling default button - mDefaultBtnTimer.start(); - mDefaultBtnTimer.setTimerExpirySec(DEFAULT_BUTTON_DELAY); } - return true; -} - -void LLAlertDialog::format(std::string& msg, const LLStringUtil::format_map_t& args) -{ - // XUI:translate! - LLStringUtil::format_map_t targs = args; - targs["[SECOND_LIFE]"] = "Second Life"; - targs["[_URL]"] = mURL; - LLStringUtil::format(msg, targs); -} -void LLAlertDialog::createDialog(const options_list_t& options_in, S32 default_option, - const std::string& msg_in, const LLStringUtil::format_map_t& args, - const std::string& edit_text) -{ - setBackgroundVisible(TRUE); - setBackgroundOpaque(TRUE); - - const LLFontGL* font = LLResMgr::getInstance()->getRes( font_name ); - const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); - const S32 EDITOR_HEIGHT = 20; - - const options_list_t* optionsp = &options_in; - // Buttons - options_list_t default_option_list; - mNumOptions = options_in.size(); - if( 0 == mNumOptions ) + options_t options; + if (supplied_options.empty()) { - default_option_list.push_back("Close"); - optionsp = &default_option_list; - default_option = 0; - mNumOptions = 1; + options.push_back(std::make_pair(std::string("close"), std::string("Close"))); + + // add data for ok button. + ButtonData ok_button; + ok_button.mSelf = this; + + mButtonData.push_back(ok_button); + mDefaultOption = 0; + } + else + { + options = supplied_options; } - const options_list_t& options= *optionsp; - - mButtonData = new ButtonData[mNumOptions]; + S32 num_options = options.size(); // Calc total width of buttons S32 button_width = 0; S32 sp = font->getWidth(std::string("OO")); - for( S32 i = 0; i < mNumOptions; i++ ) + for( S32 i = 0; i < num_options; i++ ) { - S32 w = S32(font->getWidth( options[i] ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD; + S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD; button_width = llmax( w, button_width ); } S32 btn_total_width = button_width; - if( mNumOptions > 1 ) + if( num_options > 1 ) { - btn_total_width = (mNumOptions * button_width) + ((mNumOptions - 1) * BTN_HPAD); + btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD); } // Message: create text box using raw string, as text has been structure deliberately // Use size of created text box to generate dialog box size - std::string msg = msg_in; - format( msg, args ); + std::string msg = mNote->getMessage(); llwarns << "Alert: " << msg << llendl; LLTextBox* msg_box = new LLTextBox( std::string("Alert message"), msg, (F32)MAX_ALLOWED_MSG_WIDTH, font ); @@ -321,16 +218,19 @@ void LLAlertDialog::createDialog(const options_list_t& options_in, S32 default_o dialog_height += LINE_HEIGHT; // room for title bar } - if (edit_text.size() > 0) + // it's ok for the edit text body to be empty, but we want the name to exist if we're going to draw it + if (!edit_text_name.empty()) { - dialog_width = llmax(dialog_width, S32(font->getWidth( edit_text ) + 0.99f)); - dialog_height += EDITOR_HEIGHT; + dialog_height += EDITOR_HEIGHT + VPAD; + dialog_width = llmax(dialog_width, (S32)(font->getWidth( edit_text_contents ) + 0.99f)); } + if (mCaution) { // Make room for the caution icon. dialog_width += 32 + HPAD; } + reshape( dialog_width, dialog_height, FALSE ); S32 msg_y = getRect().getHeight() - VPAD; @@ -352,6 +252,7 @@ void LLAlertDialog::createDialog(const options_list_t& options_in, S32 default_o { msg_box->setColor( LLUI::sColorsGroup->getColor( "AlertTextColor" ) ); } + LLRect rect; rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() ); msg_box->setRect( rect ); @@ -360,25 +261,26 @@ void LLAlertDialog::createDialog(const options_list_t& options_in, S32 default_o // Buttons S32 button_left = (getRect().getWidth() - btn_total_width) / 2; - for( S32 i = 0; i < mNumOptions; i++ ) + for( S32 i = 0; i < num_options; i++ ) { LLRect button_rect; button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT ); - LLButton* btn = new LLButton(std::string("btn"), button_rect, - LLStringUtil::null, LLStringUtil::null, LLStringUtil::null, - &LLAlertDialog::onButtonPressed, (void*)(&mButtonData[i]), - font, - options[i], - options[i]); + LLButton* btn = new LLButton( + options[i].first, button_rect, + "","", "", + NULL, NULL, + font, + options[i].second, + options[i].second); - mButtonData[i].mSelf = this; mButtonData[i].mButton = btn; - mButtonData[i].mOption = i; + + btn->setClickedCallback(&LLAlertDialog::onButtonPressed, (void*)(&mButtonData[i])); addChild(btn); - if( i == default_option ) + if( i == mDefaultOption ) { btn->setFocus(TRUE); } @@ -387,21 +289,83 @@ void LLAlertDialog::createDialog(const options_list_t& options_in, S32 default_o } // (Optional) Edit Box - if (edit_text.size() > 0) + if (!edit_text_name.empty()) { S32 y = VPAD + BTN_HEIGHT + VPAD/2; - mLineEditor = new LLLineEditor(std::string("lineeditor"), + mLineEditor = new LLLineEditor(edit_text_name, LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y), - edit_text, - LLFontGL::sSansSerif, + edit_text_contents, + LLFontGL::getFontSansSerif(), STD_STRING_STR_LEN); + + // make sure all edit keys get handled properly (DEV-22396) + mLineEditor->setHandleEditKeysDirectly(TRUE); + addChild(mLineEditor); } + + if (mLineEditor) + { + mLineEditor->setDrawAsterixes(is_password); + + setEditTextArgs(notification->getSubstitutions()); + } + + std::string ignore_label; + + if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE) + { + setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label); + } + else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) + { + setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label); + } +} + +// All logic for deciding not to show an alert is done here, +// so that the alert is valid until show() is called. +bool LLAlertDialog::show() +{ + // If this is a caution message, change the color and add an icon. + if (mCaution) + { + setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertCautionBoxColor" ) ); + } + else + { + setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertBoxColor" ) ); + } + + startModal(); + gFloaterView->adjustToFitScreen(this, FALSE); + open(); /* Flawfinder: ignore */ + setFocus(TRUE); + if (mLineEditor) + { + mLineEditor->setFocus(TRUE); + mLineEditor->selectAll(); + } + if(mDefaultOption >= 0) + { + // delay before enabling default button + mDefaultBtnTimer.start(); + mDefaultBtnTimer.setTimerExpirySec(DEFAULT_BUTTON_DELAY); + } + + // attach to floater if necessary + LLUUID context_key = mNote->getPayload()["context"].asUUID(); + LLFloaterNotificationContext* contextp = dynamic_cast(LLNotificationContext::getInstance(context_key)); + if (contextp && contextp->getFloater()) + { + contextp->getFloater()->addDependentFloater(this, FALSE); + } + return true; } bool LLAlertDialog::setCheckBox( const std::string& check_title, const std::string& check_control ) { - const LLFontGL* font = LLResMgr::getInstance()->getRes( font_name ); + const LLFontGL* font = LLResMgr::getInstance()->getRes( FONT_NAME ); const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); // Extend dialog for "check next time" @@ -422,16 +386,9 @@ bool LLAlertDialog::setCheckBox( const std::string& check_title, const std::stri check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT); - mCheck = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font); + mCheck = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font, onClickIgnore, this); addChild(mCheck); - // mCheck is sometimes "show again" and sometimes "hide" :-( - // If it's "Show Again", and we showed it, it must be checked. JC - if (mIgnorable == IGNORE_SHOW_AGAIN) - { - mCheck->setValue(TRUE); - } - return true; } @@ -449,65 +406,12 @@ void LLAlertDialog::setVisible( BOOL visible ) void LLAlertDialog::onClose(bool app_quitting) { LLModalDialog::onClose(app_quitting); - handleCallbacks(); } LLAlertDialog::~LLAlertDialog() { - delete[] mButtonData; - if (mUnique) - { - sUniqueActiveMap.erase(mLabel); - } } -void LLAlertDialog::handleCallbacks() -{ - if (mOptionChosen >= 0) - { - if (mTextCallback && mLineEditor) - { - mTextCallback(mOptionChosen, mLineEditor->getText(), mUserData); - } - else if (mCallback) - { - mCallback(mOptionChosen, mUserData); - } - - // If we declared a URL and chose the URL option, go to the url - if (mOptionChosen == mURLOption) - { - if (!mURL.empty() && sURLLoader != NULL) - { - sURLLoader->load(mURL); - } - } - - // Only change warn state if we actually warned. - if (mCheck - && sSettings->getWarning(mIgnoreLabel)) - { - // mCheck sometimes means "hide and do the default" and - // other times means "warn me again". Yuck. JC - BOOL check = mCheck->getValue(); - switch(mIgnorable) - { - case IGNORE_USE_DEFAULT: - sSettings->setWarning(mIgnoreLabel, !check); - break; - case IGNORE_USE_SAVED: - sSettings->setWarning(mIgnoreLabel, !check); - sSettings->setS32("Default" + mIgnoreLabel, mOptionChosen); - break; - case IGNORE_SHOW_AGAIN: - sSettings->setWarning(mIgnoreLabel, check); - break; - default: - break; - } - } - } -} BOOL LLAlertDialog::hasTitleBar() const { return (getCurrentTitle() != "" && getCurrentTitle() != " ") // has title @@ -567,33 +471,11 @@ void LLAlertDialog::draw() LLModalDialog::draw(); } -void LLAlertDialog::setOptionEnabled( S32 option, BOOL enable ) -{ - if( (option >= 0) && (option < mNumOptions) ) - { - mButtonData[option].mButton->setEnabled( enable ); - } -} - -void LLAlertDialog::setEditTextCallback(alert_text_callback_t callback, void *user_data) -{ - if (mLineEditor) - { - mTextCallback = callback; - mUserData = user_data; - } - else - { - llwarns << "LLAlertDialog::setEditTextCallback called on dialog with no line editor" << llendl; - } -} - -void LLAlertDialog::setEditTextArgs(const LLStringUtil::format_map_t& edit_args) +void LLAlertDialog::setEditTextArgs(const LLSD& edit_args) { if (mLineEditor) { std::string msg = mLineEditor->getText(); - format(msg, edit_args); mLineEditor->setText(msg); } else @@ -602,268 +484,44 @@ void LLAlertDialog::setEditTextArgs(const LLStringUtil::format_map_t& edit_args) } } -void LLAlertDialog::setDrawAsterixes(BOOL enable) -{ - if (mLineEditor) - { - if (enable) - { - mLineEditor->clear(); - } - mLineEditor->setDrawAsterixes(enable); - } -} - // static void LLAlertDialog::onButtonPressed( void* userdata ) { ButtonData* button_data = (ButtonData*)userdata; LLAlertDialog* self = button_data->mSelf; - self->mOptionChosen = button_data->mOption; - self->close(); // deletes self -} - -//============================================================================= - -//static -const std::string& LLAlertDialog::getTemplateMessage(const std::string& xml_desc) -{ - template_map_t::iterator iter = sAlertTemplates.find(xml_desc); - if (iter != sAlertTemplates.end()) + LLSD response = self->mNote->getResponseTemplate(); + if (self->mLineEditor) { - return iter->second->mMessage; + response[self->mLineEditor->getName()] = self->mLineEditor->getValue(); } - else + response[button_data->mButton->getName()] = true; + + // If we declared a URL and chose the URL option, go to the url + if (!button_data->mURL.empty() && sURLLoader != NULL) { - return xml_desc; + sURLLoader->load(button_data->mURL); } + + self->mNote->respond(response); // new notification reponse + self->close(); // deletes self } -//static -bool LLAlertDialog::parseAlerts(const std::string& xml_filename, LLControlGroup* settings, BOOL settings_only) +//static +void LLAlertDialog::onClickIgnore(LLUICtrl* ctrl, void* user_data) { - LLXMLNodePtr root; - BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + LLAlertDialog* self = (LLAlertDialog*)user_data; - if (!success || root.isNull() || !root->hasName( "alerts" )) + // checkbox sometimes means "hide and do the default" and + // other times means "warn me again". Yuck. JC + BOOL check = ctrl->getValue(); + if (self->mNote->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) { - llerrs << "Problem reading UI Alerts file: " << xml_filename << llendl; - return false; + // question was "show again" so invert value to get "ignore" + check = !check; } - BOOL add_settings = FALSE; - if (settings) - { - sSettings = settings; - add_settings = TRUE; - } - llassert(sSettings); - - for (LLXMLNode* alert = root->getFirstChild(); - alert != NULL; alert = alert->getNextSibling()) - { - if (alert->hasName("global")) - { - std::string global_name; - if (alert->getAttributeString("name", global_name)) - { - if (global_name == "skipnexttime") - { - sStringSkipNextTime = alert->getTextContents(); - } - else if (global_name == "alwayschoose") - { - sStringAlwaysChoose = alert->getTextContents(); - } - } - continue; - } - - if (!alert->hasName("alert")) - { - continue; - } - - LLAlertDialogTemplate* xml_template = settings_only ? NULL : new LLAlertDialogTemplate; - - // name= - std::string alert_name; - if (alert->getAttributeString("name", alert_name)) - { - if (xml_template) - { - xml_template->mLabel = alert_name; - } - } - else - { - llwarns << "Unable to parse alert with no name" << llendl; - delete xml_template; - continue; - } - // title= - std::string title; - if (alert->getAttributeString("title", title)) - { - if (xml_template) - { - xml_template->mTitle = title; - } - } - // modal= - BOOL modal; - if (alert->getAttributeBOOL("modal", modal)) - { - if (xml_template) - { - xml_template->mModal = modal; - } - } - // caution= - BOOL caution; - if (alert->getAttributeBOOL("caution", caution)) - { - if (xml_template) - { - xml_template->mCaution = caution; - } - } - // unique= - BOOL unique; - if (alert->getAttributeBOOL("unique", unique)) - { - if (xml_template) - { - xml_template->mUnique = unique; - } - } - - S32 default_option = 0; - BOOL nodefault; - if (alert->getAttributeBOOL("nodefault", nodefault)) - { - if (nodefault) - { - if (xml_template) - { - xml_template->mDefaultOption = -1; - } - default_option = -1; - } - } - - S32 btn_idx = 0; - for (LLXMLNode* child = alert->getFirstChild(); - child != NULL; child = child->getNextSibling()) - { - // - if (child->hasName("message")) - { - if (xml_template) - { - xml_template->mMessage = child->getTextContents(); - } - } + self->mNote->setIgnored(check); +} - //