This patch adds a rename facility. It also provides the possibility to "merge" 
branches. If you have a branch "foo" and a branch "bar", and you try to rename 
"bar" to "foo", LyX asks you if both branches should be merged into one "foo" 
branch (with the settings of the original "bar" branch).

Pavel, please tell me if this interferes with your branch-add-insert plans, 
then I wait until that one is in. 

Jürgen
Index: src/LyXAction.cpp
===================================================================
--- src/LyXAction.cpp	(Revision 30420)
+++ src/LyXAction.cpp	(Arbeitskopie)
@@ -3318,6 +3318,17 @@
 		{ LFUN_BRANCH_DEACTIVATE, "branch-deactivate", AtPoint, Buffer },
 
 /*!
+ * \var lyx::FuncCode lyx::LFUN_BRANCHES_RENAME
+ * \li Action: Rename all branches of a given name in a document
+ * \li Syntax: branches-rename <OLDNAME> <NEWNAME>
+ * \li Params: <OLDNAME>: Current name of the branch to be renamed
+ *             <NEWNAME>: New name of the branch
+ * \li Origin: spitz, 9 Jul 2009
+ * \endvar
+ */
+		{ LFUN_BRANCHES_RENAME, "branches-rename", Noop, Buffer },
+
+/*!
  * \var lyx::FuncCode lyx::LFUN_LABEL_COPY_AS_REF
  * \li Action: Copies the label at the cursor as a cross-reference to be pasted elsewhere.
  * \li Syntax: copy-label-as-reference <LABEL>
Index: src/insets/InsetBranch.h
===================================================================
--- src/insets/InsetBranch.h	(Revision 30420)
+++ src/insets/InsetBranch.h	(Arbeitskopie)
@@ -53,6 +53,8 @@
 	static void string2params(std::string const &, InsetBranchParams &);
 	///
 	docstring branch() const { return params_.branch; }
+	///
+	void rename(docstring const & newname) { params_.branch = newname; }
 
 private:
 	///
Index: src/Buffer.h
===================================================================
--- src/Buffer.h	(Revision 30420)
+++ src/Buffer.h	(Arbeitskopie)
@@ -509,6 +509,8 @@
 
 	/// return a list of all used branches (also in children)
 	void getUsedBranches(std::list<docstring> &, bool const from_master = false) const;
+	/// rename all branches of \p oldname in the buffer to \p newname.
+	void renameBranches(docstring const & oldname, docstring const & newname);
 
 	/// sets the buffer_ member for every inset in this buffer.
 	// FIXME This really shouldn't be needed, but at the moment it's not
Index: src/BranchList.h
===================================================================
--- src/BranchList.h	(Revision 30420)
+++ src/BranchList.h	(Arbeitskopie)
@@ -105,6 +105,12 @@
 	 *  \returns true if a branch is removed.
 	 */
 	bool remove(docstring const &);
+	/** rename an branch in list
+	 *  \returns true if renaming succeeded.
+	 * if \p merge is true, the branch will be removed
+	 * if a branch with the newname already exists.
+	 */
+	bool rename(docstring const &, docstring const &, bool const merge = false);
 
 private:
 	///
Index: src/frontends/qt4/GuiDocument.h
===================================================================
--- src/frontends/qt4/GuiDocument.h	(Revision 30420)
+++ src/frontends/qt4/GuiDocument.h	(Arbeitskopie)
@@ -105,6 +105,7 @@
 	void changeBackgroundColor();
 	void deleteBackgroundColor();
 	void xetexChanged(bool);
+	void branchesRename(docstring const &, docstring const &);
 private:
 	/// validate listings parameters and return an error message, if any
 	QString validateListingsParameters();
Index: src/frontends/qt4/GuiDocument.cpp
===================================================================
--- src/frontends/qt4/GuiDocument.cpp	(Revision 30421)
+++ src/frontends/qt4/GuiDocument.cpp	(Arbeitskopie)
@@ -946,6 +946,8 @@
 	branchesModule = new GuiBranches;
 	connect(branchesModule, SIGNAL(changed()),
 		this, SLOT(change_adaptor()));
+	connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
+		this, SLOT(branchesRename(docstring const &, docstring const &)));
 	updateUnknownBranches();
 
 	// preamble
@@ -2812,6 +2814,13 @@
 }
 
 
+void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
+{
+	docstring const arg = '"' + oldname + '"' + " " + '"' + newname + '"';
+	dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
+}
+
+
 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
 
 
Index: src/frontends/qt4/GuiBranches.cpp
===================================================================
--- src/frontends/qt4/GuiBranches.cpp	(Revision 30421)
+++ src/frontends/qt4/GuiBranches.cpp	(Arbeitskopie)
@@ -20,9 +20,12 @@
 
 #include "ui_BranchesUnknownUi.h"
 
+#include "frontends/alert.h"
+
 #include "Buffer.h"
 #include "BufferParams.h"
 
+#include "support/gettext.h"
 #include "support/lstrings.h"
 
 #include <QListWidget>
@@ -141,6 +144,40 @@
 }
 
 
+void GuiBranches::on_renamePB_pressed()
+{
+	QTreeWidgetItem * selItem = branchesTW->currentItem();
+	QString sel_branch;
+	if (selItem != 0)
+		sel_branch = selItem->text(0);
+	if (!sel_branch.isEmpty()) {
+		docstring newname;
+		docstring const oldname = qstring_to_ucs4(sel_branch);
+		bool success = false;
+		if (Alert::askForText(newname, _("Enter new branch name"))) {
+			if (branchlist_.find(newname)) {
+				docstring text = support::bformat(
+					_("A branch with the name \"%1$s\" already exists.\n"
+					  "Do you want to merge branch \"%2$s\" with that one?"),
+					newname, oldname);
+				if (frontend::Alert::prompt(_("Branch already exists"),
+					  text, 0, 1, _("&Merge"), _("&Cancel")) == 0)
+					success = branchlist_.rename(oldname, newname, true);
+			} else
+				success = branchlist_.rename(oldname, newname);
+			newBranchLE->clear();
+			updateView();
+		}
+		if (!success)
+			Alert::error(_("Renaming failed"), 
+			      _("The branch could not be renamed."));
+		else
+			// emit signal
+			renameBranches(oldname, newname);
+	}
+}
+
+
 void GuiBranches::on_activatePB_pressed()
 {
 	toggleBranch(branchesTW->currentItem());
Index: src/frontends/qt4/GuiBranches.h
===================================================================
--- src/frontends/qt4/GuiBranches.h	(Revision 30420)
+++ src/frontends/qt4/GuiBranches.h	(Arbeitskopie)
@@ -50,6 +50,7 @@
 
 Q_SIGNALS:
 	void changed();
+	void renameBranches(docstring const &, docstring const &);
 
 protected:
 	void toggleBranch(QTreeWidgetItem *);
@@ -59,6 +60,7 @@
 protected Q_SLOTS:
 	void on_addBranchPB_pressed();
 	void on_removePB_pressed();
+	void on_renamePB_pressed();
 	void on_activatePB_pressed();
 	void on_branchesTW_itemDoubleClicked(QTreeWidgetItem *, int);
 	void on_colorPB_clicked();
Index: src/frontends/qt4/ui/BranchesUi.ui
===================================================================
--- src/frontends/qt4/ui/BranchesUi.ui	(Revision 30420)
+++ src/frontends/qt4/ui/BranchesUi.ui	(Arbeitskopie)
@@ -19,17 +19,37 @@
    <property name="spacing" >
     <number>6</number>
    </property>
-   <item row="7" column="2" colspan="2" >
-    <widget class="QPushButton" name="unknownPB" >
+   <item row="3" column="3" >
+    <widget class="QPushButton" name="renamePB" >
      <property name="toolTip" >
-      <string>Show undefined branches used in this document.</string>
+      <string>Change the name of the selected branch</string>
      </property>
      <property name="text" >
-      <string>&amp;Undefined Branches</string>
+      <string>Re&amp;name...</string>
      </property>
     </widget>
    </item>
+   <item row="2" column="3" >
+    <widget class="QPushButton" name="removePB" >
+     <property name="toolTip" >
+      <string>Remove the selected branch</string>
+     </property>
+     <property name="text" >
+      <string>&amp;Remove</string>
+     </property>
+    </widget>
+   </item>
    <item row="4" column="3" >
+    <widget class="QPushButton" name="colorPB" >
+     <property name="toolTip" >
+      <string>Define or change background color</string>
+     </property>
+     <property name="text" >
+      <string>Alter Co&amp;lor...</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="3" >
     <spacer>
      <property name="orientation" >
       <enum>Qt::Vertical</enum>
@@ -39,46 +59,39 @@
      </property>
      <property name="sizeHint" >
       <size>
-       <width>20</width>
-       <height>20</height>
+       <width>83</width>
+       <height>61</height>
       </size>
      </property>
     </spacer>
    </item>
-   <item row="7" column="0" colspan="2" >
-    <spacer>
-     <property name="orientation" >
-      <enum>Qt::Horizontal</enum>
+   <item row="0" column="1" colspan="2" >
+    <widget class="QLineEdit" name="newBranchLE" />
+   </item>
+   <item row="0" column="3" >
+    <widget class="QPushButton" name="addBranchPB" >
+     <property name="toolTip" >
+      <string>Add a new branch to the list</string>
      </property>
-     <property name="sizeHint" >
-      <size>
-       <width>251</width>
-       <height>20</height>
-      </size>
+     <property name="text" >
+      <string>&amp;Add</string>
      </property>
-    </spacer>
+    </widget>
    </item>
-   <item row="1" column="0" colspan="3" >
-    <widget class="QLabel" name="availableLB" >
+   <item row="0" column="0" >
+    <widget class="QLabel" name="newBranchLA" >
      <property name="text" >
-      <string>A&amp;vailable Branches:</string>
+      <string>&amp;New:</string>
      </property>
      <property name="buddy" >
-      <cstring>branchesTW</cstring>
+      <cstring>newBranchLE</cstring>
      </property>
     </widget>
    </item>
-   <item row="2" column="3" >
-    <widget class="QPushButton" name="removePB" >
-     <property name="toolTip" >
-      <string>Remove the selected branch</string>
-     </property>
-     <property name="text" >
-      <string>&amp;Remove</string>
-     </property>
-    </widget>
+   <item rowspan="5" row="2" column="0" colspan="3" >
+    <widget class="QTreeWidget" name="branchesTW" />
    </item>
-   <item row="5" column="3" >
+   <item row="6" column="3" >
     <widget class="QPushButton" name="activatePB" >
      <property name="toolTip" >
       <string>Toggle the selected branch</string>
@@ -88,42 +101,39 @@
      </property>
     </widget>
    </item>
-   <item row="3" column="3" >
-    <widget class="QPushButton" name="colorPB" >
-     <property name="toolTip" >
-      <string>Define or change background color</string>
-     </property>
+   <item row="1" column="0" colspan="3" >
+    <widget class="QLabel" name="availableLB" >
      <property name="text" >
-      <string>Alter Co&amp;lor...</string>
+      <string>A&amp;vailable Branches:</string>
      </property>
+     <property name="buddy" >
+      <cstring>branchesTW</cstring>
+     </property>
     </widget>
    </item>
-   <item rowspan="5" row="2" column="0" colspan="3" >
-    <widget class="QTreeWidget" name="branchesTW" />
-   </item>
-   <item row="0" column="0" >
-    <widget class="QLabel" name="newBranchLA" >
-     <property name="text" >
-      <string>&amp;New:</string>
+   <item row="7" column="0" colspan="2" >
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
      </property>
-     <property name="buddy" >
-      <cstring>newBranchLE</cstring>
+     <property name="sizeHint" >
+      <size>
+       <width>251</width>
+       <height>20</height>
+      </size>
      </property>
-    </widget>
+    </spacer>
    </item>
-   <item row="0" column="3" >
-    <widget class="QPushButton" name="addBranchPB" >
+   <item row="7" column="2" colspan="2" >
+    <widget class="QPushButton" name="unknownPB" >
      <property name="toolTip" >
-      <string>Add a new branch to the list</string>
+      <string>Show undefined branches used in this document.</string>
      </property>
      <property name="text" >
-      <string>&amp;Add</string>
+      <string>&amp;Undefined Branches</string>
      </property>
     </widget>
    </item>
-   <item row="0" column="1" colspan="2" >
-    <widget class="QLineEdit" name="newBranchLE" />
-   </item>
   </layout>
  </widget>
  <includes>
Index: src/FuncCode.h
===================================================================
--- src/FuncCode.h	(Revision 30420)
+++ src/FuncCode.h	(Arbeitskopie)
@@ -436,6 +436,7 @@
 	LFUN_BUFFER_EXPORT,             // Lgb 97-07-29
 	LFUN_BUFFER_TOGGLE_COMPRESSION, // bpeng 20060427
 	LFUN_BRANCH_ADD,                // spitz 20090707
+	LFUN_BRANCHES_RENAME,           // spitz 20090709
 
 	LFUN_LASTACTION                 // end of the table
 };
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(Revision 30420)
+++ src/Buffer.cpp	(Arbeitskopie)
@@ -1623,6 +1623,7 @@
 		}
 
 		case LFUN_BRANCH_ADD:
+		case LFUN_BRANCHES_RENAME:
 		case LFUN_BUFFER_PRINT:
 			// if no Buffer is present, then of course we won't be called!
 			flag.setEnabled(true);
@@ -1705,6 +1706,13 @@
 		break;
 	}
 
+	case LFUN_BRANCHES_RENAME: {
+		docstring const oldname = from_utf8(func.getArg(0));
+		docstring const newname = from_utf8(func.getArg(1));
+		renameBranches(oldname, newname);
+		break;
+	}
+
 	case LFUN_BUFFER_PRINT: {
 		// we'll assume there's a problem until we succeed
 		dr.setError(true); 
@@ -2405,6 +2413,54 @@
 }
 
 
+void Buffer::renameBranches(docstring const & oldname, docstring const & newname)
+{
+	// Iterate over buffer, starting with first paragraph
+	// The scope must be bigger than any lookup DocIterator
+	// later. For the global lookup, lastpit+1 is used, hence
+	// we use lastpit+2 here.
+	DocIterator it = par_iterator_begin();
+	DocIterator scope = it;
+	scope.pit() = scope.lastpit() + 2;
+	pit_type lastpit = it.lastpit();
+
+	while (it.pit() <= lastpit) {
+		Paragraph & par = it.paragraph();
+
+		// iterate over the insets of the current paragraph
+		InsetList const & insets = par.insetList();
+		InsetList::const_iterator iit = insets.begin();
+		InsetList::const_iterator end = insets.end();
+		for (; iit != end; ++iit) {
+			it.pos() = iit->pos;
+
+			if (iit->inset->lyxCode() == BRANCH_CODE) {
+				// get buffer of external file
+				InsetBranch & br =
+					static_cast<InsetBranch &>(*iit->inset);
+				if (br.branch() == oldname)
+					br.rename(newname);
+				continue;
+			}
+
+			// is it an external file?
+			if (iit->inset->lyxCode() == INCLUDE_CODE) {
+				// get buffer of external file
+				InsetInclude const & inset =
+					static_cast<InsetInclude const &>(*iit->inset);
+				Buffer * child = inset.getChildBuffer();
+				if (!child)
+					continue;
+				child->renameBranches(oldname, newname);
+			}
+		}
+		// next paragraph
+		it.pit()++;
+		it.pos() = 0;
+	}
+}
+
+
 void Buffer::updateMacroInstances() const
 {
 	LYXERR(Debug::MACROS, "updateMacroInstances for "
Index: src/BranchList.cpp
===================================================================
--- src/BranchList.cpp	(Revision 30420)
+++ src/BranchList.cpp	(Arbeitskopie)
@@ -150,4 +150,25 @@
 }
 
 
+bool BranchList::rename(docstring const & oldname,
+	docstring const & newname, bool const merge)
+{
+	if (newname.empty())
+		return false;
+	if (find_if(list.begin(), list.end(),
+		    BranchNamesEqual(newname)) != list.end()) {
+		// new name already taken
+		if (merge)
+		      return remove(oldname);
+		return false;
+	}
+
+	Branch * branch = find(oldname);
+	if (!branch)
+		return false;
+	branch->setBranch(newname);
+	return true;
+}
+
+
 } // namespace lyx

Reply via email to