From 362d6e468f8ed924b54612d318390b6707f63ae5 Mon Sep 17 00:00:00 2001 From: Richard Heck Date: Wed, 5 Nov 2008 19:42:16 +0000 Subject: [PATCH] This patch fixes a set of bugs reported by Philippe relating to excluded and default modules. The lesson, in the end, is that we need to do all the removal of modules that no longer `fit', for whatever reason, before we do anything else. So the patch basically just moves the `removal' code into a new routine that gets called before the routines that add default modules and then check consistency. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@27281 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferParams.cpp | 100 +++++++++++++++++++++++++++++-------------- src/BufferParams.h | 7 ++- 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 3a8b25b5e7..4669d5c85c 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -1468,6 +1468,53 @@ void BufferParams::setDocumentClass(DocumentClass const * const tc) { } +bool BufferParams::removeBadModules() +{ + // we'll write a new list of modules, since we can't just remove them, + // as that would invalidate our iterators + list oldModules = getModules(); + clearLayoutModules(); + + list const & provmods = baseClass()->providedModules(); + list const & exclmods = baseClass()->excludedModules(); + bool consistent = true; // set to false if we have to do anything + + list::const_iterator oit = oldModules.begin(); + list::const_iterator const oen = oldModules.end(); + for (; oit != oen; ++oit) { + string const & modname = *oit; + // skip modules that the class provides + if (find(provmods.begin(), provmods.end(), modname) != provmods.end()) { + LYXERR0("Module `" << modname << "' dropped because provided by document class."); + consistent = false; + continue; + } + // are we excluded by the document class? + if (find(exclmods.begin(), exclmods.end(), modname) != exclmods.end()) { + LYXERR0("Module `" << modname << "' dropped because excluded by document class."); + consistent = false; + continue; + } + // determine whether some provided module excludes us or we exclude it + list::const_iterator pit = provmods.begin(); + list::const_iterator const pen = provmods.end(); + bool excluded = false; + for (; !excluded && pit != pen; ++pit) { + if (!LyXModule::areCompatible(modname, *pit)) { + LYXERR0("Module " << modname << + " dropped becuase it conflicts with provided module `" << *pit << "'."); + consistent = false; + excluded = true; + } + } + if (excluded) + continue; + layoutModules_.push_back(*oit); + } + return consistent; +} + + void BufferParams::addDefaultModules() { // add any default modules not already in use @@ -1505,9 +1552,9 @@ void BufferParams::addDefaultModules() bool BufferParams::checkModuleConsistency() { bool consistent = true; - // Perform a consistency check on the set of modules. - // In particular, we need to check that modules provided by this class - // do not conflict with modules chosen by the user. + // Perform a consistency check on the set of modules. We need to make + // sure that none of the modules exclude each other and that requires + // are satisfied. list oldModules = getModules(); clearLayoutModules(); list::const_iterator oit = oldModules.begin(); @@ -1516,35 +1563,7 @@ bool BufferParams::checkModuleConsistency() { list const & exclmods = baseClass()->excludedModules(); for (; oit != oen; ++oit) { string const & modname = *oit; - // skip modules that the class provides - if (find(provmods.begin(), provmods.end(), modname) != provmods.end()) { - consistent = false; - LYXERR0("Module " << modname << " dropped because provided by document class."); - continue; - } - // are we excluded by the document class? - if (find(exclmods.begin(), exclmods.end(), modname) != exclmods.end()) { - consistent = false; - LYXERR0("Module " << modname << " dropped because excluded by document class."); - continue; - } - - // determine whether some provided module excludes us or we exclude it - list::const_iterator pit = provmods.begin(); - list::const_iterator pen = provmods.end(); bool excluded = false; - for (; !excluded && pit != pen; ++pit) { - if (!LyXModule::areCompatible(modname, *pit)) { - consistent = false; - LYXERR0("Module " << modname << - " dropped becuase it conflicts with provided module " << *pit); - excluded = true; - } - } - - if (excluded) - continue; - // Determine whether some prior module excludes us, or we exclude it list::const_iterator lit = layoutModules_.begin(); list::const_iterator len = layoutModules_.end(); @@ -1627,8 +1646,27 @@ bool BufferParams::setBaseClass(string const & classname) } pimpl_->baseClass_ = classname; + // the previous document class may have loaded some modules that the + // new one excludes, and the new class may provide, etc, some that + // conflict with ones that were already loaded. So we need to go + // through the list and fix everything. I suppose there are various + // ways this could be done, but the following seems to work at the + // moment. (Thanks to Philippe Charpentier for helping work out all + // the bugs---rgh.) + // + // first, we remove any modules the new document class itself provides, + // those it excludes, and those that conflict with ones it excludes. + // this has to be done first because, otherwise, a module we're about + // to remove could prevent a default module from being added. + removeBadModules(); + // next, we add any default modules the new class provides. addDefaultModules(); + // finally, we perform a general consistency check on the set of + // loaded modules. checkModuleConsistency(); + // FIXME removeBadModules() and checkModuleConsistency() both return + // a boolean indicating whether something had to be changed. It might + // be worth popping a message to the user if so. return true; } diff --git a/src/BufferParams.h b/src/BufferParams.h index af7333364b..f470f56f73 100644 --- a/src/BufferParams.h +++ b/src/BufferParams.h @@ -345,7 +345,12 @@ private: void readModules(Lexer &); /// void readRemovedModules(Lexer &); - /// + /// Called when the document class changes. Removes modules + /// excluded by, provided by, etc, the document class. + /// \return true if modules were consistent, false if changes had + /// to be made. + bool removeBadModules(); + /// Adds default modules, if they're addable. void addDefaultModules(); /// checks for consistency among modules: makes sure requirements /// are met, no modules exclude one another, etc, and resolves any -- 2.39.2