update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / qt / main_window.cpp
blobb684fd3b26f4e6100ab66e4c2404164a0842541b
1 /* main_window.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10 #include "config.h"
12 #include "ui/preference_utils.h"
14 #include "main_window.h"
16 #include "epan/dfilter/dfilter-translator.h"
18 #include <QClipboard>
20 #include "funnel_statistics.h"
21 #include "main_application.h"
22 #include "packet_list.h"
23 #include "utils/profile_switcher.h"
24 #include "utils/qt_ui_utils.h"
25 #include "widgets/display_filter_combo.h"
27 // Packet Menu actions
28 static QList<QAction *> dynamic_packet_menu_actions;
30 MainWindow::MainWindow(QWidget *parent) :
31 QMainWindow(parent),
32 main_stack_(nullptr),
33 welcome_page_(nullptr),
34 cur_layout_(QVector<unsigned>()),
35 packet_list_(nullptr),
36 proto_tree_(nullptr),
37 byte_view_tab_(nullptr),
38 packet_diagram_(nullptr),
39 df_combo_box_(nullptr),
40 main_status_bar_(nullptr),
41 profile_switcher_(new ProfileSwitcher())
46 MainWindow::~MainWindow()
48 clearAddedPacketMenus();
51 bool MainWindow::hasSelection()
53 if (packet_list_)
54 return packet_list_->multiSelectActive();
55 return false;
59 * As hasSelection() is not looking for one single packet
60 * selection, but at least 2, this method returns true in
61 * this specific case.
63 bool MainWindow::hasUniqueSelection()
65 if (packet_list_)
66 return packet_list_->uniqueSelectActive();
67 return false;
70 QList<int> MainWindow::selectedRows(bool useFrameNum)
72 if (packet_list_)
73 return packet_list_->selectedRows(useFrameNum);
74 return QList<int>();
77 frame_data* MainWindow::frameDataForRow(int row) const
79 if (packet_list_)
80 return packet_list_->getFDataForRow(row);
82 return Q_NULLPTR;
85 void MainWindow::insertColumn(QString name, QString abbrev, int pos)
87 int colnr = 0;
88 if (name.length() > 0 && abbrev.length() > 0)
90 colnr = column_prefs_add_custom(COL_CUSTOM, name.toStdString().c_str(), abbrev.toStdString().c_str(), pos);
91 packet_list_->columnsChanged();
92 packet_list_->resizeColumnToContents(colnr);
93 prefs_main_write();
97 void MainWindow::gotoFrame(int packet_num)
99 if (packet_num > 0) {
100 packet_list_->goToPacket(packet_num);
104 QString MainWindow::getFilter()
106 return df_combo_box_->currentText();
109 MainStatusBar *MainWindow::statusBar()
111 return main_status_bar_;
114 void MainWindow::setDisplayFilter(QString filter, FilterAction::Action action, FilterAction::ActionType filterType)
116 emit filterAction(filter, action, filterType);
120 * Used for registering custom packet menus
122 * @param funnel_action a custom packet menu action
124 void MainWindow::appendPacketMenu(FunnelAction* funnel_action)
126 dynamic_packet_menu_actions.append(funnel_action);
127 connect(funnel_action, &FunnelAction::triggered, funnel_action, &FunnelAction::triggerPacketCallback);
131 * Returns the list of registered packet menu actions
133 * After ensuring that all stored custom packet menu actions
134 * are registered with the Wireshark GUI, it returns them as a list
135 * so that they can potentially be displayed to a user.
137 * @return the list of registered packet menu actions
139 QList<QAction *> MainWindow::getPacketMenuActions()
141 if (funnel_statistics_packet_menus_modified()) {
142 // If the packet menus were modified, we need to clear the already
143 // loaded packet menus to avoid duplicates
144 this->clearAddedPacketMenus();
145 funnel_statistics_load_packet_menus();
147 return dynamic_packet_menu_actions;
151 * Clears the list of registered packet menu actions
153 * Clears the list of registered packet menu actions
154 * and frees all associated memory.
156 void MainWindow::clearAddedPacketMenus()
158 for( int i=0; i<dynamic_packet_menu_actions.count(); ++i )
160 delete dynamic_packet_menu_actions[i];
162 dynamic_packet_menu_actions.clear();
167 * Adds the custom packet menus to the supplied QMenu
169 * This method takes in QMenu and the selected packet's data
170 * and adds all applicable custom packet menus to it.
172 * @param ctx_menu The menu to add the packet menu entries to
173 * @param finfo_array The data in the selected packet
174 * @return true if a packet menu was added to the ctx_menu
176 bool MainWindow::addPacketMenus(QMenu * ctx_menu, GPtrArray *finfo_array)
178 bool insertedPacketMenu = false;
179 QList<QAction *> myPacketMenuActions = this->getPacketMenuActions();
180 if (myPacketMenuActions.isEmpty()) {
181 return insertedPacketMenu;
184 // Build a set of fields present for efficient lookups
185 QSet<QString> fieldsPresent = QSet<QString>();
186 for (unsigned fieldInfoIndex = 0; fieldInfoIndex < finfo_array->len; fieldInfoIndex++) {
187 field_info *fi = (field_info *)g_ptr_array_index (finfo_array, fieldInfoIndex);
188 fieldsPresent.insert(QString(fi->hfinfo->abbrev));
191 // Place actions in the relevant (sub)menu
192 // The 'root' menu is the ctx_menu, so map NULL to that
193 QHash<QString, QMenu *> menuTextToMenus;
194 menuTextToMenus.insert(NULL, ctx_menu);
195 foreach (QAction * action, myPacketMenuActions) {
196 if (! qobject_cast<FunnelAction *>(action)) {
197 continue;
199 FunnelAction * packetAction = qobject_cast<FunnelAction *>(action);
201 // Only display a menu if all required fields are present
202 if (!fieldsPresent.contains(packetAction->getPacketRequiredFields())) {
203 continue;
206 packetAction->setPacketData(finfo_array);
207 packetAction->addToMenu(ctx_menu, menuTextToMenus);
208 insertedPacketMenu = true;
210 return insertedPacketMenu;
213 const char *MainWindow::translator_ = "translator";
214 const char *MainWindow::translated_filter_ = "translated filter";
216 void MainWindow::addDisplayFilterTranslationActions(QMenu *copy_menu) {
217 if (!copy_menu) {
218 return;
221 char **df_translators = get_dfilter_translator_list();
223 if (df_translators == NULL || df_translators[0] == NULL) {
224 g_free(df_translators);
225 return;
228 copy_menu->addSeparator();
230 for (size_t idx = 0; df_translators[idx]; idx++) {
231 QString translator = df_translators[idx];
232 QString action_text;
233 if (idx == 0) {
234 action_text = tr("Display filter as %1").arg(translator);
235 } else {
236 action_text = tr(UTF8_HORIZONTAL_ELLIPSIS "as %1").arg(translator);
238 QAction *xlate_action = copy_menu->addAction(action_text);
239 xlate_action->setProperty(translator_, QVariant::fromValue(translator));
240 xlate_action->setEnabled(false);
241 connect(xlate_action, &QAction::triggered, this, &MainWindow::copyDisplayFilterTranslation);
242 df_translate_actions_ += xlate_action;
245 g_free(df_translators);
248 void MainWindow::updateDisplayFilterTranslationActions(const QString &df_text)
250 for (QAction *xlate_action : df_translate_actions_) {
251 bool enable = false;
252 QString translated_filter;
253 if (!df_text.isEmpty()) {
254 QString translator = xlate_action->property(translator_).toString();
255 translated_filter = gchar_free_to_qstring((char *)translate_dfilter(qUtf8Printable(translator),
256 qUtf8Printable(df_text)));
257 if (!translated_filter.isEmpty()) {
258 enable = true;
261 xlate_action->setEnabled(enable);
262 xlate_action->setProperty(translated_filter_, QVariant::fromValue(translated_filter));
266 void MainWindow::copyDisplayFilterTranslation()
268 QAction *xlate_action = qobject_cast<QAction *>(sender());
269 if (!xlate_action) {
270 return;
273 QString translated_filter = xlate_action->property(translated_filter_).toString();
274 mainApp->clipboard()->setText(translated_filter);