X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fuisupport%2Fbufferview.cpp;h=a1200bda318b175937fafc1de5e7c03fb6dcc376;hb=2c8434f74c68194d56f2084f637419123e61d18b;hp=8387f025942d3b259c8517146ebf64d2af1dd322;hpb=a25f1db4e6c59cdfb82a5d485add8a5597968279;p=quassel.git diff --git a/src/uisupport/bufferview.cpp b/src/uisupport/bufferview.cpp index 8387f025..a1200bda 100644 --- a/src/uisupport/bufferview.cpp +++ b/src/uisupport/bufferview.cpp @@ -50,13 +50,13 @@ BufferView::BufferView(QWidget *parent) : TreeViewTouch(parent) { - connect(this, SIGNAL(collapsed(const QModelIndex &)), SLOT(storeExpandedState(const QModelIndex &))); - connect(this, SIGNAL(expanded(const QModelIndex &)), SLOT(storeExpandedState(const QModelIndex &))); + connect(this, &QTreeView::collapsed, this, &BufferView::storeExpandedState); + connect(this, &QTreeView::expanded, this, &BufferView::storeExpandedState); setSelectionMode(QAbstractItemView::ExtendedSelection); QAbstractItemDelegate *oldDelegate = itemDelegate(); - BufferViewDelegate *tristateDelegate = new BufferViewDelegate(this); + auto *tristateDelegate = new BufferViewDelegate(this); setItemDelegate(tristateDelegate); delete oldDelegate; } @@ -75,9 +75,7 @@ void BufferView::init() setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - // breaks with Qt 4.8 - if (QString("4.8.0") > qVersion()) // FIXME breaks with Qt versions >= 4.10! - setAnimated(true); + setAnimated(true); // FIXME This is to workaround bug #663 setUniformRowHeights(true); @@ -93,11 +91,9 @@ void BufferView::init() #if defined Q_OS_MACOS || defined Q_OS_WIN // afaik this is better on Mac and Windows - disconnect(this, SIGNAL(activated(QModelIndex)), this, SLOT(joinChannel(QModelIndex))); - connect(this, SIGNAL(activated(QModelIndex)), SLOT(joinChannel(QModelIndex))); + connect(this, &QAbstractItemView::activated, this, &BufferView::joinChannel, Qt::UniqueConnection); #else - disconnect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(joinChannel(QModelIndex))); - connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(joinChannel(QModelIndex))); + connect(this, &QAbstractItemView::doubleClicked, this, &BufferView::joinChannel, Qt::UniqueConnection); #endif } @@ -126,11 +122,11 @@ void BufferView::setModel(QAbstractItemModel *model) showSection->setCheckable(true); showSection->setChecked(!isColumnHidden(i)); showSection->setProperty("column", i); - connect(showSection, SIGNAL(toggled(bool)), this, SLOT(toggleHeader(bool))); + connect(showSection, &QAction::toggled, this, &BufferView::toggleHeader); header()->addAction(showSection); } - connect(model, SIGNAL(layoutChanged()), this, SLOT(on_layoutChanged())); + connect(model, &QAbstractItemModel::layoutChanged, this, &BufferView::on_layoutChanged); // Make sure collapsation is correct after setting a model // This might not be needed here, only in BufferView::setFilteredModel(). If issues arise, just @@ -141,7 +137,7 @@ void BufferView::setModel(QAbstractItemModel *model) void BufferView::setFilteredModel(QAbstractItemModel *model_, BufferViewConfig *config) { - BufferViewFilter *filter = qobject_cast(model()); + auto *filter = qobject_cast(model()); if (filter) { filter->setConfig(config); setConfig(config); @@ -149,17 +145,17 @@ void BufferView::setFilteredModel(QAbstractItemModel *model_, BufferViewConfig * } if (model()) { - disconnect(this, 0, model(), 0); - disconnect(model(), 0, this, 0); + disconnect(this, nullptr, model(), nullptr); + disconnect(model(), nullptr, this, nullptr); } if (!model_) { setModel(model_); } else { - BufferViewFilter *filter = new BufferViewFilter(model_, config); + auto *filter = new BufferViewFilter(model_, config); setModel(filter); - connect(filter, SIGNAL(configChanged()), this, SLOT(on_configChanged())); + connect(filter, &BufferViewFilter::configChanged, this, &BufferView::on_configChanged); } setConfig(config); } @@ -171,12 +167,12 @@ void BufferView::setConfig(BufferViewConfig *config) return; if (_config) { - disconnect(_config, 0, this, 0); + disconnect(_config, nullptr, this, nullptr); } _config = config; if (config) { - connect(config, SIGNAL(networkIdSet(const NetworkId &)), this, SLOT(setRootIndexForNetworkId(const NetworkId &))); + connect(config, &BufferViewConfig::networkIdSet, this, &BufferView::setRootIndexForNetworkId); setRootIndexForNetworkId(config->networkId()); } else { @@ -264,7 +260,7 @@ void BufferView::dropEvent(QDropEvent *event) 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?"), + int res = QMessageBox::question(nullptr, 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) { @@ -394,15 +390,9 @@ void BufferView::setExpandedState(const QModelIndex &networkIdx) storeExpandedState(networkIdx); // this call is needed to keep track of the isActive state } -#if QT_VERSION < 0x050000 -void BufferView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - TreeViewTouch::dataChanged(topLeft, bottomRight); -#else void BufferView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { TreeViewTouch::dataChanged(topLeft, bottomRight, roles); -#endif // 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 @@ -418,7 +408,7 @@ void BufferView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bott void BufferView::toggleHeader(bool checked) { - QAction *action = qobject_cast(sender()); + auto *action = qobject_cast(sender()); header()->setSectionHidden((action->property("column")).toInt(), !checked); } @@ -449,13 +439,13 @@ void BufferView::addActionsToMenu(QMenu *contextMenu, const QModelIndex &index) indexList.removeAll(index); indexList.prepend(index); - GraphicalUi::contextMenuActionProvider()->addActions(contextMenu, indexList, this, "menuActionTriggered", (bool)config()); + GraphicalUi::contextMenuActionProvider()->addActions(contextMenu, indexList, this, &BufferView::menuActionTriggered, (bool)config()); } void BufferView::addFilterActions(QMenu *contextMenu, const QModelIndex &index) { - BufferViewFilter *filter = qobject_cast(model()); + auto *filter = qobject_cast(model()); if (filter) { QList filterActions = filter->actions(index); if (!filterActions.isEmpty()) { @@ -594,9 +584,9 @@ void BufferView::hideCurrentBuffer() config()->requestRemoveBuffer(bufferId); } -void BufferView::filterTextChanged(QString filterString) +void BufferView::filterTextChanged(const QString& filterString) { - BufferViewFilter *filter = qobject_cast(model()); + auto *filter = qobject_cast(model()); if (!filter) { return; } @@ -613,19 +603,74 @@ QSize BufferView::sizeHint() const return TreeViewTouch::sizeHint(); if (model()->rowCount() == 0) - return QSize(120, 50); + return {120, 50}; int columnSize = 0; for (int i = 0; i < model()->columnCount(); i++) { if (!isColumnHidden(i)) columnSize += sizeHintForColumn(i); } - return QSize(columnSize, 50); + return {columnSize, 50}; +} + + +void BufferView::changeHighlight(BufferView::Direction direction) +{ + // If for some weird reason we get a new delegate + auto delegate = qobject_cast(itemDelegate(_currentHighlight)); + if (delegate) { + delegate->currentHighlight = QModelIndex(); + } + + QModelIndex newIndex = _currentHighlight; + if (!newIndex.isValid()) { + newIndex = model()->index(0, 0); + } + + if (direction == Backward) { + newIndex = indexBelow(newIndex); + } else { + newIndex = indexAbove(newIndex); + } + + if (!newIndex.isValid()) { + return; + } + + _currentHighlight = newIndex; + + delegate = qobject_cast(itemDelegate(_currentHighlight)); + if (delegate) { + delegate->currentHighlight = _currentHighlight; + } + viewport()->update(); } +void BufferView::selectHighlighted() +{ + if (_currentHighlight.isValid()) { + selectionModel()->setCurrentIndex(_currentHighlight, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + selectionModel()->select(_currentHighlight, QItemSelectionModel::ClearAndSelect); + } else { + selectFirstBuffer(); + } + + clearHighlight(); +} + +void BufferView::clearHighlight() +{ + // If for some weird reason we get a new delegate + auto delegate = qobject_cast(itemDelegate(_currentHighlight)); + if (delegate) { + delegate->currentHighlight = QModelIndex(); + } + _currentHighlight = QModelIndex(); + viewport()->update(); +} // **************************************** -// BufferViewDelgate +// BufferViewDelegate // **************************************** class ColorsChangedEvent : public QEvent { @@ -661,20 +706,16 @@ bool BufferViewDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, c if (!value.isValid()) return QStyledItemDelegate::editorEvent(event, model, option, index); -#if QT_VERSION < 0x050000 - QStyleOptionViewItemV4 viewOpt(option); -#else QStyleOptionViewItem viewOpt(option); -#endif initStyleOption(&viewOpt, index); QRect checkRect = viewOpt.widget->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &viewOpt, viewOpt.widget); - QMouseEvent *me = static_cast(event); + auto *me = static_cast(event); if (me->button() != Qt::LeftButton || !checkRect.contains(me->pos())) return QStyledItemDelegate::editorEvent(event, model, option, index); - Qt::CheckState state = static_cast(value.toInt()); + auto state = static_cast(value.toInt()); if (state == Qt::Unchecked) state = Qt::PartiallyChecked; else if (state == Qt::PartiallyChecked) @@ -691,7 +732,7 @@ bool BufferViewDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, c // ============================== BufferViewDock::BufferViewDock(BufferViewConfig *config, QWidget *parent) : QDockWidget(parent), - _childWidget(0), + _childWidget(nullptr), _widget(new QWidget(parent)), _filterEdit(new QLineEdit(parent)), _active(false), @@ -700,8 +741,8 @@ BufferViewDock::BufferViewDock(BufferViewConfig *config, QWidget *parent) setObjectName("BufferViewDock-" + QString::number(config->bufferViewId())); toggleViewAction()->setData(config->bufferViewId()); setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); - connect(config, SIGNAL(bufferViewNameSet(const QString &)), this, SLOT(bufferViewRenamed(const QString &))); - connect(config, SIGNAL(configChanged()), SLOT(configChanged())); + connect(config, &BufferViewConfig::bufferViewNameSet, this, &BufferViewDock::bufferViewRenamed); + connect(config, &BufferViewConfig::configChanged, this, &BufferViewDock::configChanged); updateTitle(); _widget->setLayout(new QVBoxLayout); @@ -713,7 +754,7 @@ BufferViewDock::BufferViewDock(BufferViewConfig *config, QWidget *parent) _filterEdit->setFocusPolicy(Qt::ClickFocus); _filterEdit->installEventFilter(this); _filterEdit->setPlaceholderText(tr("Search...")); - connect(_filterEdit, SIGNAL(returnPressed()), SLOT(onFilterReturnPressed())); + connect(_filterEdit, &QLineEdit::returnPressed, this, &BufferViewDock::onFilterReturnPressed); _widget->layout()->addWidget(_filterEdit); QDockWidget::setWidget(_widget); @@ -721,7 +762,7 @@ BufferViewDock::BufferViewDock(BufferViewConfig *config, QWidget *parent) void BufferViewDock::setLocked(bool locked) { if (locked) { - setFeatures(0); + setFeatures(nullptr); } else { setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); @@ -748,7 +789,7 @@ void BufferViewDock::onFilterReturnPressed() { if (_oldFocusItem) { _oldFocusItem->setFocus(); - _oldFocusItem = 0; + _oldFocusItem = nullptr; } if (!config()->showSearch()) { @@ -756,12 +797,16 @@ void BufferViewDock::onFilterReturnPressed() } BufferView *view = bufferView(); - if (!view || _filterEdit->text().isEmpty()) { + if (!view) { return; } - view->selectFirstBuffer(); - _filterEdit->clear(); + if (!_filterEdit->text().isEmpty()) { + view->selectHighlighted(); + _filterEdit->clear(); + } else { + view->clearHighlight(); + } } void BufferViewDock::setActive(bool active) @@ -787,19 +832,36 @@ bool BufferViewDock::eventFilter(QObject *object, QEvent *event) return true; } } else if (event->type() == QEvent::KeyRelease) { - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent->key() != Qt::Key_Escape) { + auto keyEvent = static_cast(event); + + BufferView *view = bufferView(); + if (!view) { return false; } - _filterEdit->clear(); + switch (keyEvent->key()) { + case Qt::Key_Escape: { + _filterEdit->clear(); + + if (!_oldFocusItem) { + return false; + } - if (_oldFocusItem) { _oldFocusItem->setFocus(); - _oldFocusItem = 0; + _oldFocusItem = nullptr; + return true; + } + case Qt::Key_Down: + view->changeHighlight(BufferView::Backward); + return true; + case Qt::Key_Up: + view->changeHighlight(BufferView::Forward); + return true; + default: + break; } - return true; + return false; } return false; @@ -830,7 +892,7 @@ BufferViewConfig *BufferViewDock::config() const { BufferView *view = bufferView(); if (!view) - return 0; + return nullptr; else return view->config(); } @@ -840,7 +902,7 @@ void BufferViewDock::setWidget(QWidget *newWidget) _widget->layout()->addWidget(newWidget); _childWidget = newWidget; - connect(_filterEdit, SIGNAL(textChanged(QString)), bufferView(), SLOT(filterTextChanged(QString))); + connect(_filterEdit, &QLineEdit::textChanged, bufferView(), &BufferView::filterTextChanged); } void BufferViewDock::activateFilter() @@ -853,3 +915,13 @@ void BufferViewDock::activateFilter() _filterEdit->setFocus(); } + + +void BufferViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem newOption = option; + if (index == currentHighlight) { + newOption.state |= QStyle::State_HasFocus; + } + QStyledItemDelegate::paint(painter, newOption, index); +}