From: Jean-Marc Lasgouttes [lasgout...@lyx.org]
Sent: Sunday, July 15, 2012 5:14 PM

>> +             case LFUN_BUFFER_FORALL: {
>> +                     Buffer * const buf = &currentBufferView()->buffer();
>> +                     if (!buf)
>> +                             break;

>Why is this test needed? The current buffer has nothing to do with
>buffer-forall.

I use buf when I switch back to the current buffer after buffer-forall is done, 
assuming the current buffer still exists (that is, that the LFUN did not close 
it). The check is to make sure there is at least a buffer open, but as long as 
there is a check induced because of not having the NoBuffer property, I can 
take this out.

>Moreover, this code should not be in GuiView, but in
>GuiApplication, since the function is at application level.

ok, I will move it after the other issues are cleared up.

>> +
>> +                     bool processHidden = false;
>> +                     string commandToRun = argument;
>> +                     if (argument.substr(0,13) == "includehidden") {
>> +                             processHidden = true;
>> +                             commandToRun = argument.substr(14, 
>> argument.size());
>> +                     }

> Please do not use string methods by hand. FuncRequest object have
> methods getArg and getLongArg that work very well for these uses.

Done.

>> +
>> +                     docstring const hiddenOrNot = processHidden ? _("all 
>> hidden and non-hidden") : _("all non-hidden");
>> +                     dr.setMessage(bformat(_("Applied the command \"%1$s\" 
>> to %2$s buffers"), from_utf8(commandToRun), hiddenOrNot));

>Please use two complete sentences (one for hidden and one for not
>hidden). Your sentences may be difficult to translate in some languages.

Done. It is three sentences now because I am allowing three options: "visible" 
(default), "hidden", and "both".

>> +
>> +                     Buffer * const last = theBufferList().last();
>> +                     Buffer * b = theBufferList().first();
>> +                     Buffer * nextBuf = 0;
>> +                     // We cannot use a for loop as the buffer list cycles.

>I know this code is taken from somewhere else, but I am not sure why you
>can't use BufferList::begin()/end(). The only problem is maybe what
>happens if the buffer is deleted by the lfun.

Right, with BufferList::begin()/end() I don't think buffer-forall would work 
with LFUNs such as buffer-close. Should I still do it with 
BufferList::begin()/end() and blacklist certain functions? Or just let the user 
be responsible? In the attached patch I did not change it to use 
BufferList::begin()/end().


>> +                     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));
>> +                             if (hidden) {
>> +                                     if (processHidden) {
>> +                                             setBuffer(b);
>> +                                             
>> lyx::dispatch(FuncRequest(lyxaction.lookupFunc(commandToRun)));
>> +                                             GuiWorkArea * const wa = 
>> currentWorkArea();
>> +                                             wa->view().hideWorkArea(wa);
>> +                                     }
>> +                             }
>> +
>> +                             else {
>> +                                     setBuffer(b);
>> +                                     
>> lyx::dispatch(FuncRequest(lyxaction.lookupFunc(commandToRun)));
>> +                             }

>The lookup of commandToRun should be done at the place where the
>arguments are parsed.

Done.

Please see the attached patch.

Thank you for your help,

Scott
diff --git a/src/FuncCode.h b/src/FuncCode.h
index 9a7b06e..2c99432 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, 20120715
 
 	LFUN_LASTACTION                 // end of the table
 };
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 39018ce..ff3f7fe 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -3127,6 +3127,26 @@ 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.
+ * \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
+ * \li Origin: scottkostyshak, 15 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/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index 52a4379..6489303 100644
--- a/src/frontends/qt4/GuiView.cpp
+++ b/src/frontends/qt4/GuiView.cpp
@@ -1679,6 +1679,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 		break;
 	}
 
+	case LFUN_BUFFER_FORALL:
 	case LFUN_BUFFER_WRITE_AS:
 	case LFUN_BUFFER_EXPORT_AS:
 		enable = doc_buffer;
@@ -3332,6 +3333,63 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 			gotoNextOrPreviousBuffer(PREVBUFFER);
 			break;
 
+		case LFUN_BUFFER_FORALL: {
+			Buffer * const buf = &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 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 = !(guiApp->currentView() && guiApp->currentView()->workArea(*b));
+				if (hidden) {
+					if (processHidden) {
+						setBuffer(b);
+						lyx::dispatch(FuncToRun);
+						GuiWorkArea * const wa = currentWorkArea();
+						wa->view().hideWorkArea(wa);
+					}
+				}
+
+				else {
+					if (processVisible) {
+						setBuffer(b);
+						lyx::dispatch(FuncToRun);
+					}
+				}
+
+				if (b == last)
+					break;
+				b = nextBuf;
+			}
+
+			if (theBufferList().isLoaded(buf)) //the LFUN might have closed buf
+				setBuffer(buf);
+			break;
+		}
+
 		case LFUN_COMMAND_EXECUTE: {
 			bool const show_it = cmd.argument() != "off";
 			// FIXME: this is a hack, "minibuffer" should not be

Reply via email to