]> git.lyx.org Git - lyx.git/blobdiff - src/TextClass.cpp
* src/inset/InsetNomencl.cpp:
[lyx.git] / src / TextClass.cpp
index a735710eace92d40a2201ec3521fffed9a7cabb0..a594375cda5930118f51d3513ea237c56dc77d64 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "frontends/alert.h"
 
-#include "support/assert.h"
+#include "support/lassert.h"
 #include "support/debug.h"
 #include "support/ExceptionMessage.h"
 #include "support/FileName.h"
@@ -61,7 +61,7 @@ private:
 };
 
 
-int const FORMAT = 7;
+int const FORMAT = 8;
 
 
 bool layout2layout(FileName const & filename, FileName const & tempfile)
@@ -109,12 +109,20 @@ std::string translateRT(TextClass::ReadType rt)
 } // namespace anon
 
 
-docstring const TextClass::emptylayout_ = from_ascii(N_("Plain Layout"));
+// This string should not be translated here, 
+// because it is a layout identifier.
+docstring const TextClass::plain_layout_ = from_ascii("Plain Layout");
 
 
-InsetLayout DocumentClass::empty_insetlayout_;
+InsetLayout DocumentClass::plain_insetlayout_;
 
 
+/////////////////////////////////////////////////////////////////////////
+//
+// TextClass
+//
+/////////////////////////////////////////////////////////////////////////
+
 TextClass::TextClass()
 {
        outputType_ = LATEX;
@@ -129,10 +137,11 @@ TextClass::TextClass()
        titletype_ = TITLE_COMMAND_AFTER;
        titlename_ = "maketitle";
        loaded_ = false;
+       _("Plain Layout"); // a hack to make this translatable
 }
 
 
-bool TextClass::readStyle(Lexer & lexrc, Layout & lay)
+bool TextClass::readStyle(Lexer & lexrc, Layout & lay) const
 {
        LYXERR(Debug::TCLASS, "Reading style " << to_utf8(lay.name()));
        if (!lay.read(lexrc, *this)) {
@@ -154,7 +163,6 @@ enum TextClassTags {
        TC_STYLE,
        TC_DEFAULTSTYLE,
        TC_INSETLAYOUT,
-       TC_ENVIRONMENT,
        TC_NOSTYLE,
        TC_COLUMNS,
        TC_SIDES,
@@ -174,7 +182,8 @@ enum TextClassTags {
        TC_TITLELATEXNAME,
        TC_TITLELATEXTYPE,
        TC_FORMAT,
-       TC_ADDTOPREAMBLE
+       TC_ADDTOPREAMBLE,
+       TC_USEMODULE
 };
 
 
@@ -187,7 +196,6 @@ namespace {
                { "counter",         TC_COUNTER },
                { "defaultfont",     TC_DEFAULTFONT },
                { "defaultstyle",    TC_DEFAULTSTYLE },
-               { "environment",     TC_ENVIRONMENT },
                { "float",           TC_FLOAT },
                { "format",          TC_FORMAT },
                { "input",           TC_INPUT },
@@ -206,7 +214,8 @@ namespace {
                { "style",           TC_STYLE },
                { "titlelatexname",  TC_TITLELATEXNAME },
                { "titlelatextype",  TC_TITLELATEXTYPE },
-               { "tocdepth",        TC_TOCDEPTH }
+               { "tocdepth",        TC_TOCDEPTH },
+               { "usemodule",       TC_USEMODULE }
        };
        
 } //namespace anon
@@ -215,7 +224,7 @@ namespace {
 bool TextClass::convertLayoutFormat(support::FileName const & filename, ReadType rt)
 {
        LYXERR(Debug::TCLASS, "Converting layout file to " << FORMAT);
-               FileName const tempfile = FileName::tempName();
+               FileName const tempfile = FileName::tempName("convert_layout");
                bool success = layout2layout(filename, tempfile);
                if (success)
                        success = read(tempfile, rt);
@@ -234,29 +243,11 @@ bool TextClass::read(FileName const & filename, ReadType rt)
        LYXERR(Debug::TCLASS, "Reading " + translateRT(rt) + ": " +
                to_utf8(makeDisplayPath(filename.absFilename())));
 
-       // Define the `empty' layout used in table cells, ert, etc. Note that 
+       // Define the plain layout used in table cells, ert, etc. Note that 
        // we do this before loading any layout file, so that classes can 
        // override features of this layout if they should choose to do so.
-       if (rt == BASECLASS && !hasLayout(emptylayout_)) {
-               static char const * s = "Margin Static\n"
-                       "LatexType Paragraph\n"
-                       "LatexName dummy\n"
-                       "Align Block\n"
-                       "AlignPossible Left, Right, Center\n"
-                       "LabelType No_Label\n"
-                       "End";
-               istringstream ss(s);
-               Lexer lex(textClassTags);
-               lex.setStream(ss);
-               Layout lay;
-               lay.setName(emptylayout_);
-               if (!readStyle(lex, lay)) {
-                       // The only way this happens is because the hardcoded layout above
-                       // is wrong.
-                       LASSERT(false, /**/);
-               };
-               layoutlist_.push_back(lay);
-       }
+       if (rt == BASECLASS && !hasLayout(plain_layout_))
+               layoutlist_.push_back(createBasicLayout(plain_layout_));
 
        Lexer lexrc(textClassTags);
        lexrc.setFile(filename);
@@ -296,10 +287,10 @@ bool TextClass::read(std::string const & str, ReadType rt)
                return retval == OK;
 
        // write the layout string to a temporary file
-       FileName const tempfile = FileName::tempName();
+       FileName const tempfile = FileName::tempName("TextClass_read");
        ofstream os(tempfile.toFilesystemEncoding().c_str());
        if (!os) {
-               LYXERR0("Unable to create tempoary file");
+               LYXERR0("Unable to create temporary file");
                return false;
        }
        os << str;
@@ -377,7 +368,6 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        }
                        break;
 
-               case TC_ENVIRONMENT:
                case TC_STYLE:
                        if (lexrc.next()) {
                                docstring const name = from_utf8(subst(lexrc.getString(),
@@ -396,8 +386,6 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                                } else {
                                        Layout layout;
                                        layout.setName(name);
-                                       if (le == TC_ENVIRONMENT)
-                                               layout.is_environment = true;
                                        error = !readStyle(lexrc, layout);
                                        if (!error)
                                                layoutlist_.push_back(layout);
@@ -505,6 +493,13 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        break;
                }
 
+               case TC_USEMODULE: {
+                       lexrc.next();
+                       string const module = lexrc.getString();
+                       usemod_.insert(module);
+                       break;
+               }
+
                case TC_LEFTMARGIN:     // left margin type
                        if (lexrc.next())
                                leftmargin_ = lexrc.getDocString();
@@ -518,7 +513,7 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                case TC_INSETLAYOUT:
                        if (lexrc.next()) {
                                InsetLayout il;
-                               if (il.read(lexrc))
+                               if (il.read(lexrc, *this))
                                        insetlayoutlist_[il.name()] = il;
                                // else there was an error, so forget it
                        }
@@ -917,7 +912,6 @@ bool TextClass::hasLayout(docstring const & n) const
 }
 
 
-
 Layout const & TextClass::operator[](docstring const & name) const
 {
        LASSERT(!name.empty(), /**/);
@@ -962,7 +956,7 @@ Layout & TextClass::operator[](docstring const & name)
 
 bool TextClass::deleteLayout(docstring const & name)
 {
-       if (name == defaultLayoutName() || name == emptyLayoutName())
+       if (name == defaultLayoutName() || name == plainLayoutName())
                return false;
 
        LayoutList::iterator it =
@@ -983,8 +977,9 @@ bool TextClass::load(string const & path) const
                return true;
 
        // Read style-file, provided path is searched before the system ones
-       FileName layout_file;
-       if (!path.empty())
+       // If path is a file, it is loaded directly.
+       FileName layout_file(path);
+       if (!path.empty() && !layout_file.isReadableFile())
                layout_file = FileName(addName(path, name_ + ".layout"));
        if (layout_file.empty() || !layout_file.exists())
                layout_file = libFileSearch("layouts", name_, "layout");
@@ -1002,8 +997,17 @@ bool TextClass::load(string const & path) const
 }
 
 
+void DocumentClass::addLayoutIfNeeded(docstring const & n) const
+{
+       if (!hasLayout(n))
+               layoutlist_.push_back(createBasicLayout(n, true));
+}
+
+
 InsetLayout const & DocumentClass::insetLayout(docstring const & name) const 
 {
+       // FIXME The fix for the InsetLayout part of 4812 would be here:
+       // Add the InsetLayout to the document class if it is not found.
        docstring n = name;
        InsetLayouts::const_iterator cen = insetlayoutlist_.end();
        while (!n.empty()) {
@@ -1015,7 +1019,7 @@ InsetLayout const & DocumentClass::insetLayout(docstring const & name) const
                        break;
                n = n.substr(0,i);
        }
-       return empty_insetlayout_;
+       return plain_insetlayout_;
 }
 
 
@@ -1032,23 +1036,67 @@ Layout const & TextClass::defaultLayout() const
 }
 
 
-bool TextClass::isDefaultLayout(Layout const & lay) const 
+bool TextClass::isDefaultLayout(Layout const & layout) const 
 {
-       return lay.name() == defaultLayoutName();
+       return layout.name() == defaultLayoutName();
 }
 
 
-bool TextClass::isEmptyLayout(Layout const & lay) const 
+bool TextClass::isPlainLayout(Layout const & layout) const 
 {
-       return lay.name() == emptyLayoutName();
+       return layout.name() == plainLayoutName();
 }
 
 
+Layout TextClass::createBasicLayout(docstring const & name, bool unknown) const
+{
+       static Layout * defaultLayout = NULL;
+
+       if (defaultLayout) {
+               defaultLayout->setUnknown(unknown);
+               defaultLayout->setName(name);
+               return *defaultLayout;
+       }
+
+       static char const * s = "Margin Static\n"
+                       "LatexType Paragraph\n"
+                       "LatexName dummy\n"
+                       "Align Block\n"
+                       "AlignPossible Left, Right, Center\n"
+                       "LabelType No_Label\n"
+                       "End";
+       istringstream ss(s);
+       Lexer lex(textClassTags);
+       lex.setStream(ss);
+       defaultLayout = new Layout;
+       defaultLayout->setUnknown(unknown);
+       defaultLayout->setName(name);
+       if (!readStyle(lex, *defaultLayout)) {
+               // The only way this happens is because the hardcoded layout above
+               // is wrong.
+               LASSERT(false, /**/);
+       };
+       return *defaultLayout;
+}
+
+/////////////////////////////////////////////////////////////////////////
+//
+// DocumentClassBundle
+//
+/////////////////////////////////////////////////////////////////////////
+
+DocumentClassBundle::~DocumentClassBundle()
+{
+       for (size_t i = 0; i != documentClasses_.size(); ++i)
+               delete documentClasses_[i];
+       documentClasses_.clear();
+}
+
 DocumentClass & DocumentClassBundle::newClass(LayoutFile const & baseClass)
 {
        DocumentClass * dc = new DocumentClass(baseClass);
-       tc_list_.push_back(dc);
-       return *tc_list_.back();
+       documentClasses_.push_back(dc);
+       return *documentClasses_.back();
 }
 
 
@@ -1059,6 +1107,12 @@ DocumentClassBundle & DocumentClassBundle::get()
 }
 
 
+/////////////////////////////////////////////////////////////////////////
+//
+// DocumentClass
+//
+/////////////////////////////////////////////////////////////////////////
+
 DocumentClass::DocumentClass(LayoutFile const & tc)
        : TextClass(tc)
 {}
@@ -1087,6 +1141,12 @@ bool DocumentClass::hasTocLevels() const
 }
 
 
+/////////////////////////////////////////////////////////////////////////
+//
+// PageSides
+//
+/////////////////////////////////////////////////////////////////////////
+
 ostream & operator<<(ostream & os, PageSides p)
 {
        switch (p) {