diff --git a/src/admc/console_widget/console_widget.cpp b/src/admc/console_widget/console_widget.cpp index 1df7078e..c64cd06f 100644 --- a/src/admc/console_widget/console_widget.cpp +++ b/src/admc/console_widget/console_widget.cpp @@ -228,7 +228,7 @@ ConsoleWidget::ConsoleWidget(QWidget *parent) connect( d->scope_view, &QWidget::customContextMenuRequested, - d, &ConsoleWidgetPrivate::context_menu); + d, &ConsoleWidgetPrivate::on_context_menu); connect( qApp, &QApplication::focusChanged, @@ -238,26 +238,18 @@ ConsoleWidget::ConsoleWidget(QWidget *parent) d->update_view_actions(); } -void ConsoleWidget::connect_to_action_menu(QMenu *action_menu_arg) { - d->action_menu = action_menu_arg; +void ConsoleWidgetPrivate::on_context_menu(const QPoint &pos) { + const QModelIndex index = focused_view->indexAt(pos); - // Update actions right before action menu opens - connect( - d->action_menu, &QMenu::aboutToShow, - d, &ConsoleWidgetPrivate::on_action_menu_show); + if (index.isValid()) { + const QPoint global_pos = focused_view->mapToGlobal(pos); - // Open action menu as context menu for central widget - connect( - d, &ConsoleWidgetPrivate::context_menu, - [=](const QPoint pos) { - const QModelIndex index = d->focused_view->indexAt(pos); - - if (index.isValid()) { - const QPoint global_pos = d->focused_view->mapToGlobal(pos); - - d->action_menu->exec(global_pos); - } - }); + auto menu = new QMenu(q); + menu->setAttribute(Qt::WA_DeleteOnClose); + q->add_actions(menu); + q->update_actions(); + menu->popup(global_pos); + } } void ConsoleWidget::register_impl(const int type, ConsoleImpl *impl) { @@ -284,7 +276,7 @@ void ConsoleWidget::register_impl(const int type, ConsoleImpl *impl) { d, &ConsoleWidgetPrivate::on_results_activated); connect( results_view, &ResultsView::context_menu, - d, &ConsoleWidgetPrivate::context_menu); + d, &ConsoleWidgetPrivate::on_context_menu); } } @@ -579,10 +571,30 @@ void ConsoleWidgetPrivate::on_results_activated(const QModelIndex &index) { // Show/hide actions based on what's selected and emit the // signal -void ConsoleWidgetPrivate::on_action_menu_show() { - action_menu->clear(); +void ConsoleWidget::add_actions(QMenu *menu) { + // Add custom actions + const QList custom_action_list = d->get_custom_action_list(); - const QList selected_list = get_all_selected_items(); + for (QAction *action : custom_action_list) { + menu->addAction(action); + } + + menu->addSeparator(); + + // Add standard actions + menu->addAction(d->standard_action_map[StandardAction_Copy]); + menu->addAction(d->standard_action_map[StandardAction_Cut]); + menu->addAction(d->standard_action_map[StandardAction_Rename]); + menu->addAction(d->standard_action_map[StandardAction_Delete]); + menu->addAction(d->standard_action_map[StandardAction_Paste]); + menu->addAction(d->standard_action_map[StandardAction_Print]); + menu->addAction(d->standard_action_map[StandardAction_Refresh]); + menu->addSeparator(); + menu->addAction(d->standard_action_map[StandardAction_Properties]); +} + +void ConsoleWidget::update_actions() { + const QList selected_list = d->get_all_selected_items(); if (!selected_list.isEmpty() && !selected_list[0].isValid()) { return; @@ -591,43 +603,16 @@ void ConsoleWidgetPrivate::on_action_menu_show() { const bool single_selection = (selected_list.size() == 1); // - // Custom actions + // Collect information about action state from impl's // - const QSet type_set = get_selected_types(); - - // First, add all possible custom actions - const QList custom_action_list = [&]() { - QList out; - - for (const int type : type_set) { - ConsoleImpl *impl = impl_map[type]; - QList for_this_type = impl->get_all_custom_actions(); - - for (QAction *action : for_this_type) { - if (!out.contains(action)) { - out.append(action); - } - } - } - - return out; - }(); - - for (QAction *action : custom_action_list) { - action_menu->addAction(action); - } - - action_menu->addSeparator(); - - // Then show/hide custom actions const QSet visible_custom_action_set = [&]() { QSet out; for (int i = 0; i < selected_list.size(); i++) { const QModelIndex index = selected_list[i]; - ConsoleImpl *impl = get_impl(index); + ConsoleImpl *impl = d->get_impl(index); QSet for_this_index = impl->get_custom_actions(index, single_selection); if (i == 0) { @@ -649,7 +634,7 @@ void ConsoleWidgetPrivate::on_action_menu_show() { for (int i = 0; i < selected_list.size(); i++) { const QModelIndex index = selected_list[i]; - ConsoleImpl *impl = get_impl(index); + ConsoleImpl *impl = d->get_impl(index); QSet for_this_index = impl->get_disabled_custom_actions(index, single_selection); if (i == 0) { @@ -665,42 +650,13 @@ void ConsoleWidgetPrivate::on_action_menu_show() { return out; }(); - // Set visibility state for custom actions - for (QAction *action : custom_action_list) { - const bool visible = visible_custom_action_set.contains(action); - - action->setVisible(visible); - } - - // Set enabled state for custom actions - for (QAction *action : custom_action_list) { - const bool disabled = disabled_custom_action_set.contains(action); - - action->setDisabled(disabled); - } - - // - // Standard actions - // - - // Add all actions first - action_menu->addAction(standard_action_map[StandardAction_Copy]); - action_menu->addAction(standard_action_map[StandardAction_Cut]); - action_menu->addAction(standard_action_map[StandardAction_Rename]); - action_menu->addAction(standard_action_map[StandardAction_Delete]); - action_menu->addAction(standard_action_map[StandardAction_Paste]); - action_menu->addAction(standard_action_map[StandardAction_Print]); - action_menu->addAction(standard_action_map[StandardAction_Refresh]); - action_menu->addSeparator(); - action_menu->addAction(standard_action_map[StandardAction_Properties]); - const QSet visible_standard_actions = [&]() { QSet out; for (int i = 0; i < selected_list.size(); i++) { const QModelIndex index = selected_list[i]; - ConsoleImpl *impl = get_impl(index); + ConsoleImpl *impl = d->get_impl(index); QSet for_this_index = impl->get_standard_actions(index, single_selection); if (i == 0) { @@ -722,7 +678,7 @@ void ConsoleWidgetPrivate::on_action_menu_show() { for (int i = 0; i < selected_list.size(); i++) { const QModelIndex index = selected_list[i]; - ConsoleImpl *impl = get_impl(index); + ConsoleImpl *impl = d->get_impl(index); QSet for_this_index = impl->get_disabled_standard_actions(index, single_selection); if (i == 0) { @@ -738,19 +694,39 @@ void ConsoleWidgetPrivate::on_action_menu_show() { return out; }(); - // Set visibility state for standard actions - for (const StandardAction &action_enum : standard_action_list) { - const bool visible = visible_standard_actions.contains(action_enum); + // + // Apply action state + // + + const QList custom_action_list = d->get_custom_action_list(); + + // Show/hide custom actions + for (QAction *action : custom_action_list) { + const bool visible = visible_custom_action_set.contains(action); - QAction *action = standard_action_map[action_enum]; action->setVisible(visible); } - // Set enabled state for standard actions + // Enable/disable custom actions + for (QAction *action : custom_action_list) { + const bool disabled = disabled_custom_action_set.contains(action); + + action->setDisabled(disabled); + } + + // Show/hide standard actions + for (const StandardAction &action_enum : standard_action_list) { + const bool visible = visible_standard_actions.contains(action_enum); + + QAction *action = d->standard_action_map[action_enum]; + action->setVisible(visible); + } + + // Enable/disable standard actions for (const StandardAction &action_enum : standard_action_list) { const bool disabled = disabled_standard_actions.contains(action_enum); - QAction *action = standard_action_map[action_enum]; + QAction *action = d->standard_action_map[action_enum]; action->setDisabled(disabled); } } @@ -1211,3 +1187,21 @@ QSet ConsoleWidgetPrivate::get_selected_types() const { return out; } + +// Get all custom actions from impl's, in order +QList ConsoleWidgetPrivate::get_custom_action_list() const { + QList out; + + for (const int type : impl_map.keys()) { + ConsoleImpl *impl = impl_map[type]; + QList for_this_type = impl->get_all_custom_actions(); + + for (QAction *action : for_this_type) { + if (!out.contains(action)) { + out.append(action); + } + } + } + + return out; +} diff --git a/src/admc/console_widget/console_widget.h b/src/admc/console_widget/console_widget.h index 20d7a22f..d52e6eac 100644 --- a/src/admc/console_widget/console_widget.h +++ b/src/admc/console_widget/console_widget.h @@ -135,7 +135,15 @@ public: void set_scope_view_visible(const bool visible); - void connect_to_action_menu(QMenu *action_menu); + // Adds actions to a menu. Actions come from console + // itself as well as impl's. All impl's must be + // registered before this is called. + void add_actions(QMenu *menu); + + // Updates visibility and disability state of actions + // based on current selection. Call before showing the + // menu that contains console actions. + void update_actions(); QAction *refresh_current_scope_action() const; QAction *navigate_up_action() const; diff --git a/src/admc/console_widget/console_widget_p.h b/src/admc/console_widget/console_widget_p.h index a3580c16..6868bbbf 100644 --- a/src/admc/console_widget/console_widget_p.h +++ b/src/admc/console_widget/console_widget_p.h @@ -37,7 +37,6 @@ class ScopeProxyModel; class ConsoleDragModel; class QStandardItemModel; class ConsoleWidget; -class QMenu; class QSplitter; class ConsoleImpl; @@ -94,16 +93,13 @@ public: QList targets_past; QList targets_future; - QMenu *action_menu; QHash standard_action_map; ConsoleWidgetPrivate(ConsoleWidget *q_arg); - void open_action_menu_as_context_menu(const QPoint pos); void on_scope_expanded(const QModelIndex &index); void on_results_activated(const QModelIndex &index); - void on_action_menu_show(); - void on_context_menu(const QPoint pos); + void on_context_menu(const QPoint &pos); void update_navigation_actions(); void update_view_actions(); void on_current_scope_item_changed(const QModelIndex ¤t, const QModelIndex &); @@ -130,9 +126,7 @@ public: void on_standard_action(const StandardAction action_enum); QList get_all_selected_items() const; QSet get_selected_types() const; - -signals: - void context_menu(const QPoint pos); + QList get_custom_action_list() const; }; #endif /* CONSOLE_WIDGET_P_H */ diff --git a/src/admc/find_object_dialog.cpp b/src/admc/find_object_dialog.cpp index 36d35b52..7bdc9e53 100644 --- a/src/admc/find_object_dialog.cpp +++ b/src/admc/find_object_dialog.cpp @@ -25,6 +25,7 @@ #include "find_widget.h" #include "globals.h" #include "settings.h" +#include "console_widget/console_widget.h" #include #include @@ -46,7 +47,14 @@ FindObjectDialog::FindObjectDialog(const QList classes, const QString d layout->setMenuBar(menubar); layout->addWidget(find_widget); - find_widget->find_results->add_actions(action_menu, view_menu); + ConsoleWidget *console = find_widget->find_results->console; + console->add_actions(action_menu); + + view_menu->addAction(console->customize_columns_action()); settings_setup_dialog_geometry(SETTING_find_object_dialog_geometry, this); + + connect( + action_menu, &QMenu::aboutToShow, + console, &ConsoleWidget::update_actions); } diff --git a/src/admc/find_results.cpp b/src/admc/find_results.cpp index fcbb11ed..487fe9c5 100644 --- a/src/admc/find_results.cpp +++ b/src/admc/find_results.cpp @@ -79,12 +79,6 @@ FindResults::~FindResults() { settings_set_variant(SETTING_find_results_state, state); } -void FindResults::add_actions(QMenu *action_menu, QMenu *view_menu) { - console->connect_to_action_menu(action_menu); - - view_menu->addAction(console->customize_columns_action()); -} - void FindResults::clear() { console->delete_children(head_index); } diff --git a/src/admc/find_results.h b/src/admc/find_results.h index 126bd812..9758aca9 100644 --- a/src/admc/find_results.h +++ b/src/admc/find_results.h @@ -39,6 +39,8 @@ class FindResults final : public QWidget { Q_OBJECT public: + ConsoleWidget *console; + FindResults(); ~FindResults(); @@ -50,10 +52,7 @@ public: // NOTE: returned items need to be re-parented or deleted! QList> get_selected_rows() const; - void add_actions(QMenu *action_menu, QMenu *view_menu); - private: - ConsoleWidget *console; QPersistentModelIndex head_index; }; diff --git a/src/admc/main_window.cpp b/src/admc/main_window.cpp index 9d6fda68..f3406978 100644 --- a/src/admc/main_window.cpp +++ b/src/admc/main_window.cpp @@ -182,7 +182,7 @@ MainWindow::MainWindow() file_menu->addAction(quit_action); // Action - console->connect_to_action_menu(action_menu); + console->add_actions(action_menu); // View view_menu->addAction(console->set_results_to_icons_action()); @@ -277,6 +277,10 @@ MainWindow::MainWindow() this, &MainWindow::on_connect_options_dialog_accepted); on_connect_options_dialog_accepted(); + connect( + action_menu, &QMenu::aboutToShow, + console, &ConsoleWidget::update_actions); + const bool restored_geometry = settings_restore_geometry(SETTING_main_window_geometry, this); if (!restored_geometry) { resize(1024, 768);