forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'aesylwinn/KeyConfigAndShortcuts'
This commit is contained in:
commit
f32d0121fc
42 changed files with 3263 additions and 542 deletions
|
@ -86,12 +86,12 @@ opencs_units (view/widget
|
|||
opencs_units (view/render
|
||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||
orbitcameramode pathgridmode selectionmode pathgridselectionmode
|
||||
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
||||
cellarrow cellmarker cellborder cameracontroller pathgrid
|
||||
cellarrow cellmarker cellborder pathgrid
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (view/render
|
||||
|
@ -108,11 +108,12 @@ opencs_units_noqt (view/tools
|
|||
)
|
||||
|
||||
opencs_units (view/prefs
|
||||
dialogue pagebase page
|
||||
dialogue pagebase page keybindingpage
|
||||
)
|
||||
|
||||
opencs_units (model/prefs
|
||||
state setting intsetting doublesetting boolsetting enumsetting coloursetting
|
||||
state setting intsetting doublesetting boolsetting enumsetting coloursetting shortcut
|
||||
shortcuteventhandler shortcutmanager shortcutsetting modifiersetting
|
||||
)
|
||||
|
||||
opencs_units_noqt (model/prefs
|
||||
|
|
146
apps/opencs/model/prefs/modifiersetting.cpp
Normal file
146
apps/opencs/model/prefs/modifiersetting.cpp
Normal file
|
@ -0,0 +1,146 @@
|
|||
#include "modifiersetting.hpp"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
#include "state.hpp"
|
||||
#include "shortcutmanager.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
ModifierSetting::ModifierSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||
const std::string& label)
|
||||
: Setting(parent, values, mutex, key, label)
|
||||
, mEditorActive(false)
|
||||
{
|
||||
}
|
||||
|
||||
std::pair<QWidget*, QWidget*> ModifierSetting::makeWidgets(QWidget* parent)
|
||||
{
|
||||
int modifier = 0;
|
||||
State::get().getShortcutManager().getModifier(getKey(), modifier);
|
||||
|
||||
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(modifier).c_str());
|
||||
|
||||
QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent);
|
||||
QPushButton* widget = new QPushButton(text, parent);
|
||||
|
||||
widget->setCheckable(true);
|
||||
widget->installEventFilter(this);
|
||||
mButton = widget;
|
||||
|
||||
connect(widget, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool)));
|
||||
|
||||
return std::make_pair(label, widget);
|
||||
}
|
||||
|
||||
bool ModifierSetting::eventFilter(QObject* target, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->isAutoRepeat())
|
||||
return true;
|
||||
|
||||
int mod = keyEvent->modifiers();
|
||||
int key = keyEvent->key();
|
||||
|
||||
return handleEvent(target, mod, key);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
int mod = mouseEvent->modifiers();
|
||||
int button = mouseEvent->button();
|
||||
|
||||
return handleEvent(target, mod, button);
|
||||
}
|
||||
else if (event->type() == QEvent::FocusOut)
|
||||
{
|
||||
resetState();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModifierSetting::handleEvent(QObject* target, int mod, int value)
|
||||
{
|
||||
// For potential future exceptions
|
||||
const int Blacklist[] =
|
||||
{
|
||||
0
|
||||
};
|
||||
|
||||
const size_t BlacklistSize = sizeof(Blacklist) / sizeof(int);
|
||||
|
||||
if (!mEditorActive)
|
||||
{
|
||||
if (value == Qt::RightButton)
|
||||
{
|
||||
// Clear modifier
|
||||
int modifier = 0;
|
||||
storeValue(modifier);
|
||||
|
||||
resetState();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle blacklist
|
||||
for (size_t i = 0; i < BlacklistSize; ++i)
|
||||
{
|
||||
if (value == Blacklist[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Update modifier
|
||||
int modifier = value;
|
||||
storeValue(modifier);
|
||||
|
||||
resetState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModifierSetting::storeValue(int modifier)
|
||||
{
|
||||
State::get().getShortcutManager().setModifier(getKey(), modifier);
|
||||
|
||||
// Convert to string and assign
|
||||
std::string value = State::get().getShortcutManager().convertToString(modifier);
|
||||
|
||||
{
|
||||
QMutexLocker lock(getMutex());
|
||||
getValues().setString(getKey(), getParent()->getKey(), value);
|
||||
}
|
||||
|
||||
getParent()->getState()->update(*this);
|
||||
}
|
||||
|
||||
void ModifierSetting::resetState()
|
||||
{
|
||||
mButton->setChecked(false);
|
||||
mEditorActive = false;
|
||||
|
||||
// Button text
|
||||
int modifier = 0;
|
||||
State::get().getShortcutManager().getModifier(getKey(), modifier);
|
||||
|
||||
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(modifier).c_str());
|
||||
mButton->setText(text);
|
||||
}
|
||||
|
||||
void ModifierSetting::buttonToggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
mButton->setText("Press keys or click here...");
|
||||
|
||||
mEditorActive = checked;
|
||||
}
|
||||
}
|
44
apps/opencs/model/prefs/modifiersetting.hpp
Normal file
44
apps/opencs/model/prefs/modifiersetting.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef CSM_PREFS_MODIFIERSETTING_H
|
||||
#define CSM_PREFS_MODIFIERSETTING_H
|
||||
|
||||
#include <QKeySequence>
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
class QEvent;
|
||||
class QPushButton;
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class ModifierSetting : public Setting
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
ModifierSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||
const std::string& label);
|
||||
|
||||
virtual std::pair<QWidget*, QWidget*> makeWidgets(QWidget* parent);
|
||||
|
||||
protected:
|
||||
|
||||
bool eventFilter(QObject* target, QEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
bool handleEvent(QObject* target, int mod, int value);
|
||||
|
||||
void storeValue(int modifier);
|
||||
void resetState();
|
||||
|
||||
QPushButton* mButton;
|
||||
bool mEditorActive;
|
||||
|
||||
private slots:
|
||||
|
||||
void buttonToggled(bool checked);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
214
apps/opencs/model/prefs/shortcut.cpp
Normal file
214
apps/opencs/model/prefs/shortcut.cpp
Normal file
|
@ -0,0 +1,214 @@
|
|||
#include "shortcut.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <QAction>
|
||||
#include <QWidget>
|
||||
|
||||
#include "state.hpp"
|
||||
#include "shortcutmanager.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
Shortcut::Shortcut(const std::string& name, QWidget* parent)
|
||||
: QObject(parent)
|
||||
, mEnabled(true)
|
||||
, mName(name)
|
||||
, mModName("")
|
||||
, mSecondaryMode(SM_Ignore)
|
||||
, mModifier(0)
|
||||
, mCurrentPos(0)
|
||||
, mLastPos(0)
|
||||
, mActivationStatus(AS_Inactive)
|
||||
, mModifierStatus(false)
|
||||
, mAction(0)
|
||||
{
|
||||
assert (parent);
|
||||
|
||||
State::get().getShortcutManager().addShortcut(this);
|
||||
State::get().getShortcutManager().getSequence(name, mSequence);
|
||||
}
|
||||
|
||||
Shortcut::Shortcut(const std::string& name, const std::string& modName, QWidget* parent)
|
||||
: QObject(parent)
|
||||
, mEnabled(true)
|
||||
, mName(name)
|
||||
, mModName(modName)
|
||||
, mSecondaryMode(SM_Ignore)
|
||||
, mModifier(0)
|
||||
, mCurrentPos(0)
|
||||
, mLastPos(0)
|
||||
, mActivationStatus(AS_Inactive)
|
||||
, mModifierStatus(false)
|
||||
, mAction(0)
|
||||
{
|
||||
assert (parent);
|
||||
|
||||
State::get().getShortcutManager().addShortcut(this);
|
||||
State::get().getShortcutManager().getSequence(name, mSequence);
|
||||
State::get().getShortcutManager().getModifier(modName, mModifier);
|
||||
}
|
||||
|
||||
Shortcut::Shortcut(const std::string& name, const std::string& modName, SecondaryMode secMode, QWidget* parent)
|
||||
: QObject(parent)
|
||||
, mEnabled(true)
|
||||
, mName(name)
|
||||
, mModName(modName)
|
||||
, mSecondaryMode(secMode)
|
||||
, mModifier(0)
|
||||
, mCurrentPos(0)
|
||||
, mLastPos(0)
|
||||
, mActivationStatus(AS_Inactive)
|
||||
, mModifierStatus(false)
|
||||
, mAction(0)
|
||||
{
|
||||
assert (parent);
|
||||
|
||||
State::get().getShortcutManager().addShortcut(this);
|
||||
State::get().getShortcutManager().getSequence(name, mSequence);
|
||||
State::get().getShortcutManager().getModifier(modName, mModifier);
|
||||
}
|
||||
|
||||
Shortcut::~Shortcut()
|
||||
{
|
||||
State::get().getShortcutManager().removeShortcut(this);
|
||||
}
|
||||
|
||||
bool Shortcut::isEnabled() const
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
const std::string& Shortcut::getName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
const std::string& Shortcut::getModifierName() const
|
||||
{
|
||||
return mModName;
|
||||
}
|
||||
|
||||
Shortcut::SecondaryMode Shortcut::getSecondaryMode() const
|
||||
{
|
||||
return mSecondaryMode;
|
||||
}
|
||||
|
||||
const QKeySequence& Shortcut::getSequence() const
|
||||
{
|
||||
return mSequence;
|
||||
}
|
||||
|
||||
int Shortcut::getModifier() const
|
||||
{
|
||||
return mModifier;
|
||||
}
|
||||
|
||||
int Shortcut::getPosition() const
|
||||
{
|
||||
return mCurrentPos;
|
||||
}
|
||||
|
||||
int Shortcut::getLastPosition() const
|
||||
{
|
||||
return mLastPos;
|
||||
}
|
||||
|
||||
Shortcut::ActivationStatus Shortcut::getActivationStatus() const
|
||||
{
|
||||
return mActivationStatus;
|
||||
}
|
||||
|
||||
bool Shortcut::getModifierStatus() const
|
||||
{
|
||||
return mModifierStatus;
|
||||
}
|
||||
|
||||
void Shortcut::enable(bool state)
|
||||
{
|
||||
mEnabled = state;
|
||||
}
|
||||
|
||||
void Shortcut::setSequence(const QKeySequence& sequence)
|
||||
{
|
||||
mSequence = sequence;
|
||||
mCurrentPos = 0;
|
||||
mLastPos = sequence.count() - 1;
|
||||
|
||||
if (mAction)
|
||||
{
|
||||
mAction->setText(mActionText + "\t" + State::get().getShortcutManager().convertToString(mSequence).data());
|
||||
}
|
||||
}
|
||||
|
||||
void Shortcut::setModifier(int modifier)
|
||||
{
|
||||
mModifier = modifier;
|
||||
}
|
||||
|
||||
void Shortcut::setPosition(int pos)
|
||||
{
|
||||
mCurrentPos = pos;
|
||||
}
|
||||
|
||||
void Shortcut::setActivationStatus(ActivationStatus status)
|
||||
{
|
||||
mActivationStatus = status;
|
||||
}
|
||||
|
||||
void Shortcut::setModifierStatus(bool status)
|
||||
{
|
||||
mModifierStatus = status;
|
||||
}
|
||||
|
||||
void Shortcut::associateAction(QAction* action)
|
||||
{
|
||||
if (mAction)
|
||||
{
|
||||
mAction->setText(mActionText);
|
||||
|
||||
disconnect(this, SIGNAL(activated()), mAction, SLOT(trigger()));
|
||||
disconnect(mAction, SIGNAL(destroyed()), this, SLOT(actionDeleted()));
|
||||
}
|
||||
|
||||
mAction = action;
|
||||
|
||||
if (mAction)
|
||||
{
|
||||
mActionText = mAction->text();
|
||||
mAction->setText(mActionText + "\t" + State::get().getShortcutManager().convertToString(mSequence).data());
|
||||
|
||||
connect(this, SIGNAL(activated()), mAction, SLOT(trigger()));
|
||||
connect(mAction, SIGNAL(destroyed()), this, SLOT(actionDeleted()));
|
||||
}
|
||||
}
|
||||
|
||||
void Shortcut::signalActivated(bool state)
|
||||
{
|
||||
emit activated(state);
|
||||
}
|
||||
|
||||
void Shortcut::signalActivated()
|
||||
{
|
||||
emit activated();
|
||||
}
|
||||
|
||||
void Shortcut::signalSecondary(bool state)
|
||||
{
|
||||
emit secondary(state);
|
||||
}
|
||||
void Shortcut::signalSecondary()
|
||||
{
|
||||
emit secondary();
|
||||
}
|
||||
|
||||
QString Shortcut::toString() const
|
||||
{
|
||||
return QString(State::get().getShortcutManager().convertToString(mSequence, mModifier).data());
|
||||
}
|
||||
|
||||
void Shortcut::actionDeleted()
|
||||
{
|
||||
mAction = 0;
|
||||
}
|
||||
}
|
122
apps/opencs/model/prefs/shortcut.hpp
Normal file
122
apps/opencs/model/prefs/shortcut.hpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
#ifndef CSM_PREFS_SHORTCUT_H
|
||||
#define CSM_PREFS_SHORTCUT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class QAction;
|
||||
class QWidget;
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
/// A class similar in purpose to QShortcut, but with the ability to use mouse buttons
|
||||
class Shortcut : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum ActivationStatus
|
||||
{
|
||||
AS_Regular,
|
||||
AS_Secondary,
|
||||
AS_Inactive
|
||||
};
|
||||
|
||||
enum SecondaryMode
|
||||
{
|
||||
SM_Replace, ///< The secondary signal replaces the regular signal when the modifier is active
|
||||
SM_Detach, ///< The secondary signal is emitted independant of the regular signal, even if not active
|
||||
SM_Ignore ///< The secondary signal will not ever be emitted
|
||||
};
|
||||
|
||||
Shortcut(const std::string& name, QWidget* parent);
|
||||
Shortcut(const std::string& name, const std::string& modName, QWidget* parent);
|
||||
Shortcut(const std::string& name, const std::string& modName, SecondaryMode secMode, QWidget* parent);
|
||||
|
||||
~Shortcut();
|
||||
|
||||
bool isEnabled() const;
|
||||
|
||||
const std::string& getName() const;
|
||||
const std::string& getModifierName() const;
|
||||
|
||||
SecondaryMode getSecondaryMode() const;
|
||||
|
||||
const QKeySequence& getSequence() const;
|
||||
int getModifier() const;
|
||||
|
||||
/// The position in the sequence
|
||||
int getPosition() const;
|
||||
/// The position in the sequence
|
||||
int getLastPosition() const;
|
||||
|
||||
ActivationStatus getActivationStatus() const;
|
||||
bool getModifierStatus() const;
|
||||
|
||||
void enable(bool state);
|
||||
|
||||
void setSequence(const QKeySequence& sequence);
|
||||
void setModifier(int modifier);
|
||||
|
||||
/// The position in the sequence
|
||||
void setPosition(int pos);
|
||||
|
||||
void setActivationStatus(ActivationStatus status);
|
||||
void setModifierStatus(bool status);
|
||||
|
||||
/// Appends the sequence to the QAction text, also keeps it up to date
|
||||
void associateAction(QAction* action);
|
||||
|
||||
// Workaround for Qt4 signals being "protected"
|
||||
void signalActivated(bool state);
|
||||
void signalActivated();
|
||||
|
||||
void signalSecondary(bool state);
|
||||
void signalSecondary();
|
||||
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
|
||||
bool mEnabled;
|
||||
|
||||
std::string mName;
|
||||
std::string mModName;
|
||||
SecondaryMode mSecondaryMode;
|
||||
QKeySequence mSequence;
|
||||
int mModifier;
|
||||
|
||||
int mCurrentPos;
|
||||
int mLastPos;
|
||||
|
||||
ActivationStatus mActivationStatus;
|
||||
bool mModifierStatus;
|
||||
|
||||
QAction* mAction;
|
||||
QString mActionText;
|
||||
|
||||
private slots:
|
||||
|
||||
void actionDeleted();
|
||||
|
||||
signals:
|
||||
|
||||
/// Triggered when the shortcut is activated or deactivated; can be determined from \p state
|
||||
void activated(bool state);
|
||||
|
||||
/// Convenience signal.
|
||||
void activated();
|
||||
|
||||
/// Triggered depending on SecondaryMode
|
||||
void secondary(bool state);
|
||||
|
||||
/// Convenience signal.
|
||||
void secondary();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
338
apps/opencs/model/prefs/shortcuteventhandler.cpp
Normal file
338
apps/opencs/model/prefs/shortcuteventhandler.cpp
Normal file
|
@ -0,0 +1,338 @@
|
|||
#include "shortcuteventhandler.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QWidget>
|
||||
|
||||
#include "shortcut.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
ShortcutEventHandler::ShortcutEventHandler(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void ShortcutEventHandler::addShortcut(Shortcut* shortcut)
|
||||
{
|
||||
// Enforced by shortcut class
|
||||
QWidget* widget = static_cast<QWidget*>(shortcut->parent());
|
||||
|
||||
// Check if widget setup is needed
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
if (shortcutListIt == mWidgetShortcuts.end())
|
||||
{
|
||||
// Create list
|
||||
shortcutListIt = mWidgetShortcuts.insert(std::make_pair(widget, ShortcutList())).first;
|
||||
|
||||
// Check if widget has a parent with shortcuts, unfortunately it is not typically set yet
|
||||
updateParent(widget);
|
||||
|
||||
// Intercept widget events
|
||||
widget->installEventFilter(this);
|
||||
connect(widget, SIGNAL(destroyed()), this, SLOT(widgetDestroyed()));
|
||||
}
|
||||
|
||||
// Add to list
|
||||
shortcutListIt->second.push_back(shortcut);
|
||||
}
|
||||
|
||||
void ShortcutEventHandler::removeShortcut(Shortcut* shortcut)
|
||||
{
|
||||
// Enforced by shortcut class
|
||||
QWidget* widget = static_cast<QWidget*>(shortcut->parent());
|
||||
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
if (shortcutListIt != mWidgetShortcuts.end())
|
||||
{
|
||||
std::remove(shortcutListIt->second.begin(), shortcutListIt->second.end(), shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
bool ShortcutEventHandler::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
// Process event
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
unsigned int mod = (unsigned int) keyEvent->modifiers();
|
||||
unsigned int key = (unsigned int) keyEvent->key();
|
||||
|
||||
if (!keyEvent->isAutoRepeat())
|
||||
return activate(widget, mod, key);
|
||||
}
|
||||
else if (event->type() == QEvent::KeyRelease)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
unsigned int mod = (unsigned int) keyEvent->modifiers();
|
||||
unsigned int key = (unsigned int) keyEvent->key();
|
||||
|
||||
if (!keyEvent->isAutoRepeat())
|
||||
return deactivate(widget, mod, key);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
||||
unsigned int button = (unsigned int) mouseEvent->button();
|
||||
|
||||
return activate(widget, mod, button);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseButtonRelease)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
||||
unsigned int button = (unsigned int) mouseEvent->button();
|
||||
|
||||
return deactivate(widget, mod, button);
|
||||
}
|
||||
else if (event->type() == QEvent::FocusOut)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
|
||||
// Deactivate in case events are missed
|
||||
for (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||
{
|
||||
Shortcut* shortcut = *it;
|
||||
|
||||
shortcut->setPosition(0);
|
||||
shortcut->setModifierStatus(false);
|
||||
|
||||
if (shortcut->getActivationStatus() == Shortcut::AS_Regular)
|
||||
{
|
||||
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||
shortcut->signalActivated(false);
|
||||
}
|
||||
else if (shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||
{
|
||||
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||
shortcut->signalSecondary(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event->type() == QEvent::FocusIn)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
updateParent(widget);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShortcutEventHandler::updateParent(QWidget* widget)
|
||||
{
|
||||
QWidget* parent = widget->parentWidget();
|
||||
while (parent)
|
||||
{
|
||||
ShortcutMap::iterator parentIt = mWidgetShortcuts.find(parent);
|
||||
if (parentIt != mWidgetShortcuts.end())
|
||||
{
|
||||
mChildParentRelations.insert(std::make_pair(widget, parent));
|
||||
updateParent(parent);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check next
|
||||
parent = parent->parentWidget();
|
||||
}
|
||||
}
|
||||
|
||||
bool ShortcutEventHandler::activate(QWidget* widget, unsigned int mod, unsigned int button)
|
||||
{
|
||||
std::vector<std::pair<MatchResult, Shortcut*> > potentials;
|
||||
bool used = false;
|
||||
|
||||
while (widget)
|
||||
{
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
assert(shortcutListIt != mWidgetShortcuts.end());
|
||||
|
||||
// Find potential activations
|
||||
for (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||
{
|
||||
Shortcut* shortcut = *it;
|
||||
|
||||
if (!shortcut->isEnabled())
|
||||
continue;
|
||||
|
||||
if (checkModifier(mod, button, shortcut, true))
|
||||
used = true;
|
||||
|
||||
if (shortcut->getActivationStatus() != Shortcut::AS_Inactive)
|
||||
continue;
|
||||
|
||||
int pos = shortcut->getPosition();
|
||||
int lastPos = shortcut->getLastPosition();
|
||||
MatchResult result = match(mod, button, shortcut->getSequence()[pos]);
|
||||
|
||||
if (result == Matches_WithMod || result == Matches_NoMod)
|
||||
{
|
||||
if (pos < lastPos && (result == Matches_WithMod || pos > 0))
|
||||
{
|
||||
shortcut->setPosition(pos+1);
|
||||
}
|
||||
else if (pos == lastPos)
|
||||
{
|
||||
potentials.push_back(std::make_pair(result, shortcut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move on to parent
|
||||
WidgetMap::iterator widgetIt = mChildParentRelations.find(widget);
|
||||
widget = (widgetIt != mChildParentRelations.end()) ? widgetIt->second : 0;
|
||||
}
|
||||
|
||||
// Only activate the best match; in exact conflicts, this will favor the first shortcut added.
|
||||
if (!potentials.empty())
|
||||
{
|
||||
std::sort(potentials.begin(), potentials.end(), ShortcutEventHandler::sort);
|
||||
Shortcut* shortcut = potentials.front().second;
|
||||
|
||||
if (shortcut->getModifierStatus() && shortcut->getSecondaryMode() == Shortcut::SM_Replace)
|
||||
{
|
||||
shortcut->setActivationStatus(Shortcut::AS_Secondary);
|
||||
shortcut->signalSecondary(true);
|
||||
shortcut->signalSecondary();
|
||||
}
|
||||
else
|
||||
{
|
||||
shortcut->setActivationStatus(Shortcut::AS_Regular);
|
||||
shortcut->signalActivated(true);
|
||||
shortcut->signalActivated();
|
||||
}
|
||||
|
||||
used = true;
|
||||
}
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
bool ShortcutEventHandler::deactivate(QWidget* widget, unsigned int mod, unsigned int button)
|
||||
{
|
||||
const int KeyMask = 0x01FFFFFF;
|
||||
|
||||
bool used = false;
|
||||
|
||||
while (widget)
|
||||
{
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
assert(shortcutListIt != mWidgetShortcuts.end());
|
||||
|
||||
for (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||
{
|
||||
Shortcut* shortcut = *it;
|
||||
|
||||
if (checkModifier(mod, button, shortcut, false))
|
||||
used = true;
|
||||
|
||||
int pos = shortcut->getPosition();
|
||||
MatchResult result = match(0, button, shortcut->getSequence()[pos] & KeyMask);
|
||||
|
||||
if (result != Matches_Not)
|
||||
{
|
||||
shortcut->setPosition(0);
|
||||
|
||||
if (shortcut->getActivationStatus() == Shortcut::AS_Regular)
|
||||
{
|
||||
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||
shortcut->signalActivated(false);
|
||||
used = true;
|
||||
}
|
||||
else if (shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||
{
|
||||
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||
shortcut->signalSecondary(false);
|
||||
used = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move on to parent
|
||||
WidgetMap::iterator widgetIt = mChildParentRelations.find(widget);
|
||||
widget = (widgetIt != mChildParentRelations.end()) ? widgetIt->second : 0;
|
||||
}
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
bool ShortcutEventHandler::checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate)
|
||||
{
|
||||
if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore ||
|
||||
shortcut->getModifierStatus() == activate)
|
||||
return false;
|
||||
|
||||
MatchResult result = match(mod, button, shortcut->getModifier());
|
||||
bool used = false;
|
||||
|
||||
if (result != Matches_Not)
|
||||
{
|
||||
shortcut->setModifierStatus(activate);
|
||||
|
||||
if (shortcut->getSecondaryMode() == Shortcut::SM_Detach)
|
||||
{
|
||||
if (activate)
|
||||
{
|
||||
shortcut->signalSecondary(true);
|
||||
shortcut->signalSecondary();
|
||||
}
|
||||
else
|
||||
{
|
||||
shortcut->signalSecondary(false);
|
||||
}
|
||||
}
|
||||
else if (!activate && shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||
{
|
||||
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||
shortcut->setPosition(0);
|
||||
shortcut->signalSecondary(false);
|
||||
used = true;
|
||||
}
|
||||
}
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
ShortcutEventHandler::MatchResult ShortcutEventHandler::match(unsigned int mod, unsigned int button,
|
||||
unsigned int value)
|
||||
{
|
||||
if ((mod | button) == value)
|
||||
{
|
||||
return Matches_WithMod;
|
||||
}
|
||||
else if (button == value)
|
||||
{
|
||||
return Matches_NoMod;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Matches_Not;
|
||||
}
|
||||
}
|
||||
|
||||
bool ShortcutEventHandler::sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||
const std::pair<MatchResult, Shortcut*>& right)
|
||||
{
|
||||
if (left.first == Matches_WithMod && right.first == Matches_NoMod)
|
||||
return true;
|
||||
else
|
||||
return left.second->getPosition() >= right.second->getPosition();
|
||||
}
|
||||
|
||||
void ShortcutEventHandler::widgetDestroyed()
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(sender());
|
||||
|
||||
mWidgetShortcuts.erase(widget);
|
||||
mChildParentRelations.erase(widget);
|
||||
}
|
||||
}
|
69
apps/opencs/model/prefs/shortcuteventhandler.hpp
Normal file
69
apps/opencs/model/prefs/shortcuteventhandler.hpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
||||
#define CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QEvent;
|
||||
class QWidget;
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Shortcut;
|
||||
|
||||
/// Users of this class should install it as an event handler
|
||||
class ShortcutEventHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
ShortcutEventHandler(QObject* parent);
|
||||
|
||||
void addShortcut(Shortcut* shortcut);
|
||||
void removeShortcut(Shortcut* shortcut);
|
||||
|
||||
protected:
|
||||
|
||||
bool eventFilter(QObject* watched, QEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::vector<Shortcut*> ShortcutList;
|
||||
// Child, Parent
|
||||
typedef std::map<QWidget*, QWidget*> WidgetMap;
|
||||
typedef std::map<QWidget*, ShortcutList> ShortcutMap;
|
||||
|
||||
enum MatchResult
|
||||
{
|
||||
Matches_WithMod,
|
||||
Matches_NoMod,
|
||||
Matches_Not
|
||||
};
|
||||
|
||||
void updateParent(QWidget* widget);
|
||||
|
||||
bool activate(QWidget* widget, unsigned int mod, unsigned int button);
|
||||
|
||||
bool deactivate(QWidget* widget, unsigned int mod, unsigned int button);
|
||||
|
||||
bool checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate);
|
||||
|
||||
MatchResult match(unsigned int mod, unsigned int button, unsigned int value);
|
||||
|
||||
// Prefers Matches_WithMod and a larger number of buttons
|
||||
static bool sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||
const std::pair<MatchResult, Shortcut*>& right);
|
||||
|
||||
WidgetMap mChildParentRelations;
|
||||
ShortcutMap mWidgetShortcuts;
|
||||
|
||||
private slots:
|
||||
|
||||
void widgetDestroyed();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
791
apps/opencs/model/prefs/shortcutmanager.cpp
Normal file
791
apps/opencs/model/prefs/shortcutmanager.cpp
Normal file
|
@ -0,0 +1,791 @@
|
|||
#include "shortcutmanager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QStringList>
|
||||
|
||||
#include "shortcut.hpp"
|
||||
#include "shortcuteventhandler.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
ShortcutManager::ShortcutManager()
|
||||
{
|
||||
createLookupTables();
|
||||
mEventHandler = new ShortcutEventHandler(this);
|
||||
}
|
||||
|
||||
void ShortcutManager::addShortcut(Shortcut* shortcut)
|
||||
{
|
||||
mShortcuts.insert(std::make_pair(shortcut->getName(), shortcut));
|
||||
mShortcuts.insert(std::make_pair(shortcut->getModifierName(), shortcut));
|
||||
mEventHandler->addShortcut(shortcut);
|
||||
}
|
||||
|
||||
void ShortcutManager::removeShortcut(Shortcut* shortcut)
|
||||
{
|
||||
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> range = mShortcuts.equal_range(shortcut->getName());
|
||||
|
||||
for (ShortcutMap::iterator it = range.first; it != range.second;)
|
||||
{
|
||||
if (it->second == shortcut)
|
||||
{
|
||||
mShortcuts.erase(it++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
mEventHandler->removeShortcut(shortcut);
|
||||
}
|
||||
|
||||
bool ShortcutManager::getSequence(const std::string& name, QKeySequence& sequence) const
|
||||
{
|
||||
SequenceMap::const_iterator item = mSequences.find(name);
|
||||
if (item != mSequences.end())
|
||||
{
|
||||
sequence = item->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShortcutManager::setSequence(const std::string& name, const QKeySequence& sequence)
|
||||
{
|
||||
// Add to map/modify
|
||||
SequenceMap::iterator item = mSequences.find(name);
|
||||
if (item != mSequences.end())
|
||||
{
|
||||
item->second = sequence;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSequences.insert(std::make_pair(name, sequence));
|
||||
}
|
||||
|
||||
// Change active shortcuts
|
||||
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> rangeS = mShortcuts.equal_range(name);
|
||||
|
||||
for (ShortcutMap::iterator it = rangeS.first; it != rangeS.second; ++it)
|
||||
{
|
||||
it->second->setSequence(sequence);
|
||||
}
|
||||
}
|
||||
|
||||
bool ShortcutManager::getModifier(const std::string& name, int& modifier) const
|
||||
{
|
||||
ModifierMap::const_iterator item = mModifiers.find(name);
|
||||
if (item != mModifiers.end())
|
||||
{
|
||||
modifier = item->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShortcutManager::setModifier(const std::string& name, int modifier)
|
||||
{
|
||||
// Add to map/modify
|
||||
ModifierMap::iterator item = mModifiers.find(name);
|
||||
if (item != mModifiers.end())
|
||||
{
|
||||
item->second = modifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
mModifiers.insert(std::make_pair(name, modifier));
|
||||
}
|
||||
|
||||
// Change active shortcuts
|
||||
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> rangeS = mShortcuts.equal_range(name);
|
||||
|
||||
for (ShortcutMap::iterator it = rangeS.first; it != rangeS.second; ++it)
|
||||
{
|
||||
it->second->setModifier(modifier);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ShortcutManager::convertToString(const QKeySequence& sequence) const
|
||||
{
|
||||
const int MouseKeyMask = 0x01FFFFFF;
|
||||
const int ModMask = 0x7E000000;
|
||||
|
||||
std::string result;
|
||||
|
||||
for (int i = 0; i < (int)sequence.count(); ++i)
|
||||
{
|
||||
int mods = sequence[i] & ModMask;
|
||||
int key = sequence[i] & MouseKeyMask;
|
||||
|
||||
if (key)
|
||||
{
|
||||
NameMap::const_iterator searchResult = mNames.find(key);
|
||||
if (searchResult != mNames.end())
|
||||
{
|
||||
if (mods && i == 0)
|
||||
{
|
||||
if (mods & Qt::ControlModifier)
|
||||
result.append("Ctl+");
|
||||
if (mods & Qt::ShiftModifier)
|
||||
result.append("Shift+");
|
||||
if (mods & Qt::AltModifier)
|
||||
result.append("Alt+");
|
||||
if (mods & Qt::MetaModifier)
|
||||
result.append("Meta+");
|
||||
if (mods & Qt::KeypadModifier)
|
||||
result.append("Keypad+");
|
||||
if (mods & Qt::GroupSwitchModifier)
|
||||
result.append("GroupSwitch+");
|
||||
}
|
||||
else if (i > 0)
|
||||
{
|
||||
result.append("+");
|
||||
}
|
||||
|
||||
result.append(searchResult->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ShortcutManager::convertToString(int modifier) const
|
||||
{
|
||||
NameMap::const_iterator searchResult = mNames.find(modifier);
|
||||
if (searchResult != mNames.end())
|
||||
{
|
||||
return searchResult->second;
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ShortcutManager::convertToString(const QKeySequence& sequence, int modifier) const
|
||||
{
|
||||
std::string concat = convertToString(sequence) + ";" + convertToString(modifier);
|
||||
return concat;
|
||||
}
|
||||
|
||||
void ShortcutManager::convertFromString(const std::string& data, QKeySequence& sequence) const
|
||||
{
|
||||
const int MaxKeys = 4; // A limitation of QKeySequence
|
||||
|
||||
size_t end = data.find(";");
|
||||
size_t size = std::min(end, data.size());
|
||||
|
||||
std::string value = data.substr(0, size);
|
||||
size_t start = 0;
|
||||
|
||||
int keyPos = 0;
|
||||
int mods = 0;
|
||||
|
||||
int keys[MaxKeys] = {};
|
||||
|
||||
while (start < value.size())
|
||||
{
|
||||
end = data.find("+", start);
|
||||
end = std::min(end, value.size());
|
||||
|
||||
std::string name = value.substr(start, end - start);
|
||||
|
||||
if (name == "Ctl")
|
||||
{
|
||||
mods |= Qt::ControlModifier;
|
||||
}
|
||||
else if (name == "Shift")
|
||||
{
|
||||
mods |= Qt::ShiftModifier;
|
||||
}
|
||||
else if (name == "Alt")
|
||||
{
|
||||
mods |= Qt::AltModifier;
|
||||
}
|
||||
else if (name == "Meta")
|
||||
{
|
||||
mods |= Qt::MetaModifier;
|
||||
}
|
||||
else if (name == "Keypad")
|
||||
{
|
||||
mods |= Qt::KeypadModifier;
|
||||
}
|
||||
else if (name == "GroupSwitch")
|
||||
{
|
||||
mods |= Qt::GroupSwitchModifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyMap::const_iterator searchResult = mKeys.find(name);
|
||||
if (searchResult != mKeys.end())
|
||||
{
|
||||
keys[keyPos] = mods | searchResult->second;
|
||||
|
||||
mods = 0;
|
||||
keyPos += 1;
|
||||
|
||||
if (keyPos >= MaxKeys)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
sequence = QKeySequence(keys[0], keys[1], keys[2], keys[3]);
|
||||
}
|
||||
|
||||
void ShortcutManager::convertFromString(const std::string& data, int& modifier) const
|
||||
{
|
||||
size_t start = data.find(";") + 1;
|
||||
start = std::min(start, data.size());
|
||||
|
||||
std::string name = data.substr(start);
|
||||
KeyMap::const_iterator searchResult = mKeys.find(name);
|
||||
if (searchResult != mKeys.end())
|
||||
{
|
||||
modifier = searchResult->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
modifier = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ShortcutManager::convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const
|
||||
{
|
||||
convertFromString(data, sequence);
|
||||
convertFromString(data, modifier);
|
||||
}
|
||||
|
||||
void ShortcutManager::createLookupTables()
|
||||
{
|
||||
// Mouse buttons
|
||||
mNames.insert(std::make_pair(Qt::LeftButton, "LMB"));
|
||||
mNames.insert(std::make_pair(Qt::RightButton, "RMB"));
|
||||
mNames.insert(std::make_pair(Qt::MiddleButton, "MMB"));
|
||||
mNames.insert(std::make_pair(Qt::XButton1, "Mouse4"));
|
||||
mNames.insert(std::make_pair(Qt::XButton2, "Mouse5"));
|
||||
|
||||
// Keyboard buttons
|
||||
for (size_t i = 0; QtKeys[i].first != 0; ++i)
|
||||
{
|
||||
mNames.insert(QtKeys[i]);
|
||||
}
|
||||
|
||||
// Generate inverse map
|
||||
for (NameMap::const_iterator it = mNames.begin(); it != mNames.end(); ++it)
|
||||
{
|
||||
mKeys.insert(std::make_pair(it->second, it->first));
|
||||
}
|
||||
}
|
||||
|
||||
QString ShortcutManager::processToolTip(const QString& toolTip) const
|
||||
{
|
||||
const QChar SequenceStart = '{';
|
||||
const QChar SequenceEnd = '}';
|
||||
|
||||
QStringList substrings;
|
||||
|
||||
int prevIndex = 0;
|
||||
int startIndex = toolTip.indexOf(SequenceStart);
|
||||
int endIndex = (startIndex != -1) ? toolTip.indexOf(SequenceEnd, startIndex) : -1;
|
||||
|
||||
// Process every valid shortcut escape sequence
|
||||
while (startIndex != -1 && endIndex != -1)
|
||||
{
|
||||
int count = startIndex - prevIndex;
|
||||
if (count > 0)
|
||||
{
|
||||
substrings.push_back(toolTip.mid(prevIndex, count));
|
||||
}
|
||||
|
||||
// Find sequence name
|
||||
startIndex += 1; // '{' character
|
||||
count = endIndex - startIndex;
|
||||
if (count > 0)
|
||||
{
|
||||
QString settingName = toolTip.mid(startIndex, count);
|
||||
|
||||
QKeySequence sequence;
|
||||
int modifier;
|
||||
|
||||
if (getSequence(settingName.toUtf8().data(), sequence))
|
||||
{
|
||||
QString value = QString::fromUtf8(convertToString(sequence).c_str());
|
||||
substrings.push_back(value);
|
||||
}
|
||||
else if (getModifier(settingName.toUtf8().data(), modifier))
|
||||
{
|
||||
QString value = QString::fromUtf8(convertToString(modifier).c_str());
|
||||
substrings.push_back(value);
|
||||
}
|
||||
|
||||
prevIndex = endIndex + 1; // '}' character
|
||||
}
|
||||
|
||||
startIndex = toolTip.indexOf(SequenceStart, endIndex);
|
||||
endIndex = (startIndex != -1) ? toolTip.indexOf(SequenceEnd, startIndex) : -1;
|
||||
}
|
||||
|
||||
if (prevIndex < toolTip.size())
|
||||
{
|
||||
substrings.push_back(toolTip.mid(prevIndex));
|
||||
}
|
||||
|
||||
return substrings.join("");
|
||||
}
|
||||
|
||||
const std::pair<int, const char*> ShortcutManager::QtKeys[] =
|
||||
{
|
||||
std::make_pair((int)Qt::Key_Space , "Space"),
|
||||
std::make_pair((int)Qt::Key_Exclam , "Exclam"),
|
||||
std::make_pair((int)Qt::Key_QuoteDbl , "QuoteDbl"),
|
||||
std::make_pair((int)Qt::Key_NumberSign , "NumberSign"),
|
||||
std::make_pair((int)Qt::Key_Dollar , "Dollar"),
|
||||
std::make_pair((int)Qt::Key_Percent , "Percent"),
|
||||
std::make_pair((int)Qt::Key_Ampersand , "Ampersand"),
|
||||
std::make_pair((int)Qt::Key_Apostrophe , "Apostrophe"),
|
||||
std::make_pair((int)Qt::Key_ParenLeft , "ParenLeft"),
|
||||
std::make_pair((int)Qt::Key_ParenRight , "ParenRight"),
|
||||
std::make_pair((int)Qt::Key_Asterisk , "Asterisk"),
|
||||
std::make_pair((int)Qt::Key_Plus , "Plus"),
|
||||
std::make_pair((int)Qt::Key_Comma , "Comma"),
|
||||
std::make_pair((int)Qt::Key_Minus , "Minus"),
|
||||
std::make_pair((int)Qt::Key_Period , "Period"),
|
||||
std::make_pair((int)Qt::Key_Slash , "Slash"),
|
||||
std::make_pair((int)Qt::Key_0 , "0"),
|
||||
std::make_pair((int)Qt::Key_1 , "1"),
|
||||
std::make_pair((int)Qt::Key_2 , "2"),
|
||||
std::make_pair((int)Qt::Key_3 , "3"),
|
||||
std::make_pair((int)Qt::Key_4 , "4"),
|
||||
std::make_pair((int)Qt::Key_5 , "5"),
|
||||
std::make_pair((int)Qt::Key_6 , "6"),
|
||||
std::make_pair((int)Qt::Key_7 , "7"),
|
||||
std::make_pair((int)Qt::Key_8 , "8"),
|
||||
std::make_pair((int)Qt::Key_9 , "9"),
|
||||
std::make_pair((int)Qt::Key_Colon , "Colon"),
|
||||
std::make_pair((int)Qt::Key_Semicolon , "Semicolon"),
|
||||
std::make_pair((int)Qt::Key_Less , "Less"),
|
||||
std::make_pair((int)Qt::Key_Equal , "Equal"),
|
||||
std::make_pair((int)Qt::Key_Greater , "Greater"),
|
||||
std::make_pair((int)Qt::Key_Question , "Question"),
|
||||
std::make_pair((int)Qt::Key_At , "At"),
|
||||
std::make_pair((int)Qt::Key_A , "A"),
|
||||
std::make_pair((int)Qt::Key_B , "B"),
|
||||
std::make_pair((int)Qt::Key_C , "C"),
|
||||
std::make_pair((int)Qt::Key_D , "D"),
|
||||
std::make_pair((int)Qt::Key_E , "E"),
|
||||
std::make_pair((int)Qt::Key_F , "F"),
|
||||
std::make_pair((int)Qt::Key_G , "G"),
|
||||
std::make_pair((int)Qt::Key_H , "H"),
|
||||
std::make_pair((int)Qt::Key_I , "I"),
|
||||
std::make_pair((int)Qt::Key_J , "J"),
|
||||
std::make_pair((int)Qt::Key_K , "K"),
|
||||
std::make_pair((int)Qt::Key_L , "L"),
|
||||
std::make_pair((int)Qt::Key_M , "M"),
|
||||
std::make_pair((int)Qt::Key_N , "N"),
|
||||
std::make_pair((int)Qt::Key_O , "O"),
|
||||
std::make_pair((int)Qt::Key_P , "P"),
|
||||
std::make_pair((int)Qt::Key_Q , "Q"),
|
||||
std::make_pair((int)Qt::Key_R , "R"),
|
||||
std::make_pair((int)Qt::Key_S , "S"),
|
||||
std::make_pair((int)Qt::Key_T , "T"),
|
||||
std::make_pair((int)Qt::Key_U , "U"),
|
||||
std::make_pair((int)Qt::Key_V , "V"),
|
||||
std::make_pair((int)Qt::Key_W , "W"),
|
||||
std::make_pair((int)Qt::Key_X , "X"),
|
||||
std::make_pair((int)Qt::Key_Y , "Y"),
|
||||
std::make_pair((int)Qt::Key_Z , "Z"),
|
||||
std::make_pair((int)Qt::Key_BracketLeft , "BracketLeft"),
|
||||
std::make_pair((int)Qt::Key_Backslash , "Backslash"),
|
||||
std::make_pair((int)Qt::Key_BracketRight , "BracketRight"),
|
||||
std::make_pair((int)Qt::Key_AsciiCircum , "AsciiCircum"),
|
||||
std::make_pair((int)Qt::Key_Underscore , "Underscore"),
|
||||
std::make_pair((int)Qt::Key_QuoteLeft , "QuoteLeft"),
|
||||
std::make_pair((int)Qt::Key_BraceLeft , "BraceLeft"),
|
||||
std::make_pair((int)Qt::Key_Bar , "Bar"),
|
||||
std::make_pair((int)Qt::Key_BraceRight , "BraceRight"),
|
||||
std::make_pair((int)Qt::Key_AsciiTilde , "AsciiTilde"),
|
||||
std::make_pair((int)Qt::Key_nobreakspace , "nobreakspace"),
|
||||
std::make_pair((int)Qt::Key_exclamdown , "exclamdown"),
|
||||
std::make_pair((int)Qt::Key_cent , "cent"),
|
||||
std::make_pair((int)Qt::Key_sterling , "sterling"),
|
||||
std::make_pair((int)Qt::Key_currency , "currency"),
|
||||
std::make_pair((int)Qt::Key_yen , "yen"),
|
||||
std::make_pair((int)Qt::Key_brokenbar , "brokenbar"),
|
||||
std::make_pair((int)Qt::Key_section , "section"),
|
||||
std::make_pair((int)Qt::Key_diaeresis , "diaeresis"),
|
||||
std::make_pair((int)Qt::Key_copyright , "copyright"),
|
||||
std::make_pair((int)Qt::Key_ordfeminine , "ordfeminine"),
|
||||
std::make_pair((int)Qt::Key_guillemotleft , "guillemotleft"),
|
||||
std::make_pair((int)Qt::Key_notsign , "notsign"),
|
||||
std::make_pair((int)Qt::Key_hyphen , "hyphen"),
|
||||
std::make_pair((int)Qt::Key_registered , "registered"),
|
||||
std::make_pair((int)Qt::Key_macron , "macron"),
|
||||
std::make_pair((int)Qt::Key_degree , "degree"),
|
||||
std::make_pair((int)Qt::Key_plusminus , "plusminus"),
|
||||
std::make_pair((int)Qt::Key_twosuperior , "twosuperior"),
|
||||
std::make_pair((int)Qt::Key_threesuperior , "threesuperior"),
|
||||
std::make_pair((int)Qt::Key_acute , "acute"),
|
||||
std::make_pair((int)Qt::Key_mu , "mu"),
|
||||
std::make_pair((int)Qt::Key_paragraph , "paragraph"),
|
||||
std::make_pair((int)Qt::Key_periodcentered , "periodcentered"),
|
||||
std::make_pair((int)Qt::Key_cedilla , "cedilla"),
|
||||
std::make_pair((int)Qt::Key_onesuperior , "onesuperior"),
|
||||
std::make_pair((int)Qt::Key_masculine , "masculine"),
|
||||
std::make_pair((int)Qt::Key_guillemotright , "guillemotright"),
|
||||
std::make_pair((int)Qt::Key_onequarter , "onequarter"),
|
||||
std::make_pair((int)Qt::Key_onehalf , "onehalf"),
|
||||
std::make_pair((int)Qt::Key_threequarters , "threequarters"),
|
||||
std::make_pair((int)Qt::Key_questiondown , "questiondown"),
|
||||
std::make_pair((int)Qt::Key_Agrave , "Agrave"),
|
||||
std::make_pair((int)Qt::Key_Aacute , "Aacute"),
|
||||
std::make_pair((int)Qt::Key_Acircumflex , "Acircumflex"),
|
||||
std::make_pair((int)Qt::Key_Atilde , "Atilde"),
|
||||
std::make_pair((int)Qt::Key_Adiaeresis , "Adiaeresis"),
|
||||
std::make_pair((int)Qt::Key_Aring , "Aring"),
|
||||
std::make_pair((int)Qt::Key_AE , "AE"),
|
||||
std::make_pair((int)Qt::Key_Ccedilla , "Ccedilla"),
|
||||
std::make_pair((int)Qt::Key_Egrave , "Egrave"),
|
||||
std::make_pair((int)Qt::Key_Eacute , "Eacute"),
|
||||
std::make_pair((int)Qt::Key_Ecircumflex , "Ecircumflex"),
|
||||
std::make_pair((int)Qt::Key_Ediaeresis , "Ediaeresis"),
|
||||
std::make_pair((int)Qt::Key_Igrave , "Igrave"),
|
||||
std::make_pair((int)Qt::Key_Iacute , "Iacute"),
|
||||
std::make_pair((int)Qt::Key_Icircumflex , "Icircumflex"),
|
||||
std::make_pair((int)Qt::Key_Idiaeresis , "Idiaeresis"),
|
||||
std::make_pair((int)Qt::Key_ETH , "ETH"),
|
||||
std::make_pair((int)Qt::Key_Ntilde , "Ntilde"),
|
||||
std::make_pair((int)Qt::Key_Ograve , "Ograve"),
|
||||
std::make_pair((int)Qt::Key_Oacute , "Oacute"),
|
||||
std::make_pair((int)Qt::Key_Ocircumflex , "Ocircumflex"),
|
||||
std::make_pair((int)Qt::Key_Otilde , "Otilde"),
|
||||
std::make_pair((int)Qt::Key_Odiaeresis , "Odiaeresis"),
|
||||
std::make_pair((int)Qt::Key_multiply , "multiply"),
|
||||
std::make_pair((int)Qt::Key_Ooblique , "Ooblique"),
|
||||
std::make_pair((int)Qt::Key_Ugrave , "Ugrave"),
|
||||
std::make_pair((int)Qt::Key_Uacute , "Uacute"),
|
||||
std::make_pair((int)Qt::Key_Ucircumflex , "Ucircumflex"),
|
||||
std::make_pair((int)Qt::Key_Udiaeresis , "Udiaeresis"),
|
||||
std::make_pair((int)Qt::Key_Yacute , "Yacute"),
|
||||
std::make_pair((int)Qt::Key_THORN , "THORN"),
|
||||
std::make_pair((int)Qt::Key_ssharp , "ssharp"),
|
||||
std::make_pair((int)Qt::Key_division , "division"),
|
||||
std::make_pair((int)Qt::Key_ydiaeresis , "ydiaeresis"),
|
||||
std::make_pair((int)Qt::Key_Escape , "Escape"),
|
||||
std::make_pair((int)Qt::Key_Tab , "Tab"),
|
||||
std::make_pair((int)Qt::Key_Backtab , "Backtab"),
|
||||
std::make_pair((int)Qt::Key_Backspace , "Backspace"),
|
||||
std::make_pair((int)Qt::Key_Return , "Return"),
|
||||
std::make_pair((int)Qt::Key_Enter , "Enter"),
|
||||
std::make_pair((int)Qt::Key_Insert , "Insert"),
|
||||
std::make_pair((int)Qt::Key_Delete , "Delete"),
|
||||
std::make_pair((int)Qt::Key_Pause , "Pause"),
|
||||
std::make_pair((int)Qt::Key_Print , "Print"),
|
||||
std::make_pair((int)Qt::Key_SysReq , "SysReq"),
|
||||
std::make_pair((int)Qt::Key_Clear , "Clear"),
|
||||
std::make_pair((int)Qt::Key_Home , "Home"),
|
||||
std::make_pair((int)Qt::Key_End , "End"),
|
||||
std::make_pair((int)Qt::Key_Left , "Left"),
|
||||
std::make_pair((int)Qt::Key_Up , "Up"),
|
||||
std::make_pair((int)Qt::Key_Right , "Right"),
|
||||
std::make_pair((int)Qt::Key_Down , "Down"),
|
||||
std::make_pair((int)Qt::Key_PageUp , "PageUp"),
|
||||
std::make_pair((int)Qt::Key_PageDown , "PageDown"),
|
||||
std::make_pair((int)Qt::Key_Shift , "Shift"),
|
||||
std::make_pair((int)Qt::Key_Control , "Control"),
|
||||
std::make_pair((int)Qt::Key_Meta , "Meta"),
|
||||
std::make_pair((int)Qt::Key_Alt , "Alt"),
|
||||
std::make_pair((int)Qt::Key_CapsLock , "CapsLock"),
|
||||
std::make_pair((int)Qt::Key_NumLock , "NumLock"),
|
||||
std::make_pair((int)Qt::Key_ScrollLock , "ScrollLock"),
|
||||
std::make_pair((int)Qt::Key_F1 , "F1"),
|
||||
std::make_pair((int)Qt::Key_F2 , "F2"),
|
||||
std::make_pair((int)Qt::Key_F3 , "F3"),
|
||||
std::make_pair((int)Qt::Key_F4 , "F4"),
|
||||
std::make_pair((int)Qt::Key_F5 , "F5"),
|
||||
std::make_pair((int)Qt::Key_F6 , "F6"),
|
||||
std::make_pair((int)Qt::Key_F7 , "F7"),
|
||||
std::make_pair((int)Qt::Key_F8 , "F8"),
|
||||
std::make_pair((int)Qt::Key_F9 , "F9"),
|
||||
std::make_pair((int)Qt::Key_F10 , "F10"),
|
||||
std::make_pair((int)Qt::Key_F11 , "F11"),
|
||||
std::make_pair((int)Qt::Key_F12 , "F12"),
|
||||
std::make_pair((int)Qt::Key_F13 , "F13"),
|
||||
std::make_pair((int)Qt::Key_F14 , "F14"),
|
||||
std::make_pair((int)Qt::Key_F15 , "F15"),
|
||||
std::make_pair((int)Qt::Key_F16 , "F16"),
|
||||
std::make_pair((int)Qt::Key_F17 , "F17"),
|
||||
std::make_pair((int)Qt::Key_F18 , "F18"),
|
||||
std::make_pair((int)Qt::Key_F19 , "F19"),
|
||||
std::make_pair((int)Qt::Key_F20 , "F20"),
|
||||
std::make_pair((int)Qt::Key_F21 , "F21"),
|
||||
std::make_pair((int)Qt::Key_F22 , "F22"),
|
||||
std::make_pair((int)Qt::Key_F23 , "F23"),
|
||||
std::make_pair((int)Qt::Key_F24 , "F24"),
|
||||
std::make_pair((int)Qt::Key_F25 , "F25"),
|
||||
std::make_pair((int)Qt::Key_F26 , "F26"),
|
||||
std::make_pair((int)Qt::Key_F27 , "F27"),
|
||||
std::make_pair((int)Qt::Key_F28 , "F28"),
|
||||
std::make_pair((int)Qt::Key_F29 , "F29"),
|
||||
std::make_pair((int)Qt::Key_F30 , "F30"),
|
||||
std::make_pair((int)Qt::Key_F31 , "F31"),
|
||||
std::make_pair((int)Qt::Key_F32 , "F32"),
|
||||
std::make_pair((int)Qt::Key_F33 , "F33"),
|
||||
std::make_pair((int)Qt::Key_F34 , "F34"),
|
||||
std::make_pair((int)Qt::Key_F35 , "F35"),
|
||||
std::make_pair((int)Qt::Key_Super_L , "Super_L"),
|
||||
std::make_pair((int)Qt::Key_Super_R , "Super_R"),
|
||||
std::make_pair((int)Qt::Key_Menu , "Menu"),
|
||||
std::make_pair((int)Qt::Key_Hyper_L , "Hyper_L"),
|
||||
std::make_pair((int)Qt::Key_Hyper_R , "Hyper_R"),
|
||||
std::make_pair((int)Qt::Key_Help , "Help"),
|
||||
std::make_pair((int)Qt::Key_Direction_L , "Direction_L"),
|
||||
std::make_pair((int)Qt::Key_Direction_R , "Direction_R"),
|
||||
std::make_pair((int)Qt::Key_Back , "Back"),
|
||||
std::make_pair((int)Qt::Key_Forward , "Forward"),
|
||||
std::make_pair((int)Qt::Key_Stop , "Stop"),
|
||||
std::make_pair((int)Qt::Key_Refresh , "Refresh"),
|
||||
std::make_pair((int)Qt::Key_VolumeDown , "VolumeDown"),
|
||||
std::make_pair((int)Qt::Key_VolumeMute , "VolumeMute"),
|
||||
std::make_pair((int)Qt::Key_VolumeUp , "VolumeUp"),
|
||||
std::make_pair((int)Qt::Key_BassBoost , "BassBoost"),
|
||||
std::make_pair((int)Qt::Key_BassUp , "BassUp"),
|
||||
std::make_pair((int)Qt::Key_BassDown , "BassDown"),
|
||||
std::make_pair((int)Qt::Key_TrebleUp , "TrebleUp"),
|
||||
std::make_pair((int)Qt::Key_TrebleDown , "TrebleDown"),
|
||||
std::make_pair((int)Qt::Key_MediaPlay , "MediaPlay"),
|
||||
std::make_pair((int)Qt::Key_MediaStop , "MediaStop"),
|
||||
std::make_pair((int)Qt::Key_MediaPrevious , "MediaPrevious"),
|
||||
std::make_pair((int)Qt::Key_MediaNext , "MediaNext"),
|
||||
std::make_pair((int)Qt::Key_MediaRecord , "MediaRecord"),
|
||||
std::make_pair((int)Qt::Key_MediaPause , "MediaPause"),
|
||||
std::make_pair((int)Qt::Key_MediaTogglePlayPause , "MediaTogglePlayPause"),
|
||||
std::make_pair((int)Qt::Key_HomePage , "HomePage"),
|
||||
std::make_pair((int)Qt::Key_Favorites , "Favorites"),
|
||||
std::make_pair((int)Qt::Key_Search , "Search"),
|
||||
std::make_pair((int)Qt::Key_Standby , "Standby"),
|
||||
std::make_pair((int)Qt::Key_OpenUrl , "OpenUrl"),
|
||||
std::make_pair((int)Qt::Key_LaunchMail , "LaunchMail"),
|
||||
std::make_pair((int)Qt::Key_LaunchMedia , "LaunchMedia"),
|
||||
std::make_pair((int)Qt::Key_Launch0 , "Launch0"),
|
||||
std::make_pair((int)Qt::Key_Launch1 , "Launch1"),
|
||||
std::make_pair((int)Qt::Key_Launch2 , "Launch2"),
|
||||
std::make_pair((int)Qt::Key_Launch3 , "Launch3"),
|
||||
std::make_pair((int)Qt::Key_Launch4 , "Launch4"),
|
||||
std::make_pair((int)Qt::Key_Launch5 , "Launch5"),
|
||||
std::make_pair((int)Qt::Key_Launch6 , "Launch6"),
|
||||
std::make_pair((int)Qt::Key_Launch7 , "Launch7"),
|
||||
std::make_pair((int)Qt::Key_Launch8 , "Launch8"),
|
||||
std::make_pair((int)Qt::Key_Launch9 , "Launch9"),
|
||||
std::make_pair((int)Qt::Key_LaunchA , "LaunchA"),
|
||||
std::make_pair((int)Qt::Key_LaunchB , "LaunchB"),
|
||||
std::make_pair((int)Qt::Key_LaunchC , "LaunchC"),
|
||||
std::make_pair((int)Qt::Key_LaunchD , "LaunchD"),
|
||||
std::make_pair((int)Qt::Key_LaunchE , "LaunchE"),
|
||||
std::make_pair((int)Qt::Key_LaunchF , "LaunchF"),
|
||||
std::make_pair((int)Qt::Key_MonBrightnessUp , "MonBrightnessUp"),
|
||||
std::make_pair((int)Qt::Key_MonBrightnessDown , "MonBrightnessDown"),
|
||||
std::make_pair((int)Qt::Key_KeyboardLightOnOff , "KeyboardLightOnOff"),
|
||||
std::make_pair((int)Qt::Key_KeyboardBrightnessUp , "KeyboardBrightnessUp"),
|
||||
std::make_pair((int)Qt::Key_KeyboardBrightnessDown , "KeyboardBrightnessDown"),
|
||||
std::make_pair((int)Qt::Key_PowerOff , "PowerOff"),
|
||||
std::make_pair((int)Qt::Key_WakeUp , "WakeUp"),
|
||||
std::make_pair((int)Qt::Key_Eject , "Eject"),
|
||||
std::make_pair((int)Qt::Key_ScreenSaver , "ScreenSaver"),
|
||||
std::make_pair((int)Qt::Key_WWW , "WWW"),
|
||||
std::make_pair((int)Qt::Key_Memo , "Memo"),
|
||||
std::make_pair((int)Qt::Key_LightBulb , "LightBulb"),
|
||||
std::make_pair((int)Qt::Key_Shop , "Shop"),
|
||||
std::make_pair((int)Qt::Key_History , "History"),
|
||||
std::make_pair((int)Qt::Key_AddFavorite , "AddFavorite"),
|
||||
std::make_pair((int)Qt::Key_HotLinks , "HotLinks"),
|
||||
std::make_pair((int)Qt::Key_BrightnessAdjust , "BrightnessAdjust"),
|
||||
std::make_pair((int)Qt::Key_Finance , "Finance"),
|
||||
std::make_pair((int)Qt::Key_Community , "Community"),
|
||||
std::make_pair((int)Qt::Key_AudioRewind , "AudioRewind"),
|
||||
std::make_pair((int)Qt::Key_BackForward , "BackForward"),
|
||||
std::make_pair((int)Qt::Key_ApplicationLeft , "ApplicationLeft"),
|
||||
std::make_pair((int)Qt::Key_ApplicationRight , "ApplicationRight"),
|
||||
std::make_pair((int)Qt::Key_Book , "Book"),
|
||||
std::make_pair((int)Qt::Key_CD , "CD"),
|
||||
std::make_pair((int)Qt::Key_Calculator , "Calculator"),
|
||||
std::make_pair((int)Qt::Key_ToDoList , "ToDoList"),
|
||||
std::make_pair((int)Qt::Key_ClearGrab , "ClearGrab"),
|
||||
std::make_pair((int)Qt::Key_Close , "Close"),
|
||||
std::make_pair((int)Qt::Key_Copy , "Copy"),
|
||||
std::make_pair((int)Qt::Key_Cut , "Cut"),
|
||||
std::make_pair((int)Qt::Key_Display , "Display"),
|
||||
std::make_pair((int)Qt::Key_DOS , "DOS"),
|
||||
std::make_pair((int)Qt::Key_Documents , "Documents"),
|
||||
std::make_pair((int)Qt::Key_Excel , "Excel"),
|
||||
std::make_pair((int)Qt::Key_Explorer , "Explorer"),
|
||||
std::make_pair((int)Qt::Key_Game , "Game"),
|
||||
std::make_pair((int)Qt::Key_Go , "Go"),
|
||||
std::make_pair((int)Qt::Key_iTouch , "iTouch"),
|
||||
std::make_pair((int)Qt::Key_LogOff , "LogOff"),
|
||||
std::make_pair((int)Qt::Key_Market , "Market"),
|
||||
std::make_pair((int)Qt::Key_Meeting , "Meeting"),
|
||||
std::make_pair((int)Qt::Key_MenuKB , "MenuKB"),
|
||||
std::make_pair((int)Qt::Key_MenuPB , "MenuPB"),
|
||||
std::make_pair((int)Qt::Key_MySites , "MySites"),
|
||||
std::make_pair((int)Qt::Key_News , "News"),
|
||||
std::make_pair((int)Qt::Key_OfficeHome , "OfficeHome"),
|
||||
std::make_pair((int)Qt::Key_Option , "Option"),
|
||||
std::make_pair((int)Qt::Key_Paste , "Paste"),
|
||||
std::make_pair((int)Qt::Key_Phone , "Phone"),
|
||||
std::make_pair((int)Qt::Key_Calendar , "Calendar"),
|
||||
std::make_pair((int)Qt::Key_Reply , "Reply"),
|
||||
std::make_pair((int)Qt::Key_Reload , "Reload"),
|
||||
std::make_pair((int)Qt::Key_RotateWindows , "RotateWindows"),
|
||||
std::make_pair((int)Qt::Key_RotationPB , "RotationPB"),
|
||||
std::make_pair((int)Qt::Key_RotationKB , "RotationKB"),
|
||||
std::make_pair((int)Qt::Key_Save , "Save"),
|
||||
std::make_pair((int)Qt::Key_Send , "Send"),
|
||||
std::make_pair((int)Qt::Key_Spell , "Spell"),
|
||||
std::make_pair((int)Qt::Key_SplitScreen , "SplitScreen"),
|
||||
std::make_pair((int)Qt::Key_Support , "Support"),
|
||||
std::make_pair((int)Qt::Key_TaskPane , "TaskPane"),
|
||||
std::make_pair((int)Qt::Key_Terminal , "Terminal"),
|
||||
std::make_pair((int)Qt::Key_Tools , "Tools"),
|
||||
std::make_pair((int)Qt::Key_Travel , "Travel"),
|
||||
std::make_pair((int)Qt::Key_Video , "Video"),
|
||||
std::make_pair((int)Qt::Key_Word , "Word"),
|
||||
std::make_pair((int)Qt::Key_Xfer , "Xfer"),
|
||||
std::make_pair((int)Qt::Key_ZoomIn , "ZoomIn"),
|
||||
std::make_pair((int)Qt::Key_ZoomOut , "ZoomOut"),
|
||||
std::make_pair((int)Qt::Key_Away , "Away"),
|
||||
std::make_pair((int)Qt::Key_Messenger , "Messenger"),
|
||||
std::make_pair((int)Qt::Key_WebCam , "WebCam"),
|
||||
std::make_pair((int)Qt::Key_MailForward , "MailForward"),
|
||||
std::make_pair((int)Qt::Key_Pictures , "Pictures"),
|
||||
std::make_pair((int)Qt::Key_Music , "Music"),
|
||||
std::make_pair((int)Qt::Key_Battery , "Battery"),
|
||||
std::make_pair((int)Qt::Key_Bluetooth , "Bluetooth"),
|
||||
std::make_pair((int)Qt::Key_WLAN , "WLAN"),
|
||||
std::make_pair((int)Qt::Key_UWB , "UWB"),
|
||||
std::make_pair((int)Qt::Key_AudioForward , "AudioForward"),
|
||||
std::make_pair((int)Qt::Key_AudioRepeat , "AudioRepeat"),
|
||||
std::make_pair((int)Qt::Key_AudioRandomPlay , "AudioRandomPlay"),
|
||||
std::make_pair((int)Qt::Key_Subtitle , "Subtitle"),
|
||||
std::make_pair((int)Qt::Key_AudioCycleTrack , "AudioCycleTrack"),
|
||||
std::make_pair((int)Qt::Key_Time , "Time"),
|
||||
std::make_pair((int)Qt::Key_Hibernate , "Hibernate"),
|
||||
std::make_pair((int)Qt::Key_View , "View"),
|
||||
std::make_pair((int)Qt::Key_TopMenu , "TopMenu"),
|
||||
std::make_pair((int)Qt::Key_PowerDown , "PowerDown"),
|
||||
std::make_pair((int)Qt::Key_Suspend , "Suspend"),
|
||||
std::make_pair((int)Qt::Key_ContrastAdjust , "ContrastAdjust"),
|
||||
std::make_pair((int)Qt::Key_LaunchG , "LaunchG"),
|
||||
std::make_pair((int)Qt::Key_LaunchH , "LaunchH"),
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
|
||||
std::make_pair((int)Qt::Key_TouchpadToggle , "TouchpadToggle"),
|
||||
std::make_pair((int)Qt::Key_TouchpadOn , "TouchpadOn"),
|
||||
std::make_pair((int)Qt::Key_TouchpadOff , "TouchpadOff"),
|
||||
std::make_pair((int)Qt::Key_MicMute , "MicMute"),
|
||||
std::make_pair((int)Qt::Key_Red , "Red"),
|
||||
std::make_pair((int)Qt::Key_Green , "Green"),
|
||||
std::make_pair((int)Qt::Key_Yellow , "Yellow"),
|
||||
std::make_pair((int)Qt::Key_Blue , "Blue"),
|
||||
std::make_pair((int)Qt::Key_ChannelUp , "ChannelUp"),
|
||||
std::make_pair((int)Qt::Key_ChannelDown , "ChannelDown"),
|
||||
std::make_pair((int)Qt::Key_Guide , "Guide"),
|
||||
std::make_pair((int)Qt::Key_Info , "Info"),
|
||||
std::make_pair((int)Qt::Key_Settings , "Settings"),
|
||||
std::make_pair((int)Qt::Key_MicVolumeUp , "MicVolumeUp"),
|
||||
std::make_pair((int)Qt::Key_MicVolumeDown , "MicVolumeDown"),
|
||||
std::make_pair((int)Qt::Key_New , "New"),
|
||||
std::make_pair((int)Qt::Key_Open , "Open"),
|
||||
std::make_pair((int)Qt::Key_Find , "Find"),
|
||||
std::make_pair((int)Qt::Key_Undo , "Undo"),
|
||||
std::make_pair((int)Qt::Key_Redo , "Redo"),
|
||||
#endif
|
||||
std::make_pair((int)Qt::Key_AltGr , "AltGr"),
|
||||
std::make_pair((int)Qt::Key_Multi_key , "Multi_key"),
|
||||
std::make_pair((int)Qt::Key_Kanji , "Kanji"),
|
||||
std::make_pair((int)Qt::Key_Muhenkan , "Muhenkan"),
|
||||
std::make_pair((int)Qt::Key_Henkan , "Henkan"),
|
||||
std::make_pair((int)Qt::Key_Romaji , "Romaji"),
|
||||
std::make_pair((int)Qt::Key_Hiragana , "Hiragana"),
|
||||
std::make_pair((int)Qt::Key_Katakana , "Katakana"),
|
||||
std::make_pair((int)Qt::Key_Hiragana_Katakana , "Hiragana_Katakana"),
|
||||
std::make_pair((int)Qt::Key_Zenkaku , "Zenkaku"),
|
||||
std::make_pair((int)Qt::Key_Hankaku , "Hankaku"),
|
||||
std::make_pair((int)Qt::Key_Zenkaku_Hankaku , "Zenkaku_Hankaku"),
|
||||
std::make_pair((int)Qt::Key_Touroku , "Touroku"),
|
||||
std::make_pair((int)Qt::Key_Massyo , "Massyo"),
|
||||
std::make_pair((int)Qt::Key_Kana_Lock , "Kana_Lock"),
|
||||
std::make_pair((int)Qt::Key_Kana_Shift , "Kana_Shift"),
|
||||
std::make_pair((int)Qt::Key_Eisu_Shift , "Eisu_Shift"),
|
||||
std::make_pair((int)Qt::Key_Eisu_toggle , "Eisu_toggle"),
|
||||
std::make_pair((int)Qt::Key_Hangul , "Hangul"),
|
||||
std::make_pair((int)Qt::Key_Hangul_Start , "Hangul_Start"),
|
||||
std::make_pair((int)Qt::Key_Hangul_End , "Hangul_End"),
|
||||
std::make_pair((int)Qt::Key_Hangul_Hanja , "Hangul_Hanja"),
|
||||
std::make_pair((int)Qt::Key_Hangul_Jamo , "Hangul_Jamo"),
|
||||
std::make_pair((int)Qt::Key_Hangul_Romaja , "Hangul_Romaja"),
|
||||
std::make_pair((int)Qt::Key_Codeinput , "Codeinput"),
|
||||
std::make_pair((int)Qt::Key_Hangul_Jeonja , "Hangul_Jeonja"),
|
||||
std::make_pair((int)Qt::Key_Hangul_Banja , "Hangul_Banja"),
|
||||
std::make_pair((int)Qt::Key_Hangul_PreHanja , "Hangul_PreHanja"),
|
||||
std::make_pair((int)Qt::Key_Hangul_PostHanja , "Hangul_PostHanja"),
|
||||
std::make_pair((int)Qt::Key_SingleCandidate , "SingleCandidate"),
|
||||
std::make_pair((int)Qt::Key_MultipleCandidate , "MultipleCandidate"),
|
||||
std::make_pair((int)Qt::Key_PreviousCandidate , "PreviousCandidate"),
|
||||
std::make_pair((int)Qt::Key_Hangul_Special , "Hangul_Special"),
|
||||
std::make_pair((int)Qt::Key_Mode_switch , "Mode_switch"),
|
||||
std::make_pair((int)Qt::Key_Dead_Grave , "Dead_Grave"),
|
||||
std::make_pair((int)Qt::Key_Dead_Acute , "Dead_Acute"),
|
||||
std::make_pair((int)Qt::Key_Dead_Circumflex , "Dead_Circumflex"),
|
||||
std::make_pair((int)Qt::Key_Dead_Tilde , "Dead_Tilde"),
|
||||
std::make_pair((int)Qt::Key_Dead_Macron , "Dead_Macron"),
|
||||
std::make_pair((int)Qt::Key_Dead_Breve , "Dead_Breve"),
|
||||
std::make_pair((int)Qt::Key_Dead_Abovedot , "Dead_Abovedot"),
|
||||
std::make_pair((int)Qt::Key_Dead_Diaeresis , "Dead_Diaeresis"),
|
||||
std::make_pair((int)Qt::Key_Dead_Abovering , "Dead_Abovering"),
|
||||
std::make_pair((int)Qt::Key_Dead_Doubleacute , "Dead_Doubleacute"),
|
||||
std::make_pair((int)Qt::Key_Dead_Caron , "Dead_Caron"),
|
||||
std::make_pair((int)Qt::Key_Dead_Cedilla , "Dead_Cedilla"),
|
||||
std::make_pair((int)Qt::Key_Dead_Ogonek , "Dead_Ogonek"),
|
||||
std::make_pair((int)Qt::Key_Dead_Iota , "Dead_Iota"),
|
||||
std::make_pair((int)Qt::Key_Dead_Voiced_Sound , "Dead_Voiced_Sound"),
|
||||
std::make_pair((int)Qt::Key_Dead_Semivoiced_Sound , "Dead_Semivoiced_Sound"),
|
||||
std::make_pair((int)Qt::Key_Dead_Belowdot , "Dead_Belowdot"),
|
||||
std::make_pair((int)Qt::Key_Dead_Hook , "Dead_Hook"),
|
||||
std::make_pair((int)Qt::Key_Dead_Horn , "Dead_Horn"),
|
||||
std::make_pair((int)Qt::Key_MediaLast , "MediaLast"),
|
||||
std::make_pair((int)Qt::Key_Select , "Select"),
|
||||
std::make_pair((int)Qt::Key_Yes , "Yes"),
|
||||
std::make_pair((int)Qt::Key_No , "No"),
|
||||
std::make_pair((int)Qt::Key_Cancel , "Cancel"),
|
||||
std::make_pair((int)Qt::Key_Printer , "Printer"),
|
||||
std::make_pair((int)Qt::Key_Execute , "Execute"),
|
||||
std::make_pair((int)Qt::Key_Sleep , "Sleep"),
|
||||
std::make_pair((int)Qt::Key_Play , "Play"),
|
||||
std::make_pair((int)Qt::Key_Zoom , "Zoom"),
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
|
||||
std::make_pair((int)Qt::Key_Exit , "Exit"),
|
||||
#endif
|
||||
std::make_pair((int)Qt::Key_Context1 , "Context1"),
|
||||
std::make_pair((int)Qt::Key_Context2 , "Context2"),
|
||||
std::make_pair((int)Qt::Key_Context3 , "Context3"),
|
||||
std::make_pair((int)Qt::Key_Context4 , "Context4"),
|
||||
std::make_pair((int)Qt::Key_Call , "Call"),
|
||||
std::make_pair((int)Qt::Key_Hangup , "Hangup"),
|
||||
std::make_pair((int)Qt::Key_Flip , "Flip"),
|
||||
std::make_pair((int)Qt::Key_ToggleCallHangup , "ToggleCallHangup"),
|
||||
std::make_pair((int)Qt::Key_VoiceDial , "VoiceDial"),
|
||||
std::make_pair((int)Qt::Key_LastNumberRedial , "LastNumberRedial"),
|
||||
std::make_pair((int)Qt::Key_Camera , "Camera"),
|
||||
std::make_pair((int)Qt::Key_CameraFocus , "CameraFocus"),
|
||||
std::make_pair(0 , (const char*) 0)
|
||||
};
|
||||
|
||||
}
|
73
apps/opencs/model/prefs/shortcutmanager.hpp
Normal file
73
apps/opencs/model/prefs/shortcutmanager.hpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
#ifndef CSM_PREFS_SHORTCUTMANAGER_H
|
||||
#define CSM_PREFS_SHORTCUTMANAGER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Shortcut;
|
||||
class ShortcutEventHandler;
|
||||
|
||||
/// Class used to track and update shortcuts/sequences
|
||||
class ShortcutManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
ShortcutManager();
|
||||
|
||||
/// The shortcut class will do this automatically
|
||||
void addShortcut(Shortcut* shortcut);
|
||||
|
||||
/// The shortcut class will do this automatically
|
||||
void removeShortcut(Shortcut* shortcut);
|
||||
|
||||
bool getSequence(const std::string& name, QKeySequence& sequence) const;
|
||||
void setSequence(const std::string& name, const QKeySequence& sequence);
|
||||
|
||||
bool getModifier(const std::string& name, int& modifier) const;
|
||||
void setModifier(const std::string& name, int modifier);
|
||||
|
||||
std::string convertToString(const QKeySequence& sequence) const;
|
||||
std::string convertToString(int modifier) const;
|
||||
|
||||
std::string convertToString(const QKeySequence& sequence, int modifier) const;
|
||||
|
||||
void convertFromString(const std::string& data, QKeySequence& sequence) const;
|
||||
void convertFromString(const std::string& data, int& modifier) const;
|
||||
|
||||
void convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const;
|
||||
|
||||
/// Replaces "{sequence-name}" or "{modifier-name}" with the appropriate text
|
||||
QString processToolTip(const QString& toolTip) const;
|
||||
|
||||
private:
|
||||
|
||||
// Need a multimap in case multiple shortcuts share the same name
|
||||
typedef std::multimap<std::string, Shortcut*> ShortcutMap;
|
||||
typedef std::map<std::string, QKeySequence> SequenceMap;
|
||||
typedef std::map<std::string, int> ModifierMap;
|
||||
typedef std::map<int, std::string> NameMap;
|
||||
typedef std::map<std::string, int> KeyMap;
|
||||
|
||||
ShortcutMap mShortcuts;
|
||||
SequenceMap mSequences;
|
||||
ModifierMap mModifiers;
|
||||
|
||||
NameMap mNames;
|
||||
KeyMap mKeys;
|
||||
|
||||
ShortcutEventHandler* mEventHandler;
|
||||
|
||||
void createLookupTables();
|
||||
|
||||
static const std::pair<int, const char*> QtKeys[];
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
196
apps/opencs/model/prefs/shortcutsetting.cpp
Normal file
196
apps/opencs/model/prefs/shortcutsetting.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
#include "shortcutsetting.hpp"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
#include "state.hpp"
|
||||
#include "shortcutmanager.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
const int ShortcutSetting::MaxKeys;
|
||||
|
||||
ShortcutSetting::ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||
const std::string& label)
|
||||
: Setting(parent, values, mutex, key, label)
|
||||
, mEditorActive(false)
|
||||
, mEditorPos(0)
|
||||
{
|
||||
for (int i = 0; i < MaxKeys; ++i)
|
||||
{
|
||||
mEditorKeys[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<QWidget*, QWidget*> ShortcutSetting::makeWidgets(QWidget* parent)
|
||||
{
|
||||
QKeySequence sequence;
|
||||
State::get().getShortcutManager().getSequence(getKey(), sequence);
|
||||
|
||||
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(sequence).c_str());
|
||||
|
||||
QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent);
|
||||
QPushButton* widget = new QPushButton(text, parent);
|
||||
|
||||
widget->setCheckable(true);
|
||||
widget->installEventFilter(this);
|
||||
mButton = widget;
|
||||
|
||||
connect(widget, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool)));
|
||||
|
||||
return std::make_pair(label, widget);
|
||||
}
|
||||
|
||||
bool ShortcutSetting::eventFilter(QObject* target, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->isAutoRepeat())
|
||||
return true;
|
||||
|
||||
int mod = keyEvent->modifiers();
|
||||
int key = keyEvent->key();
|
||||
|
||||
return handleEvent(target, mod, key, true);
|
||||
}
|
||||
else if (event->type() == QEvent::KeyRelease)
|
||||
{
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->isAutoRepeat())
|
||||
return true;
|
||||
|
||||
int mod = keyEvent->modifiers();
|
||||
int key = keyEvent->key();
|
||||
|
||||
return handleEvent(target, mod, key, false);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
int mod = mouseEvent->modifiers();
|
||||
int key = mouseEvent->button();
|
||||
|
||||
return handleEvent(target, mod, key, true);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseButtonRelease)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
int mod = mouseEvent->modifiers();
|
||||
int key = mouseEvent->button();
|
||||
|
||||
return handleEvent(target, mod, key, false);
|
||||
}
|
||||
else if (event->type() == QEvent::FocusOut)
|
||||
{
|
||||
resetState();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ShortcutSetting::handleEvent(QObject* target, int mod, int value, bool active)
|
||||
{
|
||||
// Modifiers are handled differently
|
||||
const int Blacklist[] =
|
||||
{
|
||||
Qt::Key_Shift,
|
||||
Qt::Key_Control,
|
||||
Qt::Key_Meta,
|
||||
Qt::Key_Alt,
|
||||
Qt::Key_AltGr
|
||||
};
|
||||
|
||||
const size_t BlacklistSize = sizeof(Blacklist) / sizeof(int);
|
||||
|
||||
if (!mEditorActive)
|
||||
{
|
||||
if (value == Qt::RightButton && !active)
|
||||
{
|
||||
// Clear sequence
|
||||
QKeySequence sequence = QKeySequence(0, 0, 0, 0);
|
||||
storeValue(sequence);
|
||||
|
||||
resetState();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle blacklist
|
||||
for (size_t i = 0; i < BlacklistSize; ++i)
|
||||
{
|
||||
if (value == Blacklist[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!active || mEditorPos >= MaxKeys)
|
||||
{
|
||||
// Update key
|
||||
QKeySequence sequence = QKeySequence(mEditorKeys[0], mEditorKeys[1], mEditorKeys[2], mEditorKeys[3]);
|
||||
storeValue(sequence);
|
||||
|
||||
resetState();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mEditorPos == 0)
|
||||
{
|
||||
mEditorKeys[0] = mod | value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEditorKeys[mEditorPos] = value;
|
||||
}
|
||||
|
||||
mEditorPos += 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShortcutSetting::storeValue(const QKeySequence& sequence)
|
||||
{
|
||||
State::get().getShortcutManager().setSequence(getKey(), sequence);
|
||||
|
||||
// Convert to string and assign
|
||||
std::string value = State::get().getShortcutManager().convertToString(sequence);
|
||||
|
||||
{
|
||||
QMutexLocker lock(getMutex());
|
||||
getValues().setString(getKey(), getParent()->getKey(), value);
|
||||
}
|
||||
|
||||
getParent()->getState()->update(*this);
|
||||
}
|
||||
|
||||
void ShortcutSetting::resetState()
|
||||
{
|
||||
mButton->setChecked(false);
|
||||
mEditorActive = false;
|
||||
mEditorPos = 0;
|
||||
for (int i = 0; i < MaxKeys; ++i)
|
||||
{
|
||||
mEditorKeys[i] = 0;
|
||||
}
|
||||
|
||||
// Button text
|
||||
QKeySequence sequence;
|
||||
State::get().getShortcutManager().getSequence(getKey(), sequence);
|
||||
|
||||
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(sequence).c_str());
|
||||
mButton->setText(text);
|
||||
}
|
||||
|
||||
void ShortcutSetting::buttonToggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
mButton->setText("Press keys or click here...");
|
||||
|
||||
mEditorActive = checked;
|
||||
}
|
||||
}
|
49
apps/opencs/model/prefs/shortcutsetting.hpp
Normal file
49
apps/opencs/model/prefs/shortcutsetting.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#ifndef CSM_PREFS_SHORTCUTSETTING_H
|
||||
#define CSM_PREFS_SHORTCUTSETTING_H
|
||||
|
||||
#include <QKeySequence>
|
||||
|
||||
#include "setting.hpp"
|
||||
|
||||
class QEvent;
|
||||
class QPushButton;
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class ShortcutSetting : public Setting
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||
const std::string& label);
|
||||
|
||||
virtual std::pair<QWidget*, QWidget*> makeWidgets(QWidget* parent);
|
||||
|
||||
protected:
|
||||
|
||||
bool eventFilter(QObject* target, QEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
bool handleEvent(QObject* target, int mod, int value, bool active);
|
||||
|
||||
void storeValue(const QKeySequence& sequence);
|
||||
void resetState();
|
||||
|
||||
static const int MaxKeys = 4;
|
||||
|
||||
QPushButton* mButton;
|
||||
|
||||
bool mEditorActive;
|
||||
int mEditorPos;
|
||||
int mEditorKeys[MaxKeys];
|
||||
|
||||
private slots:
|
||||
|
||||
void buttonToggled(bool checked);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9,6 +9,8 @@
|
|||
#include "doublesetting.hpp"
|
||||
#include "boolsetting.hpp"
|
||||
#include "coloursetting.hpp"
|
||||
#include "shortcutsetting.hpp"
|
||||
#include "modifiersetting.hpp"
|
||||
|
||||
CSMPrefs::State *CSMPrefs::State::sThis = 0;
|
||||
|
||||
|
@ -165,16 +167,6 @@ void CSMPrefs::State::declare()
|
|||
"list go to the first/last item");
|
||||
|
||||
declareCategory ("3D Scene Input");
|
||||
EnumValue left ("Left Mouse-Button");
|
||||
EnumValue cLeft ("Ctrl-Left Mouse-Button");
|
||||
EnumValue right ("Right Mouse-Button");
|
||||
EnumValue cRight ("Ctrl-Right Mouse-Button");
|
||||
EnumValue middle ("Middle Mouse-Button");
|
||||
EnumValue cMiddle ("Ctrl-Middle Mouse-Button");
|
||||
EnumValues inputButtons;
|
||||
inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle);
|
||||
declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons);
|
||||
declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons);
|
||||
declareDouble ("p-navi-free-sensitivity", "Free Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
||||
declareBool ("p-navi-free-invert", "Invert Free Camera Mouse Input", false);
|
||||
declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
||||
|
@ -186,10 +178,6 @@ void CSMPrefs::State::declare()
|
|||
declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0);
|
||||
declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28);
|
||||
declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0);
|
||||
declareEnum ("p-edit", "Primary Editing Button", right).addValues (inputButtons);
|
||||
declareEnum ("s-edit", "Secondary Editing Button", cRight).addValues (inputButtons);
|
||||
declareEnum ("p-select", "Primary Selection Button", middle).addValues (inputButtons);
|
||||
declareEnum ("s-select", "Secondary Selection Button", cMiddle).addValues (inputButtons);
|
||||
declareSeparator();
|
||||
declareBool ("context-select", "Context Sensitive Selection", false);
|
||||
declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0).
|
||||
|
@ -224,6 +212,119 @@ void CSMPrefs::State::declare()
|
|||
addValues (insertOutsideCell);
|
||||
declareEnum ("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert).
|
||||
addValues (insertOutsideVisibleCell);
|
||||
|
||||
declareCategory ("Key Bindings");
|
||||
|
||||
declareSubcategory ("Document");
|
||||
declareShortcut ("document-file-newgame", "New Game", QKeySequence(Qt::ControlModifier | Qt::Key_N));
|
||||
declareShortcut ("document-file-newaddon", "New Addon", QKeySequence());
|
||||
declareShortcut ("document-file-open", "Open", QKeySequence(Qt::ControlModifier | Qt::Key_O));
|
||||
declareShortcut ("document-file-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S));
|
||||
declareShortcut ("document-file-verify", "Verify", QKeySequence());
|
||||
declareShortcut ("document-file-merge", "Merge", QKeySequence());
|
||||
declareShortcut ("document-file-errorlog", "Open Load Error Log", QKeySequence());
|
||||
declareShortcut ("document-file-metadata", "Meta Data", QKeySequence());
|
||||
declareShortcut ("document-file-close", "Close Document", QKeySequence(Qt::ControlModifier | Qt::Key_W));
|
||||
declareShortcut ("document-file-exit", "Exit Application", QKeySequence(Qt::ControlModifier | Qt::Key_Q));
|
||||
declareShortcut ("document-edit-undo", "Undo", QKeySequence(Qt::ControlModifier | Qt::Key_Z));
|
||||
declareShortcut ("document-edit-redo", "Redo", QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Z));
|
||||
declareShortcut ("document-edit-preferences", "Open Preferences", QKeySequence());
|
||||
declareShortcut ("document-edit-search", "Search", QKeySequence(Qt::ControlModifier | Qt::Key_F));
|
||||
declareShortcut ("document-view-newview", "New View", QKeySequence());
|
||||
declareShortcut ("document-view-statusbar", "Toggle Status Bar", QKeySequence());
|
||||
declareShortcut ("document-view-filters", "Open Filter List", QKeySequence());
|
||||
declareShortcut ("document-world-regions", "Open Region List", QKeySequence());
|
||||
declareShortcut ("document-world-cells", "Open Cell List", QKeySequence());
|
||||
declareShortcut ("document-world-referencables", "Open Object List", QKeySequence());
|
||||
declareShortcut ("document-world-references", "Open Instance List", QKeySequence());
|
||||
declareShortcut ("document-world-pathgrid", "Open Pathgrid List", QKeySequence());
|
||||
declareShortcut ("document-world-regionmap", "Open Region Map", QKeySequence());
|
||||
declareShortcut ("document-mechanics-globals", "Open Global List", QKeySequence());
|
||||
declareShortcut ("document-mechanics-gamesettings", "Open Game Settings", QKeySequence());
|
||||
declareShortcut ("document-mechanics-scripts", "Open Script List", QKeySequence());
|
||||
declareShortcut ("document-mechanics-spells", "Open Spell List", QKeySequence());
|
||||
declareShortcut ("document-mechanics-enchantments", "Open Enchantment List", QKeySequence());
|
||||
declareShortcut ("document-mechanics-magiceffects", "Open Magic Effect List", QKeySequence());
|
||||
declareShortcut ("document-mechanics-startscripts", "Open Start Script List", QKeySequence());
|
||||
declareShortcut ("document-character-skills", "Open Skill List", QKeySequence());
|
||||
declareShortcut ("document-character-classes", "Open Class List", QKeySequence());
|
||||
declareShortcut ("document-character-factions", "Open Faction List", QKeySequence());
|
||||
declareShortcut ("document-character-races", "Open Race List", QKeySequence());
|
||||
declareShortcut ("document-character-birthsigns", "Open Birthsign List", QKeySequence());
|
||||
declareShortcut ("document-character-topics", "Open Topic List", QKeySequence());
|
||||
declareShortcut ("document-character-journals", "Open Journal List", QKeySequence());
|
||||
declareShortcut ("document-character-topicinfos", "Open Topic Info List", QKeySequence());
|
||||
declareShortcut ("document-character-journalinfos", "Open Journal Info List", QKeySequence());
|
||||
declareShortcut ("document-character-bodyparts", "Open Body Part List", QKeySequence());
|
||||
declareShortcut ("document-assets-sounds", "Open Sound Asset List", QKeySequence());
|
||||
declareShortcut ("document-assets-soundgens", "Open Sound Generator List", QKeySequence());
|
||||
declareShortcut ("document-assets-meshes", "Open Mesh Asset List", QKeySequence());
|
||||
declareShortcut ("document-assets-icons", "Open Icon Asset List", QKeySequence());
|
||||
declareShortcut ("document-assets-music", "Open Music Asset List", QKeySequence());
|
||||
declareShortcut ("document-assets-soundres", "Open Sound File List", QKeySequence());
|
||||
declareShortcut ("document-assets-textures", "Open Texture Asset List", QKeySequence());
|
||||
declareShortcut ("document-assets-videos", "Open Video Asset List", QKeySequence());
|
||||
declareShortcut ("document-debug-run", "Run Debug", QKeySequence());
|
||||
declareShortcut ("document-debug-shutdown", "Stop Debug", QKeySequence());
|
||||
declareShortcut ("document-debug-runlog", "Open Run Log", QKeySequence());
|
||||
|
||||
declareSubcategory ("Table");
|
||||
declareShortcut ("table-edit", "Edit Record", QKeySequence());
|
||||
declareShortcut ("table-add", "Add Row/Record", QKeySequence(Qt::ShiftModifier | Qt::Key_A));
|
||||
declareShortcut ("table-clone", "Clone Record", QKeySequence(Qt::ShiftModifier | Qt::Key_D));
|
||||
declareShortcut ("table-revert", "Revert Record", QKeySequence());
|
||||
declareShortcut ("table-remove", "Remove Row/Record", QKeySequence(Qt::Key_Delete));
|
||||
declareShortcut ("table-moveup", "Move Record Up", QKeySequence());
|
||||
declareShortcut ("table-movedown", "Move Record Down", QKeySequence());
|
||||
declareShortcut ("table-view", "View Record", QKeySequence());
|
||||
declareShortcut ("table-preview", "Preview Record", QKeySequence());
|
||||
declareShortcut ("table-extendeddelete", "Extended Record Deletion", QKeySequence());
|
||||
declareShortcut ("table-extendedrevert", "Extended Record Revertion", QKeySequence());
|
||||
|
||||
declareSubcategory ("Report Table");
|
||||
declareShortcut ("reporttable-show", "Show Report", QKeySequence());
|
||||
declareShortcut ("reporttable-remove", "Remove Report", QKeySequence(Qt::Key_Delete));
|
||||
declareShortcut ("reporttable-replace", "Replace Report", QKeySequence());
|
||||
declareShortcut ("reporttable-refresh", "Refresh Report", QKeySequence());
|
||||
|
||||
declareSubcategory ("Scene");
|
||||
declareShortcut ("scene-navi-primary", "Camera Rotation From Mouse Movement", QKeySequence(Qt::LeftButton));
|
||||
declareShortcut ("scene-navi-secondary", "Camera Translation From Mouse Movement",
|
||||
QKeySequence(Qt::ControlModifier | (int)Qt::LeftButton));
|
||||
declareShortcut ("scene-edit-primary", "Primary Edit", QKeySequence(Qt::RightButton));
|
||||
declareShortcut ("scene-edit-secondary", "Secondary Edit",
|
||||
QKeySequence(Qt::ControlModifier | (int)Qt::RightButton));
|
||||
declareShortcut ("scene-select-primary", "Primary Select", QKeySequence(Qt::MiddleButton));
|
||||
declareShortcut ("scene-select-secondary", "Secondary Select",
|
||||
QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton));
|
||||
declareModifier ("scene-speed-modifier", "Speed Modifier", Qt::Key_Shift);
|
||||
declareShortcut ("scene-load-cam-cell", "Load Camera Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_5));
|
||||
declareShortcut ("scene-load-cam-eastcell", "Load East Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_6));
|
||||
declareShortcut ("scene-load-cam-northcell", "Load North Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_8));
|
||||
declareShortcut ("scene-load-cam-westcell", "Load West Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_4));
|
||||
declareShortcut ("scene-load-cam-southcell", "Load South Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_2));
|
||||
declareShortcut ("scene-edit-abort", "Abort", QKeySequence(Qt::Key_Escape));
|
||||
declareShortcut ("scene-focus-toolbar", "Toggle Toolbar Focus", QKeySequence(Qt::Key_T));
|
||||
declareShortcut ("scene-render-stats", "Debug Rendering Stats", QKeySequence(Qt::Key_F3));
|
||||
|
||||
declareSubcategory ("1st/Free Camera");
|
||||
declareShortcut ("free-forward", "Forward", QKeySequence(Qt::Key_W));
|
||||
declareShortcut ("free-backward", "Backward", QKeySequence(Qt::Key_S));
|
||||
declareShortcut ("free-left", "Left", QKeySequence(Qt::Key_A));
|
||||
declareShortcut ("free-right", "Right", QKeySequence(Qt::Key_D));
|
||||
declareShortcut ("free-roll-left", "Roll Left", QKeySequence(Qt::Key_Q));
|
||||
declareShortcut ("free-roll-right", "Roll Right", QKeySequence(Qt::Key_E));
|
||||
declareShortcut ("free-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F));
|
||||
|
||||
declareSubcategory ("Orbit Camera");
|
||||
declareShortcut ("orbit-up", "Up", QKeySequence(Qt::Key_W));
|
||||
declareShortcut ("orbit-down", "Down", QKeySequence(Qt::Key_S));
|
||||
declareShortcut ("orbit-left", "Left", QKeySequence(Qt::Key_A));
|
||||
declareShortcut ("orbit-right", "Right", QKeySequence(Qt::Key_D));
|
||||
declareShortcut ("orbit-roll-left", "Roll Left", QKeySequence(Qt::Key_Q));
|
||||
declareShortcut ("orbit-roll-right", "Roll Right", QKeySequence(Qt::Key_E));
|
||||
declareShortcut ("orbit-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F));
|
||||
declareShortcut ("orbit-center-selection", "Center On Selected", QKeySequence(Qt::Key_C));
|
||||
}
|
||||
|
||||
void CSMPrefs::State::declareCategory (const std::string& key)
|
||||
|
@ -340,6 +441,50 @@ CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key,
|
|||
return *setting;
|
||||
}
|
||||
|
||||
CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut (const std::string& key, const std::string& label,
|
||||
const QKeySequence& default_)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
std::string seqStr = getShortcutManager().convertToString(default_);
|
||||
setDefault (key, seqStr);
|
||||
|
||||
// Setup with actual data
|
||||
QKeySequence sequence;
|
||||
|
||||
getShortcutManager().convertFromString(mSettings.getString(key, mCurrentCategory->second.getKey()), sequence);
|
||||
getShortcutManager().setSequence(key, sequence);
|
||||
|
||||
CSMPrefs::ShortcutSetting *setting = new CSMPrefs::ShortcutSetting (&mCurrentCategory->second, &mSettings, &mMutex,
|
||||
key, label);
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
|
||||
return *setting;
|
||||
}
|
||||
|
||||
CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier(const std::string& key, const std::string& label,
|
||||
int default_)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
std::string modStr = getShortcutManager().convertToString(default_);
|
||||
setDefault (key, modStr);
|
||||
|
||||
// Setup with actual data
|
||||
int modifier;
|
||||
|
||||
getShortcutManager().convertFromString(mSettings.getString(key, mCurrentCategory->second.getKey()), modifier);
|
||||
getShortcutManager().setModifier(key, modifier);
|
||||
|
||||
CSMPrefs::ModifierSetting *setting = new CSMPrefs::ModifierSetting (&mCurrentCategory->second, &mSettings, &mMutex,
|
||||
key, label);
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
|
||||
return *setting;
|
||||
}
|
||||
|
||||
void CSMPrefs::State::declareSeparator()
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
|
@ -351,6 +496,17 @@ void CSMPrefs::State::declareSeparator()
|
|||
mCurrentCategory->second.addSetting (setting);
|
||||
}
|
||||
|
||||
void CSMPrefs::State::declareSubcategory(const std::string& label)
|
||||
{
|
||||
if (mCurrentCategory==mCategories.end())
|
||||
throw std::logic_error ("no category for setting");
|
||||
|
||||
CSMPrefs::Setting *setting =
|
||||
new CSMPrefs::Setting (&mCurrentCategory->second, &mSettings, &mMutex, "", label);
|
||||
|
||||
mCurrentCategory->second.addSetting (setting);
|
||||
}
|
||||
|
||||
void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_)
|
||||
{
|
||||
Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key);
|
||||
|
@ -369,10 +525,10 @@ CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager)
|
|||
if (sThis)
|
||||
throw std::logic_error ("An instance of CSMPRefs::State already exists");
|
||||
|
||||
sThis = this;
|
||||
|
||||
load();
|
||||
declare();
|
||||
|
||||
sThis = this;
|
||||
}
|
||||
|
||||
CSMPrefs::State::~State()
|
||||
|
@ -396,6 +552,11 @@ CSMPrefs::State::Iterator CSMPrefs::State::end()
|
|||
return mCategories.end();
|
||||
}
|
||||
|
||||
CSMPrefs::ShortcutManager& CSMPrefs::State::getShortcutManager()
|
||||
{
|
||||
return mShortcutManager;
|
||||
}
|
||||
|
||||
CSMPrefs::Category& CSMPrefs::State::operator[] (const std::string& key)
|
||||
{
|
||||
Iterator iter = mCategories.find (key);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "category.hpp"
|
||||
#include "setting.hpp"
|
||||
#include "enumsetting.hpp"
|
||||
#include "shortcutmanager.hpp"
|
||||
|
||||
class QColor;
|
||||
|
||||
|
@ -25,6 +26,8 @@ namespace CSMPrefs
|
|||
class DoubleSetting;
|
||||
class BoolSetting;
|
||||
class ColourSetting;
|
||||
class ShortcutSetting;
|
||||
class ModifierSetting;
|
||||
|
||||
/// \brief User settings state
|
||||
///
|
||||
|
@ -45,6 +48,7 @@ namespace CSMPrefs
|
|||
|
||||
const std::string mConfigFile;
|
||||
const Files::ConfigurationManager& mConfigurationManager;
|
||||
ShortcutManager mShortcutManager;
|
||||
Settings::Manager mSettings;
|
||||
Collection mCategories;
|
||||
Iterator mCurrentCategory;
|
||||
|
@ -71,8 +75,15 @@ namespace CSMPrefs
|
|||
|
||||
ColourSetting& declareColour (const std::string& key, const std::string& label, QColor default_);
|
||||
|
||||
ShortcutSetting& declareShortcut (const std::string& key, const std::string& label,
|
||||
const QKeySequence& default_);
|
||||
|
||||
ModifierSetting& declareModifier(const std::string& key, const std::string& label, int modifier_);
|
||||
|
||||
void declareSeparator();
|
||||
|
||||
void declareSubcategory(const std::string& label);
|
||||
|
||||
void setDefault (const std::string& key, const std::string& default_);
|
||||
|
||||
public:
|
||||
|
@ -87,6 +98,8 @@ namespace CSMPrefs
|
|||
|
||||
Iterator end();
|
||||
|
||||
ShortcutManager& getShortcutManager();
|
||||
|
||||
Category& operator[](const std::string& key);
|
||||
|
||||
void update (const Setting& setting);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
|
@ -44,83 +45,98 @@ void CSVDoc::View::closeEvent (QCloseEvent *event)
|
|||
|
||||
void CSVDoc::View::setupFileMenu()
|
||||
{
|
||||
QMenu *file = menuBar()->addMenu (tr ("&File"));
|
||||
QMenu *file = menuBar()->addMenu (tr ("File"));
|
||||
|
||||
QAction *newGame = new QAction (tr ("New Game"), this);
|
||||
connect (newGame, SIGNAL (triggered()), this, SIGNAL (newGameRequest()));
|
||||
setupShortcut("document-file-newgame", newGame);
|
||||
file->addAction (newGame);
|
||||
|
||||
|
||||
QAction *newAddon = new QAction (tr ("New Addon"), this);
|
||||
connect (newAddon, SIGNAL (triggered()), this, SIGNAL (newAddonRequest()));
|
||||
setupShortcut("document-file-newaddon", newAddon);
|
||||
file->addAction (newAddon);
|
||||
|
||||
QAction *open = new QAction (tr ("&Open"), this);
|
||||
QAction *open = new QAction (tr ("Open"), this);
|
||||
connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest()));
|
||||
setupShortcut("document-file-open", open);
|
||||
file->addAction (open);
|
||||
|
||||
mSave = new QAction (tr ("&Save"), this);
|
||||
mSave = new QAction (tr ("Save"), this);
|
||||
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
|
||||
setupShortcut("document-file-save", mSave);
|
||||
file->addAction (mSave);
|
||||
|
||||
mVerify = new QAction (tr ("&Verify"), this);
|
||||
mVerify = new QAction (tr ("Verify"), this);
|
||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||
setupShortcut("document-file-verify", mVerify);
|
||||
file->addAction (mVerify);
|
||||
|
||||
mMerge = new QAction (tr ("Merge"), this);
|
||||
connect (mMerge, SIGNAL (triggered()), this, SLOT (merge()));
|
||||
setupShortcut("document-file-merge", mMerge);
|
||||
file->addAction (mMerge);
|
||||
|
||||
QAction *loadErrors = new QAction (tr ("Load Error Log"), this);
|
||||
QAction *loadErrors = new QAction (tr ("Open Load Error Log"), this);
|
||||
connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog()));
|
||||
setupShortcut("document-file-errorlog", loadErrors);
|
||||
file->addAction (loadErrors);
|
||||
|
||||
QAction *meta = new QAction (tr ("Meta Data"), this);
|
||||
connect (meta, SIGNAL (triggered()), this, SLOT (addMetaDataSubView()));
|
||||
setupShortcut("document-file-metadata", meta);
|
||||
file->addAction (meta);
|
||||
|
||||
QAction *close = new QAction (tr ("&Close"), this);
|
||||
QAction *close = new QAction (tr ("Close Document"), this);
|
||||
connect (close, SIGNAL (triggered()), this, SLOT (close()));
|
||||
setupShortcut("document-file-close", close);
|
||||
file->addAction(close);
|
||||
|
||||
QAction *exit = new QAction (tr ("&Exit"), this);
|
||||
QAction *exit = new QAction (tr ("Exit Application"), this);
|
||||
connect (exit, SIGNAL (triggered()), this, SLOT (exit()));
|
||||
connect (this, SIGNAL(exitApplicationRequest(CSVDoc::View *)), &mViewManager, SLOT(exitApplication(CSVDoc::View *)));
|
||||
setupShortcut("document-file-exit", exit);
|
||||
|
||||
file->addAction(exit);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupEditMenu()
|
||||
{
|
||||
QMenu *edit = menuBar()->addMenu (tr ("&Edit"));
|
||||
QMenu *edit = menuBar()->addMenu (tr ("Edit"));
|
||||
|
||||
mUndo = mDocument->getUndoStack().createUndoAction (this, tr("&Undo"));
|
||||
mUndo->setShortcuts (QKeySequence::Undo);
|
||||
mUndo = mDocument->getUndoStack().createUndoAction (this, tr("Undo"));
|
||||
setupShortcut("document-edit-undo", mUndo);
|
||||
edit->addAction (mUndo);
|
||||
|
||||
mRedo= mDocument->getUndoStack().createRedoAction (this, tr("&Redo"));
|
||||
mRedo->setShortcuts (QKeySequence::Redo);
|
||||
mRedo= mDocument->getUndoStack().createRedoAction (this, tr("Redo"));
|
||||
setupShortcut("document-edit-redo", mRedo);
|
||||
edit->addAction (mRedo);
|
||||
|
||||
QAction *userSettings = new QAction (tr ("&Preferences"), this);
|
||||
QAction *userSettings = new QAction (tr ("Preferences"), this);
|
||||
connect (userSettings, SIGNAL (triggered()), this, SIGNAL (editSettingsRequest()));
|
||||
setupShortcut("document-edit-preferences", userSettings);
|
||||
edit->addAction (userSettings);
|
||||
|
||||
QAction *search = new QAction (tr ("Search"), this);
|
||||
connect (search, SIGNAL (triggered()), this, SLOT (addSearchSubView()));
|
||||
setupShortcut("document-edit-search", search);
|
||||
edit->addAction (search);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupViewMenu()
|
||||
{
|
||||
QMenu *view = menuBar()->addMenu (tr ("&View"));
|
||||
QMenu *view = menuBar()->addMenu (tr ("View"));
|
||||
|
||||
QAction *newWindow = new QAction (tr ("&New View"), this);
|
||||
QAction *newWindow = new QAction (tr ("New View"), this);
|
||||
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView()));
|
||||
setupShortcut("document-view-newview", newWindow);
|
||||
view->addAction (newWindow);
|
||||
|
||||
mShowStatusBar = new QAction (tr ("Show Status Bar"), this);
|
||||
mShowStatusBar = new QAction (tr ("Toggle Status Bar"), this);
|
||||
mShowStatusBar->setCheckable (true);
|
||||
connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool)));
|
||||
setupShortcut("document-view-statusbar", mShowStatusBar);
|
||||
|
||||
mShowStatusBar->setChecked (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue());
|
||||
|
||||
|
@ -128,70 +144,84 @@ void CSVDoc::View::setupViewMenu()
|
|||
|
||||
QAction *filters = new QAction (tr ("Filters"), this);
|
||||
connect (filters, SIGNAL (triggered()), this, SLOT (addFiltersSubView()));
|
||||
setupShortcut("document-view-filters", filters);
|
||||
view->addAction (filters);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupWorldMenu()
|
||||
{
|
||||
QMenu *world = menuBar()->addMenu (tr ("&World"));
|
||||
QMenu *world = menuBar()->addMenu (tr ("World"));
|
||||
|
||||
QAction *regions = new QAction (tr ("Regions"), this);
|
||||
connect (regions, SIGNAL (triggered()), this, SLOT (addRegionsSubView()));
|
||||
setupShortcut("document-world-regions", regions);
|
||||
world->addAction (regions);
|
||||
|
||||
QAction *cells = new QAction (tr ("Cells"), this);
|
||||
connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView()));
|
||||
setupShortcut("document-world-cells", cells);
|
||||
world->addAction (cells);
|
||||
|
||||
QAction *referenceables = new QAction (tr ("Objects"), this);
|
||||
connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView()));
|
||||
setupShortcut("document-world-referencables", referenceables);
|
||||
world->addAction (referenceables);
|
||||
|
||||
QAction *references = new QAction (tr ("Instances"), this);
|
||||
connect (references, SIGNAL (triggered()), this, SLOT (addReferencesSubView()));
|
||||
setupShortcut("document-world-references", references);
|
||||
world->addAction (references);
|
||||
|
||||
QAction *grid = new QAction (tr ("Pathgrid"), this);
|
||||
connect (grid, SIGNAL (triggered()), this, SLOT (addPathgridSubView()));
|
||||
setupShortcut("document-world-pathgrid", grid);
|
||||
world->addAction (grid);
|
||||
|
||||
world->addSeparator(); // items that don't represent single record lists follow here
|
||||
|
||||
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
||||
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
||||
setupShortcut("document-world-regionmap", regionMap);
|
||||
world->addAction (regionMap);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupMechanicsMenu()
|
||||
{
|
||||
QMenu *mechanics = menuBar()->addMenu (tr ("&Mechanics"));
|
||||
QMenu *mechanics = menuBar()->addMenu (tr ("Mechanics"));
|
||||
|
||||
QAction *globals = new QAction (tr ("Globals"), this);
|
||||
connect (globals, SIGNAL (triggered()), this, SLOT (addGlobalsSubView()));
|
||||
setupShortcut("document-mechanics-globals", globals);
|
||||
mechanics->addAction (globals);
|
||||
|
||||
QAction *gmsts = new QAction (tr ("Game settings"), this);
|
||||
QAction *gmsts = new QAction (tr ("Game Settings"), this);
|
||||
connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView()));
|
||||
setupShortcut("document-mechanics-gamesettings", gmsts);
|
||||
mechanics->addAction (gmsts);
|
||||
|
||||
QAction *scripts = new QAction (tr ("Scripts"), this);
|
||||
connect (scripts, SIGNAL (triggered()), this, SLOT (addScriptsSubView()));
|
||||
setupShortcut("document-mechanics-scripts", scripts);
|
||||
mechanics->addAction (scripts);
|
||||
|
||||
QAction *spells = new QAction (tr ("Spells"), this);
|
||||
connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView()));
|
||||
setupShortcut("document-mechanics-spells", spells);
|
||||
mechanics->addAction (spells);
|
||||
|
||||
QAction *enchantments = new QAction (tr ("Enchantments"), this);
|
||||
connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView()));
|
||||
setupShortcut("document-mechanics-enchantments", enchantments);
|
||||
mechanics->addAction (enchantments);
|
||||
|
||||
QAction *effects = new QAction (tr ("Magic Effects"), this);
|
||||
connect (effects, SIGNAL (triggered()), this, SLOT (addMagicEffectsSubView()));
|
||||
setupShortcut("document-mechanics-magiceffects", effects);
|
||||
mechanics->addAction (effects);
|
||||
|
||||
QAction *startScripts = new QAction (tr ("Start Scripts"), this);
|
||||
connect (startScripts, SIGNAL (triggered()), this, SLOT (addStartScriptsSubView()));
|
||||
setupShortcut("document-mechanics-startscripts", startScripts);
|
||||
mechanics->addAction (startScripts);
|
||||
}
|
||||
|
||||
|
@ -201,81 +231,99 @@ void CSVDoc::View::setupCharacterMenu()
|
|||
|
||||
QAction *skills = new QAction (tr ("Skills"), this);
|
||||
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
|
||||
setupShortcut("document-character-skills", skills);
|
||||
characters->addAction (skills);
|
||||
|
||||
QAction *classes = new QAction (tr ("Classes"), this);
|
||||
connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView()));
|
||||
setupShortcut("document-character-classes", classes);
|
||||
characters->addAction (classes);
|
||||
|
||||
QAction *factions = new QAction (tr ("Factions"), this);
|
||||
connect (factions, SIGNAL (triggered()), this, SLOT (addFactionsSubView()));
|
||||
setupShortcut("document-character-factions", factions);
|
||||
characters->addAction (factions);
|
||||
|
||||
QAction *races = new QAction (tr ("Races"), this);
|
||||
connect (races, SIGNAL (triggered()), this, SLOT (addRacesSubView()));
|
||||
setupShortcut("document-character-races", races);
|
||||
characters->addAction (races);
|
||||
|
||||
QAction *birthsigns = new QAction (tr ("Birthsigns"), this);
|
||||
connect (birthsigns, SIGNAL (triggered()), this, SLOT (addBirthsignsSubView()));
|
||||
setupShortcut("document-character-birthsigns", birthsigns);
|
||||
characters->addAction (birthsigns);
|
||||
|
||||
QAction *topics = new QAction (tr ("Topics"), this);
|
||||
connect (topics, SIGNAL (triggered()), this, SLOT (addTopicsSubView()));
|
||||
setupShortcut("document-character-topics", topics);
|
||||
characters->addAction (topics);
|
||||
|
||||
QAction *journals = new QAction (tr ("Journals"), this);
|
||||
connect (journals, SIGNAL (triggered()), this, SLOT (addJournalsSubView()));
|
||||
setupShortcut("document-character-journals", journals);
|
||||
characters->addAction (journals);
|
||||
|
||||
QAction *topicInfos = new QAction (tr ("Topic Infos"), this);
|
||||
connect (topicInfos, SIGNAL (triggered()), this, SLOT (addTopicInfosSubView()));
|
||||
setupShortcut("document-character-topicinfos", topicInfos);
|
||||
characters->addAction (topicInfos);
|
||||
|
||||
QAction *journalInfos = new QAction (tr ("Journal Infos"), this);
|
||||
connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView()));
|
||||
setupShortcut("document-character-journalinfos", journalInfos);
|
||||
characters->addAction (journalInfos);
|
||||
|
||||
QAction *bodyParts = new QAction (tr ("Body Parts"), this);
|
||||
connect (bodyParts, SIGNAL (triggered()), this, SLOT (addBodyPartsSubView()));
|
||||
setupShortcut("document-character-bodyparts", bodyParts);
|
||||
characters->addAction (bodyParts);
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupAssetsMenu()
|
||||
{
|
||||
QMenu *assets = menuBar()->addMenu (tr ("&Assets"));
|
||||
QMenu *assets = menuBar()->addMenu (tr ("Assets"));
|
||||
|
||||
QAction *sounds = new QAction (tr ("Sounds"), this);
|
||||
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView()));
|
||||
setupShortcut("document-assets-sounds", sounds);
|
||||
assets->addAction (sounds);
|
||||
|
||||
QAction *soundGens = new QAction (tr ("Sound Generators"), this);
|
||||
connect (soundGens, SIGNAL (triggered()), this, SLOT (addSoundGensSubView()));
|
||||
setupShortcut("document-assets-soundgens", soundGens);
|
||||
assets->addAction (soundGens);
|
||||
|
||||
assets->addSeparator(); // resources follow here
|
||||
|
||||
QAction *meshes = new QAction (tr ("Meshes"), this);
|
||||
connect (meshes, SIGNAL (triggered()), this, SLOT (addMeshesSubView()));
|
||||
setupShortcut("document-assets-meshes", meshes);
|
||||
assets->addAction (meshes);
|
||||
|
||||
QAction *icons = new QAction (tr ("Icons"), this);
|
||||
connect (icons, SIGNAL (triggered()), this, SLOT (addIconsSubView()));
|
||||
setupShortcut("document-assets-icons", icons);
|
||||
assets->addAction (icons);
|
||||
|
||||
QAction *musics = new QAction (tr ("Music"), this);
|
||||
connect (musics, SIGNAL (triggered()), this, SLOT (addMusicsSubView()));
|
||||
setupShortcut("document-assets-music", musics);
|
||||
assets->addAction (musics);
|
||||
|
||||
QAction *soundsRes = new QAction (tr ("Sound Files"), this);
|
||||
connect (soundsRes, SIGNAL (triggered()), this, SLOT (addSoundsResSubView()));
|
||||
setupShortcut("document-assets-soundres", soundsRes);
|
||||
assets->addAction (soundsRes);
|
||||
|
||||
QAction *textures = new QAction (tr ("Textures"), this);
|
||||
connect (textures, SIGNAL (triggered()), this, SLOT (addTexturesSubView()));
|
||||
setupShortcut("document-assets-textures", textures);
|
||||
assets->addAction (textures);
|
||||
|
||||
QAction *videos = new QAction (tr ("Videos"), this);
|
||||
connect (videos, SIGNAL (triggered()), this, SLOT (addVideosSubView()));
|
||||
setupShortcut("document-assets-videos", videos);
|
||||
assets->addAction (videos);
|
||||
}
|
||||
|
||||
|
@ -299,12 +347,16 @@ void CSVDoc::View::setupDebugMenu()
|
|||
QAction *runDebug = debug->addMenu (mGlobalDebugProfileMenu);
|
||||
runDebug->setText (tr ("Run OpenMW"));
|
||||
|
||||
setupShortcut("document-debug-run", runDebug);
|
||||
|
||||
mStopDebug = new QAction (tr ("Shutdown OpenMW"), this);
|
||||
connect (mStopDebug, SIGNAL (triggered()), this, SLOT (stop()));
|
||||
setupShortcut("document-debug-shutdown", mStopDebug);
|
||||
debug->addAction (mStopDebug);
|
||||
|
||||
QAction *runLog = new QAction (tr ("Run Log"), this);
|
||||
QAction *runLog = new QAction (tr ("Open Run Log"), this);
|
||||
connect (runLog, SIGNAL (triggered()), this, SLOT (addRunLogSubView()));
|
||||
setupShortcut("document-debug-runlog", runLog);
|
||||
debug->addAction (runLog);
|
||||
}
|
||||
|
||||
|
@ -320,6 +372,12 @@ void CSVDoc::View::setupUi()
|
|||
setupDebugMenu();
|
||||
}
|
||||
|
||||
void CSVDoc::View::setupShortcut(const char* name, QAction* action)
|
||||
{
|
||||
CSMPrefs::Shortcut* shortcut = new CSMPrefs::Shortcut(name, this);
|
||||
shortcut->associateAction(action);
|
||||
}
|
||||
|
||||
void CSVDoc::View::updateTitle()
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
|
|
@ -84,6 +84,8 @@ namespace CSVDoc
|
|||
|
||||
void setupUi();
|
||||
|
||||
void setupShortcut(const char* name, QAction* action);
|
||||
|
||||
void updateActions();
|
||||
|
||||
void exitApplication();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../../model/prefs/state.hpp"
|
||||
|
||||
#include "page.hpp"
|
||||
#include "keybindingpage.hpp"
|
||||
|
||||
void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main)
|
||||
{
|
||||
|
@ -52,8 +53,10 @@ void CSVPrefs::Dialogue::buildContentArea (QSplitter *main)
|
|||
CSVPrefs::PageBase *CSVPrefs::Dialogue::makePage (const std::string& key)
|
||||
{
|
||||
// special case page code goes here
|
||||
|
||||
return new Page (CSMPrefs::get()[key], mContent);
|
||||
if (key == "Key Bindings")
|
||||
return new KeyBindingPage(CSMPrefs::get()[key], mContent);
|
||||
else
|
||||
return new Page (CSMPrefs::get()[key], mContent);
|
||||
}
|
||||
|
||||
CSVPrefs::Dialogue::Dialogue()
|
||||
|
|
88
apps/opencs/view/prefs/keybindingpage.cpp
Normal file
88
apps/opencs/view/prefs/keybindingpage.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include "keybindingpage.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QGridLayout>
|
||||
#include <QStackedLayout>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "../../model/prefs/setting.hpp"
|
||||
#include "../../model/prefs/category.hpp"
|
||||
|
||||
namespace CSVPrefs
|
||||
{
|
||||
KeyBindingPage::KeyBindingPage(CSMPrefs::Category& category, QWidget* parent)
|
||||
: PageBase(category, parent)
|
||||
, mStackedLayout(0)
|
||||
, mPageLayout(0)
|
||||
, mPageSelector(0)
|
||||
{
|
||||
// Need one widget for scroll area
|
||||
QWidget* topWidget = new QWidget();
|
||||
QVBoxLayout* topLayout = new QVBoxLayout(topWidget);
|
||||
|
||||
// Allows switching between "pages"
|
||||
QWidget* stackedWidget = new QWidget();
|
||||
mStackedLayout = new QStackedLayout(stackedWidget);
|
||||
|
||||
mPageSelector = new QComboBox();
|
||||
connect(mPageSelector, SIGNAL(currentIndexChanged(int)), mStackedLayout, SLOT(setCurrentIndex(int)));
|
||||
|
||||
topLayout->addWidget(mPageSelector);
|
||||
topLayout->addWidget(stackedWidget);
|
||||
topLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||
|
||||
// Add each option
|
||||
for (CSMPrefs::Category::Iterator iter = category.begin(); iter!=category.end(); ++iter)
|
||||
addSetting (*iter);
|
||||
|
||||
setWidgetResizable(true);
|
||||
setWidget(topWidget);
|
||||
}
|
||||
|
||||
void KeyBindingPage::addSetting(CSMPrefs::Setting *setting)
|
||||
{
|
||||
std::pair<QWidget*, QWidget*> widgets = setting->makeWidgets (this);
|
||||
|
||||
if (widgets.first)
|
||||
{
|
||||
// Label, Option widgets
|
||||
assert(mPageLayout);
|
||||
|
||||
int next = mPageLayout->rowCount();
|
||||
mPageLayout->addWidget(widgets.first, next, 0);
|
||||
mPageLayout->addWidget(widgets.second, next, 1);
|
||||
}
|
||||
else if (widgets.second)
|
||||
{
|
||||
// Wide single widget
|
||||
assert(mPageLayout);
|
||||
|
||||
int next = mPageLayout->rowCount();
|
||||
mPageLayout->addWidget(widgets.second, next, 0, 1, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (setting->getLabel().empty())
|
||||
{
|
||||
// Insert empty space
|
||||
assert(mPageLayout);
|
||||
|
||||
int next = mPageLayout->rowCount();
|
||||
mPageLayout->addWidget(new QWidget(), next, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create new page
|
||||
QWidget* pageWidget = new QWidget();
|
||||
mPageLayout = new QGridLayout(pageWidget);
|
||||
mPageLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||
|
||||
mStackedLayout->addWidget(pageWidget);
|
||||
|
||||
mPageSelector->addItem(QString::fromUtf8(setting->getLabel().c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
apps/opencs/view/prefs/keybindingpage.hpp
Normal file
35
apps/opencs/view/prefs/keybindingpage.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef CSV_PREFS_KEYBINDINGPAGE_H
|
||||
#define CSV_PREFS_KEYBINDINGPAGE_H
|
||||
|
||||
#include "pagebase.hpp"
|
||||
|
||||
class QComboBox;
|
||||
class QGridLayout;
|
||||
class QStackedLayout;
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Setting;
|
||||
}
|
||||
|
||||
namespace CSVPrefs
|
||||
{
|
||||
class KeyBindingPage : public PageBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
KeyBindingPage(CSMPrefs::Category& category, QWidget* parent);
|
||||
|
||||
void addSetting(CSMPrefs::Setting* setting);
|
||||
|
||||
private:
|
||||
|
||||
QStackedLayout* mStackedLayout;
|
||||
QGridLayout* mPageLayout;
|
||||
QComboBox* mPageSelector;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QWidget>
|
||||
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/Camera>
|
||||
|
@ -14,6 +14,10 @@
|
|||
|
||||
#include <osgUtil/LineSegmentIntersector>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "scenewidget.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
|
@ -27,8 +31,9 @@ namespace CSVRender
|
|||
const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0);
|
||||
const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1);
|
||||
|
||||
CameraController::CameraController()
|
||||
: mActive(false)
|
||||
CameraController::CameraController(QObject* parent)
|
||||
: QObject(parent)
|
||||
, mActive(false)
|
||||
, mInverted(false)
|
||||
, mCameraSensitivity(1/650.f)
|
||||
, mSecondaryMoveMult(50)
|
||||
|
@ -73,11 +78,19 @@ namespace CSVRender
|
|||
|
||||
void CameraController::setCamera(osg::Camera* camera)
|
||||
{
|
||||
bool wasActive = mActive;
|
||||
|
||||
mCamera = camera;
|
||||
mActive = (mCamera != NULL);
|
||||
|
||||
if (mActive)
|
||||
onActivate();
|
||||
if (mActive != wasActive)
|
||||
{
|
||||
for (std::vector<CSMPrefs::Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
|
||||
{
|
||||
CSMPrefs::Shortcut* shortcut = *it;
|
||||
shortcut->enable(mActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraController::setCameraSensitivity(double value)
|
||||
|
@ -136,14 +149,23 @@ namespace CSVRender
|
|||
getCamera()->setViewMatrixAsLookAt(eye, center, up);
|
||||
}
|
||||
|
||||
void CameraController::addShortcut(CSMPrefs::Shortcut* shortcut)
|
||||
{
|
||||
mShortcuts.push_back(shortcut);
|
||||
}
|
||||
|
||||
/*
|
||||
Free Camera Controller
|
||||
*/
|
||||
|
||||
FreeCameraController::FreeCameraController()
|
||||
: mLockUpright(false)
|
||||
FreeCameraController::FreeCameraController(QWidget* widget)
|
||||
: CameraController(widget)
|
||||
, mLockUpright(false)
|
||||
, mModified(false)
|
||||
, mNaviPrimary(false)
|
||||
, mNaviSecondary(false)
|
||||
, mFast(false)
|
||||
, mFastAlternate(false)
|
||||
, mLeft(false)
|
||||
, mRight(false)
|
||||
, mForward(false)
|
||||
|
@ -155,6 +177,61 @@ namespace CSVRender
|
|||
, mRotSpeed(osg::PI / 2)
|
||||
, mSpeedMult(8)
|
||||
{
|
||||
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", widget);
|
||||
naviPrimaryShortcut->enable(false);
|
||||
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
||||
|
||||
addShortcut(naviPrimaryShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget);
|
||||
naviSecondaryShortcut->enable(false);
|
||||
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
||||
|
||||
addShortcut(naviSecondaryShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", "scene-speed-modifier",
|
||||
CSMPrefs::Shortcut::SM_Detach, widget);
|
||||
forwardShortcut->enable(false);
|
||||
connect(forwardShortcut, SIGNAL(activated(bool)), this, SLOT(forward(bool)));
|
||||
connect(forwardShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
||||
|
||||
addShortcut(forwardShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", widget);
|
||||
leftShortcut->enable(false);
|
||||
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
||||
|
||||
addShortcut(leftShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* backShortcut = new CSMPrefs::Shortcut("free-backward", widget);
|
||||
backShortcut->enable(false);
|
||||
connect(backShortcut, SIGNAL(activated(bool)), this, SLOT(backward(bool)));
|
||||
|
||||
addShortcut(backShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("free-right", widget);
|
||||
rightShortcut->enable(false);
|
||||
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
||||
|
||||
addShortcut(rightShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("free-roll-left", widget);
|
||||
rollLeftShortcut->enable(false);
|
||||
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
||||
|
||||
addShortcut(rollLeftShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("free-roll-right", widget);
|
||||
rollRightShortcut->enable(false);
|
||||
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
||||
|
||||
addShortcut(rollRightShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", widget);
|
||||
speedModeShortcut->enable(false);
|
||||
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||
|
||||
addShortcut(speedModeShortcut);
|
||||
}
|
||||
|
||||
double FreeCameraController::getLinearSpeed() const
|
||||
|
@ -199,59 +276,18 @@ namespace CSVRender
|
|||
mLockUpright = false;
|
||||
}
|
||||
|
||||
bool FreeCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
|
||||
void FreeCameraController::handleMouseMoveEvent(int x, int y)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
return;
|
||||
|
||||
if (event->key() == Qt::Key_Q)
|
||||
{
|
||||
mRollLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_E)
|
||||
{
|
||||
mRollRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_A)
|
||||
{
|
||||
mLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_D)
|
||||
{
|
||||
mRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_W)
|
||||
{
|
||||
mForward = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_S)
|
||||
{
|
||||
mBackward = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_Shift)
|
||||
{
|
||||
mFast = pressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreeCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
|
||||
if (mode == "p-navi")
|
||||
if (mNaviPrimary)
|
||||
{
|
||||
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
||||
yaw(x * scalar);
|
||||
pitch(y * scalar);
|
||||
}
|
||||
else if (mode == "s-navi")
|
||||
else if (mNaviSecondary)
|
||||
{
|
||||
osg::Vec3d movement;
|
||||
movement += LocalLeft * -x * getSecondaryMovementMultiplier();
|
||||
|
@ -259,16 +295,14 @@ namespace CSVRender
|
|||
|
||||
translate(movement);
|
||||
}
|
||||
else if (mode == "t-navi")
|
||||
{
|
||||
translate(LocalForward * x * (mFast ? getWheelMovementMultiplier() : 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
void FreeCameraController::handleMouseScrollEvent(int x)
|
||||
{
|
||||
if (!isActive())
|
||||
return;
|
||||
|
||||
translate(LocalForward * x * ((mFast ^ mFastAlternate) ? getWheelMovementMultiplier() : 1));
|
||||
}
|
||||
|
||||
void FreeCameraController::update(double dt)
|
||||
|
@ -279,7 +313,7 @@ namespace CSVRender
|
|||
double linDist = mLinSpeed * dt;
|
||||
double rotDist = mRotSpeed * dt;
|
||||
|
||||
if (mFast)
|
||||
if (mFast ^ mFastAlternate)
|
||||
linDist *= mSpeedMult;
|
||||
|
||||
if (mLeft)
|
||||
|
@ -308,17 +342,6 @@ namespace CSVRender
|
|||
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
||||
}
|
||||
|
||||
void FreeCameraController::resetInput()
|
||||
{
|
||||
mFast = false;
|
||||
mLeft = false;
|
||||
mRight = false;
|
||||
mForward = false;
|
||||
mBackward = false;
|
||||
mRollLeft = false;
|
||||
mRollRight = false;
|
||||
}
|
||||
|
||||
void FreeCameraController::yaw(double value)
|
||||
{
|
||||
getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalUp);
|
||||
|
@ -368,13 +391,67 @@ namespace CSVRender
|
|||
getCamera()->setViewMatrixAsLookAt(eye, center, mUp);
|
||||
}
|
||||
|
||||
void FreeCameraController::naviPrimary(bool active)
|
||||
{
|
||||
mNaviPrimary = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::naviSecondary(bool active)
|
||||
{
|
||||
mNaviSecondary = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::forward(bool active)
|
||||
{
|
||||
mForward = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::left(bool active)
|
||||
{
|
||||
mLeft = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::backward(bool active)
|
||||
{
|
||||
mBackward = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::right(bool active)
|
||||
{
|
||||
mRight = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::rollLeft(bool active)
|
||||
{
|
||||
mRollLeft = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::rollRight(bool active)
|
||||
{
|
||||
mRollRight = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::alternateFast(bool active)
|
||||
{
|
||||
mFastAlternate = active;
|
||||
}
|
||||
|
||||
void FreeCameraController::swapSpeedMode()
|
||||
{
|
||||
mFast = !mFast;
|
||||
}
|
||||
|
||||
/*
|
||||
Orbit Camera Controller
|
||||
*/
|
||||
|
||||
OrbitCameraController::OrbitCameraController()
|
||||
: mInitialized(false)
|
||||
OrbitCameraController::OrbitCameraController(QWidget* widget)
|
||||
: CameraController(widget)
|
||||
, mInitialized(false)
|
||||
, mNaviPrimary(false)
|
||||
, mNaviSecondary(false)
|
||||
, mFast(false)
|
||||
, mFastAlternate(false)
|
||||
, mLeft(false)
|
||||
, mRight(false)
|
||||
, mUp(false)
|
||||
|
@ -387,6 +464,61 @@ namespace CSVRender
|
|||
, mOrbitSpeed(osg::PI / 4)
|
||||
, mOrbitSpeedMult(4)
|
||||
{
|
||||
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", widget);
|
||||
naviPrimaryShortcut->enable(false);
|
||||
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
||||
|
||||
addShortcut(naviPrimaryShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget);
|
||||
naviSecondaryShortcut->enable(false);
|
||||
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
||||
|
||||
addShortcut(naviSecondaryShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", "scene-speed-modifier",
|
||||
CSMPrefs::Shortcut::SM_Detach, widget);
|
||||
upShortcut->enable(false);
|
||||
connect(upShortcut, SIGNAL(activated(bool)), this, SLOT(up(bool)));
|
||||
connect(upShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
||||
|
||||
addShortcut(upShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", widget);
|
||||
leftShortcut->enable(false);
|
||||
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
||||
|
||||
addShortcut(leftShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* downShortcut = new CSMPrefs::Shortcut("orbit-down", widget);
|
||||
downShortcut->enable(false);
|
||||
connect(downShortcut, SIGNAL(activated(bool)), this, SLOT(down(bool)));
|
||||
|
||||
addShortcut(downShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("orbit-right", widget);
|
||||
rightShortcut->enable(false);
|
||||
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
||||
|
||||
addShortcut(rightShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("orbit-roll-left", widget);
|
||||
rollLeftShortcut->enable(false);
|
||||
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
||||
|
||||
addShortcut(rollLeftShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("orbit-roll-right", widget);
|
||||
rollRightShortcut->enable(false);
|
||||
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
||||
|
||||
addShortcut(rollRightShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", widget);
|
||||
speedModeShortcut->enable(false);
|
||||
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||
|
||||
addShortcut(speedModeShortcut);
|
||||
}
|
||||
|
||||
osg::Vec3d OrbitCameraController::getCenter() const
|
||||
|
@ -437,65 +569,21 @@ namespace CSVRender
|
|||
mPickingMask = value;
|
||||
}
|
||||
|
||||
bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
|
||||
void OrbitCameraController::handleMouseMoveEvent(int x, int y)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
return;
|
||||
|
||||
if (!mInitialized)
|
||||
initialize();
|
||||
|
||||
if (event->key() == Qt::Key_Q)
|
||||
{
|
||||
mRollLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_E)
|
||||
{
|
||||
mRollRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_A)
|
||||
{
|
||||
mLeft = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_D)
|
||||
{
|
||||
mRight = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_W)
|
||||
{
|
||||
mUp = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_S)
|
||||
{
|
||||
mDown = pressed;
|
||||
}
|
||||
else if (event->key() == Qt::Key_Shift)
|
||||
{
|
||||
mFast = pressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OrbitCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
|
||||
{
|
||||
if (!isActive())
|
||||
return false;
|
||||
|
||||
if (!mInitialized)
|
||||
initialize();
|
||||
|
||||
if (mode == "p-navi")
|
||||
if (mNaviPrimary)
|
||||
{
|
||||
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
||||
rotateHorizontal(x * scalar);
|
||||
rotateVertical(-y * scalar);
|
||||
}
|
||||
else if (mode == "s-navi")
|
||||
else if (mNaviSecondary)
|
||||
{
|
||||
osg::Vec3d movement;
|
||||
movement += LocalLeft * x * getSecondaryMovementMultiplier();
|
||||
|
@ -503,16 +591,14 @@ namespace CSVRender
|
|||
|
||||
translate(movement);
|
||||
}
|
||||
else if (mode == "t-navi")
|
||||
{
|
||||
zoom(-x * (mFast ? getWheelMovementMultiplier() : 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
void OrbitCameraController::handleMouseScrollEvent(int x)
|
||||
{
|
||||
if (!isActive())
|
||||
return;
|
||||
|
||||
zoom(-x * ((mFast ^ mFastAlternate) ? getWheelMovementMultiplier() : 1));
|
||||
}
|
||||
|
||||
void OrbitCameraController::update(double dt)
|
||||
|
@ -525,7 +611,7 @@ namespace CSVRender
|
|||
|
||||
double rotDist = mOrbitSpeed * dt;
|
||||
|
||||
if (mFast)
|
||||
if (mFast ^ mFastAlternate)
|
||||
rotDist *= mOrbitSpeedMult;
|
||||
|
||||
if (mLeft)
|
||||
|
@ -546,17 +632,6 @@ namespace CSVRender
|
|||
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
||||
}
|
||||
|
||||
void OrbitCameraController::resetInput()
|
||||
{
|
||||
mFast = false;
|
||||
mLeft = false;
|
||||
mRight =false;
|
||||
mUp = false;
|
||||
mDown = false;
|
||||
mRollLeft = false;
|
||||
mRollRight = false;
|
||||
}
|
||||
|
||||
void OrbitCameraController::onActivate()
|
||||
{
|
||||
mInitialized = false;
|
||||
|
@ -647,4 +722,55 @@ namespace CSVRender
|
|||
|
||||
getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up);
|
||||
}
|
||||
|
||||
void OrbitCameraController::naviPrimary(bool active)
|
||||
{
|
||||
mNaviPrimary = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::naviSecondary(bool active)
|
||||
{
|
||||
mNaviSecondary = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::up(bool active)
|
||||
{
|
||||
mUp = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::left(bool active)
|
||||
{
|
||||
mLeft = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::down(bool active)
|
||||
{
|
||||
mDown = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::right(bool active)
|
||||
{
|
||||
mRight = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::rollLeft(bool active)
|
||||
{
|
||||
if (isActive())
|
||||
mRollLeft = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::rollRight(bool active)
|
||||
{
|
||||
mRollRight = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::alternateFast(bool active)
|
||||
{
|
||||
mFastAlternate = active;
|
||||
}
|
||||
|
||||
void OrbitCameraController::swapSpeedMode()
|
||||
{
|
||||
mFast = !mFast;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,22 +2,32 @@
|
|||
#define OPENCS_VIEW_CAMERACONTROLLER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Vec3d>
|
||||
|
||||
class QKeyEvent;
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Camera;
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Shortcut;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class CameraController
|
||||
class SceneWidget;
|
||||
|
||||
class CameraController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
static const osg::Vec3d WorldUp;
|
||||
|
@ -26,7 +36,7 @@ namespace CSVRender
|
|||
static const osg::Vec3d LocalLeft;
|
||||
static const osg::Vec3d LocalForward;
|
||||
|
||||
CameraController();
|
||||
CameraController(QObject* parent);
|
||||
virtual ~CameraController();
|
||||
|
||||
bool isActive() const;
|
||||
|
@ -46,17 +56,17 @@ namespace CSVRender
|
|||
// moves the camera to an intelligent position
|
||||
void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up);
|
||||
|
||||
virtual bool handleKeyEvent(QKeyEvent* event, bool pressed) = 0;
|
||||
virtual bool handleMouseMoveEvent(std::string mode, int x, int y) = 0;
|
||||
virtual void handleMouseMoveEvent(int x, int y) = 0;
|
||||
virtual void handleMouseScrollEvent(int x) = 0;
|
||||
|
||||
virtual void update(double dt) = 0;
|
||||
|
||||
virtual void resetInput() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onActivate(){}
|
||||
|
||||
void addShortcut(CSMPrefs::Shortcut* shortcut);
|
||||
|
||||
private:
|
||||
|
||||
bool mActive, mInverted;
|
||||
|
@ -65,13 +75,17 @@ namespace CSVRender
|
|||
double mWheelMoveMult;
|
||||
|
||||
osg::Camera* mCamera;
|
||||
|
||||
std::vector<CSMPrefs::Shortcut*> mShortcuts;
|
||||
};
|
||||
|
||||
class FreeCameraController : public CameraController
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
FreeCameraController();
|
||||
FreeCameraController(QWidget* parent);
|
||||
|
||||
double getLinearSpeed() const;
|
||||
double getRotationalSpeed() const;
|
||||
|
@ -84,13 +98,11 @@ namespace CSVRender
|
|||
void fixUpAxis(const osg::Vec3d& up);
|
||||
void unfixUpAxis();
|
||||
|
||||
bool handleKeyEvent(QKeyEvent* event, bool pressed);
|
||||
bool handleMouseMoveEvent(std::string mode, int x, int y);
|
||||
void handleMouseMoveEvent(int x, int y);
|
||||
void handleMouseScrollEvent(int x);
|
||||
|
||||
void update(double dt);
|
||||
|
||||
void resetInput();
|
||||
|
||||
private:
|
||||
|
||||
void yaw(double value);
|
||||
|
@ -101,19 +113,36 @@ namespace CSVRender
|
|||
void stabilize();
|
||||
|
||||
bool mLockUpright, mModified;
|
||||
bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
|
||||
bool mNaviPrimary, mNaviSecondary;
|
||||
bool mFast, mFastAlternate;
|
||||
bool mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
|
||||
osg::Vec3d mUp;
|
||||
|
||||
double mLinSpeed;
|
||||
double mRotSpeed;
|
||||
double mSpeedMult;
|
||||
|
||||
private slots:
|
||||
|
||||
void naviPrimary(bool active);
|
||||
void naviSecondary(bool active);
|
||||
void forward(bool active);
|
||||
void left(bool active);
|
||||
void backward(bool active);
|
||||
void right(bool active);
|
||||
void rollLeft(bool active);
|
||||
void rollRight(bool active);
|
||||
void alternateFast(bool active);
|
||||
void swapSpeedMode();
|
||||
};
|
||||
|
||||
class OrbitCameraController : public CameraController
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
OrbitCameraController();
|
||||
OrbitCameraController(QWidget* parent);
|
||||
|
||||
osg::Vec3d getCenter() const;
|
||||
double getOrbitSpeed() const;
|
||||
|
@ -125,13 +154,11 @@ namespace CSVRender
|
|||
void setOrbitSpeedMultiplier(double value);
|
||||
void setPickingMask(unsigned int value);
|
||||
|
||||
bool handleKeyEvent(QKeyEvent* event, bool pressed);
|
||||
bool handleMouseMoveEvent(std::string mode, int x, int y);
|
||||
void handleMouseMoveEvent(int x, int y);
|
||||
void handleMouseScrollEvent(int x);
|
||||
|
||||
void update(double dt);
|
||||
|
||||
void resetInput();
|
||||
|
||||
private:
|
||||
|
||||
void onActivate();
|
||||
|
@ -145,13 +172,28 @@ namespace CSVRender
|
|||
void zoom(double value);
|
||||
|
||||
bool mInitialized;
|
||||
bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
|
||||
bool mNaviPrimary, mNaviSecondary;
|
||||
bool mFast, mFastAlternate;
|
||||
bool mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
|
||||
unsigned int mPickingMask;
|
||||
osg::Vec3d mCenter;
|
||||
double mDistance;
|
||||
|
||||
double mOrbitSpeed;
|
||||
double mOrbitSpeedMult;
|
||||
|
||||
private slots:
|
||||
|
||||
void naviPrimary(bool active);
|
||||
void naviSecondary(bool active);
|
||||
void up(bool active);
|
||||
void left(bool active);
|
||||
void down(bool active);
|
||||
void right(bool active);
|
||||
void rollLeft(bool active);
|
||||
void rollRight(bool active);
|
||||
void alternateFast(bool active);
|
||||
void swapSpeedMode();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#include <osg/Geometry>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcutmanager.hpp"
|
||||
|
||||
#include "mask.hpp"
|
||||
|
||||
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
|
||||
|
@ -35,14 +38,19 @@ QString CSVRender::CellArrowTag::getToolTip (bool hideBasics) const
|
|||
text +=
|
||||
"<p>"
|
||||
"Modify which cells are shown"
|
||||
"<ul><li>Primary-Edit: Add cell in given direction</li>"
|
||||
"<li>Secondary-Edit: Add cell and remove old cell</li>"
|
||||
"<li>Shift Primary-Edit: Add cells in given direction</li>"
|
||||
"<li>Shift Secondary-Edit: Add cells and remove old cells</li>"
|
||||
"<ul><li>{scene-edit-primary}: Add cell in given direction</li>"
|
||||
"<li>{scene-edit-secondary}: Add cell and remove old cell</li>"
|
||||
"<li>{scene-select-primary}: Add cells in given direction</li>"
|
||||
"<li>{scene-select-secondary}: Add cells and remove old cells</li>"
|
||||
"<li>{scene-load-cam-cell}: Load cell where camera is located</li>"
|
||||
"<li>{scene-load-cam-eastcell}: Load cell to east</li>"
|
||||
"<li>{scene-load-cam-northcell}: Load cell to north</li>"
|
||||
"<li>{scene-load-cam-westcell}: Load cell to west</li>"
|
||||
"<li>{scene-load-cam-southcell}: Load cell to south</li>"
|
||||
"</ul>";
|
||||
}
|
||||
|
||||
return text;
|
||||
return CSMPrefs::State::get().getShortcutManager().processToolTip(text);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,14 +42,14 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
|
|||
mSubMode->addButton (new InstanceMoveMode (this), "move");
|
||||
mSubMode->addButton (":placeholder", "rotate",
|
||||
"Rotate selected instances"
|
||||
"<ul><li>Use primary edit to rotate instances freely</li>"
|
||||
"<li>Use secondary edit to rotate instances within the grid</li>"
|
||||
"<ul><li>Use {scene-edit-primary} to rotate instances freely</li>"
|
||||
"<li>Use {scene-edit-secondary} to rotate instances within the grid</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
mSubMode->addButton (":placeholder", "scale",
|
||||
"Scale selected instances"
|
||||
"<ul><li>Use primary edit to scale instances freely</li>"
|
||||
"<li>Use secondary edit to scale instances along the grid</li>"
|
||||
"<ul><li>Use {scene-edit-primary} to scale instances freely</li>"
|
||||
"<li>Use {scene-edit-secondary} to scale instances along the grid</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent)
|
||||
: ModeButton (QIcon (QPixmap (":placeholder")),
|
||||
"Move selected instances"
|
||||
"<ul><li>Use primary edit to move instances around freely</li>"
|
||||
"<li>Use secondary edit to move instances around within the grid</li>"
|
||||
"<ul><li>Use {scene-edit-primary} to move instances around freely</li>"
|
||||
"<li>Use {scene-edit-secondary} to move instances around within the grid</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Grid move not implemented yet</font color>",
|
||||
parent)
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include <QMenu>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
|
@ -11,13 +14,29 @@ namespace CSVRender
|
|||
: ModeButton(icon, tooltip, parent)
|
||||
, mWorldspaceWidget(worldspaceWidget)
|
||||
, mCenterOnSelection(0)
|
||||
{
|
||||
mCenterShortcut.reset(new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget));
|
||||
mCenterShortcut->enable(false);
|
||||
connect(mCenterShortcut.get(), SIGNAL(activated()), this, SLOT(centerSelection()));
|
||||
}
|
||||
|
||||
OrbitCameraMode::~OrbitCameraMode()
|
||||
{
|
||||
}
|
||||
|
||||
void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar)
|
||||
{
|
||||
mCenterOnSelection = new QAction("Center on selected object", this);
|
||||
mCenterShortcut->associateAction(mCenterOnSelection);
|
||||
connect(mCenterOnSelection, SIGNAL(triggered()), this, SLOT(centerSelection()));
|
||||
|
||||
mCenterShortcut->enable(true);
|
||||
}
|
||||
|
||||
void OrbitCameraMode::deactivate(CSVWidget::SceneToolbar* toolbar)
|
||||
{
|
||||
mCenterShortcut->associateAction(0);
|
||||
mCenterShortcut->enable(false);
|
||||
}
|
||||
|
||||
bool OrbitCameraMode::createContextMenu(QMenu* menu)
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
#ifndef CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||
#define CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../widget/modebutton.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Shortcut;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class WorldspaceWidget;
|
||||
|
@ -15,14 +22,17 @@ namespace CSVRender
|
|||
|
||||
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "",
|
||||
QWidget* parent = 0);
|
||||
~OrbitCameraMode();
|
||||
|
||||
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
||||
virtual void deactivate(CSVWidget::SceneToolbar* toolbar);
|
||||
virtual bool createContextMenu(QMenu* menu);
|
||||
|
||||
private:
|
||||
|
||||
WorldspaceWidget* mWorldspaceWidget;
|
||||
QAction* mCenterOnSelection;
|
||||
std::auto_ptr<CSMPrefs::Shortcut> mCenterShortcut;
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
|
@ -142,75 +144,71 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
|
|||
"terrain-move");
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
|
||||
bool shift)
|
||||
void CSVRender::PagedWorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type)
|
||||
{
|
||||
if (hit.tag && hit.tag->getMask()==Mask_CellArrow)
|
||||
{
|
||||
if (button=="p-edit" || button=="s-edit")
|
||||
if (CellArrowTag *cellArrowTag = dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
|
||||
{
|
||||
if (CellArrowTag *cellArrowTag =
|
||||
dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
|
||||
CellArrow *arrow = cellArrowTag->getCellArrow();
|
||||
|
||||
CSMWorld::CellCoordinates coordinates = arrow->getCoordinates();
|
||||
|
||||
CellArrow::Direction direction = arrow->getDirection();
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
CellArrow *arrow = cellArrowTag->getCellArrow();
|
||||
case CellArrow::Direction_North: y = 1; break;
|
||||
case CellArrow::Direction_West: x = -1; break;
|
||||
case CellArrow::Direction_South: y = -1; break;
|
||||
case CellArrow::Direction_East: x = 1; break;
|
||||
}
|
||||
|
||||
CSMWorld::CellCoordinates coordinates = arrow->getCoordinates();
|
||||
bool modified = false;
|
||||
|
||||
CellArrow::Direction direction = arrow->getDirection();
|
||||
if (type == InteractionType_PrimarySelect)
|
||||
{
|
||||
addCellSelection (x, y);
|
||||
modified = true;
|
||||
}
|
||||
else if (type == InteractionType_SecondarySelect)
|
||||
{
|
||||
moveCellSelection (x, y);
|
||||
modified = true;
|
||||
}
|
||||
else // Primary/SecondaryEdit
|
||||
{
|
||||
CSMWorld::CellCoordinates newCoordinates = coordinates.move (x, y);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
switch (direction)
|
||||
if (mCells.find (newCoordinates)==mCells.end())
|
||||
{
|
||||
case CellArrow::Direction_North: y = 1; break;
|
||||
case CellArrow::Direction_West: x = -1; break;
|
||||
case CellArrow::Direction_South: y = -1; break;
|
||||
case CellArrow::Direction_East: x = 1; break;
|
||||
}
|
||||
|
||||
bool modified = false;
|
||||
|
||||
if (shift)
|
||||
{
|
||||
if (button=="p-edit")
|
||||
addCellSelection (x, y);
|
||||
else
|
||||
moveCellSelection (x, y);
|
||||
|
||||
addCellToScene (newCoordinates);
|
||||
mSelection.add (newCoordinates);
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CSMWorld::CellCoordinates newCoordinates = coordinates.move (x, y);
|
||||
|
||||
if (mCells.find (newCoordinates)==mCells.end())
|
||||
if (type == InteractionType_SecondaryEdit)
|
||||
{
|
||||
if (mCells.find (coordinates)!=mCells.end())
|
||||
{
|
||||
addCellToScene (newCoordinates);
|
||||
mSelection.add (newCoordinates);
|
||||
removeCellFromScene (coordinates);
|
||||
mSelection.remove (coordinates);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (button=="s-edit")
|
||||
{
|
||||
if (mCells.find (coordinates)!=mCells.end())
|
||||
{
|
||||
removeCellFromScene (coordinates);
|
||||
mSelection.remove (coordinates);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modified)
|
||||
adjustCells();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (modified)
|
||||
adjustCells();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WorldspaceWidget::handleMouseClick (hit, button, shift);
|
||||
WorldspaceWidget::handleInteractionPress (hit, type);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
|
@ -437,6 +435,27 @@ void CSVRender::PagedWorldspaceWidget::moveCellSelection (int x, int y)
|
|||
mSelection = newSelection;
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::addCellToSceneFromCamera (int offsetX, int offsetY)
|
||||
{
|
||||
const int CellSize = 8192;
|
||||
|
||||
osg::Vec3f eye, center, up;
|
||||
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||
|
||||
int cellX = (int)std::floor(center.x() / CellSize) + offsetX;
|
||||
int cellY = (int)std::floor(center.y() / CellSize) + offsetY;
|
||||
|
||||
CSMWorld::CellCoordinates cellCoordinates(cellX, cellY);
|
||||
|
||||
if (!mSelection.has(cellCoordinates))
|
||||
{
|
||||
addCellToScene(cellCoordinates);
|
||||
mSelection.add(cellCoordinates);
|
||||
|
||||
adjustCells();
|
||||
}
|
||||
}
|
||||
|
||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
||||
: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"),
|
||||
mControlElements(NULL), mDisplayCellCoord(true)
|
||||
|
@ -450,6 +469,22 @@ CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc
|
|||
this, SLOT (cellRemoved (const QModelIndex&, int, int)));
|
||||
connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||
this, SLOT (cellAdded (const QModelIndex&, int, int)));
|
||||
|
||||
// Shortcuts
|
||||
CSMPrefs::Shortcut* loadCameraCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-cell", this);
|
||||
connect(loadCameraCellShortcut, SIGNAL(activated()), this, SLOT(loadCameraCell()));
|
||||
|
||||
CSMPrefs::Shortcut* loadCameraEastCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-eastcell", this);
|
||||
connect(loadCameraEastCellShortcut, SIGNAL(activated()), this, SLOT(loadEastCell()));
|
||||
|
||||
CSMPrefs::Shortcut* loadCameraNorthCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-northcell", this);
|
||||
connect(loadCameraNorthCellShortcut, SIGNAL(activated()), this, SLOT(loadNorthCell()));
|
||||
|
||||
CSMPrefs::Shortcut* loadCameraWestCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-westcell", this);
|
||||
connect(loadCameraWestCellShortcut, SIGNAL(activated()), this, SLOT(loadWestCell()));
|
||||
|
||||
CSMPrefs::Shortcut* loadCameraSouthCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-southcell", this);
|
||||
connect(loadCameraSouthCellShortcut, SIGNAL(activated()), this, SLOT(loadSouthCell()));
|
||||
}
|
||||
|
||||
CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
|
||||
|
@ -722,3 +757,28 @@ void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int
|
|||
if (adjustCells())
|
||||
flagAsModified();
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::loadCameraCell()
|
||||
{
|
||||
addCellToSceneFromCamera(0, 0);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::loadEastCell()
|
||||
{
|
||||
addCellToSceneFromCamera(1, 0);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::loadNorthCell()
|
||||
{
|
||||
addCellToSceneFromCamera(0, 1);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::loadWestCell()
|
||||
{
|
||||
addCellToSceneFromCamera(-1, 0);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::loadSouthCell()
|
||||
{
|
||||
addCellToSceneFromCamera(0, -1);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ namespace CSVRender
|
|||
/// \note Does not update the view or any cell marker
|
||||
void moveCellSelection (int x, int y);
|
||||
|
||||
void addCellToSceneFromCamera (int offsetX, int offsetY);
|
||||
|
||||
public:
|
||||
|
||||
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
||||
|
@ -138,7 +140,7 @@ namespace CSVRender
|
|||
|
||||
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
||||
|
||||
virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift);
|
||||
virtual void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type);
|
||||
|
||||
signals:
|
||||
|
||||
|
@ -152,6 +154,16 @@ namespace CSVRender
|
|||
|
||||
virtual void cellAdded (const QModelIndex& index, int start, int end);
|
||||
|
||||
void loadCameraCell();
|
||||
|
||||
void loadEastCell();
|
||||
|
||||
void loadNorthCell();
|
||||
|
||||
void loadWestCell();
|
||||
|
||||
void loadSouthCell();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@ namespace CSVRender
|
|||
{
|
||||
return QString(
|
||||
"Pathgrid editing"
|
||||
"<ul><li>Primary edit: Add node to scene</li>"
|
||||
"<li>Secondary edit: Connect selected nodes to node</li>"
|
||||
"<li>Primary drag: Move selected nodes</li>"
|
||||
"<li>Secondary drag: Connect one node to another</li>"
|
||||
"<ul><li>Press {scene-edit-primary} to add a node to the cursor location</li>"
|
||||
"<li>Press {scene-edit-secondary} to connect the selected nodes to the node beneath the cursor</li>"
|
||||
"<li>Press {scene-edit-primary} and drag to move selected nodes</li>"
|
||||
"<li>Press {scene-edit-secondary} and drag to connect one node to another</li>"
|
||||
"</ul><p>Note: Only a single cell's pathgrid may be edited at a time");
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,16 @@ namespace CSVRender
|
|||
toolbar->addTool(mSelectionMode);
|
||||
}
|
||||
|
||||
void PathgridMode::deactivate(CSVWidget::SceneToolbar* toolbar)
|
||||
{
|
||||
if (mSelectionMode)
|
||||
{
|
||||
toolbar->removeTool (mSelectionMode);
|
||||
delete mSelectionMode;
|
||||
mSelectionMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hitResult)
|
||||
{
|
||||
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue() &&
|
||||
|
|
|
@ -19,6 +19,8 @@ namespace CSVRender
|
|||
|
||||
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
||||
|
||||
virtual void deactivate(CSVWidget::SceneToolbar* toolbar);
|
||||
|
||||
virtual void primaryEditPressed(const WorldspaceHitResult& hit);
|
||||
|
||||
virtual void secondaryEditPressed(const WorldspaceHitResult& hit);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <QEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QTimer>
|
||||
#include <QShortcut>
|
||||
#include <QLayout>
|
||||
|
||||
#include <extern/osgQt/GraphicsWindowQt>
|
||||
|
@ -19,6 +18,8 @@
|
|||
#include "../widget/scenetoolmode.hpp"
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||
|
||||
#include "lighting.hpp"
|
||||
#include "mask.hpp"
|
||||
|
@ -75,7 +76,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
|
|||
|
||||
mView->setSceneData(mRootNode);
|
||||
|
||||
// Press S to reveal profiling stats
|
||||
// Add ability to signal osg to show its statistics for debugging purposes
|
||||
mView->addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
|
||||
|
@ -105,6 +106,15 @@ osg::Camera *RenderWidget::getCamera()
|
|||
return mView->getCamera();
|
||||
}
|
||||
|
||||
void RenderWidget::toggleRenderStats()
|
||||
{
|
||||
osgViewer::GraphicsWindow* window =
|
||||
static_cast<osgViewer::GraphicsWindow*>(mView->getCamera()->getGraphicsContext());
|
||||
|
||||
window->getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_S);
|
||||
window->getEventQueue()->keyRelease(osgGA::GUIEventAdapter::KEY_S);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
|
||||
|
@ -158,13 +168,13 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
|||
, mHasDefaultAmbient(false)
|
||||
, mPrevMouseX(0)
|
||||
, mPrevMouseY(0)
|
||||
, mFreeCamControl(new FreeCameraController())
|
||||
, mOrbitCamControl(new OrbitCameraController())
|
||||
, mCurrentCamControl(mFreeCamControl.get())
|
||||
, mCamPositionSet(false)
|
||||
{
|
||||
mFreeCamControl = new FreeCameraController(this);
|
||||
mOrbitCamControl = new OrbitCameraController(this);
|
||||
mCurrentCamControl = mFreeCamControl;
|
||||
|
||||
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
|
||||
selectNavigationMode("free");
|
||||
|
||||
// we handle lighting manually
|
||||
mView->setLightingMode(osgViewer::View::NO_LIGHT);
|
||||
|
@ -175,11 +185,7 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
|||
|
||||
// Recieve mouse move event even if mouse button is not pressed
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
/// \todo make shortcut configurable
|
||||
QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
|
||||
connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest()));
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
|
||||
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
|
||||
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
|
||||
|
@ -192,6 +198,13 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
|||
}
|
||||
|
||||
connect (&CompositeViewer::get(), SIGNAL (simulationUpdated(double)), this, SLOT (update(double)));
|
||||
|
||||
// Shortcuts
|
||||
CSMPrefs::Shortcut* focusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
|
||||
connect(focusToolbarShortcut, SIGNAL(activated()), this, SIGNAL(focusToolbarRequest()));
|
||||
|
||||
CSMPrefs::Shortcut* renderStatsShortcut = new CSMPrefs::Shortcut("scene-render-stats", this);
|
||||
connect(renderStatsShortcut, SIGNAL(activated()), this, SLOT(toggleRenderStats()));
|
||||
}
|
||||
|
||||
SceneWidget::~SceneWidget()
|
||||
|
@ -271,45 +284,17 @@ void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour)
|
|||
setAmbient(mLighting->getAmbientColour(&mDefaultAmbient));
|
||||
}
|
||||
|
||||
void SceneWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
mMouseMode = mapButton(event);
|
||||
|
||||
mPrevMouseX = event->x();
|
||||
mPrevMouseY = event->y();
|
||||
}
|
||||
|
||||
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
mMouseMode = "";
|
||||
}
|
||||
|
||||
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleMouseMoveEvent(mMouseMode, event->x() - mPrevMouseX, event->y() - mPrevMouseY);
|
||||
mCurrentCamControl->handleMouseMoveEvent(event->x() - mPrevMouseX, event->y() - mPrevMouseY);
|
||||
|
||||
mPrevMouseX = event->x();
|
||||
mPrevMouseY = event->y();
|
||||
}
|
||||
|
||||
void SceneWidget::focusOutEvent (QFocusEvent *event)
|
||||
{
|
||||
mCurrentCamControl->resetInput();
|
||||
}
|
||||
|
||||
void SceneWidget::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0);
|
||||
}
|
||||
|
||||
void SceneWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleKeyEvent(event, true);
|
||||
}
|
||||
|
||||
void SceneWidget::keyReleaseEvent (QKeyEvent *event)
|
||||
{
|
||||
mCurrentCamControl->handleKeyEvent(event, false);
|
||||
mCurrentCamControl->handleMouseScrollEvent(event->delta());
|
||||
}
|
||||
|
||||
void SceneWidget::update(double dt)
|
||||
|
@ -373,10 +358,6 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting)
|
|||
{
|
||||
mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble());
|
||||
}
|
||||
else
|
||||
{
|
||||
storeMappingSetting(setting);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::selectNavigationMode (const std::string& mode)
|
||||
|
@ -384,73 +365,23 @@ void SceneWidget::selectNavigationMode (const std::string& mode)
|
|||
if (mode=="1st")
|
||||
{
|
||||
mCurrentCamControl->setCamera(NULL);
|
||||
mCurrentCamControl = mFreeCamControl.get();
|
||||
mCurrentCamControl->setCamera(getCamera());
|
||||
mCurrentCamControl = mFreeCamControl;
|
||||
mFreeCamControl->setCamera(getCamera());
|
||||
mFreeCamControl->fixUpAxis(CameraController::WorldUp);
|
||||
}
|
||||
else if (mode=="free")
|
||||
{
|
||||
mCurrentCamControl->setCamera(NULL);
|
||||
mCurrentCamControl = mFreeCamControl.get();
|
||||
mCurrentCamControl->setCamera(getCamera());
|
||||
mCurrentCamControl = mFreeCamControl;
|
||||
mFreeCamControl->setCamera(getCamera());
|
||||
mFreeCamControl->unfixUpAxis();
|
||||
}
|
||||
else if (mode=="orbit")
|
||||
{
|
||||
mCurrentCamControl->setCamera(NULL);
|
||||
mCurrentCamControl = mOrbitCamControl.get();
|
||||
mCurrentCamControl->setCamera(getCamera());
|
||||
mCurrentCamControl = mOrbitCamControl;
|
||||
mOrbitCamControl->setCamera(getCamera());
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
|
||||
{
|
||||
if (setting->getParent()->getKey()!="3D Scene Input")
|
||||
return false;
|
||||
|
||||
static const char * const sMappingSettings[] =
|
||||
{
|
||||
"p-navi", "s-navi",
|
||||
0
|
||||
};
|
||||
|
||||
for (int i=0; sMappingSettings[i]; ++i)
|
||||
if (setting->getKey()==sMappingSettings[i])
|
||||
{
|
||||
QString value = QString::fromUtf8 (setting->toString().c_str());
|
||||
|
||||
Qt::MouseButton button = Qt::NoButton;
|
||||
|
||||
if (value.endsWith ("Left Mouse-Button"))
|
||||
button = Qt::LeftButton;
|
||||
else if (value.endsWith ("Right Mouse-Button"))
|
||||
button = Qt::RightButton;
|
||||
else if (value.endsWith ("Middle Mouse-Button"))
|
||||
button = Qt::MiddleButton;
|
||||
else
|
||||
return false;
|
||||
|
||||
bool ctrl = value.startsWith ("Ctrl-");
|
||||
|
||||
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string SceneWidget::mapButton (QMouseEvent *event)
|
||||
{
|
||||
std::pair<Qt::MouseButton, bool> phyiscal (
|
||||
event->button(), event->modifiers() & Qt::ControlModifier);
|
||||
|
||||
std::map<std::pair<Qt::MouseButton, bool>, std::string>::const_iterator iter =
|
||||
mButtonMapping.find (phyiscal);
|
||||
|
||||
if (iter!=mButtonMapping.end())
|
||||
return iter->second;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
|
||||
#include <osgViewer/View>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "lightingday.hpp"
|
||||
#include "lightingnight.hpp"
|
||||
#include "lightingbright.hpp"
|
||||
|
||||
#include <osgViewer/View>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
|
@ -53,6 +54,7 @@ namespace CSVRender
|
|||
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~RenderWidget();
|
||||
|
||||
/// Initiates a request to redraw the view
|
||||
void flagAsModified();
|
||||
|
||||
void setVisibilityMask(int mask);
|
||||
|
@ -62,13 +64,16 @@ namespace CSVRender
|
|||
protected:
|
||||
|
||||
osg::ref_ptr<osgViewer::View> mView;
|
||||
|
||||
osg::Group* mRootNode;
|
||||
osg::ref_ptr<osg::Group> mRootNode;
|
||||
|
||||
QTimer mTimer;
|
||||
|
||||
protected slots:
|
||||
|
||||
void toggleRenderStats();
|
||||
};
|
||||
|
||||
// Extension of RenderWidget to support lighting mode selection & toolbar
|
||||
/// Extension of RenderWidget to support lighting mode selection & toolbar
|
||||
class SceneWidget : public RenderWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -90,18 +95,8 @@ namespace CSVRender
|
|||
|
||||
void setAmbient(const osg::Vec4f& ambient);
|
||||
|
||||
virtual void mousePressEvent (QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||
virtual void wheelEvent (QWheelEvent *event);
|
||||
virtual void keyPressEvent (QKeyEvent *event);
|
||||
virtual void keyReleaseEvent (QKeyEvent *event);
|
||||
virtual void focusOutEvent (QFocusEvent *event);
|
||||
|
||||
/// \return Is \a key a button mapping setting? (ignored otherwise)
|
||||
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
|
||||
|
||||
std::string mapButton (QMouseEvent *event);
|
||||
|
||||
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
|
||||
|
||||
|
@ -114,12 +109,10 @@ namespace CSVRender
|
|||
LightingBright mLightingBright;
|
||||
|
||||
int mPrevMouseX, mPrevMouseY;
|
||||
std::string mMouseMode;
|
||||
std::auto_ptr<FreeCameraController> mFreeCamControl;
|
||||
std::auto_ptr<OrbitCameraController> mOrbitCamControl;
|
||||
CameraController* mCurrentCamControl;
|
||||
|
||||
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
|
||||
FreeCameraController* mFreeCamControl;
|
||||
OrbitCameraController* mOrbitCamControl;
|
||||
CameraController* mCurrentCamControl;
|
||||
|
||||
private:
|
||||
bool mCamPositionSet;
|
||||
|
|
|
@ -15,22 +15,28 @@ namespace CSVRender
|
|||
{
|
||||
addButton(":placeholder", "cube-centre",
|
||||
"Centred cube"
|
||||
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection cube outwards</li>"
|
||||
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||
"(invert selection state) from the centre of the selection cube outwards</li>"
|
||||
"<li>The selection cube is aligned to the word space axis</li>"
|
||||
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
|
||||
"<li>If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not "
|
||||
"starting on an instance will have the same effect</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
addButton(":placeholder", "cube-corner",
|
||||
"Cube corner to corner"
|
||||
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from one corner of the selection cube to the opposite corner</li>"
|
||||
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||
"(invert selection state) from one corner of the selection cube to the opposite corner</li>"
|
||||
"<li>The selection cube is aligned to the word space axis</li>"
|
||||
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
|
||||
"<li>If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not "
|
||||
"starting on an instance will have the same effect</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
addButton(":placeholder", "sphere",
|
||||
"Centred sphere"
|
||||
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection sphere outwards</li>"
|
||||
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
|
||||
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||
"(invert selection state) from the centre of the selection sphere outwards</li>"
|
||||
"<li>If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not "
|
||||
"starting on an instance will have the same effect</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
|
||||
#include "../render/orbitcameramode.hpp"
|
||||
|
@ -31,10 +33,24 @@
|
|||
#include "cameracontroller.hpp"
|
||||
|
||||
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
||||
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false), mSceneElements(0), mRun(0), mDocument(document),
|
||||
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0),
|
||||
mDragWheelFactor(0), mDragShiftFactor(0),
|
||||
mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(0)
|
||||
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false)
|
||||
, mSceneElements(0)
|
||||
, mRun(0)
|
||||
, mDocument(document)
|
||||
, mInteractionMask (0)
|
||||
, mEditMode (0)
|
||||
, mLocked (false)
|
||||
, mDragMode(InteractionType_None)
|
||||
, mDragging (false)
|
||||
, mDragX(0)
|
||||
, mDragY(0)
|
||||
, mSpeedMode(false)
|
||||
, mDragFactor(0)
|
||||
, mDragWheelFactor(0)
|
||||
, mDragShiftFactor(0)
|
||||
, mToolTipPos (-1, -1)
|
||||
, mShowToolTips(false)
|
||||
, mToolTipDelay(0)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
|
||||
|
@ -80,6 +96,24 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
|||
|
||||
CSMPrefs::get()["3D Scene Input"].update();
|
||||
CSMPrefs::get()["Tooltips"].update();
|
||||
|
||||
// Shortcuts
|
||||
CSMPrefs::Shortcut* primaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", "scene-speed-modifier",
|
||||
CSMPrefs::Shortcut::SM_Detach, this);
|
||||
connect(primaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(primaryEdit(bool)));
|
||||
connect(primaryEditShortcut, SIGNAL(secondary(bool)), this, SLOT(speedMode(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* secondaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-secondary", this);
|
||||
connect(secondaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(secondaryEdit(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* primarySelectShortcut = new CSMPrefs::Shortcut("scene-select-primary", this);
|
||||
connect(primarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(primarySelect(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* secondarySelectShortcut = new CSMPrefs::Shortcut("scene-select-secondary", this);
|
||||
connect(secondarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(secondarySelect(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* abortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this);
|
||||
connect(abortShortcut, SIGNAL(activated()), this, SLOT(abortDrag()));
|
||||
}
|
||||
|
||||
CSVRender::WorldspaceWidget::~WorldspaceWidget ()
|
||||
|
@ -132,30 +166,32 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
|||
/// \todo consider user-defined button-mapping
|
||||
tool->addButton (":scenetoolbar/1st-person", "1st",
|
||||
"First Person"
|
||||
"<ul><li>Mouse-Look while holding the left button</li>"
|
||||
"<li>WASD movement keys</li>"
|
||||
"<ul><li>Camera is held upright</li>"
|
||||
"<li>Mouse-Look while holding {scene-navi-primary}</li>"
|
||||
"<li>Movement keys: {free-forward}(forward), {free-left}(left), {free-backward}(back), {free-right}(right)</li>"
|
||||
"<li>Strafing (also vertically) by holding {scene-navi-secondary}</li>"
|
||||
"<li>Mouse wheel moves the camera forward/backward</li>"
|
||||
"<li>Strafing (also vertically) by holding the left mouse button and control</li>"
|
||||
"<li>Camera is held upright</li>"
|
||||
"<li>Hold shift to speed up movement</li>"
|
||||
"<li>Hold {scene-speed-modifier} to speed up movement</li>"
|
||||
"</ul>");
|
||||
tool->addButton (":scenetoolbar/free-camera", "free",
|
||||
"Free Camera"
|
||||
"<ul><li>Mouse-Look while holding the left button</li>"
|
||||
"<li>Strafing (also vertically) via WASD or by holding the left mouse button and control</li>"
|
||||
"<ul><li>Mouse-Look while holding {scene-navi-primary}</li>"
|
||||
"<li>Movement keys: {free-forward}(forward), {free-left}(left), {free-backward}(back), {free-right}(right)</li>"
|
||||
"<li>Roll camera with {free-roll-left} and {free-roll-right} keys</li>"
|
||||
"<li>Strafing (also vertically) by holding {scene-navi-secondary}</li>"
|
||||
"<li>Mouse wheel moves the camera forward/backward</li>"
|
||||
"<li>Roll camera with Q and E keys</li>"
|
||||
"<li>Hold shift to speed up movement</li>"
|
||||
"<li>Hold {free-forward:mod} to speed up movement</li>"
|
||||
"</ul>");
|
||||
tool->addButton(
|
||||
new CSVRender::OrbitCameraMode(this, QIcon(":scenetoolbar/orbiting-camera"),
|
||||
"Orbiting Camera"
|
||||
"<ul><li>Always facing the centre point</li>"
|
||||
"<li>Rotate around the centre point via WASD or by moving the mouse while holding the left button</li>"
|
||||
"<li>Rotate around the centre point via {orbit-up}, {orbit-left}, {orbit-down}, {orbit-right} or by moving "
|
||||
"the mouse while holding {scene-navi-primary}</li>"
|
||||
"<li>Roll camera with {orbit-roll-left} and {orbit-roll-right} keys</li>"
|
||||
"<li>Strafing (also vertically) by holding {scene-navi-secondary} (includes relocation of the centre point)</li>"
|
||||
"<li>Mouse wheel moves camera away or towards centre point but can not pass through it</li>"
|
||||
"<li>Roll camera with Q and E keys</li>"
|
||||
"<li>Strafing (also vertically) by holding the left mouse button and control (includes relocation of the centre point)</li>"
|
||||
"<li>Hold shift to speed up movement</li>"
|
||||
"<li>Hold {scene-speed-modifier} to speed up movement</li>"
|
||||
"</ul>", tool),
|
||||
"orbit");
|
||||
|
||||
|
@ -409,7 +445,7 @@ void CSVRender::WorldspaceWidget::abortDrag()
|
|||
|
||||
editMode.dragAborted();
|
||||
mDragging = false;
|
||||
mDragMode.clear();
|
||||
mDragMode = InteractionType_None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,45 +489,6 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
|
||||
{
|
||||
static const char * const sMappingSettings[] =
|
||||
{
|
||||
"p-edit", "s-edit",
|
||||
"p-select", "s-select",
|
||||
0
|
||||
};
|
||||
|
||||
if (setting->getParent()->getKey()=="3D Scene Input")
|
||||
{
|
||||
for (int i=0; sMappingSettings[i]; ++i)
|
||||
{
|
||||
if (setting->getKey()==sMappingSettings[i])
|
||||
{
|
||||
QString value = QString::fromUtf8 (setting->toString().c_str());
|
||||
|
||||
Qt::MouseButton button = Qt::NoButton;
|
||||
|
||||
if (value.endsWith ("Left Mouse-Button"))
|
||||
button = Qt::LeftButton;
|
||||
else if (value.endsWith ("Right Mouse-Button"))
|
||||
button = Qt::RightButton;
|
||||
else if (value.endsWith ("Middle Mouse-Button"))
|
||||
button = Qt::MiddleButton;
|
||||
else
|
||||
return false;
|
||||
|
||||
bool ctrl = value.startsWith ("Ctrl-");
|
||||
|
||||
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SceneWidget::storeMappingSetting(setting);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
|
||||
{
|
||||
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
|
||||
|
@ -567,7 +564,7 @@ void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id)
|
|||
{
|
||||
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
|
||||
mDragging = false;
|
||||
mDragMode.clear();
|
||||
mDragMode = InteractionType_None;
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::showToolTip()
|
||||
|
@ -608,24 +605,24 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
|||
|
||||
double factor = mDragFactor;
|
||||
|
||||
if (event->modifiers() & Qt::ShiftModifier)
|
||||
if (mSpeedMode)
|
||||
factor *= mDragShiftFactor;
|
||||
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
editMode.drag (event->pos(), diffX, diffY, factor);
|
||||
}
|
||||
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select")
|
||||
else if (mDragMode != InteractionType_None)
|
||||
{
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
if (mDragMode=="p-edit")
|
||||
if (mDragMode == InteractionType_PrimaryEdit)
|
||||
mDragging = editMode.primaryEditStartDrag (event->pos());
|
||||
else if (mDragMode=="s-edit")
|
||||
else if (mDragMode == InteractionType_SecondaryEdit)
|
||||
mDragging = editMode.secondaryEditStartDrag (event->pos());
|
||||
else if (mDragMode=="p-select")
|
||||
else if (mDragMode == InteractionType_PrimarySelect)
|
||||
mDragging = editMode.primarySelectStartDrag (event->pos());
|
||||
else if (mDragMode=="s-select")
|
||||
else if (mDragMode == InteractionType_SecondarySelect)
|
||||
mDragging = editMode.secondarySelectStartDrag (event->pos());
|
||||
|
||||
if (mDragging)
|
||||
|
@ -656,53 +653,13 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
std::string button = mapButton (event);
|
||||
|
||||
if (button=="p-edit" || button=="s-edit" ||
|
||||
button=="p-select" || button=="s-select")
|
||||
{
|
||||
if (!mDragging)
|
||||
mDragMode = button;
|
||||
}
|
||||
else
|
||||
SceneWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
std::string button = mapButton (event);
|
||||
mDragMode.clear();
|
||||
|
||||
if (button=="p-edit" || button=="s-edit" ||
|
||||
button=="p-select" || button=="s-select")
|
||||
{
|
||||
if (mDragging)
|
||||
{
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
editMode.dragCompleted(event->pos());
|
||||
mDragging = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldspaceHitResult hit = mousePick(event->pos(), getInteractionMask());
|
||||
|
||||
handleMouseClick (hit, button, event->modifiers() & Qt::ShiftModifier);
|
||||
}
|
||||
}
|
||||
else
|
||||
SceneWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
||||
{
|
||||
if (mDragging)
|
||||
{
|
||||
double factor = mDragWheelFactor;
|
||||
|
||||
if (event->modifiers() & Qt::ShiftModifier)
|
||||
if (mSpeedMode)
|
||||
factor *= mDragShiftFactor;
|
||||
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
@ -713,27 +670,17 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
|||
SceneWidget::wheelEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Escape)
|
||||
{
|
||||
abortDrag();
|
||||
}
|
||||
else
|
||||
SceneWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift)
|
||||
void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type)
|
||||
{
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
if (button=="p-edit")
|
||||
if (type == InteractionType_PrimaryEdit)
|
||||
editMode.primaryEditPressed (hit);
|
||||
else if (button=="s-edit")
|
||||
else if (type == InteractionType_SecondaryEdit)
|
||||
editMode.secondaryEditPressed (hit);
|
||||
else if (button=="p-select")
|
||||
else if (type == InteractionType_PrimarySelect)
|
||||
editMode.primarySelectPressed (hit);
|
||||
else if (button=="s-select")
|
||||
else if (type == InteractionType_SecondarySelect)
|
||||
editMode.secondarySelectPressed (hit);
|
||||
}
|
||||
|
||||
|
@ -741,3 +688,53 @@ CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
|
|||
{
|
||||
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::primaryEdit(bool activate)
|
||||
{
|
||||
handleInteraction(InteractionType_PrimaryEdit, activate);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::secondaryEdit(bool activate)
|
||||
{
|
||||
handleInteraction(InteractionType_SecondaryEdit, activate);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::primarySelect(bool activate)
|
||||
{
|
||||
handleInteraction(InteractionType_PrimarySelect, activate);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::secondarySelect(bool activate)
|
||||
{
|
||||
handleInteraction(InteractionType_SecondarySelect, activate);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::speedMode(bool activate)
|
||||
{
|
||||
mSpeedMode = activate;
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::handleInteraction(InteractionType type, bool activate)
|
||||
{
|
||||
if (activate)
|
||||
{
|
||||
if (!mDragging)
|
||||
mDragMode = type;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDragMode = InteractionType_None;
|
||||
|
||||
if (mDragging)
|
||||
{
|
||||
EditMode* editMode = getEditMode();
|
||||
editMode->dragCompleted(mapFromGlobal(QCursor::pos()));
|
||||
mDragging = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldspaceHitResult hit = mousePick(mapFromGlobal(QCursor::pos()), getInteractionMask());
|
||||
handleInteractionPress(hit, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,10 +55,11 @@ namespace CSVRender
|
|||
unsigned int mInteractionMask;
|
||||
CSVWidget::SceneToolMode *mEditMode;
|
||||
bool mLocked;
|
||||
std::string mDragMode;
|
||||
int mDragMode;
|
||||
bool mDragging;
|
||||
int mDragX;
|
||||
int mDragY;
|
||||
bool mSpeedMode;
|
||||
double mDragFactor;
|
||||
double mDragWheelFactor;
|
||||
double mDragShiftFactor;
|
||||
|
@ -85,6 +86,15 @@ namespace CSVRender
|
|||
ignored //either mixed cells, or not cells
|
||||
};
|
||||
|
||||
enum InteractionType
|
||||
{
|
||||
InteractionType_PrimaryEdit,
|
||||
InteractionType_PrimarySelect,
|
||||
InteractionType_SecondaryEdit,
|
||||
InteractionType_SecondarySelect,
|
||||
InteractionType_None
|
||||
};
|
||||
|
||||
WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = 0);
|
||||
~WorldspaceWidget ();
|
||||
|
||||
|
@ -171,12 +181,6 @@ namespace CSVRender
|
|||
/// Erase all overrides and restore the visual representation to its true state.
|
||||
virtual void reset (unsigned int elementMask) = 0;
|
||||
|
||||
/// \note Drags will be automatically aborted when the aborting is triggered
|
||||
/// (either explicitly or implicitly) from within this class. This function only
|
||||
/// needs to be called, when the drag abort is triggered externally (e.g. from
|
||||
/// an edit mode).
|
||||
void abortDrag();
|
||||
|
||||
protected:
|
||||
|
||||
/// Visual elements in a scene
|
||||
|
@ -197,21 +201,16 @@ namespace CSVRender
|
|||
virtual void updateOverlay();
|
||||
|
||||
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||
virtual void mousePressEvent (QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||
virtual void wheelEvent (QWheelEvent *event);
|
||||
virtual void keyPressEvent (QKeyEvent *event);
|
||||
|
||||
virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
|
||||
bool shift);
|
||||
|
||||
/// \return Is \a key a button mapping setting? (ignored otherwise)
|
||||
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
|
||||
virtual void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type);
|
||||
|
||||
virtual void settingChanged (const CSMPrefs::Setting *setting);
|
||||
|
||||
EditMode *getEditMode();
|
||||
|
||||
bool getSpeedMode();
|
||||
|
||||
private:
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
|
@ -222,6 +221,16 @@ namespace CSVRender
|
|||
|
||||
virtual std::string getStartupInstruction() = 0;
|
||||
|
||||
void handleInteraction(InteractionType type, bool activate);
|
||||
|
||||
public slots:
|
||||
|
||||
/// \note Drags will be automatically aborted when the aborting is triggered
|
||||
/// (either explicitly or implicitly) from within this class. This function only
|
||||
/// needs to be called, when the drag abort is triggered externally (e.g. from
|
||||
/// an edit mode).
|
||||
void abortDrag();
|
||||
|
||||
private slots:
|
||||
|
||||
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||
|
@ -255,6 +264,16 @@ namespace CSVRender
|
|||
|
||||
void showToolTip();
|
||||
|
||||
void primaryEdit(bool activate);
|
||||
|
||||
void secondaryEdit(bool activate);
|
||||
|
||||
void primarySelect(bool activate);
|
||||
|
||||
void secondarySelect(bool activate);
|
||||
|
||||
void speedMode(bool activate);
|
||||
|
||||
protected slots:
|
||||
|
||||
void elementSelectionChanged();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "../../model/tools/reportmodel.hpp"
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "../../view/world/idtypedelegate.hpp"
|
||||
|
||||
|
@ -171,14 +172,20 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
|||
mShowAction = new QAction (tr ("Show"), this);
|
||||
connect (mShowAction, SIGNAL (triggered()), this, SLOT (showSelection()));
|
||||
addAction (mShowAction);
|
||||
CSMPrefs::Shortcut* showShortcut = new CSMPrefs::Shortcut("reporttable-show", this);
|
||||
showShortcut->associateAction(mShowAction);
|
||||
|
||||
mRemoveAction = new QAction (tr ("Remove from list"), this);
|
||||
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (removeSelection()));
|
||||
addAction (mRemoveAction);
|
||||
CSMPrefs::Shortcut* removeShortcut = new CSMPrefs::Shortcut("reporttable-remove", this);
|
||||
removeShortcut->associateAction(mRemoveAction);
|
||||
|
||||
mReplaceAction = new QAction (tr ("Replace"), this);
|
||||
connect (mReplaceAction, SIGNAL (triggered()), this, SIGNAL (replaceRequest()));
|
||||
addAction (mReplaceAction);
|
||||
CSMPrefs::Shortcut* replaceShortcut = new CSMPrefs::Shortcut("reporttable-replace", this);
|
||||
replaceShortcut->associateAction(mReplaceAction);
|
||||
|
||||
if (mRefreshState)
|
||||
{
|
||||
|
@ -186,6 +193,8 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
|||
mRefreshAction->setEnabled (!(mDocument.getState() & mRefreshState));
|
||||
connect (mRefreshAction, SIGNAL (triggered()), this, SIGNAL (refreshRequest()));
|
||||
addAction (mRefreshAction);
|
||||
CSMPrefs::Shortcut* refreshShortcut = new CSMPrefs::Shortcut("reporttable-refresh", this);
|
||||
refreshShortcut->associateAction(mRefreshAction);
|
||||
}
|
||||
|
||||
mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit));
|
||||
|
|
|
@ -3,9 +3,17 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcutmanager.hpp"
|
||||
|
||||
void CSVWidget::PushButton::processShortcuts()
|
||||
{
|
||||
mProcessedToolTip = CSMPrefs::State::get().getShortcutManager().processToolTip(mToolTip);
|
||||
}
|
||||
|
||||
void CSVWidget::PushButton::setExtendedToolTip()
|
||||
{
|
||||
QString tooltip = mToolTip;
|
||||
QString tooltip = mProcessedToolTip;
|
||||
|
||||
if (tooltip.isEmpty())
|
||||
tooltip = "(Tool tip not implemented yet)";
|
||||
|
@ -77,13 +85,18 @@ CSVWidget::PushButton::PushButton (const QIcon& icon, Type type, const QString&
|
|||
connect (this, SIGNAL (toggled (bool)), this, SLOT (checkedStateChanged (bool)));
|
||||
}
|
||||
setCheckable (type==Type_Mode || type==Type_Toggle);
|
||||
processShortcuts();
|
||||
setExtendedToolTip();
|
||||
|
||||
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
|
||||
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
|
||||
}
|
||||
|
||||
CSVWidget::PushButton::PushButton (Type type, const QString& tooltip, QWidget *parent)
|
||||
: QPushButton (parent), mKeepOpen (false), mType (type), mToolTip (tooltip)
|
||||
{
|
||||
setCheckable (type==Type_Mode || type==Type_Toggle);
|
||||
processShortcuts();
|
||||
setExtendedToolTip();
|
||||
}
|
||||
|
||||
|
@ -94,7 +107,7 @@ bool CSVWidget::PushButton::hasKeepOpen() const
|
|||
|
||||
QString CSVWidget::PushButton::getBaseToolTip() const
|
||||
{
|
||||
return mToolTip;
|
||||
return mProcessedToolTip;
|
||||
}
|
||||
|
||||
CSVWidget::PushButton::Type CSVWidget::PushButton::getType() const
|
||||
|
@ -106,3 +119,12 @@ void CSVWidget::PushButton::checkedStateChanged (bool checked)
|
|||
{
|
||||
setExtendedToolTip();
|
||||
}
|
||||
|
||||
void CSVWidget::PushButton::settingChanged (const CSMPrefs::Setting *setting)
|
||||
{
|
||||
if (setting->getParent()->getKey() == "Key Bindings")
|
||||
{
|
||||
processShortcuts();
|
||||
setExtendedToolTip();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include <QPushButton>
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Setting;
|
||||
}
|
||||
|
||||
namespace CSVWidget
|
||||
{
|
||||
class PushButton : public QPushButton
|
||||
|
@ -24,9 +29,11 @@ namespace CSVWidget
|
|||
bool mKeepOpen;
|
||||
Type mType;
|
||||
QString mToolTip;
|
||||
QString mProcessedToolTip;
|
||||
|
||||
private:
|
||||
|
||||
void processShortcuts();
|
||||
void setExtendedToolTip();
|
||||
|
||||
protected:
|
||||
|
@ -57,6 +64,7 @@ namespace CSVWidget
|
|||
private slots:
|
||||
|
||||
void checkedStateChanged (bool checked);
|
||||
void settingChanged (const CSMPrefs::Setting *setting);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "scenetoolbar.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QShortcut>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "scenetool.hpp"
|
||||
|
||||
|
@ -25,9 +26,8 @@ CSVWidget::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent)
|
|||
|
||||
setLayout (mLayout);
|
||||
|
||||
/// \todo make shortcut configurable
|
||||
QShortcut *focusScene = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
|
||||
connect (focusScene, SIGNAL (activated()), this, SIGNAL (focusSceneRequest()));
|
||||
CSMPrefs::Shortcut* focusSceneShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
|
||||
connect(focusSceneShortcut, SIGNAL(activated()), this, SIGNAL(focusSceneRequest()));
|
||||
}
|
||||
|
||||
void CSVWidget::SceneToolbar::addTool (SceneTool *tool, SceneTool *insertPoint)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <QSignalMapper>
|
||||
#include <QMenu>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QEvent>
|
||||
|
||||
#include "scenetoolbar.hpp"
|
||||
#include "modebutton.hpp"
|
||||
|
@ -133,6 +134,16 @@ void CSVWidget::SceneToolMode::setButton (const std::string& id)
|
|||
}
|
||||
}
|
||||
|
||||
bool CSVWidget::SceneToolMode::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip)
|
||||
{
|
||||
adjustToolTip(mCurrent);
|
||||
}
|
||||
|
||||
return SceneTool::event(event);
|
||||
}
|
||||
|
||||
void CSVWidget::SceneToolMode::selected()
|
||||
{
|
||||
std::map<ModeButton *, std::string>::iterator iter =
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
class QHBoxLayout;
|
||||
class QMenu;
|
||||
class QEvent;
|
||||
|
||||
namespace CSVWidget
|
||||
{
|
||||
|
@ -43,6 +44,10 @@ namespace CSVWidget
|
|||
|
||||
void setButton (std::map<ModeButton *, std::string>::iterator iter);
|
||||
|
||||
protected:
|
||||
|
||||
bool event(QEvent* event);
|
||||
|
||||
public:
|
||||
|
||||
SceneToolMode (SceneToolbar *parent, const QString& toolTip);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QMenu>
|
||||
#include <QDebug>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "../../model/world/nestedtableproxymodel.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
|
@ -60,14 +62,16 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
|
|||
if (!fixedRows)
|
||||
{
|
||||
mAddNewRowAction = new QAction (tr ("Add new row"), this);
|
||||
|
||||
connect(mAddNewRowAction, SIGNAL(triggered()),
|
||||
this, SLOT(addNewRowActionTriggered()));
|
||||
CSMPrefs::Shortcut* addRowShortcut = new CSMPrefs::Shortcut("table-add", this);
|
||||
addRowShortcut->associateAction(mAddNewRowAction);
|
||||
|
||||
mRemoveRowAction = new QAction (tr ("Remove rows"), this);
|
||||
|
||||
connect(mRemoveRowAction, SIGNAL(triggered()),
|
||||
this, SLOT(removeRowActionTriggered()));
|
||||
CSMPrefs::Shortcut* removeRowShortcut = new CSMPrefs::Shortcut("table-remove", this);
|
||||
removeRowShortcut->associateAction(mRemoveRowAction);
|
||||
}
|
||||
|
||||
mEditIdAction = new TableEditIdAction(*this, this);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../../model/world/commanddispatcher.hpp"
|
||||
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "tableeditidaction.hpp"
|
||||
#include "util.hpp"
|
||||
|
@ -283,49 +284,72 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
|||
mEditAction = new QAction (tr ("Edit Record"), this);
|
||||
connect (mEditAction, SIGNAL (triggered()), this, SLOT (editRecord()));
|
||||
addAction (mEditAction);
|
||||
CSMPrefs::Shortcut* editShortcut = new CSMPrefs::Shortcut("table-edit", this);
|
||||
editShortcut->associateAction(mEditAction);
|
||||
|
||||
if (createAndDelete)
|
||||
{
|
||||
mCreateAction = new QAction (tr ("Add Record"), this);
|
||||
connect (mCreateAction, SIGNAL (triggered()), this, SIGNAL (createRequest()));
|
||||
addAction (mCreateAction);
|
||||
CSMPrefs::Shortcut* createShortcut = new CSMPrefs::Shortcut("table-add", this);
|
||||
createShortcut->associateAction(mCreateAction);
|
||||
|
||||
mCloneAction = new QAction (tr ("Clone Record"), this);
|
||||
connect(mCloneAction, SIGNAL (triggered()), this, SLOT (cloneRecord()));
|
||||
addAction(mCloneAction);
|
||||
CSMPrefs::Shortcut* cloneShortcut = new CSMPrefs::Shortcut("table-clone", this);
|
||||
cloneShortcut->associateAction(mCloneAction);
|
||||
}
|
||||
|
||||
mRevertAction = new QAction (tr ("Revert Record"), this);
|
||||
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
|
||||
addAction (mRevertAction);
|
||||
CSMPrefs::Shortcut* revertShortcut = new CSMPrefs::Shortcut("table-revert", this);
|
||||
revertShortcut->associateAction(mRevertAction);
|
||||
|
||||
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
||||
connect (mDeleteAction, SIGNAL (triggered()), mDispatcher, SLOT (executeDelete()));
|
||||
addAction (mDeleteAction);
|
||||
CSMPrefs::Shortcut* deleteShortcut = new CSMPrefs::Shortcut("table-remove", this);
|
||||
deleteShortcut->associateAction(mDeleteAction);
|
||||
|
||||
|
||||
mMoveUpAction = new QAction (tr ("Move Up"), this);
|
||||
connect (mMoveUpAction, SIGNAL (triggered()), this, SLOT (moveUpRecord()));
|
||||
addAction (mMoveUpAction);
|
||||
CSMPrefs::Shortcut* moveUpShortcut = new CSMPrefs::Shortcut("table-moveup", this);
|
||||
moveUpShortcut->associateAction(mMoveUpAction);
|
||||
|
||||
mMoveDownAction = new QAction (tr ("Move Down"), this);
|
||||
connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord()));
|
||||
addAction (mMoveDownAction);
|
||||
CSMPrefs::Shortcut* moveDownShortcut = new CSMPrefs::Shortcut("table-movedown", this);
|
||||
moveDownShortcut->associateAction(mMoveDownAction);
|
||||
|
||||
mViewAction = new QAction (tr ("View"), this);
|
||||
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
||||
addAction (mViewAction);
|
||||
CSMPrefs::Shortcut* viewShortcut = new CSMPrefs::Shortcut("table-view", this);
|
||||
viewShortcut->associateAction(mViewAction);
|
||||
|
||||
mPreviewAction = new QAction (tr ("Preview"), this);
|
||||
connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord()));
|
||||
addAction (mPreviewAction);
|
||||
CSMPrefs::Shortcut* previewShortcut = new CSMPrefs::Shortcut("table-preview", this);
|
||||
previewShortcut->associateAction(mPreviewAction);
|
||||
|
||||
mExtendedDeleteAction = new QAction (tr ("Extended Delete Record"), this);
|
||||
connect (mExtendedDeleteAction, SIGNAL (triggered()), this, SLOT (executeExtendedDelete()));
|
||||
addAction (mExtendedDeleteAction);
|
||||
CSMPrefs::Shortcut* extendedDeleteShortcut = new CSMPrefs::Shortcut("table-extendeddelete", this);
|
||||
extendedDeleteShortcut->associateAction(mExtendedDeleteAction);
|
||||
|
||||
mExtendedRevertAction = new QAction (tr ("Extended Revert Record"), this);
|
||||
connect (mExtendedRevertAction, SIGNAL (triggered()), this, SLOT (executeExtendedRevert()));
|
||||
addAction (mExtendedRevertAction);
|
||||
CSMPrefs::Shortcut* extendedRevertShortcut = new CSMPrefs::Shortcut("table-extendedrevert", this);
|
||||
extendedRevertShortcut->associateAction(mExtendedRevertAction);
|
||||
|
||||
mEditIdAction = new TableEditIdAction (*this, this);
|
||||
connect (mEditIdAction, SIGNAL (triggered()), this, SLOT (editCell()));
|
||||
|
|
Loading…
Reference in a new issue