-void BufferView::keyPressEvent(QKeyEvent *event) {
- if(event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
- event->accept();
- QModelIndex index = selectionModel()->selectedIndexes().first();
- if(index.isValid()) {
- emit removeBuffer(index);
- }
- }
- QTreeView::keyPressEvent(event);
-}
-
-// ensure that newly inserted network nodes are expanded per default
-void BufferView::rowsInserted(const QModelIndex & parent, int start, int end) {
- QTreeView::rowsInserted(parent, start, end);
- if(model()->rowCount(parent) == 1 && parent != QModelIndex()) {
- // without updating the parent the expand will have no effect... Qt Bug?
- update(parent);
- expand(parent);
- }
-}
-
-void BufferView::toggleHeader(bool checked) {
- QAction *action = qobject_cast<QAction *>(sender());
- header()->setSectionHidden((action->property("column")).toInt(), !checked);
-}
-
-void BufferView::showContextMenu(const QPoint &pos) {
- QModelIndex index = indexAt(pos);
- if(!index.isValid()) return;
- QMenu contextMenu(this);
- QAction *connectNetAction = new QAction(tr("Connect"), this);
- QAction *disconnectNetAction = new QAction(tr("Disconnect"), this);
-
- QAction *joinBufferAction = new QAction(tr("Join"), this);
- QAction *partBufferAction = new QAction(tr("Part"), this);
- QAction *removeBufferAction = new QAction(tr("Delete buffer"), this);
-
- QMenu *hideEventsMenu = new QMenu(tr("Hide Events"), this);
- QAction *hideJoinAction = hideEventsMenu->addAction(tr("Join Events"));
- QAction *hidePartAction = hideEventsMenu->addAction(tr("Part Events"));
- QAction *hideKillAction = hideEventsMenu->addAction(tr("Kill Events"));
- QAction *hideQuitAction = hideEventsMenu->addAction(tr("Quit Events"));
- QAction *hideModeAction = hideEventsMenu->addAction(tr("Mode Events"));
- hideJoinAction->setCheckable(true);
- hidePartAction->setCheckable(true);
- hideKillAction->setCheckable(true);
- hideQuitAction->setCheckable(true);
- hideModeAction->setCheckable(true);
- hideJoinAction->setEnabled(false);
- hidePartAction->setEnabled(false);
- hideKillAction->setEnabled(false);
- hideQuitAction->setEnabled(false);
- hideModeAction->setEnabled(false);
-
- QAction *ignoreListAction = new QAction(tr("Ignore list"), this);
- ignoreListAction->setEnabled(false);
- QAction *whoBufferAction = new QAction(tr("WHO"), this);
-
- if(index.data(NetworkModel::ItemTypeRole) == NetworkModel::NetworkItemType) {
- if(index.data(NetworkModel::ItemActiveRole).toBool()) {
- contextMenu.addAction(disconnectNetAction);
- } else {
- contextMenu.addAction(connectNetAction);
- }
- }
-
- BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
- QString channelname = index.sibling(index.row(), 0).data().toString();
-
- if(index.data(NetworkModel::ItemTypeRole) == NetworkModel::BufferItemType) {
- if(bufferInfo.type() != BufferInfo::ChannelBuffer && bufferInfo.type() != BufferInfo::QueryBuffer) return;
- contextMenu.addAction(joinBufferAction);
- contextMenu.addAction(partBufferAction);
- contextMenu.addAction(removeBufferAction);
- contextMenu.addMenu(hideEventsMenu);
- contextMenu.addAction(ignoreListAction);
- contextMenu.addAction(whoBufferAction);
-
- if(bufferInfo.type() == BufferInfo::ChannelBuffer) {
- if(index.data(NetworkModel::ItemActiveRole).toBool()) {
- removeBufferAction->setEnabled(false);
- removeBufferAction->setToolTip("To delete the buffer, part the channel first.");
- joinBufferAction->setVisible(false);
- } else {
- partBufferAction->setVisible(false);
- }
- } else {
- joinBufferAction->setVisible(false);
- partBufferAction->setVisible(false);
- }
- }
-
- QAction *result = contextMenu.exec(QCursor::pos());
- if(result == connectNetAction || result == disconnectNetAction) {
- const Network *network = Client::network(index.data(NetworkModel::NetworkIdRole).value<NetworkId>());
- if(!network) return;
- if(network->connectionState() == Network::Disconnected)
- network->requestConnect();
- else
- network->requestDisconnect();
- } else
- if(result == joinBufferAction) {
- Client::instance()->userInput(bufferInfo, QString("/JOIN %1").arg(channelname));
- } else
- if(result == partBufferAction) {
- Client::instance()->userInput(bufferInfo, QString("/PART %1").arg(channelname));
- } else
- if(result == removeBufferAction) {
- int res = QMessageBox::question(this, tr("Remove buffer permanently?"),
- tr("Do you want to delete the buffer \"%1\" permanently? This will delete all related data, including all backlog "
- "data, from the core's database!").arg(bufferInfo.bufferName()),
- QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
- if(res == QMessageBox::Yes) {
- Client::removeBuffer(bufferInfo.bufferId());
- }
- } else
- if(result == whoBufferAction) {
- Client::instance()->userInput(bufferInfo, QString("/WHO %1").arg(channelname));
- }
-}
-
-void BufferView::wheelEvent(QWheelEvent* event)
-{
- UiSettings s;
- if(s.value("MouseWheelChangesBuffers",QVariant(true)).toBool()) {
- int rowDelta = ( event->delta() > 0 ) ? -1 : 1;
+
+void BufferView::setConfig(BufferViewConfig *config)
+{
+ if (_config == config)
+ return;
+
+ if (_config) {
+ disconnect(_config, 0, this, 0);
+ }
+
+ _config = config;
+ if (config) {
+ connect(config, SIGNAL(networkIdSet(const NetworkId &)), this, SLOT(setRootIndexForNetworkId(const NetworkId &)));
+ setRootIndexForNetworkId(config->networkId());
+ }
+ else {
+ setIndentation(10);
+ setRootIndex(QModelIndex());
+ }
+}
+
+
+void BufferView::setRootIndexForNetworkId(const NetworkId &networkId)
+{
+ if (!networkId.isValid() || !model()) {
+ setIndentation(10);
+ setRootIndex(QModelIndex());
+ }
+ else {
+ setIndentation(5);
+ int networkCount = model()->rowCount();
+ QModelIndex child;
+ for (int i = 0; i < networkCount; i++) {
+ child = model()->index(i, 0);
+ if (networkId == model()->data(child, NetworkModel::NetworkIdRole).value<NetworkId>())
+ setRootIndex(child);
+ }
+ }
+}
+
+
+void BufferView::joinChannel(const QModelIndex &index)
+{
+ BufferInfo::Type bufferType = (BufferInfo::Type)index.data(NetworkModel::BufferTypeRole).value<int>();
+
+ if (bufferType != BufferInfo::ChannelBuffer)
+ return;
+
+ BufferInfo bufferInfo = index.data(NetworkModel::BufferInfoRole).value<BufferInfo>();
+
+ Client::userInput(bufferInfo, QString("/JOIN %1").arg(bufferInfo.bufferName()));
+}
+
+
+void BufferView::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
+ event->accept();
+ removeSelectedBuffers();
+ }
+ QTreeView::keyPressEvent(event);
+}
+
+
+void BufferView::dropEvent(QDropEvent *event)
+{
+ QModelIndex index = indexAt(event->pos());
+
+ QRect indexRect = visualRect(index);
+ QPoint cursorPos = event->pos();
+
+ // check if we're really _on_ the item and not indicating a move to just above or below the item
+ const int margin = 2;
+ if (cursorPos.y() - indexRect.top() < margin
+ || indexRect.bottom() - cursorPos.y() < margin)
+ return QTreeView::dropEvent(event);
+
+ QList<QPair<NetworkId, BufferId> > bufferList = Client::networkModel()->mimeDataToBufferList(event->mimeData());
+ if (bufferList.count() != 1)
+ return QTreeView::dropEvent(event);
+
+ NetworkId networkId = bufferList[0].first;
+ BufferId bufferId2 = bufferList[0].second;
+
+ if (index.data(NetworkModel::ItemTypeRole) != NetworkModel::BufferItemType)
+ return QTreeView::dropEvent(event);
+
+ if (index.data(NetworkModel::BufferTypeRole) != BufferInfo::QueryBuffer)
+ return QTreeView::dropEvent(event);
+
+ if (index.data(NetworkModel::NetworkIdRole).value<NetworkId>() != networkId)
+ return QTreeView::dropEvent(event);
+
+ BufferId bufferId1 = index.data(NetworkModel::BufferIdRole).value<BufferId>();
+ if (bufferId1 == bufferId2)
+ return QTreeView::dropEvent(event);
+
+ 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);
+ if (res == QMessageBox::Yes) {
+ Client::mergeBuffersPermanently(bufferId1, bufferId2);
+ }
+}
+
+
+void BufferView::removeSelectedBuffers(bool permanently)
+{
+ if (!config())
+ return;
+
+ BufferId bufferId;
+ QSet<BufferId> removedRows;
+ foreach(QModelIndex index, selectionModel()->selectedIndexes()) {
+ if (index.data(NetworkModel::ItemTypeRole) != NetworkModel::BufferItemType)
+ continue;
+
+ bufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
+ if (removedRows.contains(bufferId))
+ continue;
+
+ removedRows << bufferId;
+ }
+
+ foreach(BufferId bufferId, removedRows) {
+ if (permanently)
+ config()->requestRemoveBufferPermanently(bufferId);
+ else
+ config()->requestRemoveBuffer(bufferId);
+ }
+}
+
+
+void BufferView::rowsInserted(const QModelIndex &parent, int start, int end)
+{
+ QTreeView::rowsInserted(parent, start, end);
+
+ // ensure that newly inserted network nodes are expanded per default
+ if (parent.data(NetworkModel::ItemTypeRole) != NetworkModel::NetworkItemType)
+ return;
+
+ setExpandedState(parent);
+}
+
+
+void BufferView::on_layoutChanged()
+{
+ int numNets = model()->rowCount(QModelIndex());
+ for (int row = 0; row < numNets; row++) {
+ QModelIndex networkIdx = model()->index(row, 0, QModelIndex());
+ setExpandedState(networkIdx);
+ }
+}
+
+
+void BufferView::on_configChanged()
+{
+ Q_ASSERT(model());
+
+ // expand all active networks... collapse inactive ones... unless manually changed
+ QModelIndex networkIdx;
+ NetworkId networkId;
+ for (int row = 0; row < model()->rowCount(); row++) {
+ networkIdx = model()->index(row, 0);
+ if (model()->rowCount(networkIdx) == 0)
+ continue;
+
+ networkId = model()->data(networkIdx, NetworkModel::NetworkIdRole).value<NetworkId>();
+ if (!networkId.isValid())
+ continue;
+
+ setExpandedState(networkIdx);
+ }
+
+ if (config()) {
+ // update selection to current one
+ Client::bufferModel()->synchronizeView(this);
+ }
+}
+
+
+void BufferView::storeExpandedState(const QModelIndex &networkIdx)
+{
+ NetworkId networkId = model()->data(networkIdx, NetworkModel::NetworkIdRole).value<NetworkId>();
+
+ int oldState = 0;
+ if (isExpanded(networkIdx))
+ oldState |= WasExpanded;
+ if (model()->data(networkIdx, NetworkModel::ItemActiveRole).toBool())
+ oldState |= WasActive;
+
+ _expandedState[networkId] = oldState;
+}
+
+
+void BufferView::setExpandedState(const QModelIndex &networkIdx)
+{
+ if (model()->data(networkIdx, NetworkModel::ItemTypeRole) != NetworkModel::NetworkItemType)
+ return;
+
+ if (model()->rowCount(networkIdx) == 0)
+ return;
+
+ NetworkId networkId = model()->data(networkIdx, NetworkModel::NetworkIdRole).value<NetworkId>();
+
+ bool networkActive = model()->data(networkIdx, NetworkModel::ItemActiveRole).toBool();
+ bool expandNetwork = networkActive;
+ if (_expandedState.contains(networkId)) {
+ int oldState = _expandedState[networkId];
+ if ((bool)(oldState & WasActive) == networkActive)
+ expandNetwork = (bool)(oldState & WasExpanded);
+ }
+
+ if (expandNetwork != isExpanded(networkIdx)) {
+ update(networkIdx);
+ setExpanded(networkIdx, expandNetwork);
+ }
+ storeExpandedState(networkIdx); // this call is needed to keep track of the isActive state
+}
+
+
+void BufferView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ QTreeView::dataChanged(topLeft, bottomRight);
+
+ // determine how many items have been changed and if any of them is a networkitem
+ // which just swichted from active to inactive or vice versa
+ if (topLeft.data(NetworkModel::ItemTypeRole) != NetworkModel::NetworkItemType)
+ return;
+
+ for (int i = topLeft.row(); i <= bottomRight.row(); i++) {
+ QModelIndex networkIdx = topLeft.sibling(i, 0);
+ setExpandedState(networkIdx);
+ }
+}
+
+
+void BufferView::toggleHeader(bool checked)
+{
+ QAction *action = qobject_cast<QAction *>(sender());
+ header()->setSectionHidden((action->property("column")).toInt(), !checked);
+}
+
+
+void BufferView::contextMenuEvent(QContextMenuEvent *event)
+{
+ QModelIndex index = indexAt(event->pos());
+ if (!index.isValid())
+ index = rootIndex();
+
+ QMenu contextMenu(this);
+
+ if (index.isValid()) {
+ addActionsToMenu(&contextMenu, index);
+ }
+
+ addFilterActions(&contextMenu, index);
+
+ if (!contextMenu.actions().isEmpty())
+ contextMenu.exec(QCursor::pos());
+}
+
+
+void BufferView::addActionsToMenu(QMenu *contextMenu, const QModelIndex &index)
+{
+ QModelIndexList indexList = selectedIndexes();
+ // make sure the item we clicked on is first
+ indexList.removeAll(index);
+ indexList.prepend(index);
+
+ GraphicalUi::contextMenuActionProvider()->addActions(contextMenu, indexList, this, "menuActionTriggered", (bool)config());
+}
+
+
+void BufferView::addFilterActions(QMenu *contextMenu, const QModelIndex &index)
+{
+ BufferViewFilter *filter = qobject_cast<BufferViewFilter *>(model());
+ if (filter) {
+ QList<QAction *> filterActions = filter->actions(index);
+ if (!filterActions.isEmpty()) {
+ contextMenu->addSeparator();
+ foreach(QAction *action, filterActions) {
+ contextMenu->addAction(action);
+ }
+ }
+ }
+}
+
+
+void BufferView::menuActionTriggered(QAction *result)
+{
+ ContextMenuActionProvider::ActionType type = (ContextMenuActionProvider::ActionType)result->data().toInt();
+ switch (type) {
+ case ContextMenuActionProvider::HideBufferTemporarily:
+ removeSelectedBuffers();
+ break;
+ case ContextMenuActionProvider::HideBufferPermanently:
+ removeSelectedBuffers(true);
+ break;
+ default:
+ return;
+ }
+}
+
+
+void BufferView::nextBuffer()
+{
+ changeBuffer(Forward);
+}
+
+
+void BufferView::previousBuffer()
+{
+ changeBuffer(Backward);
+}
+
+
+void BufferView::changeBuffer(Direction direction)
+{