Add halfop support
[quassel.git] / src / uisupport / networkmodelcontroller.cpp
index 3d56b1a..ac2ab66 100644 (file)
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <QGridLayout>
+#include <QLabel>
+#include <QLineEdit>
 #include <QInputDialog>
 #include <QMessageBox>
+#include <QPushButton>
 
 #include "networkmodelcontroller.h"
 
@@ -29,6 +35,8 @@
 #include "clientidentity.h"
 #include "network.h"
 #include "util.h"
+#include "clientignorelistmanager.h"
+#include "client.h"
 
 NetworkModelController::NetworkModelController(QObject *parent)
 : QObject(parent),
@@ -45,11 +53,11 @@ NetworkModelController::~NetworkModelController() {
 
 }
 
-void NetworkModelController::registerAction(ActionType type, const QString &text, bool checkable) {
-  registerAction(type, QPixmap(), text, checkable);
+Action * NetworkModelController::registerAction(ActionType type, const QString &text, bool checkable) {
+  return registerAction(type, QPixmap(), text, checkable);
 }
 
-void NetworkModelController::registerAction(ActionType type, const QPixmap &icon, const QString &text, bool checkable) {
+Action * NetworkModelController::registerAction(ActionType type, const QPixmap &icon, const QString &text, bool checkable) {
   Action *act;
   if(icon.isNull())
     act = new Action(text, this);
@@ -61,6 +69,7 @@ void NetworkModelController::registerAction(ActionType type, const QPixmap &icon
 
   _actionCollection->addAction(QString::number(type, 16), act);
   _actionByType[type] = act;
+  return act;
 }
 
 /******** Helper Functions ***********************************************************************/
@@ -108,7 +117,7 @@ QString NetworkModelController::nickName(const QModelIndex &index) const {
   BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
   if(!bufferInfo.isValid())
     return QString();
-  if(!bufferInfo.type() == BufferInfo::QueryBuffer)
+  if(bufferInfo.type() != BufferInfo::QueryBuffer)
     return QString();
 
   return bufferInfo.bufferName(); // FIXME this might break with merged queries maybe
@@ -144,9 +153,18 @@ void NetworkModelController::removeBuffers(const QModelIndexList &indexList) {
   if(inactive.count()) {
     msg = tr("Do you want to delete the following buffer(s) permanently?", 0, inactive.count());
     msg += "<ul>";
-    foreach(BufferInfo info, inactive)
-      msg += QString("<li>%1</li>").arg(info.bufferName());
+    int count = 0;
+    foreach(BufferInfo info, inactive) {
+      if(count < 10) {
+       msg += QString("<li>%1</li>").arg(info.bufferName());
+       count++;
+      }
+      else
+       break;
+    }
     msg += "</ul>";
+    if(count > 9 && inactive.size() - count != 0)
+      msg += tr("...and <b>%1</b> more<br><br>").arg(inactive.size() - count);
     msg += tr("<b>Note:</b> This will delete all related data, including all backlog data, from the core's database and cannot be undone.");
     if(inactive.count() != indexList.count())
       msg += tr("<br>Active channel buffers cannot be deleted, please part the channel first.");
@@ -189,8 +207,20 @@ void NetworkModelController::actionTriggered(QAction *action) {
 }
 
 void NetworkModelController::handleNetworkAction(ActionType type, QAction *) {
+  if(type == NetworkConnectAll || type == NetworkDisconnectAll) {
+    foreach(NetworkId id, Client::networkIds()) {
+      const Network *net = Client::network(id);
+      if(type == NetworkConnectAll && net->connectionState() == Network::Disconnected)
+        net->requestConnect();
+      if(type == NetworkDisconnectAll && net->connectionState() != Network::Disconnected)
+        net->requestDisconnect();
+    }
+    return;
+  }
+
   if(!indexList().count())
     return;
+
   const Network *network = Client::network(indexList().at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>());
   Q_CHECK_PTR(network);
   if(!network)
@@ -213,11 +243,14 @@ void NetworkModelController::handleBufferAction(ActionType type, QAction *) {
     removeBuffers(indexList());
   } else {
 
+    QList<BufferInfo> bufferList; // create temp list because model indexes might change
     foreach(QModelIndex index, indexList()) {
       BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
-      if(!bufferInfo.isValid())
-        continue;
+      if(bufferInfo.isValid())
+        bufferList << bufferInfo;
+    }
 
+    foreach(BufferInfo bufferInfo, bufferList) {
       switch(type) {
         case BufferJoin:
           Client::userInput(bufferInfo, QString("/JOIN %1").arg(bufferInfo.bufferName()));
@@ -243,17 +276,19 @@ void NetworkModelController::handleHideAction(ActionType type, QAction *action)
 
   int filter = 0;
   if(NetworkModelController::action(HideJoin)->isChecked())
-    filter |= Message::Join;
+    filter |= Message::Join | Message::NetsplitJoin;
   if(NetworkModelController::action(HidePart)->isChecked())
     filter |= Message::Part;
   if(NetworkModelController::action(HideQuit)->isChecked())
-    filter |= Message::Quit;
+    filter |= Message::Quit | Message::NetsplitQuit;
   if(NetworkModelController::action(HideNick)->isChecked())
     filter |= Message::Nick;
   if(NetworkModelController::action(HideMode)->isChecked())
     filter |= Message::Mode;
   if(NetworkModelController::action(HideDayChange)->isChecked())
     filter |= Message::DayChange;
+  if(NetworkModelController::action(HideTopic)->isChecked())
+    filter |= Message::Topic;
 
   switch(type) {
   case HideJoin:
@@ -262,6 +297,7 @@ void NetworkModelController::handleHideAction(ActionType type, QAction *action)
   case HideNick:
   case HideMode:
   case HideDayChange:
+  case HideTopic:
     if(_messageFilter)
       BufferSettings(_messageFilter->idString()).setMessageFilter(filter);
     else {
@@ -298,35 +334,41 @@ void NetworkModelController::handleGeneralAction(ActionType type, QAction *actio
   if(!indexList().count())
     return;
   NetworkId networkId = indexList().at(0).data(NetworkModel::NetworkIdRole).value<NetworkId>();
-  if(!networkId.isValid())
-    return;
 
   switch(type) {
     case JoinChannel: {
       QString channelName = contextItem();
+      QString channelPassword;
       if(channelName.isEmpty()) {
-        bool ok;
-        channelName = QInputDialog::getText(0, tr("Join Channel"), tr("Input channel name:"), QLineEdit::Normal, QString(), &ok);
-        if(!ok)
-          return;
+        JoinDlg dlg(indexList().first());
+        if(dlg.exec() == QDialog::Accepted) {
+          channelName = dlg.channelName();
+          networkId = dlg.networkId();
+         channelPassword = dlg.channelPassword();
+        }
       }
       if(!channelName.isEmpty()) {
-        Client::instance()->userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(channelName));
+       if(!channelPassword.isEmpty())
+         Client::instance()->userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1 %2").arg(channelName).arg(channelPassword));
+       else
+         Client::instance()->userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(channelName));
       }
       break;
     }
     case ShowChannelList:
-      emit showChannelList(networkId);
+      if(networkId.isValid())
+        emit showChannelList(networkId);
       break;
     case ShowIgnoreList:
-      emit showIgnoreList(networkId);
+      if(networkId.isValid())
+        emit showIgnoreList(QString());
       break;
     default:
       break;
   }
 }
 
-void NetworkModelController::handleNickAction(ActionType type, QAction *) {
+void NetworkModelController::handleNickAction(ActionType type, QAction *action) {
   foreach(QModelIndex index, indexList()) {
     NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
     if(!networkId.isValid())
@@ -351,8 +393,8 @@ void NetworkModelController::handleNickAction(ActionType type, QAction *) {
       case NickCtcpTime:
         Client::userInput(bufferInfo, QString("/CTCP %1 TIME").arg(nick));
         break;
-      case NickCtcpFinger:
-        Client::userInput(bufferInfo, QString("/CTCP %1 FINGER").arg(nick));
+      case NickCtcpClientinfo:
+        Client::userInput(bufferInfo, QString("/CTCP %1 CLIENTINFO").arg(nick));
         break;
       case NickOp:
         Client::userInput(bufferInfo, QString("/OP %1").arg(nick));
@@ -360,6 +402,12 @@ void NetworkModelController::handleNickAction(ActionType type, QAction *) {
       case NickDeop:
         Client::userInput(bufferInfo, QString("/DEOP %1").arg(nick));
         break;
+      case NickHalfop:
+        Client::userInput(bufferInfo, QString("/HALFOP %1").arg(nick));
+        break;
+      case NickDehalfop:
+        Client::userInput(bufferInfo, QString("/DEHALFOP %1").arg(nick));
+        break;
       case NickVoice:
         Client::userInput(bufferInfo, QString("/VOICE %1").arg(nick));
         break;
@@ -377,13 +425,119 @@ void NetworkModelController::handleNickAction(ActionType type, QAction *) {
         Client::userInput(bufferInfo, QString("/KICK %1").arg(nick));
         break;
       case NickSwitchTo:
-        Client::bufferModel()->switchToBuffer(findQueryBuffer(networkId, nick));
-        break;
       case NickQuery:
-        Client::userInput(bufferInfo, QString("/QUERY %1").arg(nick));
+        Client::bufferModel()->switchToOrStartQuery(networkId, nick);
+        break;
+      case NickIgnoreUser:
+      {
+        IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
+        if(!ircUser)
+          break;
+        Client::ignoreListManager()->requestAddIgnoreListItem(IgnoreListManager::SenderIgnore,
+                                                       action->property("ignoreRule").toString(),
+                                                       false, IgnoreListManager::SoftStrictness,
+                                                       IgnoreListManager::NetworkScope,
+                                                       ircUser->network()->networkName(), true);
+        break;
+      }
+      case NickIgnoreHost:
+      {
+        IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
+        if(!ircUser)
+          break;
+        Client::ignoreListManager()->requestAddIgnoreListItem(IgnoreListManager::SenderIgnore,
+                                                       action->property("ignoreRule").toString(),
+                                                       false, IgnoreListManager::SoftStrictness,
+                                                       IgnoreListManager::NetworkScope,
+                                                       ircUser->network()->networkName(), true);
+        break;
+      }
+      case NickIgnoreDomain:
+      {
+        IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
+        if(!ircUser)
+          break;
+        Client::ignoreListManager()->requestAddIgnoreListItem(IgnoreListManager::SenderIgnore,
+                                                       action->property("ignoreRule").toString(),
+                                                       false, IgnoreListManager::SoftStrictness,
+                                                       IgnoreListManager::NetworkScope,
+                                                       ircUser->network()->networkName(), true);
+        break;
+      }
+      case NickIgnoreCustom:
+        // forward that to mainwin since we can access the settingspage only from there
+        emit showIgnoreList(action->property("ignoreRule").toString());
+        break;
+      case NickIgnoreToggleEnabled0:
+      case NickIgnoreToggleEnabled1:
+      case NickIgnoreToggleEnabled2:
+      case NickIgnoreToggleEnabled3:
+      case NickIgnoreToggleEnabled4:
+        Client::ignoreListManager()->requestToggleIgnoreRule(action->property("ignoreRule").toString());
         break;
       default:
         qWarning() << "Unhandled nick action";
     }
   }
 }
+
+/***************************************************************************************************************
+ * JoinDlg
+ ***************************************************************************************************************/
+
+NetworkModelController::JoinDlg::JoinDlg(const QModelIndex &index, QWidget *parent) : QDialog(parent) {
+  setWindowIcon(SmallIcon("irc-join-channel"));
+  setWindowTitle(tr("Join Channel"));
+
+  QGridLayout *layout = new QGridLayout(this);
+  layout->addWidget(new QLabel(tr("Network:")), 0, 0);
+  layout->addWidget(networks = new QComboBox, 0, 1);
+  layout->addWidget(new QLabel(tr("Channel:")), 1, 0);
+  layout->addWidget(channel = new QLineEdit, 1, 1);
+  layout->addWidget(new QLabel(tr("Password:")), 2, 0);
+  layout->addWidget(password = new QLineEdit, 2, 1);
+  layout->addWidget(buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel), 3, 0, 1, 2);
+  setLayout(layout);
+
+  channel->setFocus();
+  buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+  networks->setInsertPolicy(QComboBox::InsertAlphabetically);
+  password->setEchoMode(QLineEdit::Password);
+
+  connect(buttonBox, SIGNAL(accepted()), SLOT(accept()));
+  connect(buttonBox, SIGNAL(rejected()), SLOT(reject()));
+  connect(channel, SIGNAL(textChanged(QString)), SLOT(on_channel_textChanged(QString)));
+
+  foreach(NetworkId id, Client::networkIds()) {
+    const Network *net = Client::network(id);
+    if(net->isConnected()) {
+      networks->addItem(net->networkName(), QVariant::fromValue<NetworkId>(id));
+    }
+  }
+
+  if(index.isValid()) {
+    NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
+    if(networkId.isValid()) {
+      networks->setCurrentIndex(networks->findText(Client::network(networkId)->networkName()));
+      if(index.data(NetworkModel::BufferTypeRole) == BufferInfo::ChannelBuffer
+      && !index.data(NetworkModel::ItemActiveRole).toBool())
+          channel->setText(index.data(Qt::DisplayRole).toString());
+    }
+  }
+}
+
+NetworkId NetworkModelController::JoinDlg::networkId() const {
+  return networks->itemData(networks->currentIndex()).value<NetworkId>();
+}
+
+QString NetworkModelController::JoinDlg::channelName() const {
+  return channel->text();
+}
+
+QString NetworkModelController::JoinDlg::channelPassword() const {
+  return password->text();
+}
+
+void NetworkModelController::JoinDlg::on_channel_textChanged(const QString &text) {
+  buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
+}