diff options
Diffstat (limited to 'ui/qt/additional_toolbar.cpp')
-rw-r--r-- | ui/qt/additional_toolbar.cpp | 537 |
1 files changed, 537 insertions, 0 deletions
diff --git a/ui/qt/additional_toolbar.cpp b/ui/qt/additional_toolbar.cpp new file mode 100644 index 0000000000..5192fb5312 --- /dev/null +++ b/ui/qt/additional_toolbar.cpp @@ -0,0 +1,537 @@ +/* additional_toolbar.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <additional_toolbar.h> +#include <config.h> + +#include <glib.h> + +#include <ui/qt/apply_line_edit.h> +#include <ui/qt/qt_ui_utils.h> +#include <ui/qt/variant_pointer.h> +#include <ui/qt/wireshark_application.h> + +#include <QLabel> +#include <QLineEdit> +#include <QHBoxLayout> +#include <QComboBox> +#include <QWidget> +#include <QCheckBox> +#include <QPushButton> +#include <QStandardItem> +#include <QStandardItemModel> +#include <QLayoutItem> + +const char * AdditionalToolbarWidgetAction::propertyName = "additional_toolbar_item"; + +AdditionalToolBar::AdditionalToolBar(ext_toolbar_t * exttoolbar, QWidget * parent) +: QToolBar(parent), + toolbar(exttoolbar) +{ } + +AdditionalToolBar::~AdditionalToolBar() +{ } + +AdditionalToolBar * AdditionalToolBar::create(QWidget * parent, ext_toolbar_t * toolbar) +{ + if ( g_list_length( toolbar->children ) == 0 ) + return NULL; + + AdditionalToolBar * result = new AdditionalToolBar(toolbar, parent); + result->setMovable(false); + result->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + result->layout()->setMargin(0); + result->layout()->setSpacing(4); + + GList * walker = toolbar->children; + bool spacerNeeded = true; + + while ( walker && walker->data ) + { + ext_toolbar_t * item = (ext_toolbar_t *)walker->data; + if ( item->type == EXT_TOOLBAR_ITEM ) + { + if ( item->item_type == EXT_TOOLBAR_STRING ) + spacerNeeded = false; + + QAction * newAction = new AdditionalToolbarWidgetAction(item, result); + if ( newAction ) + { + result->addAction(newAction); + /* Necessary, because enable state is resetted upon adding the action */ + result->actions()[result->actions().count() - 1]->setEnabled(!item->capture_only); + } + } + + walker = g_list_next ( walker ); + } + + if ( result->children().count() == 0 ) + return NULL; + + if ( spacerNeeded ) + { + QWidget * empty = new QWidget(); + empty->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred); + result->addWidget(empty); + + } + + return result; +} + +QString AdditionalToolBar::menuName() +{ + return (toolbar && toolbar->name) ? QString(toolbar->name) : QString(); +} + +AdditionalToolbarWidgetAction::AdditionalToolbarWidgetAction(QObject * parent) +: QWidgetAction(parent), + toolbar_item(0) +{ } + +AdditionalToolbarWidgetAction::AdditionalToolbarWidgetAction(ext_toolbar_t * item, QObject * parent) +: QWidgetAction(parent), + toolbar_item(item) +{ + connect(wsApp, SIGNAL(captureActive(int)), this, SLOT(captureActive(int))); +} + +AdditionalToolbarWidgetAction::AdditionalToolbarWidgetAction(const AdditionalToolbarWidgetAction & copy_object) +: QWidgetAction(copy_object.parent()), + toolbar_item(copy_object.toolbar_item) +{ + connect(wsApp, SIGNAL(captureActive(int)), this, SLOT(captureActive(int))); +} + + +void AdditionalToolbarWidgetAction::captureActive(int activeCaptures) +{ + if ( toolbar_item && toolbar_item->capture_only ) + { + setEnabled(activeCaptures != 0); + } +} + +/* Exists, so a default deconstructor does not call delete on toolbar_item */ +AdditionalToolbarWidgetAction::~AdditionalToolbarWidgetAction() { } + +QWidget * AdditionalToolbarWidgetAction::createWidget(QWidget * parent) +{ + QWidget * barItem = 0; + + if ( toolbar_item->type != EXT_TOOLBAR_ITEM ) + return barItem; + + switch ( toolbar_item->item_type ) + { + case EXT_TOOLBAR_BUTTON: + barItem = createButton(toolbar_item, parent); + break; + case EXT_TOOLBAR_BOOLEAN: + barItem = createBoolean(toolbar_item, parent); + break; + case EXT_TOOLBAR_STRING: + barItem = createTextEditor(toolbar_item, parent); + break; + case EXT_TOOLBAR_SELECTOR: + barItem = createSelector(toolbar_item, parent); + break; + } + + if ( ! barItem ) + return 0; + + barItem->setToolTip(toolbar_item->tooltip); + barItem->setProperty(propertyName, VariantPointer<ext_toolbar_t>::asQVariant(toolbar_item)); + +#ifdef Q_OS_MAC + barItem->setAttribute(Qt::WA_MacSmallSize, true); +#endif + + return barItem; +} + +static void +toolbar_button_cb(gpointer item, gpointer item_data, gpointer user_data) +{ + if ( ! item || ! item_data || ! user_data ) + return; + + QPushButton * widget = (QPushButton *)(item_data); + ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data; + + if ( widget && update_entry->type == EXT_TOOLBAR_UPDATE_VALUE ) + widget->setText((gchar *)update_entry->user_data); +} + +QWidget * AdditionalToolbarWidgetAction::createButton(ext_toolbar_t * item, QWidget * parent) +{ + if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_BUTTON ) + return 0; + + QString defValue = item->defvalue; + + QPushButton * button = new QPushButton(item->name, parent); + button->setText(item->name); + connect(button, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + + ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_button_cb, (void *)button); + + return button; +} + +static void +toolbar_boolean_cb(gpointer item, gpointer item_data, gpointer user_data) +{ + if ( ! item || ! item_data || ! user_data ) + return; + + QCheckBox * widget = (QCheckBox *)(item_data); + ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data; + + if ( widget && update_entry->type == EXT_TOOLBAR_UPDATE_VALUE ) + { + bool oldState = false; + if ( update_entry->silent ) + oldState = widget->blockSignals(true); + + widget->setCheckState(GPOINTER_TO_INT(update_entry->user_data) == 1 ? Qt::Checked : Qt::Unchecked); + + if ( update_entry->silent ) + widget->blockSignals(oldState); + } +} + +QWidget * AdditionalToolbarWidgetAction::createBoolean(ext_toolbar_t * item, QWidget * parent) +{ + if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_BOOLEAN ) + return 0; + + QString defValue = toolbar_item->defvalue; + + QCheckBox * checkbox = new QCheckBox(item->name, parent); + checkbox->setText(item->name); + setCheckable(true); + checkbox->setCheckState(defValue.compare("true", Qt::CaseInsensitive) == 0 ? Qt::Checked : Qt::Unchecked); + connect(checkbox, SIGNAL(stateChanged(int)), this, SLOT(onCheckBoxChecked(int))); + + ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_boolean_cb, (void *)checkbox); + + return checkbox; +} + +QWidget * AdditionalToolbarWidgetAction::createLabelFrame(ext_toolbar_t * item, QWidget * parent) +{ + if ( ! item ) + return new QWidget(); + + QWidget * frame = new QWidget(parent); + + QHBoxLayout * frameLayout = new QHBoxLayout(frame); + frameLayout->setMargin(0); + frameLayout->setSpacing(0); + + QLabel * strLabel = new QLabel(item->name, frame); + strLabel->setToolTip(item->tooltip); + +#ifdef Q_OS_MAC + frame->setAttribute(Qt::WA_MacSmallSize, true); + strLabel->setAttribute(Qt::WA_MacSmallSize, true); +#endif + + frameLayout->addWidget(strLabel); + + frame->setLayout(frameLayout); + + return frame; +} + +static void +toolbar_string_cb(gpointer item, gpointer item_data, gpointer user_data) +{ + if ( ! item || ! item_data || ! user_data ) + return; + + ApplyLineEdit * edit = (ApplyLineEdit *)(item_data); + ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data; + + if ( edit && update_entry->type == EXT_TOOLBAR_UPDATE_VALUE ) + { + bool oldState = false; + if ( update_entry->silent ) + oldState = edit->blockSignals(true); + + edit->setText((gchar *)update_entry->user_data); + + if ( update_entry->silent ) + edit->blockSignals(oldState); + } +} + +QWidget * AdditionalToolbarWidgetAction::createTextEditor(ext_toolbar_t * item, QWidget * parent) +{ + if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_STRING ) + return 0; + + QWidget * frame = createLabelFrame(toolbar_item, parent); + + ApplyLineEdit * strEdit = new ApplyLineEdit(toolbar_item->defvalue, frame); + strEdit->setToolTip(toolbar_item->tooltip); + strEdit->setRegEx(toolbar_item->regex); + strEdit->setEmptyAllowed(toolbar_item->is_required); + strEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + +#ifdef Q_OS_MAC + strEdit->setAttribute(Qt::WA_MacSmallSize, true); +#endif + + frame->layout()->addWidget(strEdit); + + connect(strEdit, SIGNAL(textApplied()), this, SLOT(sendTextToCallback())); + + ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_string_cb, (void *)strEdit); + + return frame; +} + +static void +toolbar_selector_cb(gpointer item, gpointer item_data, gpointer user_data) +{ + if ( ! item || ! item_data || ! user_data ) + return; + + QComboBox * comboBox = (QComboBox *)(item_data); + ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data; + + bool oldState = false; + + if ( update_entry->silent ) + oldState = comboBox->blockSignals(true); + + if ( update_entry->type == EXT_TOOLBAR_UPDATE_VALUE ) + { + QString data = QString((gchar *)update_entry->user_data); + bool conv_ok = false; + + int dataValue = data.toInt(&conv_ok, 10); + if ( conv_ok && dataValue >= 0 && comboBox->model()->rowCount() < dataValue ) + comboBox->setCurrentIndex(dataValue); + else + comboBox->setCurrentText(data); + } + else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATA ) + { + QStandardItemModel * sourceModel = (QStandardItemModel *)comboBox->model(); + + GList * walker = (GList *)update_entry->user_data; + if ( g_list_length(walker) == 0 ) + return; + + sourceModel->clear(); + + while ( walker && walker->data ) + { + ext_toolbar_value_t * listvalue = (ext_toolbar_value_t *)walker->data; + + QStandardItem * si = new QStandardItem(listvalue->display); + si->setData(VariantPointer<ext_toolbar_value_t>::asQVariant(listvalue), Qt::UserRole); + sourceModel->appendRow(si); + + walker = g_list_next(walker); + } + } + else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATABYINDEX ) + { + QStandardItemModel * sourceModel = (QStandardItemModel *)comboBox->model(); + + if ( ! update_entry->user_data || ! update_entry->data_index ) + return; + + gchar * idx = (gchar *)update_entry->data_index; + gchar * display = (gchar *)update_entry->user_data; + + for ( int i = 0; i < sourceModel->rowCount(); i++ ) + { + QStandardItem * item = sourceModel->item(i, 0); + ext_toolbar_value_t * entry = VariantPointer<ext_toolbar_value_t>::asPtr(item->data(Qt::UserRole)); + if ( entry && g_strcmp0( entry->value, idx) == 0 ) + { + item->setText(display); + break; + } + } + } + + if ( update_entry->silent ) + comboBox->blockSignals(oldState); + +} + +QWidget * AdditionalToolbarWidgetAction::createSelector(ext_toolbar_t * item, QWidget * parent) +{ + if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_SELECTOR ) + return 0; + + if ( g_list_length(item->values) == 0 ) + return 0; + + QWidget * frame = createLabelFrame(item, parent); + + QComboBox * myBox = new QComboBox(parent); + myBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + + QStandardItemModel * sourceModel = new QStandardItemModel(); + + GList * walker = item->values; + int selIndex = 0; + while ( walker && walker->data ) + { + ext_toolbar_value_t * listvalue = (ext_toolbar_value_t *)walker->data; + + QStandardItem * si = new QStandardItem(listvalue->display); + si->setData(VariantPointer<ext_toolbar_value_t>::asQVariant(listvalue), Qt::UserRole); + sourceModel->appendRow(si); + + if ( listvalue->is_default ) + selIndex = sourceModel->rowCount(); + + walker = g_list_next(walker); + } + + myBox->setModel(sourceModel); + myBox->setCurrentIndex(selIndex); + +#ifdef Q_OS_MAC + myBox->setAttribute(Qt::WA_MacSmallSize, true); +#endif + + frame->layout()->addWidget(myBox); + + connect(myBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionInWidgetChanged(int))); + + ext_toolbar_register_update_cb(item, (ext_toolbar_action_cb)&toolbar_selector_cb, (void *)myBox); + + return frame; +} + +ext_toolbar_t * AdditionalToolbarWidgetAction::extractToolbarItemFromObject(QObject * object) +{ + QWidget * widget = dynamic_cast<QWidget *>(object); + if ( ! widget ) + return 0; + + QVariant propValue = widget->property(propertyName); + + /* If property is invalid, look if our parent has this property */ + if ( ! propValue.isValid() ) + { + QWidget * frame = dynamic_cast<QWidget *>(widget->parent()); + if ( ! frame ) + return 0; + + propValue = frame->property(propertyName); + } + + if ( ! propValue.isValid() ) + return 0; + + return VariantPointer<ext_toolbar_t>::asPtr(propValue); +} + +void AdditionalToolbarWidgetAction::onButtonClicked() +{ + ext_toolbar_t * item = extractToolbarItemFromObject(sender()); + if ( ! item ) + return; + + item->callback(item, 0, item->user_data); +} + +void AdditionalToolbarWidgetAction::onCheckBoxChecked(int checkState) +{ + ext_toolbar_t * item = extractToolbarItemFromObject(sender()); + if ( ! item ) + return; + + gboolean value = checkState == Qt::Checked ? true : false; + + item->callback(item, &value, item->user_data); +} + +void AdditionalToolbarWidgetAction::sendTextToCallback() +{ + ext_toolbar_t * item = extractToolbarItemFromObject(sender()); + if ( ! item ) + return; + + if (item->item_type != EXT_TOOLBAR_STRING ) + return; + + ApplyLineEdit * editor = dynamic_cast<ApplyLineEdit *>(sender()); + if ( ! editor ) + { + /* Called from button, searching for acompanying line edit */ + QWidget * parent = dynamic_cast<QWidget *>(sender()->parent()); + if ( parent ) + { + QList<ApplyLineEdit *> children = parent->findChildren<ApplyLineEdit *>(); + if ( children.count() >= 0 ) + editor = children.at(0); + } + } + + if ( editor ) + item->callback(item, qstring_strdup(editor->text()), item->user_data); +} + +void AdditionalToolbarWidgetAction::onSelectionInWidgetChanged(int idx) +{ + QComboBox * editor = dynamic_cast<QComboBox *>(sender()); + ext_toolbar_t * item = extractToolbarItemFromObject(editor); + if ( ! item || item->item_type != EXT_TOOLBAR_SELECTOR ) + return; + + QStandardItemModel * sourceModel = (QStandardItemModel *) editor->model(); + if ( sourceModel->rowCount() <= idx ) + return; + + QModelIndex mdIdx = sourceModel->index(idx, 0); + QVariant dataSet = sourceModel->data(mdIdx, Qt::UserRole); + if ( dataSet.isValid() ) + { + ext_toolbar_value_t * value_entry = VariantPointer<ext_toolbar_value_t>::asPtr(dataSet); + item->callback(item, value_entry, item->user_data); + } +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |