mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-26 11:16:55 +00:00
More work towards type safety regarding TextClass's. A couple bugs have been fixed here, too, discovered along the way.
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
This commit is contained in:
parent
0e67e8423f
commit
2c382f2f47
@ -40,52 +40,25 @@ 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));
|
||||
}
|
||||
|
||||
|
||||
// Gets a textclass structure from number
|
||||
TextClass const &
|
||||
BaseClassList::operator[](BaseClassIndex textclass) 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];
|
||||
}
|
||||
|
||||
|
||||
// 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());
|
||||
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 string
|
||||
TextClass const &
|
||||
BaseClassList::operator[](string const & classname) const
|
||||
{
|
||||
BOOST_ASSERT(haveClass(classname));
|
||||
return classmap_[classname];
|
||||
}
|
||||
|
||||
|
||||
// Reads LyX textclass definitions according to textclass config file
|
||||
@ -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];
|
||||
TextClass tmpl(tc.name(), tc.latexname(), tc.description(),
|
||||
tc.isTeXClassAvailable());
|
||||
classlist_[textclass] = tmpl;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
pair<bool, BaseClassIndex> const
|
||||
BaseClassList::addTextClass(string const & textclass, string const & path)
|
||||
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());
|
||||
classmap_[classname] = tmpl;
|
||||
}
|
||||
|
||||
|
||||
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("");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
bool empty() const { return classmap_.empty(); }
|
||||
///
|
||||
typedef ClassList::const_iterator const_iterator;
|
||||
bool haveClass(std::string const & classname) const;
|
||||
///
|
||||
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;
|
||||
|
||||
///
|
||||
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
|
||||
};
|
||||
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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_; }
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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 &);
|
||||
|
@ -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: {
|
||||
|
Loading…
Reference in New Issue
Block a user