From 5d8a66884aa150edcd9e8b80c6b218ffeac391c5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Sun, 6 Oct 2019 12:03:51 +0200 Subject: [PATCH] confgui: using the shared code had slightly broken the local parameters management. Fix it --- src/qtgui/confgui/confgui.cpp | 200 ++++++++++++++++++++--------- src/qtgui/confgui/confgui.h | 117 ++++++++++++----- src/qtgui/confgui/confguiindex.cpp | 15 ++- 3 files changed, 234 insertions(+), 98 deletions(-) diff --git a/src/qtgui/confgui/confgui.cpp b/src/qtgui/confgui/confgui.cpp index 7b118a91..8a2082b4 100644 --- a/src/qtgui/confgui/confgui.cpp +++ b/src/qtgui/confgui/confgui.cpp @@ -92,7 +92,6 @@ void ConfTabsW::hideButtons() void ConfTabsW::acceptChanges() { - cerr << "ConfTabsW::acceptChanges()\n"; for (auto& entry : m_panels) { entry->storeValues(); } @@ -106,7 +105,6 @@ void ConfTabsW::acceptChanges() void ConfTabsW::rejectChanges() { - cerr << "ConfTabsW::rejectChanges()\n"; reloadPanels(); if (!buttonBox->isHidden()) close(); @@ -147,6 +145,30 @@ void ConfTabsW::setCurrentIndex(int idx) } } +QWidget *ConfTabsW::addBlurb(int tabindex, const QString& txt) +{ + ConfPanelW *panel = (ConfPanelW*)tabWidget->widget(tabindex); + if (panel == 0) { + return 0; + } + + QFrame *line = new QFrame(panel); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + panel->addWidget(line); + + QLabel *explain = new QLabel(panel); + explain->setWordWrap(true); + explain->setText(txt); + panel->addWidget(explain); + + line = new QFrame(panel); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + panel->addWidget(line); + return explain; +} + ConfParamW *ConfTabsW::addParam( int tabindex, ParamType tp, const QString& varname, const QString& label, const QString& tooltip, @@ -190,36 +212,29 @@ ConfParamW *ConfTabsW::addParam( cp = new ConfParamCSLW(varname, this, lnk, label, tooltip, *sl); break; } - panel->addWidget(cp); - m_params.push_back(cp); + panel->addParam(cp); return cp; } ConfParamW *ConfTabsW::findParamW(const QString& varname) { - for (const auto& param : m_params) { - if (!varname.compare(param->getVarName())) { - return param; - } + for (const auto& panel : m_panels) { + ConfParamW *w = panel->findParamW(varname); + if (w) + return w; } - return 0; + return nullptr; } void ConfTabsW::endOfList(int tabindex) { ConfPanelW *panel = (ConfPanelW*)tabWidget->widget(tabindex); - if (panel == 0) + if (nullptr == panel) return; panel->endOfList(); } bool ConfTabsW::enableLink(ConfParamW* boolw, ConfParamW* otherw, bool revert) { - if (std::find(m_params.begin(), m_params.end(), boolw) == m_params.end() || - std::find(m_params.begin(), m_params.end(), otherw) == - m_params.end()) { - cerr << "ConfTabsW::enableLink: param not found\n"; - return false; - } ConfParamBoolW *bw = dynamic_cast(boolw); if (bw == 0) { cerr << "ConfTabsW::enableLink: not a boolw\n"; @@ -245,10 +260,25 @@ ConfPanelW::ConfPanelW(QWidget *parent) m_vboxlayout->setContentsMargins(margin); } +void ConfPanelW::addParam(ConfParamW *w) +{ + m_vboxlayout->addWidget(w); + m_params.push_back(w); +} + void ConfPanelW::addWidget(QWidget *w) { m_vboxlayout->addWidget(w); - m_widgets.push_back(w); +} + +ConfParamW *ConfPanelW::findParamW(const QString& varname) +{ + for (const auto& param : m_params) { + if (!varname.compare(param->getVarName())) { + return param; + } + } + return nullptr; } void ConfPanelW::endOfList() @@ -258,15 +288,15 @@ void ConfPanelW::endOfList() void ConfPanelW::storeValues() { - for (auto& widgetp : m_widgets) { - ((ConfParamW*)widgetp)->storeValue(); + for (auto& widgetp : m_params) { + widgetp->storeValue(); } } void ConfPanelW::loadValues() { - for (auto& widgetp : m_widgets) { - ((ConfParamW*)widgetp)->loadValue(); + for (auto& widgetp : m_params) { + widgetp->loadValue(); } } @@ -397,6 +427,12 @@ void ConfParamIntW::loadValue() } } +void ConfParamIntW::setImmediate() +{ + connect(m_sb, SIGNAL(valueChanged(int)), + this, SLOT(setValue(int))); +} + ConfParamStrW::ConfParamStrW( const QString& varnm, QWidget *parent, ConfLink cflink, const QString& lbltxt, const QString& tltptxt) @@ -432,6 +468,12 @@ void ConfParamStrW::loadValue() } } +void ConfParamStrW::setImmediate() +{ + connect(m_le, SIGNAL(textChanged(const QString&)), + this, SLOT(setValue(const QString&))); +} + ConfParamCStrW::ConfParamCStrW( const QString& varnm, QWidget *parent, ConfLink cflink, const QString& lbltxt, const QString& tltptxt, const QStringList& sl) @@ -485,6 +527,12 @@ void ConfParamCStrW::loadValue() m_origvalue = cs; } +void ConfParamCStrW::setImmediate() +{ + connect(m_cmb, SIGNAL(activated(const QString&)), + this, SLOT(setValue(const QString&))); +} + ConfParamBoolW::ConfParamBoolW( const QString& varnm, QWidget *parent, ConfLink cflink, const QString& lbltxt, const QString& tltptxt, bool deflt) @@ -525,6 +573,12 @@ void ConfParamBoolW::loadValue() m_cb->setChecked(m_origvalue); } + +void ConfParamBoolW::setImmediate() +{ + connect(m_cb, SIGNAL(toggled(bool)), this, SLOT(setValue(bool))); +} + ConfParamFNW::ConfParamFNW( const QString& varnm, QWidget *parent, ConfLink cflink, const QString& lbltxt, const QString& tltptxt, bool isdir) @@ -576,6 +630,12 @@ void ConfParamFNW::showBrowserDialog() } } +void ConfParamFNW::setImmediate() +{ + connect(m_le, SIGNAL(textChanged(const QString&)), + this, SLOT(setValue(const QString&))); +} + class SmallerListWidget: public QListWidget { public: SmallerListWidget(QWidget *parent) @@ -644,6 +704,9 @@ ConfParamSLW::ConfParamSLW( m_lb = new SmallerListWidget(this); m_lb->setSelectionMode(QAbstractItemView::ExtendedSelection); + connect(m_lb, SIGNAL(currentTextChanged(const QString&)), + this, SIGNAL(currentTextChanged(const QString&))); + setSzPol(m_lb, QSizePolicy::Preferred, QSizePolicy::Preferred, 1, 1); m_hl->addWidget(m_lb); @@ -660,7 +723,7 @@ void ConfParamSLW::setEditable(bool onoff) } } -void ConfParamSLW::storeValue() +string ConfParamSLW::listToString() { vector ls; for (int i = 0; i < m_lb->count(); i++) { @@ -676,6 +739,12 @@ void ConfParamSLW::storeValue() } string s; stringsToString(ls, s); + return s; +} + +void ConfParamSLW::storeValue() +{ + string s = listToString(); if (s.compare(m_origvalue)) { m_cflink->set(s); } @@ -702,20 +771,34 @@ void ConfParamSLW::loadValue() void ConfParamSLW::showInputDialog() { bool ok; - QString s = QInputDialog::getText(this, - "", // title - "", // label, - QLineEdit::Normal, // EchoMode mode - "", // const QString & text - &ok); + QString s = QInputDialog::getText(this, "", "", QLineEdit::Normal, "", &ok); + if (!ok || s.isEmpty()) { + return; + } - if (ok && !s.isEmpty()) { - QListitems = - m_lb->findItems(s, Qt::MatchFixedString | Qt::MatchCaseSensitive); - if (items.empty()) { - m_lb->insertItem(0, s); - m_lb->sortItems(); - } + performInsert(s); +} + +void ConfParamSLW::performInsert(const QString& s) +{ + QList existing = + m_lb->findItems(s, Qt::MatchFixedString | Qt::MatchCaseSensitive); + if (!existing.empty()) { + m_lb->setCurrentItem(existing[0]); + return; + } + m_lb->insertItem(0, s); + m_lb->sortItems(); + existing = m_lb->findItems(s, Qt::MatchFixedString | Qt::MatchCaseSensitive); + if (existing.empty()) { + cerr << "Item not found after insertion!" << endl; + return; + } + m_lb->setCurrentItem(existing[0], QItemSelectionModel::ClearAndSelect); + + if (m_immediate) { + string nv = listToString(); + m_cflink->set(nv); } } @@ -743,6 +826,13 @@ void ConfParamSLW::deleteSelected() emit entryDeleted(item->text()); delete item; } + if (m_immediate) { + string nv = listToString(); + m_cflink->set(nv); + } + if (m_lb->count()) { + m_lb->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + } } void ConfParamSLW::editSelected() @@ -754,6 +844,10 @@ void ConfParamSLW::editSelected() this, "", "", QLineEdit::Normal, m_lb->item(i)->text(), &ok); if (ok && !s.isEmpty()) { m_lb->item(i)->setText(s); + if (m_immediate) { + string nv = listToString(); + m_cflink->set(nv); + } } } } @@ -763,46 +857,24 @@ void ConfParamSLW::editSelected() void ConfParamDNLW::showInputDialog() { QString s = myGetFileName(true); - if (!s.isEmpty()) { - QListitems = - m_lb->findItems(s, Qt::MatchFixedString | Qt::MatchCaseSensitive); - if (items.empty()) { - m_lb->insertItem(0, s); - m_lb->sortItems(); - QListitems = - m_lb->findItems(s, Qt::MatchFixedString|Qt::MatchCaseSensitive); - if (m_lb->selectionMode() == QAbstractItemView::SingleSelection && - !items.empty()) { - m_lb->setCurrentItem(*items.begin()); - } - } + if (s.isEmpty()) { + return; } + performInsert(s); } // "Add entry" dialog for a constrained string list void ConfParamCSLW::showInputDialog() { bool ok; - QString s = QInputDialog::getItem(this, // parent - "", // title - "", // label, - m_sl, // items, - 0, // current = 0 - false, // editable = true, - &ok); - - if (ok && !s.isEmpty()) { - QListitems = - m_lb->findItems(s, Qt::MatchFixedString | Qt::MatchCaseSensitive); - if (items.empty()) { - m_lb->insertItem(0, s); - m_lb->sortItems(); - } + QString s = QInputDialog::getItem(this, "", "", m_sl, 0, false, &ok); + if (!ok || s.isEmpty()) { + return; } + performInsert(s); } - #ifdef ENABLE_XMLCONF static QString u8s2qs(const std::string us) diff --git a/src/qtgui/confgui/confgui.h b/src/qtgui/confgui/confgui.h index 869bed45..335b8db6 100644 --- a/src/qtgui/confgui/confgui.h +++ b/src/qtgui/confgui/confgui.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2018 J.F.Dockes +/* Copyright (C) 2007-2019 J.F.Dockes * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or @@ -17,33 +17,48 @@ #ifndef _confgui_h_included_ #define _confgui_h_included_ /** - * This file defines a number of simple classes (virtual base: ConfParamW) - * which let the user input configuration parameters. + * Utilities for a configuration/preferences settings user interface. + * + * This file declares a number of data input Qt widgets (virtual base: + * ConfParamW), with a well defined virtual interface to configuration storage, + * which may be QSettings or something else (e.g. conftree). * - * Subclasses are defined for entering different kind of data, ie a string, + * Subclasses are defined for entering different kind of data, e.g. a string, * a file name, an integer, etc. * - * Each configuration gui object is linked to the configuration data through + * Each GUI object is linked to the configuration data through * a "link" object which knows the details of interacting with the actual - * configuration data, like the parameter name, the actual config object, - * the method to call etc. + * configuration data, like the parameter name, the actual + * configuration interface, etc. * * The link object is set when the input widget is created and cannot be * changed. * - * The widgets are typically linked to a temporary configuration object, which - * is then copied to the actual configuration if the data is accepted, or - * destroyed and recreated as a copy if Cancel is pressed (you have to - * delete/recreate the widgets in this case as the links are no longer valid). + * The link object get() methods are called for reading the initial data. * - * The set() methods of the link objects are only called if the - * current value() differs from the value obtained by get() when the - * object was initialized. This can be used to avoid cluttering the - * output with values which are unmodified from the defaults. + * The set() methods for all the objects are normally called when the + * user clicks "Accept", only if the current value() differs from the + * value obtained by get() when the object was initialized. This can + * be used to avoid cluttering the output with values which are + * unmodified from the defaults. + * + * The setImmediate() method can be called on the individial controls + * to ensure that set() is inconditionnaly called whenever the user + * changes the related value. This can be especially useful if the + * configuration state can't be fully represented in the GUI (for + * example if the same parameter name can exist in different sections + * depending on the value of another parameter). It allows using local + * storage for the values, and flushing, for example, when + * sig_prefsChanged() is emitted after the user clicks accept. * * The file also defines a multi-tabbed dialog container for the - * parameter objects, with simple interface methods to create/add - * panels and elements. + * parameter objects, with simple interface methods to add tabs and add + * configuration elements to them. + * + * Some of the tab widgets can be defined as "foreign", with specific internals. + * They just need to implement a loadValues() to be called at + * initialisation and a storeValues(), called when the user commits + * the changes. */ #include @@ -80,7 +95,7 @@ public: typedef std::shared_ptr ConfLink; // May be used to store/manage data which has no direct representation -// in the config +// in the stored configuration. class ConfLinkNullRep : public ConfLinkRep { public: virtual ~ConfLinkNullRep() {} @@ -90,13 +105,15 @@ public: virtual bool get(std::string& val) {val = ""; return true;} }; -/** Link maker class */ +/** Link maker class. Will be called back by addParam() to create the link */ class ConfLinkFact { public: virtual ~ConfLinkFact() {} virtual ConfLink operator()(const QString& nm) = 0; }; +/** Interface for "foreign" panels. The object must also be a QWidget, which + * we don't express by inheriting here to avoid qt issues */ class ConfPanelWIF { public: virtual ~ConfPanelWIF() {} @@ -115,8 +132,10 @@ class ConfTabsW : public QDialog { public: ConfTabsW(QWidget *parent, const QString& title, ConfLinkFact *linkfact); - enum ParamType {CFPT_BOOL, CFPT_INT, CFPT_STR, CFPT_CSTR, CFPT_FN, - CFPT_STRL, CFPT_DNL, CFPT_CSTRL + enum ParamType {CFPT_BOOL, CFPT_INT, CFPT_STR, + CFPT_CSTR, // Constrained string: from list + CFPT_FN, // File/directory + CFPT_STRL, CFPT_DNL, CFPT_CSTRL // lists of the same }; /** Add tab and return its identifier / index */ @@ -127,11 +146,22 @@ public: int addForeignPanel(ConfPanelWIF* w, const QString& title); /** Add parameter setter to specified tab */ - ConfParamW *addParam(int tabindex, ParamType tp, - const QString& varname, const QString& label, - const QString& tooltip, int isdirorminval = 0, - int maxval = 0, const QStringList* sl = 0); + ConfParamW *addParam( + int tabindex, ParamType tp, const QString& varname, const QString& label, + const QString& tooltip, + int isdirorminval = 0, /* Dep. on type: directory flag or min value */ + int maxval = 0, const QStringList* sl = 0); + + /** Add explanatory text between 2 horizontal lines */ + QWidget *addBlurb(int tabindex, const QString& txt); + + /** Enable link between bool value and another parameter: the control will + * be enabled depending on the boolean value (with possible inversion). Can + * be called multiple times for the same bool to enable/disable + * several controls */ bool enableLink(ConfParamW* boolw, ConfParamW* otherw, bool revert = false); + + /** Call this when you are done filling up a tab */ void endOfList(int tabindex); /** Find param widget associated with given variable name */ @@ -152,11 +182,12 @@ signals: private: ConfLinkFact *m_makelink{nullptr}; + // All ConfPanelW managed panels. Each has a load/store interface + // and an internal list of controls std::vector m_panels; - // "Foreign" panels + // "Foreign" panels. Just implement load/store std::vector m_widgets; - // All params - std::vector m_params; + QTabWidget *tabWidget{nullptr}; QDialogButtonBox *buttonBox{nullptr}; }; @@ -171,13 +202,16 @@ class ConfPanelW : public QWidget { Q_OBJECT public: ConfPanelW(QWidget *parent); + void addParam(ConfParamW *w); void addWidget(QWidget *w); void storeValues(); void loadValues(); void endOfList(); + /** Find param widget associated with given variable name */ + ConfParamW *findParamW(const QString& varname); private: QVBoxLayout *m_vboxlayout; - std::vector m_widgets; + std::vector m_params; }; /** Config panel element: manages one configuration @@ -191,6 +225,10 @@ public: m_cflink(cflink), m_fsencoding(false) { } virtual void loadValue() = 0; + + // Call setValue() each time the control changes, instead of on accept. + virtual void setImmediate() = 0; + virtual void setFsEncoding(bool onoff) { m_fsencoding = onoff; } @@ -201,6 +239,11 @@ public slots: virtual void setEnabled(bool) = 0; virtual void storeValue() = 0; +protected slots: + void setValue(const QString& newvalue); + void setValue(int newvalue); + void setValue(bool newvalue); + protected: QString m_varname; ConfLink m_cflink; @@ -209,9 +252,6 @@ protected: // are encoded as utf-8 bool m_fsencoding; virtual bool createCommon(const QString& lbltxt, const QString& tltptxt); - void setValue(const QString& newvalue); - void setValue(int newvalue); - void setValue(bool newvalue); }; //////// Widgets for setting the different types of configuration parameters: @@ -225,6 +265,7 @@ public: const QString& tltptxt, bool deflt = false); virtual void loadValue(); virtual void storeValue(); + virtual void setImmediate(); public slots: virtual void setEnabled(bool i) { if (m_cb) { @@ -251,6 +292,7 @@ public: int defaultvalue = 0); virtual void loadValue(); virtual void storeValue(); + virtual void setImmediate(); public slots: virtual void setEnabled(bool i) { if (m_sb) { @@ -272,6 +314,7 @@ public: const QString& tltptxt); virtual void loadValue(); virtual void storeValue(); + virtual void setImmediate(); public slots: virtual void setEnabled(bool i) { if (m_le) { @@ -293,6 +336,7 @@ public: virtual void loadValue(); virtual void storeValue(); virtual void setList(const QStringList& sl); + virtual void setImmediate(); public slots: virtual void setEnabled(bool i) { if (m_cmb) { @@ -313,6 +357,7 @@ public: const QString& tltptxt, bool isdir = false); virtual void loadValue(); virtual void storeValue(); + virtual void setImmediate(); protected slots: void showBrowserDialog(); public slots: @@ -344,6 +389,9 @@ public: return m_lb; } virtual void setEditable(bool onoff); + virtual void setImmediate() { + m_immediate = true; + } public slots: virtual void setEnabled(bool i) { @@ -355,13 +403,16 @@ protected slots: virtual void showInputDialog(); void deleteSelected(); void editSelected(); + void performInsert(const QString&); signals: void entryDeleted(QString); + void currentTextChanged(const QString&); protected: QListWidget *m_lb; - void listToConf(); + std::string listToString(); std::string m_origvalue; QPushButton *m_pbE; + bool m_immediate{false}; }; // Dir name list diff --git a/src/qtgui/confgui/confguiindex.cpp b/src/qtgui/confgui/confguiindex.cpp index 548f9a5e..8783d3fa 100644 --- a/src/qtgui/confgui/confguiindex.cpp +++ b/src/qtgui/confgui/confguiindex.cpp @@ -61,6 +61,8 @@ public: virtual bool set(const string& val) { if (!m_conf || !*m_conf) return false; + LOGDEB("ConfLinkRclRep: set " << m_nm << " -> " << val << " sk " << + getSk() << std::endl); bool ret = (*m_conf)->set(m_nm, val, getSk()); if (!ret) LOGERR("Value set failed\n" ); @@ -70,7 +72,7 @@ public: if (!m_conf || !*m_conf) return false; bool ret = (*m_conf)->get(m_nm, val, getSk()); - LOGDEB1("ConfLinkRcl::get: [" << m_nm << "] sk [" << + LOGDEB("ConfLinkRcl::get: [" << m_nm << "] sk [" << getSk() << "] -> [" << (ret ? val : "no value") << "]\n"); return ret; } @@ -463,6 +465,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, QObject::tr("These are patterns for file or directory " " names which should not be indexed.")); eskn->setFsEncoding(true); + eskn->setImmediate(); m_widgets.push_back(eskn); gl1->addWidget(eskn, gridy, 0); @@ -478,6 +481,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, tr("Only mime types"), tr("An exclusive list of indexed mime types.
Nothing " "else will be indexed. Normally empty and inactive"), amimesq); + eincm->setImmediate(); m_widgets.push_back(eincm); gl1->addWidget(eincm, gridy++, 1); @@ -486,6 +490,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, ConfLink(new ConfLinkRclRep(config, "excludedmimetypes", &m_sk)), tr("Exclude mime types"), tr("Mime types not to be indexed"), amimesq); + eexcm->setImmediate(); m_widgets.push_back(eexcm); gl1->addWidget(eexcm, gridy, 0); @@ -498,6 +503,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, QObject::tr("These are file name endings for files which will be " "indexed by name only \n(no MIME type identification " "attempt, no decompression, no content indexing).")); + encs->setImmediate(); encs->setFsEncoding(true); m_widgets.push_back(encs); gl1->addWidget(encs, gridy++, 1); @@ -530,6 +536,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, "The default value is empty, " "and the value from the NLS environnement is used." ), charsets); + e21->setImmediate(); m_widgets.push_back(e21); gl1->addWidget(e21, gridy++, 0); @@ -540,6 +547,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, QObject::tr("Follow symbolic links while " "indexing. The default is no, " "to avoid duplicate indexing")); + e3->setImmediate(); m_widgets.push_back(e3); gl1->addWidget(e3, gridy, 0); @@ -550,6 +558,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, QObject::tr("Index the names of files for which the contents " "cannot be identified or processed (no or " "unsupported mime type). Default true")); + eafln->setImmediate(); m_widgets.push_back(eafln); gl1->addWidget(eafln, gridy++, 1); @@ -560,6 +569,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, tr("This value sets a threshold beyond which compressed" "files will not be processed. Set to -1 for no " "limit, to 0 for no decompression ever."), -1, 1000000, -1); + ezfmaxkbs->setImmediate(); m_widgets.push_back(ezfmaxkbs); gl1->addWidget(ezfmaxkbs, gridy, 0); @@ -571,6 +581,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, "files will not be processed. Set to -1 for no " "limit. \nThis is for excluding monster " "log files from the index."), -1, 1000000); + etxtmaxmbs->setImmediate(); m_widgets.push_back(etxtmaxmbs); gl1->addWidget(etxtmaxmbs, gridy++, 1); @@ -582,6 +593,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, "files will be split in chunks of this size for " "indexing.\nThis will help searching very big text " " files (ie: log files)."), -1, 1000000); + etxtpagekbs->setImmediate(); m_widgets.push_back(etxtpagekbs); gl1->addWidget(etxtpagekbs, gridy, 0); @@ -593,6 +605,7 @@ ConfSubPanelW::ConfSubPanelW(QWidget *parent, ConfNull **config, "aborted. This is for the rare case (ie: postscript) " "where a document could cause a filter to loop. " "Set to -1 for no limit.\n"), -1, 10000); + efiltmaxsecs->setImmediate(); m_widgets.push_back(efiltmaxsecs); gl1->addWidget(efiltmaxsecs, gridy++, 1);