|
From: <cn...@us...> - 2024-08-21 19:58:47
|
Revision: 1526
http://sourceforge.net/p/seq/svn/1526
Author: cn187
Date: 2024-08-21 19:58:44 +0000 (Wed, 21 Aug 2024)
Log Message:
-----------
Redesign filter add dialog
Modified Paths:
--------------
showeq/trunk/src/filtermgr.cpp
showeq/trunk/src/filtermgr.h
showeq/trunk/src/spawnlistcommon.cpp
Modified: showeq/trunk/src/filtermgr.cpp
===================================================================
--- showeq/trunk/src/filtermgr.cpp 2024-08-21 19:58:37 UTC (rev 1525)
+++ showeq/trunk/src/filtermgr.cpp 2024-08-21 19:58:44 UTC (rev 1526)
@@ -35,6 +35,13 @@
#include <QRegExp>
#include <QString>
#include <QFileInfo>
+#include <QLineEdit>
+#include <QLabel>
+#include <QGridLayout>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
//
// ZBTEMP: predefined filters and filter mask will be migrated out
@@ -42,6 +49,12 @@
// at runtime ala the runtime Filter stuff
//
+#define X(a, b) b,
+const QString FilterStringFieldName[] = {
+ FILTERSTRINGFIELD_TABLE
+};
+#undef X
+
//----------------------------------------------------------------------
// FilterMgr
FilterMgr::FilterMgr(const DataLocationMgr* dataLocMgr,
@@ -332,6 +345,567 @@
emit runtimeFiltersChanged(type);
}
+
+
+FilterFormField::FilterFormField(QString name, QString labeltext, QWidget* parent) :
+ QWidget(parent),
+ m_name(name),
+ m_labeltext(labeltext),
+ m_check(nullptr),
+ m_label(nullptr),
+ m_edit(nullptr)
+{
+ if (m_labeltext.isNull())
+ m_labeltext = m_name;
+
+ m_check = new QCheckBox(this);
+ m_check->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
+
+ m_label = new QLabel(m_labeltext, this);
+ QSizePolicy tmpPolicy = m_label->sizePolicy();
+ tmpPolicy.setVerticalPolicy(QSizePolicy::Fixed);
+ m_label->setSizePolicy(tmpPolicy);
+
+ m_edit = new QLineEdit(this);
+ tmpPolicy = m_edit->sizePolicy();
+ tmpPolicy.setVerticalPolicy(QSizePolicy::Fixed);
+ m_edit->setSizePolicy(tmpPolicy);
+
+ QHBoxLayout* layout = new QHBoxLayout(this);
+ layout->addWidget(m_check);
+ layout->addWidget(m_label);
+ layout->addWidget(m_edit);
+
+ connect(m_check, SIGNAL(toggled(bool)), m_edit, SLOT(setEnabled(bool)));
+}
+
+void FilterFormField::stateChanged(int state)
+{
+ bool old_check_state = m_check->blockSignals(true);
+ bool old_edit_state = m_edit->blockSignals(true);
+ switch (state)
+ {
+ case Qt::Unchecked:
+ m_check->setChecked(false);
+ m_edit->setEnabled(false);
+ break;
+ case Qt::PartiallyChecked:
+ break;
+ case Qt::Checked:
+ m_check->setChecked(true);
+ m_edit->setEnabled(true);
+ break;
+ }
+ m_check->blockSignals(old_check_state);
+ m_edit->blockSignals(old_edit_state);
+}
+
+void ToggleAllCheckBox::nextCheckState()
+{
+ switch(checkState())
+ {
+ case Qt::Unchecked:
+ setCheckState(Qt::Checked);
+ break;
+ case Qt::PartiallyChecked:
+ setCheckState(Qt::Unchecked);
+ break;
+ case Qt::Checked:
+ setCheckState(Qt::Unchecked);
+ break;
+ }
+
+}
+
+FilterDialog::FilterDialog(QWidget* parent, Qt::WindowFlags flags) :
+ QDialog(parent, flags),
+ m_toggleAll(nullptr),
+ m_filterString(QString()),
+ m_fieldCount(0),
+ m_fieldsCheckedCount(0)
+{
+ //init m_spawnFilterMap
+ for (int field = FSF_Name; field < FSF_Max; ++field)
+ {
+ QString name = FilterStringFieldName[field];
+ m_spawnFilterMap[name] = "";
+ }
+ m_spawnFilterMap[FSF_MINLEVEL_NAME] = "";
+ m_spawnFilterMap[FSF_MAXLEVEL_NAME] = "";
+
+ createForm();
+}
+
+FilterDialog::~FilterDialog()
+{ }
+
+void FilterDialog::createForm()
+{
+
+ const int colspc_x = 20;
+ const int colspc_y = 1;
+
+ QVBoxLayout* pageLayout = new QVBoxLayout(this);
+ QGridLayout* gridLayout = new QGridLayout();
+
+ // info/instructions
+ QLabel* tmpLabel = new QLabel("All fields except '" FSF_MINLEVEL_LABEL "' and '" FSF_MAXLEVEL_LABEL "' accept Regular Expression syntax.", this);
+ tmpLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ pageLayout->addWidget(tmpLabel);
+ tmpLabel = new QLabel("For an exact level match or matching multiple levels using a RegEx, use the 'Level' field.", this);
+ tmpLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ pageLayout->addWidget(tmpLabel);
+ tmpLabel = new QLabel("To limit to a simple level range (no RegEx), use the '" FSF_MINLEVEL_LABEL "' and '" FSF_MAXLEVEL_LABEL "' fields.", this);
+ tmpLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ pageLayout->addWidget(tmpLabel);
+ tmpLabel = new QLabel("Any fields left blank or not checked will not be matched against.", this);
+ tmpLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ pageLayout->addWidget(tmpLabel);
+
+ pageLayout->addItem(new QSpacerItem(colspc_x, 25));
+
+ //using an extra widget so the spacing lines up
+ QWidget* toggleAllWidget = new QWidget();
+ QHBoxLayout* toggleAllLayout = new QHBoxLayout(toggleAllWidget);
+ m_toggleAll = new ToggleAllCheckBox();
+ m_toggleAll->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+ m_toggleAll->setTristate(true);
+ toggleAllLayout->addWidget(m_toggleAll);
+ toggleAllLayout->addWidget(new QLabel("Toggle All", this));
+ connect(m_toggleAll, SIGNAL(stateChanged(int)), this, SLOT(toggleAllToggled(int)));
+
+ pageLayout->addLayout(gridLayout);
+ gridLayout->addWidget(toggleAllWidget, 0, 0);
+
+ const QString labels[] = {
+ "Name", "Level", "Race", "Class", "NPC", "X", "Y", "Z", "Light", "Deity",
+ "Race Team", "Deity Team", "Type", "Last Name", "Guild", "Spawn Time", "GM" };
+
+ for (int field = FSF_Name; field < FSF_Max; ++field)
+ {
+ QString name = FilterStringFieldName[field];
+ QString label = labels[field];
+ m_filterFields[name] = new FilterFormField(name, label);
+ m_fieldCount++;
+
+ }
+
+ //not part of normal regex string, but still part of filter
+ m_filterFields[FSF_MINLEVEL_NAME] = new FilterFormField(FSF_MINLEVEL_NAME, FSF_MINLEVEL_LABEL);
+ m_filterFields[FSF_MAXLEVEL_NAME] = new FilterFormField(FSF_MAXLEVEL_NAME, FSF_MAXLEVEL_LABEL);
+ m_fieldCount += 2;
+
+ const QString formFieldOrder[] = { "Name", "LastName", "Guild", "Race", "Class",
+ "Deity", "Level", FSF_MINLEVEL_NAME, FSF_MAXLEVEL_NAME, "X", "Y", "Z", "NPC", "Type",
+ "GM", "RTeam", "DTeam", "Spawn", "Light" };
+
+ int row = 1; //toggle all is row 0
+ int col = 0;
+ for (auto fieldname : formFieldOrder)
+ {
+ gridLayout->addWidget(m_filterFields[fieldname], row, col++);
+
+ connect(m_toggleAll, SIGNAL(stateChanged(int)), m_filterFields[fieldname], SLOT(stateChanged(int)));
+ connect(m_filterFields[fieldname]->m_check, SIGNAL(toggled(bool)), this, SLOT(fieldToggled(bool)));
+
+ if (fieldname == "Guild" || fieldname == "Deity" ||
+ fieldname == FSF_MAXLEVEL_NAME || fieldname == "Z" ||
+ fieldname == "GM" || fieldname == "Spawn")
+ {
+ row++;
+ col = 0;
+ }
+ }
+
+ //buttons
+ QHBoxLayout* buttonLayout = new QHBoxLayout();
+ pageLayout->addItem(new QSpacerItem(colspc_x, 25));
+ pageLayout->addLayout(buttonLayout);
+
+ QPushButton* resetButton = new QPushButton("Reset");
+ resetButton->setDefault(false);
+ resetButton->setAutoDefault(false);
+ buttonLayout->addWidget(resetButton);
+ connect(resetButton, SIGNAL(clicked()), this, SLOT(resetForm()));
+
+ buttonLayout->addItem(new QSpacerItem(colspc_x, colspc_y));
+
+ QPushButton* okButton = new QPushButton("Ok");
+ okButton->setDefault(false);
+ okButton->setAutoDefault(false);
+ buttonLayout->addWidget(okButton);
+ connect(okButton, SIGNAL(clicked()), this, SLOT(acceptDialog()));
+
+ QPushButton* cancelButton = new QPushButton("Cancel");
+ cancelButton->setDefault(false);
+ cancelButton->setAutoDefault(false);
+ buttonLayout->addWidget(cancelButton);
+ connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+void FilterDialog::setData(const QString filterString)
+{
+ m_spawnFilterString = filterString;
+
+ FilterString2FilterFieldMap(filterString, &m_spawnFilterMap);
+
+ resetForm();
+}
+
+void FilterDialog::resetForm()
+{
+ m_fieldsCheckedCount = 0;
+ for (int field = FSF_Name; field < FSF_Max; ++field)
+ {
+ QString name = FilterStringFieldName[field];
+ m_filterFields[name]->m_edit->setText(m_spawnFilterMap[name]);
+
+ if (m_filterFields[name]->m_edit->text().length())
+ {
+ m_filterFields[name]->stateChanged(Qt::Checked);
+ m_fieldsCheckedCount++;
+ }
+ else
+ {
+ m_filterFields[name]->stateChanged(Qt::Unchecked);
+ }
+ }
+ //not part of normal regex string, but still part of filter
+ m_filterFields[FSF_MINLEVEL_NAME]->m_edit->setText(m_spawnFilterMap[FSF_MINLEVEL_NAME]);
+ if (m_filterFields[FSF_MINLEVEL_NAME]->m_edit->text().length())
+ {
+ m_filterFields[FSF_MINLEVEL_NAME]->stateChanged(Qt::Checked);
+ m_fieldsCheckedCount++;
+ }
+ else
+ {
+ m_filterFields[FSF_MINLEVEL_NAME]->stateChanged(Qt::Unchecked);
+ }
+ m_filterFields[FSF_MAXLEVEL_NAME]->m_edit->setText(m_spawnFilterMap[FSF_MAXLEVEL_NAME]);
+ if (m_filterFields[FSF_MAXLEVEL_NAME]->m_edit->text().length())
+ {
+ m_filterFields[FSF_MAXLEVEL_NAME]->stateChanged(Qt::Checked);
+ m_fieldsCheckedCount++;
+ }
+ else
+ {
+ m_filterFields[FSF_MAXLEVEL_NAME]->stateChanged(Qt::Unchecked);
+ }
+
+ bool old_state = m_toggleAll->blockSignals(true);
+ if (m_fieldsCheckedCount == 0)
+ m_toggleAll->setCheckState(Qt::Unchecked);
+ else if (m_fieldsCheckedCount == m_fieldCount)
+ m_toggleAll->setCheckState(Qt::Checked);
+ else
+ m_toggleAll->setCheckState(Qt::PartiallyChecked);
+ m_toggleAll->blockSignals(old_state);
+
+}
+
+void FilterDialog::acceptDialog()
+{
+ FilterFieldMap map;
+
+ //if enabled, add to map
+ for (int field = FSF_Name; field < FSF_Max; ++field)
+ {
+ QString name = FilterStringFieldName[field];
+ if (m_filterFields[name]->m_edit->isEnabled())
+ map[name] = m_filterFields[name]->m_edit->text();
+ }
+ //not part of normal regex string, but still part of filter
+ if (m_filterFields[FSF_MINLEVEL_NAME]->m_edit->isEnabled())
+ map[FSF_MINLEVEL_NAME] = m_filterFields[FSF_MINLEVEL_NAME]->m_edit->text();
+
+ if (m_filterFields[FSF_MAXLEVEL_NAME]->m_edit->isEnabled())
+ map[FSF_MAXLEVEL_NAME] = m_filterFields[FSF_MAXLEVEL_NAME]->m_edit->text();
+
+
+ m_filterString = FilterFieldMap2FilterString(&map);
+
+ done(QDialog::Accepted);
+}
+
+void FilterDialog::fieldToggled(bool checked)
+{
+ if (checked)
+ m_fieldsCheckedCount++;
+ else
+ m_fieldsCheckedCount--;
+
+ bool old_state = m_toggleAll->blockSignals(true);
+ if (m_fieldsCheckedCount == m_fieldCount)
+ m_toggleAll->setCheckState(Qt::Checked);
+ else if (m_fieldsCheckedCount == 0)
+ m_toggleAll->setCheckState(Qt::Unchecked);
+ else
+ m_toggleAll->setCheckState(Qt::PartiallyChecked);
+ m_toggleAll->blockSignals(old_state);
+}
+
+void FilterDialog::toggleAllToggled(int state)
+{
+ if (sender() != m_toggleAll)
+ return;
+
+ switch(state)
+ {
+ case Qt::Checked:
+ m_fieldsCheckedCount = m_fieldCount;
+ break;
+ case Qt::Unchecked:
+ m_fieldsCheckedCount = 0;
+ break;
+ case Qt::PartiallyChecked:
+ m_toggleAll->setCheckState(Qt::Checked);
+ m_fieldsCheckedCount = m_fieldCount;
+ }
+ emit stateChanged(m_toggleAll->checkState());
+}
+
+QString FilterDialog::getFilter(QWidget* parent, const QString& title,
+ const QString& filterString, bool* ok, Qt::WindowFlags flags,
+ Qt::InputMethodHints inputMethodHints)
+{
+ FilterDialog* dlg = new FilterDialog(parent, flags);
+ dlg->setWindowTitle(title);
+ dlg->setData(filterString);
+
+ const int ret = dlg->exec();
+ if (ok)
+ *ok = ret;
+
+ QString result;
+ if (ok)
+ result = dlg->m_filterString;
+
+ dlg->deleteLater();
+ return result;
+}
+
+
+void FilterString2FilterFieldMap(const QString filterString, FilterFieldMap* map)
+{
+ if (!map || !filterString.length())
+ return;
+
+ QString levelSuffix;
+ QString regex;
+ int minLevel = -1;
+ int maxLevel = -1;
+
+ int split = filterString.lastIndexOf(';');
+ if (split == -1)
+ {
+ regex = filterString;
+ }
+ else
+ {
+ regex = filterString.left(split);
+ levelSuffix = filterString.mid(split+1);
+ }
+
+
+ // parse level range string
+ if (levelSuffix.length())
+ {
+ auto range = levelSuffix.split('-');
+ bool ok = false;
+
+ if (range.size() == 1)
+ {
+ //no dash, only a single level specified - treat as exact match
+ int level = range[0].toInt(&ok);
+ if (ok)
+ {
+ minLevel = level;
+ maxLevel = level;
+ }
+ else
+ {
+ seqWarn("Could not parse level: %s", range[0].toLatin1().data());
+ }
+ }
+ else if (range.size() == 2)
+ {
+ //one dash, two fields - treat as range
+ int level = range[0].toInt(&ok);
+ if (ok)
+ minLevel = level;
+ else
+ seqWarn("Could not parse min level: %s", range[0].toLatin1().data());
+
+ ok = false;
+ level = range[1].toInt(&ok);
+ if (ok)
+ maxLevel = level;
+ else
+ seqWarn("Could not parse max level: %s", range[0].toLatin1().data());
+
+
+ // if range wasn't fully/correctly specified, use defaults
+ minLevel = (minLevel > -1) ? minLevel : 0;
+ maxLevel = (maxLevel > -1) ? maxLevel : SHRT_MAX;
+
+ }
+ else
+ {
+ seqWarn("Ignoring malformed level range string.");
+ }
+
+ if (maxLevel < minLevel)
+ {
+ int tmp = maxLevel;
+ maxLevel = minLevel;
+ minLevel = tmp;
+ }
+ }
+
+
+ // parse regex string and set map fields
+
+ //process filter string and set form fields
+ QStringList tokens = regex.split(":");
+
+ //fields should be key:value, but split will create an extra item in the
+ //list after the last :, so for a well-formed filterString, there should
+ //always be an odd number of elements
+ if (tokens.length() % 2 != 1)
+ {
+ seqWarn("Malformed filterString regex: %s", regex.toLatin1().data());
+ return;
+ }
+
+ QStringList::const_iterator itr = tokens.begin();
+ for (;itr < tokens.end(); ++itr)
+ {
+ QString name = *itr;
+ if (!map->contains(name))
+ {
+ if (!name.length() && itr == tokens.end() - 1)
+ {
+ //filter string has an ending : that we can ignore
+ continue;
+ }
+
+ seqWarn("Ignoring unknown filter string field: %s", name.toLatin1().data());
+ ++itr; // skip this field's data
+ continue;
+ }
+ if (++itr == tokens.end())
+ continue;
+ QString value = *itr;
+
+ if (name == "Name" && (value == "Door" || value == "Drop"))
+ {
+ //infuriatingly, we add a colon to door and drop names.
+ //TODO try to find out how many people's filters this will break
+ //if we remove the : from door and drop names (maybe replace it with
+ //a - or something. Or save it for 7.x and do it anyway.
+ //TODO also, check on adding trailing : to Item spawn filterstring
+ //to make it consistent with the Spawn filterstring
+ value += ":";
+ if (++itr == tokens.end())
+ continue;
+ value += *itr;
+ }
+
+ (*map)[name] = value.trimmed();
+ }
+
+ if (minLevel > -1)
+ (*map)[FSF_MINLEVEL_NAME] = QString::number(minLevel);
+
+ if (maxLevel > -1)
+ (*map)[FSF_MAXLEVEL_NAME] = QString::number(maxLevel);
+
+}
+
+QString FilterFieldMap2FilterString(FilterFieldMap* map)
+{
+ if (!map)
+ return QString();
+
+ QString filterString;
+ bool wildcard = false;
+ bool has_first_match = false;
+
+ for (int field = FSF_Name; field < FSF_Max; ++field)
+ {
+ QString name = FilterStringFieldName[field];
+
+ if (!map->contains(name) || !(*map)[name].trimmed().length())
+ {
+ if (has_first_match && !wildcard)
+ {
+ wildcard = true;
+ }
+ continue;
+ }
+
+ QString value = (*map)[name];
+ value = value.trimmed();
+
+ has_first_match = true;
+
+ if (wildcard)
+ {
+ wildcard = false;
+ filterString += ".*:";
+ }
+ filterString += name;
+ filterString += ":";
+ filterString += value;
+ filterString += ":";
+
+ }
+
+ //min/max level are not part of normal regex string, but still part of filter
+ int minLevel = -1;
+ int maxLevel = -1;
+
+ if (map->contains(FSF_MINLEVEL_NAME))
+ {
+ QString value = (*map)[FSF_MINLEVEL_NAME];
+ value = value.trimmed();
+ bool ok = false;
+ int level = value.toInt(&ok);
+ if (ok)
+ minLevel = level;
+ }
+
+ if (map->contains(FSF_MAXLEVEL_NAME))
+ {
+ QString value = (*map)[FSF_MAXLEVEL_NAME];
+ value = value.trimmed();
+ bool ok = false;
+ int level = value.toInt(&ok);
+ if (ok)
+ maxLevel = level;
+ }
+
+ if (minLevel >= 0 || maxLevel >= 0)
+ {
+ minLevel = (minLevel >= 0) ? minLevel : 0;
+ maxLevel = (maxLevel >= 0) ? maxLevel : SHRT_MAX;
+
+ if (maxLevel < minLevel)
+ {
+ int tmp = maxLevel;
+ maxLevel = minLevel;
+ minLevel = tmp;
+ }
+
+ filterString += ";";
+ filterString += QString::number(minLevel);
+ filterString += "-";
+ filterString += QString::number(maxLevel);
+ }
+
+ return filterString;
+}
+
#ifndef QMAKEBUILD
#include "filtermgr.moc"
#endif
Modified: showeq/trunk/src/filtermgr.h
===================================================================
--- showeq/trunk/src/filtermgr.h 2024-08-21 19:58:37 UTC (rev 1525)
+++ showeq/trunk/src/filtermgr.h 2024-08-21 19:58:44 UTC (rev 1526)
@@ -39,6 +39,11 @@
#include <map>
#include <QObject>
+#include <QDialog>
+#include <QString>
+#include <QLabel>
+#include <QLineEdit>
+#include <QCheckBox>
#include "everquest.h"
@@ -74,9 +79,46 @@
#define FILTER_FLAG_DANGER (1 << DANGER_FILTER)
#define FILTER_FLAG_LOCATE (1 << LOCATE_FILTER)
#define FILTER_FLAG_ALERT (1 << ALERT_FILTER)
-#define FILTER_FLAG_FILTERED (1 << FILTERED_FILTER)
+#define FILTER_FLAG_FILTERED (1 << FILTERED_FILTER)
#define FILTER_FLAG_TRACER (1 << TRACER_FILTER)
+
+#define FILTERSTRINGFIELD_TABLE \
+ X(FSF_Name, "Name") \
+ X(FSF_Level, "Level") \
+ X(FSF_Race, "Race") \
+ X(FSF_Class, "Class") \
+ X(FSF_NPC, "NPC") \
+ X(FSF_X, "X") \
+ X(FSF_Y, "Y") \
+ X(FSF_Z, "Z") \
+ X(FSF_Light, "Light") \
+ X(FSF_Deity, "Deity") \
+ X(FSF_RTeam, "RTeam") \
+ X(FSF_DTeam, "DTeam") \
+ X(FSF_Type, "Type") \
+ X(FSF_LastName, "LastName") \
+ X(FSF_Guild, "Guild") \
+ X(FSF_Spawn, "Spawn") \
+ X(FSF_GM, "GM")
+
+#define X(a, b) a,
+enum FilterStringField
+{
+ FILTERSTRINGFIELD_TABLE
+ FSF_Max
+};
+#undef X
+
+
+// special handling for min/max level, which aren't part of regex filter string
+#define FSF_MINLEVEL_NAME "MinLevel"
+#define FSF_MINLEVEL_LABEL "Min Level"
+#define FSF_MAXLEVEL_NAME "MaxLevel"
+#define FSF_MAXLEVEL_LABEL "Max Level"
+
+typedef QHash<QString, QString> FilterFieldMap;
+
//----------------------------------------------------------------------
// FilterMgr
class FilterMgr : public QObject
@@ -87,7 +129,7 @@
FilterMgr(const DataLocationMgr* dataLocMgr,
const QString filterFile, bool spawnfilter_case);
~FilterMgr();
-
+
const QString& filterFile(void) { return m_filterFile; }
const QString& zoneFilterFile(void) { return m_zoneFilterFile; }
bool caseSensitive(void) { return m_caseSensitive; }
@@ -140,4 +182,76 @@
bool m_caseSensitive;
};
+
+class FilterFormField : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ FilterFormField(QString name, QString labeltext = QString(), QWidget* parent=nullptr);
+
+ QString m_name;
+ QString m_labeltext;
+ QCheckBox* m_check;
+ QLabel* m_label;
+ QLineEdit* m_edit;
+
+ public slots:
+ void stateChanged(int state);
+};
+
+//SubClassing QCheckBox so we can control the sequence of check/uncheck/partial when
+//clicking "Toggle All"
+class ToggleAllCheckBox : public QCheckBox
+{
+ protected:
+ virtual void nextCheckState() override;
+
+};
+
+
+class FilterDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+
+ static QString getFilter(QWidget* parent, const QString& title,
+ const QString& filterString, bool* ok=nullptr,
+ Qt::WindowFlags flags = Qt::WindowFlags(),
+ Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
+
+ protected:
+ FilterDialog(QWidget* parent=nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
+ ~FilterDialog();
+
+ void setData(const QString filterString);
+ void createForm();
+
+ QHash<QString, FilterFormField*> m_filterFields;
+ ToggleAllCheckBox* m_toggleAll;
+
+ QString m_spawnFilterString;
+ FilterFieldMap m_spawnFilterMap;
+
+ QString m_filterString;
+ int m_fieldCount;
+ int m_fieldsCheckedCount;
+ bool m_hasTrailingColon;
+
+ signals:
+ void stateChanged(int state);
+
+ protected slots:
+ void resetForm();
+ void acceptDialog();
+ void fieldToggled(bool checked);
+ void toggleAllToggled(int state);
+
+};
+
+// helper functions
+void FilterString2FilterFieldMap(const QString filterString, FilterFieldMap* map);
+QString FilterFieldMap2FilterString(FilterFieldMap* map);
+
#endif // FILTERMGR_H
Modified: showeq/trunk/src/spawnlistcommon.cpp
===================================================================
--- showeq/trunk/src/spawnlistcommon.cpp 2024-08-21 19:58:37 UTC (rev 1525)
+++ showeq/trunk/src/spawnlistcommon.cpp 2024-08-21 19:58:44 UTC (rev 1526)
@@ -655,12 +655,9 @@
// get the user edited filter string, based on the items filterString
bool ok = false;
filterString =
- QInputDialog::getText(m_spawnlist, filterName + " Filter",
- "Enter the filter string:",
- QLineEdit::Normal,
+ FilterDialog::getFilter(m_spawnlist, filterName + " Filter",
filterString, &ok);
-
// if the user clicked ok, add the filter
if (ok)
m_filterMgr->addFilter(filter, filterString);
@@ -678,12 +675,9 @@
// get the user edited filter string, based on the items filterString
bool ok = false;
filterString =
- QInputDialog::getText(m_spawnlist, filterName + " Filter",
- "Enter the filter string:",
- QLineEdit::Normal,
+ FilterDialog::getFilter(m_spawnlist, filterName + " Zone Filter",
filterString, &ok);
-
// if the user clicked ok, add the filter
if (ok)
m_filterMgr->addZoneFilter(filter, filterString);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|