Dear all,

I reverted my previous patch that add @para to allow para to bypass
validation. The major problem is the handling @ in lyx2lyx.

In this patch, I add a check box 'bypass validation' that will allow
any listings parameters to be passed to lyx/latex if this checkboz is
checked. No file format is changed so no lyx2lyx is needed.

There has been a lot of underlying changes. exception invalidParam is
removed  and validation is no longer triggered automatically.
Transmission of parameters will not be checked. An error message is
returned explicitly when InsetListingsParams::validate() is called
from GUI dialogs.

Please test.

Cheers,
Bo
Index: src/insets/InsetListingsParams.h
===================================================================
--- src/insets/InsetListingsParams.h	(revision 18729)
+++ src/insets/InsetListingsParams.h	(working copy)
@@ -74,6 +74,9 @@
 
 	///
 	void clear() { params_.clear(); }
+	
+	/// validate parameter, return an error message
+	docstring validate() const;
 
 private:
 	/// inline or normal listings
@@ -87,22 +90,6 @@
 };
 
 
-class invalidParam : public std::exception {
-public:
-	invalidParam(docstring const & details)
-					: details_(to_utf8(details))
-	{}
-
-	virtual const char * what() const throw() {
-		return details_.c_str();
-	}
-
-	virtual ~invalidParam() throw() {}
-private:
-	std::string const details_;
-};
-
-
 } // namespace lyx
 
 #endif
Index: src/insets/InsetListingsParams.cpp
===================================================================
--- src/insets/InsetListingsParams.cpp	(revision 18729)
+++ src/insets/InsetListingsParams.cpp	(working copy)
@@ -271,15 +271,13 @@
 public:
 	ParValidator();
 
-	/// \return the associated \c ListingsParam.
-	/// \warning an \c invalidParamexception will be thrown
-	///          if the key is not found.
-	ListingsParam const & param(string const & key) const;
+	/// validate a parameter for a given name.
+	/// return an error message if \c par is an invalid parameter.
+	docstring validate(string const & name, string const & par) const;
 
-	/// validate a parameter for a given key.
-	/// \warning an \c invalidParam exception will be thrown if
-	/// \c par is an invalid parameter.
-	ListingsParam const & validate(string const & key, string const & par) const;
+	/// return the onoff status of a parameter \c key, if \c key is not found
+	/// return false
+	bool onoff(string const & key) const;
 
 private:
 	/// key is the name of the parameter
@@ -584,21 +582,11 @@
 }
 
 
-ListingsParam const & ParValidator::validate(string const & key,
+docstring ParValidator::validate(string const & name,
 		string const & par) const
 {
-	ListingsParam const & lparam = param(key);
-	docstring s = lparam.validate(par);
-	if (!s.empty())
-		throw invalidParam(bformat(_("Parameter %1$s: "), from_utf8(key)) + s);
-	return lparam;
-}
-
-
-ListingsParam const & ParValidator::param(string const & name) const
-{
 	if (name.empty())
-		throw invalidParam(_("Invalid (empty) listing parameter name."));
+		return _("Invalid (empty) listing parameter name.");
 
 	if (name[0] == '?') {
 		string suffix = trim(string(name, 1));
@@ -613,39 +601,59 @@
 			}
 		}
 		if (suffix.empty())
-			throw invalidParam(bformat(
-					_("Available listing parameters are %1$s"), from_ascii(param_names)));
+			return bformat(
+					_("Available listing parameters are %1$s"), from_ascii(param_names));
 		else
-			throw invalidParam(bformat(
+			return bformat(
 					_("Available listings parameters containing string \"%1$s\" are %2$s"), 
-						from_utf8(suffix), from_utf8(param_names)));
+						from_utf8(suffix), from_utf8(param_names));
 	}
  
 	// locate name in parameter table
 	ListingsParams::const_iterator it = all_params_.find(name);
-	if (it != all_params_.end())
-		return it->second;
-
-	// otherwise, produce a meaningful error message.
-	string matching_names;
-	ListingsParams::const_iterator end = all_params_.end();
-	for (it = all_params_.begin(); it != end; ++it) {
-		if (prefixIs(it->first, name)) {
-			if (!matching_names.empty())
-				matching_names += ", ";
-			matching_names += it->first;
+	if (it != all_params_.end()) {
+		docstring msg = it->second.validate(par);
+		if (msg.empty())
+			return msg;
+		else
+			return bformat(_("Parameter %1$s: "), from_utf8(name)) + msg;
+	} else {
+		// otherwise, produce a meaningful error message.
+		string matching_names;
+		ListingsParams::const_iterator end = all_params_.end();
+		for (it = all_params_.begin(); it != end; ++it) {
+			if (prefixIs(it->first, name)) {
+				if (!matching_names.empty())
+					matching_names += ", ";
+				matching_names += it->first;
+			}
 		}
+		if (matching_names.empty())
+			return bformat(_("Unknown listing parameter name: %1$s"),
+								from_utf8(name));
+		else
+			return bformat(_("Parameters starting with '%1$s': %2$s"),
+								from_utf8(name), from_utf8(matching_names));
 	}
-	if (matching_names.empty())
-		throw invalidParam(bformat(_("Unknown listing parameter name: %1$s"),
-						    from_utf8(name)));
+	return docstring();
+}
+
+
+bool ParValidator::onoff(string const & name) const
+{
+	// locate name in parameter table
+	ListingsParams::const_iterator it = all_params_.find(name);
+	if (it != all_params_.end())
+		return it->second.onoff_;
 	else
-		throw invalidParam(bformat(_("Parameters starting with '%1$s': %2$s"),
-						    from_utf8(name), from_utf8(matching_names)));
+		return false;
 }
 
 } // namespace anon.
 
+// define a global ParValidator
+ParValidator * par_validator = NULL;
+
 InsetListingsParams::InsetListingsParams()
 	: inline_(false), params_(), status_(InsetCollapsable::Open)
 {
@@ -706,10 +714,6 @@
 	if (key.empty())
 		return;
 
-	static ParValidator par_validator;
-
-	// exception may be thown.
-	ListingsParam const & lparam = par_validator.validate(key, value);
 	// duplicate parameters!
 	string keyname = key;
 	if (params_.find(key) != params_.end())
@@ -718,7 +722,9 @@
 		while (params_.find(keyname += '_') != params_.end());
 	// check onoff flag
 	// onoff parameter with value false
-	if (lparam.onoff_ && (value == "false" || value == "{false}"))
+	if (!par_validator)
+		par_validator = new ParValidator();
+	if (par_validator->onoff(key) && (value == "false" || value == "{false}"))
 		params_[keyname] = string();
 	// if the parameter is surrounded with {}, good
 	else if (prefixIs(value, "{") && suffixIs(value, "}"))
@@ -839,4 +845,18 @@
 }
 
 
+docstring InsetListingsParams::validate() const
+{
+	docstring msg;
+	if (!par_validator)
+		par_validator = new ParValidator();
+	for (map<string, string>::const_iterator it = params_.begin();
+		it != params_.end(); ++it) {
+		msg = par_validator->validate(it->first, it->second);
+		if (!msg.empty())
+			return msg;
+	}
+	return msg;
+}
+
 } // namespace lyx
Index: src/frontends/qt4/QDocument.cpp
===================================================================
--- src/frontends/qt4/QDocument.cpp	(revision 18728)
+++ src/frontends/qt4/QDocument.cpp	(working copy)
@@ -222,6 +222,8 @@
 		this, SLOT(change_adaptor()));
 	connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
 		this, SLOT(change_adaptor()));
+	connect(textLayoutModule->bypassCB, SIGNAL(clicked()), 
+		this, SLOT(change_adaptor()));
 	connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
 		this, SLOT(validate_listings_params()));
 	textLayoutModule->listingsTB->setPlainText(
@@ -622,20 +624,23 @@
 void QDocumentDialog::validate_listings_params()
 {
 	static bool isOK = true;
-	try {
-		InsetListingsParams par(fromqstr(textLayoutModule->listingsED->toPlainText()));
-		if (!isOK) {
-			isOK = true;
-			// 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);
-		}
-	} catch (invalidParam & e) {
+	InsetListingsParams par(fromqstr(textLayoutModule->listingsED->toPlainText()));
+	docstring msg;
+	if (!textLayoutModule->bypassCB->isChecked())
+		msg = par.validate();
+	if (msg.empty()) {
+		if (isOK)
+			return;
+		isOK = true;
+		// 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(e.what()));
+		textLayoutModule->listingsTB->setPlainText(toqstr(msg));
 		okPB->setEnabled(false);
 		applyPB->setEnabled(false);
 	}
Index: src/frontends/qt4/QInclude.cpp
===================================================================
--- src/frontends/qt4/QInclude.cpp	(revision 18728)
+++ src/frontends/qt4/QInclude.cpp	(working copy)
@@ -66,6 +66,7 @@
 	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(bypassCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
 
 	filenameED->setValidator(new PathValidator(true, filenameED));
 	setFocusProxy(filenameED);
@@ -87,17 +88,20 @@
 void QIncludeDialog::validate_listings_params()
 {
 	static bool isOK = true;
-	try {
-		InsetListingsParams par(fromqstr(listingsED->toPlainText()));
-		if (!isOK) {
-			isOK = true;
-			listingsTB->setPlainText(
-				qt_("Input listing parameters on the right. Enter ? for a list of parameters."));
-			okPB->setEnabled(true);
-		}
-	} catch (invalidParam & e) {
+	InsetListingsParams par(fromqstr(listingsED->toPlainText()));
+	docstring msg;
+	if (!bypassCB->isChecked())
+		msg = par.validate();
+	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(e.what()));
+		listingsTB->setPlainText(toqstr(msg));
 		okPB->setEnabled(false);
 	}
 }
@@ -250,18 +254,16 @@
 			it != pars.end(); ++it) {
 			if (prefixIs(*it, "caption=")) {
 				string cap = it->substr(8);
-				if (cap[0] == '{' && cap[cap.size()-1] == '}')
+				if (cap[0] == '{' && cap[cap.size()-1] == '}') {
 					dialog_->captionLE->setText(toqstr(cap.substr(1, cap.size()-2)));
-				else
-					throw invalidParam(_("caption parameter is not quoted with braces"));
-				*it = "";
+					*it = "";
+				} 
 			} else if (prefixIs(*it, "label=")) {
 				string lbl = it->substr(6);
-				if (lbl[0] == '{' && lbl[lbl.size()-1] == '}')
+				if (lbl[0] == '{' && lbl[lbl.size()-1] == '}') {
 					dialog_->labelLE->setText(toqstr(lbl.substr(1, lbl.size()-2)));
-				else
-					throw invalidParam(_("label parameter is not quoted with braces"));
-				*it = "";
+					*it = "";
+				}
 			}
 		}
 		// the rest is put to the extra edit box.
Index: src/frontends/qt4/ui/TextLayoutUi.ui
===================================================================
--- src/frontends/qt4/ui/TextLayoutUi.ui	(revision 18728)
+++ src/frontends/qt4/ui/TextLayoutUi.ui	(working copy)
@@ -5,8 +5,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>415</width>
-    <height>398</height>
+    <width>430</width>
+    <height>497</height>
    </rect>
   </property>
   <property name="windowTitle" >
@@ -230,6 +230,13 @@
        <number>6</number>
       </property>
       <item>
+       <widget class="QCheckBox" name="bypassCB" >
+        <property name="text" >
+         <string>Bypass validation</string>
+        </property>
+       </widget>
+      </item>
+      <item>
        <widget class="QSplitter" name="splitter" >
         <property name="orientation" >
          <enum>Qt::Horizontal</enum>
@@ -287,7 +294,7 @@
      </property>
      <property name="sizeHint" >
       <size>
-       <width>397</width>
+       <width>412</width>
        <height>16</height>
       </size>
      </property>
Index: src/frontends/qt4/ui/ListingsUi.ui
===================================================================
--- src/frontends/qt4/ui/ListingsUi.ui	(revision 18728)
+++ src/frontends/qt4/ui/ListingsUi.ui	(working copy)
@@ -559,6 +559,13 @@
       <number>6</number>
      </property>
      <item>
+      <widget class="QCheckBox" name="bypassCB" >
+       <property name="text" >
+        <string>Bypass validation</string>
+       </property>
+      </widget>
+     </item>
+     <item>
       <spacer>
        <property name="orientation" >
         <enum>Qt::Horizontal</enum>
Index: src/frontends/qt4/ui/IncludeUi.ui
===================================================================
--- src/frontends/qt4/ui/IncludeUi.ui	(revision 18728)
+++ src/frontends/qt4/ui/IncludeUi.ui	(working copy)
@@ -60,6 +60,13 @@
         </property>
        </widget>
       </item>
+       <item  row="4" column="0" colspan="2" >
+      <widget class="QCheckBox" name="bypassCB" >
+       <property name="text" >
+        <string>Bypass validation</string>
+       </property>
+      </widget>
+     </item>
       <item row="0" column="1" >
        <widget class="QLineEdit" name="captionLE" >
         <property name="minimumSize" >
Index: src/frontends/qt4/QListings.cpp
===================================================================
--- src/frontends/qt4/QListings.cpp	(revision 18728)
+++ src/frontends/qt4/QListings.cpp	(working copy)
@@ -191,6 +191,7 @@
 
 	connect(listingsED,  SIGNAL(textChanged()), this, SLOT(change_adaptor()));
 	connect(listingsED,  SIGNAL(textChanged()), this, SLOT(validate_listings_params()));
+	connect(bypassCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
 
 	for (int n = 0; languages[n][0]; ++n)
 		languageCO->addItem(qt_(languages_gui[n]));
@@ -320,18 +321,21 @@
 void QListingsDialog::validate_listings_params()
 {
 	static bool isOK = true;
-	try {
-		InsetListingsParams par(construct_params());
-		if (!isOK) {
-			isOK = true;
-			listingsTB->setPlainText(
-				qt_("Input listing parameters on the right. Enter ? for a list of parameters."));
-			okPB->setEnabled(true);
-			applyPB->setEnabled(true);
-		}
-	} catch (invalidParam & e) {
+	InsetListingsParams par(construct_params());
+	docstring msg;
+	if (!bypassCB->isChecked())
+		msg = par.validate();
+	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(e.what()));
+		listingsTB->setPlainText(toqstr(msg));
 		okPB->setEnabled(false);
 		applyPB->setEnabled(false);
 	}
Index: src/BufferParams.cpp
===================================================================
--- src/BufferParams.cpp	(revision 18728)
+++ src/BufferParams.cpp	(working copy)
@@ -608,14 +608,7 @@
 	} else if (token == "\\listings_params") {
 		string par;
 		lex >> par;
-		// validate par and produce a valid listings parameter string
-		try {
-			listings_params = InsetListingsParams(par).params();
-		} catch (invalidParam & e) {
-			lyxerr << "Invalid parameter string " << par << endl;
-			lyxerr << e.what() << endl;
-			listings_params = string();
-		}
+		listings_params = InsetListingsParams(par).params();
 	} else if (token == "\\papersides") {
 		int psides;
 		lex >> psides;

Reply via email to