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();
}
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();
}
void CaptureFilterEdit::checkFilter(const QString& filter)
{
    setSyntaxState(Busy);
    popFilterSyntaxStatus();
    bool empty = filter.isEmpty();

    setConflict(false);
    if (bookmark_button_) {
        bool match = false;

        for (GList *cf_item = get_filter_list_first(CFILTER_LIST); cf_item; cf_item = g_list_next(cf_item)) {
            if (!cf_item->data) continue;
            filter_def *cf_def = (filter_def *) cf_item->data;
            if (!cf_def->name || !cf_def->strval) continue;

            if (filter.compare(cf_def->strval) == 0) {
                match = true;
            }
        }

        if (match) {
            bookmark_button_->setStockIcon("x-filter-matching-bookmark");
            if (remove_action_) {
                remove_action_->setData(text());
                remove_action_->setVisible(true);
            }
        } else {
            bookmark_button_->setStockIcon("x-capture-filter-bookmark");
            if (remove_action_) {
                remove_action_->setVisible(false);
            }
        }

        enable_save_action_ = (!match && !filter.isEmpty());
        if (save_action_) {
            save_action_->setEnabled(false);
        }
    }

    if (apply_button_) {
        apply_button_->setEnabled(false);
    }

    if (clear_button_) {
        clear_button_->setVisible(!empty);
    }

    if (empty) {
        setFilterSyntaxState(filter, Empty, QString());
    } else {
        syntax_worker_->checkFilter(filter);
    }
}
// ui/gtk/filter_autocomplete.c:build_autocompletion_list
void FieldFilterEdit::buildCompletionList(const QString &field_word)
{
    // Push a hint about the current field.
    if (syntaxState() == Valid) {
        emit popFilterSyntaxStatus();

        header_field_info *hfinfo = proto_registrar_get_byname(field_word.toUtf8().constData());
        if (hfinfo) {
            QString cursor_field_msg = QString("%1: %2")
                    .arg(hfinfo->name)
                    .arg(ftype_pretty_name(hfinfo->type));
            emit pushFilterSyntaxStatus(cursor_field_msg);
        }
    }

    if (field_word.length() < 1) {
        completion_model_->setStringList(QStringList());
        return;
    }

    void *proto_cookie;
    QStringList field_list;
    int field_dots = field_word.count('.'); // Some protocol names (_ws.expert) contain periods.
    for (int proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; proto_id = proto_get_next_protocol(&proto_cookie)) {
        protocol_t *protocol = find_protocol_by_id(proto_id);
        if (!proto_is_protocol_enabled(protocol)) continue;

        // Don't complete the current word.
        const QString pfname = proto_get_protocol_filter_name(proto_id);
        if (field_word.compare(pfname)) field_list << pfname;

        // Add fields only if we're past the protocol name and only for the
        // current protocol.
        if (field_dots > pfname.count('.')) {
            void *field_cookie;
            const QByteArray fw_ba = field_word.toUtf8(); // or toLatin1 or toStdString?
            const char *fw_utf8 = fw_ba.constData();
            gsize fw_len = (gsize) strlen(fw_utf8);
            for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) {
                if (hfinfo->same_name_prev_id != -1) continue; // Ignore duplicate names.

                if (!g_ascii_strncasecmp(fw_utf8, hfinfo->abbrev, fw_len)) {
                    if ((gsize) strlen(hfinfo->abbrev) != fw_len) field_list << hfinfo->abbrev;
                }
            }
        }
    }
    field_list.sort();

    completion_model_->setStringList(field_list);
    completer()->setCompletionPrefix(field_word);
}
void DisplayFilterEdit::checkFilter(const QString& text)
{
    dfilter_t *dfp;
    guchar c;

    clear_button_->setVisible(!text.isEmpty());

    popFilterSyntaxStatus();

    if (field_name_only_ && (c = proto_check_field_name(text.toUtf8().constData()))) {
        setSyntaxState(Invalid);
        emit pushFilterSyntaxStatus(QString().sprintf("Illegal character in field name: '%c'", c));
    } else if (dfilter_compile(text.toUtf8().constData(), &dfp)) {
        GPtrArray *depr = NULL;
        if (dfp != NULL) {
            depr = dfilter_deprecated_tokens(dfp);
        }
        if (text.isEmpty()) {
            setSyntaxState(Empty);
        } else if (depr) {
            /* You keep using that word. I do not think it means what you think it means. */
            setSyntaxState(Deprecated);
            /*
             * We're being lazy and only printing the first "problem" token.
             * Would it be better to print all of them?
             */
            emit pushFilterSyntaxWarning(QString().sprintf("\"%s\" may have unexpected results (see the User's Guide)",
                                                          (const char *) g_ptr_array_index(depr, 0)));
        } else {
            setSyntaxState(Valid);
        }
        dfilter_free(dfp);
    } else {
        setSyntaxState(Invalid);
        QString invalidMsg(tr("Invalid filter"));
        if (dfilter_error_msg) {
            invalidMsg.append(QString().sprintf(": %s", dfilter_error_msg));
        }
        emit pushFilterSyntaxStatus(invalidMsg);
    }

    bookmark_button_->setEnabled(syntaxState() == Valid || syntaxState() == Deprecated);
    if (apply_button_) {
        apply_button_->setEnabled(SyntaxState() != Invalid);
    }
}
void CaptureFilterEdit::checkFilter(const QString& text)
{
    setSyntaxState(Empty);
    popFilterSyntaxStatus();
    bool empty = text.isEmpty();

    bookmark_button_->setEnabled(false);
    if (apply_button_) {
        apply_button_->setEnabled(false);
    }

    if (empty) {
        clear_button_->setVisible(false);
        setFilterSyntaxState(text, true, QString());
    } else {
        clear_button_->setVisible(true);
        syntax_worker_->checkFilter(text);
    }
}
示例#7
0
void FieldFilterEdit::checkFilter(const QString& filter_text)
{
    popFilterSyntaxStatus();
    checkDisplayFilter(filter_text);

    switch (syntaxState()) {
    case Deprecated:
    {
        emit pushFilterSyntaxWarning(syntaxErrorMessage());
        break;
    }
    case Invalid:
    {
        QString invalidMsg(tr("Invalid filter: "));
        invalidMsg.append(syntaxErrorMessage());
        emit pushFilterSyntaxStatus(invalidMsg);
        break;
    }
    default:
        break;
    }
}
void CaptureFilterEdit::checkFilter(const QString& filter)
{
    setSyntaxState(Busy);
    popFilterSyntaxStatus();
    bool empty = filter.isEmpty();

    if (bookmark_button_) {
        bookmark_button_->setEnabled(false);
    }

    if (apply_button_) {
        apply_button_->setEnabled(false);
    }

    if (clear_button_) {
        clear_button_->setVisible(!empty);
    }

    if (empty) {
        setFilterSyntaxState(filter, Empty, QString());
    } else {
        syntax_worker_->checkFilter(filter);
    }
}
示例#9
0
void FieldFilterEdit::focusOutEvent(QFocusEvent *event)
{
    if (syntaxState() == Valid)
        emit popFilterSyntaxStatus();
    SyntaxLineEdit::focusOutEvent(event);
}
示例#10
0
void DisplayFilterEdit::checkFilter(const QString& filter_text)
{
    if (clear_button_) {
        clear_button_->setVisible(!filter_text.isEmpty());
    }

    popFilterSyntaxStatus();
    checkDisplayFilter(filter_text);

    switch (syntaxState()) {
    case Deprecated:
    {
        /*
         * We're being lazy and only printing the first "problem" token.
         * Would it be better to print all of them?
         */
        QString deprecatedMsg(tr("\"%1\" may have unexpected results (see the User's Guide)")
                .arg(deprecatedToken()));
        emit pushFilterSyntaxWarning(deprecatedMsg);
        break;
    }
    case Invalid:
    {
        QString invalidMsg(tr("Invalid filter: "));
        invalidMsg.append(syntaxErrorMessage());
        emit pushFilterSyntaxStatus(invalidMsg);
        break;
    }
    default:
        break;
    }

    if (bookmark_button_) {
        bool enable_save_action = false;
        bool match = false;
        QMenu *bb_menu = bookmark_button_->menu();

        bb_menu->clear();
        QAction *save_action = bb_menu->addAction(tr("Save this filter"));
        connect(save_action, SIGNAL(triggered(bool)), this, SLOT(saveFilter()));
        QAction *manage_action = bb_menu->addAction(tr("Manage Display Filters"));
        connect(manage_action, SIGNAL(triggered(bool)), this, SLOT(showFilters()));
        QAction *expr_action = bb_menu->addAction(tr("Manage Filter Expressions"));
        connect(expr_action, SIGNAL(triggered(bool)), this, SLOT(showExpressionPrefs()));

        QAction *first_filter = NULL;
        for (GList *df_item = get_filter_list_first(DFILTER_LIST); df_item; df_item = g_list_next(df_item)) {
            if (!df_item->data) continue;
            filter_def *df_def = (filter_def *) df_item->data;
            if (!df_def->name || !df_def->strval) continue;

            int one_em = bb_menu->fontMetrics().height();
            QString prep_text = QString("%1: %2").arg(df_def->name).arg(df_def->strval);
            prep_text = bb_menu->fontMetrics().elidedText(prep_text, Qt::ElideRight, one_em * 40);

            QAction *prep_action = bb_menu->addAction(prep_text);
            prep_action->setData(df_def->strval);
            connect(prep_action, SIGNAL(triggered(bool)), this, SLOT(prepareFilter()));
            if (!first_filter) first_filter = prep_action;

            if (filter_text.compare(df_def->strval) == 0) {
                match = true;
            }
        }
        if (first_filter) bb_menu->insertSeparator(first_filter);

        if (match) {
            bookmark_button_->setStockIcon("x-filter-matching-bookmark");
            QAction *remove_action = new QAction(tr("Remove this filter"), bb_menu);
            bb_menu->insertAction(manage_action, remove_action);
            remove_action->setData(filter_text);
            connect(remove_action, SIGNAL(triggered(bool)), this, SLOT(removeFilter()));
        } else {
            bookmark_button_->setStockIcon("x-filter-bookmark");
        }

        if (!match && (syntaxState() == Valid || syntaxState() == Deprecated) && !filter_text.isEmpty()) {
            enable_save_action = true;
        }
        save_action->setEnabled(enable_save_action);
    }