2012-12-29 01:39:02 +00:00
|
|
|
/* profile_dialog.cpp
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-04-30 07:47:58 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2012-12-29 01:39:02 +00:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include <glib.h>
|
|
|
|
|
2013-11-17 02:55:14 +00:00
|
|
|
#include "wsutil/filesystem.h"
|
2012-12-29 01:39:02 +00:00
|
|
|
#include "epan/prefs.h"
|
|
|
|
|
2017-07-25 14:15:18 +00:00
|
|
|
#include <ui/qt/utils/qt_ui_utils.h>
|
2014-11-29 18:32:30 +00:00
|
|
|
|
2012-12-29 01:39:02 +00:00
|
|
|
#include "ui/profile.h"
|
2018-01-30 12:17:01 +00:00
|
|
|
#include "ui/recent.h"
|
2012-12-29 01:39:02 +00:00
|
|
|
|
2017-07-25 14:15:18 +00:00
|
|
|
#include <ui/qt/utils/variant_pointer.h>
|
2019-07-04 19:55:21 +00:00
|
|
|
#include <ui/qt/models/profile_model.h>
|
2017-01-11 12:55:23 +00:00
|
|
|
|
2012-12-29 01:39:02 +00:00
|
|
|
#include "profile_dialog.h"
|
2015-06-25 16:17:03 +00:00
|
|
|
#include <ui_profile_dialog.h>
|
2012-12-29 01:39:02 +00:00
|
|
|
#include "wireshark_application.h"
|
2017-07-25 14:15:18 +00:00
|
|
|
#include <ui/qt/utils/color_utils.h>
|
2012-12-29 01:39:02 +00:00
|
|
|
|
|
|
|
#include <QBrush>
|
2013-07-25 23:49:47 +00:00
|
|
|
#include <QDir>
|
|
|
|
#include <QFont>
|
2012-12-29 01:39:02 +00:00
|
|
|
#include <QMessageBox>
|
2015-02-08 20:24:19 +00:00
|
|
|
#include <QPushButton>
|
|
|
|
#include <QTreeWidgetItem>
|
2013-07-25 23:49:47 +00:00
|
|
|
#include <QUrl>
|
2019-07-04 19:55:21 +00:00
|
|
|
#include <QComboBox>
|
|
|
|
#include <QLineEdit>
|
2012-12-29 01:39:02 +00:00
|
|
|
|
|
|
|
ProfileDialog::ProfileDialog(QWidget *parent) :
|
2016-02-28 18:23:20 +00:00
|
|
|
GeometryStateDialog(parent),
|
2012-12-29 01:39:02 +00:00
|
|
|
pd_ui_(new Ui::ProfileDialog),
|
2019-07-04 19:55:21 +00:00
|
|
|
ok_button_(Q_NULLPTR),
|
|
|
|
model_(Q_NULLPTR),
|
|
|
|
sort_model_(Q_NULLPTR)
|
2012-12-29 01:39:02 +00:00
|
|
|
{
|
|
|
|
pd_ui_->setupUi(this);
|
2016-02-28 18:23:20 +00:00
|
|
|
loadGeometry();
|
2014-12-29 23:15:59 +00:00
|
|
|
setWindowTitle(wsApp->windowTitleString(tr("Configuration Profiles")));
|
2019-07-04 19:55:21 +00:00
|
|
|
|
2012-12-29 01:39:02 +00:00
|
|
|
ok_button_ = pd_ui_->buttonBox->button(QDialogButtonBox::Ok);
|
|
|
|
|
|
|
|
// XXX - Use NSImageNameAddTemplate and NSImageNameRemoveTemplate to set stock
|
2017-04-05 19:15:27 +00:00
|
|
|
// icons on macOS.
|
2012-12-29 01:39:02 +00:00
|
|
|
// Are there equivalent stock icons on Windows?
|
2019-06-20 18:25:49 +00:00
|
|
|
pd_ui_->newToolButton->setStockIcon("list-add");
|
|
|
|
pd_ui_->deleteToolButton->setStockIcon("list-remove");
|
|
|
|
pd_ui_->copyToolButton->setStockIcon("list-copy");
|
2013-04-24 11:07:25 +00:00
|
|
|
#ifdef Q_OS_MAC
|
2012-12-29 01:39:02 +00:00
|
|
|
pd_ui_->newToolButton->setAttribute(Qt::WA_MacSmallSize, true);
|
|
|
|
pd_ui_->deleteToolButton->setAttribute(Qt::WA_MacSmallSize, true);
|
|
|
|
pd_ui_->copyToolButton->setAttribute(Qt::WA_MacSmallSize, true);
|
2015-12-06 11:15:53 +00:00
|
|
|
pd_ui_->infoLabel->setAttribute(Qt::WA_MacSmallSize, true);
|
2012-12-29 01:39:02 +00:00
|
|
|
#endif
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
model_ = new ProfileModel(this);
|
|
|
|
sort_model_ = new ProfileSortModel(this);
|
|
|
|
sort_model_->setSourceModel(model_);
|
|
|
|
pd_ui_->profileTreeView->setModel(sort_model_);
|
2015-11-22 14:25:27 +00:00
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
connect(pd_ui_->profileTreeView, &ProfileTreeView::currentItemChanged,
|
|
|
|
this, &ProfileDialog::currentItemChanged);
|
2012-12-29 01:39:02 +00:00
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
connect(pd_ui_->profileTreeView->itemDelegate(), SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)),
|
2012-12-29 01:39:02 +00:00
|
|
|
this, SLOT(editingFinished()));
|
2019-07-04 19:55:21 +00:00
|
|
|
|
|
|
|
/* Select the row for the currently selected profile or the first row if non is selected*/
|
|
|
|
selectProfile();
|
|
|
|
|
|
|
|
QStringList items;
|
|
|
|
items << tr("All Profiles") << tr("Global profiles") << tr("User-defined profiles");
|
|
|
|
pd_ui_->cmbProfileTypes->addItems(items);
|
|
|
|
|
|
|
|
connect (pd_ui_->cmbProfileTypes, SIGNAL(currentTextChanged(const QString &)),
|
|
|
|
this, SLOT(filterChanged(const QString &)));
|
|
|
|
connect (pd_ui_->lineProfileFilter, SIGNAL(textChanged(const QString &)),
|
|
|
|
this, SLOT(filterChanged(const QString &)));
|
|
|
|
|
2012-12-29 01:39:02 +00:00
|
|
|
updateWidgets();
|
|
|
|
}
|
|
|
|
|
|
|
|
ProfileDialog::~ProfileDialog()
|
|
|
|
{
|
|
|
|
delete pd_ui_;
|
|
|
|
empty_profile_list (TRUE);
|
|
|
|
}
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
void ProfileDialog::selectProfile(QString profile)
|
|
|
|
{
|
|
|
|
if ( profile.isEmpty() )
|
|
|
|
profile = QString(get_profile_name());
|
|
|
|
|
|
|
|
int row = model_->findByName(profile);
|
|
|
|
QModelIndex idx = sort_model_->mapFromSource(model_->index(row, ProfileModel::COL_NAME));
|
|
|
|
if ( idx.isValid() )
|
|
|
|
pd_ui_->profileTreeView->selectRow(idx.row());
|
|
|
|
}
|
|
|
|
|
2012-12-30 19:33:05 +00:00
|
|
|
int ProfileDialog::execAction(ProfileDialog::ProfileAction profile_action)
|
|
|
|
{
|
|
|
|
int ret = QDialog::Accepted;
|
2019-07-04 19:55:21 +00:00
|
|
|
QModelIndex item;
|
2012-12-30 19:33:05 +00:00
|
|
|
|
|
|
|
switch (profile_action) {
|
|
|
|
case ShowProfiles:
|
|
|
|
ret = exec();
|
|
|
|
break;
|
|
|
|
case NewProfile:
|
|
|
|
on_newToolButton_clicked();
|
|
|
|
ret = exec();
|
|
|
|
break;
|
|
|
|
case EditCurrentProfile:
|
2019-07-04 19:55:21 +00:00
|
|
|
item = pd_ui_->profileTreeView->currentIndex();
|
|
|
|
if (item.isValid()) {
|
|
|
|
pd_ui_->profileTreeView->edit(item);
|
2012-12-30 19:33:05 +00:00
|
|
|
}
|
|
|
|
ret = exec();
|
|
|
|
break;
|
|
|
|
case DeleteCurrentProfile:
|
|
|
|
if (delete_current_profile()) {
|
2019-07-04 19:55:21 +00:00
|
|
|
wsApp->setConfigurationProfile (Q_NULLPTR);
|
2012-12-30 19:33:05 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-12-29 01:39:02 +00:00
|
|
|
void ProfileDialog::updateWidgets()
|
|
|
|
{
|
|
|
|
bool enable_del = false;
|
|
|
|
bool enable_ok = true;
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
QModelIndex index = sort_model_->mapToSource(pd_ui_->profileTreeView->currentIndex());
|
|
|
|
if ( index.column() != ProfileModel::COL_NAME )
|
|
|
|
index = index.sibling(index.row(), ProfileModel::COL_NAME);
|
|
|
|
|
|
|
|
if (index.isValid()) {
|
|
|
|
if ( !index.data(ProfileModel::DATA_IS_GLOBAL).toBool() && ! model_->resetDefault())
|
2012-12-29 01:39:02 +00:00
|
|
|
enable_del = true;
|
|
|
|
}
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
if (model_ && model_->rowCount() > 0)
|
|
|
|
{
|
|
|
|
for ( int row = 0; row < model_->rowCount(); row++ )
|
|
|
|
{
|
|
|
|
QModelIndex idx = model_->index(row, ProfileModel::COL_NAME);
|
|
|
|
QString name = idx.data().toString();
|
2012-12-29 01:39:02 +00:00
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
if (gchar * err_msg = profile_name_is_valid(name.toLatin1().data()))
|
|
|
|
{
|
|
|
|
pd_ui_->infoLabel->setText(gchar_free_to_qstring(err_msg));
|
2017-02-07 20:35:16 +00:00
|
|
|
enable_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
2019-07-04 19:55:21 +00:00
|
|
|
|
|
|
|
if ( idx != index && idx.data().toString().compare(index.data().toString()) == 0 )
|
|
|
|
{
|
|
|
|
if (idx.data(ProfileModel::DATA_IS_GLOBAL).toBool() == index.data(ProfileModel::DATA_IS_GLOBAL).toBool())
|
2015-12-06 11:15:53 +00:00
|
|
|
{
|
2019-07-04 19:55:21 +00:00
|
|
|
int status = index.data(ProfileModel::DATA_STATUS).toInt();
|
|
|
|
if (status != PROF_STAT_DEFAULT && status != PROF_STAT_EXISTS)
|
|
|
|
pd_ui_->infoLabel->setText(tr("A profile already exists with this name"));
|
|
|
|
enable_ok = false;
|
2015-12-06 11:15:53 +00:00
|
|
|
}
|
2012-12-29 01:39:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
pd_ui_->profileTreeView->resizeColumnToContents(0);
|
2012-12-29 01:39:02 +00:00
|
|
|
pd_ui_->deleteToolButton->setEnabled(enable_del);
|
|
|
|
ok_button_->setEnabled(enable_ok);
|
|
|
|
}
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
void ProfileDialog::currentItemChanged()
|
2012-12-29 01:39:02 +00:00
|
|
|
{
|
2019-07-04 19:55:21 +00:00
|
|
|
updateWidgets();
|
2012-12-29 01:39:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProfileDialog::on_newToolButton_clicked()
|
|
|
|
{
|
2019-07-04 19:55:21 +00:00
|
|
|
if ( model_->findByName(tr("New profile")) >= 0 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
pd_ui_->cmbProfileTypes->setCurrentIndex(ProfileSortModel::UserProfiles);
|
|
|
|
sort_model_->setFilterString();
|
|
|
|
|
|
|
|
QModelIndex ridx = sort_model_->mapFromSource(model_->addNewProfile(tr("New profile")));
|
|
|
|
if (ridx.isValid())
|
|
|
|
{
|
|
|
|
pd_ui_->profileTreeView->setCurrentIndex(ridx);
|
|
|
|
pd_ui_->profileTreeView->edit(ridx);
|
|
|
|
}
|
2012-12-29 01:39:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProfileDialog::on_deleteToolButton_clicked()
|
|
|
|
{
|
2019-07-04 19:55:21 +00:00
|
|
|
QModelIndex index = sort_model_->mapToSource(pd_ui_->profileTreeView->currentIndex());
|
2012-12-29 01:39:02 +00:00
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
model_->deleteEntry(index);
|
2012-12-29 01:39:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProfileDialog::on_copyToolButton_clicked()
|
|
|
|
{
|
2019-07-04 19:55:21 +00:00
|
|
|
pd_ui_->cmbProfileTypes->setCurrentIndex(ProfileSortModel::AllProfiles);
|
|
|
|
sort_model_->setFilterString();
|
|
|
|
|
|
|
|
QModelIndex current = pd_ui_->profileTreeView->currentIndex();
|
|
|
|
if ( current.column() != ProfileModel::COL_NAME )
|
|
|
|
current = current.sibling(current.row(), ProfileModel::COL_NAME);
|
|
|
|
|
|
|
|
QModelIndex source = sort_model_->mapToSource(current);
|
|
|
|
QModelIndex ridx = model_->duplicateEntry(source);
|
|
|
|
if (ridx.isValid())
|
|
|
|
{
|
|
|
|
pd_ui_->profileTreeView->setCurrentIndex(sort_model_->mapFromSource(ridx));
|
|
|
|
pd_ui_->profileTreeView->edit(sort_model_->mapFromSource(ridx));
|
2012-12-29 01:39:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProfileDialog::on_buttonBox_accepted()
|
|
|
|
{
|
2019-07-04 19:55:21 +00:00
|
|
|
QModelIndex default_item = sort_model_->mapFromSource(model_->index(0, ProfileModel::COL_NAME));
|
|
|
|
QModelIndex index = sort_model_->mapToSource(pd_ui_->profileTreeView->currentIndex());
|
|
|
|
if (index.column() != ProfileModel::COL_NAME)
|
|
|
|
index = index.sibling(index.row(), ProfileModel::COL_NAME);
|
|
|
|
|
2017-02-13 22:00:00 +00:00
|
|
|
bool write_recent = true;
|
|
|
|
bool item_data_removed = false;
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
if (default_item.data(ProfileModel::DATA_STATUS).toInt() == PROF_STAT_DEFAULT && model_->resetDefault())
|
|
|
|
{
|
2017-02-13 22:00:00 +00:00
|
|
|
// Reset Default profile.
|
2019-07-04 19:55:21 +00:00
|
|
|
GList *fl_entry = model_->at(0);
|
2017-02-13 22:00:00 +00:00
|
|
|
remove_from_profile_list(fl_entry);
|
|
|
|
|
|
|
|
// Don't write recent file if leaving the Default profile after this has been reset.
|
|
|
|
write_recent = !is_default_profile();
|
|
|
|
|
|
|
|
// Don't fetch profile data if removed.
|
2019-07-04 19:55:21 +00:00
|
|
|
item_data_removed = (index.row() == 0);
|
2017-02-13 22:00:00 +00:00
|
|
|
}
|
2012-12-29 01:39:02 +00:00
|
|
|
|
2018-01-30 12:17:01 +00:00
|
|
|
if (write_recent) {
|
|
|
|
/* Get the current geometry, before writing it to disk */
|
|
|
|
wsApp->emitAppSignal(WiresharkApplication::ProfileChanging);
|
|
|
|
|
|
|
|
/* Write recent file for current profile now because
|
|
|
|
* the profile may be renamed in apply_profile_changes() */
|
|
|
|
write_profile_recent();
|
|
|
|
}
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
gchar * err_msg = Q_NULLPTR;
|
|
|
|
if ((err_msg = apply_profile_changes()) != Q_NULLPTR) {
|
2012-12-29 01:39:02 +00:00
|
|
|
QMessageBox::critical(this, tr("Profile Error"),
|
|
|
|
err_msg,
|
|
|
|
QMessageBox::Ok);
|
2018-01-18 07:33:03 +00:00
|
|
|
g_free(err_msg);
|
2019-07-04 19:55:21 +00:00
|
|
|
|
|
|
|
model_->doResetModel();
|
2012-12-29 01:39:02 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
model_->doResetModel();
|
|
|
|
|
|
|
|
const char * profile_name = Q_NULLPTR;
|
|
|
|
if (index.isValid() && !item_data_removed) {
|
|
|
|
QString profileName = model_->data(index).toString();
|
|
|
|
profile_name = profileName.toLatin1().data();
|
2017-02-13 22:00:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (profile_exists (profile_name, FALSE) || profile_exists (profile_name, TRUE)) {
|
|
|
|
// The new profile exists, change.
|
2018-01-30 12:17:01 +00:00
|
|
|
wsApp->setConfigurationProfile (profile_name, FALSE);
|
2017-02-13 22:00:00 +00:00
|
|
|
} else if (!profile_exists (get_profile_name(), FALSE)) {
|
|
|
|
// The new profile does not exist, and the previous profile has
|
|
|
|
// been deleted. Change to the default profile.
|
2019-07-04 19:55:21 +00:00
|
|
|
wsApp->setConfigurationProfile (Q_NULLPTR, FALSE);
|
2012-12-29 01:42:01 +00:00
|
|
|
}
|
2012-12-29 01:39:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProfileDialog::on_buttonBox_helpRequested()
|
|
|
|
{
|
|
|
|
wsApp->helpTopicAction(HELP_CONFIG_PROFILES_DIALOG);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProfileDialog::editingFinished()
|
|
|
|
{
|
|
|
|
updateWidgets();
|
|
|
|
}
|
|
|
|
|
2019-07-04 19:55:21 +00:00
|
|
|
void ProfileDialog::filterChanged(const QString &text)
|
|
|
|
{
|
|
|
|
if (qobject_cast<QComboBox *>(sender()))
|
|
|
|
{
|
|
|
|
QComboBox * cmb = qobject_cast<QComboBox *>(sender());
|
|
|
|
sort_model_->setFilterType(static_cast<ProfileSortModel::FilterType>(cmb->currentIndex()));
|
|
|
|
}
|
|
|
|
else if (qobject_cast<QLineEdit *>(sender()))
|
|
|
|
sort_model_->setFilterString(text);
|
|
|
|
|
|
|
|
pd_ui_->profileTreeView->resizeColumnToContents(ProfileModel::COL_NAME);
|
|
|
|
|
|
|
|
QModelIndex active = sort_model_->mapFromSource(model_->activeProfile());
|
|
|
|
if (active.isValid())
|
|
|
|
pd_ui_->profileTreeView->setCurrentIndex(active);
|
|
|
|
}
|
|
|
|
|
2012-12-29 01:39:02 +00:00
|
|
|
/*
|
|
|
|
* 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:
|
|
|
|
*/
|