]> git.lyx.org Git - features.git/commitdiff
#12576 improved file name chooser implementation for GUI dialogs
authorStephan Witt <switt@lyx.org>
Sat, 5 Aug 2023 06:56:35 +0000 (08:56 +0200)
committerStephan Witt <switt@lyx.org>
Sat, 5 Aug 2023 06:56:35 +0000 (08:56 +0200)
- 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

15 files changed:
src/frontends/qt/GuiBibtex.cpp
src/frontends/qt/GuiBibtex.h
src/frontends/qt/GuiCompare.cpp
src/frontends/qt/GuiCompare.h
src/frontends/qt/GuiDialog.cpp
src/frontends/qt/GuiDialog.h
src/frontends/qt/GuiExternal.cpp
src/frontends/qt/GuiExternal.h
src/frontends/qt/GuiGraphics.cpp
src/frontends/qt/GuiGraphics.h
src/frontends/qt/GuiInclude.cpp
src/frontends/qt/GuiInclude.h
src/frontends/qt/GuiPrefs.cpp
src/frontends/qt/GuiPrefs.h
src/frontends/qt/qt_helpers.h

index b9c928a2de7448b1ab1597f29aec6d5c3a7a368e..757c2c95e4094a0863a11bf6f8a6cd5dc0225842 100644 (file)
@@ -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);
index 5d54be755438eecbc32e815feb23ecd613d6eb44..bd0a0ea536d3507ec61eab10aafa338236b1613a 100644 (file)
@@ -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
index e485ec0a548c6de028a6ae5ed6952dfcfd8a84b4..7a58c7a8cd40943b36616659b49a530a9c76bcc2 100644 (file)
@@ -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");
 
index e71a13139ebbfa0e928e1453241bd7b07c0968e8..9538083e900a16c94e8bf1cda16bd4ef2f6f1b76 100644 (file)
@@ -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;
 
index 70d086c7f8ca23d37f7c3a3f6184719aaec87d62..67793df0230a4478c086a27520b6bb24409ea466 100644 (file)
 
 #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
 
index 160357dbc64d02da00fa55be4d28a27faac241c8..50910f434c67196d3dfb07c6db0bdc28435f66af 100644 (file)
@@ -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 ?
index 372053af3b0a897f2c5dc6574281c0325469dfa4..c88be8cdb808a9643edc2bfd6c8435f625d2f694 100644 (file)
@@ -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();
index d83b1138c35265fd1589b57b396c4f16984d98bc..dfb6c5fec1c553b92751bd8aeed6b0c3f77e60a2 100644 (file)
@@ -68,7 +68,7 @@ private:
 
        ///
        QString browse(QString const & input_file,
-                                QString const & template_name) const;
+                                QString const & template_name);
 
        ///
        MapType extra_;
index 6801f4c5d009fbb88c3687f435f575bae2f4c1ee..7ba70fb07a120081b4886cca2d2b7723ef91734f 100644 (file)
@@ -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");
 
index 2687c0836b6710b08ed981a4c781187b68b86389..68ef7ddc5e32f2966b0674642d94d771276b4f8d 100644 (file)
@@ -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
index 6120d669ef5072096cfa3fb346a249d58fc38025..73d4690a303dbd7a9bf8a07570f5f9fa03d93890 100644 (file)
@@ -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");
 
index 1c94692ebeeca4f763a43483d44420ad530a81af..da3972f9b4f68f913840325e21732753e07540b3 100644 (file)
@@ -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:
        ///
index a5f4014874772d747b61ddaa73e0c1b974705b66..a74d97fcc37797cd3a342eb8f0fdd1119a71de6f 100644 (file)
@@ -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);
 }
index d23759089e6160f915d8879e4022600cc6cd5eb9..9c25793877cd9f1799bcaabcfbcd0689b5a00ecc 100644 (file)
@@ -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);
index 6cad775267db5c69fce7e4d001c570024f8ce879..f3230b2d3212566b27fea9dd312877d0cc2c3fde 100644 (file)
@@ -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.