/* module_preferences_scroll_area.cpp * * $Id$ * * 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 "module_preferences_scroll_area.h" #include "ui_module_preferences_scroll_area.h" #include "syntax_line_edit.h" #include "qt_ui_utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include Q_DECLARE_METATYPE(pref_t *) const char *pref_prop_ = "pref_ptr"; extern "C" { // Callbacks prefs routines /* show a single preference on the GtkGrid of a preference page */ static guint pref_show(pref_t *pref, gpointer layout_ptr) { QVBoxLayout *vb = static_cast(layout_ptr); if (!pref || !vb) return 0; switch (pref->type) { case PREF_UINT: { QHBoxLayout *hb = new QHBoxLayout(); hb->addWidget(new QLabel(pref->title)); QLineEdit *uint_le = new QLineEdit(); uint_le->setProperty(pref_prop_, qVariantFromValue(pref)); uint_le->setMinimumWidth(uint_le->fontMetrics().height() * 8); hb->addWidget(uint_le); hb->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); vb->addLayout(hb); break; } case PREF_BOOL: { QCheckBox *bool_cb = new QCheckBox(pref->title); bool_cb->setProperty(pref_prop_, qVariantFromValue(pref)); vb->addWidget(bool_cb); break; } case PREF_ENUM: { const enum_val_t *ev; if (!pref->info.enum_info.enumvals) return 0; if (pref->info.enum_info.radio_buttons) { vb->addWidget(new QLabel(pref->title)); QButtonGroup *enum_bg = new QButtonGroup(); for (ev = pref->info.enum_info.enumvals; ev && ev->description; ev++) { QRadioButton *enum_rb = new QRadioButton(ev->description); QStyleOption style_opt; enum_rb->setProperty(pref_prop_, qVariantFromValue(pref)); enum_rb->setStyleSheet(QString( "QRadioButton {" " margin-left: %1px;" "}" ) .arg(enum_rb->style()->subElementRect(QStyle::SE_CheckBoxContents, &style_opt).left())); enum_bg->addButton(enum_rb, ev->value); vb->addWidget(enum_rb); } } else { QHBoxLayout *hb = new QHBoxLayout(); QComboBox *enum_cb = new QComboBox(); enum_cb->setProperty(pref_prop_, qVariantFromValue(pref)); for (ev = pref->info.enum_info.enumvals; ev && ev->description; ev++) { enum_cb->addItem(ev->description, QVariant(ev->value)); } hb->addWidget(new QLabel(pref->title)); hb->addWidget(enum_cb); hb->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); vb->addLayout(hb); } break; } case PREF_STRING: { QHBoxLayout *hb = new QHBoxLayout(); hb->addWidget(new QLabel(pref->title)); QLineEdit *string_le = new QLineEdit(); string_le->setProperty(pref_prop_, qVariantFromValue(pref)); string_le->setMinimumWidth(string_le->fontMetrics().height() * 20); hb->addWidget(string_le); hb->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); vb->addLayout(hb); break; } case PREF_RANGE: { QHBoxLayout *hb = new QHBoxLayout(); hb->addWidget(new QLabel(pref->title)); SyntaxLineEdit *range_se = new SyntaxLineEdit(); range_se->setProperty(pref_prop_, qVariantFromValue(pref)); range_se->setMinimumWidth(range_se->fontMetrics().height() * 20); hb->addWidget(range_se); hb->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); vb->addLayout(hb); break; } case PREF_STATIC_TEXT: { vb->addWidget(new QLabel(pref->title)); break; } case PREF_UAT: { QHBoxLayout *hb = new QHBoxLayout(); hb->addWidget(new QLabel(pref->title)); QPushButton *uat_pb = new QPushButton("Edit..."); uat_pb->setProperty(pref_prop_, qVariantFromValue(pref)); hb->addWidget(uat_pb); hb->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); vb->addLayout(hb); break; } case PREF_COLOR: { // XXX - Not needed yet. When it is needed we can add a label + QFrame which pops up a // color picker similar to the Font and Colors prefs. break; } default: break; } return 0; } } // extern "C" ModulePreferencesScrollArea::ModulePreferencesScrollArea(module_t *module, QWidget *parent) : QScrollArea(parent), ui(new Ui::ModulePreferencesScrollArea), module_(module) { ui->setupUi(this); if (!module) return; /* Add items for each of the preferences */ prefs_pref_foreach(module, pref_show, (gpointer) ui->verticalLayout); foreach (QLineEdit *le, findChildren()) { pref_t *pref = le->property(pref_prop_).value(); if (!pref) continue; if (pref->type == PREF_UINT) { connect(le, SIGNAL(textEdited(QString)), this, SLOT(uintLineEditTextEdited(QString))); } else if (pref->type == PREF_STRING) { connect(le, SIGNAL(textEdited(QString)), this, SLOT(stringLineEditTextEdited(QString))); } else if (pref->type == PREF_RANGE) { connect(le, SIGNAL(textEdited(QString)), this, SLOT(rangeSyntaxLineEditTextEdited(QString))); } } foreach (QCheckBox *cb, findChildren()) { pref_t *pref = cb->property(pref_prop_).value(); if (!pref) continue; if (pref->type == PREF_BOOL) { connect(cb, SIGNAL(toggled(bool)), this, SLOT(boolCheckBoxToggled(bool))); } } foreach (QRadioButton *enum_rb, findChildren()) { pref_t *pref = enum_rb->property(pref_prop_).value(); if (!pref) continue; if (pref->type == PREF_ENUM && pref->info.enum_info.radio_buttons) { connect(enum_rb, SIGNAL(toggled(bool)), this, SLOT(enumRadioButtonToggled(bool))); } } foreach (QComboBox *enum_cb, findChildren()) { pref_t *pref = enum_cb->property(pref_prop_).value(); if (!pref) continue; if (pref->type == PREF_ENUM && !pref->info.enum_info.radio_buttons) { connect(enum_cb, SIGNAL(currentIndexChanged(int)), this, SLOT(enumComboBoxCurrentIndexChanged(int))); } } foreach (QPushButton *uat_pb, findChildren()) { pref_t *pref = uat_pb->property(pref_prop_).value(); if (!pref) continue; if (pref->type == PREF_UAT) { connect(uat_pb, SIGNAL(pressed()), this, SLOT(uatPushButtonPressed())); } } ui->verticalLayout->addSpacerItem(new QSpacerItem(10, 1, QSizePolicy::Minimum, QSizePolicy::Expanding)); } ModulePreferencesScrollArea::~ModulePreferencesScrollArea() { delete ui; } void ModulePreferencesScrollArea::showEvent(QShowEvent *evt) { Q_UNUSED(evt) updateWidgets(); } void ModulePreferencesScrollArea::resizeEvent(QResizeEvent *evt) { QScrollArea::resizeEvent(evt); if (verticalScrollBar()->isVisible()) { setFrameStyle(QFrame::StyledPanel); } else { setFrameStyle(QFrame::NoFrame); } } void ModulePreferencesScrollArea::updateWidgets() { foreach (QLineEdit *le, findChildren()) { pref_t *pref = le->property(pref_prop_).value(); if (!pref) continue; le->setText(gchar_free_to_qstring(prefs_pref_to_str(pref, pref_stashed)).remove(QRegExp("\n\t"))); } foreach (QCheckBox *cb, findChildren()) { pref_t *pref = cb->property(pref_prop_).value(); if (!pref) continue; if (pref->type == PREF_BOOL) { cb->setChecked(pref->stashed_val.boolval); } } foreach (QRadioButton *enum_rb, findChildren()) { pref_t *pref = enum_rb->property(pref_prop_).value(); if (!pref) continue; QButtonGroup *enum_bg = enum_rb->group(); if (!enum_bg) continue; if (pref->type == PREF_ENUM && pref->info.enum_info.radio_buttons) { if (pref->stashed_val.enumval == enum_bg->id(enum_rb)) { enum_rb->setChecked(true); } } } foreach (QComboBox *enum_cb, findChildren()) { pref_t *pref = enum_cb->property(pref_prop_).value(); if (!pref) continue; if (pref->type == PREF_ENUM && !pref->info.enum_info.radio_buttons) { for (int i = 0; i < enum_cb->count(); i++) { if (pref->stashed_val.enumval == enum_cb->itemData(i).toInt()) { enum_cb->setCurrentIndex(i); } } } } } void ModulePreferencesScrollArea::uintLineEditTextEdited(const QString &new_str) { QLineEdit *uint_le = qobject_cast(sender()); if (!uint_le) return; pref_t *pref = uint_le->property(pref_prop_).value(); if (!pref) return; bool ok; uint new_uint = new_str.toUInt(&ok); if (ok) { pref->stashed_val.uint = new_uint; } } void ModulePreferencesScrollArea::boolCheckBoxToggled(bool checked) { QCheckBox *bool_cb = qobject_cast(sender()); if (!bool_cb) return; pref_t *pref = bool_cb->property(pref_prop_).value(); if (!pref) return; pref->stashed_val.boolval = checked; } void ModulePreferencesScrollArea::enumRadioButtonToggled(bool checked) { if (!checked) return; QRadioButton *enum_rb = qobject_cast(sender()); if (!enum_rb) return; QButtonGroup *enum_bg = enum_rb->group(); if (!enum_bg) return; pref_t *pref = enum_rb->property(pref_prop_).value(); if (!pref) return; if (enum_bg->checkedId() >= 0) { pref->stashed_val.enumval = enum_bg->checkedId(); } } void ModulePreferencesScrollArea::enumComboBoxCurrentIndexChanged(int index) { QComboBox *enum_cb = qobject_cast(sender()); if (!enum_cb) return; pref_t *pref = enum_cb->property(pref_prop_).value(); if (!pref) return; pref->stashed_val.enumval = enum_cb->itemData(index).toInt(); } void ModulePreferencesScrollArea::stringLineEditTextEdited(const QString &new_str) { QLineEdit *string_le = qobject_cast(sender()); if (!string_le) return; pref_t *pref = string_le->property(pref_prop_).value(); if (!pref) return; g_free((void *)pref->stashed_val.string); pref->stashed_val.string = qstring_strdup(new_str); } void ModulePreferencesScrollArea::rangeSyntaxLineEditTextEdited(const QString &new_str) { SyntaxLineEdit *range_se = qobject_cast(sender()); if (!range_se) return; pref_t *pref = range_se->property(pref_prop_).value(); if (!pref) return; range_t *newrange; convert_ret_t ret = range_convert_str(&newrange, new_str.toUtf8().constData(), pref->info.max_value); if (ret == CVT_NO_ERROR) { g_free(pref->stashed_val.range); pref->stashed_val.range = newrange; if (new_str.isEmpty()) { range_se->setSyntaxState(SyntaxLineEdit::Empty); } else { range_se->setSyntaxState(SyntaxLineEdit::Valid); } } else { range_se->setSyntaxState(SyntaxLineEdit::Invalid); } } void ModulePreferencesScrollArea::uatPushButtonPressed() { QPushButton *uat_pb = qobject_cast(sender()); if (!uat_pb) return; pref_t *pref = uat_pb->property(pref_prop_).value(); if (!pref) return; qDebug() << "FIX Implement UATs:" << pref->title; } /* * Editor modelines * * Local Variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * ex: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */