Fix ToC action when cursor is in adv. F&R pane

This important part is the last point, the rest is what is needed to
make it happen.

* implement (FindAndReplace|FindAndReplaceWidget)::hasWorkArea, that
  tell whether a work area is own by the advanced find & replace
  widget.

* factor out method find() from GuiView::findOrBuild.

* implement GuiView::hasVisibleWorkArea, that tells whether a workarea
  is visible in the view (current tab in a split or adv. f&r
  workarea).

* Finally, in TocWidget::sendDispatch, change the current workarea
  temporarily to the document workarea before dispatching the
  function. The code tries to be as careful as possible to handle all
  cases. The future will tell whether it is good enough.
This commit is contained in:
Jean-Marc Lasgouttes 2022-06-28 23:17:05 +02:00
parent 2283440e77
commit ae528715d3
5 changed files with 51 additions and 2 deletions

View File

@ -721,6 +721,11 @@ void FindAndReplaceWidget::updateButtons()
}
bool FindAndReplaceWidget::hasWorkArea(GuiWorkArea * wa) const
{
return wa == find_work_area_ || wa == replace_work_area_;
}
} // namespace frontend
} // namespace lyx

View File

@ -36,6 +36,9 @@ public:
void updateGUI();
void updateButtons();
// return true if \c wa is one if the adv. F&R workareas
bool hasWorkArea(GuiWorkArea * wa) const;
public Q_SLOTS:
///
void dockLocationChanged(Qt::DockWidgetArea area);
@ -97,6 +100,7 @@ public:
void dispatchParams() override {}
bool isBufferDependent() const override { return false; }
bool canApplyToReadOnly() const override { return true; }
bool hasWorkArea(GuiWorkArea * wa) const { return widget_->hasWorkArea(wa); }
void selectAll();
/// update

View File

@ -18,6 +18,7 @@
#include "DialogFactory.h"
#include "DispatchResult.h"
#include "FileDialog.h"
#include "FindAndReplace.h"
#include "FontLoader.h"
#include "GuiApplication.h"
#include "GuiClickableLabel.h"
@ -1867,6 +1868,17 @@ void GuiView::removeWorkArea(GuiWorkArea * wa)
}
bool GuiView::hasVisibleWorkArea(GuiWorkArea * wa) const
{
for (int i = 0; i < d.splitter_->count(); ++i)
if (d.tabWorkArea(i)->currentWorkArea() == wa)
return true;
FindAndReplace * fr = static_cast<FindAndReplace*>(find("findreplaceadv", false));
return fr->isVisible() && fr->hasWorkArea(wa);
}
LayoutBox * GuiView::getLayoutDialog() const
{
return d.layout_;
@ -5034,7 +5046,7 @@ void GuiView::flatGroupBoxes(const QObject * widget, bool flag)
}
Dialog * GuiView::findOrBuild(string const & name, bool hide_it)
Dialog * GuiView::find(string const & name, bool hide_it) const
{
if (!isValidName(name))
return nullptr;
@ -5046,8 +5058,17 @@ Dialog * GuiView::findOrBuild(string const & name, bool hide_it)
it->second->hideView();
return it->second.get();
}
return nullptr;
}
Dialog * dialog = build(name);
Dialog * GuiView::findOrBuild(string const & name, bool hide_it)
{
Dialog * dialog = find(name, hide_it);
if (dialog != nullptr)
return dialog;
dialog = build(name);
d.dialogs_[name].reset(dialog);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
// Force a uniform style for group boxes

View File

@ -206,6 +206,8 @@ public:
void setCurrentWorkArea(GuiWorkArea * work_area);
///
void removeWorkArea(GuiWorkArea * work_area);
/// return true if \c wa is one of the visibles workareas of this view
bool hasVisibleWorkArea(GuiWorkArea * wa) const;
/// return the current WorkArea (the one that has the focus).
GuiWorkArea const * currentWorkArea() const;
/// return the current WorkArea (the one that has the focus).
@ -472,6 +474,8 @@ private:
/// Is the dialog currently visible?
bool isDialogVisible(std::string const & name) const;
///
Dialog * find(std::string const & name, bool hide_it) const;
///
Dialog * findOrBuild(std::string const & name, bool hide_it);
///
Dialog * build(std::string const & name);

View File

@ -380,7 +380,22 @@ void TocWidget::sendDispatch(FuncRequest fr)
{
fr.setViewOrigin(&gui_view_);
GuiWorkArea * old_wa = gui_view_.currentWorkArea();
GuiWorkArea * doc_wa = gui_view_.currentMainWorkArea();
/* The ToC command should be dispatched to the document work area,
* not the Adv. Find&Replace (which is the only other know
* possibility.
*/
if (doc_wa != nullptr && doc_wa != old_wa)
gui_view_.setCurrentWorkArea(doc_wa);
DispatchResult const & dr = dispatch(fr);
/* If the current workarea has not explicitely changed, and the
* original one is still visible, let's reset it.
*/
if (gui_view_.currentWorkArea() == doc_wa
&& gui_view_.hasVisibleWorkArea(old_wa)
&& doc_wa != old_wa)
gui_view_.setCurrentWorkArea(old_wa);
if (dr.error())
gui_view_.message(dr.message());
}