1 /***************************************************************************
2 * Copyright (C) 2005-09 by the Quassel Project *
3 * devel@quassel-irc.org *
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. *
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. *
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 ***************************************************************************/
22 #include <QDialogButtonBox>
23 #include <QGridLayout>
26 #include <QInputDialog>
27 #include <QMessageBox>
28 #include <QPushButton>
30 #include "networkmodelcontroller.h"
32 #include "buffermodel.h"
33 #include "buffersettings.h"
34 #include "iconloader.h"
35 #include "clientidentity.h"
38 #include "clientignorelistmanager.h"
41 NetworkModelController::NetworkModelController(QObject *parent)
43 _actionCollection(new ActionCollection(this)),
48 connect(_actionCollection, SIGNAL(actionTriggered(QAction *)), SLOT(actionTriggered(QAction *)));
52 NetworkModelController::~NetworkModelController() {
56 Action * NetworkModelController::registerAction(ActionType type, const QString &text, bool checkable) {
57 return registerAction(type, QPixmap(), text, checkable);
60 Action * NetworkModelController::registerAction(ActionType type, const QPixmap &icon, const QString &text, bool checkable) {
63 act = new Action(text, this);
65 act = new Action(icon, text, this);
67 act->setCheckable(checkable);
70 _actionCollection->addAction(QString::number(type, 16), act);
71 _actionByType[type] = act;
75 /******** Helper Functions ***********************************************************************/
77 void NetworkModelController::setIndexList(const QModelIndex &index) {
78 _indexList = QList<QModelIndex>() << index;
81 void NetworkModelController::setIndexList(const QList<QModelIndex> &list) {
85 void NetworkModelController::setMessageFilter(MessageFilter *filter) {
86 _messageFilter = filter;
89 void NetworkModelController::setContextItem(const QString &contextItem) {
90 _contextItem = contextItem;
93 void NetworkModelController::setSlot(QObject *receiver, const char *method) {
98 bool NetworkModelController::checkRequirements(const QModelIndex &index, ItemActiveStates requiredActiveState) {
102 ItemActiveStates isActive = index.data(NetworkModel::ItemActiveRole).toBool()
106 if(!(isActive & requiredActiveState))
112 QString NetworkModelController::nickName(const QModelIndex &index) const {
113 IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
115 return ircUser->nick();
117 BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
118 if(!bufferInfo.isValid())
120 if(bufferInfo.type() != BufferInfo::QueryBuffer)
123 return bufferInfo.bufferName(); // FIXME this might break with merged queries maybe
126 BufferId NetworkModelController::findQueryBuffer(const QModelIndex &index, const QString &predefinedNick) const {
127 NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
128 if(!networkId.isValid())
131 QString nick = predefinedNick.isEmpty() ? nickName(index) : predefinedNick;
135 return findQueryBuffer(networkId, nick);
138 BufferId NetworkModelController::findQueryBuffer(NetworkId networkId, const QString &nick) const {
139 return Client::networkModel()->bufferId(networkId, nick);
142 void NetworkModelController::removeBuffers(const QModelIndexList &indexList) {
143 QList<BufferInfo> inactive;
144 foreach(QModelIndex index, indexList) {
145 BufferInfo info = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
147 if(info.type() == BufferInfo::QueryBuffer
148 || (info.type() == BufferInfo::ChannelBuffer && !index.data(NetworkModel::ItemActiveRole).toBool()))
153 if(inactive.count()) {
154 msg = tr("Do you want to delete the following buffer(s) permanently?", 0, inactive.count());
157 foreach(BufferInfo info, inactive) {
159 msg += QString("<li>%1</li>").arg(info.bufferName());
166 if(count > 9 && inactive.size() - count != 0)
167 msg += tr("...and <b>%1</b> more<br><br>").arg(inactive.size() - count);
168 msg += tr("<b>Note:</b> This will delete all related data, including all backlog data, from the core's database and cannot be undone.");
169 if(inactive.count() != indexList.count())
170 msg += tr("<br>Active channel buffers cannot be deleted, please part the channel first.");
172 if(QMessageBox::question(0, tr("Remove buffers permanently?"), msg, QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
173 foreach(BufferInfo info, inactive)
174 Client::removeBuffer(info.bufferId());
179 void NetworkModelController::handleExternalAction(ActionType type, QAction *action) {
181 if(receiver() && method()) {
182 if(!QMetaObject::invokeMethod(receiver(), method(), Q_ARG(QAction *, action)))
183 qWarning() << "NetworkModelActionController::handleExternalAction(): Could not invoke slot" << receiver() << method();
187 /******** Handle Actions *************************************************************************/
189 void NetworkModelController::actionTriggered(QAction *action) {
190 ActionType type = (ActionType)action->data().toInt();
192 if(type & NetworkMask)
193 handleNetworkAction(type, action);
194 else if(type & BufferMask)
195 handleBufferAction(type, action);
196 else if(type & HideMask)
197 handleHideAction(type, action);
198 else if(type & GeneralMask)
199 handleGeneralAction(type, action);
200 else if(type & NickMask)
201 handleNickAction(type, action);
202 else if(type & ExternalMask)
203 handleExternalAction(type, action);
205 qWarning() << "NetworkModelController::actionTriggered(): Unhandled action!";
209 void NetworkModelController::handleNetworkAction(ActionType type, QAction *) {
210 if(type == NetworkConnectAll || type == NetworkDisconnectAll) {
211 foreach(NetworkId id, Client::networkIds()) {
212 const Network *net = Client::network(id);
213 if(type == NetworkConnectAll && net->connectionState() == Network::Disconnected)
214 net->requestConnect();
215 if(type == NetworkDisconnectAll && net->connectionState() != Network::Disconnected)
216 net->requestDisconnect();
221 if(!indexList().count())
224 const Network *network = Client::network(indexList().at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>());
225 Q_CHECK_PTR(network);
231 network->requestConnect();
233 case NetworkDisconnect:
234 network->requestDisconnect();
241 void NetworkModelController::handleBufferAction(ActionType type, QAction *) {
242 if(type == BufferRemove) {
243 removeBuffers(indexList());
246 QList<BufferInfo> bufferList; // create temp list because model indexes might change
247 foreach(QModelIndex index, indexList()) {
248 BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
249 if(bufferInfo.isValid())
250 bufferList << bufferInfo;
253 foreach(BufferInfo bufferInfo, bufferList) {
256 Client::userInput(bufferInfo, QString("/JOIN %1").arg(bufferInfo.bufferName()));
260 QString reason = Client::identity(Client::network(bufferInfo.networkId())->identity())->partReason();
261 Client::userInput(bufferInfo, QString("/PART %1").arg(reason));
265 Client::bufferModel()->switchToBuffer(bufferInfo.bufferId());
274 void NetworkModelController::handleHideAction(ActionType type, QAction *action) {
278 if(NetworkModelController::action(HideJoin)->isChecked())
279 filter |= Message::Join | Message::NetsplitJoin;
280 if(NetworkModelController::action(HidePart)->isChecked())
281 filter |= Message::Part;
282 if(NetworkModelController::action(HideQuit)->isChecked())
283 filter |= Message::Quit | Message::NetsplitQuit;
284 if(NetworkModelController::action(HideNick)->isChecked())
285 filter |= Message::Nick;
286 if(NetworkModelController::action(HideMode)->isChecked())
287 filter |= Message::Mode;
288 if(NetworkModelController::action(HideDayChange)->isChecked())
289 filter |= Message::DayChange;
290 if(NetworkModelController::action(HideTopic)->isChecked())
291 filter |= Message::Topic;
302 BufferSettings(_messageFilter->idString()).setMessageFilter(filter);
304 foreach(QModelIndex index, _indexList) {
305 BufferId bufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
306 if(!bufferId.isValid())
308 BufferSettings(bufferId).setMessageFilter(filter);
313 BufferSettings().setMessageFilter(filter);
314 case HideUseDefaults:
316 BufferSettings(_messageFilter->idString()).removeFilter();
318 foreach(QModelIndex index, _indexList) {
319 BufferId bufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
320 if(!bufferId.isValid())
322 BufferSettings(bufferId).removeFilter();
331 void NetworkModelController::handleGeneralAction(ActionType type, QAction *action) {
334 if(!indexList().count())
336 NetworkId networkId = indexList().at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>();
340 QString channelName = contextItem();
341 QString channelPassword;
342 if(channelName.isEmpty()) {
343 JoinDlg dlg(indexList().first());
344 if(dlg.exec() == QDialog::Accepted) {
345 channelName = dlg.channelName();
346 networkId = dlg.networkId();
347 channelPassword = dlg.channelPassword();
350 if(!channelName.isEmpty()) {
351 if(!channelPassword.isEmpty())
352 Client::instance()->userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1 %2").arg(channelName).arg(channelPassword));
354 Client::instance()->userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(channelName));
358 case ShowChannelList:
359 if(networkId.isValid())
360 emit showChannelList(networkId);
363 if(networkId.isValid())
364 emit showIgnoreList(QString());
371 void NetworkModelController::handleNickAction(ActionType type, QAction *action) {
372 foreach(QModelIndex index, indexList()) {
373 NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
374 if(!networkId.isValid())
376 QString nick = nickName(index);
379 BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
380 if(!bufferInfo.isValid())
385 Client::userInput(bufferInfo, QString("/WHOIS %1 %1").arg(nick));
387 case NickCtcpVersion:
388 Client::userInput(bufferInfo, QString("/CTCP %1 VERSION").arg(nick));
391 Client::userInput(bufferInfo, QString("/CTCP %1 PING").arg(nick));
394 Client::userInput(bufferInfo, QString("/CTCP %1 TIME").arg(nick));
396 case NickCtcpClientinfo:
397 Client::userInput(bufferInfo, QString("/CTCP %1 CLIENTINFO").arg(nick));
400 Client::userInput(bufferInfo, QString("/OP %1").arg(nick));
403 Client::userInput(bufferInfo, QString("/DEOP %1").arg(nick));
406 Client::userInput(bufferInfo, QString("/VOICE %1").arg(nick));
409 Client::userInput(bufferInfo, QString("/DEVOICE %1").arg(nick));
412 Client::userInput(bufferInfo, QString("/KICK %1").arg(nick));
415 Client::userInput(bufferInfo, QString("/BAN %1").arg(nick));
418 Client::userInput(bufferInfo, QString("/BAN %1").arg(nick));
419 Client::userInput(bufferInfo, QString("/KICK %1").arg(nick));
423 Client::bufferModel()->switchToOrStartQuery(networkId, nick);
427 IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
430 Client::ignoreListManager()->requestAddIgnoreListItem(IgnoreListManager::SenderIgnore,
431 action->property("ignoreRule").toString(),
432 false, IgnoreListManager::SoftStrictness,
433 IgnoreListManager::NetworkScope,
434 ircUser->network()->networkName(), true);
439 IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
442 Client::ignoreListManager()->requestAddIgnoreListItem(IgnoreListManager::SenderIgnore,
443 action->property("ignoreRule").toString(),
444 false, IgnoreListManager::SoftStrictness,
445 IgnoreListManager::NetworkScope,
446 ircUser->network()->networkName(), true);
449 case NickIgnoreDomain:
451 IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
454 Client::ignoreListManager()->requestAddIgnoreListItem(IgnoreListManager::SenderIgnore,
455 action->property("ignoreRule").toString(),
456 false, IgnoreListManager::SoftStrictness,
457 IgnoreListManager::NetworkScope,
458 ircUser->network()->networkName(), true);
461 case NickIgnoreCustom:
462 // forward that to mainwin since we can access the settingspage only from there
463 emit showIgnoreList(action->property("ignoreRule").toString());
465 case NickIgnoreToggleEnabled0:
466 case NickIgnoreToggleEnabled1:
467 case NickIgnoreToggleEnabled2:
468 case NickIgnoreToggleEnabled3:
469 case NickIgnoreToggleEnabled4:
470 Client::ignoreListManager()->requestToggleIgnoreRule(action->property("ignoreRule").toString());
473 qWarning() << "Unhandled nick action";
478 /***************************************************************************************************************
480 ***************************************************************************************************************/
482 NetworkModelController::JoinDlg::JoinDlg(const QModelIndex &index, QWidget *parent) : QDialog(parent) {
483 setWindowIcon(SmallIcon("irc-join-channel"));
484 setWindowTitle(tr("Join Channel"));
486 QGridLayout *layout = new QGridLayout(this);
487 layout->addWidget(new QLabel(tr("Network:")), 0, 0);
488 layout->addWidget(networks = new QComboBox, 0, 1);
489 layout->addWidget(new QLabel(tr("Channel:")), 1, 0);
490 layout->addWidget(channel = new QLineEdit, 1, 1);
491 layout->addWidget(new QLabel(tr("Password:")), 2, 0);
492 layout->addWidget(password = new QLineEdit, 2, 1);
493 layout->addWidget(buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel), 3, 0, 1, 2);
497 buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
498 networks->setInsertPolicy(QComboBox::InsertAlphabetically);
499 password->setEchoMode(QLineEdit::Password);
501 connect(buttonBox, SIGNAL(accepted()), SLOT(accept()));
502 connect(buttonBox, SIGNAL(rejected()), SLOT(reject()));
503 connect(channel, SIGNAL(textChanged(QString)), SLOT(on_channel_textChanged(QString)));
505 foreach(NetworkId id, Client::networkIds()) {
506 const Network *net = Client::network(id);
507 if(net->isConnected()) {
508 networks->addItem(net->networkName(), QVariant::fromValue<NetworkId>(id));
512 if(index.isValid()) {
513 NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
514 if(networkId.isValid()) {
515 networks->setCurrentIndex(networks->findText(Client::network(networkId)->networkName()));
516 if(index.data(NetworkModel::BufferTypeRole) == BufferInfo::ChannelBuffer
517 && !index.data(NetworkModel::ItemActiveRole).toBool())
518 channel->setText(index.data(Qt::DisplayRole).toString());
523 NetworkId NetworkModelController::JoinDlg::networkId() const {
524 return networks->itemData(networks->currentIndex()).value<NetworkId>();
527 QString NetworkModelController::JoinDlg::channelName() const {
528 return channel->text();
531 QString NetworkModelController::JoinDlg::channelPassword() const {
532 return password->text();
535 void NetworkModelController::JoinDlg::on_channel_textChanged(const QString &text) {
536 buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());