Dear list, I am surprised to see that nobody seems to be interested in such a feature, which is, at least to me, a big step forward for the userfriendliness of lyx. Considering that you can directly open a lyx file using whatever class/layout ....
Attached is an updated patch, using a slightly different approach. My final goal is to perform partial reconfigure on-demand so users will seldom need to run reconfigure and restart lyx again. Cheers, Bo
Index: src/buffer.C =================================================================== --- src/buffer.C (revision 9623) +++ src/buffer.C (working copy) @@ -416,6 +416,8 @@ params().headheight.erase(); params().headsep.erase(); params().footskip.erase(); + // store buffer path + params().buffer_path = filePath(); while (lex.isOK()) { lex.next(); @@ -475,7 +477,7 @@ BOOST_ASSERT(paragraphs().empty()); readHeader(lex); - if (!params().getLyXTextClass().load()) { + if (!params().getLyXTextClass().load(filePath())) { string theclass = params().getLyXTextClass().name(); Alert::error(_("Can't load document class"), bformat( "Using the default document class, because the " Index: src/bufferparams.C =================================================================== --- src/bufferparams.C (revision 9623) +++ src/bufferparams.C (working copy) @@ -406,8 +406,15 @@ if (pp.first) { textclass = pp.second; } else { - textclass = 0; - return classname; + // if text class does not exist, try to load it from buffer_path + pp = textclasslist.addTextClass(classname, buffer_path); + if (pp.first) { + textclass = pp.second; + } + else { + textclass = 0; + return classname; + } } if (!getLyXTextClass().isTeXClassAvailable()) { string const msg = Index: src/lyxtextclasslist.C =================================================================== --- src/lyxtextclasslist.C (revision 9623) +++ src/lyxtextclasslist.C (working copy) @@ -26,6 +26,8 @@ using lyx::support::MakeDisplayPath; using boost::bind; +#include <boost/filesystem/operations.hpp> +namespace fs = boost::filesystem; #ifndef CXX_GLOBAL_CSTD using std::exit; @@ -166,6 +168,43 @@ return true; } +std::pair<bool, lyx::textclass_type> const +LyXTextClassList::addTextClass(std::string const & textclass, std::string const & path) +{ + if (fs::exists(path + "/" + textclass + ".cls")) { + lyxerr[Debug::TCLASS] << "Adding class " << textclass << " from directory " << path << endl; + // FIXME: actually find/read the layout file and set these info correctly + // That means a C++ version of the horrible sed commands in configure.py :-) + // I may well call configure.py for this purpose. + LyXTextClass tmpl(textclass, textclass, textclass + "(auto loaded)", true); + if (lyxerr.debugging(Debug::TCLASS)) { + tmpl.load(path); + } + classlist_.push_back(tmpl); + return make_pair(true, classlist_.size() - 1); + } + else { + // FIXME: it is possible that we now have a class file, that is either newly + // added, or is not in classlist because of missing layout file. + // Partial re-configure (e.g. python configure.py --checkTexClass class ) + // will be run here. + /* + Path p(package().user_support()); + string const configure_script = + AddName(package().system_support(), "configure.py"); + string const configure_command = "python " + QuoteName(configure_script); + Systemcall one; + one.startscript(Systemcall::Wait, configure_command); + p.pop(); + bv->owner()->message(_("Reloading configuration...")); + lyxrc.read(LibFileSearch(string(), "lyxrc.defaults")); + // Re-read packages.lst + LaTeXFeatures::getAvailable(); + */ + return make_pair(false, textclass_type(0)); + } +} + // Global variable: textclass table. LyXTextClassList textclasslist; Index: src/bufferparams.h =================================================================== --- src/bufferparams.h (revision 9623) +++ src/bufferparams.h (working copy) @@ -230,6 +230,9 @@ std::string const paperSizeName() const; /// std::string const babelCall(std::string const & lang_opts) const; + /// path of the current buffer + /// we need to agree upon whether or not this is a valid param + std::string buffer_path; private: /** Use the Pimpl idiom to hide those member variables that would otherwise Index: src/lyxtextclass.C =================================================================== --- src/lyxtextclass.C (revision 9623) +++ src/lyxtextclass.C (working copy) @@ -24,6 +24,8 @@ #include "support/lstrings.h" #include "support/lyxlib.h" #include "support/filetools.h" +#include <boost/filesystem/operations.hpp> +namespace fs = boost::filesystem; #include <sstream> @@ -910,13 +912,16 @@ // Load textclass info if not loaded yet -bool LyXTextClass::load() const +bool LyXTextClass::load(string const & path) const { if (loaded_) return true; // Read style-file - string const real_file = LibFileSearch("layouts", name_, "layout"); + string real_file = path + "/" + name_ + ".layout"; + // if local layout file exists, use it. + if (!fs::exists(real_file)) + real_file = LibFileSearch("layouts", name_, "layout"); loaded_ = const_cast<LyXTextClass*>(this)->Read(real_file) == 0; if (!loaded_) { Index: src/lyxtextclasslist.h =================================================================== --- src/lyxtextclasslist.h (revision 9623) +++ src/lyxtextclasslist.h (working copy) @@ -47,6 +47,11 @@ /// Read textclass list. Returns false if this fails. bool Read(); + /// add a textclass from user local directory. + /// Return ture/false, and textclass number + std::pair<bool, lyx::textclass_type> const + addTextClass(std::string const & textclass, std::string const & path); + private: /// mutable ClassList classlist_; Index: src/lyxtextclass.h =================================================================== --- src/lyxtextclass.h (revision 9623) +++ src/lyxtextclass.h (working copy) @@ -84,7 +84,7 @@ LyXLayout_ptr const & operator[](std::string const & vname) const; /// Sees to that the textclass structure has been loaded - bool load() const; + bool load(std::string const & path=".") const; /// Has this layout file been loaded yet? bool loaded() const { return loaded_; }