CaptureFilterCombo::CaptureFilterCombo(QWidget *parent, bool plain) : QComboBox(parent), cf_edit_(NULL) { cf_edit_ = new CaptureFilterEdit(this, plain); setEditable(true); // Enabling autocompletion here gives us two simultaneous completions: // Inline (highlighted text) for entire filters, handled here and popup // completion for fields handled by CaptureFilterEdit. setAutoCompletion(false); setLineEdit(cf_edit_); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); setInsertPolicy(QComboBox::NoInsert); setAccessibleName(tr("Capture filter selector")); setStyleSheet( "QComboBox {" #ifdef Q_OS_MAC " border: 1px solid gray;" #else " border: 1px solid palette(shadow);" #endif " border-radius: 3px;" " padding: 0px 0px 0px 0px;" " margin-left: 0px;" " min-width: 20em;" " }" "QComboBox::drop-down {" " subcontrol-origin: padding;" " subcontrol-position: top right;" " width: 16px;" " border-left-width: 0px;" " }" "QComboBox::down-arrow {" " image: url(:/icons/toolbar/14x14/x-filter-dropdown.png);" " }" "QComboBox::down-arrow:on { /* shift the arrow when popup is open */" " top: 1px;" " left: 1px;" "}" ); connect(this, SIGNAL(interfacesChanged()), cf_edit_, SLOT(checkFilter())); connect(cf_edit_, SIGNAL(pushFilterSyntaxStatus(const QString&)), this, SIGNAL(pushFilterSyntaxStatus(const QString&))); connect(cf_edit_, SIGNAL(popFilterSyntaxStatus()), this, SIGNAL(popFilterSyntaxStatus())); connect(cf_edit_, SIGNAL(captureFilterSyntaxChanged(bool)), this, SIGNAL(captureFilterSyntaxChanged(bool))); connect(cf_edit_, SIGNAL(startCapture()), this, SIGNAL(startCapture())); connect(cf_edit_, SIGNAL(startCapture()), this, SLOT(saveAndRebuildFilterList())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(rebuildFilterList())); connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(rebuildFilterList())); rebuildFilterList(); clearEditText(); }
InterfaceTree::InterfaceTree(QWidget *parent) : QTreeWidget(parent) #ifdef HAVE_LIBPCAP ,stat_cache_(NULL) ,stat_timer_(NULL) #endif // HAVE_LIBPCAP { QTreeWidgetItem *ti; header()->setVisible(false); setRootIsDecorated(false); setUniformRowHeights(true); setColumnCount(2); setSelectionMode(QAbstractItemView::ExtendedSelection); setAccessibleName(tr("Welcome screen list")); setItemDelegateForColumn(1, new SparkLineDelegate()); setDisabled(true); ti = new QTreeWidgetItem(); ti->setText(0, tr("Waiting for startup" UTF8_HORIZONTAL_ELLIPSIS)); addTopLevelItem(ti); resizeColumnToContents(0); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(getInterfaceList())); connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(updateSelectedInterfaces())); }
FilterExpressionToolBar::FilterExpressionToolBar(QWidget * parent) : DragDropToolBar(parent) { // Try to draw 1-pixel-wide separator lines from the button label // ascent to its baseline. int sep_margin = (fontMetrics().height() * 0.5) - 1; QColor sep_color = ColorUtils::alphaBlend(palette().text(), palette().base(), 0.3); setStyleSheet(QString( "QToolBar { background: none; border: none; spacing: 1px; }" "QFrame {" " min-width: 1px; max-width: 1px;" " margin: %1px 0 %2px 0; padding: 0;" " background-color: %3;" "}" ).arg(sep_margin).arg(sep_margin - 1).arg(sep_color.name())); setContextMenuPolicy(Qt::CustomContextMenu); connect ( this, &QWidget::customContextMenuRequested, this, &FilterExpressionToolBar::onCustomMenuHandler ); connect(this, &DragDropToolBar::actionMoved, this, &FilterExpressionToolBar::onActionMoved); connect(this, &DragDropToolBar::newFilterDropped, this, &FilterExpressionToolBar::onFilterDropped); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(filterExpressionsChanged())); connect(wsApp, SIGNAL(filterExpressionsChanged()), this, SLOT(filterExpressionsChanged())); }
InterfaceTree::InterfaceTree(QWidget *parent) : QTreeWidget(parent) #ifdef HAVE_LIBPCAP ,stat_cache_(NULL) ,stat_timer_(NULL) #endif // HAVE_LIBPCAP { QTreeWidgetItem *ti; qRegisterMetaType< PointList >("PointList"); header()->setVisible(false); setRootIsDecorated(false); setUniformRowHeights(true); /* Seems to have no effect, still the default value (2) is being used, as it * was set in the .ui file. But better safe, then sorry. */ resetColumnCount(); setSelectionMode(QAbstractItemView::ExtendedSelection); setAccessibleName(tr("Welcome screen list")); setItemDelegateForColumn(IFTREE_COL_STATS, new SparkLineDelegate(this)); setDisabled(true); ti = new QTreeWidgetItem(); ti->setText(IFTREE_COL_NAME, tr("Waiting for startup%1").arg(UTF8_HORIZONTAL_ELLIPSIS)); addTopLevelItem(ti); resizeColumnToContents(IFTREE_COL_NAME); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(getInterfaceList())); connect(wsApp, SIGNAL(localInterfaceListChanged()), this, SLOT(interfaceListChanged())); connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(updateSelectedInterfaces())); }
CaptureFilterCombo::CaptureFilterCombo(QWidget *parent) : QComboBox(parent), cf_edit_(NULL) { cf_edit_ = new CaptureFilterEdit(); setEditable(true); setLineEdit(cf_edit_); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); setInsertPolicy(QComboBox::NoInsert); setAccessibleName(tr("Capture filter selector")); setStyleSheet( "QComboBox {" #ifdef Q_OS_MAC " border: 1px solid gray;" #else " border: 1px solid palette(shadow);" #endif " border-radius: 3px;" " padding: 0px 0px 0px 0px;" " margin-left: 0px;" " min-width: 20em;" " }" "QComboBox::drop-down {" " subcontrol-origin: padding;" " subcontrol-position: top right;" " width: 16px;" " border-left-width: 0px;" " }" "QComboBox::down-arrow {" " image: url(:/dfilter/dfilter_dropdown.png);" " }" "QComboBox::down-arrow:on { /* shift the arrow when popup is open */" " top: 1px;" " left: 1px;" "}" ); completer()->setCompletionMode(QCompleter::PopupCompletion); connect(this, SIGNAL(interfacesChanged()), cf_edit_, SLOT(checkFilter())); connect(cf_edit_, SIGNAL(pushFilterSyntaxStatus(QString&)), this, SIGNAL(pushFilterSyntaxStatus(QString&))); connect(cf_edit_, SIGNAL(popFilterSyntaxStatus()), this, SIGNAL(popFilterSyntaxStatus())); connect(cf_edit_, SIGNAL(captureFilterSyntaxChanged(bool)), this, SIGNAL(captureFilterSyntaxChanged(bool))); connect(cf_edit_, SIGNAL(startCapture()), this, SIGNAL(startCapture())); connect(cf_edit_, SIGNAL(startCapture()), this, SLOT(rebuildFilterList())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(rebuildFilterList())); connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(rebuildFilterList())); rebuildFilterList(false); clearEditText(); }
WirelessTimeline::WirelessTimeline(QWidget *parent) : QWidget(parent) { setHidden(true); zoom_level = 1.0; setFixedHeight(TIMELINE_HEIGHT); first_packet = 1; setMouseTracking(true); start_x = 0; last_x = 0; packet_list = NULL; start_tsf = 0; end_tsf = 0; first = NULL; last = NULL; capfile = NULL; radio_packet_list = NULL; connect(wsApp, SIGNAL(appInitialized()), this, SLOT(appInitialized())); }
ByteViewTab::ByteViewTab(QWidget *parent) : QTabWidget(parent), cap_file_(0) { setAccessibleName(tr("Packet bytes")); setTabPosition(QTabWidget::South); setDocumentMode(true); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(connectToMainWindow())); }
MainStatusBar::MainStatusBar(QWidget *parent) : QStatusBar(parent) { QSplitter *splitter = new QSplitter(this); QString ready_msg(DEF_READY_MESSAGE); QWidget *info_progress = new QWidget(this); QHBoxLayout *info_progress_hb = new QHBoxLayout(info_progress); #if defined(Q_WS_WIN) // Handles are the same color as widgets, at least on Windows 7. splitter->setHandleWidth(3); splitter->setStyleSheet(QString( "QSplitter::handle {" " border-left: 1px solid palette(mid);" " border-right: 1px solid palette(mid);" "}" )); #elif defined(Q_WS_MAC) expert_status_.setAttribute(Qt::WA_MacSmallSize, true); #endif expert_status_.setTextFormat(Qt::RichText); expert_status_.hide(); // XXX Add the comment icon info_progress_hb->setContentsMargins(0, 0, 0, 0); info_status_.setTemporaryContext(STATUS_CTX_TEMPORARY); info_progress_hb->addWidget(&expert_status_); info_progress_hb->addWidget(&info_status_); info_progress_hb->addWidget(&progress_bar_); info_progress_hb->addStretch(10); splitter->addWidget(info_progress); splitter->addWidget(&packet_status_); splitter->addWidget(&profile_status_); splitter->setStretchFactor(0, 3); splitter->setStretchFactor(1, 3); splitter->setStretchFactor(2, 1); addWidget(splitter, 1); cur_main_status_bar_ = this; splitter->hide(); info_status_.pushText(ready_msg, STATUS_CTX_MAIN); packets_bar_update(); connect(wsApp, SIGNAL(appInitialized()), splitter, SLOT(show())); connect(&info_status_, SIGNAL(toggleTemporaryFlash(bool)), this, SLOT(toggleBackground(bool))); }
ByteViewTab::ByteViewTab(QWidget *parent, epan_dissect_t *edt_fixed) : QTabWidget(parent), cap_file_(0), is_fixed_packet_(edt_fixed != NULL), edt_(edt_fixed) { setAccessibleName(tr("Packet bytes")); setTabPosition(QTabWidget::South); setDocumentMode(true); // Shrink down to a small but nonzero size in the main splitter. int one_em = fontMetrics().height(); setMinimumSize(one_em, one_em); if (!edt_fixed) { connect(wsApp, SIGNAL(appInitialized()), this, SLOT(connectToMainWindow())); } }
MainStatusBar::MainStatusBar(QWidget *parent) : QStatusBar(parent), cap_file_(NULL), edit_action_(NULL), delete_action_(NULL) { QSplitter *splitter = new QSplitter(this); #ifdef HAVE_LIBPCAP QString ready_msg(tr("Ready to load or capture")); #else QString ready_msg(tr("Ready to load file")); #endif QWidget *info_progress = new QWidget(this); QHBoxLayout *info_progress_hb = new QHBoxLayout(info_progress); QAction *action; #if defined(Q_OS_WIN) // Handles are the same color as widgets, at least on Windows 7. splitter->setHandleWidth(3); splitter->setStyleSheet(QString( "QSplitter::handle {" " border-left: 1px solid palette(mid);" " border-right: 1px solid palette(mid);" "}" )); #elif defined(Q_OS_MAC) expert_status_.setAttribute(Qt::WA_MacSmallSize, true); #endif expert_status_.setTextFormat(Qt::RichText); expert_status_.hide(); // XXX Add the comment icon info_progress_hb->setContentsMargins(0, 0, 0, 0); info_status_.setTemporaryContext(STATUS_CTX_TEMPORARY); info_progress_hb->addWidget(&expert_status_); info_progress_hb->addWidget(&info_status_); info_progress_hb->addWidget(&progress_bar_); info_progress_hb->addStretch(10); splitter->addWidget(info_progress); splitter->addWidget(&packet_status_); splitter->addWidget(&profile_status_); splitter->setStretchFactor(0, 3); splitter->setStretchFactor(1, 3); splitter->setStretchFactor(2, 1); addWidget(splitter, 1); cur_main_status_bar_ = this; splitter->hide(); info_status_.pushText(ready_msg, STATUS_CTX_MAIN); packets_bar_update(); action = ctx_menu_.addAction(tr("Manage Profiles...")); action->setData(ProfileDialog::ShowProfiles); connect(action, SIGNAL(triggered()), this, SLOT(manageProfile())); ctx_menu_.addSeparator(); action = ctx_menu_.addAction(tr("New...")); action->setData(ProfileDialog::NewProfile); connect(action, SIGNAL(triggered()), this, SLOT(manageProfile())); edit_action_ = ctx_menu_.addAction(tr("Edit...")); edit_action_->setData(ProfileDialog::EditCurrentProfile); connect(edit_action_, SIGNAL(triggered()), this, SLOT(manageProfile())); delete_action_ = ctx_menu_.addAction(tr("Delete")); delete_action_->setData(ProfileDialog::DeleteCurrentProfile); connect(delete_action_, SIGNAL(triggered()), this, SLOT(manageProfile())); ctx_menu_.addSeparator(); profile_menu_.setTitle(tr("Switch to")); ctx_menu_.addMenu(&profile_menu_); connect(wsApp, SIGNAL(appInitialized()), splitter, SLOT(show())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(pushProfileName())); connect(&info_status_, SIGNAL(toggleTemporaryFlash(bool)), this, SLOT(toggleBackground(bool))); connect(wsApp, SIGNAL(captureCaptureUpdateContinue(capture_session*)), this, SLOT(updateCaptureStatistics(capture_session*))); connect(wsApp, SIGNAL(configurationProfileChanged(const gchar *)), this, SLOT(pushProfileName())); connect(&profile_status_, SIGNAL(mousePressedAt(QPoint,Qt::MouseButton)), this, SLOT(showProfileMenu(QPoint,Qt::MouseButton))); }
// appears to support that flag as well, but no other *BSD appears // to. // // I'm not sure what can be done on Linux. // recent_timer_.setParent(this); connect(&recent_timer_, SIGNAL(timeout()), this, SLOT(refreshRecentFiles())); recent_timer_.start(2000); addr_resolv_timer_.setParent(this); connect(&addr_resolv_timer_, SIGNAL(timeout()), this, SLOT(refreshAddressResolution())); addr_resolv_timer_.start(1000); tap_update_timer_.setParent(this); tap_update_timer_.setInterval(TAP_UPDATE_DEFAULT_INTERVAL); connect(this, SIGNAL(appInitialized()), &tap_update_timer_, SLOT(start())); connect(&tap_update_timer_, SIGNAL(timeout()), this, SLOT(updateTaps())); // Application-wide style sheet QString app_style_sheet = qApp->styleSheet(); #if defined(Q_OS_MAC) && QT_VERSION < QT_VERSION_CHECK(5, 6, 0) // Qt uses the HITheme API to draw splitters. In recent versions of OS X // this looks particularly bad: https://bugreports.qt.io/browse/QTBUG-43425 // This doesn't look native but it looks better than Yosemite's bit-rotten // rendering of HIThemeSplitterDrawInfo. app_style_sheet += "QSplitter::handle:vertical { height: 0px; }\n" "QSplitter::handle:horizontal { width: 0px; }\n"; #endif qApp->setStyleSheet(app_style_sheet);
CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) : SyntaxLineEdit(parent), plain_(plain), field_name_only_(false), bookmark_button_(NULL), clear_button_(NULL), apply_button_(NULL) { setAccessibleName(tr("Capture filter entry")); completion_model_ = new QStringListModel(this); setCompleter(new QCompleter(completion_model_, this)); setCompletionTokenChars(libpcap_primitive_chars_); placeholder_text_ = QString(tr("Enter a capture filter %1")).arg(UTF8_HORIZONTAL_ELLIPSIS); #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) setPlaceholderText(placeholder_text_); #endif // These are fully implemented in DisplayFilterEdit but not here. if (!plain_) { bookmark_button_ = new StockIconToolButton(this, "x-filter-bookmark"); bookmark_button_->setCursor(Qt::ArrowCursor); 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; }" ); connect(bookmark_button_, SIGNAL(clicked()), this, SLOT(bookmarkClicked())); } if (!plain_) { clear_button_ = new StockIconToolButton(this, "x-filter-clear"); clear_button_->setCursor(Qt::ArrowCursor); clear_button_->setToolTip(QString()); 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;" "}" ); connect(clear_button_, SIGNAL(clicked()), this, SLOT(clear())); } connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(checkFilter(const QString&))); if (!plain_) { apply_button_ = new StockIconToolButton(this, "x-filter-apply"); apply_button_->setCursor(Qt::ArrowCursor); apply_button_->setEnabled(false); apply_button_->setToolTip(tr("Apply this filter string to the display.")); 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_, SIGNAL(clicked()), this, SLOT(applyCaptureFilter())); connect(this, SIGNAL(returnPressed()), this, SLOT(applyCaptureFilter())); } 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(); setStyleSheet(QString( "CaptureFilterEdit {" " padding-left: %1px;" " margin-left: %2px;" " margin-right: %3px;" "}" ) .arg(frameWidth + 1) .arg(bksz.width()) .arg(cbsz.width() + apsz.width() + frameWidth + 1) ); QThread *syntax_thread = new QThread; syntax_worker_ = new CaptureFilterSyntaxWorker; syntax_worker_->moveToThread(syntax_thread); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initCaptureFilter())); connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start())); connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter())); connect(syntax_worker_, SIGNAL(syntaxResult(QString,bool,QString)), this, SLOT(setFilterSyntaxState(QString,bool,QString))); connect(syntax_thread, SIGNAL(finished()), syntax_worker_, SLOT(deleteLater())); syntax_thread->start(); checkFilter(); }
MainStatusBar::MainStatusBar(QWidget *parent) : QStatusBar(parent), cap_file_(NULL), edit_action_(NULL), delete_action_(NULL) { QSplitter *splitter = new QSplitter(this); #ifdef HAVE_LIBPCAP QString ready_msg(tr("Ready to load or capture")); #else QString ready_msg(tr("Ready to load file")); #endif QWidget *info_progress = new QWidget(this); QHBoxLayout *info_progress_hb = new QHBoxLayout(info_progress); QAction *action; #if defined(Q_OS_WIN) // Handles are the same color as widgets, at least on Windows 7. splitter->setHandleWidth(3); splitter->setStyleSheet(QString( "QSplitter::handle {" " border-left: 1px solid palette(mid);" " border-right: 1px solid palette(mid);" "}" )); #endif QString button_ss = "QToolButton {" " border: none;" " background: transparent;" // Disables platform style on Windows. " padding: 0px;" " margin: 0px;" "}"; expert_button_ = new QToolButton(this); expert_button_->setIconSize(QSize(icon_size, icon_size)); expert_button_->setStyleSheet(button_ss); expert_button_->hide(); // We just want a clickable image. Using a QPushButton or QToolButton would require // a lot of adjustment. StockIcon comment_icon("x-capture-comment-update"); comment_button_ = new QToolButton(this); comment_button_->setIcon(comment_icon); comment_button_->setIconSize(QSize(icon_size, icon_size)); comment_button_->setStyleSheet(button_ss); comment_button_->setToolTip(tr("Open the Capture File Properties dialog")); comment_button_->setEnabled(false); connect(expert_button_, SIGNAL(clicked(bool)), this, SIGNAL(showExpertInfo())); connect(comment_button_, SIGNAL(clicked(bool)), this, SIGNAL(editCaptureComment())); info_progress_hb->setContentsMargins(icon_size / 2, 0, 0, 0); info_status_.setTemporaryContext(STATUS_CTX_TEMPORARY); info_status_.setShrinkable(true); info_progress_hb->addWidget(expert_button_); info_progress_hb->addWidget(comment_button_); info_progress_hb->addWidget(&info_status_); info_progress_hb->addWidget(&progress_frame_); info_progress_hb->addStretch(10); splitter->addWidget(info_progress); splitter->addWidget(&packet_status_); splitter->addWidget(&profile_status_); splitter->setStretchFactor(0, 3); splitter->setStretchFactor(1, 3); splitter->setStretchFactor(2, 1); addWidget(splitter, 1); cur_main_status_bar_ = this; splitter->hide(); info_status_.pushText(ready_msg, STATUS_CTX_MAIN); packets_bar_update(); action = ctx_menu_.addAction(tr("Manage Profiles" UTF8_HORIZONTAL_ELLIPSIS)); action->setData(ProfileDialog::ShowProfiles); connect(action, SIGNAL(triggered()), this, SLOT(manageProfile())); ctx_menu_.addSeparator(); action = ctx_menu_.addAction(tr("New" UTF8_HORIZONTAL_ELLIPSIS)); action->setData(ProfileDialog::NewProfile); connect(action, SIGNAL(triggered()), this, SLOT(manageProfile())); edit_action_ = ctx_menu_.addAction(tr("Edit" UTF8_HORIZONTAL_ELLIPSIS)); edit_action_->setData(ProfileDialog::EditCurrentProfile); connect(edit_action_, SIGNAL(triggered()), this, SLOT(manageProfile())); delete_action_ = ctx_menu_.addAction(tr("Delete")); delete_action_->setData(ProfileDialog::DeleteCurrentProfile); connect(delete_action_, SIGNAL(triggered()), this, SLOT(manageProfile())); ctx_menu_.addSeparator(); profile_menu_.setTitle(tr("Switch to")); ctx_menu_.addMenu(&profile_menu_); #ifdef QWINTASKBARPROGRESS_H progress_frame_.enableTaskbarUpdates(true); #endif connect(wsApp, SIGNAL(appInitialized()), splitter, SLOT(show())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(pushProfileName())); connect(&info_status_, SIGNAL(toggleTemporaryFlash(bool)), this, SLOT(toggleBackground(bool))); connect(wsApp, SIGNAL(profileNameChanged(const gchar *)), this, SLOT(pushProfileName())); connect(&profile_status_, SIGNAL(mousePressedAt(QPoint,Qt::MouseButton)), this, SLOT(showProfileMenu(QPoint,Qt::MouseButton))); connect(&progress_frame_, SIGNAL(stopLoading()), this, SIGNAL(stopLoading())); }
CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) : SyntaxLineEdit(parent), plain_(plain), field_name_only_(false), enable_save_action_(false), save_action_(NULL), remove_action_(NULL), bookmark_button_(NULL), clear_button_(NULL), apply_button_(NULL) { setAccessibleName(tr("Capture filter entry")); completion_model_ = new QStringListModel(this); setCompleter(new QCompleter(completion_model_, this)); setCompletionTokenChars(libpcap_primitive_chars_); setConflict(false); if (!plain_) { bookmark_button_ = new StockIconToolButton(this, "x-capture-filter-bookmark"); bookmark_button_->setCursor(Qt::ArrowCursor); bookmark_button_->setMenu(new QMenu()); 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; }" ); connect(bookmark_button_, SIGNAL(clicked()), this, SLOT(bookmarkClicked())); } if (!plain_) { clear_button_ = new StockIconToolButton(this, "x-filter-clear"); clear_button_->setCursor(Qt::ArrowCursor); clear_button_->setToolTip(QString()); 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;" "}" ); connect(clear_button_, SIGNAL(clicked()), this, SLOT(clearFilter())); } connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(checkFilter(const QString&))); #if 0 // Disable the apply button for now if (!plain_) { apply_button_ = new StockIconToolButton(this, "x-filter-apply"); apply_button_->setCursor(Qt::ArrowCursor); apply_button_->setEnabled(false); apply_button_->setToolTip(tr("Apply this filter string to the display.")); 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_, SIGNAL(clicked()), this, SLOT(applyCaptureFilter())); } #endif connect(this, SIGNAL(returnPressed()), this, SLOT(applyCaptureFilter())); 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(); setStyleSheet(QString( "CaptureFilterEdit {" " padding-left: %1px;" " margin-left: %2px;" " margin-right: %3px;" "}" ) .arg(frameWidth + 1) .arg(bksz.width()) .arg(cbsz.width() + apsz.width() + frameWidth + 1) ); QComboBox *cf_combo = qobject_cast<QComboBox *>(parent); if (cf_combo) { connect(cf_combo, SIGNAL(activated(QString)), this, SIGNAL(textEdited(QString))); } QThread *syntax_thread = new QThread; syntax_worker_ = new CaptureFilterSyntaxWorker; syntax_worker_->moveToThread(syntax_thread); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(updateBookmarkMenu())); connect(wsApp, SIGNAL(captureFilterListChanged()), this, SLOT(updateBookmarkMenu())); connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start())); connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter())); connect(syntax_worker_, SIGNAL(syntaxResult(QString,int,QString)), this, SLOT(setFilterSyntaxState(QString,int,QString))); connect(syntax_thread, SIGNAL(finished()), syntax_worker_, SLOT(deleteLater())); syntax_thread->start(); }
CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) : SyntaxLineEdit(parent), plain_(plain), field_name_only_(false), apply_button_(NULL) { setAccessibleName(tr("Capture filter entry")); completion_model_ = new QStringListModel(this); setCompleter(new QCompleter(completion_model_, this)); setCompletionTokenChars(libpcap_primitive_chars_); placeholder_text_ = QString(tr("Enter a capture filter %1")).arg(UTF8_HORIZONTAL_ELLIPSIS); #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) setPlaceholderText(placeholder_text_); #endif // DFCombo // Bookmark (star) // DispalyFilterEdit // Clear button // Apply (right arrow) + Cancel (x) + Reload (arrowed circle) // Combo drop-down // XXX - Move bookmark and apply buttons to the toolbar a la Firefox, Chrome & Safari? // XXX - Use native buttons on OS X? bookmark_button_ = new QToolButton(this); bookmark_button_->setCursor(Qt::ArrowCursor); bookmark_button_->setStyleSheet(QString( "QToolButton { /* all types of tool button */" " border 0 0 0 0;" #ifdef Q_OS_MAC " border-right: %1px solid gray;" #else " border-right: %1px solid palette(shadow);" #endif " border-top-left-radius: 3px;" " border-bottom-left-radius: 3px;" " padding-left: 1px;" " image: url(:/dfilter/dfilter_bookmark_normal.png) center;" "}" "QToolButton:hover {" " image: url(:/dfilter/dfilter_bookmark_hover.png) center;" "}" "QToolButton:pressed {" " image: url(:/dfilter/dfilter_bookmark_pressed.png) center;" "}" "QToolButton:disabled {" " image: url(:/dfilter/dfilter_bookmark_disabled.png) center;" "}" ).arg(plain_ ? 0 : 1) ); connect(bookmark_button_, SIGNAL(clicked()), this, SLOT(bookmarkClicked())); clear_button_ = new QToolButton(this); clear_button_->setCursor(Qt::ArrowCursor); clear_button_->setStyleSheet( "QToolButton {" " image: url(:/dfilter/dfilter_erase_normal.png) center;" " border: none;" " width: 16px;" "}" "QToolButton:hover {" " image: url(:/dfilter/dfilter_erase_active.png) center;" "}" "QToolButton:pressed {" " image: url(:/dfilter/dfilter_erase_selected.png) center;" "}" ); clear_button_->hide(); connect(clear_button_, SIGNAL(clicked()), this, SLOT(clear())); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(checkFilter(const QString&))); if (!plain_) { apply_button_ = new QToolButton(this); apply_button_->setCursor(Qt::ArrowCursor); apply_button_->setEnabled(false); apply_button_->setStyleSheet( "QToolButton { /* all types of tool button */" " border 0 0 0 0;" " border-top-right-radius: 3px;" " border-bottom-right-radius: 3px;" " padding-right: 1px;" " image: url(:/dfilter/dfilter_apply_normal.png) center;" "}" "QToolButton:hover {" " image: url(:/dfilter/dfilter_apply_hover.png) center;" "}" "QToolButton:pressed {" " image: url(:/dfilter/dfilter_apply_pressed.png) center;" "}" "QToolButton:disabled {" " image: url(:/dfilter/dfilter_apply_disabled.png) center;" "}" ); connect(apply_button_, SIGNAL(clicked()), this, SLOT(applyCaptureFilter())); connect(this, SIGNAL(returnPressed()), this, SLOT(applyCaptureFilter())); } int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); QSize bksz = bookmark_button_->sizeHint(); QSize cbsz = clear_button_->sizeHint(); QSize apsz; if (apply_button_) { apsz = apply_button_->sizeHint(); } else { apsz.setHeight(0); apsz.setWidth(0); } setStyleSheet(QString( "CaptureFilterEdit {" " padding-left: %1px;" " margin-left: %2px;" " margin-right: %3px;" "}" ) .arg(frameWidth + 1) .arg(bksz.width()) .arg(cbsz.width() + apsz.width() + frameWidth + 1) ); QThread *syntax_thread = new QThread; syntax_worker_ = new CaptureFilterSyntaxWorker; syntax_worker_->moveToThread(syntax_thread); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initCaptureFilter())); connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start())); connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter())); connect(syntax_worker_, SIGNAL(syntaxResult(QString,bool,QString)), this, SLOT(setFilterSyntaxState(QString,bool,QString))); connect(syntax_thread, SIGNAL(finished()), syntax_worker_, SLOT(deleteLater())); syntax_thread->start(); }