Fix bug #6611. This also gives us a more robust fall-back in case we are

completely unable to load a text class. At least not very long ago, if
we were unable even to load article, we would crash. Not now. We will
ALWAYS have at least a really basic class (nothing but Standard!)
available.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34080 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2010-04-07 16:15:26 +00:00
parent d407a15c0a
commit 907df4570d
3 changed files with 50 additions and 24 deletions

View File

@ -1764,10 +1764,11 @@ bool BufferParams::setBaseClass(string const & classname)
LayoutFileList & bcl = LayoutFileList::get();
if (!bcl.haveClass(classname)) {
docstring s =
bformat(_("The document class %1$s could not be found. "
"A default textclass with default layouts will be used. "
"LyX might not be able to produce output unless a correct "
"textclass is selected from the document settings dialog."),
bformat(_("The layout file:\n"
"%1$s\n"
"could not be found. A default textclass with default\n"
"layouts will be used. LyX will not be able to produce\n"
"correct output."),
from_utf8(classname));
frontend::Alert::error(_("Document class not found"), s);
bcl.addEmptyClass(classname);
@ -1776,10 +1777,14 @@ bool BufferParams::setBaseClass(string const & classname)
bool const success = bcl[classname].load();
if (!success) {
docstring s =
bformat(_("The document class %1$s could not be loaded."),
bformat(_("Due to some error in it, the layout file:\n"
"%1$s\n"
"could not be loaded. A default textclass with default\n"
"layouts will be used. LyX will not be able to produce\n"
"correct output."),
from_utf8(classname));
frontend::Alert::error(_("Could not load class"), s);
return false;
bcl.addEmptyClass(classname);
}
pimpl_->baseClass_ = classname;

View File

@ -204,17 +204,9 @@ void LayoutFileList::reset(LayoutFileIndex const & classname) {
}
LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass)
{
if (haveClass(textclass))
return textclass;
namespace {
FileName const tempLayout = FileName::tempName();
ofstream ofs(tempLayout.toFilesystemEncoding().c_str());
ofs << "# This layout is automatically generated\n"
"# \\DeclareLaTeXClass{" << textclass << "}\n\n"
"Format 7\n"
"Input stdclass.inc\n\n"
string layoutpost =
"Columns 1\n"
"Sides 1\n"
"SecNumDepth 2\n"
@ -231,6 +223,20 @@ LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass)
" AlignPossible Block, Left, Right, Center\n"
" LabelType No_Label\n"
"End\n";
}
LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass)
{
FileName const tempLayout = FileName::tempName();
ofstream ofs(tempLayout.toFilesystemEncoding().c_str());
// This writes a very basic class, but it also attempts to include
// stdclass.inc. That would give us something moderately usable.
ofs << "# This layout is automatically generated\n"
"# \\DeclareLaTeXClass{" << textclass << "}\n\n"
"Format 26\n"
"Input stdclass.inc\n\n"
<< layoutpost;
ofs.close();
// We do not know if a LaTeX class is available for this document, but setting
@ -238,11 +244,24 @@ LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass)
// tex class.
LayoutFile * tc = new LayoutFile(textclass, textclass,
"Unknown text class " + textclass, textclass + ".cls", true);
if (!tc->load(tempLayout.absFilename())) {
// The only way this happens is because the hardcoded layout file above
// is wrong.
LASSERT(false, /**/);
// The only way this happens is because the hardcoded layout file
// aboveis wrong or stdclass.inc cannot be found. So try again
// without stdclass.inc.
ofstream ofs2(tempLayout.toFilesystemEncoding().c_str());
ofs2 << "# This layout is automatically generated\n"
"# \\DeclareLaTeXClass{" << textclass << "}\n\n"
"Format 26\n"
"Input stdclass.inc\n\n"
<< layoutpost;
ofs2.close();
if (!tc->load(tempLayout.absFilename())) {
// This can only happen if the hardcoded file above is wrong.
LASSERT(false, /* */);
}
}
classmap_[textclass] = tc;
return textclass;
}

View File

@ -115,7 +115,9 @@ public:
/// Clears the textclass so as to force it to be reloaded
void reset(LayoutFileIndex const & tc);
/// add a default textclass with all standard layouts.
/// Add a default textclass with all standard layouts.
/// Note that this will over-write any information we may have
/// gotten from textclass.lst about this class.
LayoutFileIndex addEmptyClass(std::string const & textclass);
/// add a textclass from user local directory.