diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index dfcb5afecf..0cf555d769 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -29,15 +29,6 @@ else() set( USE_AUTOBUILD_3P ON ) endif() -# The viewer code base can now be successfully compiled with -std=c++14. But -# turning that on in the generic viewer-build-variables/variables file would -# potentially require tweaking each of our ~50 third-party library builds. -# Until we decide to set -std=c++14 in viewer-build-variables/variables, set -# it locally here: we want to at least prevent inadvertently reintroducing -# viewer code that would fail with C++14. -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - include(Variables) include(BuildVersion) diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 86a26df6ad..3e181c6bea 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -165,6 +165,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mPreeditBgColor(p.preedit_bg_color()), mGLFont(p.font), mContextMenuHandle(), + mShowContextMenu(true), mAutoreplaceCallback() { llassert( mMaxLengthBytes > 0 ); @@ -828,7 +829,7 @@ BOOL LLLineEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) { setFocus(TRUE); - if (!LLUICtrl::handleRightMouseDown(x, y, mask)) + if (!LLUICtrl::handleRightMouseDown(x, y, mask) && getShowContextMenu()) { showContextMenu(x, y); } diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index a7b4029d32..4833c76179 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -295,13 +295,16 @@ public: void setBgImage(LLPointer image) { mBgImage = image; } void setBgImageFocused(LLPointer image) { mBgImageFocused = image; } + void setShowContextMenu(bool show) { mShowContextMenu = show; } + bool getShowContextMenu() const { return mShowContextMenu; } + // Make these protected void removeChar(); void removeWord(bool prev); void addChar(const llwchar c); // -private: + private: // private helper methods void pasteHelper(bool is_primary); @@ -422,6 +425,8 @@ protected: LLHandle mContextMenuHandle; + bool mShowContextMenu; + private: // Instances that by default point to the statics but can be overidden in XML. LLPointer mBgImage; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 29e117aa9f..c1d6696b69 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -35,7 +35,9 @@ #include "llavatarnamecache.h" #include "llcachename.h" +#include "llkeyboard.h" #include "llregex.h" +#include "llscrolllistctrl.h" // for LLUrlEntryKeybinding file parsing #include "lltrans.h" #include "lluicolortable.h" #include "message.h" @@ -1837,3 +1839,122 @@ std::string LLUrlEntryIPv6::getUrl(const std::string &string) const { return string; } + + +// +// LLUrlEntryKeybinding Displays currently assigned key +// +LLUrlEntryKeybinding::LLUrlEntryKeybinding() + : LLUrlEntryBase() + , pHandler(NULL) +{ + mPattern = boost::regex(APP_HEADER_REGEX "/keybinding/\\w+(\\?mode=\\w+)?$", + boost::regex::perl | boost::regex::icase); + mMenuName = "menu_url_experience.xml"; + + initLocalization(); +} + +std::string LLUrlEntryKeybinding::getLabel(const std::string& url, const LLUrlLabelCallback& cb) +{ + std::string control = getControlName(url); + + std::map::iterator iter = mLocalizations.find(control); + + std::string keybind; + if (pHandler) + { + keybind = pHandler->getKeyBindingAsString(getMode(url), control); + } + + if (iter != mLocalizations.end()) + { + return iter->second.mLocalization + ": " + keybind; + } + + return control + ": " + keybind; +} + +std::string LLUrlEntryKeybinding::getTooltip(const std::string& url) const +{ + std::string control = getControlName(url); + + std::map::const_iterator iter = mLocalizations.find(control); + if (iter != mLocalizations.end()) + { + return iter->second.mTooltip; + } + return url; +} + +std::string LLUrlEntryKeybinding::getControlName(const std::string& url) const +{ + std::string search = "/keybinding/"; + size_t pos_start = url.find(search); + if (pos_start == std::string::npos) + { + return std::string(); + } + pos_start += search.size(); + + size_t pos_end = url.find("?mode="); + if (pos_end == std::string::npos) + { + pos_end = url.size(); + } + return url.substr(pos_start, pos_end - pos_start); +} + +std::string LLUrlEntryKeybinding::getMode(const std::string& url) const +{ + std::string search = "?mode="; + size_t pos_start = url.find(search); + if (pos_start == std::string::npos) + { + return std::string(); + } + pos_start += search.size(); + return url.substr(pos_start, url.size() - pos_start); +} + +void LLUrlEntryKeybinding::initLocalization() +{ + initLocalizationFromFile("control_table_contents_movement.xml"); + initLocalizationFromFile("control_table_contents_camera.xml"); + initLocalizationFromFile("control_table_contents_editing.xml"); + initLocalizationFromFile("control_table_contents_media.xml"); +} + +void LLUrlEntryKeybinding::initLocalizationFromFile(const std::string& filename) +{ + LLXMLNodePtr xmlNode; + LLScrollListCtrl::Contents contents; + if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode)) + { + LL_WARNS() << "Failed to load " << filename << LL_ENDL; + return; + } + LLXUIParser parser; + parser.readXUI(xmlNode, contents, filename); + + if (!contents.validateBlock()) + { + LL_WARNS() << "Failed to validate " << filename << LL_ENDL; + return; + } + + for (LLInitParam::ParamIterator::const_iterator row_it = contents.rows.begin(); + row_it != contents.rows.end(); + ++row_it) + { + std::string control = row_it->value.getValue().asString(); + if (!control.empty() && control != "menu_separator") + { + mLocalizations[control] = + LLLocalizationData( + row_it->columns.begin()->value.getValue().asString(), + row_it->columns.begin()->tool_tip.getValue() + ); + } + } +} diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index cfdab0c64c..3e90de938d 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -625,6 +625,39 @@ public: std::string mHostPath; }; +class LLKeyBindingToStringHandler; + +/// +/// LLUrlEntryKeybinding A way to access keybindings and show currently used one in text. +/// secondlife:///app/keybinding/control_name +class LLUrlEntryKeybinding: public LLUrlEntryBase +{ +public: + LLUrlEntryKeybinding(); + /*virtual*/ std::string getLabel(const std::string& url, const LLUrlLabelCallback& cb); + /*virtual*/ std::string getTooltip(const std::string& url) const; + void setHandler(LLKeyBindingToStringHandler* handler) {pHandler = handler;} +private: + std::string getControlName(const std::string& url) const; + std::string getMode(const std::string& url) const; + void initLocalization(); + void initLocalizationFromFile(const std::string& filename); + + struct LLLocalizationData + { + LLLocalizationData() {} + LLLocalizationData(const std::string& localization, const std::string& tooltip) + : mLocalization(localization) + , mTooltip(tooltip) + {} + std::string mLocalization; + std::string mTooltip; + }; + + std::map mLocalizations; + LLKeyBindingToStringHandler* pHandler; +}; + /// /// LLUrlEntryJira Describes Jira issue names -KC /// diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 81b0ba6d05..dcc2197982 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -41,7 +41,7 @@ LLUrlRegistry::LLUrlRegistry() { // mUrlEntry.reserve(20); // [RLVa:KB] - Checked: 2010-11-01 (RLVa-1.2.2a) | Added: RLVa-1.2.2a - mUrlEntry.reserve(29); + mUrlEntry.reserve(30); // [/RLVa:KB] // Urls are matched in the order that they were registered @@ -85,6 +85,8 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntryPlace()); registerUrl(new LLUrlEntryInventory()); registerUrl(new LLUrlEntryExperienceProfile()); + mUrlEntryKeybinding = new LLUrlEntryKeybinding(); + registerUrl(mUrlEntryKeybinding); registerUrl(new FSHelpDebugUrlEntrySL()); // FS Help SLUrl // Wear folder SLUrl mUrlEntryWear = new FSUrlEntryWear(); @@ -397,3 +399,9 @@ bool LLUrlRegistry::isUrl(const LLWString &text) } return false; } + +void LLUrlRegistry::setKeybindingHandler(LLKeyBindingToStringHandler* handler) +{ + LLUrlEntryKeybinding *entry = (LLUrlEntryKeybinding*)mUrlEntryKeybinding; + entry->setHandler(handler); +} diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index fad69cdd9f..801f4cbfd7 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -36,6 +36,8 @@ #include #include +class LLKeyBindingToStringHandler; + /// This default callback for findUrl() simply ignores any label updates void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, @@ -88,6 +90,9 @@ public: bool isUrl(const std::string &text); bool isUrl(const LLWString &text); + // Set handler for url registry to be capable of parsing and populating keybindings + void setKeybindingHandler(LLKeyBindingToStringHandler* handler); + private: std::vector mUrlEntry; LLUrlEntryBase* mUrlEntryTrusted; @@ -96,6 +101,7 @@ private: LLUrlEntryBase* mUrlEntryHTTPLabel; LLUrlEntryBase* mUrlEntrySLLabel; LLUrlEntryBase* mUrlEntryNoLink; + LLUrlEntryBase* mUrlEntryKeybinding; // Normalize only trusted URL LLUrlEntryBase* mUrlEntryTrustedUrl; // Wear folder SLUrl diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 0711356afb..a6a80c6aa5 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -367,6 +367,45 @@ std::string LLKeyboard::stringFromKey(KEY key, bool translate) return res; } +//static +std::string LLKeyboard::stringFromMouse(EMouseClickType click, bool translate) +{ + std::string res; + switch (click) + { + case CLICK_LEFT: + res = "LMB"; + break; + case CLICK_MIDDLE: + res = "MMB"; + break; + case CLICK_RIGHT: + res = "RMB"; + break; + case CLICK_BUTTON4: + res = "MB4"; + break; + case CLICK_BUTTON5: + res = "MB5"; + break; + case CLICK_DOUBLELEFT: + res = "Double LMB"; + break; + default: + break; + } + + if (translate && !res.empty()) + { + LLKeyStringTranslatorFunc* trans = gKeyboard->mStringTranslator; + if (trans != NULL) + { + res = trans(res.c_str()); + } + } + return res; +} + //static std::string LLKeyboard::stringFromAccelerator(MASK accel_mask) { @@ -434,6 +473,18 @@ std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key ) return res; } +//static +std::string LLKeyboard::stringFromAccelerator(MASK accel_mask, EMouseClickType click) +{ + std::string res; + if (CLICK_NONE == click) + { + return res; + } + res.append(stringFromAccelerator(accel_mask)); + res.append(stringFromMouse(click)); + return res; +} //static BOOL LLKeyboard::maskFromString(const std::string& str, MASK *mask) diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index c067cdd034..df859f2a41 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -111,8 +111,10 @@ public: static BOOL maskFromString(const std::string& str, MASK *mask); // False on failure static BOOL keyFromString(const std::string& str, KEY *key); // False on failure static std::string stringFromKey(KEY key, bool translate = true); + static std::string stringFromMouse(EMouseClickType click, bool translate = true); static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"... static std::string stringFromAccelerator( MASK accel_mask, KEY key ); + static std::string stringFromAccelerator(MASK accel_mask, EMouseClickType click); void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; } F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed. @@ -150,6 +152,13 @@ protected: static std::map sNamesToKeys; }; +// Interface to get key from assigned command +class LLKeyBindingToStringHandler +{ +public: + virtual std::string getKeyBindingAsString(const std::string& mode, const std::string& control) const = 0; +}; + extern LLKeyboard *gKeyboard; #endif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8eedfbbc88..c7839ac75b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -211,6 +211,7 @@ #include "llhudeffecttrail.h" #include "llvectorperfoptions.h" #include "llslurl.h" +#include "llurlregistry.h" #include "llwatchdog.h" // Included so that constants/settings might be initialized @@ -5131,6 +5132,7 @@ void LLAppViewer::loadKeyBindings() LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL; } } + LLUrlRegistry::instance().setKeybindingHandler(&gViewerInput); } void LLAppViewer::purgeCache() diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index aef117941e..71da61e92c 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -418,11 +418,49 @@ void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator) } } } -// static -std::string LLFloaterPreference::sSkin = ""; + +// handle secondlife:///app/worldmap/{NAME}/{COORDS} URLs +// Also see LLUrlEntryKeybinding, the value of this command type +// is ability to show up to date value in chat +class LLKeybindingHandler: public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLKeybindingHandler(): LLCommandHandler("keybinding", UNTRUSTED_CLICK_ONLY) + { + } + + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() < 1) return false; + + LLFloaterPreference* prefsfloater = dynamic_cast + (LLFloaterReg::showInstance("preferences")); + + if (prefsfloater) + { + // find 'controls' panel and bring it the front + LLTabContainer* tabcontainer = prefsfloater->getChild("pref core"); + LLPanel* panel = prefsfloater->getChild("controls"); + if (tabcontainer && panel) + { + tabcontainer->selectTabPanel(panel); + } + } + + return true; + } +}; +LLKeybindingHandler gKeybindHandler; + + ////////////////////////////////////////////// // LLFloaterPreference +// static +std::string LLFloaterPreference::sSkin = ""; + LLFloaterPreference::LLFloaterPreference(const LLSD& key) : LLFloater(key), mGotPersonalInfo(false), diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 38811ab250..84870a2aac 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -534,20 +534,7 @@ void LLFriendCardsManager::syncFriendsFolder() // Create own calling card if it was not found in Friends/All folder if (!collector.isAgentCallingCardFound()) { - LLAvatarName av_name; - LLAvatarNameCache::get( gAgentID, &av_name ); - - create_inventory_item(gAgentID, - gAgent.getSessionID(), - calling_cards_folder_id, - LLTransactionID::tnull, - av_name.getCompleteName(), - gAgentID.asString(), - LLAssetType::AT_CALLINGCARD, - LLInventoryType::IT_CALLINGCARD, - NO_INV_SUBTYPE, - PERM_MOVE | PERM_TRANSFER, - NULL); + create_inventory_callingcard(gAgentID, calling_cards_folder_id); } // All folders created and updated. diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d5570cd6f7..a4402a5c1c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4576,7 +4576,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items || is_recent_panel || !trash || trash->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN - || trash->getDescendentCount() == LLViewerInventoryCategory::VERSION_UNKNOWN) + || trash->getDescendentCount() == LLViewerInventoryCategory::VERSION_UNKNOWN + || gAgentAvatarp->hasAttachmentsInTrash()) { disabled_items.push_back(std::string("Empty Trash")); } diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index 60f8aca94c..4a0ee8fd0c 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -74,40 +74,6 @@ std::string string_from_mask(MASK mask) return res; } -std::string string_from_mouse(EMouseClickType click, bool translate) -{ - std::string res; - switch (click) - { - case CLICK_LEFT: - res = "LMB"; - break; - case CLICK_MIDDLE: - res = "MMB"; - break; - case CLICK_RIGHT: - res = "RMB"; - break; - case CLICK_BUTTON4: - res = "MB4"; - break; - case CLICK_BUTTON5: - res = "MB5"; - break; - case CLICK_DOUBLELEFT: - res = "Double LMB"; - break; - default: - break; - } - - if (translate && !res.empty()) - { - res = LLTrans::getString(res); - } - return res; -} - // LLKeyConflictHandler S32 LLKeyConflictHandler::sTemporaryFileUseCount = 0; @@ -270,7 +236,7 @@ std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata) result = LLKeyboard::stringFromAccelerator(keydata.mMask); } - result += string_from_mouse(keydata.mMouse, true); + result += LLKeyboard::stringFromMouse(keydata.mMouse); return result; } @@ -545,7 +511,7 @@ void LLKeyConflictHandler::saveToSettings(bool temporary) { // set() because 'optional', for compatibility purposes // just copy old keys.xml and rename to key_bindings.xml, it should work - binding.mouse.set(string_from_mouse(data.mMouse, false), true); + binding.mouse.set(LLKeyboard::stringFromMouse(data.mMouse, false), true); } binding.command = iter->first; mode.bindings.add(binding); diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index a6b51555a8..91da32bede 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -406,7 +406,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) LL_WARNS() << "Error loading navigation bar context menu" << LL_ENDL; } - getTextEntry()->setRightMouseUpCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked,this,_2,_3,_4)); + //don't show default context menu + getTextEntry()->setShowContextMenu(false); + getTextEntry()->setRightMouseDownCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked, this, _2, _3, _4)); updateWidgetlayout(); // Connecting signal for updating location on "Show Coordinates" setting change. diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 430fd1a86a..b7270112a7 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -1083,34 +1083,50 @@ LLViewerInput::LLViewerInput() } } -// static -BOOL LLViewerInput::modeFromString(const std::string& string, S32 *mode) +LLViewerInput::~LLViewerInput() { - if (string == "FIRST_PERSON") + +} + +// static +bool LLViewerInput::modeFromString(const std::string& string, S32 *mode) +{ + if (string.empty()) + { + return false; + } + + std::string cmp_string = string; + LLStringUtil::toLower(cmp_string); + if (cmp_string == "first_person") { *mode = MODE_FIRST_PERSON; - return TRUE; + return true; } - else if (string == "THIRD_PERSON") + else if (cmp_string == "third_person") { *mode = MODE_THIRD_PERSON; - return TRUE; + return true; } - else if (string == "EDIT_AVATAR") + else if (cmp_string == "edit_avatar") { *mode = MODE_EDIT_AVATAR; - return TRUE; + return true; } - else if (string == "SITTING") + else if (cmp_string == "sitting") { *mode = MODE_SITTING; - return TRUE; - } - else - { - *mode = MODE_THIRD_PERSON; - return FALSE; + return true; } + + S32 val = atoi(string.c_str()); + if (val >= 0 || val < MODE_COUNT) + { + *mode = val; + return true; + } + + return false; } // static @@ -1315,6 +1331,7 @@ BOOL LLViewerInput::bindKey(const S32 mode, const KEY key, const MASK mask, cons bind.mKey = key; bind.mMask = mask; bind.mFunction = function; + bind.mFunctionName = function_name; if (result->mIsGlobal) { @@ -1396,6 +1413,7 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const bind.mMouse = mouse; bind.mMask = mask; bind.mFunction = function; + bind.mFunctionName = function_name; if (result->mIsGlobal) { @@ -1894,3 +1912,49 @@ bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask } return false; } + +std::string LLViewerInput::getKeyBindingAsString(const std::string& mode, const std::string& control) const +{ + S32 keyboard_mode; + if (!modeFromString(mode, &keyboard_mode)) + { + keyboard_mode = getMode(); + } + + std::string res; + bool needs_separator = false; + + // keybindings are sorted from having most mask to no mask (from restrictive to less restrictive), + // but it's visually better to present this data in reverse + std::vector::const_reverse_iterator iter_key = mKeyBindings[keyboard_mode].rbegin(); + while (iter_key != mKeyBindings[keyboard_mode].rend()) + { + if (iter_key->mFunctionName == control) + { + if (needs_separator) + { + res.append(" | "); + } + res.append(LLKeyboard::stringFromAccelerator(iter_key->mMask, iter_key->mKey)); + needs_separator = true; + } + iter_key++; + } + + std::vector::const_reverse_iterator iter_mouse = mMouseBindings[keyboard_mode].rbegin(); + while (iter_mouse != mMouseBindings[keyboard_mode].rend()) + { + if (iter_mouse->mFunctionName == control) + { + if (needs_separator) + { + res.append(" | "); + } + res.append(LLKeyboard::stringFromAccelerator(iter_mouse->mMask, iter_mouse->mMouse)); + needs_separator = true; + } + iter_mouse++; + } + + return res; +} diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h index d5c8e6c8e1..694c6505fa 100644 --- a/indra/newview/llviewerinput.h +++ b/indra/newview/llviewerinput.h @@ -28,12 +28,13 @@ #define LL_LLVIEWERINPUT_H #include "llkeyboard.h" // For EKeystate -#include "llinitparam.h" const S32 MAX_KEY_BINDINGS = 128; // was 60 const S32 keybindings_xml_version = 1; const std::string script_mouse_handler_name = "script_trigger_lbutton"; +class LLWindow; + class LLNamedFunction { public: @@ -51,6 +52,7 @@ public: MASK mMask; LLKeyFunc mFunction; + std::string mFunctionName; }; class LLMouseBinding @@ -60,6 +62,7 @@ public: MASK mMask; LLKeyFunc mFunction; + std::string mFunctionName; }; @@ -72,11 +75,7 @@ typedef enum e_keyboard_mode MODE_COUNT } EKeyboardMode; -class LLWindow; - -void bind_keyboard_functions(); - -class LLViewerInput +class LLViewerInput : public LLKeyBindingToStringHandler { public: struct KeyBinding : public LLInitParam::Block @@ -107,6 +106,7 @@ public: }; LLViewerInput(); + virtual ~LLViewerInput(); BOOL handleKey(KEY key, MASK mask, BOOL repeated); BOOL handleKeyUp(KEY key, MASK mask); @@ -121,7 +121,7 @@ public: S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error EKeyboardMode getMode() const; - static BOOL modeFromString(const std::string& string, S32 *mode); // False on failure + static bool modeFromString(const std::string& string, S32 *mode); // False on failure static BOOL mouseFromString(const std::string& string, EMouseClickType *mode);// False on failure bool scanKey(KEY key, @@ -136,6 +136,9 @@ public: bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const; bool isLMouseHandlingDefault(const S32 mode) const { return mLMouseDefaultHandling[mode]; } + // inherited from LLKeyBindingToStringHandler + virtual std::string getKeyBindingAsString(const std::string& mode, const std::string& control) const override; + private: bool scanKey(const std::vector &binding, S32 binding_count, diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 04b2b1de68..65151e5ec5 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1146,17 +1146,32 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id, gAgent.sendReliableMessage(); } +void create_inventory_callingcard_callback(LLPointer cb, + const LLUUID &parent, + const LLUUID &avatar_id, + const LLAvatarName &av_name) +{ + std::string item_desc = avatar_id.asString(); + create_inventory_item(gAgent.getID(), + gAgent.getSessionID(), + // Must provide a parent LLUUID; Default to calling card folder + //parent, + (parent.isNull() ? gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD) : parent), + // + LLTransactionID::tnull, + av_name.getUserName(), + item_desc, + LLAssetType::AT_CALLINGCARD, + LLInventoryType::IT_CALLINGCARD, + NO_INV_SUBTYPE, + PERM_MOVE | PERM_TRANSFER, + cb); +} + void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent /*= LLUUID::null*/, LLPointer cb/*=NULL*/) { - std::string item_desc = avatar_id.asString(); LLAvatarName av_name; - LLAvatarNameCache::get(avatar_id, &av_name); - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - // Must provide a parent LLUUID; Default to calling card folder - //parent, LLTransactionID::tnull, av_name.getUserName(), item_desc, LLAssetType::AT_CALLINGCARD, - (parent.isNull() ? gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD) : parent), LLTransactionID::tnull, av_name.getUserName(), item_desc, LLAssetType::AT_CALLINGCARD, - // - LLInventoryType::IT_CALLINGCARD, NO_INV_SUBTYPE, PERM_MOVE | PERM_TRANSFER, cb); + LLAvatarNameCache::get(avatar_id, boost::bind(&create_inventory_callingcard_callback, cb, parent, _1, _2)); } void create_inventory_wearable(const LLUUID& agent_id, const LLUUID& session_id, diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 5b57c7c4bc..230a13f98e 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1785,6 +1785,27 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) return FALSE; } +bool LLVOAvatarSelf::hasAttachmentsInTrash() +{ + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) + { + LLViewerJointAttachment *attachment = iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = attachment_iter->get(); + if (attached_object && gInventory.isObjectDescendentOf(attached_object->getAttachmentItemID(), trash_id)) + { + return true; + } + } + } + return false; +} + // static BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 8d244fbec3..ac29890eca 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -336,6 +336,8 @@ public: /*virtual*/ BOOL detachObject(LLViewerObject *viewer_object); static BOOL detachAttachmentIntoInventory(const LLUUID& item_id); + bool hasAttachmentsInTrash(); + // [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) enum EAttachAction { ACTION_ATTACH, ACTION_DETACH }; typedef boost::signals2::signal attachment_signal_t; diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index be7b2b1453..eabbb33e63 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -1100,6 +1100,8 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) readCacheHeader(); + LL_INFOS() << "Viewer Object Cache Versions - expected: " << cache_version << " found: " << mMetaInfo.mVersion << LL_ENDL; + if( mMetaInfo.mVersion != cache_version || mMetaInfo.mAddressSize != expected_address) { @@ -1110,7 +1112,8 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) clearCacheInMemory(); } else //delete the current cache if the format does not match. - { + { + LL_INFOS() << "Viewer Object Cache Versions unmatched. clearing cache." << LL_ENDL; removeCache(); } }