llalertdialog.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llboost.h"
00035 
00036 #include "llalertdialog.h"
00037 #include "llfontgl.h"
00038 #include "llresmgr.h"
00039 #include "lltextbox.h"
00040 #include "llbutton.h"
00041 #include "llcheckboxctrl.h"
00042 #include "llkeyboard.h"
00043 #include "llfocusmgr.h"
00044 #include "lliconctrl.h"
00045 #include "llui.h"
00046 #include "llxmlnode.h"
00047 #include "lllineeditor.h"
00048 #include "lluictrlfactory.h"
00049 
00050 
00051 const S32 MAX_ALLOWED_MSG_WIDTH = 400;
00052 const F32 DEFAULT_BUTTON_DELAY = 0.5f;
00053 const S32 MSG_PAD = 8;
00054 
00055 /*static*/ LLAlertDialog::template_map_t LLAlertDialog::sAlertTemplates;
00056 /*static*/ LLAlertDialog::template_map_t LLAlertDialog::sIgnorableTemplates;
00057 /*static*/ LLControlGroup* LLAlertDialog::sSettings = NULL;
00058 /*static*/ std::map<LLString,LLAlertDialog*> LLAlertDialog::sUniqueActiveMap;
00059 /*static*/ LLAlertDialog::display_callback_t LLAlertDialog::sDisplayCallback;
00060 /*static*/ LLString LLAlertDialog::sStringSkipNextTime("Skip this dialog next time");
00061 /*static*/ LLString LLAlertDialog::sStringAlwaysChoose("Always choose this option");
00062 /*static*/ LLAlertDialog::URLLoader* LLAlertDialog::sURLLoader;
00063 
00064 
00065 //static
00066 LLAlertDialog* LLAlertDialog::createXml( const LLString& xml_desc,
00067                                                                                  alert_callback_t callback, void *user_data)
00068 {
00069         LLString::format_map_t args;
00070         return createXml(xml_desc, args, callback, user_data);
00071 }
00072 
00073 //static
00074 LLAlertDialog* LLAlertDialog::createXml( const LLString& xml_desc, const LLString::format_map_t& args,
00075                                                                                  alert_callback_t callback, void *user_data)
00076 {
00077         template_map_t::iterator iter = sAlertTemplates.find(xml_desc);
00078         if (iter != sAlertTemplates.end())
00079         {
00080                 LLAlertDialogTemplate* xml_template = iter->second;
00081                 // deletes itself
00082                 llwarns << "Alert: [" << xml_desc << "] " << llendl;
00083                 LLAlertDialog* dialog = new LLAlertDialog( xml_template, args, callback, user_data);
00084                 return dialog;
00085         }
00086         else
00087         {
00088                 LLString::format_map_t args;
00089                 args["[ALERT_NAME]"] = xml_desc;
00090                 llwarns << "Missing Alert: [" << xml_desc << "]" << llendl;
00091                 LLAlertDialog* dialogp = LLAlertDialog::showXml("MissingAlert", args);
00092                 if (dialogp == NULL)
00093                 {
00094                         llerrs << "Bad or missing alerts.xml!" << llendl;
00095                 }
00096                 return NULL;
00097         }
00098 }
00099 
00100 //static
00101 LLAlertDialog* LLAlertDialog::showXml( const LLString& xml_desc,
00102                                                          alert_callback_t callback, void *user_data)
00103 {
00104         LLString::format_map_t args;
00105         return showXml(xml_desc, args, callback, user_data);
00106 }
00107 
00108 //static
00109 LLAlertDialog* LLAlertDialog::showXml( const LLString& xml_desc, const LLString::format_map_t& args,
00110                                                          alert_callback_t callback, void *user_data)
00111 {
00112         LLAlertDialog* dialog = createXml(xml_desc, args, callback, user_data);
00113         return dialog && dialog->show() ? dialog : NULL;
00114 }
00115 
00116 //static
00117 LLAlertDialog* LLAlertDialog::showCritical( const LLString& desc, alert_callback_t callback, void *user_data)
00118 {
00119         LLAlertDialogTemplate xml_template;
00120         LLString::format_map_t args;
00121         xml_template.mTitle = "Critical Error";
00122         xml_template.mMessage = desc;
00123         xml_template.mModal = TRUE;
00124         xml_template.mOptions.push_back("Quit");
00125         LLAlertDialog* dialog = new LLAlertDialog( &xml_template, args, callback, user_data);
00126         return dialog && dialog->show() ? dialog : NULL;
00127 }
00128 
00129 //-----------------------------------------------------------------------------
00130 // Private methods
00131 
00132 static const S32 VPAD = 16;
00133 static const S32 HPAD = 25;
00134 static const S32 BTN_HPAD = 8;
00135 static const LLFONT_ID font_name = LLFONT_SANSSERIF;
00136 
00137 LLAlertDialog::LLAlertDialog( const LLAlertDialogTemplate* xml_template,
00138                                                           const LLString::format_map_t& args,
00139                                                           alert_callback_t callback, void *user_data)
00140         :       LLModalDialog( xml_template->mTitle, 100, 100, xml_template->mModal ),  // dummy size.  Will reshape below.
00141                 mCallback( callback ),
00142                 mUserData( user_data ),
00143                 mNumOptions( 0 ),
00144                 mDefaultOption( 0 ),
00145                 mOptionChosen( -1 ),
00146                 mCheck(NULL),
00147                 mCaution(xml_template->mCaution),
00148                 mUnique(xml_template->mUnique),
00149                 mIgnorable(xml_template->mIgnorable),
00150                 mLabel(xml_template->mLabel),
00151                 mIgnoreLabel(xml_template->mIgnoreLabel),
00152                 mButtonData(NULL),
00153                 mLineEditor(NULL),
00154                 mTextCallback(NULL),
00155                 mURLOption(0)
00156 {
00157         mURL = xml_template->mURL;
00158         mURLOption = xml_template->mURLOption;
00159         createDialog(&(xml_template->mOptions), xml_template->mDefaultOption,
00160                                  xml_template->mMessage, args,
00161                                  xml_template->mEditLineText);
00162         setTitle(xml_template->mTitle);
00163         if (xml_template->mIgnorable)
00164         {
00165                 if (xml_template->mIgnorable == IGNORE_USE_DEFAULT)
00166                 {
00167                         setCheckBox(sStringSkipNextTime, xml_template->mIgnoreLabel);
00168                 }
00169                 else // xml_template->mIgnorable == IGNORE_USE_SAVED
00170                 {
00171                         setCheckBox(sStringAlwaysChoose, xml_template->mIgnoreLabel);
00172                 }
00173         }
00174 }
00175 
00176 // All logic for deciding not to show an alert is done here,
00177 // so that the alert is valid until show() is called.
00178 bool LLAlertDialog::show()
00179 {
00180         // If modal, check to see if we are not displaying alerts,
00181         //   and do any application logic before showing modal alerts
00182         if (sDisplayCallback)
00183         {
00184                 bool show = sDisplayCallback(isModal());
00185                 if (show == false)
00186                 {
00187                         mOptionChosen = mDefaultOption;
00188                         llinfos << "Alert: " << mLabel << llendl;
00189                         close();
00190                         return false;
00191                 }
00192         }
00193 
00194         // Check to see if the user wants to ignore this alert
00195         if (mIgnorable > 0)
00196         {
00197                 BOOL warn = sSettings->getWarning(mIgnoreLabel);
00198                 if (!warn)
00199                 {
00200                         switch(mIgnorable)
00201                         {
00202                         case IGNORE_USE_DEFAULT:
00203                                 mOptionChosen = mDefaultOption;
00204                                 break;
00205                         case IGNORE_USE_SAVED:
00206                                 mOptionChosen = sSettings->getS32("Default" + mIgnoreLabel);
00207                                 break;
00208                         case IGNORE_SHOW_AGAIN:
00209                                 break;
00210                         }
00211                         close();
00212                         return false;
00213                 }
00214         }
00215 
00216         // If this is a caution message, change the color and add an icon.
00217         if (mCaution)
00218         {
00219                 setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertCautionBoxColor" ) );
00220         }
00221         else
00222         {
00223                 setBackgroundColor( LLUI::sColorsGroup->getColor( "AlertBoxColor" ) );
00224         }
00225 
00226         // Check to see if we are already displaying the alert
00227         if (mUnique)
00228         {
00229                 std::map<LLString,LLAlertDialog*>::iterator iter = sUniqueActiveMap.find(mLabel);
00230                 if (iter != sUniqueActiveMap.end())
00231                 {
00232                         gFloaterView->bringToFront(iter->second);
00233                         mUnique = FALSE; // don't remove entry from map on destruction
00234                         close();
00235                         return false;
00236                 }
00237                 sUniqueActiveMap[mLabel] = this;
00238         }
00239         startModal();
00240         gFloaterView->adjustToFitScreen(this, FALSE);
00241         open(); /* Flawfinder: ignore */
00242         setFocus(TRUE);
00243         if (mLineEditor)
00244         {
00245                 mLineEditor->setFocus(TRUE);
00246                 mLineEditor->selectAll();
00247         }
00248         if(mDefaultOption >= 0)
00249         {
00250                 // delay before enabling default button
00251                 mDefaultBtnTimer.start();
00252                 mDefaultBtnTimer.setTimerExpirySec(DEFAULT_BUTTON_DELAY);
00253         }
00254         return true;
00255 }
00256 
00257 void LLAlertDialog::format(LLString& msg, const LLString::format_map_t& args)
00258 {
00259         // XUI:translate!
00260         LLString::format_map_t targs = args;
00261         targs["[SECOND_LIFE]"] = "Second Life";
00262         targs["[_URL]"] = mURL;
00263         LLString::format(msg, targs);
00264 }
00265 
00266 void LLAlertDialog::createDialog(const std::vector<LLString>* optionsp, S32 default_option,
00267                                                                  const LLString& msg_in, const LLString::format_map_t& args,
00268                                                                  const LLString& edit_text)
00269 {
00270         setBackgroundVisible(TRUE);
00271         setBackgroundOpaque(TRUE);
00272 
00273         const LLFontGL* font = LLResMgr::getInstance()->getRes( font_name );
00274         const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
00275         const S32 EDITOR_HEIGHT = 20;
00276 
00277         // Buttons
00278         std::vector<LLString> default_option_list;
00279         mNumOptions = optionsp->size();
00280         if( 0 == mNumOptions )
00281         {
00282                 default_option_list.push_back("Close");
00283                 optionsp = &default_option_list;
00284                 default_option = 0;
00285                 mNumOptions = 1;
00286         }
00287 
00288         const std::vector<LLString>& options = *optionsp;
00289         mButtonData = new ButtonData[mNumOptions];
00290 
00291         // Calc total width of buttons
00292         S32 button_width = 0;
00293         S32 sp = font->getWidth("OO");
00294         for( S32 i = 0; i < mNumOptions; i++ )
00295         {
00296                 S32 w = S32(font->getWidth( options[i] ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD;
00297                 button_width = llmax( w, button_width );
00298         }
00299         S32 btn_total_width = button_width;
00300         if( mNumOptions > 1 )
00301         {
00302                 btn_total_width = (mNumOptions * button_width) + ((mNumOptions - 1) * BTN_HPAD);
00303         }
00304 
00305         // Message: create text box using raw string, as text has been structure deliberately
00306         // Use size of created text box to generate dialog box size
00307         LLString msg = msg_in;
00308         format( msg, args );             
00309         llwarns << "Alert: " << msg << llendl;
00310         LLTextBox* msg_box = new LLTextBox( "Alert message", msg, (F32)MAX_ALLOWED_MSG_WIDTH, font );
00311 
00312         const LLRect& text_rect = msg_box->getRect();
00313         S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD;
00314         S32 dialog_height = text_rect.getHeight() + 3 * VPAD + BTN_HEIGHT;
00315 
00316         if (hasTitleBar())
00317         {
00318                 dialog_height += LINE_HEIGHT; // room for title bar
00319         }
00320 
00321         if (edit_text.size() > 0)
00322         {
00323                 dialog_width = llmax(dialog_width, S32(font->getWidth( edit_text ) + 0.99f));
00324                 dialog_height += EDITOR_HEIGHT;
00325         }
00326         if (mCaution)
00327         {
00328                 // Make room for the caution icon.
00329                 dialog_width += 32 + HPAD;
00330         }
00331         reshape( dialog_width, dialog_height, FALSE );
00332 
00333         S32 msg_y = getRect().getHeight() - VPAD;
00334         S32 msg_x = HPAD;
00335         if (hasTitleBar())
00336         {
00337                 msg_y -= LINE_HEIGHT; // room for title
00338         }
00339 
00340         if (mCaution)
00341         {
00342                 LLIconCtrl* icon = new LLIconCtrl("icon", LLRect(msg_x, msg_y, msg_x+32, msg_y-32), "notify_caution_icon.tga");
00343                 icon->setMouseOpaque(FALSE);
00344                 addChild(icon);
00345                 msg_x += 32 + HPAD;
00346                 msg_box->setColor( LLUI::sColorsGroup->getColor( "AlertCautionTextColor" ) );
00347         }
00348         else
00349         {
00350                 msg_box->setColor( LLUI::sColorsGroup->getColor( "AlertTextColor" ) );
00351         }
00352         LLRect rect;
00353         rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() );
00354         msg_box->setRect( rect );
00355         addChild(msg_box);
00356 
00357         // Buttons      
00358         S32 button_left = (getRect().getWidth() - btn_total_width) / 2;
00359 
00360         for( S32 i = 0; i < mNumOptions; i++ )
00361         {
00362                 LLRect button_rect;
00363                 button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT );
00364 
00365                 LLButton* btn = new LLButton(
00366                         "btn", button_rect,
00367                         "","", "", 
00368                         &LLAlertDialog::onButtonPressed, (void*)(&mButtonData[i]),
00369                         font,
00370                         options[i], 
00371                         options[i]);
00372 
00373                 mButtonData[i].mSelf = this;
00374                 mButtonData[i].mButton = btn;
00375                 mButtonData[i].mOption = i;
00376 
00377                 addChild(btn);
00378 
00379                 if( i == default_option )
00380                 {
00381                         btn->setFocus(TRUE);
00382                 }
00383 
00384                 button_left += button_width + BTN_HPAD;
00385         }
00386 
00387         // (Optional) Edit Box  
00388         if (edit_text.size() > 0)
00389         {
00390                 S32 y = VPAD + BTN_HEIGHT + VPAD/2;
00391                 mLineEditor = new LLLineEditor("lineeditor",
00392                         LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y),
00393                         edit_text,
00394                         LLFontGL::sSansSerif,
00395                         STD_STRING_STR_LEN);
00396                 addChild(mLineEditor);
00397         }
00398 }
00399 
00400 bool LLAlertDialog::setCheckBox( const LLString& check_title, const LLString& check_control )
00401 {
00402         const LLFontGL* font = LLResMgr::getInstance()->getRes( font_name );
00403         const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
00404         
00405         // Extend dialog for "check next time"
00406         S32 max_msg_width = getRect().getWidth() - 2 * HPAD;            
00407         S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16;
00408         max_msg_width = llmax(max_msg_width, check_width);
00409         S32 dialog_width = max_msg_width + 2 * HPAD;
00410 
00411         S32 dialog_height = getRect().getHeight();
00412         dialog_height += LINE_HEIGHT;
00413         dialog_height += LINE_HEIGHT / 2;
00414 
00415         reshape( dialog_width, dialog_height, FALSE );
00416 
00417         S32 msg_x = (getRect().getWidth() - max_msg_width) / 2;
00418         
00419         LLRect check_rect;
00420         check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, 
00421                                                                 max_msg_width, LINE_HEIGHT);
00422 
00423         mCheck = new LLCheckboxCtrl("check", check_rect, check_title, font);
00424         addChild(mCheck);
00425 
00426         // mCheck is sometimes "show again" and sometimes "hide" :-(
00427         // If it's "Show Again", and we showed it, it must be checked. JC
00428         if (mIgnorable == IGNORE_SHOW_AGAIN)
00429         {
00430                 mCheck->setValue(TRUE);
00431         }
00432 
00433         return true;
00434 }
00435 
00436 void LLAlertDialog::setVisible( BOOL visible )
00437 {
00438         LLModalDialog::setVisible( visible );
00439         
00440         if( visible )
00441         {
00442                 centerOnScreen();
00443                 make_ui_sound("UISndAlert");
00444         }
00445 }
00446 
00447 void LLAlertDialog::onClose(bool app_quitting)
00448 {
00449         LLModalDialog::onClose(app_quitting);
00450         handleCallbacks();
00451 }
00452 
00453 LLAlertDialog::~LLAlertDialog()
00454 {
00455         delete[] mButtonData;
00456         if (mUnique)
00457         {
00458                 sUniqueActiveMap.erase(mLabel);
00459         }
00460 }
00461 
00462 void LLAlertDialog::handleCallbacks()
00463 {
00464         if (mOptionChosen >= 0)
00465         {
00466                 if (mTextCallback && mLineEditor)
00467                 {
00468                         mTextCallback(mOptionChosen, mLineEditor->getText(), mUserData);
00469                 }
00470                 else if (mCallback)
00471                 {
00472                         mCallback(mOptionChosen, mUserData);
00473                 }
00474 
00475                 // If we declared a URL and chose the URL option, go to the url
00476                 if (mOptionChosen == mURLOption)
00477                 {
00478                         if (!mURL.empty() && sURLLoader != NULL)
00479                         {
00480                                 sURLLoader->load(mURL);
00481                         }
00482                 }
00483 
00484                 // Only change warn state if we actually warned.
00485                 if (mCheck
00486                         && sSettings->getWarning(mIgnoreLabel))
00487                 {
00488                         // mCheck sometimes means "hide and do the default" and
00489                         // other times means "warn me again".  Yuck. JC
00490                         BOOL check = mCheck->getValue();
00491                         switch(mIgnorable)
00492                         {
00493                         case IGNORE_USE_DEFAULT:
00494                                 sSettings->setWarning(mIgnoreLabel, !check);
00495                                 break;
00496                         case IGNORE_USE_SAVED:
00497                                 sSettings->setWarning(mIgnoreLabel, !check);
00498                                 sSettings->setS32("Default" + mIgnoreLabel, mOptionChosen);
00499                                 break;
00500                         case IGNORE_SHOW_AGAIN:
00501                                 sSettings->setWarning(mIgnoreLabel, check);
00502                                 break;
00503                         default:
00504                                 break;
00505                         }
00506                 }
00507         }
00508 }
00509 BOOL LLAlertDialog::hasTitleBar() const
00510 {
00511         return (getTitle() != "" && getTitle() != " ")  // has title
00512                         || isMinimizeable()
00513                         || isCloseable();
00514 }
00515 
00516 BOOL LLAlertDialog::handleKeyHere(KEY key, MASK mask )
00517 {
00518         if( KEY_RETURN == key && mask == MASK_NONE )
00519         {
00520                 LLModalDialog::handleKeyHere( key, mask );
00521                 return TRUE;
00522         }
00523         else if (KEY_RIGHT == key)
00524         {
00525                 focusNextItem(FALSE);
00526                 return TRUE;
00527         }
00528         else if (KEY_LEFT == key)
00529         {
00530                 focusPrevItem(FALSE);
00531                 return TRUE;
00532         }
00533         else if (KEY_TAB == key && mask == MASK_NONE)
00534         {
00535                 focusNextItem(FALSE);
00536                 return TRUE;
00537         }
00538         else if (KEY_TAB == key && mask == MASK_SHIFT)
00539         {
00540                 focusPrevItem(FALSE);
00541                 return TRUE;
00542         }
00543         else
00544         {
00545                 return LLModalDialog::handleKeyHere( key, mask );
00546         }
00547 }
00548 
00549 // virtual
00550 void LLAlertDialog::draw()
00551 {
00552         // if the default button timer has just expired, activate the default button
00553         if(mDefaultBtnTimer.hasExpired() && mDefaultBtnTimer.getStarted())
00554         {
00555                 mDefaultBtnTimer.stop();  // prevent this block from being run more than once
00556                 setDefaultBtn(mButtonData[mDefaultOption].mButton);
00557         }
00558 
00559         LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
00560         S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
00561 
00562         gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0,
00563                 shadow_color, shadow_lines);
00564 
00565         LLModalDialog::draw();
00566 }
00567 
00568 void LLAlertDialog::setOptionEnabled( S32 option, BOOL enable )
00569 {
00570         if( (option >= 0) && (option < mNumOptions) )
00571         {
00572                 mButtonData[option].mButton->setEnabled( enable );
00573         }
00574 }
00575 
00576 void LLAlertDialog::setEditTextCallback(alert_text_callback_t callback, void *user_data)
00577 {
00578         if (mLineEditor)
00579         {
00580                 mTextCallback = callback;
00581                 mUserData = user_data;
00582         }
00583         else
00584         {
00585                 llwarns << "LLAlertDialog::setEditTextCallback called on dialog with no line editor" << llendl;
00586         }
00587 }
00588 
00589 void LLAlertDialog::setEditTextArgs(const LLString::format_map_t& edit_args)
00590 {
00591         if (mLineEditor)
00592         {
00593                 LLString msg = mLineEditor->getText();
00594                 format(msg, edit_args);
00595                 mLineEditor->setText(msg);
00596         }
00597         else
00598         {
00599                 llwarns << "LLAlertDialog::setEditTextArgs called on dialog with no line editor" << llendl;
00600         }
00601 }
00602 
00603 void LLAlertDialog::setDrawAsterixes(BOOL enable)
00604 {
00605         if (mLineEditor)
00606         {
00607                 if (enable)
00608                 {
00609                         mLineEditor->clear();
00610                 }
00611                 mLineEditor->setDrawAsterixes(enable);
00612         }
00613 }
00614 
00615 // static 
00616 void LLAlertDialog::onButtonPressed( void* userdata )
00617 {
00618         ButtonData* button_data = (ButtonData*)userdata;
00619         LLAlertDialog* self = button_data->mSelf;
00620 
00621         self->mOptionChosen = button_data->mOption;
00622         self->close(); // deletes self
00623 }
00624 
00625 //=============================================================================
00626 
00627 //static
00628 const LLString& LLAlertDialog::getTemplateMessage(const LLString& xml_desc)
00629 {
00630         template_map_t::iterator iter = sAlertTemplates.find(xml_desc);
00631         if (iter != sAlertTemplates.end())
00632         {
00633                 return iter->second->mMessage;
00634         }
00635         else
00636         {
00637                 return xml_desc;
00638         }
00639 }
00640 
00641 //static
00642 bool LLAlertDialog::parseAlerts(const LLString& xml_filename, LLControlGroup* settings, BOOL settings_only)
00643 {
00644         LLXMLNodePtr root;
00645         BOOL success  = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
00646 
00647         if (!success || root.isNull() || !root->hasName( "alerts" ))
00648         {
00649                 llerrs << "Problem reading UI Alerts file: " << xml_filename << llendl;
00650                 return false;
00651         }
00652 
00653         BOOL add_settings = FALSE;
00654         if (settings)
00655         {
00656                 sSettings = settings;
00657                 add_settings = TRUE;
00658         }
00659         llassert(sSettings);
00660         
00661         for (LLXMLNode* alert = root->getFirstChild();
00662                  alert != NULL; alert = alert->getNextSibling())
00663         {
00664                 if (alert->hasName("global"))
00665                 {
00666                         LLString global_name;
00667                         if (alert->getAttributeString("name", global_name))
00668                         {
00669                                 if (global_name == "skipnexttime")
00670                                 {
00671                                         sStringSkipNextTime = alert->getTextContents();
00672                                 }
00673                                 else if (global_name == "alwayschoose")
00674                                 {
00675                                         sStringAlwaysChoose = alert->getTextContents();
00676                                 }
00677                         }
00678                         continue;
00679                 }
00680 
00681                 if (!alert->hasName("alert"))
00682                 {
00683                         continue;
00684                 }
00685                 
00686                 LLAlertDialogTemplate* xml_template = settings_only ? NULL : new LLAlertDialogTemplate;
00687 
00688                 // name=
00689                 LLString alert_name;
00690                 if (alert->getAttributeString("name", alert_name))
00691                 {
00692                         if (xml_template)
00693                         {
00694                                 xml_template->mLabel = alert_name;
00695                         }
00696                 }
00697                 else
00698                 {
00699                         llwarns << "Unable to parse alert with no name" << llendl;
00700                         delete xml_template;
00701                         continue;
00702                 }
00703                 // title=
00704                 LLString title;
00705                 if (alert->getAttributeString("title", title))
00706                 {
00707                         if (xml_template)
00708                         {
00709                                 xml_template->mTitle = title;
00710                         }
00711                 }
00712                 // modal=
00713                 BOOL modal;
00714                 if (alert->getAttributeBOOL("modal", modal))
00715                 {
00716                         if (xml_template)
00717                         {
00718                                 xml_template->mModal = modal;
00719                         }
00720                 }
00721                 // caution=
00722                 BOOL caution;
00723                 if (alert->getAttributeBOOL("caution", caution))
00724                 {
00725                         if (xml_template)
00726                         {
00727                                 xml_template->mCaution = caution;
00728                         }
00729                 }
00730                 // unique=
00731                 BOOL unique;
00732                 if (alert->getAttributeBOOL("unique", unique))
00733                 {
00734                         if (xml_template)
00735                         {
00736                                 xml_template->mUnique = unique;
00737                         }
00738                 }
00739                                 
00740                 S32 default_option = 0;
00741                 BOOL nodefault;
00742                 if (alert->getAttributeBOOL("nodefault", nodefault))
00743                 {
00744                         if (nodefault)
00745                         {
00746                                 if (xml_template)
00747                                 {
00748                                         xml_template->mDefaultOption = -1;
00749                                 }
00750                                 default_option = -1;
00751                         }
00752                 }
00753 
00754                 S32 btn_idx = 0;
00755                 for (LLXMLNode* child = alert->getFirstChild();
00756                          child != NULL; child = child->getNextSibling())
00757                 {
00758                         // <message>
00759                         if (child->hasName("message"))
00760                         {
00761                                 if (xml_template)
00762                                 {
00763                                         xml_template->mMessage = child->getTextContents();
00764                                 }
00765                         }
00766 
00767                         // <option>
00768                         if (child->hasName("option"))
00769                         {
00770                                 LLString label = child->getTextContents();
00771                                 BOOL is_default = FALSE;
00772                                 child->getAttributeBOOL("default", is_default);
00773                                 LLString ignore_text;
00774                                 if (!child->getAttributeString("ignore", ignore_text))
00775                                 {
00776                                         ignore_text = label;
00777                                 }
00778                                 if (xml_template)
00779                                 {
00780                                         xml_template->addOption(label, ignore_text, is_default);
00781                                 }
00782                                 if (is_default)
00783                                 {
00784                                         default_option = btn_idx;
00785                                 }
00786                                 btn_idx++;
00787                         }
00788                 
00789                         // <editline>
00790                         if (child->hasName("editline"))
00791                         {
00792                                 if (xml_template)
00793                                 {
00794                                         xml_template->mEditLineText = child->getTextContents();
00795                                         if (xml_template->mEditLineText.empty())
00796                                         {
00797                                                 xml_template->mEditLineText = " ";
00798                                         }
00799                                 }
00800                         }
00801                         
00802                         // <ignore>
00803                         if (child->hasName("ignore"))
00804                         {
00805                                 LLString ignore_text = child->getTextContents();
00806                                 // label=
00807                                 LLString name;
00808                                 child->getAttributeString("name", name);
00809                                 
00810                                 //always set to alert_name for the sake of i18n
00811                                 //if (name.empty())
00812                                 name = alert_name;
00813                                 
00814                                 if (xml_template)
00815                                 {
00816                                         xml_template->mIgnorable = LLAlertDialog::IGNORE_USE_DEFAULT;
00817                                         xml_template->mIgnoreListText = ignore_text;
00818                                         xml_template->mIgnoreLabel = name;
00819                                 }
00820                                 if (!ignore_text.empty())
00821                                 {
00822                                         if (add_settings)
00823                                         {
00824                                                 settings->addWarning(name);
00825                                         }
00826                                         if (xml_template)
00827                                         {
00828                                                 sIgnorableTemplates[name] = xml_template; // will override any previous entry
00829                                         }
00830                                 }
00831                                 // save_option=
00832                                 BOOL save_option = FALSE;
00833                                 child->getAttributeBOOL("save_option", save_option);
00834                                 if (save_option)
00835                                 {
00836                                         if (xml_template)
00837                                         {
00838                                                 xml_template->mIgnorable = LLAlertDialog::IGNORE_USE_SAVED;
00839                                         }
00840                                         if (add_settings)
00841                                         {
00842                                                 settings->declareS32("Default" + name, default_option, "Default option number for this alert dialog");
00843                                         }
00844                                 }
00845                         }
00846 
00847                         // <url>
00848                         if (child->hasName("url"))
00849                         {
00850                                 S32 url_option = 0;
00851                                 child->getAttributeS32("option", url_option);
00852                                 if (xml_template)
00853                                 {
00854                                         xml_template->mURL = child->getTextContents();
00855                                         xml_template->mURLOption = url_option;
00856                                 }
00857                         }
00858                         
00859                 }
00860                 if (xml_template)
00861                 {
00862                         xml_template->mDefaultOption = default_option;
00863                         sAlertTemplates[xml_template->mLabel] = xml_template;
00864                 }
00865         }
00866         return true;
00867 }

Generated on Fri May 16 08:32:50 2008 for SecondLife by  doxygen 1.5.5