From fa2b53c2a77d8fcae8e12d358465d6e3786769ca Mon Sep 17 00:00:00 2001 From: selabnayr Date: Fri, 24 Jun 2016 14:38:04 -0700 Subject: [PATCH] Allow client-side channel buffer merges, and associated changes. networkmodel.cpp: Mark ChannelBufferItems as being a drop target, to allow for channel buffer merging. bufferviewfilter.cpp: Rework BufferViewFilter::flags() to make it more clear what's going on, and remove the restriction that made QueryBuffers the only merge-able buffers. bufferview.cpp: Rework BufferView::dropEvent() to add a bunch of comments, and allow ChannelBuffers to be merged as well as QueryBuffers. ChannelBuffers can only be the source for a merge if they are not currently joined, to prevent UI weirdness of being in a channel but not having any associated UI elements. Resolves GH-220. (cherry picked from commit 6ee26fd6d0a163314002616d277e5444f11b7720) --- src/client/networkmodel.cpp | 1 + src/uisupport/bufferview.cpp | 25 +++++++++++++++++++++---- src/uisupport/bufferviewfilter.cpp | 24 ++++++++++++------------ 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/client/networkmodel.cpp b/src/client/networkmodel.cpp index c49d1190..11b96f39 100644 --- a/src/client/networkmodel.cpp +++ b/src/client/networkmodel.cpp @@ -566,6 +566,7 @@ ChannelBufferItem::ChannelBufferItem(const BufferInfo &bufferInfo, AbstractTreeI : BufferItem(bufferInfo, parent), _ircChannel(0) { + setFlags(flags() | Qt::ItemIsDropEnabled); } diff --git a/src/uisupport/bufferview.cpp b/src/uisupport/bufferview.cpp index 5dc31548..b0917b2c 100644 --- a/src/uisupport/bufferview.cpp +++ b/src/uisupport/bufferview.cpp @@ -229,27 +229,44 @@ void BufferView::dropEvent(QDropEvent *event) QPoint cursorPos = event->pos(); // check if we're really _on_ the item and not indicating a move to just above or below the item + // Magic margin number for this is from QAbstractItemViewPrivate::position() const int margin = 2; if (cursorPos.y() - indexRect.top() < margin || indexRect.bottom() - cursorPos.y() < margin) return TreeViewTouch::dropEvent(event); + // If more than one buffer was being dragged, treat this as a rearrangement instead of a merge request QList > bufferList = Client::networkModel()->mimeDataToBufferList(event->mimeData()); if (bufferList.count() != 1) return TreeViewTouch::dropEvent(event); + // Get the Buffer ID of the buffer that was being dragged BufferId bufferId2 = bufferList[0].second; - if (index.data(NetworkModel::ItemTypeRole) != NetworkModel::BufferItemType) + // Get the Buffer ID of the target buffer + BufferId bufferId1 = index.data(NetworkModel::BufferIdRole).value(); + + // If the source and target are the same buffer, this was an aborted rearrangement + if (bufferId1 == bufferId2) return TreeViewTouch::dropEvent(event); - if (index.data(NetworkModel::BufferTypeRole) != BufferInfo::QueryBuffer) + // Get index of buffer that was being dragged + QModelIndex index2 = Client::networkModel()->bufferIndex(bufferId2); + + // If the buffer being dragged is a channel and we're still joined to it, treat this as a rearrangement + // This prevents us from being joined to a channel with no associated UI elements + if (index2.data(NetworkModel::BufferTypeRole) == BufferInfo::ChannelBuffer && index2.data(NetworkModel::ItemActiveRole) == true) return TreeViewTouch::dropEvent(event); - BufferId bufferId1 = index.data(NetworkModel::BufferIdRole).value(); - if (bufferId1 == bufferId2) + //If the source buffer is not mergeable(AKA not a Channel and not a Query), try rearranging instead + if (index2.data(NetworkModel::BufferTypeRole) != BufferInfo::ChannelBuffer && index2.data(NetworkModel::BufferTypeRole) != BufferInfo::QueryBuffer) + return TreeViewTouch::dropEvent(event); + + // If the target buffer is not mergeable(AKA not a Channel and not a Query), try rearranging instead + if (index.data(NetworkModel::BufferTypeRole) != BufferInfo::ChannelBuffer && index.data(NetworkModel::BufferTypeRole) != BufferInfo::QueryBuffer) return TreeViewTouch::dropEvent(event); + // Confirm that the user really wants to merge the buffers before doing so int res = QMessageBox::question(0, tr("Merge buffers permanently?"), tr("Do you want to merge the buffer \"%1\" permanently into buffer \"%2\"?\n This cannot be reversed!").arg(Client::networkModel()->bufferName(bufferId2)).arg(Client::networkModel()->bufferName(bufferId1)), QMessageBox::Yes|QMessageBox::No, QMessageBox::No); diff --git a/src/uisupport/bufferviewfilter.cpp b/src/uisupport/bufferviewfilter.cpp index 4c5d4a9c..bd396a6e 100644 --- a/src/uisupport/bufferviewfilter.cpp +++ b/src/uisupport/bufferviewfilter.cpp @@ -175,23 +175,23 @@ Qt::ItemFlags BufferViewFilter::flags(const QModelIndex &index) const 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) { + // We need Status Buffers to be a drop target, to allow for rearranging buffers. + // The Status Buffer "owns" the space between Channel/Query buffers in the tree. + // This DOES mean that it looks like you can merge a buffer into the Status buffer, but that is restricted in BufferView::dropEvent(). + if (bufferType == BufferInfo::StatusBuffer) { + // But only if the layout isn't locked! ClientBufferViewConfig *clientConf = qobject_cast(config()); - if (clientConf && clientConf->isLocked()) { - flags &= ~(Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled); + if (clientConf && !clientConf->isLocked()) { + flags |= Qt::ItemIsDropEnabled; } } + + // If we're in Edit Mode, everything except Status Buffers should be hideable. + if (_editMode && bufferType != BufferInfo::StatusBuffer) { + flags |= Qt::ItemIsUserCheckable | Qt::ItemIsTristate; + } } return flags; } -- 2.20.1