[LyX/master] #12576 improved file name chooser implementation for GUI dialogs
Stephan Witt
switt at lyx.org
Sat Aug 5 05:42:09 UTC 2023
commit 65ec100f6a13c0ee9b6edecd2b81552373fa70a0
Author: Stephan Witt <switt at lyx.org>
Date: Sat Aug 5 08:56:35 2023 +0200
#12576 improved file name chooser implementation for GUI dialogs
- code reorganization to move the file name chooser methods in GuiDialog class
- on Mac add explicit raise of the current dialog window on close of the file browser to work around the bug 12576
---
src/frontends/qt/GuiBibtex.cpp | 4 +-
src/frontends/qt/GuiBibtex.h | 4 +-
src/frontends/qt/GuiCompare.cpp | 2 +-
src/frontends/qt/GuiCompare.h | 2 +-
src/frontends/qt/GuiDialog.cpp | 128 ++++++++++++++++++++++++++++++++++-
src/frontends/qt/GuiDialog.h | 66 ++++++++++++++++++
src/frontends/qt/GuiExternal.cpp | 2 +-
src/frontends/qt/GuiExternal.h | 2 +-
src/frontends/qt/GuiGraphics.cpp | 2 +-
src/frontends/qt/GuiGraphics.h | 2 +-
src/frontends/qt/GuiInclude.cpp | 2 +-
src/frontends/qt/GuiInclude.h | 2 +-
src/frontends/qt/GuiPrefs.cpp | 140 ++++----------------------------------
src/frontends/qt/GuiPrefs.h | 2 +-
src/frontends/qt/qt_helpers.h | 41 -----------
15 files changed, 220 insertions(+), 181 deletions(-)
diff --git a/src/frontends/qt/GuiBibtex.cpp b/src/frontends/qt/GuiBibtex.cpp
index b9c928a..757c2c9 100644
--- a/src/frontends/qt/GuiBibtex.cpp
+++ b/src/frontends/qt/GuiBibtex.cpp
@@ -491,7 +491,7 @@ void GuiBibtex::applyView()
}
-QString GuiBibtex::browseBib(QString const & in_name) const
+QString GuiBibtex::browseBib(QString const & in_name)
{
QString const label1 = qt_("D&ocuments");
QString const dir1 = toqstr(lyxrc.document_path);
@@ -501,7 +501,7 @@ QString GuiBibtex::browseBib(QString const & in_name) const
}
-QString GuiBibtex::browseBst(QString const & in_name) const
+QString GuiBibtex::browseBst(QString const & in_name)
{
QString const label1 = qt_("D&ocuments");
QString const dir1 = toqstr(lyxrc.document_path);
diff --git a/src/frontends/qt/GuiBibtex.h b/src/frontends/qt/GuiBibtex.h
index 5d54be7..bd0a0ea 100644
--- a/src/frontends/qt/GuiBibtex.h
+++ b/src/frontends/qt/GuiBibtex.h
@@ -56,9 +56,9 @@ private:
void updateContents() override;
/// Browse for a .bib file
- QString browseBib(QString const & in_name) const;
+ QString browseBib(QString const & in_name);
/// Browse for a .bst file
- QString browseBst(QString const & in_name) const;
+ QString browseBst(QString const & in_name);
/// get the list of bst files
QStringList bibStyles() const;
/// get the list of bib files
diff --git a/src/frontends/qt/GuiCompare.cpp b/src/frontends/qt/GuiCompare.cpp
index e485ec0..7a58c7a 100644
--- a/src/frontends/qt/GuiCompare.cpp
+++ b/src/frontends/qt/GuiCompare.cpp
@@ -153,7 +153,7 @@ void GuiCompare::selectOldFile()
}
-QString GuiCompare::browse(QString const & in_name) const
+QString GuiCompare::browse(QString const & in_name)
{
QString const title = qt_("Select document");
diff --git a/src/frontends/qt/GuiCompare.h b/src/frontends/qt/GuiCompare.h
index e71a131..9538083 100644
--- a/src/frontends/qt/GuiCompare.h
+++ b/src/frontends/qt/GuiCompare.h
@@ -80,7 +80,7 @@ private:
void enableControls(bool enable);
/// browse for a file
- QString browse(QString const & in_name) const;
+ QString browse(QString const & in_name);
/// retrieve the buffer from the specified filename
Buffer const * bufferFromFileName(std::string const & file) const;
diff --git a/src/frontends/qt/GuiDialog.cpp b/src/frontends/qt/GuiDialog.cpp
index 70d086c..67793df 100644
--- a/src/frontends/qt/GuiDialog.cpp
+++ b/src/frontends/qt/GuiDialog.cpp
@@ -10,12 +10,14 @@
#include <config.h>
+#include "FileDialog.h"
+#include "GuiApplication.h"
#include "GuiDialog.h"
-
#include "GuiView.h"
#include "qt_helpers.h"
#include "support/debug.h"
+#include "support/filetools.h"
#include <QCloseEvent>
#include <QDialogButtonBox>
@@ -156,6 +158,130 @@ void GuiDialog::updateView()
setUpdatesEnabled(true);
}
+QString GuiDialog::browseFile(QString const & filename,
+ QString const & title,
+ QStringList const & filters,
+ bool save,
+ QString const & label1,
+ QString const & dir1,
+ QString const & label2,
+ QString const & dir2,
+ QString const & fallback_dir)
+{
+ QString lastPath = ".";
+ if (!filename.isEmpty())
+ lastPath = onlyPath(filename);
+ else if(!fallback_dir.isEmpty())
+ lastPath = fallback_dir;
+
+ FileDialog dlg(title);
+ dlg.setButton1(label1, dir1);
+ dlg.setButton2(label2, dir2);
+
+ FileDialog::Result result;
+
+ if (save)
+ result = dlg.save(lastPath, filters, onlyFileName(filename));
+ else
+ result = dlg.open(lastPath, filters, onlyFileName(filename));
+
+ if (guiApp->platformName() == "cocoa") {
+ QWidget * dialog = asQWidget();
+ dialog->raise();
+ dialog->activateWindow();
+ }
+
+ return result.second;
+}
+
+
+/** Launch a file dialog and return the chosen directory.
+ pathname: a suggested pathname.
+ title: the title of the dialog.
+ dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
+*/
+QString GuiDialog::browseDir(QString const & pathname,
+ QString const & title,
+ QString const & label1,
+ QString const & dir1,
+ QString const & label2,
+ QString const & dir2)
+{
+ QString lastPath = ".";
+ if (!pathname.isEmpty())
+ lastPath = onlyPath(pathname);
+
+ FileDialog dlg(title);
+ dlg.setButton1(label1, dir1);
+ dlg.setButton2(label2, dir2);
+
+ FileDialog::Result const result =
+ dlg.opendir(lastPath, onlyFileName(pathname));
+
+ if (guiApp->platformName() == "cocoa") {
+ QWidget * dialog = asQWidget();
+ dialog->raise();
+ dialog->activateWindow();
+ }
+
+ return result.second;
+}
+
+QString GuiDialog::browseRelToParent(
+ QString const & filename,
+ QString const & relpath,
+ QString const & title,
+ QStringList const & filters,
+ bool save,
+ QString const & label1,
+ QString const & dir1,
+ QString const & label2,
+ QString const & dir2)
+{
+ QString const fname = makeAbsPath(filename, relpath);
+
+ QString const outname =
+ browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
+
+ QString const reloutname =
+ toqstr(support::makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
+
+ if (reloutname.startsWith("../"))
+ return outname;
+ else
+ return reloutname;
+}
+
+
+QString GuiDialog::browseRelToSub(
+ QString const & filename,
+ QString const & relpath,
+ QString const & title,
+ QStringList const & filters,
+ bool save,
+ QString const & label1,
+ QString const & dir1,
+ QString const & label2,
+ QString const & dir2)
+{
+ QString const fname = makeAbsPath(filename, relpath);
+
+ QString const outname =
+ browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
+
+ QString const reloutname =
+ toqstr(support::makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
+
+ QString testname = reloutname;
+ testname.remove(QRegularExpression("^(\\.\\./)+"));
+
+ if (testname.contains("/"))
+ return outname;
+ else
+ return reloutname;
+}
+
+
} // namespace frontend
} // namespace lyx
diff --git a/src/frontends/qt/GuiDialog.h b/src/frontends/qt/GuiDialog.h
index 160357d..50910f4 100644
--- a/src/frontends/qt/GuiDialog.h
+++ b/src/frontends/qt/GuiDialog.h
@@ -112,6 +112,72 @@ public:
/// Update the display of the dialog whilst it is still visible.
void updateView() override;
+
+ /** Launch a file dialog and return the chosen file.
+ filename: a suggested filename.
+ title: the title of the dialog.
+ filters: *.ps etc.
+ dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
+ */
+ QString browseFile(QString const & filename,
+ QString const & title,
+ QStringList const & filters,
+ bool save = false,
+ QString const & label1 = QString(),
+ QString const & dir1 = QString(),
+ QString const & label2 = QString(),
+ QString const & dir2 = QString(),
+ QString const & fallback_dir = QString());
+ /** Launch a file dialog and return the chosen directory.
+ pathname: a suggested pathname.
+ title: the title of the dialog.
+ dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
+ */
+ QString browseDir(QString const & pathname,
+ QString const & title,
+ QString const & label1 = QString(),
+ QString const & dir1 = QString(),
+ QString const & label2 = QString(),
+ QString const & dir2 = QString());
+ /** Wrappers around browseFile which try to provide a filename relative to relpath.
+
+ \param title: title for dialog
+
+ \param filters: *.ps, etc
+
+ \param save: whether to save dialog info (current path, etc) for next use.
+
+ The \param labelN and \param dirN arguments provide for extra buttons
+ in the dialog (e.g., "Templates" and a path to that directory).
+
+ The difference between the functions concerns when we think we have a
+ relative path.
+
+ In \c browseRelToParent, we return a relative path only if it IS NOT of
+ the form "../../foo.txt".
+
+ In \c browseRelToSub, we return a relative path only if it IS of the
+ form "../../foo.txt".
+ */
+ QString browseRelToParent(QString const & filename,
+ QString const & relpath,
+ QString const & title,
+ QStringList const & filters,
+ bool save = false,
+ QString const & label1 = QString(),
+ QString const & dir1 = QString(),
+ QString const & label2 = QString(),
+ QString const & dir2 = QString());
+ QString browseRelToSub(QString const & filename,
+ QString const & relpath,
+ QString const & title,
+ QStringList const & filters,
+ bool save = false,
+ QString const & label1 = QString(),
+ QString const & dir1 = QString(),
+ QString const & label2 = QString(),
+ QString const & dir2 = QString());
+
private:
ButtonController bc_;
/// are we updating ?
diff --git a/src/frontends/qt/GuiExternal.cpp b/src/frontends/qt/GuiExternal.cpp
index 372053a..c88be8c 100644
--- a/src/frontends/qt/GuiExternal.cpp
+++ b/src/frontends/qt/GuiExternal.cpp
@@ -682,7 +682,7 @@ static QStringList templateFilters(QString const & template_name)
QString GuiExternal::browse(QString const & input,
- QString const & template_name) const
+ QString const & template_name)
{
QString const title = qt_("Select external file");
QString const bufpath = bufferFilePath();
diff --git a/src/frontends/qt/GuiExternal.h b/src/frontends/qt/GuiExternal.h
index d83b113..dfb6c5f 100644
--- a/src/frontends/qt/GuiExternal.h
+++ b/src/frontends/qt/GuiExternal.h
@@ -68,7 +68,7 @@ private:
///
QString browse(QString const & input_file,
- QString const & template_name) const;
+ QString const & template_name);
///
MapType extra_;
diff --git a/src/frontends/qt/GuiGraphics.cpp b/src/frontends/qt/GuiGraphics.cpp
index 6801f4c..7ba70fb 100644
--- a/src/frontends/qt/GuiGraphics.cpp
+++ b/src/frontends/qt/GuiGraphics.cpp
@@ -823,7 +823,7 @@ void GuiGraphics::dispatchParams()
}
-QString GuiGraphics::browse(QString const & in_name) const
+QString GuiGraphics::browse(QString const & in_name)
{
QString const title = qt_("Select graphics file");
diff --git a/src/frontends/qt/GuiGraphics.h b/src/frontends/qt/GuiGraphics.h
index 2687c08..68ef7dd 100644
--- a/src/frontends/qt/GuiGraphics.h
+++ b/src/frontends/qt/GuiGraphics.h
@@ -71,7 +71,7 @@ private:
/// does the bounding box differ from the file?
bool isChangedBB();
/// Browse for a file
- QString browse(QString const &) const;
+ QString browse(QString const &);
/// Read the Bounding Box from a eps or ps-file
std::string readBoundingBox(std::string const & file);
/// test if file exist
diff --git a/src/frontends/qt/GuiInclude.cpp b/src/frontends/qt/GuiInclude.cpp
index 6120d66..73d4690 100644
--- a/src/frontends/qt/GuiInclude.cpp
+++ b/src/frontends/qt/GuiInclude.cpp
@@ -359,7 +359,7 @@ void GuiInclude::browse()
}
-QString GuiInclude::browse(QString const & in_name, Type in_type) const
+QString GuiInclude::browse(QString const & in_name, Type in_type)
{
QString const title = qt_("Select document to include");
diff --git a/src/frontends/qt/GuiInclude.h b/src/frontends/qt/GuiInclude.h
index 1c94692..da3972f 100644
--- a/src/frontends/qt/GuiInclude.h
+++ b/src/frontends/qt/GuiInclude.h
@@ -79,7 +79,7 @@ private:
/// update
void updateContents() override {}
/// Browse for a file
- QString browse(QString const &, Type) const;
+ QString browse(QString const &, Type);
private:
///
diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp
index a5f4014..a74d97f 100644
--- a/src/frontends/qt/GuiPrefs.cpp
+++ b/src/frontends/qt/GuiPrefs.cpp
@@ -80,124 +80,6 @@ using namespace lyx::support;
using namespace lyx::support::os;
namespace lyx {
-namespace frontend {
-
-/////////////////////////////////////////////////////////////////////
-//
-// Browser Helpers
-//
-/////////////////////////////////////////////////////////////////////
-
-/** Launch a file dialog and return the chosen file.
- filename: a suggested filename.
- title: the title of the dialog.
- filters: *.ps etc.
- dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
-*/
-QString browseFile(QString const & filename,
- QString const & title,
- QStringList const & filters,
- bool save = false,
- QString const & label1 = QString(),
- QString const & dir1 = QString(),
- QString const & label2 = QString(),
- QString const & dir2 = QString(),
- QString const & fallback_dir = QString())
-{
- QString lastPath = ".";
- if (!filename.isEmpty())
- lastPath = onlyPath(filename);
- else if(!fallback_dir.isEmpty())
- lastPath = fallback_dir;
-
- FileDialog dlg(title);
- dlg.setButton1(label1, dir1);
- dlg.setButton2(label2, dir2);
-
- FileDialog::Result result;
-
- if (save)
- result = dlg.save(lastPath, filters, onlyFileName(filename));
- else
- result = dlg.open(lastPath, filters, onlyFileName(filename));
-
- return result.second;
-}
-
-
-/** Launch a file dialog and return the chosen directory.
- pathname: a suggested pathname.
- title: the title of the dialog.
- dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
-*/
-QString browseDir(QString const & pathname,
- QString const & title,
- QString const & label1 = QString(),
- QString const & dir1 = QString(),
- QString const & label2 = QString(),
- QString const & dir2 = QString())
-{
- QString lastPath = ".";
- if (!pathname.isEmpty())
- lastPath = onlyPath(pathname);
-
- FileDialog dlg(title);
- dlg.setButton1(label1, dir1);
- dlg.setButton2(label2, dir2);
-
- FileDialog::Result const result =
- dlg.opendir(lastPath, onlyFileName(pathname));
-
- return result.second;
-}
-
-
-} // namespace frontend
-
-
-QString browseRelToParent(QString const & filename, QString const & relpath,
- QString const & title, QStringList const & filters, bool save,
- QString const & label1, QString const & dir1,
- QString const & label2, QString const & dir2)
-{
- QString const fname = makeAbsPath(filename, relpath);
-
- QString const outname =
- frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
-
- QString const reloutname =
- toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
-
- if (reloutname.startsWith("../"))
- return outname;
- else
- return reloutname;
-}
-
-
-QString browseRelToSub(QString const & filename, QString const & relpath,
- QString const & title, QStringList const & filters, bool save,
- QString const & label1, QString const & dir1,
- QString const & label2, QString const & dir2)
-{
- QString const fname = makeAbsPath(filename, relpath);
-
- QString const outname =
- frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
-
- QString const reloutname =
- toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
-
- QString testname = reloutname;
- testname.remove(QRegularExpression("^(\\.\\./)+"));
-
- if (testname.contains("/"))
- return outname;
- else
- return reloutname;
-}
-
-
/////////////////////////////////////////////////////////////////////
//
@@ -1478,7 +1360,7 @@ void PrefPaths::updateRC(LyXRC const & rc)
void PrefPaths::selectExampledir()
{
- QString file = browseDir(internalPath(exampleDirED->text()),
+ QString file = form_->browseDir(internalPath(exampleDirED->text()),
qt_("Select directory for example files"));
if (!file.isEmpty())
exampleDirED->setText(file);
@@ -1487,7 +1369,7 @@ void PrefPaths::selectExampledir()
void PrefPaths::selectTemplatedir()
{
- QString file = browseDir(internalPath(templateDirED->text()),
+ QString file = form_->browseDir(internalPath(templateDirED->text()),
qt_("Select a document templates directory"));
if (!file.isEmpty())
templateDirED->setText(file);
@@ -1496,7 +1378,7 @@ void PrefPaths::selectTemplatedir()
void PrefPaths::selectTempdir()
{
- QString file = browseDir(internalPath(tempDirED->text()),
+ QString file = form_->browseDir(internalPath(tempDirED->text()),
qt_("Select a temporary directory"));
if (!file.isEmpty())
tempDirED->setText(file);
@@ -1505,7 +1387,7 @@ void PrefPaths::selectTempdir()
void PrefPaths::selectBackupdir()
{
- QString file = browseDir(internalPath(backupDirED->text()),
+ QString file = form_->browseDir(internalPath(backupDirED->text()),
qt_("Select a backups directory"));
if (!file.isEmpty())
backupDirED->setText(file);
@@ -1514,7 +1396,7 @@ void PrefPaths::selectBackupdir()
void PrefPaths::selectWorkingdir()
{
- QString file = browseDir(internalPath(workingDirED->text()),
+ QString file = form_->browseDir(internalPath(workingDirED->text()),
qt_("Select a document directory"));
if (!file.isEmpty())
workingDirED->setText(file);
@@ -1523,7 +1405,7 @@ void PrefPaths::selectWorkingdir()
void PrefPaths::selectThesaurusdir()
{
- QString file = browseDir(internalPath(thesaurusDirED->text()),
+ QString file = form_->browseDir(internalPath(thesaurusDirED->text()),
qt_("Set the path to the thesaurus dictionaries"));
if (!file.isEmpty())
thesaurusDirED->setText(file);
@@ -1532,7 +1414,7 @@ void PrefPaths::selectThesaurusdir()
void PrefPaths::selectHunspelldir()
{
- QString file = browseDir(internalPath(hunspellDirED->text()),
+ QString file = form_->browseDir(internalPath(hunspellDirED->text()),
qt_("Set the path to the Hunspell dictionaries"));
if (!file.isEmpty())
hunspellDirED->setText(file);
@@ -3718,6 +3600,12 @@ QString GuiPreferences::browseLibFile(QString const & dir,
guilyxfiles_->passParams(fromqstr(dir));
guilyxfiles_->selectItem(name);
guilyxfiles_->exec();
+
+ if (frontend::guiApp->platformName() == "cocoa") {
+ QWidget * dialog_ = asQWidget();
+ dialog_->raise();
+ dialog_->activateWindow();
+ }
QString const result = uifile_;
@@ -3756,7 +3644,7 @@ QString GuiPreferences::browsekbmap(QString const & file)
QString GuiPreferences::browse(QString const & file,
- QString const & title) const
+ QString const & title)
{
return browseFile(file, title, QStringList(), true);
}
diff --git a/src/frontends/qt/GuiPrefs.h b/src/frontends/qt/GuiPrefs.h
index d237590..9c25793 100644
--- a/src/frontends/qt/GuiPrefs.h
+++ b/src/frontends/qt/GuiPrefs.h
@@ -92,7 +92,7 @@ public:
QString browsekbmap(QString const & file);
/// general browse
- QString browse(QString const & file, QString const & title) const;
+ QString browse(QString const & file, QString const & title);
/// set a color
void setColor(ColorCode col, QString const & hex);
diff --git a/src/frontends/qt/qt_helpers.h b/src/frontends/qt/qt_helpers.h
index 6cad775..f3230b2 100644
--- a/src/frontends/qt/qt_helpers.h
+++ b/src/frontends/qt/qt_helpers.h
@@ -120,47 +120,6 @@ support::FileName imageLibFileSearch(QString & dir, QString const & name,
QString const & ext = QString(),
support::search_mode mode = support::must_exist);
-/** Wrappers around browseFile which try to provide a filename
- relative to relpath.
-
-\param title: title for dialog
-
-\param filters: *.ps, etc
-
-\param save: whether to save dialog info (current path, etc) for next use.
-
-The \param labelN and \param dirN arguments provide for extra buttons
-in the dialog (e.g., "Templates" and a path to that directory).
-
-The difference between the functions concerns when we think we have a
-relative path.
-
-In \c browseRelToParent, we return a relative path only if it IS NOT of
- the form "../../foo.txt".
-
-In \c browseRelToSub, we return a relative path only if it IS of the
- form "../../foo.txt".
-*/
-QString browseRelToParent(QString const & filename,
- QString const & relpath,
- QString const & title,
- QStringList const & filters,
- bool save = false,
- QString const & label1 = QString(),
- QString const & dir1 = QString(),
- QString const & label2 = QString(),
- QString const & dir2 = QString());
-
-QString browseRelToSub(QString const & filename,
- QString const & relpath,
- QString const & title,
- QStringList const & filters,
- bool save = false,
- QString const & label1 = QString(),
- QString const & dir1 = QString(),
- QString const & label2 = QString(),
- QString const & dir2 = QString());
-
/** Build filelists of all available bst/cls/sty-files. Done through
* kpsewhich and an external script, saved in *Files.lst.
* \param arg: cls, sty, bst, or bib, as required by TeXFiles.py.
More information about the lyx-cvs
mailing list