commit f6083280596217987accb55538ba8bc57814b302
Author: Daniel Ramoeller <[email protected]>
Date:   Tue Dec 20 11:55:25 2022 +0100

    Allow multiple selections in the file open dialog
    
    Fix for bug #4315.
---
 src/frontends/qt/FileDialog.cpp     |   38 ++++++++---
 src/frontends/qt/FileDialog.h       |    6 ++
 src/frontends/qt/GuiApplication.cpp |    4 +-
 src/frontends/qt/GuiView.cpp        |  119 ++++++++++++++++++-----------------
 src/frontends/qt/GuiView.h          |    2 +-
 5 files changed, 99 insertions(+), 70 deletions(-)

diff --git a/src/frontends/qt/FileDialog.cpp b/src/frontends/qt/FileDialog.cpp
index 1491939..704c34c 100644
--- a/src/frontends/qt/FileDialog.cpp
+++ b/src/frontends/qt/FileDialog.cpp
@@ -134,20 +134,38 @@ FileDialog::Result FileDialog::save(QString const & path,
 FileDialog::Result FileDialog::open(QString const & path,
        QStringList const & filters, QString const & suggested)
 {
+       FileDialog::Result result;
+       FileDialog::Results results = openMulti(path, filters, suggested, 
false);
+       result.first = results.first;
+       result.second = results.second.at(0);
+       return result;
+}
+
+
+FileDialog::Results FileDialog::openMulti(QString const & path,
+       QStringList const & filters, QString const & suggested, bool multi)
+{
        LYXERR(Debug::GUI, "Select with path \"" << path
                           << "\", mask \"" << filters.join(";;")
                           << "\", suggested \"" << suggested << '"');
-       FileDialog::Result result;
-       result.first = FileDialog::Chosen;
+       FileDialog::Results results;
+       results.first = FileDialog::Chosen;
 
        if (lyxrc.use_native_filedialog) {
                QString const startsWith = makeAbsPath(suggested, path);
-               QString const file = 
QFileDialog::getOpenFileName(qApp->focusWidget(),
-                               title_, startsWith, filters.join(";;"));
-               if (file.isNull())
-                       result.first = FileDialog::Later;
+               QStringList files;
+               if (multi)
+                       files = 
QFileDialog::getOpenFileNames(qApp->focusWidget(),
+                                       title_, startsWith, filters.join(";;"));
                else
-                       result.second = internalPath(file);
+                       files << 
QFileDialog::getOpenFileName(qApp->focusWidget(),
+                                       title_, startsWith, filters.join(";;"));
+               if (files.isEmpty())
+                       results.first = FileDialog::Later;
+               else {
+                       for (const auto& file : files)
+                               results.second << internalPath(file);
+               }
        } else {
                LyXFileDialog dlg(title_, path, filters, private_->b1, 
private_->b2);
 
@@ -158,12 +176,12 @@ FileDialog::Result FileDialog::open(QString const & path,
                int res = dlg.exec();
                LYXERR(Debug::GUI, "result " << res);
                if (res == QDialog::Accepted)
-                       result.second = internalPath(dlg.selectedFiles()[0]);
+                       results.second << internalPath(dlg.selectedFiles()[0]);
                else
-                       result.first = FileDialog::Later;
+                       results.first = FileDialog::Later;
                dlg.hide();
        }
-       return result;
+       return results;
 }
 
 
diff --git a/src/frontends/qt/FileDialog.h b/src/frontends/qt/FileDialog.h
index fe75b5b..3d6a549 100644
--- a/src/frontends/qt/FileDialog.h
+++ b/src/frontends/qt/FileDialog.h
@@ -41,6 +41,9 @@ public:
        /// result return
        typedef std::pair<FileDialog::ResultType, QString> Result;
 
+       /// result return
+       typedef std::pair<FileDialog::ResultType, QStringList> Results;
+
        /**
         * Constructs a file dialog with title \param title.
         *
@@ -58,6 +61,9 @@ public:
        /// Choose a file for opening, starting in directory \c path.
        Result open(QString const & path, QStringList const & filters,
                          QString const & suggested = QString());
+       /// Choose several files for opening, starting in directory \c path.
+       Results openMulti(QString const & path, QStringList const & filters,
+                         QString const & suggested = QString(), bool multi = 
true);
 
        /// Choose a directory, starting in directory \c path.
        Result opendir(QString const & path = QString(),
diff --git a/src/frontends/qt/GuiApplication.cpp 
b/src/frontends/qt/GuiApplication.cpp
index 967f134..25ca4b2 100644
--- a/src/frontends/qt/GuiApplication.cpp
+++ b/src/frontends/qt/GuiApplication.cpp
@@ -1858,7 +1858,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                        // We want the ui session to be saved per document and 
not per
                        // window number. The filename crc is a good enough 
identifier.
                        createView(support::checksum(fname));
-                       current_view_->openDocument(fname, cmd.origin());
+                       current_view_->openDocuments(fname, cmd.origin());
                        if (!current_view_->documentBufferView())
                                current_view_->close();
                        else if (cmd.origin() == FuncRequest::LYXSERVER) {
@@ -1867,7 +1867,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                                current_view_->showNormal();
                        }
                } else {
-                       current_view_->openDocument(fname, cmd.origin());
+                       current_view_->openDocuments(fname, cmd.origin());
                        if (cmd.origin() == FuncRequest::LYXSERVER) {
                                current_view_->raise();
                                current_view_->activateWindow();
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index e7a3b29..461b09c 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -2792,7 +2792,7 @@ Buffer * GuiView::loadDocument(FileName const & filename, 
bool tolastfiles)
 }
 
 
-void GuiView::openDocument(string const & fname, int origin)
+void GuiView::openDocuments(string const & fname, int origin)
 {
        string initpath = lyxrc.document_path;
 
@@ -2803,10 +2803,10 @@ void GuiView::openDocument(string const & fname, int 
origin)
                        initpath = trypath;
        }
 
-       string filename;
+       QStringList files;
 
        if (fname.empty()) {
-               FileDialog dlg(qt_("Select document to open"));
+               FileDialog dlg(qt_("Select documents to open"));
                dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
                dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
 
@@ -2815,74 +2815,79 @@ void GuiView::openDocument(string const & fname, int 
origin)
                                qt_("LyX Document Backups (*.lyx~)"),
                                qt_("All Files (*.*)")
                });
-               FileDialog::Result result =
-                       dlg.open(toqstr(initpath), filter);
+               FileDialog::Results results =
+                       dlg.openMulti(toqstr(initpath), filter);
 
-               if (result.first == FileDialog::Later)
+               if (results.first == FileDialog::Later)
                        return;
 
-               filename = fromqstr(result.second);
+               files = results.second;
 
                // check selected filename
-               if (filename.empty()) {
+               if (files.isEmpty()) {
                        message(_("Canceled."));
                        return;
                }
        } else
-               filename = fname;
-
-       // get absolute path of file and add ".lyx" to the filename if
-       // necessary.
-       FileName const fullname =
-                       fileSearch(string(), filename, "lyx", 
support::may_not_exist);
-       if (!fullname.empty())
-               filename = fullname.absFileName();
-
-       if (!fullname.onlyPath().isDirectory()) {
-               Alert::warning(_("Invalid filename"),
-                               bformat(_("The directory in the given 
path\n%1$s\ndoes not exist."),
-                               from_utf8(fullname.absFileName())));
-               return;
-       }
+               files << toqstr(fname);
+
+       // iterate over all selected files
+       for (auto const & file : files) {
+               string filename = fromqstr(file);
+
+               // get absolute path of file and add ".lyx" to the filename if
+               // necessary.
+               FileName const fullname =
+                               fileSearch(string(), filename, "lyx", 
support::may_not_exist);
+               if (!fullname.empty())
+                       filename = fullname.absFileName();
+
+               if (!fullname.onlyPath().isDirectory()) {
+                       Alert::warning(_("Invalid filename"),
+                                       bformat(_("The directory in the given 
path\n%1$s\ndoes not exist."),
+                                       from_utf8(fullname.absFileName())));
+                       continue;
+               }
 
-       // if the file doesn't exist and isn't already open (bug 6645),
-       // let the user create one
-       if (!fullname.exists() && !theBufferList().exists(fullname) &&
-           !LyXVC::file_not_found_hook(fullname)) {
-               // see bug #12609
-               if (origin == FuncRequest::MENU) {
-                       docstring const & msg =
-                               bformat(_("File\n"
-                                         "%1$s\n"
-                                         "does not exist. Create empty file?"),
-                                               from_utf8(filename));
-                       int ret = Alert::prompt(_("File does not exist"),
-                                               msg, 0, 1,
-                                               _("Create &File"),
-                                               _("&Cancel"));
-                       if (ret == 1)
-                               return;
+               // if the file doesn't exist and isn't already open (bug 6645),
+               // let the user create one
+               if (!fullname.exists() && !theBufferList().exists(fullname) &&
+                       !LyXVC::file_not_found_hook(fullname)) {
+                       // see bug #12609
+                       if (origin == FuncRequest::MENU) {
+                               docstring const & msg =
+                                       bformat(_("File\n"
+                                               "%1$s\n"
+                                               "does not exist. Create empty 
file?"),
+                                                       from_utf8(filename));
+                               int ret = Alert::prompt(_("File does not 
exist"),
+                                                       msg, 0, 1,
+                                                       _("Create &File"),
+                                                       _("&Cancel"));
+                               if (ret == 1)
+                                       continue;
+                       }
+                       Buffer * const b = newFile(filename, string(), true);
+                       if (b)
+                               setBuffer(b);
+                       continue;
                }
-               Buffer * const b = newFile(filename, string(), true);
-               if (b)
-                       setBuffer(b);
-               return;
-       }
 
-       docstring const disp_fn = makeDisplayPath(filename);
-       message(bformat(_("Opening document %1$s..."), disp_fn));
+               docstring const disp_fn = makeDisplayPath(filename);
+               message(bformat(_("Opening document %1$s..."), disp_fn));
 
-       docstring str2;
-       Buffer * buf = loadDocument(fullname);
-       if (buf) {
-               str2 = bformat(_("Document %1$s opened."), disp_fn);
-               if (buf->lyxvc().inUse())
-                       str2 += " " + from_utf8(buf->lyxvc().versionString()) +
-                               " " + _("Version control detected.");
-       } else {
-               str2 = bformat(_("Could not open document %1$s"), disp_fn);
+               docstring str2;
+               Buffer * buf = loadDocument(fullname);
+               if (buf) {
+                       str2 = bformat(_("Document %1$s opened."), disp_fn);
+                       if (buf->lyxvc().inUse())
+                               str2 += " " + 
from_utf8(buf->lyxvc().versionString()) +
+                                       " " + _("Version control detected.");
+               } else {
+                       str2 = bformat(_("Could not open document %1$s"), 
disp_fn);
+               }
+               message(str2);
        }
-       message(str2);
 }
 
 // FIXME: clean that
diff --git a/src/frontends/qt/GuiView.h b/src/frontends/qt/GuiView.h
index 57461d0..29687c3 100644
--- a/src/frontends/qt/GuiView.h
+++ b/src/frontends/qt/GuiView.h
@@ -164,7 +164,7 @@ public:
        /// closes the buffer
        bool closeBuffer(Buffer & buf);
        ///
-       void openDocument(std::string const & filename, int origin);
+       void openDocuments(std::string const & filename, int origin);
        ///
        void importDocument(std::string const &);
 
-- 
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to