From 2b3bd7b5f4a8815427d05c6cc6aaf25b6b8ffba5 Mon Sep 17 00:00:00 2001 From: Richard Heck Date: Fri, 29 Feb 2008 02:45:33 +0000 Subject: [PATCH] This is the last of the commits that hopes to enforce the distinction between "layout files" and "document classes" that was introduced by the modules code. For the most part, these changes just refactor code from TextClass between: (a) a TextClass base class; (b) a LayoutFile subclass, which represents the information in a .layout file; and (c) a DocumentClass subclass, which represents the layout information associated with a Buffer---a LayoutFile plus Modules. Methods from TextClass have been apportioned between the three classes depending upon what is needed where, and signatures have been changed where necessary so that the right kind of class is required. At this point, there are no simple TextClass objects in the main LyX code, and it is impossible to create them, since the TextClass constructor is protected. Only LayoutFile and DocumentClass objects can be constructed, and for the most part these are constructed only by their respective containers: BaseClassList and DocumentClassBundle. There is an exception: LayoutFile does have a public default constructor, but if anyone knows how to make it go away, please do. There will be one or two more commits along these lines, but these will be simple renamings. For example, BaseClassList should be LayoutFileList. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23343 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BaseClassList.cpp | 47 ++-- src/BaseClassList.h | 43 +++- src/Buffer.cpp | 3 +- src/BufferParams.cpp | 10 +- src/BufferParams.h | 12 +- src/LyXFunc.cpp | 16 +- src/TextClass.cpp | 222 +++---------------- src/TextClass.h | 344 +++++++++++++++--------------- src/frontends/qt4/GuiDocument.cpp | 12 +- src/frontends/qt4/GuiToolbar.h | 4 +- src/insets/InsetCaption.cpp | 4 +- src/insets/InsetCaption.h | 4 - src/insets/InsetCollapsable.cpp | 4 +- src/tex2lyx/Context.cpp | 2 +- src/tex2lyx/Context.h | 6 +- src/tex2lyx/Makefile.am | 1 + src/tex2lyx/preamble.cpp | 5 +- src/tex2lyx/tex2lyx.cpp | 2 +- src/tex2lyx/tex2lyx.h | 6 +- 19 files changed, 314 insertions(+), 433 deletions(-) diff --git a/src/BaseClassList.cpp b/src/BaseClassList.cpp index 5fd88b9582..64e1f5b805 100644 --- a/src/BaseClassList.cpp +++ b/src/BaseClassList.cpp @@ -12,12 +12,16 @@ #include #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 #include @@ -33,6 +37,16 @@ using boost::bind; using boost::regex; using boost::smatch; +LayoutFile::LayoutFile(string const & fn, string const & cln, + string const & desc, bool texClassAvail ) +{ + name_ = fn; + latexname_ = cln; + description_ = desc; + texClassAvail_ = texClassAvail; +} + + BaseClassList & BaseClassList::get() { static BaseClassList baseclasslist; @@ -52,9 +66,16 @@ bool BaseClassList::haveClass(string const & classname) const } +LayoutFile const & BaseClassList::operator[](string const & classname) const +{ + BOOST_ASSERT(haveClass(classname)); + return classmap_[classname]; +} + + // Gets a textclass structure from string -TextClass const & - BaseClassList::operator[](string const & classname) const +LayoutFile & + BaseClassList::operator[](string const & classname) { BOOST_ASSERT(haveClass(classname)); return classmap_[classname]; @@ -119,7 +140,7 @@ 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. @@ -143,9 +164,9 @@ bool BaseClassList::read() } -std::vector BaseClassList::classList() const +std::vector BaseClassList::classList() const { - std::vector cl; + std::vector cl; ClassMap::const_iterator it = classmap_.begin(); ClassMap::const_iterator en = classmap_.end(); for (; it != en; ++it) @@ -154,10 +175,10 @@ std::vector BaseClassList::classList() const } -void BaseClassList::reset(BaseClassIndex const & classname) { +void BaseClassList::reset(LayoutFileIndex const & classname) { BOOST_ASSERT(haveClass(classname)); - TextClass const & tc = classmap_[classname]; - TextClass tmpl(tc.name(), tc.latexname(), tc.description(), + LayoutFile const & tc = classmap_[classname]; + LayoutFile tmpl(tc.name(), tc.latexname(), tc.description(), tc.isTeXClassAvailable()); classmap_[classname] = tmpl; } @@ -166,8 +187,8 @@ void BaseClassList::reset(BaseClassIndex const & classname) { string const BaseClassList::localPrefix = "LOCAL:"; -BaseClassIndex - BaseClassList::addTextClass(string const & textclass, string const & path) +LayoutFileIndex + BaseClassList::addLayoutFile(string const & textclass, string const & path) { // FIXME BUGS // There be bugs here. The way this presently works, the local class gets @@ -209,7 +230,7 @@ BaseClassIndex // 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); // Do not add this local TextClass to classmap_ if it has // already been loaded by, for example, a master buffer. @@ -233,7 +254,7 @@ BaseClassIndex } -BaseClassIndex defaultBaseclass() +LayoutFileIndex defaultBaseclass() { if (BaseClassList::get().haveClass("article")) return string("article"); diff --git a/src/BaseClassList.h b/src/BaseClassList.h index fc03d7db74..df3e6ddb18 100644 --- a/src/BaseClassList.h +++ b/src/BaseClassList.h @@ -28,12 +28,12 @@ extern bool LyXSetStyle(); /// Index into BaseClassList. Basically a 'strong typedef'. -class BaseClassIndex { +class LayoutFileIndex { public: /// typedef std::string base_type; /// - BaseClassIndex(base_type t) { data_ = t; } + LayoutFileIndex(base_type t) { data_ = t; } /// operator base_type() const { return data_; } /// @@ -41,6 +41,29 @@ private: base_type data_; }; +/// This class amounts to little more than a `strong typedef'. +/// A LayoutFile represents the layout information that is +/// contained in a *.layout file. +class LayoutFile : public TextClass { +public: + /// This should never be used, but it has to be provided for + /// std::map operator[] to work. Something like: + /// mapthingy[stuff] = otherthing + /// creates an empty object before doing the assignment. + LayoutFile() {} + /// check whether the TeX class is available + bool isTeXClassAvailable() const { return texClassAvail_; } +private: + /// Construct a layout with default values. Actual values loaded later. + explicit LayoutFile(std::string const &, + std::string const & = std::string(), + std::string const & = std::string(), + bool texClassAvail = false); + /// The only class that should create a LayoutFile is + /// BaseClassList, which calls the private constructor. + friend class BaseClassList; +}; + /// A list of base document classes (*.layout files). /// This is a singleton class. The sole instance is accessed @@ -56,23 +79,25 @@ public: /// bool haveClass(std::string const & classname) const; /// - TextClass const & operator[](std::string const & classname) const; + LayoutFile const & operator[](std::string const & classname) const; + /// + LayoutFile & operator[](std::string const & classname); /// 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 & tc); + void reset(LayoutFileIndex const & tc); /// add a textclass from user local directory. /// \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); + LayoutFileIndex + addLayoutFile(std::string const & textclass, std::string const & path); /// a list of the available classes - std::vector classList() const; + std::vector classList() const; /// static std::string const localPrefix; private: /// - typedef std::map ClassMap; + typedef std::map ClassMap; /// noncopyable BaseClassList(BaseClassList const &); /// nonassignable @@ -82,7 +107,7 @@ private: }; /// -BaseClassIndex defaultBaseclass(); +LayoutFileIndex defaultBaseclass(); } // namespace lyx diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 5310349c87..2ffe443302 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -14,6 +14,7 @@ #include "Buffer.h" #include "Author.h" +#include "BaseClassList.h" #include "BiblioInfo.h" #include "BranchList.h" #include "buffer_funcs.h" @@ -2535,7 +2536,7 @@ vector Buffer::exportableFormats(bool only_viewable) const vector Buffer::backends() const { vector v; - if (params().documentClass().isTeXClassAvailable()) { + if (params().baseClass()->isTeXClassAvailable()) { v.push_back(bufferFormat()); // FIXME: Don't hardcode format names here, but use a flag if (v.back() == "latex") diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 3425efe4f3..2fba2fb213 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -283,7 +283,7 @@ public: */ VSpace defskip; PDFOptions pdfoptions; - BaseClassIndex baseClass_; + LayoutFileIndex baseClass_; }; @@ -466,7 +466,7 @@ string const BufferParams::readToken(Lexer & lex, string const & token, string tcp; BaseClassList & bcl = BaseClassList::get(); if (!filepath.empty()) - tcp = bcl.addTextClass(classname, filepath.absFilename()); + tcp = bcl.addLayoutFile(classname, filepath.absFilename()); if (!tcp.empty()) setBaseClass(tcp); else if (bcl.haveClass(classname)) { @@ -479,7 +479,7 @@ string const BufferParams::readToken(Lexer & lex, string const & token, // 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 // because the textclass is marked as unavilable. - if (!documentClass().isTeXClassAvailable()) { + if (!baseClass()->isTeXClassAvailable()) { docstring const msg = bformat(_("The layout file requested by this document,\n" "%1$s.layout,\n" @@ -1413,7 +1413,7 @@ bool BufferParams::setBaseClass(string const & classname) } -TextClass const * BufferParams::baseClass() const +LayoutFile const * BufferParams::baseClass() const { if (BaseClassList::get().haveClass(pimpl_->baseClass_)) return &(BaseClassList::get()[pimpl_->baseClass_]); @@ -1422,7 +1422,7 @@ TextClass const * BufferParams::baseClass() const } -BaseClassIndex const & BufferParams::baseClassID() const +LayoutFileIndex const & BufferParams::baseClassID() const { return pimpl_->baseClass_; } diff --git a/src/BufferParams.h b/src/BufferParams.h index 6d5b0234f1..2aa2ef49a2 100644 --- a/src/BufferParams.h +++ b/src/BufferParams.h @@ -32,7 +32,7 @@ class FileName; } class AuthorList; -class BaseClassIndex; +class LayoutFileIndex; class BranchList; class Bullet; class DocumentClass; @@ -40,9 +40,9 @@ class Encoding; class Language; class Lexer; class LatexFeatures; +class LayoutFile; class PDFOptions; class Spacing; -class TextClass; class TexRow; class VSpace; @@ -106,11 +106,11 @@ public: InsetQuotes::quote_times quotes_times; /// std::string fontsize; - ///Get the LyX TextClass (that is, the layout file) this document is using. - TextClass const * baseClass() const; + ///Get the LayoutFile this document is using. + LayoutFile const * baseClass() const; /// - BaseClassIndex const & baseClassID() const; - /// Set the LyX TextClass (that is, the layout file) this document is using. + LayoutFileIndex const & baseClassID() const; + /// Set the LyX layout file this document is using. /// NOTE: This does not call makeDocumentClass() to update the local /// DocumentClass. That needs to be done manually. /// \param filename the name of the layout file diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index d94fe1b360..a6eb19eac9 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -715,7 +715,7 @@ void showPrintError(string const & name) } -bool loadTextClass(string const & name, string const & buf_path) +bool loadLayoutFile(string const & name, string const & buf_path) { if (!BaseClassList::get().haveClass(name)) { lyxerr << "Document class \"" << name @@ -724,7 +724,7 @@ bool loadTextClass(string const & name, string const & buf_path) return false; } - TextClass const & tc = BaseClassList::get()[name]; + LayoutFile & tc = BaseClassList::get()[name]; if (!tc.load(buf_path)) { docstring s = bformat(_("The document class %1$s." "could not be loaded."), from_utf8(name)); @@ -1605,13 +1605,13 @@ void LyXFunc::dispatch(FuncRequest const & cmd) BOOST_ASSERT(lyx_view_); Buffer * buffer = lyx_view_->buffer(); - if (!loadTextClass(argument, buffer->filePath())) + if (!loadLayoutFile(argument, buffer->filePath())) break; - TextClass const * old_class = buffer->params().baseClass(); - TextClass const * new_class = &(BaseClassList::get()[argument]); + LayoutFile const * old_layout = buffer->params().baseClass(); + LayoutFile const * new_layout = &(BaseClassList::get()[argument]); - if (old_class == new_class) + if (old_layout == new_layout) // nothing to do break; @@ -1629,7 +1629,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) BOOST_ASSERT(lyx_view_); Buffer * buffer = lyx_view_->buffer(); DocumentClass * oldClass = buffer->params().documentClassPtr(); - BaseClassIndex bc = buffer->params().baseClassID(); + LayoutFileIndex bc = buffer->params().baseClassID(); BaseClassList::get().reset(bc); buffer->params().makeDocumentClass(); updateLayout(oldClass, buffer); @@ -1638,7 +1638,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_TEXTCLASS_LOAD: - loadTextClass(argument, lyx_view_->buffer()->filePath()); + loadLayoutFile(argument, lyx_view_->buffer()->filePath()); break; case LFUN_LYXRC_APPLY: { diff --git a/src/TextClass.cpp b/src/TextClass.cpp index 1a7b0ab7eb..aa2f307330 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -16,6 +16,7 @@ #include "TextClass.h" +#include "BaseClassList.h" #include "Color.h" #include "Counters.h" #include "Floating.h" @@ -105,13 +106,16 @@ std::string translateRT(TextClass::ReadType rt) } // namespace anon -TextClass::TextClass(string const & fn, string const & cln, - string const & desc, bool texClassAvail ) - : name_(fn), latexname_(cln), description_(desc), - floatlist_(new FloatList), counters_(new Counters), - texClassAvail_(texClassAvail) +docstring const TextClass::emptylayout_ = from_ascii("PlainLayout"); + + +InsetLayout DocumentClass::empty_insetlayout_; + + +TextClass::TextClass() { - modular_ = false; + floatlist_ = boost::shared_ptr(new FloatList); + counters_ = boost::shared_ptr(new Counters); outputType_ = LATEX; columns_ = 1; sides_ = OneSide; @@ -130,18 +134,6 @@ TextClass::TextClass(string const & fn, string const & cln, } -docstring const TextClass::emptylayout_ = from_ascii("PlainLayout"); - - -InsetLayout TextClass::empty_insetlayout_; - - -bool TextClass::isTeXClassAvailable() const -{ - return texClassAvail_; -} - - bool TextClass::readStyle(Lexer & lexrc, Layout & lay) { LYXERR(Debug::TCLASS, "Reading style " << to_utf8(lay.name())); @@ -151,9 +143,9 @@ bool TextClass::readStyle(Lexer & lexrc, Layout & lay) } // Resolve fonts lay.resfont = lay.font; - lay.resfont.realize(defaultfont()); + lay.resfont.realize(defaultfont_); lay.reslabelfont = lay.labelfont; - lay.reslabelfont.realize(defaultfont()); + lay.reslabelfont.realize(defaultfont_); return true; // no errors } @@ -853,24 +845,6 @@ void TextClass::readCounter(Lexer & lexrc) } -FontInfo const & TextClass::defaultfont() const -{ - return defaultfont_; -} - - -docstring const & TextClass::leftmargin() const -{ - return leftmargin_; -} - - -docstring const & TextClass::rightmargin() const -{ - return rightmargin_; -} - - bool TextClass::hasLayout(docstring const & n) const { docstring const name = n.empty() ? defaultLayoutName() : n; @@ -949,32 +923,7 @@ bool TextClass::load(string const & path) const } -FloatList & TextClass::floats() -{ - return *floatlist_.get(); -} - - -FloatList const & TextClass::floats() const -{ - return *floatlist_.get(); -} - - -Counters & TextClass::counters() const -{ - return *counters_.get(); -} - - -// Return the layout object of an inset given by name. If the name -// is not found as such, the part after the ':' is stripped off, and -// searched again. In this way, an error fallback can be provided: -// An erroneous 'CharStyle:badname' (e.g., after a documentclass switch) -// will invoke the layout object defined by name = 'CharStyle'. -// If that doesn't work either, an empty object returns (shouldn't -// happen). -- Idea JMarc, comment MV -InsetLayout const & TextClass::insetLayout(docstring const & name) const +InsetLayout const & DocumentClass::insetLayout(docstring const & name) const { docstring n = name; while (!n.empty()) { @@ -1002,136 +951,7 @@ LayoutPtr const & TextClass::defaultLayout() const } -string const & TextClass::name() const -{ - return name_; -} - - -string const & TextClass::latexname() const -{ - // No buffer path information is needed here because on-demand layout files - // have already been loaded, and no path is needed for system layouts. - const_cast(this)->load(); - return latexname_; -} - - -string const & TextClass::description() const -{ - return description_; -} - - -string const & TextClass::opt_fontsize() const -{ - return opt_fontsize_; -} - - -string const & TextClass::opt_pagestyle() const -{ - return opt_pagestyle_; -} - - -string const & TextClass::options() const -{ - return options_; -} - - -string const & TextClass::class_header() const -{ - return class_header_; -} - - -string const & TextClass::pagestyle() const -{ - return pagestyle_; -} - - -docstring const & TextClass::preamble() const -{ - return preamble_; -} - - -PageSides TextClass::sides() const -{ - return sides_; -} - - -int TextClass::secnumdepth() const -{ - return secnumdepth_; -} - - -int TextClass::tocdepth() const -{ - return tocdepth_; -} - - -OutputType TextClass::outputType() const -{ - return outputType_; -} - - -bool TextClass::provides(string const & p) const -{ - return provides_.find(p) != provides_.end(); -} - - -unsigned int TextClass::columns() const -{ - return columns_; -} - - -TitleLatexType TextClass::titletype() const -{ - return titletype_; -} - - -string const & TextClass::titlename() const -{ - return titlename_; -} - - -int TextClass::size() const -{ - return layoutlist_.size(); -} - - -int TextClass::min_toclevel() const -{ - return min_toclevel_; -} - - -int TextClass::max_toclevel() const -{ - return max_toclevel_; -} - - -bool TextClass::hasTocLevels() const -{ - return min_toclevel_ != Layout::NOT_IN_TOC; -} - - -DocumentClass & DocumentClassBundle::newClass(TextClass const & baseClass) +DocumentClass & DocumentClassBundle::newClass(LayoutFile const & baseClass) { DocumentClass dc(baseClass); tc_list_.push_back(dc); @@ -1146,7 +966,7 @@ DocumentClassBundle & DocumentClassBundle::get() } -DocumentClass::DocumentClass(TextClass const & tc) +DocumentClass::DocumentClass(LayoutFile const & tc) : TextClass(tc) {} @@ -1162,6 +982,18 @@ bool DocumentClass::hasLaTeXLayout(std::string const & lay) const } +bool DocumentClass::provides(string const & p) const +{ + return provides_.find(p) != provides_.end(); +} + + +bool DocumentClass::hasTocLevels() const +{ + return min_toclevel_ != Layout::NOT_IN_TOC; +} + + ostream & operator<<(ostream & os, PageSides p) { switch (p) { diff --git a/src/TextClass.h b/src/TextClass.h index a8ad7e9933..6e2302db50 100644 --- a/src/TextClass.h +++ b/src/TextClass.h @@ -34,48 +34,56 @@ namespace support { class FileName; } class Counters; class FloatList; class Layout; +class LayoutFile; class Lexer; /// A TextClass represents a collection of layout information: At the /// moment, this includes Layout's and InsetLayout's. /// -/// The main function of TextClass objecs is to provide layout information -/// to a Buffer, by being the TextClass associated with the BufferParams for -/// a given Buffer. This is the object returned by BufferParams::textClass(). -/// These instances of TextClass do not necessarily correspond just to a -/// *.layout file---that is, to a LyX "document class" or *.layout file--- -/// since a Buffer's TextClass, though always based upon a "document class" -/// may be modified by loading modules. - -/// That said, some TextClass instances do correspond strictly to document -/// classes, that is, to *.layout files. These instances are known in the code -/// as "base classes". These are cached in BaseClassList. -/// -/// Though it does not presently exist, one can imagine an extension of this -/// mechanism that would lead to caching of *.module or *.inc files. In that -/// case, some TextClass's would just correspond to *.module or *.inc files, -/// just as some now correspond to *.layout files. +/// There are two major subclasses of TextClass: LayoutFile and +/// DocumentClass. These subclasses are what are actually used in LyX. +/// Simple TextClass objects are not directly constructed in the main +/// LyX code---the constructor is protected. (That said, in tex2lyx +/// there are what amount to simple TextClass objects.) class TextClass { public: + /// + virtual ~TextClass() {}; + /////////////////////////////////////////////////////////////////// + // typedefs + /////////////////////////////////////////////////////////////////// /// The individual paragraph layouts comprising the document class typedef std::vector LayoutList; /// The inset layouts available to this class typedef std::map InsetLayouts; - /// Construct a layout with default values. Actual values loaded later. - explicit TextClass(std::string const & = std::string(), - std::string const & = std::string(), - std::string const & = std::string(), - bool texClassAvail = false); - - /// check whether the TeX class is available - bool isTeXClassAvailable() const; + /////////////////////////////////////////////////////////////////// + // Layout Info + /////////////////////////////////////////////////////////////////// + /// + LayoutPtr const & defaultLayout() const; + /// + docstring const & defaultLayoutName() const; + /// returns a special layout for use when we don't really want one, + /// e.g., in table cells + LayoutPtr const & emptyLayout() const + { return operator[](emptylayout_); }; + /// the name of the empty layout + docstring const & emptyLayoutName() const + { return emptylayout_; } /// Enumerate the paragraph styles. size_t layoutCount() const { return layoutlist_.size(); } /// Access the paragraph styles. LayoutPtr const & layout(size_t index) const { return layoutlist_[index]; } + /// + bool hasLayout(docstring const & name) const; + /// + LayoutPtr const & operator[](docstring const & vname) const; + /////////////////////////////////////////////////////////////////// + // reading routines + /////////////////////////////////////////////////////////////////// /// Enum used with TextClass::read enum ReadType { BASECLASS, //>This is a base class, i.e., top-level layout file @@ -85,143 +93,47 @@ public: /// Performs the read of the layout file. /// \return true on success. bool read(support::FileName const & filename, ReadType rt = BASECLASS); - /// - void readOutputType(Lexer &); - /// - void readTitleType(Lexer &); - /// - void readMaxCounter(Lexer &); - /// - void readClassOptions(Lexer &); - /// - void readCharStyle(Lexer &, std::string const &); - /// - void readFloat(Lexer &); - /// - void readCounter(Lexer &); - /// - bool hasLayout(docstring const & name) const; - - /// - LayoutPtr const & operator[](docstring const & vname) const; - /// Sees to that the textclass structure has been loaded + /////////////////////////////////////////////////////////////////// + // loading + /////////////////////////////////////////////////////////////////// + /// Sees to it the textclass structure has been loaded bool load(std::string const & path = std::string()) const; /// Has this layout file been loaded yet? - /// NOTE This only makes sense when used with "static" TextClass - /// objects, e.g., ones that represent files on disk, as opposed - /// to ones that can be modified by modules. - // FIXME Therefore it should return true only for BaseClass objects, - // and false for DocumentClass objects. - // Indeed, quite generally, those two sorts of objects should now be - // disentangled a bit. - bool loaded() const { return loaded_; } + /// Overridden by DocumentClass + virtual bool loaded() const { return loaded_; } - /// the list of floats defined in the document class - FloatList & floats(); - /// the list of floats defined in the document class - FloatList const & floats() const; - /// The Counters present in this document class. - Counters & counters() const; - /// Inset layouts of this doc class - InsetLayouts & insetLayouts() const { return insetlayoutlist_; }; + /////////////////////////////////////////////////////////////////// + // accessors + /////////////////////////////////////////////////////////////////// /// - InsetLayout const & insetLayout(docstring const & name) const; + std::string const & name() const { return name_; }; /// - docstring const & defaultLayoutName() const; - /// - LayoutPtr const & defaultLayout() const; - /// returns a special layout for use when we don't really want one, - /// e.g., in table cells - LayoutPtr const & emptyLayout() const - { return operator[](emptylayout_); }; - /// - docstring const & emptyLayoutName() const - { return emptylayout_; } - /// - std::string const & name() const; - /// - docstring const & labelstring() const; - /// - std::string const & latexname() const; - /// - std::string const & description() const; - /// - bool isModular() const { return modular_; } - /// Sets the layout as a modular one. There is never any - /// need to reset this. - void markAsModular() { modular_ = true; } - /// - std::string const & opt_fontsize() const; - /// - std::string const & opt_pagestyle() const; - /// - std::string const & options() const; - /// - std::string const & class_header() const; - /// - std::string const & pagestyle() const; - /// - docstring const & preamble() const; - - /// is this feature already provided by the class? - bool provides(std::string const & p) const; - /// features required by the class? - std::set const & requires() const { return requires_; } - - /// - unsigned int columns() const; - /// - PageSides sides() const; - /// - int secnumdepth() const; - /// - int tocdepth() const; - - /// Can be LaTeX, DocBook, etc. - OutputType outputType() const; - - /// - FontInfo const & defaultfont() const; - - /// Text that dictates how wide the left margin is on the screen - docstring const & leftmargin() const; - - /// Text that dictates how wide the right margin is on the screen - docstring const & rightmargin() const; - - /// The type of command used to produce a title - TitleLatexType titletype() const; - /// The name of the title command - std::string const & titlename() const; - - /// - int size() const; - /// The minimal TocLevel of sectioning layouts - int min_toclevel() const; - /// The maximal TocLevel of sectioning layouts - int max_toclevel() const; - /// returns true if the class has a ToC structure - bool hasTocLevels() const; + std::string const & description() const { return description_; }; /// - static InsetLayout const & emptyInsetLayout() { return empty_insetlayout_; } + std::string const & latexname() const { return latexname_; } protected: + /// Protect construction + TextClass(); + /////////////////////////////////////////////////////////////////// + // members + /////////////////////////////////////////////////////////////////// /// Paragraph styles used in this layout LayoutList layoutlist_; -private: - /// - bool deleteLayout(docstring const &); - /// \return true for success. - bool readStyle(Lexer &, Layout &); /// Layout file name std::string name_; /// document class name std::string latexname_; /// document class description std::string description_; - /// whether this is a modular layout, i.e., whether it has been - /// modified by loading of layout modules. - bool modular_; + /// available types of float, eg. figure, algorithm. + boost::shared_ptr floatlist_; + /// Types of counters, eg. sections, eqns, figures, avail. in document class. + boost::shared_ptr counters_; + /// Has this layout file been loaded yet? + mutable bool loaded_; + /// Is the TeX class available? + bool texClassAvail_; /// std::string opt_fontsize_; /// @@ -260,58 +172,146 @@ private: FontInfo defaultfont_; /// Text that dictates how wide the left margin is on the screen docstring leftmargin_; - /// Text that dictates how wide the right margin is on the screen docstring rightmargin_; - /// The type of command used to produce a title TitleLatexType titletype_; /// The name of the title command std::string titlename_; /// Input layouts available to this layout mutable InsetLayouts insetlayoutlist_; - - /// available types of float, eg. figure, algorithm. - boost::shared_ptr floatlist_; - - /// Types of counters, eg. sections, eqns, figures, avail. in document class. - boost::shared_ptr counters_; - - /// Has this layout file been loaded yet? - mutable bool loaded_; - - /// Is the TeX class available? - bool texClassAvail_; - /// The minimal TocLevel of sectioning layouts int min_toclevel_; /// The maximal TocLevel of sectioning layouts int max_toclevel_; +private: + /////////////////////////////////////////////////////////////////// + // helper routines for reading layout files + /////////////////////////////////////////////////////////////////// /// - static InsetLayout empty_insetlayout_; + bool deleteLayout(docstring const &); + /// \return true for success. + bool readStyle(Lexer &, Layout &); + /// + void readOutputType(Lexer &); + /// + void readTitleType(Lexer &); + /// + void readMaxCounter(Lexer &); + /// + void readClassOptions(Lexer &); + /// + void readCharStyle(Lexer &, std::string const &); + /// + void readFloat(Lexer &); + /// + void readCounter(Lexer &); }; -/// This class amounts to little more than a `strong typedef'. -/// Its purpose is to control the creation of TextClass objects -/// within the DocumentClassBundle. -/// These TextClasses represent the layout information that is -/// associated with a given buffer. +/// A DocumentClass represents the layout information associated with a +/// Buffer. It is based upon a LayoutFile, but may be modified by loading +/// various Modules. It is thus a dynamic object, as opposed to LayoutFile's +/// which are pretty much static. +/// +/// In the main LyX code, DocumentClass objects are created only by +/// DocumentClassBundle, for which see below. class DocumentClass : public TextClass { public: + /// + virtual ~DocumentClass() {} + + /////////////////////////////////////////////////////////////////// + // Layout Info + /////////////////////////////////////////////////////////////////// + /// \return true if there is a Layout with latexname lay bool hasLaTeXLayout(std::string const & lay) const; + /// A DocumentClass nevers count as loaded, since it is dynamic + virtual bool loaded() { return false; } + /// Inset layouts of this doc class + InsetLayouts & insetLayouts() const { return insetlayoutlist_; }; + /// \return the layout object of an inset given by name. If the name + /// is not found as such, the part after the ':' is stripped off, and + /// searched again. In this way, an error fallback can be provided: + /// An erroneous 'CharStyle:badname' (e.g., after a documentclass switch) + /// will invoke the layout object defined by name = 'CharStyle'. + /// If that doesn't work either, an empty object returns (shouldn't + /// happen). -- Idea JMarc, comment MV + /// + InsetLayout const & insetLayout(docstring const & name) const; + /// an empty inset layout for use as a default + static InsetLayout const & emptyInsetLayout() { return empty_insetlayout_; } + + /////////////////////////////////////////////////////////////////// + // accessors + /////////////////////////////////////////////////////////////////// + /// the list of floats defined in the document class + FloatList & floats() { return *floatlist_.get(); } + /// the list of floats defined in the document class + FloatList const & floats() const { return *floatlist_.get(); } + /// The Counters present in this document class. + Counters & counters() const { return *counters_.get(); } + /// + std::string const & opt_fontsize() const { return opt_fontsize_; } + /// + std::string const & opt_pagestyle() const { return opt_pagestyle_; } + /// + std::string const & options() const { return options_; } + /// + std::string const & class_header() const { return class_header_; } + /// + std::string const & pagestyle() const { return pagestyle_; } + /// + docstring const & preamble() const { return preamble_; } + /// is this feature already provided by the class? + bool provides(std::string const & p) const; + /// features required by the class? + std::set const & requires() const { return requires_; } + /// + unsigned int columns() const { return columns_; } + /// + PageSides sides() const { return sides_; } + /// + int secnumdepth() const { return secnumdepth_; } + /// + int tocdepth() const { return tocdepth_; } + /// + FontInfo const & defaultfont() const { return defaultfont_; } + /// Text that dictates how wide the left margin is on the screen + docstring const & leftmargin() const { return leftmargin_; } + /// Text that dictates how wide the right margin is on the screen + docstring const & rightmargin() const { return rightmargin_; } + /// The type of command used to produce a title + TitleLatexType titletype() const { return titletype_; }; + /// The name of the title command + std::string const & titlename() const { return titlename_; }; + /// + int size() const { return layoutlist_.size(); } + /// The minimal TocLevel of sectioning layouts + int min_toclevel() const { return min_toclevel_; } + /// The maximal TocLevel of sectioning layouts + int max_toclevel() const { return max_toclevel_; } + /// returns true if the class has a ToC structure + bool hasTocLevels() const; + /// Can be LaTeX, DocBook, etc. + OutputType outputType() const { return outputType_; } +protected: + /// Constructs a DocumentClass based upon a LayoutFile. + DocumentClass(LayoutFile const & tc); + /// Needed in tex2lyx + DocumentClass() {}; private: - /// Constructs a DocumentClass based upon a TextClass. - DocumentClass(TextClass const & tc); /// The only class that can create a DocumentClass is /// DocumentClassBundle, which calls the private constructor. friend class DocumentClassBundle; + /// + static InsetLayout empty_insetlayout_; }; -/// This is simply a container for the text classes generated when modules -/// are read, so that they stay in memory for use by Insets, CutAndPaste, -/// and the like. +/// DocumentClassBundle is a container for DocumentClass objects, so that +/// they stay in memory for use by Insets, CutAndPaste, and the like, even +/// when their associated Buffers are destroyed. /// FIXME Some sort of garbage collection or reference counting wouldn't /// be a bad idea here. It might be enough to check when a Buffer is closed /// (or makeDocumentClass is called) whether the old DocumentClass is in use @@ -322,7 +322,7 @@ private: class DocumentClassBundle { public: /// \return Pointer to a new class equal to baseClass - DocumentClass & newClass(TextClass const & baseClass); + DocumentClass & newClass(LayoutFile const & baseClass); /// \return The sole instance of this class. static DocumentClassBundle & get(); private: diff --git a/src/frontends/qt4/GuiDocument.cpp b/src/frontends/qt4/GuiDocument.cpp index 2bffddda12..e2309bfbef 100644 --- a/src/frontends/qt4/GuiDocument.cpp +++ b/src/frontends/qt4/GuiDocument.cpp @@ -152,8 +152,8 @@ public: // Ordering criteria: // 1. Availability of text class // 2. Description (lexicographic) - TextClass const & tc1 = BaseClassList::get()[lhs]; - TextClass const & tc2 = BaseClassList::get()[rhs]; + LayoutFile const & tc1 = BaseClassList::get()[lhs]; + LayoutFile const & tc2 = BaseClassList::get()[rhs]; return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) || (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && _(tc1.description()) < _(tc2.description())); @@ -906,13 +906,13 @@ GuiDocument::GuiDocument(GuiView & lv) //give us a list of entries or something of the sort. latexModule->classCO->setModel(&classes_model_); BaseClassList const & bcl = BaseClassList::get(); - vector classList = bcl.classList(); + vector classList = bcl.classList(); sort(classList.begin(), classList.end(), less_textclass_avail_desc()); - vector::const_iterator cit = classList.begin(); - vector::const_iterator cen = classList.end(); + vector::const_iterator cit = classList.begin(); + vector::const_iterator cen = classList.end(); for (int i = 0; cit != cen; ++cit, ++i) { - TextClass const & tc = bcl[*cit]; + LayoutFile const & tc = bcl[*cit]; docstring item = (tc.isTeXClassAvailable()) ? from_utf8(tc.description()) : bformat(_("Unavailable: %1$s"), from_utf8(tc.description())); diff --git a/src/frontends/qt4/GuiToolbar.h b/src/frontends/qt4/GuiToolbar.h index d912f99074..d9431f7ead 100644 --- a/src/frontends/qt4/GuiToolbar.h +++ b/src/frontends/qt4/GuiToolbar.h @@ -25,7 +25,7 @@ namespace lyx { class Inset; -class TextClass; +class DocumentClass; class ToolbarItem; namespace frontend { @@ -53,7 +53,7 @@ private Q_SLOTS: private: GuiView & owner_; - TextClass const * text_class_; + DocumentClass const * text_class_; Inset const * inset_; }; diff --git a/src/insets/InsetCaption.cpp b/src/insets/InsetCaption.cpp index 1c968b4a01..47dc0f0c0f 100644 --- a/src/insets/InsetCaption.cpp +++ b/src/insets/InsetCaption.cpp @@ -48,7 +48,7 @@ namespace lyx { InsetCaption::InsetCaption(InsetCaption const & ic) - : InsetText(ic), textclass_(ic.textclass_) + : InsetText(ic) { setAutoBreakRows(true); setDrawFrame(true); @@ -57,7 +57,7 @@ InsetCaption::InsetCaption(InsetCaption const & ic) InsetCaption::InsetCaption(BufferParams const & bp) - : InsetText(bp), textclass_(bp.documentClass()) + : InsetText(bp) { setAutoBreakRows(true); setDrawFrame(true); diff --git a/src/insets/InsetCaption.h b/src/insets/InsetCaption.h index b3dce709da..837aaa442b 100644 --- a/src/insets/InsetCaption.h +++ b/src/insets/InsetCaption.h @@ -16,8 +16,6 @@ namespace lyx { -class TextClass; - /** A caption inset */ class InsetCaption : public InsetText { @@ -90,8 +88,6 @@ private: std::string type_; /// docstring custom_label_; - /// - TextClass const & textclass_; }; diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp index 870f75ac37..a0cae01244 100644 --- a/src/insets/InsetCollapsable.cpp +++ b/src/insets/InsetCollapsable.cpp @@ -134,7 +134,7 @@ void InsetCollapsable::setLayout(DocumentClass const * const dc) layout_ = &(dc->insetLayout(name())); labelstring_ = layout_->labelstring(); } else { - layout_ = &TextClass::emptyInsetLayout(); + layout_ = &DocumentClass::emptyInsetLayout(); labelstring_ = _("UNDEFINED"); } @@ -896,7 +896,7 @@ void InsetCollapsable::validate(LaTeXFeatures & features) const bool InsetCollapsable::undefined() const { docstring const & n = getLayout().name(); - return n.empty() || n == TextClass::emptyInsetLayout().name(); + return n.empty() || n == DocumentClass::emptyInsetLayout().name(); } diff --git a/src/tex2lyx/Context.cpp b/src/tex2lyx/Context.cpp index e2cc1b5e70..6b0bfb64d2 100644 --- a/src/tex2lyx/Context.cpp +++ b/src/tex2lyx/Context.cpp @@ -83,7 +83,7 @@ bool Context::empty = true; Context::Context(bool need_layout_, - TextClass const & textclass_, + TeX2LyXDocClass const & textclass_, LayoutPtr layout_, LayoutPtr parent_layout_, TeXFont font_) : need_layout(need_layout_), diff --git a/src/tex2lyx/Context.h b/src/tex2lyx/Context.h index 564b332713..9fb8ce103f 100644 --- a/src/tex2lyx/Context.h +++ b/src/tex2lyx/Context.h @@ -12,7 +12,7 @@ #ifndef CONTEXT_H #define CONTEXT_H -#include "TextClass.h" +#include "tex2lyx.h" #include @@ -77,7 +77,7 @@ void output_font_change(std::ostream & os, TeXFont const & oldfont, class Context { public: Context(bool need_layout_, - TextClass const & textclass_, + TeX2LyXDocClass const & textclass_, LayoutPtr layout_ = LayoutPtr(), LayoutPtr parent_layout_= LayoutPtr(), TeXFont font_ = TeXFont()); @@ -140,7 +140,7 @@ public: static bool empty; /// The textclass of the document. Could actually be a global variable - TextClass const & textclass; + TeX2LyXDocClass const & textclass; /// The layout of the current paragraph LayoutPtr layout; /// The layout of the outer paragraph (for environment layouts) diff --git a/src/tex2lyx/Makefile.am b/src/tex2lyx/Makefile.am index fb7d95ba46..6b26436c41 100644 --- a/src/tex2lyx/Makefile.am +++ b/src/tex2lyx/Makefile.am @@ -33,6 +33,7 @@ LINKED_FILES = \ ../Floating.cpp \ ../Counters.cpp \ ../insets/InsetLayout.cpp \ + ../BaseClassList.h \ ../Layout.h \ ../Layout.cpp \ ../TextClass.cpp \ diff --git a/src/tex2lyx/preamble.cpp b/src/tex2lyx/preamble.cpp index 3813a36bf6..aaf434c720 100644 --- a/src/tex2lyx/preamble.cpp +++ b/src/tex2lyx/preamble.cpp @@ -15,6 +15,7 @@ #include "tex2lyx.h" +#include "BaseClassList.h" #include "Layout.h" #include "Lexer.h" #include "TextClass.h" @@ -405,7 +406,7 @@ void end_preamble(ostream & os, TextClass const & /*textclass*/) } // anonymous namespace -TextClass const parse_preamble(Parser & p, ostream & os, string const & forceclass) +TeX2LyXDocClass const parse_preamble(Parser & p, ostream & os, string const & forceclass) { // initialize fixed types special_columns['D'] = 3; @@ -660,7 +661,7 @@ TextClass const parse_preamble(Parser & p, ostream & os, string const & forcecla cerr << "Error: Could not find layout file for textclass \"" << h_textclass << "\"." << endl; exit(1); } - TextClass textclass; + TeX2LyXDocClass textclass; textclass.read(layoutfilename); if (h_papersides.empty()) { ostringstream ss; diff --git a/src/tex2lyx/tex2lyx.cpp b/src/tex2lyx/tex2lyx.cpp index 02630b3df7..1170ded8e4 100644 --- a/src/tex2lyx/tex2lyx.cpp +++ b/src/tex2lyx/tex2lyx.cpp @@ -397,7 +397,7 @@ void tex2lyx(istream & is, ostream & os) //p.dump(); stringstream ss; - TextClass textclass = parse_preamble(p, ss, documentclass); + TeX2LyXDocClass textclass = parse_preamble(p, ss, documentclass); captionlayout = LayoutPtr(Layout::forCaption()); active_environments.push_back("document"); diff --git a/src/tex2lyx/tex2lyx.h b/src/tex2lyx/tex2lyx.h index c3ffe97d50..7c5ed348d9 100644 --- a/src/tex2lyx/tex2lyx.h +++ b/src/tex2lyx/tex2lyx.h @@ -28,8 +28,12 @@ namespace support { class FileName; } class Context; +/// A trivial subclass, just to give us a public default constructor +class TeX2LyXDocClass : public DocumentClass +{}; + /// in preamble.cpp -TextClass const parse_preamble(Parser & p, std::ostream & os, std::string const & forceclass); +TeX2LyXDocClass const parse_preamble(Parser & p, std::ostream & os, std::string const & forceclass); /// used packages with options extern std::map > used_packages; -- 2.39.2