diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index ed2ad1471..cf86b1dbd 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -30,6 +30,7 @@ #include +#include #include #include #include @@ -235,7 +236,11 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP if (category != defaultCategory && category != m_torrentParams.category) m_ui->categoryComboBox->addItem(category); + m_ui->contentTreeView->header()->setContextMenuPolicy(Qt::CustomContextMenu); m_ui->contentTreeView->header()->setSortIndicator(0, Qt::AscendingOrder); + + connect(m_ui->contentTreeView->header(), &QWidget::customContextMenuRequested, this, &AddNewTorrentDialog::displayColumnHeaderMenu); + loadState(); // Signal / slots connect(m_ui->doNotDeleteTorrentCheckBox, &QCheckBox::clicked, this, &AddNewTorrentDialog::doNotDeleteTorrentClicked); @@ -656,7 +661,7 @@ void AddNewTorrentDialog::populateSavePaths() m_ui->groupBoxDownloadPath->blockSignals(false); } -void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &) +void AddNewTorrentDialog::displayContentTreeMenu() { const QModelIndexList selectedRows = m_ui->contentTreeView->selectionModel()->selectedRows(0); @@ -705,6 +710,7 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &) QMenu *menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); + if (selectedRows.size() == 1) { menu->addAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Rename..."), this, &AddNewTorrentDialog::renameSelectedFile); @@ -755,6 +761,25 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &) menu->popup(QCursor::pos()); } +void AddNewTorrentDialog::displayColumnHeaderMenu() +{ + QMenu *menu = new QMenu(this); + menu->setAttribute(Qt::WA_DeleteOnClose); + menu->setToolTipsVisible(true); + + QAction *resizeAction = menu->addAction(tr("Resize columns"), this, [this]() + { + for (int i = 0, count = m_ui->contentTreeView->header()->count(); i < count; ++i) + { + if (!m_ui->contentTreeView->isColumnHidden(i)) + m_ui->contentTreeView->resizeColumnToContents(i); + } + }); + resizeAction->setToolTip(tr("Resize all non-hidden columns to the size of their contents")); + + menu->popup(QCursor::pos()); +} + void AddNewTorrentDialog::accept() { // TODO: Check if destination actually exists diff --git a/src/gui/addnewtorrentdialog.h b/src/gui/addnewtorrentdialog.h index 3fc6cf4ae..7550b20db 100644 --- a/src/gui/addnewtorrentdialog.h +++ b/src/gui/addnewtorrentdialog.h @@ -78,7 +78,8 @@ public: static void show(const QString &source, QWidget *parent); private slots: - void displayContentTreeMenu(const QPoint &); + void displayContentTreeMenu(); + void displayColumnHeaderMenu(); void updateDiskSpaceLabel(); void onSavePathChanged(const QString &newPath); void onDownloadPathChanged(const QString &newPath); diff --git a/src/gui/categoryfilterwidget.cpp b/src/gui/categoryfilterwidget.cpp index ed2a8e34d..396f2c458 100644 --- a/src/gui/categoryfilterwidget.cpp +++ b/src/gui/categoryfilterwidget.cpp @@ -104,7 +104,7 @@ void CategoryFilterWidget::onCurrentRowChanged(const QModelIndex ¤t, const emit categoryChanged(getCategoryFilter(static_cast(model()), current)); } -void CategoryFilterWidget::showMenu(const QPoint &) +void CategoryFilterWidget::showMenu() { QMenu *menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); diff --git a/src/gui/categoryfilterwidget.h b/src/gui/categoryfilterwidget.h index 161fce968..6ca759b95 100644 --- a/src/gui/categoryfilterwidget.h +++ b/src/gui/categoryfilterwidget.h @@ -48,7 +48,7 @@ signals: private slots: void onCurrentRowChanged(const QModelIndex ¤t, const QModelIndex &previous); - void showMenu(const QPoint &); + void showMenu(); void callUpdateGeometry(); void addCategory(); void addSubcategory(); diff --git a/src/gui/executionlogwidget.cpp b/src/gui/executionlogwidget.cpp index 1e21f7bea..25f42959d 100644 --- a/src/gui/executionlogwidget.cpp +++ b/src/gui/executionlogwidget.cpp @@ -50,18 +50,18 @@ ExecutionLogWidget::ExecutionLogWidget(const Log::MsgTypes types, QWidget *paren LogListView *messageView = new LogListView(this); messageView->setModel(m_messageFilterModel); messageView->setContextMenuPolicy(Qt::CustomContextMenu); - connect(messageView, &LogListView::customContextMenuRequested, this, [this, messageView, messageModel](const QPoint &pos) + connect(messageView, &LogListView::customContextMenuRequested, this, [this, messageView, messageModel]() { - displayContextMenu(pos, messageView, messageModel); + displayContextMenu(messageView, messageModel); }); LogPeerModel *peerModel = new LogPeerModel(this); LogListView *peerView = new LogListView(this); peerView->setModel(peerModel); peerView->setContextMenuPolicy(Qt::CustomContextMenu); - connect(peerView, &LogListView::customContextMenuRequested, this, [this, peerView, peerModel](const QPoint &pos) + connect(peerView, &LogListView::customContextMenuRequested, this, [this, peerView, peerModel]() { - displayContextMenu(pos, peerView, peerModel); + displayContextMenu(peerView, peerModel); }); m_ui->tabGeneral->layout()->addWidget(messageView); @@ -83,7 +83,7 @@ void ExecutionLogWidget::setMessageTypes(const Log::MsgTypes types) m_messageFilterModel->setMessageTypes(types); } -void ExecutionLogWidget::displayContextMenu(const QPoint &pos, const LogListView *view, const BaseLogModel *model) const +void ExecutionLogWidget::displayContextMenu(const LogListView *view, const BaseLogModel *model) const { QMenu *menu = new QMenu; menu->setAttribute(Qt::WA_DeleteOnClose); @@ -98,5 +98,5 @@ void ExecutionLogWidget::displayContextMenu(const QPoint &pos, const LogListView menu->addAction(UIThemeManager::instance()->getIcon("edit-clear"), tr("Clear") , model, &BaseLogModel::reset); - menu->popup(view->mapToGlobal(pos)); + menu->popup(QCursor::pos()); } diff --git a/src/gui/executionlogwidget.h b/src/gui/executionlogwidget.h index 23c92c4eb..e22d136f6 100644 --- a/src/gui/executionlogwidget.h +++ b/src/gui/executionlogwidget.h @@ -52,7 +52,7 @@ public: void setMessageTypes(Log::MsgTypes types); private: - void displayContextMenu(const QPoint &pos, const LogListView *view, const BaseLogModel *model) const; + void displayContextMenu(const LogListView *view, const BaseLogModel *model) const; Ui::ExecutionLogWidget *m_ui; LogFilterModel *m_messageFilterModel; diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 0d7b7ebbf..00eaf82f9 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -28,6 +28,7 @@ #include "mainwindow.h" +#include #include #include @@ -601,9 +602,9 @@ void MainWindow::manageCookies() cookieDialog->open(); } -void MainWindow::toolbarMenuRequested(const QPoint &point) +void MainWindow::toolbarMenuRequested() { - m_toolbarMenu->popup(m_ui->toolBar->mapToGlobal(point)); + m_toolbarMenu->popup(QCursor::pos()); } void MainWindow::toolbarIconsOnly() @@ -708,7 +709,7 @@ void MainWindow::displayRSSTab(bool enable) } } -void MainWindow::showFilterContextMenu(const QPoint &) +void MainWindow::showFilterContextMenu() { const Preferences *pref = Preferences::instance(); @@ -1279,15 +1280,9 @@ bool MainWindow::event(QEvent *e) { qDebug() << "Has active window:" << (qApp->activeWindow() != nullptr); // Check if there is a modal window - bool hasModalWindow = false; - for (QWidget *widget : asConst(QApplication::allWidgets())) - { - if (widget->isModal()) - { - hasModalWindow = true; - break; - } - } + const QWidgetList allWidgets = QApplication::allWidgets(); + const bool hasModalWindow = std::any_of(allWidgets.cbegin(), allWidgets.cend() + , [](const QWidget *widget) { return widget->isModal(); }); // Iconify if there is no modal window if (!hasModalWindow) { diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index 48c27a8d6..907122221 100644 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -112,7 +112,7 @@ signals: void systemTrayIconCreated(); private slots: - void showFilterContextMenu(const QPoint &); + void showFilterContextMenu(); void balloonClicked(); void writeSettings(); void readSettings(); @@ -181,7 +181,7 @@ private slots: // Check for unpaused downloading or seeding torrents and prevent system suspend/sleep according to preferences void updatePowerManagementState(); - void toolbarMenuRequested(const QPoint &point); + void toolbarMenuRequested(); void toolbarIconsOnly(); void toolbarTextOnly(); void toolbarTextBeside(); diff --git a/src/gui/previewselectdialog.cpp b/src/gui/previewselectdialog.cpp index 2d5424005..a51e66e49 100644 --- a/src/gui/previewselectdialog.cpp +++ b/src/gui/previewselectdialog.cpp @@ -28,9 +28,11 @@ #include "previewselectdialog.h" +#include #include #include #include +#include #include #include #include @@ -82,11 +84,11 @@ PreviewSelectDialog::PreviewSelectDialog(QWidget *parent, const BitTorrent::Torr m_ui->previewList->header()->setParent(m_ui->previewList); unused.setVerticalHeader(new QHeaderView(Qt::Horizontal)); + m_ui->previewList->setAlternatingRowColors(pref->useAlternatingRowColors()); m_ui->previewList->setModel(m_previewListModel); m_ui->previewList->hideColumn(FILE_INDEX); m_listDelegate = new PreviewListDelegate(this); m_ui->previewList->setItemDelegate(m_listDelegate); - m_ui->previewList->setAlternatingRowColors(pref->useAlternatingRowColors()); // Fill list in const QVector fp = torrent->filesProgress(); for (int i = 0; i < torrent->filesCount(); ++i) @@ -104,9 +106,12 @@ PreviewSelectDialog::PreviewSelectDialog(QWidget *parent, const BitTorrent::Torr } m_previewListModel->sort(NAME); + m_ui->previewList->header()->setContextMenuPolicy(Qt::CustomContextMenu); m_ui->previewList->header()->setSortIndicator(0, Qt::AscendingOrder); m_ui->previewList->selectionModel()->select(m_previewListModel->index(0, NAME), QItemSelectionModel::Select | QItemSelectionModel::Rows); + connect(m_ui->previewList->header(), &QWidget::customContextMenuRequested, this, &PreviewSelectDialog::displayColumnHeaderMenu); + // Restore dialog state loadWindowState(); } @@ -145,6 +150,25 @@ void PreviewSelectDialog::previewButtonClicked() accept(); } +void PreviewSelectDialog::displayColumnHeaderMenu() +{ + auto menu = new QMenu(this); + menu->setAttribute(Qt::WA_DeleteOnClose); + menu->setToolTipsVisible(true); + + QAction *resizeAction = menu->addAction(tr("Resize columns"), this, [this]() + { + for (int i = 0, count = m_ui->previewList->header()->count(); i < count; ++i) + { + if (!m_ui->previewList->isColumnHidden(i)) + m_ui->previewList->resizeColumnToContents(i); + } + }); + resizeAction->setToolTip(tr("Resize all non-hidden columns to the size of their contents")); + + menu->popup(QCursor::pos()); +} + void PreviewSelectDialog::saveWindowState() { // Persist dialog size diff --git a/src/gui/previewselectdialog.h b/src/gui/previewselectdialog.h index afc09a4a4..874f5cc83 100644 --- a/src/gui/previewselectdialog.h +++ b/src/gui/previewselectdialog.h @@ -68,6 +68,7 @@ signals: private slots: void previewButtonClicked(); + void displayColumnHeaderMenu(); private: void showEvent(QShowEvent *event) override; diff --git a/src/gui/properties/peerlistwidget.cpp b/src/gui/properties/peerlistwidget.cpp index d8572bee4..eb15b6bab 100644 --- a/src/gui/properties/peerlistwidget.cpp +++ b/src/gui/properties/peerlistwidget.cpp @@ -155,7 +155,7 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent) updatePeerHostNameResolutionState(); // SIGNAL/SLOT header()->setContextMenuPolicy(Qt::CustomContextMenu); - connect(header(), &QWidget::customContextMenuRequested, this, &PeerListWidget::displayToggleColumnsMenu); + connect(header(), &QWidget::customContextMenuRequested, this, &PeerListWidget::displayColumnHeaderMenu); connect(header(), &QHeaderView::sectionClicked, this, &PeerListWidget::handleSortColumnChanged); connect(header(), &QHeaderView::sectionMoved, this, &PeerListWidget::saveSettings); connect(header(), &QHeaderView::sectionResized, this, &PeerListWidget::saveSettings); @@ -177,47 +177,46 @@ PeerListWidget::~PeerListWidget() saveSettings(); } -void PeerListWidget::displayToggleColumnsMenu(const QPoint &) +void PeerListWidget::displayColumnHeaderMenu() { QMenu *menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); menu->setTitle(tr("Column visibility")); + menu->setToolTipsVisible(true); for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i) { if ((i == PeerListColumns::COUNTRY) && !Preferences::instance()->resolvePeerCountries()) continue; - QAction *myAct = menu->addAction(m_listModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); - myAct->setCheckable(true); - myAct->setChecked(!isColumnHidden(i)); - myAct->setData(i); + const auto columnName = m_listModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + QAction *action = menu->addAction(columnName, this, [this, i](const bool checked) + { + if (!checked && (visibleColumnsCount() <= 1)) + return; + + setColumnHidden(i, !checked); + + if (checked && (columnWidth(i) <= 5)) + resizeColumnToContents(i); + + saveSettings(); + }); + action->setCheckable(true); + action->setChecked(!isColumnHidden(i)); } - connect(menu, &QMenu::triggered, this, [this](const QAction *action) + menu->addSeparator(); + QAction *resizeAction = menu->addAction(tr("Resize columns"), this, [this]() { - int visibleCols = 0; - for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i) + for (int i = 0, count = header()->count(); i < count; ++i) { if (!isColumnHidden(i)) - ++visibleCols; - - if (visibleCols > 1) - break; + resizeColumnToContents(i); } - - const int col = action->data().toInt(); - - if (!isColumnHidden(col) && (visibleCols == 1)) - return; - - setColumnHidden(col, !isColumnHidden(col)); - - if (!isColumnHidden(col) && (columnWidth(col) <= 5)) - resizeColumnToContents(col); - saveSettings(); }); + resizeAction->setToolTip(tr("Resize all non-hidden columns to the size of their contents")); menu->popup(QCursor::pos()); } @@ -260,7 +259,7 @@ void PeerListWidget::updatePeerCountryResolutionState() } } -void PeerListWidget::showPeerListMenu(const QPoint &) +void PeerListWidget::showPeerListMenu() { BitTorrent::Torrent *torrent = m_properties->getCurrentTorrent(); if (!torrent) return; @@ -492,6 +491,18 @@ void PeerListWidget::updatePeer(const BitTorrent::Torrent *torrent, const BitTor } } +int PeerListWidget::visibleColumnsCount() const +{ + int count = 0; + for (int i = 0, iMax = header()->count(); i < iMax; ++i) + { + if (!isColumnHidden(i)) + ++count; + } + + return count; +} + void PeerListWidget::handleResolved(const QHostAddress &ip, const QString &hostname) const { if (hostname.isEmpty()) diff --git a/src/gui/properties/peerlistwidget.h b/src/gui/properties/peerlistwidget.h index 28ae98b51..44d3b6126 100644 --- a/src/gui/properties/peerlistwidget.h +++ b/src/gui/properties/peerlistwidget.h @@ -88,8 +88,8 @@ public: private slots: void loadSettings(); void saveSettings() const; - void displayToggleColumnsMenu(const QPoint &); - void showPeerListMenu(const QPoint &); + void displayColumnHeaderMenu(); + void showPeerListMenu(); void banSelectedPeers(); void copySelectedPeers(); void handleSortColumnChanged(int col); @@ -97,6 +97,7 @@ private slots: private: void updatePeer(const BitTorrent::Torrent *torrent, const BitTorrent::PeerInfo &peer, bool &isNewPeer); + int visibleColumnsCount() const; void wheelEvent(QWheelEvent *event) override; diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 0ca722131..35d3fd234 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -111,7 +111,7 @@ PropertiesWidget::PropertiesWidget(QWidget *parent) , m_ui->filesList, qOverload(&QAbstractItemView::edit)); connect(m_ui->filesList, &QWidget::customContextMenuRequested, this, &PropertiesWidget::displayFilesListMenu); connect(m_ui->filesList, &QAbstractItemView::doubleClicked, this, &PropertiesWidget::openItem); - connect(m_ui->filesList->header(), &QWidget::customContextMenuRequested, this, &PropertiesWidget::displayFileListHeaderMenu); + connect(m_ui->filesList->header(), &QWidget::customContextMenuRequested, this, &PropertiesWidget::displayColumnHeaderMenu); connect(m_ui->filesList->header(), &QHeaderView::sectionMoved, this, &PropertiesWidget::saveSettings); connect(m_ui->filesList->header(), &QHeaderView::sectionResized, this, &PropertiesWidget::saveSettings); connect(m_ui->filesList->header(), &QHeaderView::sortIndicatorChanged, this, &PropertiesWidget::saveSettings); @@ -177,30 +177,44 @@ PropertiesWidget::~PropertiesWidget() delete m_ui; } -void PropertiesWidget::displayFileListHeaderMenu() +void PropertiesWidget::displayColumnHeaderMenu() { QMenu *menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); + menu->setTitle(tr("Column visibility")); + menu->setToolTipsVisible(true); for (int i = 0; i < TorrentContentModelItem::TreeItemColumns::NB_COL; ++i) { - QAction *myAct = menu->addAction(m_propListModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); - myAct->setCheckable(true); - myAct->setChecked(!m_ui->filesList->isColumnHidden(i)); - if (i == TorrentContentModelItem::TreeItemColumns::COL_NAME) - myAct->setEnabled(false); - - connect(myAct, &QAction::toggled, this, [this, i](const bool checked) + const auto columnName = m_propListModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + QAction *action = menu->addAction(columnName, this, [this, i](const bool checked) { m_ui->filesList->setColumnHidden(i, !checked); - if (!m_ui->filesList->isColumnHidden(i) && (m_ui->filesList->columnWidth(i) <= 5)) + if (checked && (m_ui->filesList->columnWidth(i) <= 5)) m_ui->filesList->resizeColumnToContents(i); saveSettings(); }); + action->setCheckable(true); + action->setChecked(!m_ui->filesList->isColumnHidden(i)); + + if (i == TorrentContentModelItem::TreeItemColumns::COL_NAME) + action->setEnabled(false); } + menu->addSeparator(); + QAction *resizeAction = menu->addAction(tr("Resize columns"), this, [this]() + { + for (int i = 0, count = m_ui->filesList->header()->count(); i < count; ++i) + { + if (!m_ui->filesList->isColumnHidden(i)) + m_ui->filesList->resizeColumnToContents(i); + } + saveSettings(); + }); + resizeAction->setToolTip(tr("Resize all non-hidden columns to the size of their contents")); + menu->popup(QCursor::pos()); } @@ -621,7 +635,7 @@ void PropertiesWidget::openParentFolder(const QModelIndex &index) const #endif } -void PropertiesWidget::displayFilesListMenu(const QPoint &) +void PropertiesWidget::displayFilesListMenu() { if (!m_torrent) return; @@ -728,7 +742,7 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &) menu->popup(QCursor::pos()); } -void PropertiesWidget::displayWebSeedListMenu(const QPoint &) +void PropertiesWidget::displayWebSeedListMenu() { if (!m_torrent) return; diff --git a/src/gui/properties/propertieswidget.h b/src/gui/properties/propertieswidget.h index b66443a56..7c2d00dde 100644 --- a/src/gui/properties/propertieswidget.h +++ b/src/gui/properties/propertieswidget.h @@ -81,7 +81,6 @@ public slots: void readSettings(); void saveSettings(); void reloadPreferences(); - void displayFileListHeaderMenu(); void openItem(const QModelIndex &index) const; void loadTrackers(BitTorrent::Torrent *const torrent); @@ -92,8 +91,8 @@ protected slots: void deleteSelectedUrlSeeds(); void copySelectedWebSeedsToClipboard() const; void editWebSeed(); - void displayFilesListMenu(const QPoint &); - void displayWebSeedListMenu(const QPoint &); + void displayFilesListMenu(); + void displayWebSeedListMenu(); void filteredFilesChanged(); void showPiecesDownloaded(bool show); void showPiecesAvailability(bool show); @@ -101,6 +100,7 @@ protected slots: private slots: void configure(); + void displayColumnHeaderMenu(); void filterText(const QString &filter); void updateSavePath(BitTorrent::Torrent *const torrent); diff --git a/src/gui/properties/trackerlistwidget.cpp b/src/gui/properties/trackerlistwidget.cpp index 55c55591d..e700da7dc 100644 --- a/src/gui/properties/trackerlistwidget.cpp +++ b/src/gui/properties/trackerlistwidget.cpp @@ -86,7 +86,7 @@ TrackerListWidget::TrackerListWidget(PropertiesWidget *properties) connect(this, &QWidget::customContextMenuRequested, this, &TrackerListWidget::showTrackerListMenu); // Header header()->setContextMenuPolicy(Qt::CustomContextMenu); - connect(header(), &QWidget::customContextMenuRequested, this, &TrackerListWidget::displayToggleColumnsMenu); + connect(header(), &QWidget::customContextMenuRequested, this, &TrackerListWidget::displayColumnHeaderMenu); connect(header(), &QHeaderView::sectionMoved, this, &TrackerListWidget::saveSettings); connect(header(), &QHeaderView::sectionResized, this, &TrackerListWidget::saveSettings); connect(header(), &QHeaderView::sortIndicatorChanged, this, &TrackerListWidget::saveSettings); @@ -575,7 +575,7 @@ void TrackerListWidget::reannounceSelected() loadTrackers(); } -void TrackerListWidget::showTrackerListMenu(const QPoint &) +void TrackerListWidget::showTrackerListMenu() { BitTorrent::Torrent *const torrent = m_properties->getCurrentTorrent(); if (!torrent) return; @@ -641,45 +641,52 @@ QStringList TrackerListWidget::headerLabels() int TrackerListWidget::visibleColumnsCount() const { - int visibleCols = 0; - for (int i = 0; i < COL_COUNT; ++i) + int count = 0; + for (int i = 0, iMax = header()->count(); i < iMax; ++i) { if (!isColumnHidden(i)) - ++visibleCols; + ++count; } - return visibleCols; + return count; } -void TrackerListWidget::displayToggleColumnsMenu(const QPoint &) +void TrackerListWidget::displayColumnHeaderMenu() { QMenu *menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); menu->setTitle(tr("Column visibility")); + menu->setToolTipsVisible(true); for (int i = 0; i < COL_COUNT; ++i) { - QAction *myAct = menu->addAction(headerLabels().at(i)); - myAct->setCheckable(true); - myAct->setChecked(!isColumnHidden(i)); - myAct->setData(i); - } - - connect(menu, &QMenu::triggered, this, [this](const QAction *action) - { - const int col = action->data().toInt(); - Q_ASSERT(visibleColumnsCount() > 0); + QAction *action = menu->addAction(headerLabels().at(i), this, [this, i](const bool checked) + { + if (!checked && (visibleColumnsCount() <= 1)) + return; - if (!isColumnHidden(col) && (visibleColumnsCount() == 1)) - return; + setColumnHidden(i, !checked); - setColumnHidden(col, !isColumnHidden(col)); + if (checked && (columnWidth(i) <= 5)) + resizeColumnToContents(i); - if (!isColumnHidden(col) && (columnWidth(col) <= 5)) - resizeColumnToContents(col); + saveSettings(); + }); + action->setCheckable(true); + action->setChecked(!isColumnHidden(i)); + } + menu->addSeparator(); + QAction *resizeAction = menu->addAction(tr("Resize columns"), this, [this]() + { + for (int i = 0, count = header()->count(); i < count; ++i) + { + if (!isColumnHidden(i)) + resizeColumnToContents(i); + } saveSettings(); }); + resizeAction->setToolTip(tr("Resize all non-hidden columns to the size of their contents")); menu->popup(QCursor::pos()); } diff --git a/src/gui/properties/trackerlistwidget.h b/src/gui/properties/trackerlistwidget.h index d93926449..618607214 100644 --- a/src/gui/properties/trackerlistwidget.h +++ b/src/gui/properties/trackerlistwidget.h @@ -61,8 +61,6 @@ public: explicit TrackerListWidget(PropertiesWidget *properties); ~TrackerListWidget(); - int visibleColumnsCount() const; - public slots: void setRowColor(int row, const QColor &color); @@ -77,15 +75,19 @@ public slots: void reannounceSelected(); void deleteSelectedTrackers(); void editSelectedTracker(); - void showTrackerListMenu(const QPoint &); - void displayToggleColumnsMenu(const QPoint &); + void showTrackerListMenu(); void loadSettings(); void saveSettings() const; protected: QVector getSelectedTrackerItems() const; +private slots: + void displayColumnHeaderMenu(); + private: + int visibleColumnsCount() const; + static QStringList headerLabels(); PropertiesWidget *m_properties; diff --git a/src/gui/rss/rsswidget.cpp b/src/gui/rss/rsswidget.cpp index 6e0c6e767..68179fbcd 100644 --- a/src/gui/rss/rsswidget.cpp +++ b/src/gui/rss/rsswidget.cpp @@ -192,7 +192,7 @@ void RSSWidget::displayRSSListMenu(const QPoint &pos) menu->popup(QCursor::pos()); } -void RSSWidget::displayItemsListMenu(const QPoint &) +void RSSWidget::displayItemsListMenu() { bool hasTorrent = false; bool hasLink = false; diff --git a/src/gui/rss/rsswidget.h b/src/gui/rss/rsswidget.h index 229bd51de..01beebf81 100644 --- a/src/gui/rss/rsswidget.h +++ b/src/gui/rss/rsswidget.h @@ -62,8 +62,8 @@ private slots: void on_newFeedButton_clicked(); void refreshAllFeeds(); void on_markReadButton_clicked(); - void displayRSSListMenu(const QPoint &); - void displayItemsListMenu(const QPoint &); + void displayRSSListMenu(const QPoint &pos); + void displayItemsListMenu(); void renameSelectedRSSItem(); void refreshSelectedItems(); void copySelectedFeedsURL(); diff --git a/src/gui/search/pluginselectdialog.cpp b/src/gui/search/pluginselectdialog.cpp index 9ab36b187..b7fa25cf3 100644 --- a/src/gui/search/pluginselectdialog.cpp +++ b/src/gui/search/pluginselectdialog.cpp @@ -174,7 +174,7 @@ void PluginSelectDialog::togglePluginState(QTreeWidgetItem *item, int) } } -void PluginSelectDialog::displayContextMenu(const QPoint &) +void PluginSelectDialog::displayContextMenu() { // Enable/disable pause/start action given the DL state const QList items = m_ui->pluginsTree->selectedItems(); diff --git a/src/gui/search/pluginselectdialog.h b/src/gui/search/pluginselectdialog.h index d5109f4d2..1ff280a13 100644 --- a/src/gui/search/pluginselectdialog.h +++ b/src/gui/search/pluginselectdialog.h @@ -71,7 +71,7 @@ private slots: void on_closeButton_clicked(); void togglePluginState(QTreeWidgetItem*, int); void setRowColor(int row, const QString &color); - void displayContextMenu(const QPoint &); + void displayContextMenu(); void enableSelection(bool enable); void askForLocalPlugin(); void askForPluginUrl(); diff --git a/src/gui/search/searchjobwidget.cpp b/src/gui/search/searchjobwidget.cpp index 06f0a18e0..d65689ab0 100644 --- a/src/gui/search/searchjobwidget.cpp +++ b/src/gui/search/searchjobwidget.cpp @@ -116,11 +116,13 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent) // its size is 0, because explicitly 'showing' the column isn't enough // in the above scenario. for (int i = 0; i < SearchSortModel::DL_LINK; ++i) + { if ((m_ui->resultsBrowser->columnWidth(i) <= 0) && !m_ui->resultsBrowser->isColumnHidden(i)) m_ui->resultsBrowser->resizeColumnToContents(i); + } header()->setContextMenuPolicy(Qt::CustomContextMenu); - connect(header(), &QWidget::customContextMenuRequested, this, &SearchJobWidget::displayToggleColumnsMenu); + connect(header(), &QWidget::customContextMenuRequested, this, &SearchJobWidget::displayColumnHeaderMenu); connect(header(), &QHeaderView::sectionResized, this, &SearchJobWidget::saveSettings); connect(header(), &QHeaderView::sectionMoved, this, &SearchJobWidget::saveSettings); connect(header(), &QHeaderView::sortIndicatorChanged, this, &SearchJobWidget::saveSettings); @@ -373,7 +375,7 @@ void SearchJobWidget::filterSearchResults(const QString &name) updateResultsCount(); } -void SearchJobWidget::showFilterContextMenu(const QPoint &) +void SearchJobWidget::showFilterContextMenu() { const Preferences *pref = Preferences::instance(); @@ -450,44 +452,55 @@ void SearchJobWidget::saveSettings() const Preferences::instance()->setSearchTabHeaderState(header()->saveState()); } -void SearchJobWidget::displayToggleColumnsMenu(const QPoint &) +int SearchJobWidget::visibleColumnsCount() const +{ + int count = 0; + for (int i = 0, iMax = m_ui->resultsBrowser->header()->count(); i < iMax; ++i) + { + if (!m_ui->resultsBrowser->isColumnHidden(i)) + ++count; + } + + return count; +} + +void SearchJobWidget::displayColumnHeaderMenu() { auto menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); menu->setTitle(tr("Column visibility")); + menu->setToolTipsVisible(true); for (int i = 0; i < SearchSortModel::DL_LINK; ++i) { - QAction *myAct = menu->addAction(m_searchListModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); - myAct->setCheckable(true); - myAct->setChecked(!m_ui->resultsBrowser->isColumnHidden(i)); - myAct->setData(i); + const auto columnName = m_searchListModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + QAction *action = menu->addAction(columnName, this, [this, i](const bool checked) + { + if (!checked && (visibleColumnsCount() <= 1)) + return; + + m_ui->resultsBrowser->setColumnHidden(i, !checked); + + if (checked && (m_ui->resultsBrowser->columnWidth(i) <= 5)) + m_ui->resultsBrowser->resizeColumnToContents(i); + + saveSettings(); + }); + action->setCheckable(true); + action->setChecked(!m_ui->resultsBrowser->isColumnHidden(i)); } - connect(menu, &QMenu::triggered, this, [this](const QAction *action) + menu->addSeparator(); + QAction *resizeAction = menu->addAction(tr("Resize columns"), this, [this]() { - int visibleCols = 0; - for (int i = 0; i < SearchSortModel::DL_LINK; ++i) + for (int i = 0, count = m_ui->resultsBrowser->header()->count(); i < count; ++i) { if (!m_ui->resultsBrowser->isColumnHidden(i)) - ++visibleCols; - - if (visibleCols > 1) - break; + m_ui->resultsBrowser->resizeColumnToContents(i); } - - const int col = action->data().toInt(); - - if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (visibleCols == 1)) - return; - - m_ui->resultsBrowser->setColumnHidden(col, !m_ui->resultsBrowser->isColumnHidden(col)); - - if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (m_ui->resultsBrowser->columnWidth(col) <= 5)) - m_ui->resultsBrowser->resizeColumnToContents(col); - saveSettings(); }); + resizeAction->setToolTip(tr("Resize all non-hidden columns to the size of their contents")); menu->popup(QCursor::pos()); } diff --git a/src/gui/search/searchjobwidget.h b/src/gui/search/searchjobwidget.h index ee6ce0b6c..61052168d 100644 --- a/src/gui/search/searchjobwidget.h +++ b/src/gui/search/searchjobwidget.h @@ -88,6 +88,9 @@ signals: protected: void keyPressEvent(QKeyEvent *event) override; +private slots: + void displayColumnHeaderMenu(); + private: enum class AddTorrentOption { @@ -100,9 +103,8 @@ private: void saveSettings() const; void updateFilter(); void filterSearchResults(const QString &name); - void showFilterContextMenu(const QPoint &); + void showFilterContextMenu(); void contextMenuEvent(QContextMenuEvent *event) override; - void displayToggleColumnsMenu(const QPoint &); void onItemDoubleClicked(const QModelIndex &index); void searchFinished(bool cancelled); void searchFailed(); @@ -115,6 +117,7 @@ private: NameFilteringMode filteringMode() const; QHeaderView *header() const; void setRowColor(int row, const QColor &color); + int visibleColumnsCount() const; void downloadTorrents(AddTorrentOption option = AddTorrentOption::Default); void openTorrentPages() const; diff --git a/src/gui/tagfilterwidget.cpp b/src/gui/tagfilterwidget.cpp index ab14e45cc..075ab1346 100644 --- a/src/gui/tagfilterwidget.cpp +++ b/src/gui/tagfilterwidget.cpp @@ -102,7 +102,7 @@ void TagFilterWidget::onCurrentRowChanged(const QModelIndex ¤t, const QMod emit tagChanged(getTagFilter(static_cast(model()), current)); } -void TagFilterWidget::showMenu(QPoint) +void TagFilterWidget::showMenu() { QMenu *menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); diff --git a/src/gui/tagfilterwidget.h b/src/gui/tagfilterwidget.h index 55a5f1364..6689f4b39 100644 --- a/src/gui/tagfilterwidget.h +++ b/src/gui/tagfilterwidget.h @@ -47,7 +47,7 @@ signals: private slots: void onCurrentRowChanged(const QModelIndex ¤t, const QModelIndex &previous); - void showMenu(QPoint); + void showMenu(); void callUpdateGeometry(); void addTag(); void removeTag(); diff --git a/src/gui/transferlistfilterswidget.cpp b/src/gui/transferlistfilterswidget.cpp index 042e955b2..3d51ec170 100644 --- a/src/gui/transferlistfilterswidget.cpp +++ b/src/gui/transferlistfilterswidget.cpp @@ -286,7 +286,7 @@ void StatusFilterWidget::updateTorrentNumbers() item(TorrentFilter::Errored)->setData(Qt::DisplayRole, tr("Errored (%1)").arg(nbErrored)); } -void StatusFilterWidget::showMenu(const QPoint &) {} +void StatusFilterWidget::showMenu() {} void StatusFilterWidget::applyFilter(int row) { @@ -558,7 +558,7 @@ void TrackerFiltersList::handleFavicoDownloadFinished(const Net::DownloadResult } } -void TrackerFiltersList::showMenu(const QPoint &) +void TrackerFiltersList::showMenu() { QMenu *menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); diff --git a/src/gui/transferlistfilterswidget.h b/src/gui/transferlistfilterswidget.h index 0a0f39491..2fef31aad 100644 --- a/src/gui/transferlistfilterswidget.h +++ b/src/gui/transferlistfilterswidget.h @@ -68,7 +68,7 @@ protected: TransferListWidget *transferList; private slots: - virtual void showMenu(const QPoint &) = 0; + virtual void showMenu() = 0; virtual void applyFilter(int row) = 0; virtual void handleNewTorrent(BitTorrent::Torrent *const) = 0; virtual void torrentAboutToBeDeleted(BitTorrent::Torrent *const) = 0; @@ -89,7 +89,7 @@ private slots: private: // These 4 methods are virtual slots in the base class. // No need to redeclare them here as slots. - void showMenu(const QPoint &) override; + void showMenu() override; void applyFilter(int row) override; void handleNewTorrent(BitTorrent::Torrent *const) override; void torrentAboutToBeDeleted(BitTorrent::Torrent *const) override; @@ -121,7 +121,7 @@ private slots: private: // These 4 methods are virtual slots in the base class. // No need to redeclare them here as slots. - void showMenu(const QPoint &) override; + void showMenu() override; void applyFilter(int row) override; void handleNewTorrent(BitTorrent::Torrent *const torrent) override; void torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent) override; diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 00aac45e3..1ed54974f 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -195,8 +195,10 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow) //end up being size 0 when the new version is launched with //a conf file from the previous version. for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i) + { if ((columnWidth(i) <= 0) && (!isColumnHidden(i))) resizeColumnToContents(i); + } setContextMenuPolicy(Qt::CustomContextMenu); @@ -204,7 +206,7 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow) connect(this, &QAbstractItemView::doubleClicked, this, &TransferListWidget::torrentDoubleClicked); connect(this, &QWidget::customContextMenuRequested, this, &TransferListWidget::displayListMenu); header()->setContextMenuPolicy(Qt::CustomContextMenu); - connect(header(), &QWidget::customContextMenuRequested, this, &TransferListWidget::displayDLHoSMenu); + connect(header(), &QWidget::customContextMenuRequested, this, &TransferListWidget::displayColumnHeaderMenu); connect(header(), &QHeaderView::sectionMoved, this, &TransferListWidget::saveSettings); connect(header(), &QHeaderView::sectionResized, this, &TransferListWidget::saveSettings); connect(header(), &QHeaderView::sortIndicatorChanged, this, &TransferListWidget::saveSettings); @@ -623,48 +625,59 @@ void TransferListWidget::reannounceSelectedTorrents() torrent->forceReannounce(); } +int TransferListWidget::visibleColumnsCount() const +{ + int count = 0; + for (int i = 0, iMax = header()->count(); i < iMax; ++i) + { + if (!isColumnHidden(i)) + ++count; + } + + return count; +} + // hide/show columns menu -void TransferListWidget::displayDLHoSMenu(const QPoint&) +void TransferListWidget::displayColumnHeaderMenu() { auto menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); menu->setTitle(tr("Column visibility")); + menu->setToolTipsVisible(true); - for (int i = 0; i < m_listModel->columnCount(); ++i) + for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i) { if (!BitTorrent::Session::instance()->isQueueingSystemEnabled() && (i == TransferListModel::TR_QUEUE_POSITION)) continue; - QAction *myAct = menu->addAction(m_listModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); - myAct->setCheckable(true); - myAct->setChecked(!isColumnHidden(i)); - myAct->setData(i); + const auto columnName = m_listModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + QAction *action = menu->addAction(columnName, this, [this, i](const bool checked) + { + if (!checked && (visibleColumnsCount() <= 1)) + return; + + setColumnHidden(i, !checked); + + if (checked && (columnWidth(i) <= 5)) + resizeColumnToContents(i); + + saveSettings(); + }); + action->setCheckable(true); + action->setChecked(!isColumnHidden(i)); } - connect(menu, &QMenu::triggered, this, [this](const QAction *action) + menu->addSeparator(); + QAction *resizeAction = menu->addAction(tr("Resize columns"), this, [this]() { - int visibleCols = 0; - for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i) + for (int i = 0, count = header()->count(); i < count; ++i) { if (!isColumnHidden(i)) - ++visibleCols; - - if (visibleCols > 1) - break; + resizeColumnToContents(i); } - - const int col = action->data().toInt(); - - if (!isColumnHidden(col) && visibleCols == 1) - return; - - setColumnHidden(col, !isColumnHidden(col)); - - if (!isColumnHidden(col) && columnWidth(col) <= 5) - resizeColumnToContents(col); - saveSettings(); }); + resizeAction->setToolTip(tr("Resize all non-hidden columns to the size of their contents")); menu->popup(QCursor::pos()); } @@ -832,7 +845,7 @@ void TransferListWidget::clearSelectionTags() applyToSelectedTorrents([](BitTorrent::Torrent *const torrent) { torrent->removeAllTags(); }); } -void TransferListWidget::displayListMenu(const QPoint &) +void TransferListWidget::displayListMenu() { const QModelIndexList selectedIndexes = selectionModel()->selectedRows(); if (selectedIndexes.isEmpty()) return; diff --git a/src/gui/transferlistwidget.h b/src/gui/transferlistwidget.h index 7b83fbabf..4db8bb725 100644 --- a/src/gui/transferlistwidget.h +++ b/src/gui/transferlistwidget.h @@ -91,7 +91,6 @@ public slots: void setTorrentOptions(); void previewSelectedTorrents(); void hideQueuePosColumn(bool hide); - void displayDLHoSMenu(const QPoint &); void applyNameFilter(const QString &name); void applyStatusFilter(int f); void applyCategoryFilter(const QString &category); @@ -106,7 +105,8 @@ signals: private slots: void torrentDoubleClicked(); - void displayListMenu(const QPoint &); + void displayListMenu(); + void displayColumnHeaderMenu(); void currentChanged(const QModelIndex ¤t, const QModelIndex&) override; void setSelectedTorrentsSuperSeeding(bool enabled) const; void setSelectedTorrentsSequentialDownload(bool enabled) const; @@ -127,6 +127,7 @@ private: QStringList askTagsForSelection(const QString &dialogTitle); void applyToSelectedTorrents(const std::function &fn); QVector getVisibleTorrents() const; + int visibleColumnsCount() const; TransferListModel *m_listModel; TransferListSortModel *m_sortFilterModel;