Dear all,

Using a trick that add par_id and pos information during the handling
of encoding_exception, I came up with a much simpler patch. Basically,

1. Define an exception with all needed information.
+class encoding_exception : public std::exception {
+public:
+       encoding_exception(char_type c);
+       virtual ~encoding_exception() throw() {}
+       virtual const char * what() const throw();

+       char_type failed_char;
+       int par_id;
+       pos_type pos;
+};

2. throw it first without par_id and pos
                if (it == unicodesymbols.end())
-                       lyxerr << "Could not find LaTeX command for character 
0x"
-                              << std::hex << c << std::dec
-                              << ".\nLaTeX export will fail."
-                              << endl;
+                       throw encoding_exception(c);

3. Intecept this exception and add par_id and pos somewhere.

-               pimpl_->simpleTeXSpecialChars(buf, bparams, os,
+               
+               try {
+                       pimpl_->simpleTeXSpecialChars(buf, bparams, os,
                                        texrow, rp, running_font,
                                        basefont, outerfont, open_font,
                                        runningChange, *style, i, column, c);
+               } catch (encoding_exception & e) {
+                       // add location information and throw again.
+                       e.par_id = id();
+                       e.pos = i;
+                       throw(e);
+               }

4. Handle this exception with ErrorList.

+       ErrorList & errorList = pimpl_->errorLists["Export"];
+       errorList.clear();
        bool failed_export = false;
        try {
                writeLaTeXSource(ofs, original_path,
                      runparams, output_preamble, output_body);
        }
+       catch (encoding_exception & e) {
+               docstring msg = _("Could not find LaTeX command for character 
'%'");
+               msg[msg.size() - 2] = e.failed_char;
+               errorList.push_back(ErrorItem(msg, _("Some characters of your
document are probably not "
+                               "representable in the chosen encoding.\n"
+                               "Changing the document encoding to utf8 could 
help."),
+                               e.par_id, e.pos, e.pos + 1));
+               failed_export = true;                   
+       }

@@ -962,15 +975,8 @@
                failed_export = true;
                lyxerr << "File '" << fname << "' was not closed properly." << 
endl;
        }
-
-       if (failed_export) {
-               Alert::error(_("Encoding error"),
-                       _("Some characters of your document are probably not "
-                       "representable in the chosen encoding.\n"
-                       "Changing the document encoding to utf8 could help."));
-               return false;
-       }
-       return true;
+       errors("Export");
+       return !failed_export;

The main difference is that instead of passing ErrorList around to the
very level that par_id is available, par_id is returned along with the
exception. With this patch, the offending character will be
highlighted when you select the error item.

The patch is for 1.5.4, please test. I will commit after a few days of using it.

Cheers,
Bo
Index: src/Paragraph.cpp
===================================================================
--- src/Paragraph.cpp	(revision 22192)
+++ src/Paragraph.cpp	(working copy)
@@ -2229,10 +2229,18 @@
 		rp.free_spacing = style->free_spacing;
 		rp.local_font = &font;
 		rp.intitle = style->intitle;
-		pimpl_->simpleTeXSpecialChars(buf, bparams, os,
+		
+		try {
+			pimpl_->simpleTeXSpecialChars(buf, bparams, os,
 					texrow, rp, running_font,
 					basefont, outerfont, open_font,
 					runningChange, *style, i, column, c);
+		} catch (encoding_exception & e) {
+			// add location information and throw again.
+			e.par_id = id();
+			e.pos = i;
+			throw(e);
+		}
 
 		// Set the encoding to that returned from simpleTeXSpecialChars (see
 		// comment for encoding member in OutputParams.h)
Index: src/Encoding.cpp
===================================================================
--- src/Encoding.cpp	(revision 22192)
+++ src/Encoding.cpp	(working copy)
@@ -251,6 +251,18 @@
 } // namespace anon
 
 
+encoding_exception::encoding_exception(char_type c)
+	: failed_char(c), par_id(0), pos(0)
+{
+}
+
+
+const char * encoding_exception::what() const throw()
+{
+	return "Could not find LaTeX command for a character";
+}
+
+
 Encoding::Encoding(string const & n, string const & l, string const & i,
 		   bool f, Encoding::Package p)
 	: Name_(n), LatexName_(l), iconvName_(i), fixedwidth_(f), package_(p)
@@ -325,10 +337,7 @@
 		// c cannot be encoded in this encoding
 		CharInfoMap::const_iterator const it = unicodesymbols.find(c);
 		if (it == unicodesymbols.end())
-			lyxerr << "Could not find LaTeX command for character 0x"
-			       << std::hex << c << std::dec
-			       << ".\nLaTeX export will fail."
-			       << endl;
+			throw encoding_exception(c);
 		else
 			return it->second.command;
 	}
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(revision 22192)
+++ src/Buffer.cpp	(working copy)
@@ -938,17 +938,30 @@
 	if (!openFileWrite(ofs, fname))
 		return false;
 
+	ErrorList & errorList = pimpl_->errorLists["Export"];
+	errorList.clear();
 	bool failed_export = false;
 	try {
 		writeLaTeXSource(ofs, original_path,
 		      runparams, output_preamble, output_body);
 	}
+	catch (encoding_exception & e) {
+		docstring msg = _("Could not find LaTeX command for character '%'");
+		msg[msg.size() - 2] = e.failed_char;
+		errorList.push_back(ErrorItem(msg, _("Some characters of your document are probably not "
+				"representable in the chosen encoding.\n"
+				"Changing the document encoding to utf8 could help."),
+				e.par_id, e.pos, e.pos + 1));
+		failed_export = true;			
+	}
 	catch (iconv_codecvt_facet_exception & e) {
-		lyxerr << "Caught iconv exception: " << e.what() << endl;
+		errorList.push_back(ErrorItem(_("iconv conversion failed"),
+			_(e.what()), -1, 0, 0));
 		failed_export = true;
 	}
 	catch (std::exception const & e) {
-		lyxerr << "Caught \"normal\" exception: " << e.what() << endl;
+		errorList.push_back(ErrorItem(_("conversion failed"),
+			_(e.what()), -1, 0, 0));
 		failed_export = true;
 	}
 	catch (...) {
@@ -962,15 +975,8 @@
 		failed_export = true;
 		lyxerr << "File '" << fname << "' was not closed properly." << endl;
 	}
-
-	if (failed_export) {
-		Alert::error(_("Encoding error"),
-			_("Some characters of your document are probably not "
-			"representable in the chosen encoding.\n"
-			"Changing the document encoding to utf8 could help."));
-		return false;
-	}
-	return true;
+	errors("Export");
+	return !failed_export;
 }
 
 
Index: src/Encoding.h
===================================================================
--- src/Encoding.h	(revision 22192)
+++ src/Encoding.h	(working copy)
@@ -24,7 +24,18 @@
 
 class LaTeXFeatures;
 
+class encoding_exception : public std::exception {
+public:
+	encoding_exception(char_type c);
+	virtual ~encoding_exception() throw() {}
+	virtual const char * what() const throw();
 
+	char_type failed_char;
+	int par_id;
+	pos_type pos;
+};
+
+
 ///
 class Encoding {
 public:
Index: status.15x
===================================================================
--- status.15x	(revision 22192)
+++ status.15x	(working copy)
@@ -29,9 +29,10 @@
 
 * USER INTERFACE
 
+- An dialog is displayed if some character can not be encoded properly. The
+  offending character will be highlighted.
 
 
-
 * DOCUMENT INPUT/OUTPUT
 
 

Reply via email to