From: Jean-Marc Lasgouttes [lasgout...@lyx.org]
Sent: Wednesday, July 18, 2012 4:14 AM

JMarc,

Thank you for your guidance. Attached is an updated patch and below I respond 
to your comments.

Scott

>Try to #include "GuiWorkArea.h" at the start of GuiApplication.cpp.

That works.

>> +     case LFUN_BUFFER_FORALL: {
>> +             GuiView * cv = currentView();

>What if currentView() is null? I propose to do an early return in this
>case. Or maybe this can happen when all buffers are hidden and requires
>finer codeing. I do not know whether this is only a theoretical
>possibility, this may happen when using client to do scripting. On the
>mac at least, LyX can be running witout having any open window.

>Unless you want to be very complete, it is probably enough right now to
>return early.

I wouldn't mind trying to address this if you think that would be better. For 
now I don't allow for this situation by disabling the function in getStatus. I 
didn't realize that it's possible to have a hidden window without a visible 
window. The current patch disables the function in this situation. I don't know 
how to check for the existence of a hidden buffer without a visible buffer.

>I do not think I have seen "cv" used as the name of a GuiView. From a
>quick poll if the source, I suggest "gv" or "view". The good thing about
>using a known name is that it requires less effort for the reader of the
>code.

Done.

>> +             Buffer * const buf = &cv->currentBufferView()->buffer();

>Do we have a bufferview when the LyX window is there but no buffer is open?

I put in some checks.

>> +             FuncRequest FuncToRun = lyxaction.lookupFunc(commandToRun);

>        FuncRequest const funcToRun =...
>(constify and no capitalization of variable names)

Done.

>> +             dr.setMessage(bformat(_("%1$s%2$s"), msg, 
>> from_utf8(commandToRun)));

>> +             Buffer * const last = theBufferList().last();
>> +             Buffer * b = theBufferList().first();
>> +             Buffer * nextBuf = 0;
>> +             // We cannot use a for loop as the buffer list cycles.
>> +             while (true) {
>> +                     if (b != last)
>> +                             nextBuf = theBufferList().next(b); //get next 
>> now bc LFUN might close current
>> +
>> +                     bool const hidden = !(guiApp->currentView() && 
>> guiApp->currentView()->workArea(*b));

>No need to use guiApp-> there. Are you using currentView() because cv
>could become invalid? If so, why do you use it below?

Done.

>BTW, what happens if several windows are open? It looks like you are not
>going to see whether the buffers on other windows are

If there are more windows open, buffer-forall iterates over the buffers in the 
current window, treating a buffer as hidden as designated in the current 
window. When a new window is opened it treats all of the open buffers as 
hidden. The default of buffer-forall of not iterating over hidden buffers is 
thus nice in the case that a user doesn't know what a hidden buffer is or 
doesn't know that the buffers in the other windows would be affected by 
buffer-forall because they are automatically available as hidden.

>> +                     if (hidden) {
>> +                             if (processHidden) {
>> +                                     cv->setBuffer(b);
>> +                                     lyx::dispatch(FuncToRun);
>> +                                     GuiWorkArea * const wa = 
>> cv->currentWorkArea();
>> +                                     wa->view().hideWorkArea(wa);

>I am not sure that the intermediate wa variable is useful here.

Done.
diff --git a/src/FuncCode.h b/src/FuncCode.h
index 9a7b06e..872721a 100644
--- a/src/FuncCode.h
+++ b/src/FuncCode.h
@@ -452,6 +452,7 @@ enum FuncCode
 	// 350
 	LFUN_CLIPBOARD_PASTE_SIMPLE,	// tommaso, 20111028
 	LFUN_IPA_INSERT,                // spitz, 20120305
+	LFUN_BUFFER_FORALL,             // scottkostyshak, 20120718
 
 	LFUN_LASTACTION                 // end of the table
 };
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 39018ce..3767e31 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -3127,6 +3127,28 @@ 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 current 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
+	           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
+	           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
+	           buffer-forall branch-activate Solutions \n
+               Export all visible documents to PDF (pdflatex): \n
+	           buffer-forall buffer-export pdf2 \n
+ * \li Origin: scottkostyshak, 18 Jul 2012
+ * \endvar
+ */
+		{ LFUN_BUFFER_FORALL, "buffer-forall", ReadOnly | Argument, Buffer },
+/*!
  * \var lyx::FuncCode lyx::LFUN_BUFFER_WRITE_ALL
  * \li Action: Save all changed documents.
  * \li Syntax: buffer-write-all
diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp
index b855067..e5c894f 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -38,6 +38,7 @@
 #include "Font.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "GuiWorkArea.h"
 #include "Intl.h"
 #include "KeyMap.h"
 #include "Language.h"
@@ -1077,6 +1078,15 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
 		enable = true;
 		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 current window")));
+			flag.setEnabled(false);
+		}
+		break;
+	}
+
+
 	default:
 		return false;
 	}
@@ -1592,6 +1602,63 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 		break;
 	}
 
+	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: ");
+		string commandToRun = argument;
+		if (cmd.getArg(0) == "both") {
+			processHidden = true;
+			msg = _("Applied the following command to all visible and hidden buffers: ");
+			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: ");
+		}
+		FuncRequest const funcToRun = lyxaction.lookupFunc(commandToRun);
+		dr.setMessage(bformat(_("%1$s%2$s"), msg, from_utf8(commandToRun)));
+
+		Buffer * const last = theBufferList().last();
+		Buffer * b = theBufferList().first();
+		Buffer * nextBuf = 0;
+		// We cannot use a for loop as the buffer list cycles.
+		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);
+				}
+			}
+
+			if (b == last)
+				break;
+			b = nextBuf;
+		}
+
+		if (theBufferList().isLoaded(buf)) //the LFUN might have closed buf
+			gv->setBuffer(buf);
+		break;
+	}
+
 	case LFUN_COMMAND_ALTERNATIVES: {
 		// argument contains ';'-terminated commands
 		string arg = argument;

Reply via email to