2019-10-18 22:19:05 +00:00
|
|
|
/* column_list_models.cpp
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ui/qt/models/column_list_model.h>
|
|
|
|
#include <ui/qt/utils/qt_ui_utils.h>
|
|
|
|
#include <ui/qt/widgets/field_filter_edit.h>
|
|
|
|
#include <ui/qt/widgets/syntax_line_edit.h>
|
2019-11-03 12:03:12 +00:00
|
|
|
#include <ui/qt/utils/wireshark_mime_data.h>
|
2019-10-18 22:19:05 +00:00
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
#include <epan/column-info.h>
|
|
|
|
#include <epan/column.h>
|
|
|
|
#include <epan/prefs.h>
|
|
|
|
#include <epan/proto.h>
|
|
|
|
#include <ui/preference_utils.h>
|
|
|
|
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QStringList>
|
|
|
|
#include <QComboBox>
|
|
|
|
|
|
|
|
struct ListElement
|
|
|
|
{
|
|
|
|
QString title;
|
|
|
|
QString customFields;
|
|
|
|
int nr;
|
|
|
|
int type;
|
|
|
|
int originalType;
|
|
|
|
int occurrence;
|
|
|
|
bool displayed;
|
|
|
|
bool changed;
|
|
|
|
};
|
|
|
|
|
|
|
|
static QList<ListElement> store_;
|
|
|
|
|
2019-10-20 22:19:58 +00:00
|
|
|
ColumnProxyModel::ColumnProxyModel(QObject * parent) :
|
|
|
|
QSortFilterProxyModel(parent),
|
|
|
|
showDisplayedOnly_(false)
|
|
|
|
{}
|
|
|
|
|
|
|
|
bool ColumnProxyModel::filterAcceptsRow(int source_row, const QModelIndex &/*source_parent*/) const
|
|
|
|
{
|
|
|
|
bool displayed = false;
|
2019-11-17 19:02:20 +00:00
|
|
|
if (sourceModel() &&
|
|
|
|
sourceModel()->index(source_row, ColumnListModel::COL_DISPLAYED).data(ColumnListModel::DisplayedState).toBool())
|
2019-10-20 22:19:58 +00:00
|
|
|
displayed = true;
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (showDisplayedOnly_ && ! displayed)
|
2019-10-20 22:19:58 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnProxyModel::setShowDisplayedOnly(bool set)
|
|
|
|
{
|
|
|
|
showDisplayedOnly_ = set;
|
|
|
|
invalidateFilter();
|
|
|
|
}
|
|
|
|
|
2019-10-18 22:19:05 +00:00
|
|
|
ColumnTypeDelegate::ColumnTypeDelegate(QObject * parent) :
|
|
|
|
QStyledItemDelegate(parent)
|
|
|
|
{}
|
|
|
|
|
|
|
|
QWidget *ColumnTypeDelegate::createEditor(QWidget *parent,
|
|
|
|
const QStyleOptionViewItem &option,
|
|
|
|
const QModelIndex &index) const
|
|
|
|
{
|
2020-03-02 20:40:50 +00:00
|
|
|
QWidget *editor = nullptr;
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.column() == ColumnListModel::COL_TYPE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2020-03-02 20:40:50 +00:00
|
|
|
QComboBox *cb_editor = new QComboBox(parent);
|
2019-10-18 22:19:05 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < NUM_COL_FMTS; i++)
|
|
|
|
{
|
2020-03-02 20:40:50 +00:00
|
|
|
cb_editor->addItem(col_format_desc(i), QVariant(i));
|
2019-11-17 19:02:20 +00:00
|
|
|
if (i == index.data().toInt())
|
2020-03-02 20:40:50 +00:00
|
|
|
cb_editor->setCurrentIndex(i);
|
2019-10-18 22:19:05 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 20:40:50 +00:00
|
|
|
cb_editor->setFrame(false);
|
|
|
|
editor = cb_editor;
|
2019-10-18 22:19:05 +00:00
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_FIELDS)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2020-03-02 20:40:50 +00:00
|
|
|
FieldFilterEdit * ff_editor = new FieldFilterEdit(parent);
|
|
|
|
ff_editor->setText(index.data().toString());
|
|
|
|
editor = ff_editor;
|
2019-10-18 22:19:05 +00:00
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_OCCURRENCE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2020-03-02 20:40:50 +00:00
|
|
|
SyntaxLineEdit * sl_editor = new SyntaxLineEdit(parent);
|
|
|
|
connect(sl_editor, &SyntaxLineEdit::textChanged, sl_editor, &SyntaxLineEdit::checkInteger);
|
|
|
|
sl_editor->setText(index.data().toString());
|
|
|
|
editor = sl_editor;
|
2019-10-18 22:19:05 +00:00
|
|
|
}
|
|
|
|
|
2020-03-02 20:40:50 +00:00
|
|
|
if (!editor) {
|
|
|
|
editor = QStyledItemDelegate::createEditor(parent, option, index);
|
|
|
|
}
|
|
|
|
editor->setAutoFillBackground(true);
|
|
|
|
return editor;
|
2019-10-18 22:19:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnTypeDelegate::setEditorData(QWidget *editor,
|
|
|
|
const QModelIndex &index) const
|
|
|
|
{
|
|
|
|
QVariant data = index.model()->data(index);
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.column() == ColumnListModel::COL_TYPE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
QComboBox *comboBox = static_cast<QComboBox*>(editor);
|
|
|
|
comboBox->setCurrentText(data.toString());
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_FIELDS)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (qobject_cast<FieldFilterEdit *>(editor))
|
2019-10-18 22:19:05 +00:00
|
|
|
qobject_cast<FieldFilterEdit *>(editor)->setText(data.toString());
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_OCCURRENCE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (qobject_cast<SyntaxLineEdit *>(editor))
|
2019-10-18 22:19:05 +00:00
|
|
|
qobject_cast<SyntaxLineEdit *>(editor)->setText(data.toString());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (qobject_cast<QLineEdit *>(editor))
|
2019-10-18 22:19:05 +00:00
|
|
|
qobject_cast<QLineEdit *>(editor)->setText(data.toString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
|
|
|
const QModelIndex &index) const
|
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.column() == ColumnListModel::COL_TYPE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
QComboBox *comboBox = static_cast<QComboBox*>(editor);
|
|
|
|
bool ok = false;
|
|
|
|
int value = comboBox->currentData().toInt(&ok);
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (ok)
|
2019-10-18 22:19:05 +00:00
|
|
|
model->setData(index, value, Qt::EditRole);
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_FIELDS)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
FieldFilterEdit * ffe = qobject_cast<FieldFilterEdit *>(editor);
|
2019-12-11 01:03:34 +00:00
|
|
|
if (ffe)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2019-12-11 01:03:34 +00:00
|
|
|
if (ffe->checkFilter())
|
|
|
|
{
|
|
|
|
QModelIndex typeIndex = index.sibling(index.row(), ColumnListModel::COL_TYPE);
|
|
|
|
model->setData(typeIndex, COL_CUSTOM, Qt::EditRole);
|
|
|
|
model->setData(index, ffe->text(), Qt::EditRole);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ffe->setText(index.data().toString());
|
|
|
|
}
|
2019-10-18 22:19:05 +00:00
|
|
|
}
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.data().toString().length() == 0)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
QModelIndex typeIndex = index.sibling(index.row(), ColumnListModel::COL_TYPE);
|
|
|
|
model->setData(typeIndex, index.data(ColumnListModel::OriginalType).toInt(), Qt::EditRole);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_OCCURRENCE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
SyntaxLineEdit * sle = qobject_cast<SyntaxLineEdit *>(editor);
|
|
|
|
bool ok = false;
|
2019-11-17 19:02:20 +00:00
|
|
|
if (sle)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
sle->checkInteger(index.data().toString());
|
2019-11-17 19:02:20 +00:00
|
|
|
if (sle->syntaxState() == SyntaxLineEdit::Valid)
|
2019-10-18 22:19:05 +00:00
|
|
|
ok = true;
|
|
|
|
}
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (ok)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
QModelIndex typeIndex = index.sibling(index.row(), ColumnListModel::COL_TYPE);
|
|
|
|
model->setData(typeIndex, COL_CUSTOM, Qt::EditRole);
|
|
|
|
model->setData(index, sle->text(), Qt::EditRole);
|
|
|
|
}
|
2019-12-11 01:03:34 +00:00
|
|
|
else if (sle)
|
|
|
|
{
|
2019-10-18 22:19:05 +00:00
|
|
|
sle->setText(index.data().toString());
|
2019-12-11 01:03:34 +00:00
|
|
|
}
|
2019-10-18 22:19:05 +00:00
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.data().toString().length() == 0)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
QModelIndex typeIndex = index.sibling(index.row(), ColumnListModel::COL_TYPE);
|
|
|
|
model->setData(typeIndex, index.data(ColumnListModel::OriginalType).toInt(), Qt::EditRole);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
QStyledItemDelegate::setModelData(editor, model, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnTypeDelegate::updateEditorGeometry(QWidget *editor,
|
|
|
|
const QStyleOptionViewItem &option,
|
|
|
|
const QModelIndex &/* index */) const
|
|
|
|
{
|
|
|
|
editor->setGeometry(option.rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
ColumnListModel::ColumnListModel(QObject * parent):
|
|
|
|
QAbstractTableModel(parent)
|
|
|
|
{
|
|
|
|
populate();
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant ColumnListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (section > ColumnListModel::COL_OCCURRENCE || orientation != Qt::Horizontal ||
|
|
|
|
role != Qt::DisplayRole)
|
2019-10-18 22:19:05 +00:00
|
|
|
return QVariant();
|
|
|
|
|
|
|
|
return headerTitle(section);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ColumnListModel::rowCount(const QModelIndex &/*parent*/) const
|
|
|
|
{
|
|
|
|
return store_.count();
|
|
|
|
}
|
|
|
|
|
|
|
|
int ColumnListModel::columnCount(const QModelIndex &/*parent*/) const
|
|
|
|
{
|
|
|
|
return ColumnListModel::COL_OCCURRENCE + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ColumnListModel::headerTitle(int section) const
|
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
switch (section)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
case ColumnListModel::COL_DISPLAYED:
|
|
|
|
return tr("Displayed");
|
|
|
|
case ColumnListModel::COL_TITLE:
|
|
|
|
return tr("Title");
|
|
|
|
case ColumnListModel::COL_TYPE:
|
|
|
|
return tr("Type");
|
|
|
|
case ColumnListModel::COL_FIELDS:
|
|
|
|
return tr("Fields");
|
|
|
|
case ColumnListModel::COL_OCCURRENCE:
|
|
|
|
return tr("Field Occurence");
|
|
|
|
}
|
|
|
|
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnListModel::populate()
|
|
|
|
{
|
|
|
|
store_.clear();
|
|
|
|
|
|
|
|
int nr = 0;
|
|
|
|
|
|
|
|
for (GList *cur = g_list_first(prefs.col_list); cur != NULL && cur->data != NULL; cur = cur->next) {
|
|
|
|
fmt_data *cfmt = (fmt_data *) cur->data;
|
|
|
|
ListElement ne;
|
|
|
|
ne.nr = nr;
|
|
|
|
ne.displayed = cfmt->visible;
|
|
|
|
ne.title = cfmt->title;
|
|
|
|
ne.type = ne.originalType = cfmt->fmt;
|
|
|
|
ne.customFields = cfmt->custom_fields;
|
|
|
|
ne.occurrence = cfmt->custom_occurrence;
|
|
|
|
|
|
|
|
nr++;
|
|
|
|
store_ << ne;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant ColumnListModel::data(const QModelIndex &index, int role) const
|
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (! index.isValid() || index.column() >= store_.count())
|
2019-10-18 22:19:05 +00:00
|
|
|
return QVariant();
|
|
|
|
|
|
|
|
ListElement ne = store_.at(index.row());
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (role == Qt::DisplayRole)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
switch (index.column())
|
|
|
|
{
|
|
|
|
case COL_DISPLAYED:
|
|
|
|
return QVariant();
|
|
|
|
case ColumnListModel::COL_TITLE:
|
|
|
|
return ne.title;
|
|
|
|
case ColumnListModel::COL_TYPE:
|
|
|
|
return col_format_desc(ne.type);
|
|
|
|
case ColumnListModel::COL_FIELDS:
|
|
|
|
return ne.customFields;
|
|
|
|
case ColumnListModel::COL_OCCURRENCE:
|
2019-12-20 05:57:04 +00:00
|
|
|
return ne.customFields.length() > 0 ? QVariant::fromValue(ne.occurrence) : QVariant();
|
2019-10-18 22:19:05 +00:00
|
|
|
}
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (role == Qt::CheckStateRole)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.column() == COL_DISPLAYED)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
return ne.displayed ? Qt::Checked : Qt::Unchecked;
|
|
|
|
}
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (role == OriginalType)
|
2019-12-20 05:57:04 +00:00
|
|
|
return QVariant::fromValue(ne.originalType);
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (role == DisplayedState)
|
2019-12-20 05:57:04 +00:00
|
|
|
return QVariant::fromValue(ne.displayed);
|
2019-10-18 22:19:05 +00:00
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt::ItemFlags ColumnListModel::flags(const QModelIndex &index) const
|
|
|
|
{
|
|
|
|
Qt::ItemFlags defaultFlags = QAbstractTableModel::flags(index);
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.isValid() && index.row() < store_.count())
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
ListElement ne = store_.at(index.row());
|
|
|
|
|
|
|
|
Qt::ItemFlags flags = Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (index.column() == COL_DISPLAYED)
|
2019-10-18 22:19:05 +00:00
|
|
|
flags |= Qt::ItemIsUserCheckable;
|
|
|
|
|
|
|
|
flags |= Qt::ItemIsEditable;
|
|
|
|
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return Qt::ItemIsDropEnabled | defaultFlags;
|
|
|
|
}
|
|
|
|
|
2019-11-03 12:03:12 +00:00
|
|
|
QStringList ColumnListModel::mimeTypes() const
|
|
|
|
{
|
|
|
|
return QStringList() << WiresharkMimeData::ColumnListMimeType;
|
|
|
|
}
|
|
|
|
|
2019-10-18 22:19:05 +00:00
|
|
|
QMimeData *ColumnListModel::mimeData(const QModelIndexList &indexes) const
|
|
|
|
{
|
|
|
|
QMimeData *mimeData = new QMimeData;
|
|
|
|
|
|
|
|
int row = -1;
|
2019-11-17 19:02:20 +00:00
|
|
|
if (indexes.count() > 0)
|
2019-10-18 22:19:05 +00:00
|
|
|
row = indexes.at(0).row();
|
|
|
|
|
2019-11-03 12:03:12 +00:00
|
|
|
mimeData->setData(WiresharkMimeData::ColumnListMimeType, QString::number(row).toUtf8());
|
2019-10-18 22:19:05 +00:00
|
|
|
return mimeData;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ColumnListModel::canDropMimeData(const QMimeData *data,
|
|
|
|
Qt::DropAction /* action */, int /* row */, int /* column */, const QModelIndex &parent) const
|
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (parent.isValid() || ! data->hasFormat(WiresharkMimeData::ColumnListMimeType))
|
2019-10-18 22:19:05 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ColumnListModel::dropMimeData(const QMimeData *data,
|
|
|
|
Qt::DropAction action, int row, int column, const QModelIndex &parent)
|
|
|
|
{
|
|
|
|
int moveTo;
|
|
|
|
|
|
|
|
if (!canDropMimeData(data, action, row, column, parent))
|
|
|
|
return false;
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (action == Qt::IgnoreAction || parent.isValid())
|
2019-10-18 22:19:05 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
if (row != -1)
|
|
|
|
moveTo = row;
|
|
|
|
else
|
|
|
|
moveTo = rowCount(QModelIndex());
|
|
|
|
|
|
|
|
bool ok = false;
|
2019-11-03 12:03:12 +00:00
|
|
|
int moveFrom = QString(data->data(WiresharkMimeData::ColumnListMimeType)).toInt(&ok);
|
2019-11-17 19:02:20 +00:00
|
|
|
if (! ok)
|
2019-10-18 22:19:05 +00:00
|
|
|
return false;
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (moveFrom < moveTo)
|
2019-10-18 22:19:05 +00:00
|
|
|
moveTo = moveTo - 1;
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (moveTo >= store_.count())
|
2019-10-18 22:19:05 +00:00
|
|
|
moveTo = store_.count() - 1;
|
|
|
|
|
|
|
|
emit beginResetModel();
|
|
|
|
store_.move(moveFrom, moveTo);
|
|
|
|
emit endResetModel();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt::DropActions ColumnListModel::supportedDropActions() const
|
|
|
|
{
|
|
|
|
return Qt::MoveAction;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ColumnListModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
|
|
{
|
2019-11-17 19:02:20 +00:00
|
|
|
if (!index.isValid() || ! value.isValid())
|
2019-10-18 22:19:05 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
bool change = false;
|
2019-11-17 19:02:20 +00:00
|
|
|
if (role == Qt::CheckStateRole && index.column() == ColumnListModel::COL_DISPLAYED)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
store_[index.row()].displayed = value.toInt() == Qt::Checked ? true : false;
|
|
|
|
change = true;
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_TYPE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
int val = value.toInt(&ok);
|
2019-11-17 19:02:20 +00:00
|
|
|
if (ok)
|
2019-10-18 22:19:05 +00:00
|
|
|
store_[index.row()].type = val;
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_TITLE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
store_[index.row()].title = value.toString();
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_FIELDS)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
store_[index.row()].customFields = value.toString();
|
|
|
|
}
|
2019-11-17 19:02:20 +00:00
|
|
|
else if (index.column() == ColumnListModel::COL_OCCURRENCE)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
int val = value.toInt(&ok);
|
2019-11-17 19:02:20 +00:00
|
|
|
if (ok)
|
2019-10-18 22:19:05 +00:00
|
|
|
store_[index.row()].occurrence = val;
|
|
|
|
}
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
if (change)
|
2019-10-18 22:19:05 +00:00
|
|
|
emit dataChanged(index, index);
|
|
|
|
|
|
|
|
return change;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnListModel::saveColumns()
|
|
|
|
{
|
|
|
|
GList *new_col_list = Q_NULLPTR;
|
|
|
|
|
2019-11-17 19:02:20 +00:00
|
|
|
for (int row = 0; row < store_.count(); row++)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
2019-11-05 11:42:13 +00:00
|
|
|
fmt_data * cfmt = g_new0(fmt_data, 1);
|
2019-10-18 22:19:05 +00:00
|
|
|
ListElement elem = store_.at(row);
|
|
|
|
|
|
|
|
cfmt->title = qstring_strdup(elem.title);
|
|
|
|
cfmt->visible = elem.displayed;
|
|
|
|
cfmt->fmt = elem.type;
|
|
|
|
cfmt->resolved = TRUE;
|
2019-11-17 19:02:20 +00:00
|
|
|
if (cfmt->fmt == COL_CUSTOM)
|
2019-10-18 22:19:05 +00:00
|
|
|
{
|
|
|
|
cfmt->custom_fields = qstring_strdup(elem.customFields);
|
|
|
|
cfmt->custom_occurrence = elem.occurrence;
|
|
|
|
}
|
|
|
|
|
|
|
|
new_col_list = g_list_append(new_col_list, cfmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (prefs.col_list)
|
|
|
|
column_prefs_remove_link(prefs.col_list);
|
|
|
|
|
|
|
|
prefs.col_list = new_col_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnListModel::addEntry()
|
|
|
|
{
|
|
|
|
emit beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
|
|
|
ListElement elem;
|
|
|
|
elem.nr = rowCount();
|
|
|
|
elem.title = tr("New Column");
|
|
|
|
elem.displayed = true;
|
|
|
|
elem.type = elem.originalType = COL_NUMBER;
|
|
|
|
elem.occurrence = 0;
|
|
|
|
elem.customFields = QString();
|
|
|
|
store_ << elem;
|
|
|
|
emit endInsertRows();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColumnListModel::deleteEntry(int row)
|
|
|
|
{
|
|
|
|
emit beginRemoveRows(QModelIndex(), row, row);
|
|
|
|
store_.removeAt(row);
|
|
|
|
emit endRemoveRows();
|
|
|
|
}
|
|
|
|
|
2019-10-21 16:57:56 +00:00
|
|
|
void ColumnListModel::reset()
|
|
|
|
{
|
|
|
|
emit beginResetModel();
|
|
|
|
populate();
|
|
|
|
emit endResetModel();
|
|
|
|
}
|
|
|
|
|
2019-10-18 22:19:05 +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:
|
|
|
|
*/
|