588673c20c2400937025685ab92312478b8e7892
[quassel.git] / src / qtui / settingspages / aliasesmodel.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-08 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  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "aliasesmodel.h"
22
23 #include <QDebug>
24 #include <QStringList>
25
26 #include "client.h"
27 #include "signalproxy.h"
28
29 AliasesModel::AliasesModel(QObject *parent)
30   : QAbstractItemModel(parent),
31     _configChanged(false)
32 {
33 //   _aliasManager.addAlias("a", "aa");
34 //   _aliasManager.addAlias("b", "bb");
35 //   _aliasManager.addAlias("c", "cc");
36 //   _aliasManager.addAlias("d", "dd");
37
38   // we need this signal for future connects to reset the data;
39   connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected()));
40   if(Client::isConnected())
41     clientConnected();
42 }
43
44 QVariant AliasesModel::data(const QModelIndex &index, int role) const {
45   if(!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount())
46     return QVariant();
47
48   switch(role) {
49   case Qt::ToolTipRole:
50     switch(index.column()) {
51     case 0:
52       return "<b>The shortcut for the alias</b><br />"
53         "It can be used as a regular slash command.<br /><br />"
54         "<b>Example:</b> \"foo\" can be used per /foo";
55     case 1:
56       return "<b>The string the shortcut will be expanded to</b><br />"
57         "$i represenents the i'th parameter. $0 the whole string.<br />"
58         "Multiple commands can be separated with semicolons<br /><br />"
59         "<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";
60     default:
61       return QVariant();
62     }
63   case Qt::DisplayRole:
64     switch(index.column()) {
65     case 0:
66       return aliasManager()[index.row()].name;
67     case 1:
68       return aliasManager()[index.row()].expansion;
69     default:
70       return QVariant();
71     }
72   default:
73     return QVariant();
74   }
75 }
76
77 bool AliasesModel::setData(const QModelIndex &index, const QVariant &value, int role) {
78   if(!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount() || role != Qt::EditRole)
79     return false;
80
81   QString newValue = value.toString();
82   if(newValue.isEmpty())
83     return false;
84   
85   switch(index.column()) {
86   case 0:
87     if(aliasManager().contains(newValue)) {
88       return false;
89     } else {
90       cloneAliasManager()[index.row()].name = newValue;
91       return true;
92     }
93   case 1:
94     cloneAliasManager()[index.row()].expansion = newValue;
95     return true;
96   default:
97     return false;
98   }
99 }
100
101 void AliasesModel::newAlias() {
102   QString newName("alias");
103   int i = 0;
104   AliasManager &manager = cloneAliasManager();
105   while(manager.contains(newName)) {
106     i++;
107     newName = QString("alias%1").arg(i);
108   }
109   beginInsertRows(QModelIndex(), rowCount(), rowCount());
110   manager.addAlias(newName, "Expansion");
111   endInsertRows();
112 }
113
114 void AliasesModel::removeAlias(int index) {
115   if(index < 0 || index >= rowCount())
116     return;
117
118   AliasManager &manager = cloneAliasManager();  
119   beginRemoveRows(QModelIndex(), index, index);
120   manager.removeAt(index);
121   endRemoveRows();
122 }
123
124 Qt::ItemFlags AliasesModel::flags(const QModelIndex &index) const {
125   if(!index.isValid()) {
126     return Qt::ItemIsDropEnabled;
127   } else {
128     return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
129   }
130 }
131
132
133 QVariant AliasesModel::headerData(int section, Qt::Orientation orientation, int role) const {
134   QStringList header;
135   header << tr("Alias")
136          << tr("Expansion");
137   
138   if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
139     return header[section];
140
141   return QVariant();
142 }
143
144 QModelIndex AliasesModel::index(int row, int column, const QModelIndex &parent) const {
145   Q_UNUSED(parent);
146   if(row >= rowCount() || column >= columnCount())
147     return QModelIndex();
148
149   return createIndex(row, column);
150 }
151
152
153 const AliasManager &AliasesModel::aliasManager() const {
154   if(_configChanged)
155     return _clonedAliasManager;
156   else
157     return _aliasManager;
158 }
159
160 AliasManager &AliasesModel::aliasManager() {
161   if(_configChanged)
162     return _clonedAliasManager;
163   else
164     return _aliasManager;
165 }
166
167 AliasManager &AliasesModel::cloneAliasManager() {
168   if(!_configChanged) {
169     _clonedAliasManager = _aliasManager;
170     _configChanged = true;
171     emit configChanged(true);
172   }
173   return _clonedAliasManager;
174 }
175
176 void AliasesModel::revert() {
177   if(!_configChanged)
178     return;
179   
180   _configChanged = false;
181   emit configChanged(false);
182   reset();
183 }
184
185 void AliasesModel::commit() {
186   if(!_configChanged)
187     return;
188
189   _aliasManager.requestUpdate(_clonedAliasManager.toVariantMap());
190   revert();
191 }  
192
193 void AliasesModel::initDone() {
194   reset();
195   emit modelReady();
196 }
197
198 void AliasesModel::clientConnected() {
199   _aliasManager = AliasManager();
200   Client::signalProxy()->synchronize(&_aliasManager);
201   connect(&_aliasManager, SIGNAL(initDone()), this, SLOT(initDone()));
202   connect(&_aliasManager, SIGNAL(updated(const QVariantMap &)), this, SLOT(revert()));
203 }