]> git.lyx.org Git - features.git/commitdiff
Introduce "inverted" branch insets: These are branches whose content
authorRichard Heck <rgheck@lyx.org>
Tue, 12 Jul 2016 03:56:32 +0000 (23:56 -0400)
committerRichard Heck <rgheck@lyx.org>
Tue, 12 Jul 2016 03:56:32 +0000 (23:56 -0400)
is output when a branch is NOT activated. Fixes bug #7698.

At the moment, inversion is controlled through the branch settings
dialog. There is no provision for inserting inverted insets directly,
or for changing them from the context menu. Both of these could be
done, of course. The latter would need LFUN_BRANCH_TOGGLE_INVERTED.

development/FORMAT
lib/lyx2lyx/lyx_2_3.py
src/frontends/qt4/GuiBranch.cpp
src/frontends/qt4/ui/BranchUi.ui
src/insets/InsetBranch.cpp
src/insets/InsetBranch.h
src/version.h

index fb944cbd2513d638e84441a179e14ed1f43761b3..5631eea2a235f9c1193a958ab7de3a35507024d1 100644 (file)
@@ -11,6 +11,10 @@ adjustments are made to tex2lyx and bugs are fixed in lyx2lyx.
 
 -----------------------
 
+2016-07-11 Richard Heck <rgheck@lyx.org>
+  * Format incremented to 511
+   Added "inverted" branches
+
 2016-06-19 Georg Baum  <Georg.Baum@post.rwth-aachen.de>
        * Format incremented to 510
         Removed external date inset
index 31368902b930068e16dd0e5af59bd6567b5d3d9c..fca850831f89a3e8197abf93473efbdf68e9e1dc 100644 (file)
@@ -93,6 +93,88 @@ def convert_dateinset(document):
         continue
 
 
+def convert_ibranches(document):
+    ' Add "inverted 0" to branch insets'
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Branch", i)
+        if i == -1:
+            return
+        document.body.insert(i + 1, "inverted 0")
+        i += 1
+
+
+def revert_ibranches(document):
+    ' Convert inverted branches to explicit anti-branches'
+    # Get list of branches
+    ourbranches = {}
+    i = 0
+    while True:
+        i = find_token(document.header, "\\branch", i)
+        if i == -1:
+            break
+        branch = document.header[i][8:].strip()
+        if document.header[i+1].startswith("\\selected "):
+            #document.warning(document.header[i+1])
+            #document.warning(document.header[i+1][10])
+            selected = int(document.header[i+1][10])
+        else:
+            document.warning("Malformed LyX document: No selection indicator for branch " + branch)
+            selected = 1
+            
+        # the value tells us whether the branch is selected
+        ourbranches[document.header[i][8:].strip()] = selected
+        i += 1
+
+    # Figure out what inverted branches, if any, have been used
+    # and convert them to "Anti-OldBranch"
+    ibranches = {}
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Branch", i)
+        if i == -1:
+            break
+        if not document.body[i+1].startswith("inverted "):
+            document.warning("Malformed LyX document: Missing 'inverted' tag!")
+            i += 1
+            continue
+        inverted = document.body[i+1][9]
+        #document.warning(document.body[i+1])
+
+        if inverted == "1":
+            branch = document.body[i][20:].strip()
+            #document.warning(branch)
+            if not branch in ibranches:
+                antibranch = "Anti-" + branch
+                while antibranch in ibranches:
+                    antibranch = "x" + antibranch
+                ibranches[branch] = antibranch
+            else:
+                antibranch = ibranches[branch]
+            #document.warning(antibranch)
+            document.body[i] = "\\begin_inset Branch " + antibranch
+
+        # remove "inverted" key
+        del document.body[i+1]
+        i += 1
+
+    # now we need to add the new branches to the header
+    for old, new in ibranches.iteritems():
+        i = find_token(document.header, "\\branch " + old, 0)
+        if i == -1:
+            document.warning("Can't find branch %s even though we found it before!" % (old))
+            continue
+        j = find_token(document.header, "\\end_branch", i)
+        if j == -1:
+            document.warning("Malformed LyX document! Can't find end of branch " + old)
+            continue
+        # ourbranches[old] - 1 inverts the selection status of the old branch
+        lines = ["\\branch " + new,
+                 "\\selected " + str(ourbranches[old] - 1)]
+        # these are the old lines telling us color, etc.
+        lines += document.header[i+2 : j+1]
+        document.header[i:i] = lines
+        
 
 ##
 # Conversion hub
@@ -101,10 +183,12 @@ def convert_dateinset(document):
 supported_versions = ["2.3.0", "2.3"]
 convert = [
            [509, [convert_microtype]],
-           [510, [convert_dateinset]]
+           [510, [convert_dateinset]],
+           [511, [convert_ibranches]]
           ]
 
 revert =  [
+           [510, [revert_ibranches]],
            [509, []],
            [508, [revert_microtype]]
           ]
index c3629051155f3e5d6ef61cb0056568405354250c..24b6977390101ee03e43ccf8316f0015ced405c9 100644 (file)
@@ -33,6 +33,7 @@ GuiBranch::GuiBranch(QWidget * parent) : InsetParamsWidget(parent)
 {
        setupUi(this);
        connect(branchCO, SIGNAL(activated(int)), this, SIGNAL(changed()));
+       connect(invertedCB, SIGNAL(clicked()), this, SIGNAL(changed()));
 }
 
 
@@ -55,12 +56,13 @@ void GuiBranch::paramsToDialog(Inset const * inset)
                        id = count;
        }
        branchCO->setCurrentIndex(id);
+       invertedCB->setChecked(ib->params().inverted);
 }
 
 
 docstring GuiBranch::dialogToParams() const
 {
-       InsetBranchParams params(qstring_to_ucs4(branchCO->currentText()));
+       InsetBranchParams params(qstring_to_ucs4(branchCO->currentText()), invertedCB->isChecked());
        return from_utf8(InsetBranch::params2string(params));
 }
 
@@ -68,6 +70,7 @@ docstring GuiBranch::dialogToParams() const
 bool GuiBranch::checkWidgets(bool readonly) const
 {
        branchCO->setEnabled(!readonly);
+       invertedCB->setEnabled(!readonly);
        return InsetParamsWidget::checkWidgets();
 }
 
index 44700a70c738ca995f175b63a0606ca7b4a2c056..b8ba79905359905243af75f46505d354fa7c0d27 100644 (file)
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>BranchUi</class>
  <widget class="QWidget" name="BranchUi">
@@ -6,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>259</width>
-    <height>38</height>
+    <height>62</height>
    </rect>
   </property>
   <property name="windowTitle">
      </property>
     </widget>
    </item>
+   <item row="1" column="1">
+    <widget class="QCheckBox" name="invertedCB">
+     <property name="text">
+      <string>Inverted</string>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <tabstops>
index 026dffaaf3754608d257ec46decff7c5d3cae807..59423ce7ffe0919e139003ffab8be06a1035fa18 100644 (file)
@@ -74,7 +74,8 @@ docstring InsetBranch::toolTip(BufferView const & bv, int, int) const
                masterstatus :
                support::bformat(_("master: %1$s, child: %2$s"),
                                                 masterstatus, childstatus);
-       docstring const heading = 
+       docstring const heading = params_.inverted ?
+               support::bformat(_("Branch, inverted (%1$s): %2$s"), status, params_.branch) :
                support::bformat(_("Branch (%1$s): %2$s"), status, params_.branch);
        if (isOpen(bv))
                return heading;
@@ -86,6 +87,8 @@ docstring const InsetBranch::buttonLabel(BufferView const &) const
 {
        static char_type const tick = 0x2714; // ✔ U+2714 HEAVY CHECK MARK
        static char_type const cross = 0x2716; // ✖ U+2716 HEAVY MULTIPLICATION X
+       static char_type const itick = 0x271A; // ✚ U+271A HEAVY GREEK CROSS
+       static char_type const icross = 0x274E; // ❎ U+274E NEGATIVE SQUARED CROSS MARK
 
        Buffer const & realbuffer = *buffer().masterBuffer();
        BranchList const & branchlist = realbuffer.params().branchlist();
@@ -95,9 +98,14 @@ docstring const InsetBranch::buttonLabel(BufferView const &) const
        bool const master_selected = isBranchSelected();
        bool const child_selected = isBranchSelected(true);
 
-       docstring symb = docstring(1, master_selected ? tick : cross);
-       if (inchild && master_selected != child_selected)
-               symb += child_selected ? tick : cross;
+       docstring symb = docstring(1, master_selected ? 
+               (params_.inverted ? icross : tick) :
+               (params_.inverted ? itick: cross));
+       if (inchild && master_selected != child_selected) {
+               symb += child_selected ? 
+                       (params_.inverted ? icross : tick) :
+                       (params_.inverted ? itick: cross);
+       }
 
        if (decoration() == InsetLayout::MINIMALISTIC)
                return symb + params_.branch;
@@ -113,7 +121,7 @@ docstring const InsetBranch::buttonLabel(BufferView const &) const
                s = _("Branch (undefined): ");
        s += params_.branch;
 
-    return symb + s;
+       return symb + s;
 }
 
 
@@ -138,6 +146,7 @@ void InsetBranch::doDispatch(Cursor & cur, FuncRequest & cmd)
 
                cur.recordUndoInset(this);
                params_.branch = params.branch;
+               params_.inverted = params.inverted;
                // what we really want here is a TOC update, but that means
                // a full buffer update
                cur.forceBufferUpdate();
@@ -261,7 +270,7 @@ bool InsetBranch::isBranchSelected(bool const child) const
 
 void InsetBranch::latex(otexstream & os, OutputParams const & runparams) const
 {
-       if (isBranchSelected())
+       if (isBranchActive())
                InsetText::latex(os, runparams);
 }
 
@@ -269,7 +278,7 @@ void InsetBranch::latex(otexstream & os, OutputParams const & runparams) const
 int InsetBranch::plaintext(odocstringstream & os,
                           OutputParams const & runparams, size_t max_length) const
 {
-       if (!isBranchSelected())
+       if (!isBranchActive())
                return 0;
 
        int len = InsetText::plaintext(os, runparams, max_length);
@@ -280,13 +289,13 @@ int InsetBranch::plaintext(odocstringstream & os,
 int InsetBranch::docbook(odocstream & os,
                         OutputParams const & runparams) const
 {
-       return isBranchSelected() ?  InsetText::docbook(os, runparams) : 0;
+       return isBranchActive() ?  InsetText::docbook(os, runparams) : 0;
 }
 
 
 docstring InsetBranch::xhtml(XHTMLStream & xs, OutputParams const & rp) const
 {
-       if (isBranchSelected()) {
+       if (isBranchActive()) {
                OutputParams newrp = rp;
                newrp.par_begin = 0;
                newrp.par_end = text().paragraphs().size();
@@ -298,7 +307,7 @@ docstring InsetBranch::xhtml(XHTMLStream & xs, OutputParams const & rp) const
 
 void InsetBranch::toString(odocstream & os) const
 {
-       if (isBranchSelected())
+       if (isBranchActive())
                InsetCollapsable::toString(os);
 }
 
@@ -306,14 +315,14 @@ void InsetBranch::toString(odocstream & os) const
 void InsetBranch::forOutliner(docstring & os, size_t const maxlen,
                                                          bool const shorten) const
 {
-       if (isBranchSelected())
+       if (isBranchActive())
                InsetCollapsable::forOutliner(os, maxlen, shorten);
 }
 
 
 void InsetBranch::validate(LaTeXFeatures & features) const
 {
-       if (isBranchSelected())
+       if (isBranchActive())
                InsetCollapsable::validate(features);
 }
 
@@ -327,7 +336,7 @@ string InsetBranch::contextMenuName() const
 bool InsetBranch::isMacroScope() const 
 {
        // Its own scope if not selected by buffer
-       return !isBranchSelected();
+       return !isBranchActive();
 }
 
 
@@ -361,26 +370,30 @@ void InsetBranch::addToToc(DocIterator const & cpit, bool output_active,
 
        docstring str;
        text().forOutliner(str, TOC_ENTRY_LENGTH);
-       str = params_.branch + ": " + str;
+       str = params_.branch + (params_.inverted ? " (-):" : ": ") + str;
+
        shared_ptr<Toc> toc = buffer().tocBackend().toc("branch");
        toc->push_back(TocItem(pit, 0, str, output_active));
 
        // Proceed with the rest of the inset.
-       bool const doing_output = output_active && isBranchSelected();
+       bool const doing_output = output_active && isBranchActive();
        InsetCollapsable::addToToc(cpit, doing_output, utype);
 }
 
 
 void InsetBranchParams::write(ostream & os) const
 {
-       os << to_utf8(branch);
+       os << to_utf8(branch) 
+          << '\n' 
+          << "inverted " 
+          << inverted;
 }
 
 
 void InsetBranchParams::read(Lexer & lex)
 {
-       lex.eatLine();
-       branch = lex.getDocString();
+       lex >> branch;
+       lex >> "inverted" >> inverted;
 }
 
 } // namespace lyx
index b4ecbc8c99507bd81c0be3d806ed1c17efd6867d..beca1c683bee7b42dd5acffdefe1dcb4a2b1c4d2 100644 (file)
@@ -20,13 +20,17 @@ class InsetBranchParams {
 public:
        ///
        explicit InsetBranchParams(docstring const & b = docstring())
-               : branch(b) {}
+               : branch(b), inverted(false) {}
+       InsetBranchParams(docstring const & b, bool i)
+               : branch(b), inverted(i) {}
        ///
        void write(std::ostream & os) const;
        ///
        void read(Lexer & lex);
        ///
        docstring branch;
+       ///
+       bool inverted;
 };
 
 
@@ -52,6 +56,8 @@ public:
        docstring branch() const { return params_.branch; }
        ///
        void rename(docstring const & newname) { params_.branch = newname; }
+       ///
+       InsetBranchParams const & params() const { return params_; }
 
 private:
        ///
@@ -85,14 +91,16 @@ private:
        void addToToc(DocIterator const & di, bool output_active,
                                  UpdateType utype) const;
        ///
-       InsetBranchParams const & params() const { return params_; }
-       ///
        void setParams(InsetBranchParams const & params) { params_ = params; }
 
        /** \returns true if params_.branch is listed as 'selected' in
                \c buffer. \p child only checks within child documents.
         */
        bool isBranchSelected(bool const child = false) const;
+       ///
+       bool isBranchActive(bool const child = false) const
+               // XOR
+               { return isBranchSelected(child) != params_.inverted; }
        /*!
         * Is the content of this inset part of the output document?
         *
index 883c5e247584b116825cbdfc4174f9e36ff42a25..0a3b4930085ff5bffbd4fe0cc78b5a76949e31d2 100644 (file)
@@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 510 // gb: date inset
-#define LYX_FORMAT_TEX2LYX 510
+#define LYX_FORMAT_LYX 511 // rgh: inverted branches
+#define LYX_FORMAT_TEX2LYX 511
 
 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
 #ifndef _MSC_VER