allow query merging via drag & drop even if the layout is locked
[quassel.git] / src / uisupport / bufferviewfilter.cpp
index bb67e50..3e0a59f 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-08 by the Quassel Project                          *
+ *   Copyright (C) 2005-09 by the Quassel Project                          *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 #include "buffermodel.h"
 #include "buffersettings.h"
 #include "client.h"
+#include "clientbufferviewconfig.h"
 #include "iconloader.h"
 #include "networkmodel.h"
 
-#include "uisettings.h"
-
 class CheckRemovalEvent : public QEvent {
 public:
   CheckRemovalEvent(const QModelIndex &source_index) : QEvent(QEvent::User), index(source_index) {};
@@ -46,19 +45,17 @@ BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, BufferViewConfig *
   : QSortFilterProxyModel(model),
     _config(0),
     _sortOrder(Qt::AscendingOrder),
-    _userOfflineIcon(SmallIcon("user-offline")),
-    _userAwayIcon(SmallIcon("user-away")),
-    _userOnlineIcon(SmallIcon("user-online")),
+    _userOfflineIcon(SmallIcon("im-user-offline")),
+    _userAwayIcon(SmallIcon("im-user-away")),
+    _userOnlineIcon(SmallIcon("im-user")),
     _editMode(false),
-    _enableEditMode(tr("Edit Mode"), this)
+    _enableEditMode(tr("Show / Hide buffers"), this)
 {
   setConfig(config);
   setSourceModel(model);
 
   setDynamicSortFilter(true);
 
-  loadColors();
-
   connect(this, SIGNAL(_dataChanged(const QModelIndex &, const QModelIndex &)),
          this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex)));
 
@@ -71,15 +68,6 @@ BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, BufferViewConfig *
   bufferSettings.notify("ShowUserStateIcons", this, SLOT(showUserStateIconsChanged()));
 }
 
-void BufferViewFilter::loadColors() {
-  UiSettings s("QtUiStyle/Colors");
-  _FgColorInactiveActivity = s.value("inactiveActivityFG", QVariant(QColor(Qt::gray))).value<QColor>();
-  _FgColorNoActivity = s.value("noActivityFG", QVariant(QColor(Qt::black))).value<QColor>();
-  _FgColorHighlightActivity = s.value("highlightActivityFG", QVariant(QColor(Qt::magenta))).value<QColor>();
-  _FgColorNewMessageActivity = s.value("newMessageActivityFG", QVariant(QColor(Qt::green))).value<QColor>();
-  _FgColorOtherActivity = s.value("otherActivityFG", QVariant(QColor(Qt::darkGreen))).value<QColor>();
-}
-
 void BufferViewFilter::showUserStateIconsChanged() {
   BufferSettings bufferSettings;
   _showUserStateIcons = bufferSettings.showUserStateIcons();
@@ -178,13 +166,25 @@ void BufferViewFilter::enableEditMode(bool enable) {
 
 
 Qt::ItemFlags BufferViewFilter::flags(const QModelIndex &index) const {
-  Qt::ItemFlags flags = mapToSource(index).flags();
-  if(_config) {
-    if(index == QModelIndex() || index.parent() == QModelIndex()) {
+  QModelIndex source_index = mapToSource(index);
+  Qt::ItemFlags flags = sourceModel()->flags(source_index);
+  if(config()) {
+    NetworkModel::ItemType itemType = (NetworkModel::ItemType)sourceModel()->data(source_index, NetworkModel::ItemTypeRole).toInt();
+    BufferInfo::Type bufferType = (BufferInfo::Type)sourceModel()->data(source_index, NetworkModel::BufferTypeRole).toInt();
+    if(source_index == QModelIndex() || itemType == NetworkModel::NetworkItemType) {
       flags |= Qt::ItemIsDropEnabled;
     } else if(_editMode) {
       flags |= Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
     }
+
+    // prohibit dragging of most items. and most drop places
+    // only query to query is allowed for merging
+    if(bufferType != BufferInfo::QueryBuffer) {
+      ClientBufferViewConfig *clientConf = qobject_cast<ClientBufferViewConfig *>(config());
+      if(clientConf && clientConf->isLocked()) {
+       flags &= ~(Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled);
+      }
+    }
   }
   return flags;
 }
@@ -194,8 +194,9 @@ bool BufferViewFilter::dropMimeData(const QMimeData *data, Qt::DropAction action
     return QSortFilterProxyModel::dropMimeData(data, action, row, column, parent);
 
   NetworkId droppedNetworkId;
-  if(parent.data(NetworkModel::ItemTypeRole) == NetworkModel::NetworkItemType)
-    droppedNetworkId = parent.data(NetworkModel::NetworkIdRole).value<NetworkId>();
+  QModelIndex source_parent = mapToSource(parent);
+  if(sourceModel()->data(source_parent, NetworkModel::ItemTypeRole) == NetworkModel::NetworkItemType)
+    droppedNetworkId = sourceModel()->data(source_parent, NetworkModel::NetworkIdRole).value<NetworkId>();
 
   QList< QPair<NetworkId, BufferId> > bufferList = NetworkModel::mimeDataToBufferList(data);
   BufferId bufferId;
@@ -209,7 +210,8 @@ bool BufferViewFilter::dropMimeData(const QMimeData *data, Qt::DropAction action
        row = 0;
 
       if(row < rowCount(parent)) {
-       BufferId beforeBufferId = parent.child(row, 0).data(NetworkModel::BufferIdRole).value<BufferId>();
+       QModelIndex source_child = mapToSource(index(row, 0, parent));
+       BufferId beforeBufferId = sourceModel()->data(source_child, NetworkModel::BufferIdRole).value<BufferId>();
        pos = config()->bufferList().indexOf(beforeBufferId);
        if(_sortOrder == Qt::DescendingOrder)
          pos++;
@@ -265,14 +267,15 @@ bool BufferViewFilter::filterAcceptBuffer(const QModelIndex &source_bufferIndex)
   if(!config())
     return true;
 
-  BufferId bufferId = source_bufferIndex.data(NetworkModel::BufferIdRole).value<BufferId>();
+  BufferId bufferId = sourceModel()->data(source_bufferIndex, NetworkModel::BufferIdRole).value<BufferId>();
   Q_ASSERT(bufferId.isValid());
 
-  int activityLevel = source_bufferIndex.data(NetworkModel::BufferActivityRole).toInt();
+  int activityLevel = sourceModel()->data(source_bufferIndex, NetworkModel::BufferActivityRole).toInt();
 
   if(!config()->bufferList().contains(bufferId) && !_editMode) {
     // add the buffer if...
-    if(config()->isInitialized() && !config()->removedBuffers().contains(bufferId) // it hasn't been manually removed and either
+    if(config()->isInitialized()
+       && !config()->removedBuffers().contains(bufferId) // it hasn't been manually removed and either
        && ((config()->addNewBuffersAutomatically() && !config()->temporarilyRemovedBuffers().contains(bufferId)) // is totally unknown to us (a new buffer)...
           || (config()->temporarilyRemovedBuffers().contains(bufferId) && activityLevel > BufferInfo::OtherActivity))) { // or was just temporarily hidden and has a new message waiting for us.
       addBuffer(bufferId);
@@ -281,20 +284,21 @@ bool BufferViewFilter::filterAcceptBuffer(const QModelIndex &source_bufferIndex)
     return false;
   }
 
-  if(config()->networkId().isValid() && config()->networkId() != source_bufferIndex.data(NetworkModel::NetworkIdRole).value<NetworkId>())
+  if(config()->networkId().isValid() && config()->networkId() != sourceModel()->data(source_bufferIndex, NetworkModel::NetworkIdRole).value<NetworkId>())
     return false;
 
   int allowedBufferTypes = config()->allowedBufferTypes();
   if(!config()->networkId().isValid())
     allowedBufferTypes &= ~BufferInfo::StatusBuffer;
-  if(!(allowedBufferTypes & source_bufferIndex.data(NetworkModel::BufferTypeRole).toInt()))
+  if(!(allowedBufferTypes & sourceModel()->data(source_bufferIndex, NetworkModel::BufferTypeRole).toInt()))
     return false;
 
   // the following dynamic filters may not trigger if the buffer is currently selected.
-  if(bufferId == Client::bufferModel()->standardSelectionModel()->currentIndex().data(NetworkModel::BufferIdRole).value<BufferId>())
+  QModelIndex currentIndex = Client::bufferModel()->standardSelectionModel()->currentIndex();
+  if(bufferId == Client::bufferModel()->data(currentIndex, NetworkModel::BufferIdRole).value<BufferId>())
     return true;
 
-  if(config()->hideInactiveBuffers() && !source_bufferIndex.data(NetworkModel::ItemActiveRole).toBool() && activityLevel <= BufferInfo::OtherActivity)
+  if(config()->hideInactiveBuffers() && !sourceModel()->data(source_bufferIndex, NetworkModel::ItemActiveRole).toBool() && activityLevel <= BufferInfo::OtherActivity)
     return false;
 
   if(config()->minimumActivity() > activityLevel)
@@ -310,7 +314,7 @@ bool BufferViewFilter::filterAcceptNetwork(const QModelIndex &source_index) cons
   if(!config()->networkId().isValid()) {
     return true;
   } else {
-    return config()->networkId() == source_index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
+    return config()->networkId() == sourceModel()->data(source_index, NetworkModel::NetworkIdRole).value<NetworkId>();
   }
 }
 
@@ -322,15 +326,20 @@ bool BufferViewFilter::filterAcceptsRow(int source_row, const QModelIndex &sourc
     return false;
   }
 
-  if(!source_parent.isValid())
+  NetworkModel::ItemType childType = (NetworkModel::ItemType)sourceModel()->data(child, NetworkModel::ItemTypeRole).toInt();
+  switch(childType) {
+  case NetworkModel::NetworkItemType:
     return filterAcceptNetwork(child);
-  else
+  case NetworkModel::BufferItemType:
     return filterAcceptBuffer(child);
+  default:
+    return false;
+  }
 }
 
 bool BufferViewFilter::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const {
-  int leftItemType = source_left.data(NetworkModel::ItemTypeRole).toInt();
-  int rightItemType = source_right.data(NetworkModel::ItemTypeRole).toInt();
+  int leftItemType = sourceModel()->data(source_left, NetworkModel::ItemTypeRole).toInt();
+  int rightItemType = sourceModel()->data(source_right, NetworkModel::ItemTypeRole).toInt();
   int itemType = leftItemType & rightItemType;
   switch(itemType) {
   case NetworkModel::NetworkItemType:
@@ -343,8 +352,8 @@ bool BufferViewFilter::lessThan(const QModelIndex &source_left, const QModelInde
 }
 
 bool BufferViewFilter::bufferLessThan(const QModelIndex &source_left, const QModelIndex &source_right) const {
-  BufferId leftBufferId = source_left.data(NetworkModel::BufferIdRole).value<BufferId>();
-  BufferId rightBufferId = source_right.data(NetworkModel::BufferIdRole).value<BufferId>();
+  BufferId leftBufferId = sourceModel()->data(source_left, NetworkModel::BufferIdRole).value<BufferId>();
+  BufferId rightBufferId = sourceModel()->data(source_right, NetworkModel::BufferIdRole).value<BufferId>();
   if(config()) {
     int leftPos = config()->bufferList().indexOf(leftBufferId);
     int rightPos = config()->bufferList().indexOf(rightBufferId);
@@ -358,21 +367,16 @@ bool BufferViewFilter::bufferLessThan(const QModelIndex &source_left, const QMod
 }
 
 bool BufferViewFilter::networkLessThan(const QModelIndex &source_left, const QModelIndex &source_right) const {
-  NetworkId leftNetworkId = source_left.data(NetworkModel::NetworkIdRole).value<NetworkId>();
-  NetworkId rightNetworkId = source_right.data(NetworkModel::NetworkIdRole).value<NetworkId>();
+  NetworkId leftNetworkId = sourceModel()->data(source_left, NetworkModel::NetworkIdRole).value<NetworkId>();
+  NetworkId rightNetworkId = sourceModel()->data(source_right, NetworkModel::NetworkIdRole).value<NetworkId>();
 
-  if(config() && config()->sortAlphabetically())
-    return QSortFilterProxyModel::lessThan(source_left, source_right);
-  else
-    return leftNetworkId < rightNetworkId;
+  return QSortFilterProxyModel::lessThan(source_left, source_right);
 }
 
 QVariant BufferViewFilter::data(const QModelIndex &index, int role) const {
   switch(role) {
   case Qt::DecorationRole:
     return icon(index);
-  case Qt::ForegroundRole:
-    return foreground(index);
   case Qt::CheckStateRole:
     return checkedState(index);
   default:
@@ -387,13 +391,17 @@ QVariant BufferViewFilter::icon(const QModelIndex &index) const {
   if(index.column() != 0)
     return QVariant();
 
-  if(index.data(NetworkModel::BufferTypeRole).toInt() != BufferInfo::QueryBuffer)
+  QModelIndex source_index = mapToSource(index);
+  if(sourceModel()->data(source_index, NetworkModel::ItemTypeRole).toInt() != NetworkModel::BufferItemType)
     return QVariant();
 
-  if(!index.data(NetworkModel::ItemActiveRole).toBool())
+  if(sourceModel()->data(source_index, NetworkModel::BufferTypeRole).toInt() != BufferInfo::QueryBuffer)
+    return QVariant();
+
+  if(!sourceModel()->data(source_index, NetworkModel::ItemActiveRole).toBool())
     return _userOfflineIcon;
 
-  if(index.data(NetworkModel::UserAwayRole).toBool())
+  if(sourceModel()->data(source_index, NetworkModel::UserAwayRole).toBool())
     return _userAwayIcon;
   else
     return _userOnlineIcon;
@@ -401,30 +409,15 @@ QVariant BufferViewFilter::icon(const QModelIndex &index) const {
   return QVariant();
 }
 
-QVariant BufferViewFilter::foreground(const QModelIndex &index) const {
-  if(config() && config()->disableDecoration())
-    return _FgColorNoActivity;
-
-  BufferInfo::ActivityLevel activity = (BufferInfo::ActivityLevel)index.data(NetworkModel::BufferActivityRole).toInt();
-
-  if(activity & BufferInfo::Highlight)
-    return _FgColorHighlightActivity;
-  if(activity & BufferInfo::NewMessage)
-    return _FgColorNewMessageActivity;
-  if(activity & BufferInfo::OtherActivity)
-    return _FgColorOtherActivity;
-
-  if(!index.data(NetworkModel::ItemActiveRole).toBool() || index.data(NetworkModel::UserAwayRole).toBool())
-    return _FgColorInactiveActivity;
-
-  return _FgColorNoActivity;
-}
-
 QVariant BufferViewFilter::checkedState(const QModelIndex &index) const {
   if(!_editMode || !config())
     return QVariant();
 
-  BufferId bufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
+  QModelIndex source_index = mapToSource(index);
+  if(source_index == QModelIndex() || sourceModel()->data(source_index, NetworkModel::ItemTypeRole) == NetworkModel::NetworkItemType)
+    return QVariant();
+
+  BufferId bufferId = sourceModel()->data(source_index, NetworkModel::BufferIdRole).value<BufferId>();
   if(_toAdd.contains(bufferId))
     return Qt::Checked;
 
@@ -453,7 +446,8 @@ bool BufferViewFilter::setData(const QModelIndex &index, const QVariant &value,
 }
 
 bool BufferViewFilter::setCheckedState(const QModelIndex &index, Qt::CheckState state) {
-  BufferId bufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
+  QModelIndex source_index = mapToSource(index);
+  BufferId bufferId = sourceModel()->data(source_index, NetworkModel::BufferIdRole).value<BufferId>();
   if(!bufferId.isValid())
     return false;
 
@@ -510,12 +504,12 @@ bool BufferViewFilter::bufferIdLessThan(const BufferId &left, const BufferId &ri
   QModelIndex leftIndex = Client::networkModel()->bufferIndex(left);
   QModelIndex rightIndex = Client::networkModel()->bufferIndex(right);
 
-  int leftType = leftIndex.data(NetworkModel::BufferTypeRole).toInt();
-  int rightType = rightIndex.data(NetworkModel::BufferTypeRole).toInt();
+  int leftType = Client::networkModel()->data(leftIndex, NetworkModel::BufferTypeRole).toInt();
+  int rightType = Client::networkModel()->data(rightIndex, NetworkModel::BufferTypeRole).toInt();
 
   if(leftType != rightType)
     return leftType < rightType;
   else
-    return QString::compare(leftIndex.data(Qt::DisplayRole).toString(), rightIndex.data(Qt::DisplayRole).toString(), Qt::CaseInsensitive) < 0;
+    return QString::compare(Client::networkModel()->data(leftIndex, Qt::DisplayRole).toString(), Client::networkModel()->data(rightIndex, Qt::DisplayRole).toString(), Qt::CaseInsensitive) < 0;
 }