An updated, more efficient patch. This time, I use a static cache to hold previously validated parameter and its output to avoid repeated validation of the same parameter. This happens quite often now because isValid() will be called if any control is changed.
The patch is also registered to bugzilla. Bo
Index: src/frontends/qt4/QDocument.cpp =================================================================== --- src/frontends/qt4/QDocument.cpp (revision 19165) +++ src/frontends/qt4/QDocument.cpp (working copy) @@ -225,9 +225,9 @@ connect(textLayoutModule->bypassCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(textLayoutModule->bypassCB, SIGNAL(clicked()), - this, SLOT(validate_listings_params())); + this, SLOT(set_listings_msg())); connect(textLayoutModule->listingsED, SIGNAL(textChanged()), - this, SLOT(validate_listings_params())); + this, SLOT(set_listings_msg())); textLayoutModule->listingsTB->setPlainText( qt_("Input listings parameters on the right. Enter ? for a list of parameters.")); textLayoutModule->lspacingLE->setValidator(new QDoubleValidator( @@ -623,13 +623,29 @@ } -void QDocumentDialog::validate_listings_params() +docstring QDocumentDialog::validate_listings_params() { + // use a cache here to avoid repeated validation + // of the same parameters + static string param_cache = string(); + static docstring msg_cache = docstring(); + + if (textLayoutModule->bypassCB->isChecked()) + return docstring(); + + string params = fromqstr(textLayoutModule->listingsED->toPlainText()); + if (params != param_cache) { + param_cache = params; + msg_cache = InsetListingsParams(params).validate(); + } + return msg_cache; +} + + +void QDocumentDialog::set_listings_msg() +{ static bool isOK = true; - InsetListingsParams par(fromqstr(textLayoutModule->listingsED->toPlainText())); - docstring msg; - if (!textLayoutModule->bypassCB->isChecked()) - msg = par.validate(); + docstring msg = validate_listings_params(); if (msg.empty()) { if (isOK) return; @@ -637,14 +653,10 @@ // listingsTB->setTextColor("black"); textLayoutModule->listingsTB->setPlainText( qt_("Input listings parameters on the right. Enter ? for a list of parameters.")); - okPB->setEnabled(true); - applyPB->setEnabled(true); } else { isOK = false; // listingsTB->setTextColor("red"); textLayoutModule->listingsTB->setPlainText(toqstr(msg)); - okPB->setEnabled(false); - applyPB->setEnabled(false); } } @@ -1449,6 +1461,13 @@ update_contents(); } + +bool QDocument::isValid() +{ + return dialog_->validate_listings_params().empty(); +} + + } // namespace frontend } // namespace lyx Index: src/frontends/qt4/QInclude.cpp =================================================================== --- src/frontends/qt4/QInclude.cpp (revision 19165) +++ src/frontends/qt4/QInclude.cpp (working copy) @@ -64,9 +64,9 @@ connect(captionLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor())); connect(labelLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor())); connect(listingsED, SIGNAL(textChanged()), this, SLOT(change_adaptor())); - connect(listingsED, SIGNAL(textChanged()), this, SLOT(validate_listings_params())); + connect(listingsED, SIGNAL(textChanged()), this, SLOT(set_listings_msg())); connect(bypassCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); - connect(bypassCB, SIGNAL(clicked()), this, SLOT(validate_listings_params())); + connect(bypassCB, SIGNAL(clicked()), this, SLOT(set_listings_msg())); setFocusProxy(filenameED); } @@ -84,24 +84,38 @@ } -void QIncludeDialog::validate_listings_params() +docstring QIncludeDialog::validate_listings_params() { + // use a cache here to avoid repeated validation + // of the same parameters + static string param_cache = string(); + static docstring msg_cache = docstring(); + + if (typeCO->currentIndex() != 3 || bypassCB->isChecked()) + return docstring(); + + string params = fromqstr(listingsED->toPlainText()); + if (params != param_cache) { + param_cache = params; + msg_cache = InsetListingsParams(params).validate(); + } + return msg_cache; +} + + +void QIncludeDialog::set_listings_msg() +{ static bool isOK = true; - InsetListingsParams par(fromqstr(listingsED->toPlainText())); - docstring msg; - if (!bypassCB->isChecked()) - msg = par.validate(); + docstring msg = validate_listings_params(); if (msg.empty()) { if (isOK) return; isOK = true; listingsTB->setPlainText( qt_("Input listing parameters on the right. Enter ? for a list of parameters.")); - okPB->setEnabled(true); } else { isOK = false; listingsTB->setPlainText(toqstr(msg)); - okPB->setEnabled(false); } } @@ -334,7 +348,8 @@ bool QInclude::isValid() { - return !dialog_->filenameED->text().isEmpty(); + return !dialog_->filenameED->text().isEmpty() && + dialog_->validate_listings_params().empty(); } } // namespace frontend Index: src/frontends/qt4/QListings.h =================================================================== --- src/frontends/qt4/QListings.h (revision 19165) +++ src/frontends/qt4/QListings.h (working copy) @@ -29,11 +29,15 @@ QListingsDialog(QListings * form); /// get values from all the widgets and form a string std::string construct_params(); + /// validate listings parameters and return an error message, if any + docstring validate_listings_params(); protected Q_SLOTS: virtual void change_adaptor(); /// AFAIK, QValidator only works for QLineEdit so /// I have to validate listingsED (QTextEdit) manually. - void validate_listings_params(); + /// This function displays a hint or error message returned by + /// validate_listings_params + void set_listings_msg(); /// turn off inline when float is clicked void on_floatCB_stateChanged(int state); /// turn off float when inline is clicked @@ -63,6 +67,9 @@ virtual void update_contents(); /// build the dialog virtual void build_dialog(); +protected: + /// return false if validate_listings_params returns error + virtual bool isValid(); }; } // namespace frontend Index: src/frontends/qt4/QInclude.h =================================================================== --- src/frontends/qt4/QInclude.h (revision 19165) +++ src/frontends/qt4/QInclude.h (working copy) @@ -31,12 +31,18 @@ void updateLists(); virtual void show(); + /// validate listings parameters and return an error message, if any + docstring validate_listings_params(); protected Q_SLOTS: virtual void change_adaptor(); - void validate_listings_params(); virtual void loadClicked(); virtual void browseClicked(); virtual void typeChanged(int v); + /// AFAIK, QValidator only works for QLineEdit so + /// I have to validate listingsED (QTextEdit) manually. + /// This function displays a hint or error message returned by + /// validate_listings_params + void set_listings_msg(); protected: virtual void closeEvent(QCloseEvent * e); private: Index: src/frontends/qt4/QDocument.h =================================================================== --- src/frontends/qt4/QDocument.h (revision 19165) +++ src/frontends/qt4/QDocument.h (working copy) @@ -68,11 +68,13 @@ void updatePagestyle(std::string const &, std::string const &); void showPreamble(); + /// validate listings parameters and return an error message, if any + docstring validate_listings_params(); public Q_SLOTS: void updateNumbering(); void change_adaptor(); - void validate_listings_params(); + void set_listings_msg(); void saveDefaultClicked(); void useDefaultsClicked(); @@ -141,6 +143,9 @@ void saveDocDefault(); /// reset to default params void useClassDefaults(); +protected: + /// return false if validate_listings_params returns error + virtual bool isValid(); }; Index: src/frontends/qt4/QListings.cpp =================================================================== --- src/frontends/qt4/QListings.cpp (revision 19165) +++ src/frontends/qt4/QListings.cpp (working copy) @@ -190,9 +190,9 @@ connect(extendedcharsCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(listingsED, SIGNAL(textChanged()), this, SLOT(change_adaptor())); - connect(listingsED, SIGNAL(textChanged()), this, SLOT(validate_listings_params())); + connect(listingsED, SIGNAL(textChanged()), this, SLOT(set_listings_msg())); connect(bypassCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); - connect(bypassCB, SIGNAL(clicked()), this, SLOT(validate_listings_params())); + connect(bypassCB, SIGNAL(clicked()), this, SLOT(set_listings_msg())); for (int n = 0; languages[n][0]; ++n) languageCO->addItem(qt_(languages_gui[n])); @@ -319,26 +319,38 @@ } -void QListingsDialog::validate_listings_params() +docstring QListingsDialog::validate_listings_params() { + // use a cache here to avoid repeated validation + // of the same parameters + static string param_cache = string(); + static docstring msg_cache = docstring(); + + if (bypassCB->isChecked()) + return docstring(); + + string params = construct_params(); + if (params != param_cache) { + param_cache = params; + msg_cache = InsetListingsParams(params).validate(); + } + return msg_cache; +} + + +void QListingsDialog::set_listings_msg() +{ static bool isOK = true; - InsetListingsParams par(construct_params()); - docstring msg; - if (!bypassCB->isChecked()) - msg = par.validate(); + docstring msg = validate_listings_params(); if (msg.empty()) { if (isOK) return; isOK = true; listingsTB->setPlainText( qt_("Input listing parameters on the right. Enter ? for a list of parameters.")); - okPB->setEnabled(true); - applyPB->setEnabled(true); } else { isOK = false; listingsTB->setPlainText(toqstr(msg)); - okPB->setEnabled(false); - applyPB->setEnabled(false); } } @@ -601,6 +613,12 @@ } +bool QListings::isValid() +{ + return dialog_->validate_listings_params().empty(); +} + + } // namespace frontend } // namespace lyx