From a802000a2e6d078a9875d6fef3f7a1630414da04 Mon Sep 17 00:00:00 2001 From: Roland Knall Date: Tue, 5 Nov 2019 11:41:18 +0000 Subject: [PATCH] Qt: Allow action buttons to be left-aligned Buttons can be left-aligned in the display filter edit bar, by selecting the corresponding option from the context menu Bug: 14123 Change-Id: I18b48bb0ea43a598b2e309dcad9210463be06414 Reviewed-on: https://code.wireshark.org/review/34980 Reviewed-by: Roland Knall --- docbook/release-notes.adoc | 1 + ui/qt/widgets/display_filter_edit.cpp | 213 +++++++++++++++----------- ui/qt/widgets/display_filter_edit.h | 6 + ui/recent.c | 9 ++ ui/recent.h | 1 + 5 files changed, 143 insertions(+), 87 deletions(-) diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index 5d9e80e7fd..cd8ac43164 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -39,6 +39,7 @@ since version 3.1.0: * The Windows packages are now built using Microsoft Visual Studio 2019. * IOGraph automatically adds a graph for the selected display filter if no previous graph exists +* Action buttons for the display filter bar may be aligned left via the context menu The following features are new (or have been significantly updated) since version 3.0.0: diff --git a/ui/qt/widgets/display_filter_edit.cpp b/ui/qt/widgets/display_filter_edit.cpp index 97eee6e965..95858c1874 100644 --- a/ui/qt/widgets/display_filter_edit.cpp +++ b/ui/qt/widgets/display_filter_edit.cpp @@ -13,7 +13,7 @@ #include -#include +#include #include @@ -66,7 +66,8 @@ DisplayFilterEdit::DisplayFilterEdit(QWidget *parent, DisplayFilterEditType type actions_(Q_NULLPTR), bookmark_button_(NULL), clear_button_(NULL), - apply_button_(NULL) + apply_button_(NULL), + leftAlignActions_(false) { setAccessibleName(tr("Display filter entry")); @@ -76,77 +77,108 @@ DisplayFilterEdit::DisplayFilterEdit(QWidget *parent, DisplayFilterEditType type setDefaultPlaceholderText(); - // DFCombo - // Bookmark - // DisplayFilterEdit - // Clear button - // Apply (right arrow) - // Combo drop-down + QString buttonStyle = QString( + "QToolButton {" + " border: none;" + " background: transparent;" // Disables platform style on Windows. + " padding: 0 0 0 0;" + "}" + "QToolButton::menu-indicator {" + " image: none;" + "}" + ); if (type_ == DisplayFilterToApply) { bookmark_button_ = new StockIconToolButton(this, "x-display-filter-bookmark"); - bookmark_button_->setCursor(Qt::ArrowCursor); bookmark_button_->setMenu(new QMenu(bookmark_button_)); bookmark_button_->setPopupMode(QToolButton::InstantPopup); bookmark_button_->setToolTip(tr("Manage saved bookmarks.")); bookmark_button_->setIconSize(QSize(14, 14)); - bookmark_button_->setStyleSheet( - "QToolButton {" - " border: none;" - " background: transparent;" // Disables platform style on Windows. - " padding: 0 0 0 0;" - "}" - "QToolButton::menu-indicator { image: none; }" - ); + bookmark_button_->setStyleSheet(buttonStyle); clear_button_ = new StockIconToolButton(this, "x-filter-clear"); - clear_button_->setCursor(Qt::ArrowCursor); clear_button_->setToolTip(tr("Clear display filter")); clear_button_->setIconSize(QSize(14, 14)); - clear_button_->setStyleSheet( - "QToolButton {" - " border: none;" - " background: transparent;" // Disables platform style on Windows. - " padding: 0 0 0 0;" - " margin-left: 1px;" - "}" - ); + clear_button_->setStyleSheet(buttonStyle); + clear_button_->setVisible(false); + + apply_button_ = new StockIconToolButton(this, "x-filter-apply"); + apply_button_->setEnabled(false); + apply_button_->setToolTip(tr("Apply display filter")); + apply_button_->setIconSize(QSize(24, 14)); + apply_button_->setStyleSheet(buttonStyle); + connect(clear_button_, &StockIconToolButton::clicked, this, &DisplayFilterEdit::clearFilter); + connect(apply_button_, &StockIconToolButton::clicked, this, &DisplayFilterEdit::applyDisplayFilter); + connect(this, &DisplayFilterEdit::returnPressed, this, &DisplayFilterEdit::applyDisplayFilter); } connect(this, &DisplayFilterEdit::textChanged, this, static_cast(&DisplayFilterEdit::checkFilter)); + connect(wsApp, &WiresharkApplication::appInitialized, this, &DisplayFilterEdit::updateBookmarkMenu); + connect(wsApp, &WiresharkApplication::displayFilterListChanged, this, &DisplayFilterEdit::updateBookmarkMenu); + + leftAlignActions_ = recent.gui_geometry_leftalign_actions; + + alignActionButtons(); +} + +void DisplayFilterEdit::contextMenuEvent(QContextMenuEvent *event){ + QMenu *menu = this->createStandardContextMenu(); + menu->addSeparator(); + QAction * na = new QAction(tr("Left align buttons")); + na->setCheckable(true); + na->setChecked(leftAlignActions_); + connect(na, &QAction::triggered, this, &DisplayFilterEdit::triggerAlignementAction); + menu->addAction(na); + menu->exec(event->globalPos()); +} + +void DisplayFilterEdit::triggerAlignementAction() +{ + leftAlignActions_ = ! leftAlignActions_; + if ( qobject_cast(sender()) ) + qobject_cast(sender())->setChecked(leftAlignActions_); + + recent.gui_geometry_leftalign_actions = leftAlignActions_; + write_recent(); + + alignActionButtons(); +} + +void DisplayFilterEdit::alignActionButtons() +{ + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + QSize bksz, cbsz, apsz; + bksz = apsz = cbsz = QSize(0,0); + if (type_ == DisplayFilterToApply) { - apply_button_ = new StockIconToolButton(this, "x-filter-apply"); - apply_button_->setCursor(Qt::ArrowCursor); - apply_button_->setEnabled(false); - apply_button_->setToolTip(tr("Apply display filter")); - apply_button_->setIconSize(QSize(24, 14)); - apply_button_->setStyleSheet( - "QToolButton {" - " border: none;" - " background: transparent;" // Disables platform style on Windows. - " padding: 0 0 0 0;" - "}" - ); - connect(apply_button_, &StockIconToolButton::clicked, this, &DisplayFilterEdit::applyDisplayFilter); - connect(this, &DisplayFilterEdit::returnPressed, this, &DisplayFilterEdit::applyDisplayFilter); + bookmark_button_->setMinimumHeight(contentsRect().height()); + bookmark_button_->setMaximumHeight(contentsRect().height()); + bksz = bookmark_button_->sizeHint(); + + if ( clear_button_->isVisible() ) + { + cbsz = clear_button_->sizeHint(); + clear_button_->setMinimumHeight(contentsRect().height()); + clear_button_->setMaximumHeight(contentsRect().height()); + } + + apsz = apply_button_->sizeHint(); + apply_button_->setMinimumHeight(contentsRect().height()); + apply_button_->setMaximumHeight(contentsRect().height()); } - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - QSize bksz; - if (bookmark_button_) { - bksz = bookmark_button_->sizeHint(); - } - QSize cbsz; - if (clear_button_) { - cbsz = clear_button_->sizeHint(); - } - QSize apsz; - if (apply_button_) { - apsz = apply_button_->sizeHint(); + int leftPadding = frameWidth + 1; + int leftMargin = bksz.width(); + int rightMargin = cbsz.width() + apsz.width() + frameWidth + 1; + if ( leftAlignActions_ ) + { + leftMargin = rightMargin + bksz.width(); + rightMargin = 0; } + setStyleSheet(QString( "DisplayFilterEdit {" " padding-left: %1px;" @@ -154,14 +186,35 @@ DisplayFilterEdit::DisplayFilterEdit(QWidget *parent, DisplayFilterEditType type " margin-right: %3px;" "}" ) - .arg(frameWidth + 1) - .arg(bksz.width()) - .arg(cbsz.width() + apsz.width() + frameWidth + 1) - ); + .arg(leftPadding) + .arg(leftMargin) + .arg(rightMargin) + ); - connect(wsApp, &WiresharkApplication::appInitialized, this, &DisplayFilterEdit::updateBookmarkMenu); - connect(wsApp, &WiresharkApplication::displayFilterListChanged, this, &DisplayFilterEdit::updateBookmarkMenu); + if (clear_button_) { + if ( ! leftAlignActions_ ) + { + clear_button_->move(contentsRect().right() - frameWidth - cbsz.width() - apsz.width(), + contentsRect().top()); + } else { + clear_button_->move(contentsRect().left() + bookmark_button_->width(), contentsRect().top()); + } + } + if (apply_button_) { + if ( ! leftAlignActions_ ) + { + apply_button_->move(contentsRect().right() - frameWidth - apsz.width(), + contentsRect().top()); + } else { + int additionalWidth = bookmark_button_->width(); + if ( clear_button_ && clear_button_->isVisible() ) + additionalWidth += clear_button_->width(); + apply_button_->move(contentsRect().left() + additionalWidth, contentsRect().top()); + } + } + + update(); } void DisplayFilterEdit::setDefaultPlaceholderText() @@ -187,6 +240,8 @@ void DisplayFilterEdit::setDefaultPlaceholderText() void DisplayFilterEdit::paintEvent(QPaintEvent *evt) { SyntaxLineEdit::paintEvent(evt); + alignActionButtons(); + if (bookmark_button_) { // Draw the right border by hand. We could try to do this in the // style sheet but it's a pain. @@ -198,40 +253,23 @@ void DisplayFilterEdit::paintEvent(QPaintEvent *evt) { QPainter painter(this); painter.setPen(divider_color); QRect cr = contentsRect(); - QSize bksz = bookmark_button_->size(); - painter.drawLine(bksz.width(), cr.top(), bksz.width(), cr.bottom()); + int xpos = 0; + if ( leftAlignActions_ ) + { + xpos = bookmark_button_->size().width() + apply_button_->size().width(); + if ( clear_button_->isVisible() ) + xpos += clear_button_->size().width(); + } + else + xpos = bookmark_button_->size().width(); + + painter.drawLine(xpos, cr.top(), xpos, cr.bottom()); } } void DisplayFilterEdit::resizeEvent(QResizeEvent *) { - QSize cbsz; - if (clear_button_) { - cbsz = clear_button_->sizeHint(); - } - QSize apsz; - if (apply_button_) { - apsz = apply_button_->sizeHint(); - } else { - apsz.setHeight(0); apsz.setWidth(0); - } - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - if (clear_button_) { - clear_button_->move(contentsRect().right() - frameWidth - cbsz.width() - apsz.width(), - contentsRect().top()); - clear_button_->setMinimumHeight(contentsRect().height()); - clear_button_->setMaximumHeight(contentsRect().height()); - } - if (apply_button_) { - apply_button_->move(contentsRect().right() - frameWidth - apsz.width(), - contentsRect().top()); - apply_button_->setMinimumHeight(contentsRect().height()); - apply_button_->setMaximumHeight(contentsRect().height()); - } - if (bookmark_button_) { - bookmark_button_->setMinimumHeight(contentsRect().height()); - bookmark_button_->setMaximumHeight(contentsRect().height()); - } + alignActionButtons(); } void DisplayFilterEdit::focusOutEvent(QFocusEvent *event) @@ -257,6 +295,7 @@ void DisplayFilterEdit::checkFilter(const QString& filter_text) if (clear_button_) { clear_button_->setVisible(!filter_text.isEmpty()); + alignActionButtons(); } emit popFilterSyntaxStatus(); diff --git a/ui/qt/widgets/display_filter_edit.h b/ui/qt/widgets/display_filter_edit.h index 1974430d02..32ba762cf5 100644 --- a/ui/qt/widgets/display_filter_edit.h +++ b/ui/qt/widgets/display_filter_edit.h @@ -40,6 +40,7 @@ protected: virtual void dragEnterEvent(QDragEnterEvent *event); virtual void dragMoveEvent(QDragMoveEvent *event); virtual void dropEvent(QDropEvent *event); + virtual void contextMenuEvent(QContextMenuEvent *menu); public slots: bool checkFilter(); @@ -58,6 +59,8 @@ private slots: void showExpressionPrefs(); void applyOrPrepareFilter(); + void triggerAlignementAction(); + private: DisplayFilterEditType type_; QString placeholder_text_; @@ -67,12 +70,15 @@ private: StockIconToolButton *bookmark_button_; StockIconToolButton *clear_button_; StockIconToolButton *apply_button_; + bool leftAlignActions_; void setDefaultPlaceholderText(); void buildCompletionList(const QString& field_word); void createFilterTextDropMenu(QDropEvent *event, bool prepare, QString filterText = QString()); + void alignActionButtons(); + signals: void pushFilterSyntaxStatus(const QString&); void popFilterSyntaxStatus(); diff --git a/ui/recent.c b/ui/recent.c index f67af2f8e7..2066a39ed7 100644 --- a/ui/recent.c +++ b/ui/recent.c @@ -48,6 +48,7 @@ #define RECENT_GUI_GEOMETRY_MAIN_WIDTH "gui.geometry_main_width" #define RECENT_GUI_GEOMETRY_MAIN_HEIGHT "gui.geometry_main_height" #define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized" +#define RECENT_GUI_GEOMETRY_LEFTALIGN_ACTIONS "gui.geometry_leftalign_actions" #define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane" #define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane" #define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane" @@ -713,6 +714,10 @@ write_recent(void) RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED, recent.gui_geometry_main_maximized); + write_recent_boolean(rf, "Leftalign Action Buttons", + RECENT_GUI_GEOMETRY_LEFTALIGN_ACTIONS, + recent.gui_geometry_leftalign_actions); + fprintf(rf, "\n# Statusbar left pane size.\n"); fprintf(rf, "# Decimal number.\n"); if (recent.gui_geometry_status_pane_left != 0) { @@ -941,6 +946,8 @@ read_set_recent_common_pair_static(gchar *key, const gchar *value, if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) { parse_recent_boolean(value, &recent.gui_geometry_main_maximized); + } else if (strcmp(key, RECENT_GUI_GEOMETRY_LEFTALIGN_ACTIONS) == 0) { + parse_recent_boolean(value, &recent.gui_geometry_leftalign_actions); } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X) == 0) { num = strtol(value, &p, 0); if (p == value || *p != '\0') @@ -1263,6 +1270,8 @@ recent_read_static(char **rf_path_return, int *rf_errno_return) recent.gui_geometry_main_height = DEF_HEIGHT; recent.gui_geometry_main_maximized= FALSE; + recent.gui_geometry_leftalign_actions = FALSE; + recent.gui_geometry_status_pane_left = (DEF_WIDTH/3); recent.gui_geometry_status_pane_right = (DEF_WIDTH/3); recent.gui_geometry_wlan_stats_pane = 200; diff --git a/ui/recent.h b/ui/recent.h index d14acfd5fc..1df1310039 100644 --- a/ui/recent.h +++ b/ui/recent.h @@ -109,6 +109,7 @@ typedef struct recent_settings_tag { gint gui_geometry_main_height; gboolean gui_geometry_main_maximized; + gboolean gui_geometry_leftalign_actions; gboolean has_gui_geometry_main_upper_pane; /* gui_geometry_main_upper_pane is valid */ gint gui_geometry_main_upper_pane;