diff options
Diffstat (limited to 'indra/newview/lltoastalertpanel.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/lltoastalertpanel.cpp | 264 |
1 files changed, 170 insertions, 94 deletions
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index e4a3f8603b..0a9453534b 100644..100755 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -2,35 +2,28 @@ * @file lltoastalertpanel.cpp * @brief Panel for alert toasts. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * 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 - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - #include "llviewerprecompiledheaders.h" // must be first include #include "linden_common.h" @@ -49,11 +42,12 @@ #include "lllineeditor.h" #include "lluictrlfactory.h" #include "llnotifications.h" -#include "llfunctorregistry.h" +#include "llrootview.h" +#include "lltransientfloatermgr.h" +#include "llviewercontrol.h" // for gSavedSettings const S32 MAX_ALLOWED_MSG_WIDTH = 400; const F32 DEFAULT_BUTTON_DELAY = 0.5f; -const S32 MSG_PAD = 8; /*static*/ LLControlGroup* LLToastAlertPanel::sSettings = NULL; /*static*/ LLToastAlertPanel::URLLoader* LLToastAlertPanel::sURLLoader; @@ -73,13 +67,28 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLabel(notification->getName()), mLineEditor(NULL) { + // EXP-1822 + // save currently focused view, so that return focus to it + // on destroying this toast. + LLView* current_selection = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus()); + while(current_selection) + { + if (current_selection->isFocusRoot()) + { + mPreviouslyFocusedView = current_selection->getHandle(); + break; + } + current_selection = current_selection->getParent(); + } + const LLFontGL* font = LLFontGL::getFontSansSerif(); - const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); + const S32 LINE_HEIGHT = font->getLineHeight(); const S32 EDITOR_HEIGHT = 20; LLNotificationFormPtr form = mNotification->getForm(); std::string edit_text_name; std::string edit_text_contents; + S32 edit_text_max_chars = 0; bool is_password = false; LLToastPanel::setBackgroundVisible(FALSE); @@ -119,6 +128,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal { edit_text_contents = (*it)["value"].asString(); edit_text_name = (*it)["name"].asString(); + edit_text_max_chars = (*it)["max_length_chars"].asInteger(); } else if (type == "password") { @@ -163,13 +173,14 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal // 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 = mNotification->getMessage(); - llwarns << "Alert: " << msg << llendl; + LL_WARNS() << "Alert: " << msg << LL_ENDL; LLTextBox::Params params; params.name("Alert message"); params.font(font); params.tab_stop(false); params.wrap(true); params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); + params.allow_scroll(true); LLTextBox * msg_box = LLUICtrlFactory::create<LLTextBox> (params); // Compute max allowable height for the dialog text, so we can allocate @@ -178,9 +189,16 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal gFloaterView->getRect().getHeight() - LINE_HEIGHT // title bar - 3*VPAD - BTN_HEIGHT; + // reshape to calculate real text width and height msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height ); msg_box->setValue(msg); - msg_box->reshapeToFitText(); + + S32 pixel_width = msg_box->getTextPixelWidth(); + S32 pixel_height = msg_box->getTextPixelHeight(); + + // We should use some space to prevent set textbox's scroller visible when it is unnecessary. + msg_box->reshape( llmin(MAX_ALLOWED_MSG_WIDTH,pixel_width + 2 * msg_box->getHPad() + HPAD), + llmin(max_allowed_msg_height,pixel_height + 2 * msg_box->getVPad()) ) ; const LLRect& text_rect = msg_box->getRect(); S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD; @@ -214,83 +232,116 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal } static LLUIColor alert_caution_text_color = LLUIColorTable::instance().getColor("AlertCautionTextColor"); - static LLUIColor alert_text_color = LLUIColorTable::instance().getColor("AlertTextColor"); if (mCaution) { - LLIconCtrl::Params params; - params.name("icon"); - params.rect(LLRect(msg_x, msg_y, msg_x+32, msg_y-32)); - params.mouse_opaque(false); - params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); - params.tab_stop(false); - LLIconCtrl * icon = LLUICtrlFactory::create<LLIconCtrl> (params); - icon->setValue ("notify_caution_icon.tga"); - icon->setMouseOpaque(FALSE); - LLToastPanel::addChild(icon); + LLIconCtrl* icon = LLUICtrlFactory::getInstance()->createFromFile<LLIconCtrl>("alert_icon.xml", this, LLPanel::child_registry_t::instance()); + if(icon) + { + icon->setRect(LLRect(msg_x, msg_y, msg_x+32, msg_y-32)); + LLToastPanel::addChild(icon); + } + msg_x += 32 + HPAD; msg_box->setColor( alert_caution_text_color ); } - else - { - msg_box->setColor( alert_text_color ); - } LLRect rect; rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() ); msg_box->setRect( rect ); LLToastPanel::addChild(msg_box); - // Buttons - S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2; - - for( S32 i = 0; i < num_options; i++ ) + // (Optional) Edit Box + if (!edit_text_name.empty()) { - LLRect button_rect; - button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT ); + S32 y = VPAD + BTN_HEIGHT + VPAD/2; + mLineEditor = LLUICtrlFactory::getInstance()->createFromFile<LLLineEditor>("alert_line_editor.xml", this, LLPanel::child_registry_t::instance()); + + if (mLineEditor) + { + LLRect leditor_rect = LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y); + mLineEditor->setName(edit_text_name); + mLineEditor->reshape(leditor_rect.getWidth(), leditor_rect.getHeight()); + mLineEditor->setRect(leditor_rect); + mLineEditor->setMaxTextChars(edit_text_max_chars); + mLineEditor->setText(edit_text_contents); + + if("SaveOutfitAs" == mNotification->getName()) + { + mLineEditor->setPrevalidate(&LLTextValidate::validateASCII); + } - LLButton::Params p; - p.name(options[i].first); - p.rect(button_rect); - p.click_callback.function(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i)); - p.font(font); - p.label(options[i].second); + // decrease limit of line editor of teleport offer dialog to avoid truncation of + // location URL in invitation message, see EXT-6891 + if ("OfferTeleport" == mNotification->getName()) + { + mLineEditor->setMaxTextLength(gSavedSettings.getS32( + "teleport_offer_invitation_max_length")); + } + else + { + mLineEditor->setMaxTextLength(STD_STRING_STR_LEN - 1); + } - LLButton* btn = LLUICtrlFactory::create<LLButton>(p); - mButtonData[i].mButton = btn; + LLToastPanel::addChild(mLineEditor); - LLToastPanel::addChild(btn); + mLineEditor->setDrawAsterixes(is_password); - if( i == mDefaultOption ) - { - btn->setFocus(TRUE); - } + setEditTextArgs(notification->getSubstitutions()); - button_left += button_width + BTN_HPAD; + mLineEditor->setFollowsLeft(); + mLineEditor->setFollowsRight(); + + // find form text input field + LLSD form_text; + for (LLSD::array_const_iterator it = form_sd.beginArray(); it != form_sd.endArray(); ++it) + { + std::string type = (*it)["type"].asString(); + if (type == "text") + { + form_text = (*it); + } + } + + // if form text input field has width attribute + if (form_text.has("width")) + { + // adjust floater width to fit line editor + S32 editor_width = form_text["width"]; + LLRect editor_rect = mLineEditor->getRect(); + U32 width_delta = editor_width - editor_rect.getWidth(); + LLRect toast_rect = getRect(); + reshape(toast_rect.getWidth() + width_delta, toast_rect.getHeight()); + } + } } - // (Optional) Edit Box - if (!edit_text_name.empty()) + // Buttons + S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2; + + for( S32 i = 0; i < num_options; i++ ) { - S32 y = VPAD + BTN_HEIGHT + VPAD/2; + LLRect button_rect; - LLLineEditor::Params params; - params.name(edit_text_name); - params.rect(LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y)); - params.default_text(edit_text_contents); - params.max_length_bytes(STD_STRING_STR_LEN); - mLineEditor = LLUICtrlFactory::create<LLLineEditor> (params); + LLButton* btn = LLUICtrlFactory::getInstance()->createFromFile<LLButton>("alert_button.xml", this, LLPanel::child_registry_t::instance()); + if(btn) + { + btn->setName(options[i].first); + btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT )); + btn->setLabel(options[i].second); + btn->setFont(font); - // make sure all edit keys get handled properly (DEV-22396) - mLineEditor->setHandleEditKeysDirectly(TRUE); + btn->setClickedCallback(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i)); - LLToastPanel::addChild(mLineEditor); - } - - if (mLineEditor) - { - mLineEditor->setDrawAsterixes(is_password); + mButtonData[i].mButton = btn; + + LLToastPanel::addChild(btn); - setEditTextArgs(notification->getSubstitutions()); + if( i == mDefaultOption ) + { + btn->setFocus(TRUE); + } + } + button_left += button_width + BTN_HPAD; } std::string ignore_label; @@ -309,6 +360,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal if (mLineEditor) { mLineEditor->selectAll(); + mLineEditor->setFocus(TRUE); } if(mDefaultOption >= 0) { @@ -316,12 +368,22 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mDefaultBtnTimer.start(); mDefaultBtnTimer.setTimerExpirySec(DEFAULT_BUTTON_DELAY); } + + LLTransientFloaterMgr::instance().addControlView( + LLTransientFloaterMgr::GLOBAL, this); } bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control ) { - const LLFontGL* font = LLFontGL::getFontSansSerif(); - const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); + mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance()); + + if(!mCheck) + { + return false; + } + + const LLFontGL* font = mCheck->getFont(); + const S32 LINE_HEIGHT = font->getLineHeight(); // Extend dialog for "check next time" S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD; @@ -336,14 +398,13 @@ bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std:: LLToastPanel::reshape( dialog_width, dialog_height, FALSE ); S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2; + + // set check_box's attributes + LLRect check_rect; + mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT)); + mCheck->setLabel(check_title); + mCheck->setCommitCallback(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1)); - LLCheckBoxCtrl::Params p; - p.name("check"); - p.rect.left(msg_x).bottom(VPAD+BTN_HEIGHT+LINE_HEIGHT/2).width(max_msg_width).height(LINE_HEIGHT); - p.label(check_title); - p.font(font); - p.commit_callback.function(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1)); - mCheck = LLUICtrlFactory::create<LLCheckBoxCtrl>(p); LLToastPanel::addChild(mCheck); return true; @@ -363,6 +424,15 @@ void LLToastAlertPanel::setVisible( BOOL visible ) LLToastAlertPanel::~LLToastAlertPanel() { + LLTransientFloaterMgr::instance().removeControlView( + LLTransientFloaterMgr::GLOBAL, this); + + // EXP-1822 + // return focus to the previously focused view if the viewer is not exiting + if (mPreviouslyFocusedView.get() && !LLApp::isExiting()) + { + mPreviouslyFocusedView.get()->setFocus(TRUE); + } } BOOL LLToastAlertPanel::hasTitleBar() const @@ -380,6 +450,12 @@ BOOL LLToastAlertPanel::handleKeyHere(KEY key, MASK mask ) { if( KEY_RETURN == key && mask == MASK_NONE ) { + LLButton* defaultBtn = getDefaultButton(); + if(defaultBtn && defaultBtn->getVisible() && defaultBtn->getEnabled()) + { + // If we have a default button, click it when return is pressed + defaultBtn->onCommit(); + } return TRUE; } else if (KEY_RIGHT == key) @@ -419,7 +495,7 @@ void LLToastAlertPanel::draw() } static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow"); - static LLUICachedControl<S32> shadow_lines ("DropShadowFloater"); + static LLUICachedControl<S32> shadow_lines ("DropShadowFloater", 5); gl_drop_shadow( 0, LLToastPanel::getRect().getHeight(), LLToastPanel::getRect().getWidth(), 0, shadow_color, shadow_lines); @@ -436,7 +512,7 @@ void LLToastAlertPanel::setEditTextArgs(const LLSD& edit_args) } else { - llwarns << "LLToastAlertPanel::setEditTextArgs called on dialog with no line editor" << llendl; + LL_WARNS() << "LLToastAlertPanel::setEditTextArgs called on dialog with no line editor" << LL_ENDL; } } |