]> git.lyx.org Git - features.git/commitdiff
Allow multiple selections in the file open dialog
authorDaniel Ramoeller <d.lyx@web.de>
Tue, 20 Dec 2022 10:55:25 +0000 (11:55 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 9 Jan 2023 14:52:33 +0000 (15:52 +0100)
Fix for bug #4315.

src/frontends/qt/FileDialog.cpp
src/frontends/qt/FileDialog.h
src/frontends/qt/GuiApplication.cpp
src/frontends/qt/GuiView.cpp
src/frontends/qt/GuiView.h

index 1491939a9903c3c81a622a59a258a7ad5d8437bd..704c34c9e8cb8674107c8fa962d08eb8c6fa3b3d 100644 (file)
@@ -133,21 +133,39 @@ 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;
 }
 
 
index fe75b5bf1e97403be8e6f9b84646622cce2b1f88..3d6a549a7e11e15e5a642f3c11e175c5d7cf0db1 100644 (file)
@@ -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(),
index 967f13415347d15be28eb60027da16cdf86c02de..25ca4b2eff0c41fe98a764224038d28836cbd149 100644 (file)
@@ -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();
index e7a3b296d99e0b87f9176421db329811c7432856..461b09cfd58610eae312768af92cd4f839a5997b 100644 (file)
@@ -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
index 57461d09bf747a3d277ce4ffda9eda51cb8d123c..29687c387bf8badc9e9f224a94d0effb4acd5bdf 100644 (file)
@@ -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 &);