Merge branch 'DRTVWR-587-maint-V' of https://github.com/secondlife/viewer
# Conflicts: # indra/llui/lllineeditor.cpp # indra/llui/lllineeditor.h # indra/llui/llurlentry.h # indra/llui/llurlregistry.cpp # indra/llui/llurlregistry.h # indra/newview/llviewerinventory.cpp # indra/newview/llvoavatarself.hmeow-7.2.2
commit
63151d5c6d
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -295,13 +295,16 @@ public:
|
|||
void setBgImage(LLPointer<LLUIImage> image) { mBgImage = image; }
|
||||
void setBgImageFocused(LLPointer<LLUIImage> image) { mBgImageFocused = image; }
|
||||
|
||||
void setShowContextMenu(bool show) { mShowContextMenu = show; }
|
||||
bool getShowContextMenu() const { return mShowContextMenu; }
|
||||
|
||||
// <FS:Ansariel> Make these protected
|
||||
void removeChar();
|
||||
void removeWord(bool prev);
|
||||
void addChar(const llwchar c);
|
||||
// </FS:Ansariel>
|
||||
|
||||
private:
|
||||
private:
|
||||
// private helper methods
|
||||
|
||||
void pasteHelper(bool is_primary);
|
||||
|
|
@ -422,6 +425,8 @@ protected:
|
|||
|
||||
LLHandle<LLContextMenu> mContextMenuHandle;
|
||||
|
||||
bool mShowContextMenu;
|
||||
|
||||
private:
|
||||
// Instances that by default point to the statics but can be overidden in XML.
|
||||
LLPointer<LLUIImage> mBgImage;
|
||||
|
|
|
|||
|
|
@ -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<std::string, LLLocalizationData>::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<std::string, LLLocalizationData>::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<LLScrollListItem::Params>::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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<std::string, LLLocalizationData> mLocalizations;
|
||||
LLKeyBindingToStringHandler* pHandler;
|
||||
};
|
||||
|
||||
///
|
||||
/// LLUrlEntryJira Describes Jira issue names -KC
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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:Ansariel> FS Help SLUrl
|
||||
// <FS:Ansariel> 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<LLUrlEntryBase *> mUrlEntry;
|
||||
LLUrlEntryBase* mUrlEntryTrusted;
|
||||
|
|
@ -96,6 +101,7 @@ private:
|
|||
LLUrlEntryBase* mUrlEntryHTTPLabel;
|
||||
LLUrlEntryBase* mUrlEntrySLLabel;
|
||||
LLUrlEntryBase* mUrlEntryNoLink;
|
||||
LLUrlEntryBase* mUrlEntryKeybinding;
|
||||
// <FS:Ansariel> Normalize only trusted URL
|
||||
LLUrlEntryBase* mUrlEntryTrustedUrl;
|
||||
// <FS:Ansariel> Wear folder SLUrl
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<std::string,KEY> 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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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<LLFloaterPreference*>
|
||||
(LLFloaterReg::showInstance("preferences"));
|
||||
|
||||
if (prefsfloater)
|
||||
{
|
||||
// find 'controls' panel and bring it the front
|
||||
LLTabContainer* tabcontainer = prefsfloater->getChild<LLTabContainer>("pref core");
|
||||
LLPanel* panel = prefsfloater->getChild<LLPanel>("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),
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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<LLKeyboardBinding>::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<LLMouseBinding>::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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<KeyBinding>
|
||||
|
|
@ -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<LLKeyboardBinding> &binding,
|
||||
S32 binding_count,
|
||||
|
|
|
|||
|
|
@ -1146,17 +1146,32 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
|
|||
gAgent.sendReliableMessage();
|
||||
}
|
||||
|
||||
void create_inventory_callingcard_callback(LLPointer<LLInventoryCallback> 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(),
|
||||
// <FS:Ansariel> Must provide a parent LLUUID; Default to calling card folder
|
||||
//parent,
|
||||
(parent.isNull() ? gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD) : parent),
|
||||
// </FS:Ansariel>
|
||||
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<LLInventoryCallback> 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(),
|
||||
// <FS:Ansariel> 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,
|
||||
// </FS:Ansariel>
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<void (LLViewerObject*, const LLViewerJointAttachment*, EAttachAction)> attachment_signal_t;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue