X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fsettingspages%2Faliasesmodel.cpp;h=780b152a672edd40f0d888d3a202ca292536d41b;hp=c36bebdd99f97064172e37b26e2ac3a77f0910b1;hb=673ded0d543cbdc2cf6e746b6bee7c1d21af8f90;hpb=39eb2fda3eaef2de78a8134556015ff86e9b85d4 diff --git a/src/qtui/settingspages/aliasesmodel.cpp b/src/qtui/settingspages/aliasesmodel.cpp index c36bebdd..780b152a 100644 --- a/src/qtui/settingspages/aliasesmodel.cpp +++ b/src/qtui/settingspages/aliasesmodel.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * + * Copyright (C) 2005-2020 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "aliasesmodel.h" @@ -26,223 +26,284 @@ #include "client.h" #include "signalproxy.h" -AliasesModel::AliasesModel(QObject *parent) - : QAbstractItemModel(parent), - _configChanged(false), - _modelReady(false) +AliasesModel::AliasesModel(QObject* parent) + : QAbstractItemModel(parent) { - // we need this signal for future connects to reset the data; - connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected())); - connect(Client::instance(), SIGNAL(disconnected()), this, SLOT(clientDisconnected())); + // we need this signal for future connects to reset the data; + connect(Client::instance(), &Client::connected, this, &AliasesModel::clientConnected); + connect(Client::instance(), &Client::disconnected, this, &AliasesModel::clientDisconnected); + + if (Client::isConnected()) + clientConnected(); + else + emit modelReady(false); +} - if(Client::isConnected()) - clientConnected(); - else - emit modelReady(false); +QVariant AliasesModel::data(const QModelIndex& index, int role) const +{ + if (!_modelReady) + return QVariant(); + + if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount()) + return QVariant(); + + switch (role) { + case Qt::ToolTipRole: + switch (index.column()) { + case 0: + return tr("The shortcut for the alias
" + "It can be used as a regular slash command.

" + "Example: \"foo\" can be used per /foo"); + case 1: { + // To avoid overwhelming the user, organize things into a table + QString strTooltip; + QTextStream tooltip(&strTooltip, QIODevice::WriteOnly); + tooltip << ""; + + // Function to add a row to the tooltip table + auto addRow = [&](const QString& key, const QString& value = QString(), bool condition = true) { + if (condition) { + if (value.isEmpty()) { + tooltip << "" << key << ""; + } + else { + tooltip << "" << key << "" << value << ""; + } + } + }; + + tooltip << "

" << tr("The string the shortcut will be expanded to") << "

"; + + tooltip << "

" << tr("Special variables") << "

"; + + // Variable option table + tooltip << ""; + + // Parameter variables + addRow(tr("Parameter variables")); + addRow("$i", tr("i'th parameter")); + addRow("$i..j", tr("i'th to j'th parameter separated by spaces")); + addRow("$i..", tr("all parameters from i on separated by spaces")); + + // IrcUser handling + addRow(tr("Nickname parameter variables")); + addRow("$i:account", + tr("account of user identified by i'th parameter, or a '*' if logged out or " + "unknown")); + addRow("$i:hostname", tr("hostname of user identified by i'th parameter, or a '*' if unknown")); + addRow("$i:ident", tr("ident of user identified by i'th parameter, or a '*' if unknown")); + addRow("$i:identd", + tr("ident of user identified by i'th parameter if verified, or a '*' if unknown " + "or unverified (prefixed with '~')")); + + // General variables + addRow(tr("General variables")); + addRow("$0", tr("the whole string")); + addRow("$nick", tr("your current nickname")); + addRow("$channel", tr("the name of the selected channel")); + + // End table + tooltip << "
"; + + // Example header + tooltip << "

" << tr("Multiple commands can be separated with semicolons") << "

"; + // Example + tooltip << "

"; + tooltip << QString("

%1 %2
").arg(tr("Example:"), tr("\"Test $1; Test $2; Test All $0\"")); + tooltip << tr("...will be expanded to three separate messages \"Test 1\", \"Test 2\" " + "and \"Test All 1 2 3\" when called like /test 1 2 3") + << "

"; + + // End tooltip + tooltip << "
"; + return strTooltip; + } + default: + return QVariant(); + } + case Qt::DisplayRole: + case Qt::EditRole: + switch (index.column()) { + case 0: + return aliasManager()[index.row()].name; + case 1: + return aliasManager()[index.row()].expansion; + default: + return QVariant(); + } + default: + return QVariant(); + } } -QVariant AliasesModel::data(const QModelIndex &index, int role) const { - if(!_modelReady) - return QVariant(); +bool AliasesModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + if (!_modelReady) + return false; - if(!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount()) - return QVariant(); + if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount() || role != Qt::EditRole) + return false; - switch(role) { - case Qt::ToolTipRole: - switch(index.column()) { - case 0: - return "The shortcut for the alias
" - "It can be used as a regular slash command.

" - "Example: \"foo\" can be used per /foo"; - case 1: - return "The string the shortcut will be expanded to
" - "special variables:
" - " - $i represents the i'th parameter.
" - " - $i..j represents the i'th to j'th parameter separated by spaces.
" - " - $i.. represents all parameters from i on separated by spaces.
" - " - $i:hostname represents the hostname of the user identified by the i'th parameter or a * if unknown.
" - " - $0 the whole string.
" - " - $nick your current nickname
" - " - $channel the name of the selected channel

" - "Multiple commands can be separated with semicolons

" - "Example: \"Test $1; Test $2; Test All $0\" will be expanded to three separate messages \"Test 1\", \"Test 2\" and \"Test All 1 2 3\" when called like /test 1 2 3"; - default: - return QVariant(); - } - case Qt::DisplayRole: - case Qt::EditRole: - switch(index.column()) { + QString newValue = value.toString(); + if (newValue.isEmpty()) + return false; + + switch (index.column()) { case 0: - return aliasManager()[index.row()].name; + if (aliasManager().contains(newValue)) { + return false; + } + else { + cloneAliasManager()[index.row()].name = newValue; + return true; + } case 1: - return aliasManager()[index.row()].expansion; + cloneAliasManager()[index.row()].expansion = newValue; + return true; default: - return QVariant(); + return false; } - default: - return QVariant(); - } } -bool AliasesModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if(!_modelReady) - return false; +void AliasesModel::newAlias() +{ + QString newName("alias"); + int i = 0; + AliasManager& manager = cloneAliasManager(); + while (manager.contains(newName)) { + i++; + newName = QString("alias%1").arg(i); + } + beginInsertRows(QModelIndex(), rowCount(), rowCount()); + manager.addAlias(newName, "Expansion"); + endInsertRows(); +} - if(!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount() || role != Qt::EditRole) - return false; +void AliasesModel::loadDefaults() +{ + if (!_modelReady) + return; - QString newValue = value.toString(); - if(newValue.isEmpty()) - return false; + AliasManager& manager = cloneAliasManager(); - switch(index.column()) { - case 0: - if(aliasManager().contains(newValue)) { - return false; - } else { - cloneAliasManager()[index.row()].name = newValue; - return true; + if (!manager.isEmpty()) { + beginRemoveRows(QModelIndex(), 0, rowCount() - 1); + for (int i = rowCount() - 1; i >= 0; i--) + manager.removeAt(i); + endRemoveRows(); } - case 1: - cloneAliasManager()[index.row()].expansion = newValue; - return true; - default: - return false; - } -} - -void AliasesModel::newAlias() { - QString newName("alias"); - int i = 0; - AliasManager &manager = cloneAliasManager(); - while(manager.contains(newName)) { - i++; - newName = QString("alias%1").arg(i); - } - beginInsertRows(QModelIndex(), rowCount(), rowCount()); - manager.addAlias(newName, "Expansion"); - endInsertRows(); -} - -void AliasesModel::loadDefaults() { - if(!_modelReady) - return; - - AliasManager &manager = cloneAliasManager(); - - if(!manager.isEmpty()) { - beginRemoveRows(QModelIndex(), 0, rowCount() - 1); - for(int i = rowCount() - 1; i >= 0; i--) - manager.removeAt(i); - endRemoveRows(); - } - AliasManager::AliasList defaults = AliasManager::defaults(); - beginInsertRows(QModelIndex(), 0, defaults.count() - 1); - foreach(AliasManager::Alias alias, defaults) { - manager.addAlias(alias.name, alias.expansion); - } - endInsertRows(); + AliasManager::AliasList defaults = AliasManager::defaults(); + beginInsertRows(QModelIndex(), 0, defaults.count() - 1); + foreach (AliasManager::Alias alias, defaults) { + manager.addAlias(alias.name, alias.expansion); + } + endInsertRows(); } -void AliasesModel::removeAlias(int index) { - if(index < 0 || index >= rowCount()) - return; +void AliasesModel::removeAlias(int index) +{ + if (index < 0 || index >= rowCount()) + return; - AliasManager &manager = cloneAliasManager(); - beginRemoveRows(QModelIndex(), index, index); - manager.removeAt(index); - endRemoveRows(); + AliasManager& manager = cloneAliasManager(); + beginRemoveRows(QModelIndex(), index, index); + manager.removeAt(index); + endRemoveRows(); } -Qt::ItemFlags AliasesModel::flags(const QModelIndex &index) const { - if(!index.isValid()) { - return Qt::ItemIsDropEnabled; - } else { - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; - } +Qt::ItemFlags AliasesModel::flags(const QModelIndex& index) const +{ + if (!index.isValid()) { + return Qt::ItemIsDropEnabled; + } + else { + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; + } } +QVariant AliasesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + QStringList header; + header << tr("Alias") << tr("Expansion"); -QVariant AliasesModel::headerData(int section, Qt::Orientation orientation, int role) const { - QStringList header; - header << tr("Alias") - << tr("Expansion"); - - if(orientation == Qt::Horizontal && role == Qt::DisplayRole) - return header[section]; + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return header[section]; - return QVariant(); + return QVariant(); } -QModelIndex AliasesModel::index(int row, int column, const QModelIndex &parent) const { - Q_UNUSED(parent); - if(row >= rowCount() || column >= columnCount()) - return QModelIndex(); +QModelIndex AliasesModel::index(int row, int column, const QModelIndex& parent) const +{ + Q_UNUSED(parent); + if (row >= rowCount() || column >= columnCount()) + return {}; - return createIndex(row, column); + return createIndex(row, column); } - -const AliasManager &AliasesModel::aliasManager() const { - if(_configChanged) - return _clonedAliasManager; - else - return *Client::aliasManager(); +const AliasManager& AliasesModel::aliasManager() const +{ + return _clonedAliasManager ? *_clonedAliasManager : *Client::aliasManager(); } -AliasManager &AliasesModel::aliasManager() { - if(_configChanged) - return _clonedAliasManager; - else - return *Client::aliasManager(); +AliasManager& AliasesModel::aliasManager() +{ + return _clonedAliasManager ? *_clonedAliasManager : *Client::aliasManager(); } -AliasManager &AliasesModel::cloneAliasManager() { - if(!_configChanged) { - _clonedAliasManager = *Client::aliasManager(); - _configChanged = true; - emit configChanged(true); - } - return _clonedAliasManager; +AliasManager& AliasesModel::cloneAliasManager() +{ + if (!_clonedAliasManager) { + _clonedAliasManager = std::make_unique(); + _clonedAliasManager->fromVariantMap(Client::aliasManager()->toVariantMap()); + emit configChanged(true); + } + return *_clonedAliasManager; } -void AliasesModel::revert() { - if(!_configChanged) - return; +void AliasesModel::revert() +{ + if (!_clonedAliasManager) + return; - _configChanged = false; - emit configChanged(false); - reset(); + beginResetModel(); + _clonedAliasManager.reset(); + endResetModel(); + emit configChanged(false); } -void AliasesModel::commit() { - if(!_configChanged) - return; +void AliasesModel::commit() +{ + if (!_clonedAliasManager) + return; - Client::aliasManager()->requestUpdate(_clonedAliasManager.toVariantMap()); - revert(); + Client::aliasManager()->requestUpdate(_clonedAliasManager->toVariantMap()); + revert(); } -void AliasesModel::initDone() { - _modelReady = true; - reset(); - emit modelReady(true); +void AliasesModel::initDone() +{ + _modelReady = true; + beginResetModel(); + endResetModel(); + emit modelReady(true); } -void AliasesModel::clientConnected() { - connect(Client::aliasManager(), SIGNAL(updated()), SLOT(revert())); - if(Client::aliasManager()->isInitialized()) - initDone(); - else - connect(Client::aliasManager(), SIGNAL(initDone()), SLOT(initDone())); +void AliasesModel::clientConnected() +{ + connect(Client::aliasManager(), &AliasManager::updated, this, &AliasesModel::revert); + if (Client::aliasManager()->isInitialized()) + initDone(); + else + connect(Client::aliasManager(), &SyncableObject::initDone, this, &AliasesModel::initDone); } -void AliasesModel::clientDisconnected() { - // clear - _clonedAliasManager = ClientAliasManager(); - _modelReady = false; - reset(); - emit modelReady(false); +void AliasesModel::clientDisconnected() +{ + _modelReady = false; + beginResetModel(); + _clonedAliasManager.reset(); + endResetModel(); + emit modelReady(false); }