diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 8aa548b9749f4446e7c68f072f93583346fef815..09480968a67cd39d63a83e641ef712968e7fec73 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -399,6 +399,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par : mName(p.name), mType(p.type), mMessage(p.value), + mFooter(p.footer.value), mLabel(p.label), mIcon(p.icon), mURL(p.url.value), @@ -870,6 +871,16 @@ std::string LLNotification::getMessage() const return message; } +std::string LLNotification::getFooter() const +{ + if (!mTemplatep) + return std::string(); + + std::string footer = mTemplatep->mFooter; + LLStringUtil::format(footer, mSubstitutions); + return footer; +} + std::string LLNotification::getLabel() const { std::string label = mTemplatep->mLabel; diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 3df2efcac3a66b63d7dbb092091f84c377bccdf1..4ae02b943fa415c691005db26ee61b753ab37ce4 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -509,6 +509,7 @@ friend class LLNotifications; std::string getType() const; std::string getMessage() const; + std::string getFooter() const; std::string getLabel() const; std::string getURL() const; S32 getURLOption() const; diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index fb50c9c1233b8de79e8d3e27c62b94dce617a35a..72973789db246efdb3c5eab3194ee6c6c4a58978 100644 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -167,6 +167,17 @@ struct LLNotificationTemplate {} }; + struct Footer : public LLInitParam::Block<Footer> + { + Mandatory<std::string> value; + + Footer() + : value("value") + { + addSynonym(value, ""); + } + }; + struct Params : public LLInitParam::Block<Params> { Mandatory<std::string> name; @@ -184,7 +195,8 @@ struct LLNotificationTemplate Optional<FormRef> form_ref; Optional<ENotificationPriority, NotificationPriorityValues> priority; - Multiple<Tag> tags; + Multiple<Tag> tags; + Optional<Footer> footer; Params() @@ -202,7 +214,8 @@ struct LLNotificationTemplate url("url"), unique("unique"), form_ref(""), - tags("tag") + tags("tag"), + footer("footer") {} }; @@ -231,6 +244,8 @@ struct LLNotificationTemplate // The text used to display the notification. Replaceable parameters // are enclosed in square brackets like this []. std::string mMessage; + // The text used to display the notification, but under the form. + std::string mFooter; // The label for the notification; used for // certain classes of notification (those with a window and a window title). // Also used when a notification pops up underneath the current one. diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4e8b6fc39d0d63d2df1ed75405ee672991aa5bab..7e8496e8c2d95de822dc37f612b3e150d95ca63c 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -491,6 +491,7 @@ set(viewer_SOURCE_FILES lltoastnotifypanel.cpp lltoastpanel.cpp lltoastscripttextbox.cpp + lltoastscriptquestion.cpp lltool.cpp lltoolbarview.cpp lltoolbrush.cpp @@ -1039,6 +1040,7 @@ set(viewer_HEADER_FILES lltoastnotifypanel.h lltoastpanel.h lltoastscripttextbox.h + lltoastscriptquestion.h lltool.h lltoolbarview.h lltoolbrush.h diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index 995915206bced30d7eb5a2535c030dfb9f373d35..398f54c6f799d0f41047df69c00f8b7d1cd580e1 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -101,7 +101,7 @@ bool LLScriptHandler::processNotification(const LLSD& notify) } else { - LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); + LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification); LLToast::Params p; p.notif_id = notification->getID(); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index a8060649ba6789d0870d3bf9117f2d6e045594a9..a473ee7ce03f42a80f65c9136fccffc1531302d2 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -52,7 +52,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal; -LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) : +LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) : LLToastPanel(notification), mTextBox(NULL), mInfoPanel(NULL), @@ -536,7 +536,7 @@ void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id } } -void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification) +void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification) { LLSD response = notification->getResponse(); for (LLSD::map_const_iterator response_it = response.beginMap(); diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index 57711b3d80f1a8f9850465481cbca5a42b9be4cb..db517ec8581d8dfd189c55e09216860312b564bb 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -60,7 +60,7 @@ class LLToastNotifyPanel: public LLToastPanel * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to * implement right class for desired toast panel. @see LLGenericTipPanel as example. */ - LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); + LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true); virtual ~LLToastNotifyPanel(); LLPanel * getControlPanel() { return mControlPanel; } @@ -118,7 +118,7 @@ class LLToastNotifyPanel: public LLToastPanel /** * Process response data. Will disable selected options */ - void disableRespondedOptions(LLNotificationPtr& notification); + void disableRespondedOptions(const LLNotificationPtr& notification); bool mIsTip; bool mAddedDefaultBtn; diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index d2a4ce8745a27f655a2a11200d313aebd180a60d..c33fde99c59f4d3ffd9a4abfacde1b9ea7331acf 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -29,7 +29,9 @@ #include "llpanelgenerictip.h" #include "llpanelonlinestatus.h" #include "llnotifications.h" +#include "lltoastnotifypanel.h" #include "lltoastpanel.h" +#include "lltoastscriptquestion.h" //static const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32) @@ -106,6 +108,17 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification( res = new LLPanelGenericTip(notification); } } + else if("notify" == notification->getType()) + { + if (notification->getPriority() == NOTIFICATION_PRIORITY_CRITICAL) + { + res = new LLToastScriptQuestion(notification); + } + else + { + res = new LLToastNotifyPanel(notification); + } + } /* else if(...) create all other specific non-public toast panel diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp new file mode 100644 index 0000000000000000000000000000000000000000..feeb8ca77b7e72fac7b85f7305c6518ae9d0ccf6 --- /dev/null +++ b/indra/newview/lltoastscriptquestion.cpp @@ -0,0 +1,130 @@ +/** + * @file lltoastscriptquestion.cpp + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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" + +#include "llbutton.h" +#include "llnotifications.h" +#include "lltoastscriptquestion.h" + +const int LEFT_PAD = 10; +const int BUTTON_HEIGHT = 27; +const int MAX_LINES_COUNT = 50; + +LLToastScriptQuestion::LLToastScriptQuestion(const LLNotificationPtr& notification) +: +LLToastPanel(notification) +{ + buildFromFile("panel_script_question_toast.xml"); +} + +BOOL LLToastScriptQuestion::postBuild() +{ + createButtons(); + + LLTextBox* mMessage = getChild<LLTextBox>("top_info_message"); + LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message"); + + mMessage->setValue(mNotification->getMessage()); + mFooter->setValue(mNotification->getFooter()); + + snapToMessageHeight(); + + return TRUE; +} +void LLToastScriptQuestion::snapToMessageHeight() +{ + LLTextBox* mMessage = getChild<LLTextBox>("top_info_message"); + LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message"); + if (!mMessage || !mFooter) + { + return; + } + + if (mMessage->getVisible() && mFooter->getVisible()) + { + S32 heightDelta = 0; + S32 maxTextHeight = (mMessage->getDefaultFont()->getLineHeight() * MAX_LINES_COUNT) + + (mFooter->getDefaultFont()->getLineHeight() * MAX_LINES_COUNT); + + LLRect messageRect = mMessage->getRect(); + LLRect footerRect = mFooter->getRect(); + + S32 oldTextHeight = messageRect.getHeight() + footerRect.getHeight(); + + S32 requiredTextHeight = mMessage->getTextBoundingRect().getHeight() + mFooter->getTextBoundingRect().getHeight(); + S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight); + + heightDelta = newTextHeight - oldTextHeight - heightDelta; + + reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT)); + } +} + +void LLToastScriptQuestion::createButtons() +{ + LLNotificationFormPtr form = mNotification->getForm(); + int num_elements = form->getNumElements(); + int buttons_width = 0; + + for (int i = 0; i < num_elements; ++i) + { + LLSD form_element = form->getElement(i); + if ("button" == form_element["type"].asString()) + { + LLButton::Params p; + const LLFontGL* font = LLFontGL::getFontSansSerif(); + p.name(form_element["name"].asString()); + p.label(form_element["text"].asString()); + p.layout("topleft"); + p.font(font); + p.rect.height(BUTTON_HEIGHT); + p.click_callback.function(boost::bind(&LLToastScriptQuestion::onButtonClicked, this, form_element["name"].asString())); + p.rect.left = LEFT_PAD; + p.rect.width = font->getWidth(form_element["text"].asString()); + p.auto_resize = true; + p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); + p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + + LLButton* button = LLUICtrlFactory::create<LLButton>(p); + button->autoResize(); + getChild<LLPanel>("buttons_panel")->addChild(button); + + LLRect rect = button->getRect(); + rect.setLeftTopAndSize(buttons_width, rect.mTop, rect.getWidth(), rect.getHeight()); + button->setRect(rect); + + buttons_width += rect.getWidth() + LEFT_PAD; + } + } +} + +void LLToastScriptQuestion::onButtonClicked(std::string btn_name) +{ + LLSD response = mNotification->getResponseTemplate(); + response[btn_name] = true; + mNotification->respond(response); +} diff --git a/indra/newview/lltoastscriptquestion.h b/indra/newview/lltoastscriptquestion.h new file mode 100644 index 0000000000000000000000000000000000000000..3a557f60f66dc70fde27f855117416ca4691c828 --- /dev/null +++ b/indra/newview/lltoastscriptquestion.h @@ -0,0 +1,49 @@ +/** + * @file lltoastscriptquestion.h + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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" + +#include "lltoastpanel.h" + +#ifndef LLTOASTSCRIPTQUESTION_H_ +#define LLTOASTSCRIPTQUESTION_H_ + +class LLToastScriptQuestion : public LLToastPanel +{ + LOG_CLASS(LLToastScriptQuestion); + +public: + LLToastScriptQuestion(const LLNotificationPtr& notification); + virtual BOOL postBuild(); + virtual ~LLToastScriptQuestion(){}; + +private: + void snapToMessageHeight(); + + void createButtons(); + void onButtonClicked(std::string btn_name); +}; + +#endif /* LLTOASTSCRIPTQUESTION_H_ */ diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 854e2bea5264e3a687a4001595dbd26c4ce00dae..ec42cb39f2f5a452aa8f79afaf3e1266ea2b6254 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5976,16 +5976,21 @@ void process_script_question(LLMessageSystem *msg, void **user_data) args["OBJECTNAME"] = object_name; args["NAME"] = LLCacheName::cleanFullName(owner_name); + BOOL has_not_only_debit = questions ^ LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_DEBIT]; // check the received permission flags against each permission for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) { if (questions & LSCRIPTRunTimePermissionBits[i]) { count++; - script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n"; // check whether permission question should cause special caution dialog caution |= (SCRIPT_QUESTION_IS_CAUTION[i]); + + if (("ScriptTakeMoney" == SCRIPT_QUESTIONS[i]) && has_not_only_debit) + continue; + + script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n"; } } args["QUESTIONS"] = script_question; @@ -6001,6 +6006,10 @@ void process_script_question(LLMessageSystem *msg, void **user_data) // check whether cautions are even enabled or not if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) { + if (caution) + { + args["FOOTERTEXT"] = (count > 1) ? LLTrans::getString("AdditionalPermissionsRequestHeader") + "\n\n" + script_question : ""; + } // display the caution permissions prompt LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload); } diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index afc5b916e77d5345896c82cf41587082bea2a0de..46e467e2301c85a4a767b63ca4b6cdb748e40ea6 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6373,31 +6373,28 @@ Is this OK? <notification icon="notify.tga" name="ScriptQuestionCaution" - priority="high" + priority="critical" persist="true" type="notify"> -An object named '<nolink>[OBJECTNAME]</nolink>', owned by '[NAME]' would like to: - -[QUESTIONS] -If you do not trust this object and its creator, you should deny the request. +Warning: The object '<nolink>[OBJECTNAME]</nolink>' wants total access to your Linden Dollars account. If you allow access, it can remove funds from your account at any time, or empty your account completely, on an ongoing basis with no additional warnings. + +It is rare that such a request is legitimate. Do not allow access if you do not fully understand why it wants access to your account. -Grant this request? <tag>confirm</tag> <form name="form"> <button index="0" name="Grant" - text="Grant"/> + text="Allow total access"/> <button default="true" index="1" name="Deny" text="Deny"/> - <button - index="2" - name="Details" - text="Details..."/> </form> + <footer> +[FOOTERTEXT] + </footer> </notification> <notification diff --git a/indra/newview/skins/default/xui/en/panel_script_question_toast.xml b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml new file mode 100644 index 0000000000000000000000000000000000000000..b0436bb6dcd452f5df2ea05b48485ef4fd650869 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<panel + background_opaque="false" + border_visible="false" + background_visible="true" + bg_alpha_color="PanelNotificationBackground" + bg_opaque_color="PanelNotificationBackground" + chrome="true" + height="270" + label="script_question_panel" + layout="topleft" + left="0" + name="panel_script_question_toast" + top="0" + width="305"> + <text + follows="left|right|top" + font="SansSerifBold" + height="160" + layout="topleft" + left="10" + mouse_opaque="false" + name="top_info_message" + parse_highlights="true" + parse_urls="true" + text_color="NotifyCautionBoxColor" + top="10" + value="" + width="285" + wrap="true"/> + <panel + background_visible="false" + follows="left|right|top" + height="30" + label="buttons_panel" + layout="topleft" + name="buttons_panel" + top_pad="10" + width="285"> + </panel> + <text + follows="all" + font="SansSerifBold" + height="55" + layout="topleft" + mouse_opaque="false" + name="bottom_info_message" + parse_highlights="true" + parse_urls="true" + text_color="NotifyCautionBoxColor" + top_pad="5" + value="" + width="285" + wrap="true"/> +</panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 4ccec4838ac00a6bdf57cd01fee2d23cb5e5a251..866ea296c3a33ed675c8b0e329931060ebd7b857 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -393,6 +393,7 @@ Please try logging in again in a minute.</string> <string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string> <string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string> <string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string> + <string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string> <string name="ScriptTakeMoney">Take Linden dollars (L$) from you</string> <string name="ActOnControlInputs">Act on your control inputs</string> <string name="RemapControlInputs">Remap your control inputs</string>