Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
aliasesmodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 by the Quassel Project *
3  * devel@quassel-irc.org *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) version 3. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 #include "aliasesmodel.h"
22 
23 #include <QDebug>
24 #include <QStringList>
25 
26 #include "client.h"
27 #include "signalproxy.h"
28 
30  : QAbstractItemModel(parent),
31  _configChanged(false),
32  _modelReady(false)
33 {
34  // we need this signal for future connects to reset the data;
35  connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected()));
36  connect(Client::instance(), SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
37 
38  if (Client::isConnected())
40  else
41  emit modelReady(false);
42 }
43 
44 
45 QVariant AliasesModel::data(const QModelIndex &index, int role) const
46 {
47  if (!_modelReady)
48  return QVariant();
49 
50  if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount())
51  return QVariant();
52 
53  switch (role) {
54  case Qt::ToolTipRole:
55  switch (index.column()) {
56  case 0:
57  return tr("<b>The shortcut for the alias</b><br />"
58  "It can be used as a regular slash command.<br /><br />"
59  "<b>Example:</b> \"foo\" can be used per /foo");
60  case 1:
61  return tr("<b>The string the shortcut will be expanded to</b><br />"
62  "<b>special variables:</b><br />"
63  " - <b>$i</b> represents the i'th parameter.<br />"
64  " - <b>$i..j</b> represents the i'th to j'th parameter separated by spaces.<br />"
65  " - <b>$i..</b> represents all parameters from i on separated by spaces.<br />"
66  " - <b>$i:hostname</b> represents the hostname of the user identified by the i'th parameter or a * if unknown.<br />"
67  " - <b>$0</b> the whole string.<br />"
68  " - <b>$nick</b> your current nickname<br />"
69  " - <b>$channel</b> the name of the selected channel<br /><br />"
70  "Multiple commands can be separated with semicolons<br /><br />"
71  "<b>Example:</b> \"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");
72  default:
73  return QVariant();
74  }
75  case Qt::DisplayRole:
76  case Qt::EditRole:
77  switch (index.column()) {
78  case 0:
79  return aliasManager()[index.row()].name;
80  case 1:
81  return aliasManager()[index.row()].expansion;
82  default:
83  return QVariant();
84  }
85  default:
86  return QVariant();
87  }
88 }
89 
90 
91 bool AliasesModel::setData(const QModelIndex &index, const QVariant &value, int role)
92 {
93  if (!_modelReady)
94  return false;
95 
96  if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount() || role != Qt::EditRole)
97  return false;
98 
99  QString newValue = value.toString();
100  if (newValue.isEmpty())
101  return false;
102 
103  switch (index.column()) {
104  case 0:
105  if (aliasManager().contains(newValue)) {
106  return false;
107  }
108  else {
109  cloneAliasManager()[index.row()].name = newValue;
110  return true;
111  }
112  case 1:
113  cloneAliasManager()[index.row()].expansion = newValue;
114  return true;
115  default:
116  return false;
117  }
118 }
119 
120 
122 {
123  QString newName("alias");
124  int i = 0;
125  AliasManager &manager = cloneAliasManager();
126  while (manager.contains(newName)) {
127  i++;
128  newName = QString("alias%1").arg(i);
129  }
130  beginInsertRows(QModelIndex(), rowCount(), rowCount());
131  manager.addAlias(newName, "Expansion");
132  endInsertRows();
133 }
134 
135 
137 {
138  if (!_modelReady)
139  return;
140 
141  AliasManager &manager = cloneAliasManager();
142 
143  if (!manager.isEmpty()) {
144  beginRemoveRows(QModelIndex(), 0, rowCount() - 1);
145  for (int i = rowCount() - 1; i >= 0; i--)
146  manager.removeAt(i);
147  endRemoveRows();
148  }
149 
151  beginInsertRows(QModelIndex(), 0, defaults.count() - 1);
152  foreach(AliasManager::Alias alias, defaults) {
153  manager.addAlias(alias.name, alias.expansion);
154  }
155  endInsertRows();
156 }
157 
158 
160 {
161  if (index < 0 || index >= rowCount())
162  return;
163 
164  AliasManager &manager = cloneAliasManager();
165  beginRemoveRows(QModelIndex(), index, index);
166  manager.removeAt(index);
167  endRemoveRows();
168 }
169 
170 
171 Qt::ItemFlags AliasesModel::flags(const QModelIndex &index) const
172 {
173  if (!index.isValid()) {
174  return Qt::ItemIsDropEnabled;
175  }
176  else {
177  return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
178  }
179 }
180 
181 
182 QVariant AliasesModel::headerData(int section, Qt::Orientation orientation, int role) const
183 {
184  QStringList header;
185  header << tr("Alias")
186  << tr("Expansion");
187 
188  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
189  return header[section];
190 
191  return QVariant();
192 }
193 
194 
195 QModelIndex AliasesModel::index(int row, int column, const QModelIndex &parent) const
196 {
197  Q_UNUSED(parent);
198  if (row >= rowCount() || column >= columnCount())
199  return QModelIndex();
200 
201  return createIndex(row, column);
202 }
203 
204 
206 {
207  if (_configChanged)
208  return _clonedAliasManager;
209  else
210  return *Client::aliasManager();
211 }
212 
213 
215 {
216  if (_configChanged)
217  return _clonedAliasManager;
218  else
219  return *Client::aliasManager();
220 }
221 
222 
224 {
225  if (!_configChanged) {
227  _configChanged = true;
228  emit configChanged(true);
229  }
230  return _clonedAliasManager;
231 }
232 
233 
235 {
236  if (!_configChanged)
237  return;
238 
239  _configChanged = false;
240  emit configChanged(false);
241  beginResetModel();
242  endResetModel();
243 }
244 
245 
247 {
248  if (!_configChanged)
249  return;
250 
252  revert();
253 }
254 
255 
257 {
258  _modelReady = true;
259  beginResetModel();
260  endResetModel();
261  emit modelReady(true);
262 }
263 
264 
266 {
267  connect(Client::aliasManager(), SIGNAL(updated()), SLOT(revert()));
268  if (Client::aliasManager()->isInitialized())
269  initDone();
270  else
271  connect(Client::aliasManager(), SIGNAL(initDone()), SLOT(initDone()));
272 }
273 
274 
276 {
277  // clear
279  _modelReady = false;
280  beginResetModel();
281  endResetModel();
282  emit modelReady(false);
283 }