SL-13418 Added converter from old mouse binding settings to new ones
parent
ceea2df596
commit
d07ef7df92
|
|
@ -53,7 +53,7 @@ public:
|
|||
EMouseClickType mMouse;
|
||||
KEY mKey;
|
||||
MASK mMask;
|
||||
// Either to expect exact match or ignore not expected masks
|
||||
// Either to expect exact match or ignore not expected masks as long as expected mask-bit is present
|
||||
bool mIgnoreMasks;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -224,7 +224,6 @@
|
|||
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
|
||||
|
||||
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
|
||||
<binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
|
||||
</sitting>
|
||||
<edit_avatar>
|
||||
<!--Avatar editing camera controls-->
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "llwindow.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llviewerstatsrecorder.h"
|
||||
#include "llkeyconflict.h" // for legacy keybinding support, remove later
|
||||
#include "llmarketplacefunctions.h"
|
||||
#include "llmarketplacenotifications.h"
|
||||
#include "llmd5.h"
|
||||
|
|
@ -1004,6 +1005,104 @@ bool LLAppViewer::init()
|
|||
|
||||
// Load User's bindings
|
||||
std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
|
||||
#if 1
|
||||
// Legacy support
|
||||
// Remove #if-#endif section half a year after DRTVWR-501 releases.
|
||||
// Mouse actions are part of keybinding file since DRTVWR-501 instead of being stored in
|
||||
// settings.xml. To support legacy viewers that were storing in settings.xml we need to
|
||||
// transfer old variables to new format.
|
||||
// Also part of backward compatibility is present in LLKeyConflictHandler to modify
|
||||
// legacy variables on changes in new system (to make sure we won't enforce
|
||||
// legacy values again if user dropped to defaults in new system)
|
||||
if (mIsFirstRun
|
||||
&& !gDirUtilp->fileExists(key_bindings_file)) // if file is missing, assume that there were no changes by user yet
|
||||
{
|
||||
// copy mouse actions and voice key changes to new file
|
||||
LL_INFOS("InitInfo") << "Converting legacy mouse bindings to new format" << LL_ENDL;
|
||||
// Load settings from file
|
||||
LLKeyConflictHandler third_person_view(LLKeyConflictHandler::MODE_THIRD_PERSON);
|
||||
|
||||
// Since we are only modifying keybindings if personal file doesn't exist yet,
|
||||
// it should be safe to just overwrite the value
|
||||
// If key is already in use somewhere by default, LLKeyConflictHandler should resolve it.
|
||||
BOOL value = gSavedSettings.getBOOL("DoubleClickAutoPilot");
|
||||
third_person_view.registerControl("walk_to",
|
||||
0,
|
||||
value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
|
||||
KEY_NONE,
|
||||
MASK_NONE,
|
||||
value);
|
||||
|
||||
U32 index = value ? 1 : 0; // we can store multiple combinations per action, so if first is in use by doubleclick, go to second
|
||||
value = gSavedSettings.getBOOL("ClickToWalk");
|
||||
third_person_view.registerControl("walk_to",
|
||||
index,
|
||||
value ? EMouseClickType::CLICK_LEFT : EMouseClickType::CLICK_NONE,
|
||||
KEY_NONE,
|
||||
MASK_NONE,
|
||||
value);
|
||||
|
||||
value = gSavedSettings.getBOOL("DoubleClickTeleport");
|
||||
third_person_view.registerControl("teleport_to",
|
||||
0,
|
||||
value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
|
||||
KEY_NONE,
|
||||
MASK_NONE,
|
||||
value);
|
||||
|
||||
std::string key_string = gSavedSettings.getString("PushToTalkButton");
|
||||
EMouseClickType mouse = EMouseClickType::CLICK_NONE;
|
||||
KEY key = KEY_NONE;
|
||||
if (key_string == "MiddleMouse")
|
||||
{
|
||||
mouse = EMouseClickType::CLICK_MIDDLE;
|
||||
}
|
||||
else if (key_string == "MouseButton4")
|
||||
{
|
||||
mouse = EMouseClickType::CLICK_BUTTON4;
|
||||
}
|
||||
else if (key_string == "MouseButton5")
|
||||
{
|
||||
mouse = EMouseClickType::CLICK_BUTTON5;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLKeyboard::keyFromString(key_string, &key);
|
||||
}
|
||||
|
||||
value = gSavedSettings.getBOOL("PushToTalkToggle");
|
||||
std::string control_name = value ? "toggle_voice" : "voice_follow_key";
|
||||
third_person_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
|
||||
|
||||
if (third_person_view.hasUnsavedChanges())
|
||||
{
|
||||
// calls loadBindingsXML()
|
||||
third_person_view.saveToSettings();
|
||||
}
|
||||
|
||||
// in case of voice we need to repeat this in other modes (teleports and
|
||||
// autopilot are not entirely practical when sitting or editing)
|
||||
|
||||
for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
|
||||
{
|
||||
if (i != LLKeyConflictHandler::MODE_THIRD_PERSON)
|
||||
{
|
||||
LLKeyConflictHandler handler((LLKeyConflictHandler::ESourceMode)i);
|
||||
|
||||
handler.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
|
||||
|
||||
if (handler.hasUnsavedChanges())
|
||||
{
|
||||
// calls loadBindingsXML()
|
||||
handler.saveToSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// since something might have gone wrong or there might have been nothing to save
|
||||
// (and because otherwise following code will have to be encased in else{}),
|
||||
// load everything one last time
|
||||
#endif
|
||||
if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
|
||||
{
|
||||
// Failed to load custom bindings, try default ones
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
|
|||
else if (!key.mKeyBind.empty())
|
||||
{
|
||||
// Note: this is currently not in use, might be better for load mechanics to ask for and retain control group
|
||||
// otherwise settings loaded from other control groups will end in this one
|
||||
// otherwise settings loaded from other control groups will end in gSavedSettings
|
||||
LL_INFOS() << "Creating new keybinding " << iter->first << LL_ENDL;
|
||||
gSavedSettings.declareLLSD(iter->first, key.mKeyBind.asLLSD(), "comment", LLControlVariable::PERSIST_ALWAYS);
|
||||
}
|
||||
|
|
@ -598,6 +598,71 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
|
|||
// will remove any temporary file if there were any
|
||||
clearUnsavedChanges();
|
||||
}
|
||||
|
||||
#if 1
|
||||
// Legacy support
|
||||
// Remove #if-#endif section half a year after DRTVWR-501 releases.
|
||||
// Update legacy settings in settings.xml
|
||||
// We only care for third person view since legacy settings can't store
|
||||
// more than one mode.
|
||||
// We are saving this even if we are in temporary mode - preferences
|
||||
// will restore values on cancel
|
||||
if (mLoadMode == MODE_THIRD_PERSON)
|
||||
{
|
||||
bool value = canHandleMouse("walk_to", CLICK_DOUBLELEFT, MASK_NONE);
|
||||
gSavedSettings.setBOOL("DoubleClickAutoPilot", value);
|
||||
|
||||
value = canHandleMouse("walk_to", CLICK_LEFT, MASK_NONE);
|
||||
gSavedSettings.setBOOL("ClickToWalk", value);
|
||||
|
||||
value = canHandleMouse("teleport_to", CLICK_DOUBLELEFT, MASK_NONE);
|
||||
gSavedSettings.setBOOL("DoubleClickTeleport", value);
|
||||
|
||||
// new method can save both toggle and push-to-talk values simultaneously,
|
||||
// but legacy one can save only one. It also doesn't support mask.
|
||||
LLKeyData data = getControl("toggle_voice", 0);
|
||||
bool can_toggle = !data.isEmpty();
|
||||
if (!can_toggle)
|
||||
{
|
||||
data = getControl("voice_follow_key", 0);
|
||||
}
|
||||
|
||||
gSavedSettings.setBOOL("PushToTalkToggle", can_toggle);
|
||||
if (data.isEmpty())
|
||||
{
|
||||
// legacy viewer has a bug that might crash it if NONE value is assigned.
|
||||
// just reset to default
|
||||
gSavedSettings.getControl("PushToTalkButton")->resetToDefault(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.mKey != KEY_NONE)
|
||||
{
|
||||
gSavedSettings.setString("PushToTalkButton", LLKeyboard::stringFromKey(data.mKey));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string ctrl_value;
|
||||
switch (data.mMouse)
|
||||
{
|
||||
case CLICK_MIDDLE:
|
||||
ctrl_value = "MiddleMouse";
|
||||
break;
|
||||
case CLICK_BUTTON4:
|
||||
ctrl_value = "MouseButton4";
|
||||
break;
|
||||
case CLICK_BUTTON5:
|
||||
ctrl_value = "MouseButton5";
|
||||
break;
|
||||
default:
|
||||
ctrl_value = "MiddleMouse";
|
||||
break;
|
||||
}
|
||||
gSavedSettings.setString("PushToTalkButton", ctrl_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
LLKeyData LLKeyConflictHandler::getDefaultControl(const std::string &control_name, U32 index)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,18 @@ public:
|
|||
bool canAssignControl(const std::string &control_name);
|
||||
static bool isReservedByMenu(const KEY &key, const MASK &mask);
|
||||
static bool isReservedByMenu(const LLKeyData &data);
|
||||
|
||||
// @control_name - see REGISTER_KEYBOARD_ACTION in llviewerinput for avaliable options,
|
||||
// usually this is just name of the function
|
||||
// @data_index - single control (function) can have multiple key combinations trigering
|
||||
// it, this index indicates combination function will change/add note that preferences
|
||||
// floater can only display up to 3 options, but data_index can be bigger then that
|
||||
// @mouse_ind - mouse action (middle click, MB5 etc)
|
||||
// @key - keyboard key action
|
||||
// @mask - shift/ctrl/alt flags
|
||||
// @ignore_mask - Either to expect exact match (ctrl+K will not trigger if ctrl+shift+K
|
||||
// is active) or ignore not expected masks as long as expected mask is present
|
||||
// (ctrl+K will be triggered if ctrl+shift+K is active)
|
||||
bool registerControl(const std::string &control_name, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts?
|
||||
|
||||
LLKeyData getControl(const std::string &control_name, U32 data_index);
|
||||
|
|
@ -101,6 +113,10 @@ public:
|
|||
// 'temporary' does not support gSavedSettings, those are handled
|
||||
// by preferences, so 'temporary' is such case will simply not
|
||||
// reset mHasUnsavedChanges
|
||||
//
|
||||
// 'temporary' exists to support ability of live-editing settings in
|
||||
// preferences: temporary for testing changes 'live' without saving them,
|
||||
// then hitting ok/cancel and save/discard values permanently.
|
||||
void saveToSettings(bool apply_temporary = false);
|
||||
|
||||
LLKeyData getDefaultControl(const std::string &control_name, U32 data_index);
|
||||
|
|
|
|||
Loading…
Reference in New Issue