]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt/GuiApplication.cpp
Move LYX_(BEGIN|END)_MUTE_GCC_WARNING macros to their own header.
[lyx.git] / src / frontends / qt / GuiApplication.cpp
index d04511ae7f23f6e68144ec688d5a034cabf42ed7..26288a5f55dd1cf148b1153fa56493f947480c7f 100644 (file)
@@ -71,6 +71,7 @@
 #include "support/lassert.h"
 #include "support/lstrings.h"
 #include "support/lyxalgo.h" // sorted
+#include "support/mute_warning.h"
 #include "support/textutils.h"
 #include "support/Messages.h"
 #include "support/os.h"
@@ -89,9 +90,6 @@
 #include <QByteArray>
 #include <QBitmap>
 #include <QDateTime>
-#if QT_VERSION < 0x060000
-#include <QDesktopWidget>
-#endif
 #include <QEvent>
 #include <QFileOpenEvent>
 #include <QFileInfo>
 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
 #include <QRandomGenerator>
 #endif
-#include <QRegExp>
+#include <QScreen>
 #include <QSessionManager>
 #include <QSettings>
 #include <QSocketNotifier>
 #include <QSortFilterProxyModel>
 #include <QStandardItemModel>
+#include <QSvgRenderer>
 #include <QTimer>
 #include <QTranslator>
 #include <QThreadPool>
 #if (QT_VERSION >= 0x050400)
 #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)
 #if (QT_VERSION >= 0x060000)
+#if (QT_VERSION >= 0x060500)
+#include <QtGui/QWindowsMimeConverter>
+#define QWINDOWSMIME QWindowsMimeConverter
+#define QVARIANTTYPE QMetaType
+#else
 #include <QtGui/private/qguiapplication_p.h>
 #include <QtGui/private/qwindowsmime_p.h>
 #include <QtGui/qpa/qplatformintegration.h>
 #define QVARIANTTYPE QMetaType
 using QWindowsMime = QNativeInterface::Private::QWindowsMime;
 using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
+#endif
 #else
 #include <QWinMime>
 #define QWINDOWSMIME QWinMime
@@ -1024,16 +1029,13 @@ public:
 struct GuiApplication::Private
 {
        Private(): language_model_(nullptr), meta_fake_bit(NoModifier),
-               global_menubar_(nullptr)
-       #if (QT_VERSION >= QT_VERSION_CHECK(5, 1, 0))
-               , last_state_(Qt::ApplicationInactive)
-       #endif
+               global_menubar_(nullptr), last_state_(Qt::ApplicationInactive)
        {
        #if (QT_VERSION >= 0x050400)
        #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)
                /// WMF Mime handler for Windows clipboard.
                wmf_mime_ = new QWindowsMimeMetafile;
-       #if (QT_VERSION >= 0x060000)
+       #if (QT_VERSION >= 0x060000 && QT_VERSION < 0x060500)
                win_app_ = dynamic_cast<QWindowsApplication *>
                        (QGuiApplicationPrivate::platformIntegration());
                win_app_->registerMime(wmf_mime_);
@@ -1043,7 +1045,7 @@ struct GuiApplication::Private
                initKeySequences(&theTopLevelKeymap());
        }
 
-       #if (QT_VERSION >= 0x060000)
+       #if (QT_VERSION >= 0x060000 && QT_VERSION < 0x060500)
        #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)
        ~Private()
        {
@@ -1108,10 +1110,8 @@ struct GuiApplication::Private
 
        /// Only used on mac.
        QMenuBar * global_menubar_;
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 1, 0))
        /// Holds previous application state on Mac
        Qt::ApplicationState last_state_;
-#endif
 
 #if defined(Q_OS_MAC) && (QT_VERSION < 0x060000)
        /// Linkback mime handler for MacOSX.
@@ -1122,7 +1122,7 @@ struct GuiApplication::Private
 #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)
        /// WMF Mime handler for Windows clipboard.
        QWindowsMimeMetafile * wmf_mime_;
-#if (QT_VERSION >= 0x060000)
+#if (QT_VERSION >= 0x060000 && QT_VERSION < 0x060500)
        QWindowsApplication * win_app_;
 #endif
 #endif
@@ -1152,7 +1152,7 @@ GuiApplication::GuiApplication(int & argc, char ** argv)
        QCoreApplication::setOrganizationName(app_name);
        QCoreApplication::setOrganizationDomain("lyx.org");
        QCoreApplication::setApplicationName(lyx_package);
-#if QT_VERSION >= 0x050100 && QT_VERSION < 0x060000
+#if QT_VERSION < 0x060000
        QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
 #endif
 
@@ -1191,11 +1191,9 @@ GuiApplication::GuiApplication(int & argc, char ** argv)
        setupApplescript();
        appleCleanupEditMenu();
        appleCleanupViewMenu();
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 1, 0))
        connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
                        this, SLOT(onApplicationStateChanged(Qt::ApplicationState)));
 #endif
-#endif
 
 #if defined(QPA_XCB)
        // doubleClickInterval() is 400 ms on X11 which is just too long.
@@ -1271,6 +1269,11 @@ docstring Application::mathIcon(docstring const & c)
        return qstring_to_ucs4(findImg(toqstr(c)));
 }
 
+void Application::applyPrefs()
+{
+       if (lyxrc.ui_style != "default")
+               lyx::frontend::GuiApplication::setStyle(toqstr(lyxrc.ui_style));
+}
 
 FuncStatus GuiApplication::getStatus(FuncRequest const & cmd) const
 {
@@ -1821,7 +1824,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        createView(QString(), false); // keep hidden
                        current_view_->newDocument(to_utf8(cmd.argument()));
                        current_view_->show();
-                       setActiveWindow(current_view_);
+                       current_view_->activateWindow();
                } else {
                        current_view_->newDocument(to_utf8(cmd.argument()));
                }
@@ -1858,7 +1861,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);
+                       current_view_->openDocuments(fname, cmd.origin());
                        if (!current_view_->documentBufferView())
                                current_view_->close();
                        else if (cmd.origin() == FuncRequest::LYXSERVER) {
@@ -1867,7 +1870,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                                current_view_->showNormal();
                        }
                } else {
-                       current_view_->openDocument(fname);
+                       current_view_->openDocuments(fname, cmd.origin());
                        if (cmd.origin() == FuncRequest::LYXSERVER) {
                                current_view_->raise();
                                current_view_->activateWindow();
@@ -1904,12 +1907,6 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
        }
 
        case LFUN_LYXFILES_OPEN: {
-               // This is the actual reason for this method (#12106).
-               validateCurrentView();
-               if (!current_view_
-                  || (!lyxrc.open_buffers_in_tabs
-                      && current_view_->documentBufferView() != nullptr))
-                       createView();
                string arg = to_utf8(cmd.argument());
                if (arg.empty())
                        // set default
@@ -2266,17 +2263,15 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 
        case LFUN_DIALOG_SHOW: {
                string const name = cmd.getArg(0);
-
-               if ( name == "aboutlyx"
-                       || name == "prefs"
-                       || name == "texinfo"
-                       || name == "progress"
-                       || name == "compare")
+               // Workaround: on Mac OS the application
+               // is not terminated when closing the last view.
+               // With the following dialogs which should still
+               // be usable, create a new one to be able
+               // to dispatch LFUN_DIALOG_SHOW to this view.
+               if (name == "aboutlyx" || name == "compare"
+                   || name == "lyxfiles" || name == "prefs"
+                   || name == "progress" || name == "texinfo")
                {
-                       // work around: on Mac OS the application
-                       // is not terminated when closing the last view.
-                       // Create a new one to be able to dispatch the
-                       // LFUN_DIALOG_SHOW to this view.
                        if (current_view_ == nullptr)
                                createView();
                }
@@ -2615,7 +2610,7 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow,
 
        if (autoShow) {
                view->show();
-               setActiveWindow(view);
+               view->activateWindow();
        }
 
        if (!geometry_arg.isEmpty()) {
@@ -2623,16 +2618,6 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow,
                int x, y;
                int w, h;
                QChar sx, sy;
-#if QT_VERSION < 0x060000
-               QRegExp re( "[=]*(?:([0-9]+)[xX]([0-9]+)){0,1}[ ]*(?:([+-][0-9]*)){0,1}(?:([+-][0-9]*)){0,1}" );
-               re.indexIn(geometry_arg);
-               w = re.cap(1).toInt();
-               h = re.cap(2).toInt();
-               x = re.cap(3).toInt();
-               y = re.cap(4).toInt();
-               sx = re.cap(3).isEmpty() ? '+' : re.cap(3).at(0);
-               sy = re.cap(4).isEmpty() ? '+' : re.cap(4).at(0);
-#else
                QRegularExpression re( "[=]*(?:([0-9]+)[xX]([0-9]+)){0,1}[ ]*(?:([+-][0-9]*)){0,1}(?:([+-][0-9]*)){0,1}" );
                QRegularExpressionMatch match = re.match(geometry_arg);
                w = match.captured(1).toInt();
@@ -2641,7 +2626,7 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow,
                y = match.captured(4).toInt();
                sx = match.captured(3).isEmpty() ? '+' : match.captured(3).at(0);
                sy = match.captured(4).isEmpty() ? '+' : match.captured(4).at(0);
-#endif
+
                // Set initial geometry such that we can get the frame size.
                view->setGeometry(x, y, w, h);
                int framewidth = view->geometry().x() - view->x();
@@ -2649,11 +2634,7 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow,
                // Negative displacements must be interpreted as distances
                // from the right or bottom screen borders.
                if (sx == '-' || sy == '-') {
-#if QT_VERSION < 0x060000
-                       QRect rec = QApplication::desktop()->screenGeometry();
-#else
                        QRect rec = QGuiApplication::primaryScreen()->geometry();
-#endif
                        if (sx == '-')
                                x += rec.width() - w - framewidth;
                        if (sy == '-')
@@ -2683,6 +2664,30 @@ bool GuiApplication::unhide(Buffer * buf)
 }
 
 
+QPixmap GuiApplication::getScaledPixmap(QString imagedir, QString name) const
+{
+       qreal dpr = 1.0;
+       // Consider device/pixel ratio (HiDPI)
+       if (currentView())
+               dpr = currentView()->devicePixelRatio();
+       // We render SVG directly for HiDPI scalability
+       QPixmap pm = getPixmap(imagedir, name, "svgz,png");
+       FileName fname = imageLibFileSearch(imagedir, name, "svgz,png");
+       QString fpath = toqstr(fname.absFileName());
+       if (!fpath.isEmpty() && !fpath.endsWith(".png")) {
+               QSvgRenderer svgRenderer(fpath);
+               if (svgRenderer.isValid()) {
+                       pm = QPixmap(pm.size() * dpr);
+                       pm.fill(Qt::transparent);
+                       QPainter painter(&pm);
+                       svgRenderer.render(&painter);
+                       pm.setDevicePixelRatio(dpr);
+               }
+       }
+       return pm;
+}
+
+
 Clipboard & GuiApplication::clipboard()
 {
        return d->clipboard_;
@@ -2834,8 +2839,10 @@ QAbstractItemModel * GuiApplication::languageModel()
 
        QStandardItemModel * lang_model = new QStandardItemModel(this);
        lang_model->insertColumns(0, 3);
-       QIcon speller(getPixmap("images/", "dialog-show_spellchecker", "svgz,png"));
-       QIcon saurus(getPixmap("images/", "thesaurus-entry", "svgz,png"));
+       QIcon speller(guiApp ? guiApp->getScaledPixmap("images/", "dialog-show_spellchecker")
+                         : getPixmap("images/", "dialog-show_spellchecker", "svgz,png"));
+       QIcon saurus(guiApp ? guiApp->getScaledPixmap("images/", "thesaurus-entry")
+                         : getPixmap("images/", "thesaurus-entry", "svgz,png"));
        Languages::const_iterator it = lyx::languages.begin();
        Languages::const_iterator end = lyx::languages.end();
        for (; it != end; ++it) {
@@ -2938,11 +2945,7 @@ namespace {
 
 QFont const GuiApplication::typewriterSystemFont()
 {
-#if QT_VERSION >= 0x050200
        QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
-#else
-       QFont font("monospace");
-#endif
        if (!isFixedPitch(font)) {
                // try to enforce a real monospaced font
                font.setStyleHint(QFont::Monospace);
@@ -3436,7 +3439,6 @@ void GuiApplication::onLastWindowClosed()
 }
 
 
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 1, 0))
 void GuiApplication::onApplicationStateChanged(Qt::ApplicationState state)
 {
        std::string name = "unknown";
@@ -3463,7 +3465,6 @@ void GuiApplication::onApplicationStateChanged(Qt::ApplicationState state)
        LYXERR(Debug::GUI, "onApplicationStateChanged..." << name);
        d->last_state_ = state;
 }
-#endif
 
 
 void GuiApplication::startLongOperation() {
@@ -3492,7 +3493,7 @@ bool GuiApplication::longOperationStarted() {
 
 #if defined(QPA_XCB)
 bool GuiApplication::nativeEventFilter(const QByteArray & eventType,
-                                      void * message, long *)
+                                      void * message, QINTPTR *)
 {
        if (!current_view_ || eventType != "xcb_generic_event_t")
                return false;