From: Jean-Marc Lasgouttes [lasgout...@lyx.org]
Sent: Thursday, August 23, 2012 9:15 AM

>Then I propose to simplify things a lot by only dispatching to visible
>buffers (for now). No more special parameter.

The updated patch is attached.

How does it look?

Scott
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index db1c82a..8e3ec77 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -3148,21 +3148,22 @@ void LyXAction::init()
 		{ LFUN_BUFFER_WRITE_AS, "buffer-write-as", ReadOnly, Buffer },
 /*!
  * \var lyx::FuncCode lyx::LFUN_BUFFER_FORALL
- * \li Action: Applies a command to all visible, hidden, or both types of buffers in the active window.
- * \li Syntax: buffer-forall [<BUFFER-TYPE>] <LFUN-COMMAND>
- * \li Params: <BUFFER-TYPE>: <visible|hidden|both default:> default: visible               
-               <LFUN-COMMAND>: The command that is to be applied to the buffers.
- * \li Sample: Close all Notes in all visible documents: \n
+ * \li Action: Applies a command to all non-hidden buffers.
+ * \li Notion: a buffer is `hidden' if it is internally opened in LyX, but not
+               visible in any window.
+ * \li Syntax: buffer-forall <LFUN-COMMAND>
+ * \li Params: <LFUN-COMMAND>: The command to be applied to the buffers.
+ * \li Sample: Close all Notes in buffers: \n
 	           buffer-forall inset-forall Note inset-toggle close \n
-               Toggle change tracking on all documents: \n
-	           buffer-forall both changes-track \n
-               Toggle read-only for all visible documents: \n
+               Toggle change tracking on buffers: \n
+	           buffer-forall changes-track \n
+               Toggle read-only for buffers: \n
 	           buffer-forall buffer-toggle-read-only \n
-               Show statistics for each document: \n
-	           buffer-forall both statistics \n
-               Activate the branch named "Solutions" in all visible documents: \n
+               Show statistics for individual buffers: \n
+	           buffer-forall statistics \n
+               Activate the branch named "Solutions" in buffers: \n
 	           buffer-forall branch-activate Solutions \n
-               Export all visible documents to PDF (pdflatex): \n
+               Export buffers to PDF (pdflatex): \n
 	           buffer-forall buffer-export pdf2 \n
  * \li Origin: scottkostyshak, 20 Jul 2012
  * \endvar
diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp
index c5048dd..347d403 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -1092,8 +1092,15 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
 		break;
 
 	case LFUN_BUFFER_FORALL: {
-		if (!currentView() || !currentView()->currentBufferView() || !&currentView()->currentBufferView()->buffer()) {
-			flag.message(from_utf8(N_("Command not allowed without any visible document in the active window")));
+		if (theBufferList().empty()) {
+			flag.message(from_utf8(N_("Command not allowed without a buffer open")));
+			flag.setEnabled(false);
+			break;
+		}
+
+		FuncRequest const cmdToPass = lyxaction.lookupFunc(cmd.getLongArg(0));
+		if (cmdToPass.action() == LFUN_UNKNOWN_ACTION) {
+			flag.message(from_utf8(N_("the <LFUN-COMMAND> argument of buffer-forall is not valid")));
 			flag.setEnabled(false);
 		}
 		break;
@@ -1616,59 +1623,73 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 	}
 
 	case LFUN_BUFFER_FORALL: {
-		GuiView * gv = currentView();
-		Buffer * const buf = &gv->currentBufferView()->buffer();
-
-		bool processVisible = true;
-		bool processHidden = false;
-		docstring msg = _("Applied the following command to all visible buffers in the active window: ");
-		string commandToRun = argument;
-		if (cmd.getArg(0) == "both") {
-			processHidden = true;
-			msg = _("Applied the following command to all visible and hidden buffers in the active window: ");
-			commandToRun = cmd.getLongArg(1);
-		} else if (cmd.getArg(0) == "visible") {
-			commandToRun = cmd.getLongArg(1);
-		} else if (cmd.getArg(0) == "hidden") {
-			processHidden = true;
-			processVisible = false;
-			commandToRun = cmd.getLongArg(1);
-			msg = _("Applied the following command to all hidden buffers in the active window: ");
-		}
-		FuncRequest const funcToRun = lyxaction.lookupFunc(commandToRun);
-		dr.setMessage(bformat(_("%1$s%2$s"), msg, from_utf8(commandToRun)));
+		FuncRequest const funcToRun = lyxaction.lookupFunc(cmd.getLongArg(0));
+
+		map<Buffer *, GuiView *> views_lVisible;
+		map<GuiView *, Buffer *> activeBuffers;
+
+		QList<GuiView *> allViews = d->views_.values();
 
+		//this foreach does not modify any buffer. It just collects info on local visibility of buffers
+		//and on which buffer is active in each view.
 		Buffer * const last = theBufferList().last();
+		foreach (GuiView * view, allViews) {
+			//all of the buffers might be locally hidden. That is, there is no active buffer.
+			if (!view || !view->currentBufferView() || !&view->currentBufferView()->buffer())
+				activeBuffers[view] = 0;
+			else
+				activeBuffers[view] = &view->currentBufferView()->buffer();
+
+			//find out if each is locally visible or locally hidden.
+			//we don't use a for loop as the buffer list cycles.
+			Buffer * b = theBufferList().first();
+			while (true) {
+				bool const locallyVisible = view && view->workArea(*b);
+				if (locallyVisible) {
+					bool const exists_ = (views_lVisible.find(b) != views_lVisible.end());
+					//only need to overwrite/add if we don't already know a buffer is globally
+					//visible or we do know but we would prefer to dispatch LFUN from the
+					//current view because of cursor position issues.
+					if (!exists_ || (exists_ && views_lVisible[b] != current_view_))
+						views_lVisible[b] = view;
+				}
+				if (b == last)
+					break;
+				b = theBufferList().next(b);
+			}
+		}
+
+		GuiView * const homeView = currentView();
 		Buffer * b = theBufferList().first();
 		Buffer * nextBuf = 0;
-		// We cannot use a for loop as the buffer list cycles.
+		int numProcessed = 0;
 		while (true) {
 			if (b != last)
-				nextBuf = theBufferList().next(b); //get next now bc LFUN might close current 
-
-			bool const hidden = !(gv && gv->workArea(*b));
-			if (hidden) {
-				if (processHidden) {
-					gv->setBuffer(b);
-					lyx::dispatch(funcToRun);
-					gv->currentWorkArea()->view().hideWorkArea(gv->currentWorkArea());
-				}
-			}
-
-			else {
-				if (processVisible) {
-					gv->setBuffer(b);
-					lyx::dispatch(funcToRun);
-				}
+				nextBuf = theBufferList().next(b); //get next now bc LFUN might close current.
+
+			bool const visible = (views_lVisible.find(b) != views_lVisible.end());
+			if (visible) {
+				//first change to a view where b is locally visible, preferably current_view_.
+				GuiView * const vLv = views_lVisible[b];
+				vLv->setBuffer(b);
+				lyx::dispatch(funcToRun);
+				numProcessed++;
 			}
-
 			if (b == last)
 				break;
 			b = nextBuf;
 		}
 
-		if (theBufferList().isLoaded(buf)) //the LFUN might have closed buf
-			gv->setBuffer(buf);
+		//put things back to how they were (if possible).
+		foreach (GuiView * view, allViews) {
+			Buffer * originalBuf = activeBuffers[view];
+			//there might not have been an active buffer in this view or it might have been closed by the LFUN.
+			if (theBufferList().isLoaded(originalBuf))
+				view->setBuffer(originalBuf);
+		}
+		homeView->setFocus();
+
+		dr.setMessage(bformat(_("Applied \"%1$s\" to %2$d buffer(s)"), from_utf8(cmd.getLongArg(0)), numProcessed));
 		break;
 	}
 

Reply via email to