/* additional_toolbar.cpp * * Wireshark - Network traffic analyzer * By Gerald Combs * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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::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 ) { if ( update_entry->type == EXT_TOOLBAR_UPDATE_VALUE ) widget->setText((gchar *)update_entry->user_data); else if ( update_entry->type == EXT_TOOLBAR_SET_ACTIVE ) { bool enableState = GPOINTER_TO_INT(update_entry->user_data) == 1; widget->setEnabled(enableState); } } } QWidget * AdditionalToolbarWidgetAction::createButton(ext_toolbar_t * item, QWidget * parent) { if ( ! item || item->type != EXT_TOOLBAR_ITEM || item->item_type != EXT_TOOLBAR_BUTTON ) return 0; 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); if ( ! widget ) return; ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data; if ( 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); } else if ( update_entry->type == EXT_TOOLBAR_SET_ACTIVE ) { bool enableState = GPOINTER_TO_INT(update_entry->user_data) == 1; widget->setEnabled(enableState); } } 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); if ( ! edit ) return; ext_toolbar_update_t * update_entry = (ext_toolbar_update_t *)user_data; if ( 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); } else if ( update_entry->type == EXT_TOOLBAR_SET_ACTIVE ) { bool enableState = GPOINTER_TO_INT(update_entry->user_data) == 1; edit->setEnabled(enableState); } } 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); QStandardItemModel * sourceModel = (QStandardItemModel *)comboBox->model(); if ( update_entry->type == EXT_TOOLBAR_SET_ACTIVE ) { bool enableState = GPOINTER_TO_INT(update_entry->user_data) == 1; comboBox->setEnabled(enableState); } else if ( update_entry->type != EXT_TOOLBAR_UPDATE_DATA_REMOVE && ! update_entry->user_data ) return; if ( update_entry->type == EXT_TOOLBAR_UPDATE_VALUE ) { QString data = QString((gchar *)update_entry->user_data); for(int i = 0; i < sourceModel->rowCount(); i++) { QStandardItem * dataValue = ((QStandardItemModel *)sourceModel)->item(i, 0); ext_toolbar_value_t * tbValue = VariantPointer::asPtr(dataValue->data(Qt::UserRole)); if ( tbValue && data.compare(QString(tbValue->value)) == 0 ) { comboBox->setCurrentIndex(i); break; } } } else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATA ) { 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::asQVariant(listvalue), Qt::UserRole); sourceModel->appendRow(si); walker = g_list_next(walker); } } else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATABYINDEX || update_entry->type == EXT_TOOLBAR_UPDATE_DATA_ADD || update_entry->type == EXT_TOOLBAR_UPDATE_DATA_REMOVE ) { if ( ! update_entry->data_index ) return; gchar * idx = (gchar *)update_entry->data_index; gchar * display = (gchar *)update_entry->user_data; if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATABYINDEX ) { for ( int i = 0; i < sourceModel->rowCount(); i++ ) { QStandardItem * dataValue = sourceModel->item(i, 0); ext_toolbar_value_t * entry = VariantPointer::asPtr(dataValue->data(Qt::UserRole)); if ( entry && g_strcmp0( entry->value, idx) == 0 ) { g_free(entry->display); entry->display = g_strdup(display); dataValue->setData(VariantPointer::asQVariant(entry), Qt::UserRole); dataValue->setText(display); break; } } } else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATA_ADD ) { ext_toolbar_value_t * listvalue = g_new0(ext_toolbar_value_t, 1); listvalue->display = g_strdup(display); listvalue->value = g_strdup(idx); QStandardItem * si = new QStandardItem(listvalue->display); si->setData(VariantPointer::asQVariant(listvalue), Qt::UserRole); sourceModel->appendRow(si); } else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATA_REMOVE ) { QList entryList = sourceModel->findItems(display); /* Search for index if display did not find anything */ if ( entryList.size() == 0 ) entryList = sourceModel->findItems(idx); foreach(QStandardItem *entry, entryList) { QModelIndex index = sourceModel->indexFromItem(entry); if ( index.isValid() ) sourceModel->removeRow(index.row()); } } } 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::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(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(widget->parent()); if ( ! frame ) return 0; propValue = frame->property(propertyName); } if ( ! propValue.isValid() ) return 0; return VariantPointer::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(sender()); if ( ! editor ) { /* Called from button, searching for acompanying line edit */ QWidget * parent = dynamic_cast(sender()->parent()); if ( parent ) { QList children = parent->findChildren(); 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(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::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: */