]> git.lyx.org Git - lyx.git/blobdiff - src/BaseClassList.cpp
* cosmetic
[lyx.git] / src / BaseClassList.cpp
index 8baa64abf5886445757a8b3d53b69f3154d1e22d..35decb3f5dade4b1b117a1198da5b6b1a4198c8f 100644 (file)
 #include <config.h>
 
 #include "BaseClassList.h"
-#include "TextClass.h"
+#include "Counters.h"
+#include "Floating.h"
+#include "FloatList.h"
 #include "Lexer.h"
+#include "TextClass.h"
 
 #include "support/debug.h"
 #include "support/FileName.h"
 #include "support/filetools.h"
+#include "support/gettext.h"
 
 #include <boost/bind.hpp>
 #include <boost/regex.hpp>
@@ -33,52 +37,48 @@ using boost::bind;
 using boost::regex;
 using boost::smatch;
 
-// Gets textclass number from name
-pair<bool, BaseClassIndex> const
-BaseClassList::numberOfClass(string const & textclass) const
+LayoutFile::LayoutFile(string const & fn, string const & cln,
+                          string const & desc, bool texClassAvail )
 {
-       ClassList::const_iterator cit =
-               find_if(classlist_.begin(), classlist_.end(),
-                       bind(equal_to<string>(),
-                            bind(&TextClass::name, _1),
-                            textclass));
-
-       return cit != classlist_.end() ?
-               make_pair(true, BaseClassIndex(cit - classlist_.begin())) :
-               make_pair(false, BaseClassIndex(0));
+       name_ = fn;
+       latexname_ = cln;
+       description_ = desc;
+       texClassAvail_ = texClassAvail;
 }
 
 
-// Gets a textclass structure from number
-TextClass const &
-BaseClassList::operator[](BaseClassIndex textclass) const
+BaseClassList & BaseClassList::get() 
 {
-       if (textclass >= classlist_.size())
-               return classlist_[0];
-       
-       //FIXME I don't believe the following line is actually necessary (rgh)
-       classlist_[textclass].load();
-       return classlist_[textclass];
+       static BaseClassList baseclasslist;
+       return baseclasslist;
 }
 
 
-// used when sorting the textclass list.
-class less_textclass_avail_desc
-       : public binary_function<TextClass, TextClass, int>
+bool BaseClassList::haveClass(string const & classname) const
 {
-public:
-       int operator()(TextClass const & tc1,
-                      TextClass const & tc2) const
-       {
-               // Ordering criteria:
-               //   1. Availability of text class
-               //   2. Description (lexicographic)
-
-               return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
-                       (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
-                        tc1.description() < tc2.description());
+       ClassMap::const_iterator it = classmap_.begin();
+       ClassMap::const_iterator en = classmap_.end();
+       for (; it != en; ++it) {
+               if (it->first == classname)
+                       return true;
        }
-};
+       return false;
+}
+
+
+LayoutFile const & BaseClassList::operator[](string const & classname) const
+{
+       BOOST_ASSERT(haveClass(classname));
+       return classmap_[classname];
+}
+
+
+LayoutFile & 
+       BaseClassList::operator[](string const & classname)
+{
+       BOOST_ASSERT(haveClass(classname));
+       return classmap_[classname];
+}
 
 
 // Reads LyX textclass definitions according to textclass config file
@@ -139,13 +139,13 @@ bool BaseClassList::read()
                                                LYXERR(Debug::TCLASS, "Avail: " << avail);
                                                // This code is run when we have
                                                // fname, clname, desc, and avail
-                                               TextClass tmpl(fname, clname, desc, avail);
+                                               LayoutFile tmpl(fname, clname, desc, avail);
                                                if (lyxerr.debugging(Debug::TCLASS)) {
                                                        // only system layout files are loaded here so no
                                                        // buffer path is needed.
                                                        tmpl.load();
                                                }
-                                               classlist_.push_back(tmpl);
+                                               classmap_[fname] = tmpl;
                                        }
                                }
                        }
@@ -153,35 +153,55 @@ bool BaseClassList::read()
        }
        LYXERR(Debug::TCLASS, "End of parsing of textclass.lst");
 
-       // lyx will start with an empty classlist_, but only reconfigure is allowed
+       // lyx will start with an empty classmap_, but only reconfigure is allowed
        // in this case. This gives users a second chance to configure lyx if
        // initial configuration fails. (c.f. bug 2829)
-       if (classlist_.empty())
+       if (classmap_.empty())
                lyxerr << "BaseClassList::Read: no textclasses found!"
                       << endl;
-       else 
-               // Ok everything loaded ok, now sort the list.
-               sort(classlist_.begin(), classlist_.end(), less_textclass_avail_desc());
        return true;
 }
 
 
-void BaseClassList::reset(BaseClassIndex const textclass) {
-       if (textclass >= classlist_.size())
-               return;
-       TextClass const & tc = classlist_[textclass];
-       TextClass tmpl(tc.name(), tc.latexname(), tc.description(), 
+std::vector<LayoutFileIndex> BaseClassList::classList() const
+{
+       std::vector<LayoutFileIndex> cl;
+       ClassMap::const_iterator it = classmap_.begin();
+       ClassMap::const_iterator en = classmap_.end();
+       for (; it != en; ++it)
+               cl.push_back(it->first);
+       return cl;
+}
+
+
+void BaseClassList::reset(LayoutFileIndex const & classname) {
+       BOOST_ASSERT(haveClass(classname));
+       LayoutFile const & tc = classmap_[classname];
+       LayoutFile tmpl(tc.name(), tc.latexname(), tc.description(),
                       tc.isTeXClassAvailable());
-       classlist_[textclass] = tmpl;
+       classmap_[classname] = tmpl;
 }
 
 
-pair<bool, BaseClassIndex> const
-BaseClassList::addTextClass(string const & textclass, string const & path)
+string const BaseClassList::localPrefix = "LOCAL:";
+
+
+LayoutFileIndex 
+       BaseClassList::addLayoutFile(string const & textclass, string const & path)
 {
+       // FIXME  There is a bug here: 4593
+       //
        // only check for textclass.layout file, .cls can be anywhere in $TEXINPUTS
-       // NOTE: latex class name is defined in textclass.layout, which can be different from textclass
-       FileName const layout_file(addName(path, textclass + ".layout"));
+       // NOTE: latex class name is defined in textclass.layout, which can be 
+       // different from textclass
+       string fullName = addName(path, textclass + ".layout");
+       string localIndex = localPrefix + fullName;
+       
+       // if the local file has already been loaded, return it
+       if (haveClass(localIndex))
+               return localIndex;
+
+       FileName const layout_file(fullName);
        if (layout_file.exists()) {
                LYXERR(Debug::TCLASS, "Adding class " << textclass << " from directory " << path);
                // Read .layout file and get description, real latex classname etc
@@ -197,45 +217,31 @@ BaseClassList::addTextClass(string const & textclass, string const & path)
                        // look for the \DeclareXXXClass line
                        smatch sub;
                        if (regex_match(line, sub, reg)) {
-                               // returns: whole string, classtype (not used here), first option, description
-                               BOOST_ASSERT(sub.size()==4);
+                               // returns: whole string, classtype (not used here), class name, description
+                               BOOST_ASSERT(sub.size() == 4);
                                // now, create a TextClass with description containing path information
-                               TextClass tmpl(textclass, sub.str(2)==""?textclass:sub.str(2),
+                               LayoutFile tmpl(textclass, sub.str(2) == "" ? textclass : sub.str(2),
                                        sub.str(3) + " <" + path + ">", true);
-                               if (lyxerr.debugging(Debug::TCLASS))
-                                       tmpl.load(path);
-                               // Do not add this local TextClass to classlist_ if it has
-                               // already been loaded by, for example, a master buffer.
-                               pair<bool, lyx::BaseClassIndex> pp =
-                                       baseclasslist.numberOfClass(textclass);
-                               // only layouts from the same directory are considered to be identical.
-                               if (pp.first && classlist_[pp.second].description() == tmpl.description())
-                                       return pp;
-                               classlist_.push_back(tmpl);
+                               classmap_[localIndex] = tmpl;
                                // This textclass is added on request so it will definitely be
                                // used. Load it now because other load() calls may fail if they
                                // are called in a context without buffer path information.
-                               classlist_.back().load(path);
-                               return make_pair(true, classlist_.size() - 1);
+                               classmap_[localIndex].load(path);
+                               return localIndex;
                        }
                }
        }
-       // If .layout is not in local directory, or an invalid layout is found, return false
-       return make_pair(false, BaseClassIndex(0));
+       // If .layout is not in local directory, or an invalid layout is found, return null
+       return string("");
 }
 
 
-// Global variable: textclass table.
-BaseClassList baseclasslist;
-
-
-BaseClassIndex defaultBaseclass()
+LayoutFileIndex defaultBaseclass()
 {
-       // We want to return the article class. if `first' is
-       // true in the returned pair, then `second' is the textclass
-       // number; if it is false, second is 0. In both cases, second
-       // is what we want.
-       return baseclasslist.numberOfClass("article").second;
+       if (BaseClassList::get().haveClass("article"))
+               return string("article");
+       else 
+               return string("");
 }
 
 
@@ -245,7 +251,7 @@ bool LyXSetStyle()
 {
        LYXERR(Debug::TCLASS, "LyXSetStyle: parsing configuration...");
 
-       if (!baseclasslist.read()) {
+       if (!BaseClassList::get().read()) {
                LYXERR(Debug::TCLASS, "LyXSetStyle: an error occured "
                        "during parsing.\n             Exiting.");
                return false;