]> git.lyx.org Git - features.git/commitdiff
* Add native support for \includeonly (bug 5360).
authorJürgen Spitzmüller <spitz@lyx.org>
Thu, 7 Jan 2010 10:01:26 +0000 (10:01 +0000)
committerJürgen Spitzmüller <spitz@lyx.org>
Thu, 7 Jan 2010 10:01:26 +0000 (10:01 +0000)
File format change.

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

development/FORMAT
development/scons/scons_manifest.py
lib/lyx2lyx/lyx_2_0.py
src/Buffer.cpp
src/BufferParams.cpp
src/BufferParams.h
src/frontends/qt4/GuiDocument.cpp
src/frontends/qt4/GuiDocument.h
src/frontends/qt4/Makefile.am
src/frontends/qt4/ui/MasterChildUi.ui [new file with mode: 0644]

index e3a04668bd4447ee364b22f12ce173f405cf98da..1d35830f9a543156de17ac7472bc5107ca33d60f 100644 (file)
@@ -1,6 +1,15 @@
 LyX file-format changes
 -----------------------
 
+2010-01-06 Jürgen Spitzmüller <spitz@lyx.org>
+       * Format incremented to 375: add support for \includeonly
+         This adds a new buffer param list of relative filenames
+         which are output as \includeonly arguments, like this:
+         \begin_includeonly
+         child1.lyx
+         child2.lyx
+         \end_includeonly
+
 2009-12-30 Richard Heck <rgheck@comcast.net>
        * Format incremented to 374: add html output options.
                \html_use_mathml (boolean): whether to use MathML or images
index dc660555f635c1fd69c9735e007bcdec8e1d01fc..a65cebb1c64fe281bb8bc5526bbce304c0aa31bc 100644 (file)
@@ -940,6 +940,7 @@ src_frontends_qt4_ui_files = Split('''
     ListingsSettingsUi.ui
     LogUi.ui
     MarginsUi.ui
+    MasterChildUi.ui
     MathMatrixUi.ui
     MathsUi.ui
     ModulesUi.ui
index baa0fb6af5420ed6bbec5163b145661118b0dba1..67a5abc2eaabc2a3885ba026c523384dc8acf37d 100644 (file)
@@ -1141,6 +1141,19 @@ def revert_html_options(document):
         del document.header[i]
 
 
+def revert_includeonly(document):
+    i = 0
+    while True:
+        i = find_token(document.header, "\\begin_includeonly", i)
+        if i == -1:
+            return
+        j = find_end_of(document.header, i, "\\begin_includeonly", "\\end_includeonly")
+        if j == -1:
+            # this should not happen
+            break
+        document.header[i : j + 1] = []
+
+
 ##
 # Conversion hub
 #
@@ -1174,10 +1187,12 @@ convert = [[346, []],
            [371, []],
            [372, []],
            [373, [merge_gbrief]],
-           [374, []]
+           [374, []],
+           [375, []]
           ]
 
-revert =  [[373, [revert_html_options]],
+revert =  [[374, [revert_includeonly]],
+           [373, [revert_html_options]],
            [372, [revert_gbrief]],
            [371, [revert_fontenc]],
            [370, [revert_mhchem]],
index f8c53392a97a17033f652d1198728e3bff2d227e..8c013a9fa2bc973a897005c1ee1fe632c753e304 100644 (file)
@@ -127,7 +127,7 @@ namespace {
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-int const LYX_FORMAT = 374; // rgheck: HTML output options
+int const LYX_FORMAT = 375; // jspitzm: includeonly support
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@@ -607,6 +607,7 @@ int Buffer::readHeader(Lexer & lex)
        params().listings_params.clear();
        params().clearLayoutModules();
        params().clearRemovedModules();
+       params().clearIncludedChildren();
        params().pdfoptions().clear();
        params().indiceslist().clear();
        params().backgroundcolor = lyx::rgbFromHexName("#ffffff");
@@ -1259,7 +1260,9 @@ void Buffer::writeLaTeXSource(odocstream & os,
                listParentMacros(parentMacros, features);
 
                // Write the preamble
-               runparams.use_babel = params().writeLaTeX(os, features, d->texrow);
+               runparams.use_babel = params().writeLaTeX(os, features,
+                                                         d->texrow,
+                                                         d->filename.onlyPath());
 
                runparams.use_japanese = features.isRequired("japanese");
 
index ba261ec7989d42a35ea5688af18c78b96a9b5e64..bf24b5937cb7c177fd25564897ea164963f2d1a4 100644 (file)
@@ -536,6 +536,8 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                readModules(lex);
        } else if (token == "\\begin_removed_modules") {
                readRemovedModules(lex);
+       } else if (token == "\\begin_includeonly") {
+               readIncludeonly(lex);
        } else if (token == "\\options") {
                lex.eatLine();
                options = lex.getString();
@@ -834,7 +836,17 @@ void BufferParams::writeFile(ostream & os) const
                        os << *it << '\n';
                os << "\\end_modules" << '\n';
        }
-       
+
+       // includeonly
+       if (!includedChildren_.empty()) {
+               os << "\\begin_includeonly" << '\n';
+               list<string>::const_iterator it = includedChildren_.begin();
+               list<string>::const_iterator en = includedChildren_.end();
+               for (; it != en; it++)
+                       os << *it << '\n';
+               os << "\\end_includeonly" << '\n';
+       }
+
        // local layout information
        if (!local_layout.empty()) {
                // remove '\n' from the end 
@@ -1080,7 +1092,7 @@ void BufferParams::validate(LaTeXFeatures & features) const
 
 
 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
-                             TexRow & texrow) const
+                             TexRow & texrow, FileName const & filepath) const
 {
        os << "\\documentclass";
 
@@ -1249,6 +1261,31 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
        // handle inputenc etc.
        writeEncodingPreamble(os, features, texrow);
 
+       // includeonly
+       if (!includedChildren_.empty()) {
+               os << "\\includeonly{";
+               list<string>::const_iterator it = includedChildren_.begin();
+               bool first = true;
+               for (; it != includedChildren_.end() ; ++it) {
+                       string incfile = *it;
+                       FileName inc = makeAbsPath(incfile, filepath.absFilename());
+                       string mangled = DocFileName(changeExtension(inc.absFilename(), ".tex")).
+                       mangledFilename();
+                       if (!features.runparams().nice)
+                               incfile = mangled;
+                       // \includeonly doesn't want an extension 
+                       incfile = changeExtension(incfile, string());
+                       incfile = latex_path(incfile);
+                       if (!incfile.empty()) {
+                               if (!first)
+                                       os << ",";
+                               os << from_utf8(incfile);
+                       }
+                       first = false;
+               }
+               os << "}\n";
+       }
+
        if (!listings_params.empty() || features.isRequired("listings")) {
                os << "\\usepackage{listings}\n";
                texrow.newline();
@@ -1903,6 +1940,23 @@ void BufferParams::readRemovedModules(Lexer & lex)
 }
 
 
+void BufferParams::readIncludeonly(Lexer & lex)
+{
+       if (!lex.eatLine()) {
+               lyxerr << "Error (BufferParams::readIncludeonly):"
+                               "Unexpected end of input." << endl;
+               return;
+       }
+       while (true) {
+               string child = lex.getString();
+               if (child == "\\end_includeonly")
+                       break;
+               includedChildren_.push_back(child);
+               lex.eatLine();
+       }
+}
+
+
 string BufferParams::paperSizeName(PapersizePurpose purpose) const
 {
        char real_papersize = papersize;
index 2973687d2d21a940f01c78d67b016fb20f9bb478..bacda570b37b4a8880fbb873bea9e05430a64041 100644 (file)
@@ -23,6 +23,7 @@
 #include "insets/InsetQuotes.h"
 
 #include "support/copied_ptr.h"
+#include "support/FileName.h"
 
 #include <list>
 #include <map>
@@ -84,7 +85,8 @@ public:
         *  the BufferParams and a LyXRC variable).
         *  This returned value can then be passed to the insets...
         */
-       bool writeLaTeX(odocstream &, LaTeXFeatures &, TexRow &) const;
+       bool writeLaTeX(odocstream &, LaTeXFeatures &, TexRow &,
+                       support::FileName const &) const;
 
        ///
        void useClassDefaults();
@@ -154,6 +156,15 @@ public:
        /// Clear the removed module list
        void clearRemovedModules() { removedModules_.clear(); }
 
+       /// List of included children (for includeonly)
+       std::list<std::string> const & getIncludedChildren() const 
+                       { return includedChildren_; }
+       ///
+       void addIncludedChildren(std::string const & child) 
+                       { includedChildren_.push_back(child); }
+       /// Clear the list of included children
+       void clearIncludedChildren() { includedChildren_.clear(); }
+
        /// returns the main font for the buffer (document)
        Font const getFont() const;
 
@@ -384,6 +395,8 @@ private:
        void readModules(Lexer &);
        ///
        void readRemovedModules(Lexer &);
+       ///
+       void readIncludeonly(Lexer &);
        /// for use with natbib
        CiteEngine cite_engine_;
        ///
@@ -394,6 +407,9 @@ private:
        /// the user has chosen not to use
        std::list<std::string> removedModules_;
 
+       /// the list of included children (for includeonly)
+       std::list<std::string> includedChildren_;
+
        /** Use the Pimpl idiom to hide those member variables that would otherwise
         *  drag in other header files.
         */
index 91137cbb226f1630296d1128d7fcd082f0b07ca3..6ed27ea4aa3f85dc9f6678ce813185a823528b20 100644 (file)
@@ -617,6 +617,23 @@ GuiDocument::GuiDocument(GuiView & lv)
        bc().addCheckedLineEdit(textLayoutModule->indentLE);
        bc().addCheckedLineEdit(textLayoutModule->skipLE);
 
+       // master/child handling
+       masterChildModule = new UiWidget<Ui::MasterChildUi>;
+
+       connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
+               this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
+       connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
+               masterChildModule->childrenTW, SLOT(setEnabled(bool)));
+       connect(masterChildModule->includeallRB, SIGNAL(clicked()),
+               this, SLOT(change_adaptor()));
+       connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
+               this, SLOT(change_adaptor()));
+       masterChildModule->childrenTW->setColumnCount(2);
+       masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
+       masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
+       masterChildModule->childrenTW->resizeColumnToContents(1);
+       masterChildModule->childrenTW->resizeColumnToContents(2);
+
        // output
        outputModule = new UiWidget<Ui::OutputUi>;
 
@@ -1065,6 +1082,7 @@ GuiDocument::GuiDocument(GuiView & lv)
                qt_("Input listings parameters below. Enter ? for a list of parameters."));
 
        docPS->addPanel(latexModule, qt_("Document Class"));
+       docPS->addPanel(masterChildModule, qt_("Child Documents"));
        docPS->addPanel(modulesModule, qt_("Modules"));
        docPS->addPanel(fontModule, qt_("Fonts"));
        docPS->addPanel(textLayoutModule, qt_("Text Layout"));
@@ -1115,6 +1133,26 @@ void GuiDocument::change_adaptor()
 }
 
 
+void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
+{
+       if (item == 0)
+               return;
+
+       string child = fromqstr(item->text(0));
+       if (child.empty())
+               return;
+
+       if (std::find(includeonlys_.begin(),
+                     includeonlys_.end(), child) != includeonlys_.end())
+               includeonlys_.remove(child);
+       else
+               includeonlys_.push_back(child);
+       
+       updateIncludeonlys();
+       changed();
+}
+
+
 QString GuiDocument::validateListingsParameters()
 {
        // use a cache here to avoid repeated validation
@@ -1805,6 +1843,15 @@ void GuiDocument::updateDefaultFormat()
 }
 
 
+bool GuiDocument::isChildIncluded(string const & child)
+{
+       if (includeonlys_.empty())
+               return false;
+       return (std::find(includeonlys_.begin(),
+                         includeonlys_.end(), child) != includeonlys_.end());
+}
+
+
 void GuiDocument::applyView()
 {
        // preamble
@@ -2043,6 +2090,15 @@ void GuiDocument::applyView()
        else
                bp_.master = string();
 
+       // Master/Child
+       bp_.clearIncludedChildren();
+       if (masterChildModule->includeonlyRB->isChecked()) {
+               list<string>::const_iterator it = includeonlys_.begin();
+               for (; it != includeonlys_.end() ; ++it) {
+                       bp_.addIncludedChildren(*it);
+               }
+       }
+
        // Float Placement
        bp_.float_placement = floatModule->get();
 
@@ -2422,6 +2478,17 @@ void GuiDocument::paramsToDialog()
                latexModule->childDocGB->setChecked(false);
        }
 
+       // Master/Child
+       std::vector<Buffer *> children = buffer().getChildren(false);
+       if (children.empty()) {
+               masterChildModule->setEnabled(false);
+               includeonlys_.clear();
+       } else {
+               masterChildModule->setEnabled(true);
+               includeonlys_ = bp_.getIncludedChildren();
+               updateIncludeonlys();
+       }
+
        // Float Settings
        floatModule->set(bp_.float_placement);
 
@@ -2649,6 +2716,52 @@ void GuiDocument::updateSelectedModules()
 }
 
 
+void GuiDocument::updateIncludeonlys()
+{
+       masterChildModule->childrenTW->clear();
+       QString const no = qt_("No");
+       QString const yes = qt_("Yes");
+
+       if (includeonlys_.empty()) {
+               masterChildModule->includeallRB->setChecked(true);
+               masterChildModule->childrenTW->setEnabled(false);
+       } else {
+               masterChildModule->includeonlyRB->setChecked(true);
+               masterChildModule->childrenTW->setEnabled(true);
+       }
+       QTreeWidgetItem * item = 0;
+       std::vector<Buffer *> children = buffer().getChildren(false);
+       vector<Buffer *>::const_iterator it  = children.begin();
+       vector<Buffer *>::const_iterator end = children.end();
+       bool has_unincluded = false;
+       bool all_unincluded = true;
+       for (; it != end; ++it) {
+               item = new QTreeWidgetItem(masterChildModule->childrenTW);
+               // FIXME Unicode
+               string const name =
+                       to_utf8(makeRelPath(from_utf8((*it)->fileName().absFilename()),
+                                                       from_utf8(buffer().filePath())));
+               item->setText(0, toqstr(name));
+               item->setText(1, isChildIncluded(name) ? yes : no);
+               if (!isChildIncluded(name))
+                       has_unincluded = true;
+               else
+                       all_unincluded = false;
+       }
+       // Both if all childs are included and if none is included
+       // is equal to "include all" (i.e., ommit \includeonly).
+       // Thus, reset the GUI.
+       if (!has_unincluded || all_unincluded) {
+               masterChildModule->includeallRB->setChecked(true);
+               masterChildModule->childrenTW->setEnabled(false);
+               includeonlys_.clear();
+       }
+       // If all are included, we need to update again.
+       if (!has_unincluded)
+               updateIncludeonlys();
+}
+
+
 void GuiDocument::updateContents()
 {
        // Nothing to do here as the document settings is not cursor dependant.
index 96e3433aed924e380a372b8cefeffb0b07e9c2e6..920e95145d102319956b8c1ddc407bae1b3b3c5e 100644 (file)
@@ -23,6 +23,7 @@
 #include "ui_DocumentUi.h"
 #include "ui_FontUi.h"
 #include "ui_TextLayoutUi.h"
+#include "ui_MasterChildUi.h"
 #include "ui_MathsUi.h"
 #include "ui_LaTeXUi.h"
 #include "ui_PageLayoutUi.h"
@@ -75,6 +76,7 @@ public:
        void updateFontlist();
        void updateDefaultFormat();
        void updatePagestyle(std::string const &, std::string const &);
+       bool isChildIncluded(std::string const &);
 
        void showPreamble();
        ///
@@ -83,6 +85,7 @@ public:
 private Q_SLOTS:
        void updateNumbering();
        void change_adaptor();
+       void includeonlyClicked(QTreeWidgetItem * item, int);
        void setListingsMessage();
        void saveDefaultClicked();
        void useDefaultsClicked();
@@ -115,6 +118,7 @@ private:
        QString validateListingsParameters();
 
        UiWidget<Ui::TextLayoutUi> *textLayoutModule;
+       UiWidget<Ui::MasterChildUi> *masterChildModule;
        UiWidget<Ui::FontUi> *fontModule;
        UiWidget<Ui::PageLayoutUi> *pageLayoutModule;
        UiWidget<Ui::MarginsUi> *marginsModule;
@@ -150,6 +154,8 @@ private:
        void updateAvailableModules();
        ///
        void updateSelectedModules();
+       ///
+       void updateIncludeonlys();
        /// save as default template
        void saveDocDefault();
        /// reset to default params
@@ -232,6 +238,8 @@ private:
        std::list<modInfoStruct> moduleNames_;
        ///
        std::map<docstring, docstring> changedBranches_;
+       ///
+       std::list<std::string> includeonlys_;
 };
 
 
index 5eee3a62360333e98b93471d2817004e52f7e871..78825981102e5fb7dc80c5c956483b0e8ccc1126 100644 (file)
@@ -282,6 +282,7 @@ UIFILES = \
        ListingsSettingsUi.ui \
        LogUi.ui \
        MarginsUi.ui \
+       MasterChildUi.ui \
        MathMatrixUi.ui \
        MathsUi.ui \
        ModulesUi.ui \
diff --git a/src/frontends/qt4/ui/MasterChildUi.ui b/src/frontends/qt4/ui/MasterChildUi.ui
new file mode 100644 (file)
index 0000000..360cf57
--- /dev/null
@@ -0,0 +1,70 @@
+<ui version="4.0" >
+ <class>MasterChildUi</class>
+ <widget class="QWidget" name="MasterChildUi" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>348</width>
+    <height>327</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string/>
+  </property>
+  <layout class="QGridLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item row="0" column="0" >
+    <widget class="QGroupBox" name="includeonlyGB" >
+     <property name="title" >
+      <string>Master Document Output</string>
+     </property>
+     <property name="flat" >
+      <bool>true</bool>
+     </property>
+     <layout class="QGridLayout" >
+      <property name="margin" >
+       <number>9</number>
+      </property>
+      <property name="spacing" >
+       <number>6</number>
+      </property>
+      <item row="0" column="0" >
+       <widget class="QRadioButton" name="includeallRB" >
+        <property name="toolTip" >
+         <string>Include all included subdocuments in the output</string>
+        </property>
+        <property name="text" >
+         <string>&amp;Include all children</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0" >
+       <widget class="QRadioButton" name="includeonlyRB" >
+        <property name="toolTip" >
+         <string>Include only the selected subdocuments in the output</string>
+        </property>
+        <property name="text" >
+         <string>Include &amp;only selected children</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0" >
+       <widget class="QTreeWidget" name="childrenTW" />
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <includes>
+  <include location="local" >qt_i18n.h</include>
+ </includes>
+ <resources/>
+ <connections/>
+</ui>