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() || !¤tView()->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;
}