Grant a long-standing wish of Lars's: LyX now functions even if we have

no text classes for some reason (e.g., a corrupt textclass.lst). We
still give the user a chance to reconfigure (Bo's idea).

I wonder if we still really need to "restart LyX to make use of any
updated document class specifications". What would happen if we just
reloaded?


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34081 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2010-04-07 17:02:44 +00:00
parent 907df4570d
commit f9fa189e02
3 changed files with 73 additions and 107 deletions

View File

@ -99,86 +99,74 @@ LayoutFile & LayoutFileList::operator[](string const & classname)
// Reads LyX textclass definitions according to textclass config file // Reads LyX textclass definitions according to textclass config file
bool LayoutFileList::read() bool LayoutFileList::read()
{ {
bool success = false;
Lexer lex; Lexer lex;
FileName const real_file = libFileSearch("", "textclass.lst"); FileName const real_file = libFileSearch("", "textclass.lst");
LYXERR(Debug::TCLASS, "Reading textclasses from `" << real_file << '\''); LYXERR(Debug::TCLASS, "Reading textclasses from `" << real_file << "'.");
if (real_file.empty()) { if (real_file.empty()) {
lyxerr << "LayoutFileList::Read: unable to find " LYXERR0("LayoutFileList::Read: unable to find textclass file `"
"textclass file `" << makeDisplayPath(real_file.absFilename(), 1000)
<< to_utf8(makeDisplayPath(real_file.absFilename(), 1000)) << "'.");
<< "'. Exiting." << endl; success = false;
return false; } else if (!lex.setFile(real_file)) {
// This causes LyX to end... Not a desirable behaviour. Lgb LYXERR0("LayoutFileList::Read: lyxlex was not able to set file: "
// What do you propose? That the user gets a file dialog << real_file << '.');
// and is allowed to hunt for the file? (Asger) } else if (!lex.isOK()) {
// more that we have a layout for minimal.cls statically LYXERR0("LayoutFileList::Read: unable to open textclass file `"
// compiled in... (Lgb) << makeDisplayPath(real_file.absFilename(), 1000)
} << "'\nCheck your installation.");
} else {
if (!lex.setFile(real_file)) { // we have a file we can read.
lyxerr << "LayoutFileList::Read: " bool finished = false;
"lyxlex was not able to set file: " LYXERR(Debug::TCLASS, "Starting parsing of textclass.lst");
<< real_file << endl; while (lex.isOK() && !finished) {
} LYXERR(Debug::TCLASS, "\tline by line");
switch (lex.lex()) {
if (!lex.isOK()) { case Lexer::LEX_FEOF:
lyxerr << "LayoutFileList::Read: unable to open " finished = true;
"textclass file `"
<< to_utf8(makeDisplayPath(real_file.absFilename(), 1000))
<< "'\nCheck your installation. LyX can't continue."
<< endl;
return false;
}
bool finished = false;
// Parse config-file
LYXERR(Debug::TCLASS, "Starting parsing of textclass.lst");
while (lex.isOK() && !finished) {
LYXERR(Debug::TCLASS, "\tline by line");
switch (lex.lex()) {
case Lexer::LEX_FEOF:
finished = true;
break;
default:
string const fname = lex.getString();
LYXERR(Debug::TCLASS, "Fname: " << fname);
if (!lex.next())
break; break;
string const clname = lex.getString(); default:
LYXERR(Debug::TCLASS, "Clname: " << clname); string const fname = lex.getString();
if (!lex.next()) LYXERR(Debug::TCLASS, "Fname: " << fname);
break; if (!lex.next())
string const desc = lex.getString(); break;
LYXERR(Debug::TCLASS, "Desc: " << desc); string const clname = lex.getString();
if (!lex.next()) LYXERR(Debug::TCLASS, "Clname: " << clname);
break; if (!lex.next())
bool avail = lex.getBool(); break;
LYXERR(Debug::TCLASS, "Avail: " << avail); string const desc = lex.getString();
if (!lex.next()) LYXERR(Debug::TCLASS, "Desc: " << desc);
break; if (!lex.next())
string const prereq = lex.getString(); break;
LYXERR(Debug::TCLASS, "Prereq: " << prereq); bool avail = lex.getBool();
// This code is run when we have LYXERR(Debug::TCLASS, "Avail: " << avail);
// fname, clname, desc, prereq, and avail if (!lex.next())
LayoutFile * tmpl = new LayoutFile(fname, clname, desc, prereq, avail); break;
if (lyxerr.debugging(Debug::TCLASS)) { string const prereq = lex.getString();
// only system layout files are loaded here so no LYXERR(Debug::TCLASS, "Prereq: " << prereq);
// buffer path is needed. // This code is run when we have
tmpl->load(); // fname, clname, desc, prereq, and avail
} LayoutFile * tmpl = new LayoutFile(fname, clname, desc, prereq, avail);
classmap_[fname] = tmpl; if (lyxerr.debugging(Debug::TCLASS)) {
} // only system layout files are loaded here so no
} // buffer path is needed.
LYXERR(Debug::TCLASS, "End of parsing of textclass.lst"); tmpl->load();
}
classmap_[fname] = tmpl;
} // end of switch
} // end of while loop
LYXERR(Debug::TCLASS, "End parsing of textclass.lst");
success = true;
} // end of else
// lyx will start with an empty classmap_, but only reconfigure is allowed // LyX will start with an empty classmap_. This is OK because
// in this case. This gives users a second chance to configure lyx if // (a) we will give the user a chance to reconfigure (see bug 2829) and
// initial configuration fails. (c.f. bug 2829) // (b) even if that fails, we can use addEmptyClass() to get some basic
// functionality.
if (classmap_.empty()) if (classmap_.empty())
lyxerr << "LayoutFileList::Read: no textclasses found!" LYXERR0("LayoutFileList::Read: no textclasses found!");
<< endl; return success;
return true;
} }
@ -346,26 +334,10 @@ LayoutFileIndex defaultBaseclass()
if (LayoutFileList::get().haveClass("article")) if (LayoutFileList::get().haveClass("article"))
return string("article"); return string("article");
if (LayoutFileList::get().empty()) if (LayoutFileList::get().empty())
return string(); // we'll call it that, since this gives the user a chance to
// have a functioning document when things improve.
return string("article");
return LayoutFileList::get().classList().front(); return LayoutFileList::get().classList().front();
} }
// Reads the style files
bool LyXSetStyle()
{
LYXERR(Debug::TCLASS, "LyXSetStyle: parsing configuration...");
if (!LayoutFileList::get().read()) {
LYXERR(Debug::TCLASS, "LyXSetStyle: an error occured "
"during parsing.\n Exiting.");
return false;
}
LYXERR(Debug::TCLASS, "LyXSetStyle: configuration parsed.");
return true;
}
} // namespace lyx } // namespace lyx

View File

@ -29,10 +29,6 @@ namespace lyx {
class Layout; class Layout;
/// Reads the style files
extern bool LyXSetStyle();
/// Index into LayoutFileList. Basically a 'strong typedef'. /// Index into LayoutFileList. Basically a 'strong typedef'.
class LayoutFileIndex { class LayoutFileIndex {
public: public:

View File

@ -502,16 +502,16 @@ void LyX::execCommands()
// aknowledged. // aknowledged.
// if reconfiguration is needed. // if reconfiguration is needed.
while (LayoutFileList::get().empty()) { if (LayoutFileList::get().empty()) {
switch (Alert::prompt( switch (Alert::prompt(
_("No textclass is found"), _("No textclass is found"),
_("LyX cannot continue because no textclass is found. " _("LyX will have minimal functionality because no textclasses "
"You can either reconfigure normally, or reconfigure using " "have been found. You can either try to reconfigure LyX normally, "
"default textclasses, or quit LyX."), "try to reconfigure using only the defaults, or continue."),
0, 2, 0, 2,
_("&Reconfigure"), _("&Reconfigure"),
_("&Use Default"), _("&Use Defaults"),
_("&Exit LyX"))) _("&Continue")))
{ {
case 0: case 0:
// regular reconfigure // regular reconfigure
@ -523,8 +523,7 @@ void LyX::execCommands()
" --without-latex-config")); " --without-latex-config"));
break; break;
default: default:
lyx::dispatch(FuncRequest(LFUN_LYX_QUIT)); break;
return;
} }
} }
@ -762,10 +761,9 @@ bool LyX::init()
// Set the language defined by the user. // Set the language defined by the user.
setRcGuiLanguage(); setRcGuiLanguage();
// Load the layouts
LYXERR(Debug::INIT, "Reading layouts..."); LYXERR(Debug::INIT, "Reading layouts...");
if (!LyXSetStyle()) // Load the layouts
return false; LayoutFileList::get().read();
//...and the modules //...and the modules
theModuleList.read(); theModuleList.read();