wireshark/ui/qt/widgets/additional_toolbar.cpp

601 lines
18 KiB
C++

/* 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 <config.h>
#include <glib.h>
#include <ui/qt/widgets/additional_toolbar.h>
#include <ui/qt/widgets/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 )
{
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<ext_toolbar_value_t>::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<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 ||
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<ext_toolbar_value_t>::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<ext_toolbar_value_t>::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<ext_toolbar_value_t>::asQVariant(listvalue), Qt::UserRole);
sourceModel->appendRow(si);
}
else if ( update_entry->type == EXT_TOOLBAR_UPDATE_DATA_REMOVE )
{
QList<QStandardItem *> 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<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:
*/