Make it possible to select (not)native file dialogs at run time

Add a new LyXRC variable use_native_filedialog (true by default) that
allows to select the kind of FileDialog we want at runtime.

(cherry picked from commit af795b80d8)
This commit is contained in:
Jean-Marc Lasgouttes 2018-01-30 14:32:53 +01:00
parent d9314d15dc
commit 977a0c4037
4 changed files with 104 additions and 83 deletions

View File

@ -195,6 +195,7 @@ LexerKeyword lyxrcTags[] = {
{ "\\use_converter_needauth", LyXRC::RC_USE_CONVERTER_NEEDAUTH }, { "\\use_converter_needauth", LyXRC::RC_USE_CONVERTER_NEEDAUTH },
{ "\\use_converter_needauth_forbidden", LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN }, { "\\use_converter_needauth_forbidden", LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN },
{ "\\use_lastfilepos", LyXRC::RC_USELASTFILEPOS }, { "\\use_lastfilepos", LyXRC::RC_USELASTFILEPOS },
{ "\\use_native_filedialog", LyXRC::RC_USE_NATIVE_FILEDIALOG },
{ "\\use_pixmap_cache", LyXRC::RC_USE_PIXMAP_CACHE }, { "\\use_pixmap_cache", LyXRC::RC_USE_PIXMAP_CACHE },
{ "\\use_qimage", LyXRC::RC_USE_QIMAGE }, { "\\use_qimage", LyXRC::RC_USE_QIMAGE },
// compatibility with versions older than 1.4.0 only // compatibility with versions older than 1.4.0 only
@ -273,6 +274,7 @@ void LyXRC::setDefaults()
num_lastfiles = 20; num_lastfiles = 20;
check_lastfiles = true; check_lastfiles = true;
use_lastfilepos = true; use_lastfilepos = true;
use_native_filedialog = true;
load_session = false; load_session = false;
make_backup = true; make_backup = true;
save_compressed = false; save_compressed = false;
@ -873,6 +875,9 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
case RC_ACCEPT_COMPOUND: case RC_ACCEPT_COMPOUND:
lexrc >> spellchecker_accept_compound; lexrc >> spellchecker_accept_compound;
break; break;
case RC_USE_NATIVE_FILEDIALOG:
lexrc >> use_native_filedialog;
break;
case RC_USE_SYSTEM_COLORS: case RC_USE_SYSTEM_COLORS:
lexrc >> use_system_colors; lexrc >> use_system_colors;
break; break;
@ -2410,6 +2415,16 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
// fall through // fall through
case RC_USE_NATIVE_FILEDIALOG:
if (ignore_system_lyxrc ||
use_native_filedialog != system_lyxrc.use_native_filedialog) {
os << "\\use_native_filedialog "
<< convert<string>(use_native_filedialog)
<< '\n';
}
if (tag != RC_LAST)
break;
// fall through
case RC_USE_SYSTEM_COLORS: case RC_USE_SYSTEM_COLORS:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
use_system_colors != system_lyxrc.use_system_colors) { use_system_colors != system_lyxrc.use_system_colors) {
@ -3029,6 +3044,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
case LyXRC::RC_USE_CONVERTER_CACHE: case LyXRC::RC_USE_CONVERTER_CACHE:
case LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN: case LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN:
case LyXRC::RC_USE_CONVERTER_NEEDAUTH: case LyXRC::RC_USE_CONVERTER_NEEDAUTH:
case LyXRC::RC_USE_NATIVE_FILEDIALOG:
case LyXRC::RC_USE_SYSTEM_COLORS: case LyXRC::RC_USE_SYSTEM_COLORS:
case LyXRC::RC_USE_TOOLTIP: case LyXRC::RC_USE_TOOLTIP:
case LyXRC::RC_USE_PIXMAP_CACHE: case LyXRC::RC_USE_PIXMAP_CACHE:

View File

@ -172,6 +172,7 @@ public:
RC_USE_CONVERTER_CACHE, RC_USE_CONVERTER_CACHE,
RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN, RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN,
RC_USE_CONVERTER_NEEDAUTH, RC_USE_CONVERTER_NEEDAUTH,
RC_USE_NATIVE_FILEDIALOG,
RC_USE_SYSTEM_COLORS, RC_USE_SYSTEM_COLORS,
RC_USE_TOOLTIP, RC_USE_TOOLTIP,
RC_USE_PIXMAP_CACHE, RC_USE_PIXMAP_CACHE,
@ -333,6 +334,8 @@ public:
bool use_tooltip; bool use_tooltip;
/// Use the colors from current system theme? /// Use the colors from current system theme?
bool use_system_colors; bool use_system_colors;
/// use native file dialog or our own ?
bool use_native_filedialog;
/// Use pixmap cache? /// Use pixmap cache?
bool use_pixmap_cache; bool use_pixmap_cache;
/// Use QImage backend? /// Use QImage backend?

View File

@ -16,6 +16,8 @@
#include "LyXFileDialog.h" #include "LyXFileDialog.h"
#include "qt_helpers.h" #include "qt_helpers.h"
#include "LyXRC.h"
#include "support/debug.h" #include "support/debug.h"
#include "support/FileName.h" #include "support/FileName.h"
#include "support/filetools.h" #include "support/filetools.h"
@ -24,7 +26,9 @@
#include <string> #include <string>
/** when this is defined, the code will use #include <QApplication>
/** when LyXRC::use_native_filedialog is true, we use
* QFileDialog::getOpenFileName and friends to create filedialogs. * QFileDialog::getOpenFileName and friends to create filedialogs.
* Effects: * Effects:
* - the dialog does not use the quick directory buttons (Button * - the dialog does not use the quick directory buttons (Button
@ -35,13 +39,6 @@
* *
* Therefore there is a tradeoff in enabling or disabling this (JMarc) * Therefore there is a tradeoff in enabling or disabling this (JMarc)
*/ */
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
#define USE_NATIVE_FILEDIALOG 1
#endif
#ifdef USE_NATIVE_FILEDIALOG
#include <QApplication>
#endif
namespace lyx { namespace lyx {
@ -91,38 +88,38 @@ FileDialog::Result FileDialog::save(QString const & path,
FileDialog::Result result; FileDialog::Result result;
result.first = FileDialog::Chosen; result.first = FileDialog::Chosen;
#ifdef USE_NATIVE_FILEDIALOG if (lyxrc.use_native_filedialog) {
QString const startsWith = makeAbsPath(suggested, path); QString const startsWith = makeAbsPath(suggested, path);
QString const name = QString const name =
QFileDialog::getSaveFileName(qApp->focusWidget(), QFileDialog::getSaveFileName(qApp->focusWidget(),
title_, startsWith, filters.join(";;"), title_, startsWith, filters.join(";;"),
selectedFilter, QFileDialog::DontConfirmOverwrite); selectedFilter, QFileDialog::DontConfirmOverwrite);
if (name.isNull()) if (name.isNull())
result.first = FileDialog::Later; result.first = FileDialog::Later;
else else
result.second = toqstr(os::internal_path(fromqstr(name))); result.second = toqstr(os::internal_path(fromqstr(name)));
#else } else {
LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2); LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2);
dlg.setFileMode(QFileDialog::AnyFile); dlg.setFileMode(QFileDialog::AnyFile);
dlg.setAcceptMode(QFileDialog::AcceptSave); dlg.setAcceptMode(QFileDialog::AcceptSave);
dlg.setConfirmOverwrite(false); dlg.setConfirmOverwrite(false);
if (selectedFilter != 0 && !selectedFilter->isEmpty()) if (selectedFilter != 0 && !selectedFilter->isEmpty())
dlg.selectNameFilter(*selectedFilter); dlg.selectNameFilter(*selectedFilter);
if (!suggested.isEmpty()) if (!suggested.isEmpty())
dlg.selectFile(suggested); dlg.selectFile(suggested);
LYXERR(Debug::GUI, "Synchronous FileDialog: "); LYXERR(Debug::GUI, "Synchronous FileDialog: ");
int res = dlg.exec(); int res = dlg.exec();
LYXERR(Debug::GUI, "result " << res); LYXERR(Debug::GUI, "result " << res);
if (res == QDialog::Accepted) if (res == QDialog::Accepted)
result.second = internalPath(dlg.selectedFiles()[0]); result.second = internalPath(dlg.selectedFiles()[0]);
else else
result.first = FileDialog::Later; result.first = FileDialog::Later;
if (selectedFilter != 0) if (selectedFilter != 0)
*selectedFilter = dlg.selectedNameFilter(); *selectedFilter = dlg.selectedNameFilter();
dlg.hide(); dlg.hide();
#endif }
return result; return result;
} }
@ -143,29 +140,29 @@ FileDialog::Result FileDialog::open(QString const & path,
FileDialog::Result result; FileDialog::Result result;
result.first = FileDialog::Chosen; result.first = FileDialog::Chosen;
#ifdef USE_NATIVE_FILEDIALOG if (lyxrc.use_native_filedialog) {
QString const startsWith = makeAbsPath(suggested, path); QString const startsWith = makeAbsPath(suggested, path);
QString const file = QFileDialog::getOpenFileName(qApp->focusWidget(), QString const file = QFileDialog::getOpenFileName(qApp->focusWidget(),
title_, startsWith, filters.join(";;")); title_, startsWith, filters.join(";;"));
if (file.isNull()) if (file.isNull())
result.first = FileDialog::Later; result.first = FileDialog::Later;
else else
result.second = internalPath(file); result.second = internalPath(file);
#else } else {
LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2); LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2);
if (!suggested.isEmpty()) if (!suggested.isEmpty())
dlg.selectFile(suggested); dlg.selectFile(suggested);
LYXERR(Debug::GUI, "Synchronous FileDialog: "); LYXERR(Debug::GUI, "Synchronous FileDialog: ");
int res = dlg.exec(); int res = dlg.exec();
LYXERR(Debug::GUI, "result " << res); LYXERR(Debug::GUI, "result " << res);
if (res == QDialog::Accepted) if (res == QDialog::Accepted)
result.second = internalPath(dlg.selectedFiles()[0]); result.second = internalPath(dlg.selectedFiles()[0]);
else else
result.first = FileDialog::Later; result.first = FileDialog::Later;
dlg.hide(); dlg.hide();
#endif }
return result; return result;
} }
@ -178,33 +175,33 @@ FileDialog::Result FileDialog::opendir(QString const & path,
FileDialog::Result result; FileDialog::Result result;
result.first = FileDialog::Chosen; result.first = FileDialog::Chosen;
#ifdef USE_NATIVE_FILEDIALOG if (lyxrc.use_native_filedialog) {
QString const startsWith = toqstr(makeAbsPath(fromqstr(suggested), QString const startsWith =
fromqstr(path)).absFileName()); toqstr(makeAbsPath(fromqstr(suggested), fromqstr(path)).absFileName());
QString const dir = QFileDialog::getExistingDirectory(qApp->focusWidget(), QString const dir =
title_, startsWith); QFileDialog::getExistingDirectory(qApp->focusWidget(), title_, startsWith);
if (dir.isNull()) if (dir.isNull())
result.first = FileDialog::Later; result.first = FileDialog::Later;
else else
result.second = toqstr(os::internal_path(fromqstr(dir))); result.second = toqstr(os::internal_path(fromqstr(dir)));
#else } else {
LyXFileDialog dlg(title_, path, QStringList(qt_("Directories")), LyXFileDialog dlg(title_, path, QStringList(qt_("Directories")),
private_->b1, private_->b2); private_->b1, private_->b2);
dlg.setFileMode(QFileDialog::DirectoryOnly); dlg.setFileMode(QFileDialog::DirectoryOnly);
if (!suggested.isEmpty()) if (!suggested.isEmpty())
dlg.selectFile(suggested); dlg.selectFile(suggested);
LYXERR(Debug::GUI, "Synchronous FileDialog: "); LYXERR(Debug::GUI, "Synchronous FileDialog: ");
int res = dlg.exec(); int res = dlg.exec();
LYXERR(Debug::GUI, "result " << res); LYXERR(Debug::GUI, "result " << res);
if (res == QDialog::Accepted) if (res == QDialog::Accepted)
result.second = internalPath(dlg.selectedFiles()[0]); result.second = internalPath(dlg.selectedFiles()[0]);
else else
result.first = FileDialog::Later; result.first = FileDialog::Later;
dlg.hide(); dlg.hide();
#endif }
return result; return result;
} }

View File

@ -57,6 +57,11 @@ What's new
snappier, especially on repeated events. As an added bonus, subpixel snappier, especially on repeated events. As an added bonus, subpixel
aliasing is honored in the work area. aliasing is honored in the work area.
- Use native file dialogs on all platforms by default. It is now
possible to switch to LyX custom dialogs (which have extra shortcuts
to relevant directories) by setting the preference
\use_native_filedialog true
- Handle properly top/bottom of inset with mac-like cursor movement - Handle properly top/bottom of inset with mac-like cursor movement
(bug 10701). (bug 10701).