]> git.lyx.org Git - features.git/commitdiff
More work towards type safety regarding TextClass's. A couple bugs have been fixed...
authorRichard Heck <rgheck@comcast.net>
Thu, 28 Feb 2008 21:04:55 +0000 (21:04 +0000)
committerRichard Heck <rgheck@comcast.net>
Thu, 28 Feb 2008 21:04:55 +0000 (21:04 +0000)
Note that we no longer rely upon BaseClassList to be sorted. This would allow layout descriptions---such as "article (AMS)"---to be translated, and the ordering of the list in Document>Settings will then follow the translations.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23334 a592a061-630c-0410-9148-cb99ea01b6c8

src/BaseClassList.cpp
src/BaseClassList.h
src/BufferParams.cpp
src/BufferParams.h
src/LyXFunc.cpp
src/frontends/qt4/GuiDocument.cpp
src/frontends/qt4/GuiDocument.h
src/frontends/qt4/GuiIdListModel.cpp
src/frontends/qt4/GuiIdListModel.h
src/insets/InsetInfo.cpp

index 535bb217997b83f2f562e2d296559ff1624b053c..5fd88b958267fbc818cc11db9e53109efee0354c 100644 (file)
@@ -40,54 +40,27 @@ BaseClassList & BaseClassList::get()
 }
 
 
-// Gets textclass number from name
-pair<bool, BaseClassIndex> const
-BaseClassList::numberOfClass(string const & textclass) const
+bool BaseClassList::haveClass(string const & classname) const
 {
-       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));
+       ClassMap::const_iterator it = classmap_.begin();
+       ClassMap::const_iterator en = classmap_.end();
+       for (; it != en; ++it) {
+               if (it->first == classname)
+                       return true;
+       }
+       return false;
 }
 
 
-// Gets a textclass structure from number
-TextClass const &
-BaseClassList::operator[](BaseClassIndex textclass) const
+// Gets a textclass structure from string
+TextClass const & 
+       BaseClassList::operator[](string const & classname) const
 {
-       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];
+       BOOST_ASSERT(haveClass(classname));
+       return classmap_[classname];
 }
 
 
-// used when sorting the textclass list.
-class less_textclass_avail_desc
-       : public binary_function<TextClass, TextClass, int>
-{
-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());
-       }
-};
-
-
 // Reads LyX textclass definitions according to textclass config file
 bool BaseClassList::read()
 {
@@ -152,7 +125,7 @@ bool BaseClassList::read()
                                                        // buffer path is needed.
                                                        tmpl.load();
                                                }
-                                               classlist_.push_back(tmpl);
+                                               classmap_[fname] = tmpl;
                                        }
                                }
                        }
@@ -160,35 +133,64 @@ 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];
+std::vector<BaseClassIndex> BaseClassList::classList() const
+{
+       std::vector<BaseClassIndex> 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(BaseClassIndex const & classname) {
+       BOOST_ASSERT(haveClass(classname));
+       TextClass const & tc = classmap_[classname];
        TextClass 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:";
+
+
+BaseClassIndex 
+       BaseClassList::addTextClass(string const & textclass, string const & path)
 {
+       // FIXME BUGS
+       // There be bugs here. The way this presently works, the local class gets 
+       // added to the global list of available document classes. It will then
+       // appear on the list in Document>Settings, where it could be chosen in, 
+       // say, a new document, with no real warning that the class may not be
+       // available when the document is saved, since the new document may not be
+       // in the same directory as the layout file.
+       //
+       // Another bug is this: If the Document>Settings dialog is open when a file
+       // with a local layout is opened, the dialog doesn't update.
+       //
        // 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 + textclass;
+
+       // 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
@@ -209,36 +211,34 @@ BaseClassList::addTextClass(string const & textclass, string const & path)
                                // now, create a TextClass with description containing path information
                                TextClass 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
+                               // Do not add this local TextClass to classmap_ if it has
                                // already been loaded by, for example, a master buffer.
-                               pair<bool, lyx::BaseClassIndex> pp = 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);
+                               if (haveClass(textclass)
+                                               // FIXME I don't understand this comment (rgh)
+                                               // only layouts from the same directory are considered to be identical.
+                                               && classmap_[textclass].description() == tmpl.description()
+                                  )
+                                       return textclass;
+                               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("");
 }
 
 
-
 BaseClassIndex 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::get().numberOfClass("article").second;
+       if (BaseClassList::get().haveClass("article"))
+               return string("article");
+       else 
+               return string("");
 }
 
 
index cd873ccbe668e13e3a57210bd9d2bd5858094759..fc03d7db74ec4ad9ae5724e0f7c0a09c5b67ac22 100644 (file)
@@ -26,11 +26,12 @@ class Layout;
 /// Reads the style files
 extern bool LyXSetStyle();
 
+
 /// Index into BaseClassList. Basically a 'strong typedef'.
 class BaseClassIndex {
 public:
        ///
-       typedef size_t   base_type;
+       typedef std::string base_type;
        ///
        BaseClassIndex(base_type t) { data_ = t; }
        ///
@@ -40,6 +41,7 @@ private:
        base_type data_;
 };
 
+
 /// A list of base document classes (*.layout files).
 /// This is a singleton class. The sole instance is accessed
 /// via BaseClassList::get()
@@ -50,42 +52,33 @@ public:
        /// \return The sole instance of this class.
        static BaseClassList & get();
        ///
-       typedef std::vector<TextClass> ClassList;
-       ///
-       typedef ClassList::const_iterator const_iterator;
+       bool empty() const { return classmap_.empty(); }
        ///
-       const_iterator begin() const { return classlist_.begin(); }
-       ///
-       const_iterator end() const { return classlist_.end(); }
-       ///
-       bool empty() const { return classlist_.empty(); }
-
-       /// Gets textclass number from name, -1 if textclass name does not exist
-       std::pair<bool, BaseClassIndex> const
-               numberOfClass(std::string const & textclass) const;
-
+       bool haveClass(std::string const & classname) const;
        ///
-       TextClass const & operator[](BaseClassIndex textclass) const;
-
+       TextClass const & operator[](std::string const & classname) const;
        /// Read textclass list.  Returns false if this fails.
        bool read();
-       
        /// Clears the textclass so as to force it to be reloaded
-       void reset(BaseClassIndex const textclass);
-
+       void reset(BaseClassIndex const & tc);
        /// add a textclass from user local directory.
-       /// Return ture/false, and textclass number
-       std::pair<bool, BaseClassIndex> const
+       /// \return the identifier for the loaded file, or else an
+       /// empty string if no file was loaded.
+       BaseClassIndex
                addTextClass(std::string const & textclass, std::string const & path);
-
+       /// a list of the available classes
+       std::vector<BaseClassIndex> classList() const;
+       /// 
+       static std::string const localPrefix;
 private:
+       ///
+       typedef std::map<std::string, TextClass> ClassMap;
        /// noncopyable
        BaseClassList(BaseClassList const &);
        /// nonassignable
        void operator=(BaseClassList const &);
-
        ///
-       mutable ClassList classlist_;
+       mutable ClassMap classmap_; //FIXME
 };
 
 ///
index 15c7d8a72b78a8b558f37b8ca83db38d73d2d9aa..3425efe4f3ab0783dcf06a3f86a31d6a1bc9fb0f 100644 (file)
@@ -288,7 +288,7 @@ public:
 
 
 BufferParams::Impl::Impl()
-       : defskip(VSpace::MEDSKIP), baseClass_(0)
+       : defskip(VSpace::MEDSKIP), baseClass_(string(""))
 {
        // set initial author
        // FIXME UNICODE
@@ -463,22 +463,18 @@ string const BufferParams::readToken(Lexer & lex, string const & token,
                string const classname = lex.getString();
                // if there exists a local layout file, ignore the system one
                // NOTE: in this case, the textclass (.cls file) is assumed to be available.
-               pair<bool, lyx::BaseClassIndex> pp =
-                       make_pair(false, BaseClassIndex(0));
+               string tcp;
+               BaseClassList & bcl = BaseClassList::get();
                if (!filepath.empty())
-                       pp = BaseClassList::get().addTextClass(
-                               classname, filepath.absFilename());
-               if (pp.first)
-                       setBaseClass(pp.second);
-               else {
-                       pp = BaseClassList::get().numberOfClass(classname);
-                       if (pp.first)
-                               setBaseClass(pp.second);
-                       else {
-                               // a warning will be given for unknown class
-                               setBaseClass(defaultBaseclass());
-                               return classname;
-                       }
+                       tcp = bcl.addTextClass(classname, filepath.absFilename());
+               if (!tcp.empty())
+                       setBaseClass(tcp);
+               else if (bcl.haveClass(classname)) {
+                       setBaseClass(classname);
+               } else {
+                       // a warning will be given for unknown class
+                       setBaseClass(defaultBaseclass());
+                       return classname;
                }
                // FIXME: this warning will be given even if there exists a local .cls
                // file. Even worse, the .lyx file can not be compiled or exported
@@ -678,7 +674,7 @@ void BufferParams::writeFile(ostream & os) const
        // Prints out the buffer info into the .lyx file given by file
 
        // the textclass
-       os << "\\textclass " << BaseClassList::get()[pimpl_->baseClass_].name() << '\n';
+       os << "\\textclass " << baseClass()->name() << '\n';
 
        // then the preamble
        if (!preamble.empty()) {
@@ -1344,7 +1340,7 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
 
 void BufferParams::useClassDefaults()
 {
-       TextClass const & tclass = BaseClassList::get()[pimpl_->baseClass_];
+       DocumentClass const & tclass = documentClass();
 
        sides = tclass.sides();
        columns = tclass.columns();
@@ -1360,7 +1356,7 @@ void BufferParams::useClassDefaults()
 
 bool BufferParams::hasClassDefaults() const
 {
-       TextClass const & tclass = BaseClassList::get()[pimpl_->baseClass_];
+       DocumentClass const & tclass = documentClass();
 
        return sides == tclass.sides()
                && columns == tclass.columns()
@@ -1388,22 +1384,45 @@ void BufferParams::setDocumentClass(DocumentClass const * const tc) {
 }
 
 
-bool BufferParams::setBaseClass(BaseClassIndex tc)
+bool BufferParams::setBaseClass(string const & classname)
 {
-       if (BaseClassList::get()[tc].load()) {
-               pimpl_->baseClass_ = tc;
+       string localtc = classname;
+       BaseClassList const & bcl = BaseClassList::get();
+       if (!bcl.haveClass(localtc)) {
+               // OK, let's try again assuming it's a local file
+               localtc = BaseClassList::localPrefix + localtc;
+               if (!bcl.haveClass(localtc)) {
+                       docstring s = 
+                               bformat(_("The document class %1$s could not be found."),
+                               from_utf8(classname));
+                       frontend::Alert::error(_("Class not found"), s);
+                       return false;
+               }
+       }
+
+       if (bcl[localtc].load()) {
+               pimpl_->baseClass_ = localtc;
                return true;
        }
        
        docstring s = 
                bformat(_("The document class %1$s could not be loaded."),
-               from_utf8(BaseClassList::get()[tc].name()));
+               from_utf8(classname));
        frontend::Alert::error(_("Could not load class"), s);
        return false;
 }
 
 
-BaseClassIndex BufferParams::baseClass() const
+TextClass const * BufferParams::baseClass() const
+{
+       if (BaseClassList::get().haveClass(pimpl_->baseClass_))
+               return &(BaseClassList::get()[pimpl_->baseClass_]);
+       else 
+               return 0;
+}
+
+
+BaseClassIndex const & BufferParams::baseClassID() const
 {
        return pimpl_->baseClass_;
 }
@@ -1411,7 +1430,10 @@ BaseClassIndex BufferParams::baseClass() const
 
 void BufferParams::makeDocumentClass()
 {
-       doc_class_ = &(DocumentClassBundle::get().newClass(BaseClassList::get()[baseClass()]));
+       if (!baseClass())
+               return;
+
+       doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
        
        //FIXME It might be worth loading the children's modules here,
        //just as we load their bibliographies and such, instead of just 
index c8fe76fe63cbb50a476b3ce848a9c38111ca1d4b..6d5b0234f1e291fcbc770c975b7e9640676c5981 100644 (file)
@@ -107,11 +107,14 @@ public:
        ///
        std::string fontsize;
        ///Get the LyX TextClass (that is, the layout file) this document is using.
-       BaseClassIndex baseClass() const;
+       TextClass const * baseClass() const;
+       ///
+       BaseClassIndex const & baseClassID() const;
        /// Set the LyX TextClass (that is, the layout file) this document is using.
        /// NOTE: This does not call makeDocumentClass() to update the local 
        /// DocumentClass. That needs to be done manually.
-       bool setBaseClass(BaseClassIndex);
+       /// \param filename the name of the layout file
+       bool setBaseClass(std::string const & classname);
        /// Adds the module information to the baseClass information to
        /// create our local DocumentClass.
        void makeDocumentClass();
index d3dbc7f0822875910b0554a844bd84274aa41785..d94fe1b360a6ab57f2ac3f638b89be593da91225 100644 (file)
@@ -715,26 +715,23 @@ void showPrintError(string const & name)
 }
 
 
-void loadTextClass(string const & name, string const & buf_path)
+bool loadTextClass(string const & name, string const & buf_path)
 {
-       pair<bool, BaseClassIndex> const tc_pair =
-               BaseClassList::get().numberOfClass(name);
-
-       if (!tc_pair.first) {
+       if (!BaseClassList::get().haveClass(name)) {
                lyxerr << "Document class \"" << name
                       << "\" does not exist."
                       << endl;
-               return;
+               return false;
        }
 
-       BaseClassIndex const tc = tc_pair.second;
-
-       if (!BaseClassList::get()[tc].load(buf_path)) {
+       TextClass const & tc = BaseClassList::get()[name];
+       if (!tc.load(buf_path)) {
                docstring s = bformat(_("The document class %1$s."
-                                  "could not be loaded."),
-                                  from_utf8(BaseClassList::get()[tc].name()));
+                                  "could not be loaded."), from_utf8(name));
                Alert::error(_("Could not load class"), s);
+               return false;
        }
+       return true;
 }
 
 
@@ -1608,27 +1605,22 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                        BOOST_ASSERT(lyx_view_);
                        Buffer * buffer = lyx_view_->buffer();
 
-                       loadTextClass(argument, buffer->filePath());
-
-                       pair<bool, BaseClassIndex> const tc_pair =
-                               BaseClassList::get().numberOfClass(argument);
-
-                       if (!tc_pair.first)
+                       if (!loadTextClass(argument, buffer->filePath()))
                                break;
 
-                       BaseClassIndex const old_class = buffer->params().baseClass();
-                       BaseClassIndex const new_class = tc_pair.second;
+                       TextClass const * old_class = buffer->params().baseClass();
+                       TextClass const * new_class = &(BaseClassList::get()[argument]);
 
                        if (old_class == new_class)
                                // nothing to do
                                break;
 
                        //Save the old, possibly modular, layout for use in conversion.
-                       DocumentClass * oldClass = buffer->params().documentClassPtr();
+                       DocumentClass * oldDocClass = buffer->params().documentClassPtr();
                        view()->cursor().recordUndoFullDocument();
-                       buffer->params().setBaseClass(new_class);
+                       buffer->params().setBaseClass(argument);
                        buffer->params().makeDocumentClass();
-                       updateLayout(oldClass, buffer);
+                       updateLayout(oldDocClass, buffer);
                        updateFlags = Update::Force | Update::FitCursor;
                        break;
                }
@@ -1637,9 +1629,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                        BOOST_ASSERT(lyx_view_);
                        Buffer * buffer = lyx_view_->buffer();
                        DocumentClass * oldClass = buffer->params().documentClassPtr();
-                       BaseClassIndex const tc = buffer->params().baseClass();
-                       BaseClassList::get().reset(tc);
-                       buffer->params().setBaseClass(tc);
+                       BaseClassIndex bc = buffer->params().baseClassID();
+                       BaseClassList::get().reset(bc);
                        buffer->params().makeDocumentClass();
                        updateLayout(oldClass, buffer);
                        updateFlags = Update::Force | Update::FitCursor;
index 30e4a46c55fad8f26872c22dad00f2a0e8e2600c..2bffddda12fd367a5387518acb6cb7e89fe0a1c0 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "insets/InsetListingsParams.h"
 
+#include "support/debug.h"
 #include "support/FileName.h"
 #include "support/filetools.h"
 #include "support/lstrings.h"
@@ -61,6 +62,7 @@ using namespace std;
 using namespace lyx::support;
 
 
+namespace {
 ///
 template<class Pair>
 vector<typename Pair::second_type> const
@@ -135,7 +137,31 @@ char const * tex_fonts_monospaced_gui[] =
 vector<pair<string, lyx::docstring> > pagestyles;
 
 
+} // anonymous namespace
+
 namespace lyx {
+
+namespace {
+// used when sorting the textclass list.
+class less_textclass_avail_desc
+       : public binary_function<string, string, int>
+{
+public:
+       int operator()(string const & lhs, string const & rhs) const
+       {
+               // Ordering criteria:
+               //   1. Availability of text class
+               //   2. Description (lexicographic)
+               TextClass const & tc1 = BaseClassList::get()[lhs];
+               TextClass const & tc2 = BaseClassList::get()[rhs];
+               return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
+                       (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
+                        _(tc1.description()) < _(tc2.description()));
+       }
+};
+
+}
+
 namespace frontend {
 
 
@@ -489,7 +515,6 @@ void PreambleModule::closeEvent(QCloseEvent * e)
 /////////////////////////////////////////////////////////////////////
 
 
-
 GuiDocument::GuiDocument(GuiView & lv)
        : GuiDialog(lv, "document", qt_("Document Settings")), current_id_(0)
 {
@@ -879,15 +904,19 @@ GuiDocument::GuiDocument(GuiView & lv)
        //FIXME This seems too involved with the kernel. Some of this
        //should be moved to the kernel---which should perhaps just
        //give us a list of entries or something of the sort.
-       for (BaseClassList::const_iterator cit = BaseClassList::get().begin();
-            cit != BaseClassList::get().end(); ++cit) {
-               if (cit->isTeXClassAvailable()) {
-                       latexModule->classCO->addItem(toqstr(cit->description()));
-               } else {
-                       docstring item =
-                               bformat(_("Unavailable: %1$s"), from_utf8(cit->description()));
-                       latexModule->classCO->addItem(toqstr(item));
-               }
+       latexModule->classCO->setModel(&classes_model_);
+       BaseClassList const & bcl = BaseClassList::get();
+       vector<BaseClassIndex> classList = bcl.classList();
+       sort(classList.begin(), classList.end(), less_textclass_avail_desc());
+
+       vector<BaseClassIndex>::const_iterator cit  = classList.begin();
+       vector<BaseClassIndex>::const_iterator cen = classList.end();
+       for (int i = 0; cit != cen; ++cit, ++i) {
+               TextClass const & tc = bcl[*cit];
+               docstring item = (tc.isTeXClassAvailable()) ?
+                       from_utf8(tc.description()) :
+                       bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
+               classes_model_.insertRow(i, toqstr(item), tc.name());
        }
 
        // branches
@@ -1212,8 +1241,14 @@ void GuiDocument::updatePagestyle(string const & items, string const & sel)
 
 void GuiDocument::classChanged()
 {
-       BaseClassIndex const tc = latexModule->classCO->currentIndex();
-       bp_.setBaseClass(tc);
+       int idx = latexModule->classCO->currentIndex();
+       if (idx < 0) 
+               return;
+       string const classname = classes_model_.getIDString(idx);
+       if (!bp_.setBaseClass(classname)) {
+               Alert::error(_("Error"), _("Unable to set document class."));
+               return;
+       }
        if (lyxrc.auto_reset_options) {
                if (applyPB->isEnabled()) {
                        int const ret = Alert::prompt(_("Unapplied changes"),
@@ -1287,7 +1322,7 @@ void GuiDocument::updateModuleInfo()
        }
        QModelIndex const & idx = lv->selectionModel()->currentIndex();
        GuiIdListModel const & idModel = 
-                       focusOnSelected  ? selected_model_ : available_model_;
+                       focusOnSelected  ? modules_sel_model_ : modules_av_model_;
        string const modName = idModel.getIDString(idx.row());
        docstring desc = getModuleDescription(modName);
 
@@ -1457,14 +1492,18 @@ void GuiDocument::apply(BufferParams & params)
                tex_graphics[latexModule->psdriverCO->currentIndex()];
        
        // text layout
-       params.setBaseClass(latexModule->classCO->currentIndex());
+       int idx = latexModule->classCO->currentIndex();
+       if (idx >= 0) {
+               string const classname = classes_model_.getIDString(idx);
+               params.setBaseClass(classname);
+       }
 
        // Modules
        params.clearLayoutModules();
-       int const srows = selected_model_.rowCount();
+       int const srows = modules_sel_model_.rowCount();
        vector<string> selModList;
        for (int i = 0; i < srows; ++i)
-               params.addLayoutModule(selected_model_.getIDString(i));
+               params.addLayoutModule(modules_sel_model_.getIDString(i));
 
        if (mathsModule->amsautoCB->isChecked()) {
                params.use_amsmath = BufferParams::package_auto;
@@ -1746,9 +1785,9 @@ void GuiDocument::updateParams(BufferParams const & params)
        langModule->otherencodingRB->setChecked(!default_enc);
 
        // numbering
-       int const min_toclevel = textClass().min_toclevel();
-       int const max_toclevel = textClass().max_toclevel();
-       if (textClass().hasTocLevels()) {
+       int const min_toclevel = documentClass().min_toclevel();
+       int const max_toclevel = documentClass().max_toclevel();
+       if (documentClass().hasTocLevels()) {
                numberingModule->setEnabled(true);
                numberingModule->depthSL->setMinimum(min_toclevel - 1);
                numberingModule->depthSL->setMaximum(max_toclevel);
@@ -1793,9 +1832,14 @@ void GuiDocument::updateParams(BufferParams const & params)
        }
 
        // text layout
-       latexModule->classCO->setCurrentIndex(params.baseClass());
-       
-       updatePagestyle(textClass().opt_pagestyle(),
+       string const & classname = params.baseClass()->name();
+       int idx = classes_model_.findIDString(classname);
+       if (idx < 0)
+               lyxerr << "Unable to set layout for classname " << classname << std::endl;
+       else 
+               latexModule->classCO->setCurrentIndex(idx);
+
+       updatePagestyle(documentClass().opt_pagestyle(),
                                 params.pagestyle);
 
        textLayoutModule->lspacingCO->setCurrentIndex(nitem);
@@ -1855,7 +1899,7 @@ void GuiDocument::updateParams(BufferParams const & params)
        floatModule->set(params.float_placement);
 
        // Fonts
-       updateFontsize(textClass().opt_fontsize(),
+       updateFontsize(documentClass().opt_fontsize(),
                        params.fontsize);
 
        int n = findToken(tex_fonts_roman, params.fontsRoman);
@@ -1982,12 +2026,12 @@ void GuiDocument::saveDocDefault()
 
 void GuiDocument::updateAvailableModules() 
 {
-       available_model_.clear();
+       modules_av_model_.clear();
        vector<modInfoStruct> const modInfoList = getModuleInfo();
        int const mSize = modInfoList.size();
        for (int i = 0; i < mSize; ++i) {
                modInfoStruct const & modInfo = modInfoList[i];
-               available_model_.insertRow(i, qt_(modInfo.name), modInfo.id);
+               modules_av_model_.insertRow(i, qt_(modInfo.name), modInfo.id);
        }
 }
 
@@ -1995,12 +2039,12 @@ void GuiDocument::updateAvailableModules()
 void GuiDocument::updateSelectedModules() 
 {
        //and selected ones, too
-       selected_model_.clear();
+       modules_sel_model_.clear();
        vector<modInfoStruct> const selModList = getSelectedModules();
        int const sSize = selModList.size();
        for (int i = 0; i < sSize; ++i) {
                modInfoStruct const & modInfo = selModList[i];
-               selected_model_.insertRow(i, qt_(modInfo.name), modInfo.id);
+               modules_sel_model_.insertRow(i, qt_(modInfo.name), modInfo.id);
        }
 }
 
@@ -2041,7 +2085,12 @@ void GuiDocument::useClassDefaults()
                        applyView();
        }
 
-       bp_.setBaseClass(latexModule->classCO->currentIndex());
+       int idx = latexModule->classCO->currentIndex();
+       string const classname = classes_model_.getIDString(idx);
+       if (!bp_.setBaseClass(classname)) {
+               Alert::error(_("Error"), _("Unable to set document class."));
+               return;
+       }
        bp_.useClassDefaults();
        forceUpdate();
 }
@@ -2111,9 +2160,9 @@ vector<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
 }
 
 
-TextClass const & GuiDocument::textClass() const
+DocumentClass const & GuiDocument::documentClass() const
 {
-       return BaseClassList::get()[bp_.baseClass()];
+       return bp_.documentClass();
 }
 
 
index bc5dc1c4b0f76e74dd340b343b42e23a30d85dfb..188b72d10a6afb8083bc27c642f9ae362df733c5 100644 (file)
@@ -64,6 +64,7 @@ public:
 };
 
 
+/// SelectionManager for use with modules
 class ModuleSelMan : public GuiSelectionManager 
 {
 public:
@@ -98,9 +99,6 @@ private:
 };
 
 
-typedef void const * BufferId;
-
-
 class GuiDocument : public GuiDialog, public Ui::DocumentUi
 {
        Q_OBJECT
@@ -166,9 +164,9 @@ private:
        std::vector<std::string> lang_;
 
        /// Available modules
-       GuiIdListModel * availableModel() { return &available_model_; }
+       GuiIdListModel * availableModel() { return &modules_av_model_; }
        /// Selected modules
-       GuiIdListModel * selectedModel() { return &selected_model_; }
+       GuiIdListModel * selectedModel() { return &modules_sel_model_; }
 private:
        /// Apply changes
        void applyView();
@@ -184,10 +182,12 @@ private:
        void saveDocDefault();
        /// reset to default params
        void useClassDefaults();
+       /// available classes
+       GuiIdListModel classes_model_;
        /// available modules
-       GuiIdListModel available_model_;
+       GuiIdListModel modules_av_model_;
        /// selected modules
-       GuiIdListModel selected_model_;
+       GuiIdListModel modules_sel_model_;
        /// current buffer
        BufferId current_id_;
 
@@ -210,7 +210,7 @@ protected:
        /// always true since we don't manipulate document contents
        bool canApply() const { return true; }
        ///
-       TextClass const & textClass() const;
+       DocumentClass const & documentClass() const;
        ///
        BufferParams & params() { return bp_; }
        ///
index 658be130237e877c8bfc4a0f32db8ea0bff0ce8b..2d15b0efabf511c46c25b3660e67fbdbac4c8dcc 100644 (file)
@@ -93,7 +93,7 @@ void GuiIdListModel::insertRow(int const i, QString const & uiString,
 }
 
 
-QMap<int, QVariant> GuiIdListModel::itemData(QModelIndex const & index ) const
+QMap<int, QVariant> GuiIdListModel::itemData(QModelIndex const & index) const
 {
        int const row = index.row();
        if (!rowIsValid(row))
@@ -103,6 +103,18 @@ QMap<int, QVariant> GuiIdListModel::itemData(QModelIndex const & index ) const
        return qm;
 }
 
+
+int GuiIdListModel::findIDString(std::string const & idString) 
+{
+       vector<OurData>::const_iterator it  = userData_.begin();
+       vector<OurData>::const_iterator end = userData_.end();
+       for (; it != end; ++it)
+               if (fromqstr(it->idString.toString()) == idString)
+                       return it - userData_.begin();
+       return -1;
+}
+
+
 #if 0
 // The following functions are currently unused but are retained here in
 //   case they should at some point be useful.
@@ -126,15 +138,6 @@ void GuiIdListModel::insertRow(int const i, QString const & uiString,
        setIDString(i, idString);
 }
 
-bool GuiIdListModel::containsID(QVariant const & q) const
-{
-       vector<OurData>::const_iterator it  = userData_.begin();
-       vector<OurData>::const_iterator end = userData_.end();
-       for (; it != end; ++it)
-               if (it->idString == q)
-                       return true;
-       return false;
-}
 #endif
 
 } // namespace frontend
index 09906ff71b9ceca04e2275ffba12f9cfcb81923e..1879968d2b14abf1c167e6468c50ea35fcf12740 100644 (file)
@@ -85,8 +85,13 @@ public:
        ///
        void insertRow(int const i, QString const & uiString, 
                        std::string const & idString);
-       /* The following functions are currently unused but are retained here in
-          case they should at some point be useful.
+       /// \return the index of the (first) item with idString
+       /// \return -1 if not found
+       int findIDString(std::string const & idString);
+
+#if 0
+       //The following functions are currently unused but are retained here in
+       //case they should at some point be useful.
        ///
        void setUIString(int const i, std::string const & value)
                        { setUIString(index(i), value); }
@@ -101,9 +106,7 @@ public:
        ///
        void insertRow(int const i, std::string const & uiString, 
                        std::string const & idString);
-       /// Returns whether the model contains an item with the given ID
-       bool containsID(QVariant const &) const;
-       */
+#endif
 private:
        /// noncopyable
        GuiIdListModel(GuiIdListModel const &);
index 39a9517b4457db7dad3f435206d7d1ed9f6cd64e..44d3b5e0a7082c11c9d9229903758e6002f6c267 100644 (file)
@@ -202,9 +202,8 @@ void InsetInfo::updateInfo()
                break;
        case TEXTCLASS_INFO: {
                // name_ is the class name
-               pair<bool, lyx::BaseClassIndex> pp = BaseClassList::get().numberOfClass(name_);
-               setText(pp.first ? _("yes") : _("no"),
-                       bp.getFont(), false);
+               setText(BaseClassList::get().haveClass(name_) ? _("yes") : _("no"),
+               bp.getFont(), false);
                break;
        }
        case MENU_INFO: {