mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
713 lines
20 KiB
C++
713 lines
20 KiB
C++
/**
|
|
* RobloxKeyboardConfig.cpp
|
|
* Copyright (c) 2013 ROBLOX Corp. All Rights Reserved.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "RobloxKeyboardConfig.h"
|
|
|
|
#include <QDialogButtonBox>
|
|
#include <QKeyEvent>
|
|
#include <QLineEdit>
|
|
#include <QMap>
|
|
#include <QPushButton>
|
|
#include <QSettings>
|
|
#include <QStyledItemDelegate>
|
|
#include <QTreeView>
|
|
|
|
#include "RobloxMainWindow.h"
|
|
#include "StudioUtilities.h"
|
|
|
|
FASTFLAG(StudioShowTutorialsByDefault)
|
|
|
|
// shortcuts that should not be visible to the average user
|
|
static const QString ShortcutExceptions =
|
|
"toggleBuildModeAction filePublishedProjectsAction screenShotAction";
|
|
|
|
enum eShortcutTableColumns
|
|
{
|
|
STC_NAME = 0,
|
|
STC_SHORTCUT,
|
|
STC_DESCRIPTION,
|
|
STC_MAX,
|
|
};
|
|
|
|
// A comparator for sorting shortcuts and their overrides.
|
|
class ShortcutComparator
|
|
{
|
|
public:
|
|
ShortcutComparator(int columnArg, Qt::SortOrder orderArg, ShortcutsModel& modelArg)
|
|
: column(columnArg)
|
|
, order(orderArg)
|
|
, model(modelArg)
|
|
{}
|
|
|
|
bool operator()(const int& a, const int& b) const
|
|
{
|
|
QString aData = model.m_shortcutData[a].toString(column);
|
|
QString bData = model.m_shortcutData[b].toString(column);
|
|
|
|
if (order == Qt::AscendingOrder)
|
|
return aData.toLower() > bData.toLower();
|
|
else
|
|
return aData.toLower() < bData.toLower();
|
|
}
|
|
|
|
int column;
|
|
Qt::SortOrder order;
|
|
ShortcutsModel& model;
|
|
};
|
|
|
|
|
|
KeySequenceEdit::KeySequenceEdit(QWidget* parent)
|
|
: QWidget(parent)
|
|
, m_num(0)
|
|
{
|
|
setContentsMargins(0, 0, 0, 0);
|
|
QHBoxLayout *layout = new QHBoxLayout(this);
|
|
m_lineEdit = new QLineEdit(this);
|
|
m_lineEdit->setFixedHeight(20);
|
|
|
|
layout->addWidget(m_lineEdit);
|
|
layout->setMargin(0);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
m_lineEdit->installEventFilter(this);
|
|
m_lineEdit->setReadOnly(true);
|
|
m_lineEdit->setFocusProxy(this);
|
|
setFocusPolicy(m_lineEdit->focusPolicy());
|
|
setAttribute(Qt::WA_InputMethodEnabled);
|
|
}
|
|
|
|
bool KeySequenceEdit::eventFilter(QObject* o, QEvent* e)
|
|
{
|
|
// Create a right click context menu for clearing the QKeySequence set.
|
|
if (o == m_lineEdit && e->type() == QEvent::ContextMenu)
|
|
{
|
|
QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
|
|
QMenu *menu = m_lineEdit->createStandardContextMenu();
|
|
menu->clear();
|
|
|
|
QAction *clearAction = new QAction(tr("Clear Shortcut"), menu);
|
|
menu->insertAction(NULL, clearAction);
|
|
clearAction->setEnabled(!m_keySequence.isEmpty());
|
|
connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearShortcut()));
|
|
|
|
menu->exec(c->globalPos());
|
|
delete menu;
|
|
e->accept();
|
|
|
|
return true;
|
|
}
|
|
|
|
return QWidget::eventFilter(o, e);
|
|
}
|
|
|
|
void KeySequenceEdit::slotClearShortcut()
|
|
{
|
|
if (m_keySequence.isEmpty())
|
|
return;
|
|
|
|
setKeySequence(QKeySequence());
|
|
Q_EMIT keySequenceChanged(m_keySequence);
|
|
}
|
|
|
|
void KeySequenceEdit::handleKeyEvent(QKeyEvent* e)
|
|
{
|
|
// Main key processing function. All keys pressed will pass through
|
|
// here and then be converted to QKeySequences.
|
|
|
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)
|
|
{
|
|
Q_EMIT(editingFinished());
|
|
return;
|
|
}
|
|
|
|
int key = e->key();
|
|
if (key == Qt::Key_Control || key == Qt::Key_Shift ||
|
|
key == Qt::Key_Meta || key == Qt::Key_Alt ||
|
|
key == Qt::Key_Super_L || key == Qt::Key_AltGr)
|
|
return;
|
|
|
|
key |= StudioUtilities::translateKeyModifiers(e->modifiers(), e->text());
|
|
m_keySequence = QKeySequence(key);
|
|
m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
|
|
e->accept();
|
|
Q_EMIT keySequenceChanged(m_keySequence);
|
|
}
|
|
|
|
void KeySequenceEdit::setKeySequence(const QKeySequence &sequence)
|
|
{
|
|
if (sequence == m_keySequence)
|
|
return;
|
|
m_num = 0;
|
|
m_keySequence = sequence;
|
|
m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
|
|
}
|
|
|
|
QKeySequence KeySequenceEdit::keySequence() const
|
|
{
|
|
return m_keySequence;
|
|
}
|
|
|
|
void KeySequenceEdit::focusInEvent(QFocusEvent *e)
|
|
{
|
|
m_lineEdit->event(e);
|
|
m_lineEdit->selectAll();
|
|
QWidget::focusInEvent(e);
|
|
}
|
|
|
|
void KeySequenceEdit::focusOutEvent(QFocusEvent *e)
|
|
{
|
|
m_num = 0;
|
|
m_lineEdit->event(e);
|
|
QWidget::focusOutEvent(e);
|
|
}
|
|
|
|
void KeySequenceEdit::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
handleKeyEvent(e);
|
|
e->accept();
|
|
}
|
|
|
|
void KeySequenceEdit::keyReleaseEvent(QKeyEvent *e)
|
|
{
|
|
m_lineEdit->event(e);
|
|
}
|
|
|
|
bool KeySequenceEdit::event(QEvent *e)
|
|
{
|
|
if (e->type() == QEvent::Shortcut ||
|
|
e->type() == QEvent::ShortcutOverride ||
|
|
e->type() == QEvent::KeyRelease)
|
|
{
|
|
e->accept();
|
|
return true;
|
|
}
|
|
|
|
return QWidget::event(e);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
QString ShortcutData::toString(int column) const
|
|
{
|
|
if (column == STC_NAME)
|
|
{
|
|
return m_action->text();
|
|
}
|
|
else if (column == STC_SHORTCUT)
|
|
{
|
|
if (hasOverride())
|
|
{
|
|
const QKeySequence& override = m_shortcutOverride;
|
|
return override.toString(QKeySequence::NativeText);
|
|
}
|
|
|
|
return m_action->shortcut().toString(QKeySequence::NativeText);
|
|
}
|
|
else if (column == STC_DESCRIPTION)
|
|
{
|
|
return m_action->statusTip();
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ShortcutsModel::ShortcutsModel(RobloxMainWindow& mainWindow, QObject *parent)
|
|
: QAbstractTableModel(parent)
|
|
, m_mainWindow(mainWindow)
|
|
{
|
|
resetData();
|
|
}
|
|
|
|
void ShortcutsModel::resetData()
|
|
{
|
|
// Performs a complete flush of the model and repopulates it based
|
|
// off of the mainWindow's action loadout.
|
|
|
|
m_shortcutData.clear();
|
|
m_sortOrder.clear();
|
|
|
|
int i = 0;
|
|
QObjectList objects = m_mainWindow.children();
|
|
QObjectList::iterator iter = objects.begin();
|
|
for ( ; iter != objects.end() ; ++iter )
|
|
{
|
|
RBX::BaldPtr<QAction> action = dynamic_cast<QAction*>(*iter);
|
|
if ( action &&
|
|
!action->text().isEmpty() &&
|
|
!action->text().startsWith("&") &&
|
|
!ShortcutExceptions.contains(action->objectName()) &&
|
|
!(!FFlag::StudioShowTutorialsByDefault && action->objectName() == "viewTutorialsAction"))
|
|
{
|
|
m_shortcutData.push_back(ShortcutData(action));
|
|
m_sortOrder.push_back(i++);
|
|
}
|
|
}
|
|
|
|
Q_EMIT(dataChanged(index(0,0), index(rowCount(), columnCount())));
|
|
}
|
|
|
|
int ShortcutsModel::rowCount(const QModelIndex& /*parent*/) const
|
|
{
|
|
return m_shortcutData.size();
|
|
}
|
|
|
|
int ShortcutsModel::columnCount(const QModelIndex& /*parent*/) const
|
|
{
|
|
return STC_MAX;
|
|
}
|
|
|
|
// awagnerTODO: add a search bar and use a QSortFilterProxyModel
|
|
void ShortcutsModel::sort(int column, Qt::SortOrder order)
|
|
{
|
|
ShortcutComparator comparator(column, order, *this);
|
|
qSort(m_sortOrder.begin(), m_sortOrder.end(), comparator);
|
|
Q_EMIT(layoutChanged());
|
|
}
|
|
|
|
QVariant ShortcutsModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
const ShortcutData& shortcutData = m_shortcutData[m_sortOrder[index.row()]];
|
|
const QAction* action = shortcutData.action();
|
|
|
|
if (role == Qt::DecorationRole)
|
|
{
|
|
if (index.column() == STC_NAME)
|
|
{
|
|
QIcon icon = action->icon();
|
|
if ( icon.isNull() )
|
|
{
|
|
QPixmap pix(16,16);
|
|
pix.fill(QColor(0,0,0,0));
|
|
icon = QIcon(pix);
|
|
}
|
|
|
|
return icon;
|
|
}
|
|
}
|
|
if (role == Qt::EditRole)
|
|
{
|
|
return QVariant::fromValue(shortcutData);
|
|
}
|
|
if (role == Qt::DisplayRole)
|
|
{
|
|
return shortcutData.toString(index.column());
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
bool ShortcutsModel::setData(const QModelIndex & index, const QVariant& value, int role)
|
|
{
|
|
if (role == Qt::EditRole && index.column() == STC_SHORTCUT)
|
|
{
|
|
ShortcutData shortcut = qvariant_cast<ShortcutData>(value);
|
|
ShortcutData& shortcutData = m_shortcutData[m_sortOrder[index.row()]];
|
|
shortcutData = shortcut;
|
|
Q_EMIT(dataChanged(index, index));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
QVariant ShortcutsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (role == Qt::DisplayRole)
|
|
{
|
|
if (orientation == Qt::Horizontal) {
|
|
switch (section)
|
|
{
|
|
case STC_NAME:
|
|
return QString("Name");
|
|
case STC_SHORTCUT:
|
|
return QString("Shortcut");
|
|
case STC_DESCRIPTION:
|
|
return QString("Description");
|
|
}
|
|
}
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
Qt::ItemFlags ShortcutsModel::flags(const QModelIndex& index) const
|
|
{
|
|
if (index.column() == STC_SHORTCUT)
|
|
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
|
|
else
|
|
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
|
}
|
|
|
|
void ShortcutsModel::commitOverrides()
|
|
{
|
|
for (QList<ShortcutData>::iterator iter = m_shortcutData.begin();
|
|
iter != m_shortcutData.end();
|
|
iter++)
|
|
{
|
|
if (iter->hasOverride())
|
|
{
|
|
iter->action()->setShortcut(iter->shortcutOverride());
|
|
}
|
|
}
|
|
}
|
|
|
|
void ShortcutsModel::resetOverrides()
|
|
{
|
|
for (QList<ShortcutData>::iterator iter = m_shortcutData.begin();
|
|
iter != m_shortcutData.end();
|
|
iter++)
|
|
{
|
|
if (iter->hasOverride())
|
|
{
|
|
iter->removeShortcutOverride();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ShortcutsModel::removeShortcut(const QKeySequence& keySequence)
|
|
{
|
|
for (QList<ShortcutData>::iterator iter = m_shortcutData.begin();
|
|
iter != m_shortcutData.end();
|
|
iter++)
|
|
{
|
|
// If an action already has the shortcut, then add a override. Or if
|
|
// the shortcut is overriden and it matches the keysequence, then set
|
|
// the override to empty.
|
|
|
|
if (iter->hasOverride())
|
|
{
|
|
if (iter->shortcutOverride().toString() == keySequence.toString())
|
|
{
|
|
iter->setShortcutOverride(QKeySequence());
|
|
}
|
|
}
|
|
else if (iter->action()->shortcut().toString() == keySequence.toString())
|
|
{
|
|
iter->setShortcutOverride(QKeySequence());
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
QWidget* ShortcutDelegate::createEditor(QWidget *parent,
|
|
const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) const
|
|
|
|
{
|
|
if (index.column() == STC_SHORTCUT)
|
|
{
|
|
KeySequenceEdit *editor = new KeySequenceEdit(parent);
|
|
return editor;
|
|
}
|
|
|
|
return QStyledItemDelegate::createEditor(parent, option, index);
|
|
}
|
|
|
|
void ShortcutDelegate::setEditorData(QWidget *editor,
|
|
const QModelIndex &index) const
|
|
{
|
|
if (index.column() == STC_SHORTCUT)
|
|
{
|
|
const ShortcutsModel* model = qobject_cast<const ShortcutsModel*>(index.model());
|
|
|
|
if (!model)
|
|
return;
|
|
|
|
ShortcutData shortcutData = qvariant_cast<ShortcutData>(model->data(index, Qt::EditRole));
|
|
|
|
KeySequenceEdit *keySequenceEdit = qobject_cast<KeySequenceEdit*>(editor);
|
|
|
|
if (shortcutData.hasOverride())
|
|
{
|
|
const QKeySequence& override = shortcutData.shortcutOverride();
|
|
keySequenceEdit->setKeySequence(override);
|
|
return;
|
|
}
|
|
|
|
keySequenceEdit->setKeySequence(shortcutData.action()->shortcut());
|
|
}
|
|
else
|
|
{
|
|
QStyledItemDelegate::setEditorData(editor, index);
|
|
}
|
|
}
|
|
|
|
QSize ShortcutDelegate::sizeHint(const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) const
|
|
{
|
|
if (index.column() == STC_SHORTCUT)
|
|
{
|
|
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
|
size.setHeight(28);
|
|
return size;
|
|
}
|
|
else
|
|
{
|
|
return QStyledItemDelegate::sizeHint(option, index);
|
|
}
|
|
}
|
|
|
|
void ShortcutDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
|
const QModelIndex &index) const
|
|
{
|
|
// Called when the edit has finished. Saves the QKeySequence generated
|
|
// to a shortcut override on the model, first removing it from any action
|
|
// that may already have it.
|
|
|
|
if (index.column() == STC_SHORTCUT)
|
|
{
|
|
KeySequenceEdit *keySequenceEdit = qobject_cast<KeySequenceEdit*>(editor);
|
|
|
|
if (!keySequenceEdit)
|
|
return;
|
|
|
|
ShortcutsModel* shortcutsModel = qobject_cast<ShortcutsModel*>(model);
|
|
|
|
if (!shortcutsModel)
|
|
return;
|
|
|
|
ShortcutData shortcut = qvariant_cast<ShortcutData>(shortcutsModel->data(index, Qt::EditRole));
|
|
|
|
const QKeySequence& keySequence = keySequenceEdit->keySequence();
|
|
|
|
// Remove the shortcut from all actions if it's already assigned.
|
|
shortcutsModel->removeShortcut(keySequence);
|
|
|
|
shortcut.setShortcutOverride(keySequence);
|
|
shortcutsModel->setData(index, QVariant::fromValue(shortcut));
|
|
}
|
|
else
|
|
{
|
|
QStyledItemDelegate::setModelData(editor, model, index);
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
RobloxKeyboardConfig::RobloxKeyboardConfig()
|
|
{
|
|
}
|
|
|
|
RobloxKeyboardConfig& RobloxKeyboardConfig::singleton()
|
|
{
|
|
static RobloxKeyboardConfig* robloxKeyboardConfig = new RobloxKeyboardConfig();
|
|
return *robloxKeyboardConfig;
|
|
}
|
|
|
|
void RobloxKeyboardConfig::storeDefaults(RobloxMainWindow& mainWindow)
|
|
{
|
|
// Store off all the action shortcuts in their default state.
|
|
|
|
QObjectList objects = mainWindow.children();
|
|
QObjectList::iterator iter = objects.begin();
|
|
for (; iter != objects.end(); ++iter)
|
|
{
|
|
RBX::BaldPtr<QAction> action = dynamic_cast<QAction*>(*iter);
|
|
if (action &&
|
|
!action->text().isEmpty() &&
|
|
!action->text().startsWith("&") &&
|
|
!ShortcutExceptions.contains(action->objectName()))
|
|
{
|
|
m_defaultShortcuts[action->objectName()] = action->shortcut();
|
|
}
|
|
}
|
|
}
|
|
|
|
void RobloxKeyboardConfig::saveKeyboardConfig(RobloxMainWindow& mainWindow)
|
|
{
|
|
// Save any action shortcut that deviates from its default in a QSetting.
|
|
|
|
QMap<QString, QKeySequence> keymap;
|
|
|
|
QObjectList objects = mainWindow.children();
|
|
QObjectList::iterator iter = objects.begin();
|
|
for ( ; iter != objects.end() ; ++iter )
|
|
{
|
|
RBX::BaldPtr<QAction> action = dynamic_cast<QAction*>(*iter);
|
|
if (action &&
|
|
!action->text().isEmpty() &&
|
|
!action->text().startsWith("&") &&
|
|
!ShortcutExceptions.contains(action->objectName()) &&
|
|
!(!FFlag::StudioShowTutorialsByDefault && action->objectName() == "viewTutorialsAction"))
|
|
{
|
|
QMap<QString, QKeySequence>::iterator iter = m_defaultShortcuts.find(action->objectName());
|
|
if (iter != m_defaultShortcuts.end())
|
|
{
|
|
if(iter.value().toString(QKeySequence::NativeText) != action->shortcut().toString(QKeySequence::NativeText))
|
|
{
|
|
keymap[action->objectName()] = action->shortcut();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
QSettings settings;
|
|
|
|
// The only way to clear a group is by calling remove on an empty string.
|
|
// http://qt-project.org/doc/qt-4.8/qsettings.html#remove
|
|
//
|
|
settings.beginGroup("Roblox Studio Key Mapping");
|
|
settings.remove("");
|
|
settings.endGroup();
|
|
|
|
settings.beginGroup("Roblox Studio Key Mapping");
|
|
QMap<QString, QKeySequence>::const_iterator i = keymap.constBegin();
|
|
while (i != keymap.constEnd())
|
|
{
|
|
settings.setValue(i.key(), i.value().toString());
|
|
++i;
|
|
}
|
|
settings.endGroup();
|
|
}
|
|
|
|
void RobloxKeyboardConfig::loadKeyboardConfig(RobloxMainWindow& mainWindow)
|
|
{
|
|
// Load the shortcut QSettings group into a map and map it back to each
|
|
// action by objectName().
|
|
|
|
QMap<QString, QKeySequence> keymap;
|
|
|
|
QSettings settings;
|
|
settings.beginGroup("Roblox Studio Key Mapping");
|
|
QStringList keys = settings.childKeys();
|
|
Q_FOREACH (QString key, keys) {
|
|
keymap[key] = QKeySequence(settings.value(key).toString());
|
|
}
|
|
settings.endGroup();
|
|
|
|
QObjectList objects = mainWindow.children();
|
|
QObjectList::iterator iter = objects.begin();
|
|
for ( ; iter != objects.end() ; ++iter )
|
|
{
|
|
RBX::BaldPtr<QAction> action = dynamic_cast<QAction*>(*iter);
|
|
if (action &&
|
|
!action->text().isEmpty() &&
|
|
!action->text().startsWith("&") &&
|
|
!ShortcutExceptions.contains(action->objectName()) &&
|
|
!(!FFlag::StudioShowTutorialsByDefault && action->objectName() == "viewTutorialsAction"))
|
|
{
|
|
QMap<QString, QKeySequence>::iterator iter = keymap.find(action->objectName());
|
|
if (iter != keymap.end())
|
|
{
|
|
action->setShortcut(iter.value());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
RobloxKeyboardConfigWidget::RobloxKeyboardConfigWidget(RobloxMainWindow& MainWindow,
|
|
QWidget* parent)
|
|
: QWidget(parent)
|
|
, m_mainWindow(MainWindow)
|
|
, m_filterEdit(NULL)
|
|
{
|
|
initialize();
|
|
}
|
|
|
|
void RobloxKeyboardConfigWidget::initialize()
|
|
{
|
|
RBXASSERT(!layout());
|
|
|
|
RBX::BaldPtr<QLayout> layout = new QVBoxLayout;
|
|
|
|
m_filterEdit = new QLineEdit(this);
|
|
m_filterEdit->setPlaceholderText("Search Actions");
|
|
m_filterEdit->setFocusPolicy(Qt::ClickFocus);
|
|
layout->addWidget(m_filterEdit);
|
|
connect(m_filterEdit, SIGNAL(textChanged(QString)), this, SLOT(setFilter(QString)));
|
|
|
|
m_treeView = new QTreeView(this);
|
|
layout->addWidget(m_treeView);
|
|
setLayout(layout);
|
|
|
|
m_model = new ShortcutsModel(m_mainWindow, this);
|
|
m_treeView->setModel(m_model);
|
|
m_treeView->setItemsExpandable(false);
|
|
m_treeView->setRootIsDecorated(false);
|
|
m_treeView->setSortingEnabled(true);
|
|
m_treeView->header()->setDefaultSectionSize(200);
|
|
connect(m_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
|
|
this, SLOT(dataChanged(const QModelIndex&, const QModelIndex&)));
|
|
|
|
m_treeView->setItemDelegateForColumn(STC_SHORTCUT, new ShortcutDelegate(this));
|
|
}
|
|
|
|
void RobloxKeyboardConfigWidget::cancel()
|
|
{
|
|
m_model->resetOverrides();
|
|
}
|
|
|
|
void RobloxKeyboardConfigWidget::accept()
|
|
{
|
|
m_model->commitOverrides();
|
|
m_mainWindow.updateShortcutSet();
|
|
RobloxKeyboardConfig::singleton().saveKeyboardConfig(m_mainWindow);
|
|
}
|
|
|
|
void RobloxKeyboardConfigWidget::restoreAllDefaults()
|
|
{
|
|
// Iterate through all the actions on mainWindow and set them back to the
|
|
// defaultShortcuts we stored off after application load.
|
|
|
|
m_treeView->closePersistentEditor(m_treeView->currentIndex());
|
|
|
|
QObjectList objects = m_mainWindow.children();
|
|
QObjectList::iterator iter = objects.begin();
|
|
for (; iter != objects.end(); ++iter)
|
|
{
|
|
RBX::BaldPtr<QAction> action = dynamic_cast<QAction*>(*iter);
|
|
if (action &&
|
|
!action->text().isEmpty() &&
|
|
!action->text().startsWith("&") &&
|
|
!ShortcutExceptions.contains(action->objectName()))
|
|
{
|
|
QMap<QString, QKeySequence>::const_iterator iter =
|
|
RobloxKeyboardConfig::singleton().defaultShortcuts().find(action->objectName());
|
|
if (iter != RobloxKeyboardConfig::singleton().defaultShortcuts().end())
|
|
{
|
|
action->setShortcut(iter.value());
|
|
}
|
|
}
|
|
}
|
|
|
|
m_model->resetData();
|
|
m_treeView->sortByColumn(0, Qt::DescendingOrder);
|
|
Q_EMIT(dataChanged());
|
|
}
|
|
|
|
void RobloxKeyboardConfigWidget::dataChanged(const QModelIndex&,
|
|
const QModelIndex&)
|
|
{
|
|
Q_EMIT(dataChanged());
|
|
}
|
|
|
|
void RobloxKeyboardConfigWidget::setFilter(QString filter)
|
|
{
|
|
setUpdatesEnabled(false);
|
|
QAbstractItemModel* treeViewModel = m_treeView->model();
|
|
|
|
int numRows = treeViewModel->rowCount();
|
|
QString text;
|
|
|
|
for (int ii = 0; ii < numRows; ++ii)
|
|
{
|
|
text = treeViewModel->data(treeViewModel->index(ii, 0)).toString();
|
|
if (filter.isEmpty() || text.contains(filter, Qt::CaseInsensitive))
|
|
m_treeView->setRowHidden(ii, QModelIndex(), false);
|
|
else
|
|
m_treeView->setRowHidden(ii, QModelIndex(), true);
|
|
}
|
|
setUpdatesEnabled(true);
|
|
} |