X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt%2FGuiApplication.cpp;h=01a646de37372e84bc6b62219456b2d124859129;hb=20cee1593752df09b6c1d47794eb9971404fa448;hp=306ade54572f2e27b6fbf973a4899c9ff8d1ce81;hpb=80e20e86bef2118bc4bd3a0060d29ac797a29670;p=features.git diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp index 306ade5457..01a646de37 100644 --- a/src/frontends/qt/GuiApplication.cpp +++ b/src/frontends/qt/GuiApplication.cpp @@ -63,6 +63,7 @@ #include "support/convert.h" #include "support/debug.h" #include "support/ExceptionMessage.h" +#include "support/environment.h" #include "support/FileName.h" #include "support/filetools.h" #include "support/ForkedCalls.h" @@ -88,7 +89,9 @@ #include #include #include +#if QT_VERSION < 0x060000 #include +#endif #include #include #include @@ -105,6 +108,9 @@ #include #include #include +#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) +#include +#endif #include #include #include @@ -131,6 +137,7 @@ #if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) +#if (QT_VERSION < 0x060000) #if (QT_VERSION < 0x050000) #include #define QWINDOWSMIME QWindowsMime @@ -138,6 +145,7 @@ #include #define QWINDOWSMIME QWinMime #endif +#endif #ifdef Q_CC_GNU #include #endif @@ -145,7 +153,7 @@ #endif #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && (QT_VERSION < 0x060000) #include #endif // Q_OS_MAC @@ -180,6 +188,24 @@ frontend::Application * createApplication(int & argc, char * argv[]) AllowSetForegroundWindow(ASFW_ANY); #endif + +// Setup high DPI handling. This is a bit complicated, but will be default in Qt6. +// macOS does it by itself. +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_OS_MAC) +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + // Attribute Qt::AA_EnableHighDpiScaling must be set before QCoreApplication is created + if (getEnv("QT_ENABLE_HIGHDPI_SCALING").empty() + && getEnv("QT_AUTO_SCREEN_SCALE_FACTOR").empty()) + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); +#endif + +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + // HighDPI scale factor policy must be set before QGuiApplication is created + if (getEnv("QT_SCALE_FACTOR_ROUNDING_POLICY").empty()) + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); +#endif +#endif + frontend::GuiApplication * guiApp = new frontend::GuiApplication(argc, argv); // I'd rather do that in the constructor, but I do not think that // the palette is accessible there. @@ -490,6 +516,8 @@ IconInfo iconInfo(FuncRequest const & f, bool unknown, bool rtl) name.replace(' ', '_'); name.replace(';', '_'); name.replace('\\', "backslash"); + // avoid duplication for these + name.replace("dialog-toggle", "dialog-show"); names << name; // then special default icon for some lfuns @@ -607,7 +635,8 @@ QPixmap getPixmap(QString const & path, QString const & name, QString const & ex QPixmap pixmap = QPixmap(); if (pixmap.load(fpath)) { - if (fpath.contains("math") || fpath.contains("ipa")) + if (fpath.contains("math") || fpath.contains("ipa") + || fpath.contains("bullets")) return prepareForDarkMode(pixmap); return pixmap; } @@ -723,7 +752,7 @@ public: // //////////////////////////////////////////////////////////////////////// -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && (QT_VERSION < 0x060000) // QMacPasteboardMimeGraphics can only be compiled on Mac. class QMacPasteboardMimeGraphics : public QMacPasteboardMime @@ -783,7 +812,7 @@ public: //////////////////////////////////////////////////////////////////////// // Windows specific stuff goes here... -#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) +#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400 && QT_VERSION < 0x060000) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) // QWindowsMimeMetafile can only be compiled on Windows. @@ -949,7 +978,7 @@ struct GuiApplication::Private , last_state_(Qt::ApplicationInactive) #endif { - #if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) + #if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400 && QT_VERSION < 0x060000) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) /// WMF Mime handler for Windows clipboard. wmf_mime_ = new QWindowsMimeMetafile; @@ -1019,12 +1048,12 @@ struct GuiApplication::Private Qt::ApplicationState last_state_; #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && (QT_VERSION < 0x060000) /// Linkback mime handler for MacOSX. QMacPasteboardMimeGraphics mac_pasteboard_mime_; #endif -#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) +#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400 && QT_VERSION < 0x060000) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) /// WMF Mime handler for Windows clipboard. QWindowsMimeMetafile * wmf_mime_; @@ -1055,7 +1084,7 @@ GuiApplication::GuiApplication(int & argc, char ** argv) QCoreApplication::setOrganizationName(app_name); QCoreApplication::setOrganizationDomain("lyx.org"); QCoreApplication::setApplicationName(lyx_package); -#if QT_VERSION >= 0x050000 +#if QT_VERSION >= 0x050000 && QT_VERSION < 0x060000 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif @@ -1063,8 +1092,11 @@ GuiApplication::GuiApplication(int & argc, char ** argv) setDesktopFileName(lyx_package); #endif - // FIXME Deprecated. Should use QRandomGenerator since 5.10 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) + QRandomGenerator(QDateTime::currentDateTime().toSecsSinceEpoch()); +#else qsrand(QDateTime::currentDateTime().toTime_t()); +#endif // Install LyX translator for missing Qt translations installTranslator(&d->gui_trans_); @@ -1367,10 +1399,17 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const case LFUN_REPEAT: case LFUN_PREFERENCES_SAVE: case LFUN_BUFFER_SAVE_AS_DEFAULT: - case LFUN_DEBUG_LEVEL_SET: // these are handled in our dispatch() break; + case LFUN_DEBUG_LEVEL_SET: { + string bad = Debug::badValue(to_utf8(cmd.argument())); + enable = bad.empty(); + if (!bad.empty()) + flag.message(bformat(_("Bad debug value `%1$s'."), from_utf8(bad))); + break; + } + case LFUN_WINDOW_CLOSE: enable = !d->views_.empty(); break; @@ -1378,6 +1417,7 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const case LFUN_BUFFER_NEW: case LFUN_BUFFER_NEW_TEMPLATE: case LFUN_FILE_OPEN: + case LFUN_LYXFILES_OPEN: case LFUN_HELP_OPEN: case LFUN_SCREEN_FONT_UPDATE: case LFUN_SET_COLOR: @@ -1515,7 +1555,7 @@ void GuiApplication::updateCurrentView(FuncRequest const & cmd, DispatchResult & BufferView * bv = current_view_->currentBufferView(); if (bv) { - if (dr.needBufferUpdate()) { + if (dr.needBufferUpdate() || bv->buffer().needUpdate()) { bv->cursor().clearBufferUpdate(); bv->buffer().updateBuffer(); } @@ -1612,8 +1652,10 @@ void GuiApplication::gotoBookmark(unsigned int idx, bool openFile, void GuiApplication::reconfigure(string const & option) { // emit message signal. - if (current_view_) + if (current_view_) { current_view_->message(_("Running configure...")); + current_view_->setCursor(Qt::WaitCursor); + } // Run configure in user lyx directory string const lock_file = package().getConfigureLockName(); @@ -1627,6 +1669,9 @@ void GuiApplication::reconfigure(string const & option) LaTeXPackages::getAvailable(); fileUnlock(fd, lock_file.c_str()); + if (current_view_) + current_view_->unsetCursor(); + if (ret) Alert::information(_("System reconfiguration failed"), _("The system reconfiguration has failed.\n" @@ -1820,6 +1865,25 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; } + 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 + arg = "templates"; + if (arg != "templates" && arg != "examples") { + current_view_->message(_("Wrong argument. Must be 'examples' or 'templates'.")); + break; + } + lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "lyxfiles " + arg)); + break; + } + case LFUN_SET_COLOR: { string const lyx_name = cmd.getArg(0); string x11_name = cmd.getArg(1); @@ -2127,9 +2191,8 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr) DocumentClassConstPtr olddc = defaults.params().documentClassPtr(); int const unknown_tokens = defaults.readHeader(lex); DocumentClassConstPtr newdc = defaults.params().documentClassPtr(); - ErrorList el; InsetText & theinset = static_cast(defaults.inset()); - cap::switchBetweenClasses(olddc, newdc, theinset, el); + cap::switchBetweenClasses(olddc, newdc, theinset); if (unknown_tokens != 0) { lyxerr << "Warning in LFUN_BUFFER_SAVE_AS_DEFAULT!\n" @@ -2276,7 +2339,8 @@ bool GuiApplication::queryKeySym(KeySymbol const & keysym, // seq has been reset at this point func = seq.addkey(keysym, NoModifier); - LYXERR(Debug::KEY, " Key (queried) [action=" << func.action() << "][" + LYXERR(Debug::KEY, " Key (queried) [action=" + << lyxaction.getActionName(func.action()) << "][" << seq.print(KeySequence::Portable) << ']'); return func.action() != LFUN_UNKNOWN_ACTION; } @@ -2303,7 +2367,8 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state) d->cancel_meta_seq.reset(); FuncRequest func = d->cancel_meta_seq.addkey(keysym, state); - LYXERR(Debug::KEY, "action first set to [" << func.action() << ']'); + LYXERR(Debug::KEY, "action first set to [" + << lyxaction.getActionName(func.action()) << ']'); // When not cancel or meta-fake, do the normal lookup. // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards. @@ -2311,7 +2376,8 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state) if ((func.action() != LFUN_CANCEL) && (func.action() != LFUN_META_PREFIX)) { // remove Caps Lock and Mod2 as a modifiers func = d->keyseq.addkey(keysym, (state | d->meta_fake_bit)); - LYXERR(Debug::KEY, "action now set to [" << func.action() << ']'); + LYXERR(Debug::KEY, "action now set to [" + << lyxaction.getActionName(func.action()) << ']'); } // Don't remove this unless you know what you are doing. @@ -2321,8 +2387,9 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state) if (func.action() == LFUN_NOACTION) func = FuncRequest(LFUN_COMMAND_PREFIX); - LYXERR(Debug::KEY, " Key [action=" << func.action() << "][" - << d->keyseq.print(KeySequence::Portable) << ']'); + LYXERR(Debug::KEY, " Key [action=" + << lyxaction.getActionName(func.action()) << "][" + << d->keyseq.print(KeySequence::Portable) << ']'); // already here we know if it any point in going further // why not return already here if action == -1 and @@ -2339,7 +2406,7 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state) // If addkey looked up a command and did not find further commands then // seq has been reset at this point func = d->keyseq.addkey(keysym, NoModifier); - LYXERR(Debug::KEY, "Action now " << func.action()); + LYXERR(Debug::KEY, "Action now " << lyxaction.getActionName(func.action())); } if (func.action() == LFUN_UNKNOWN_ACTION) { @@ -2516,6 +2583,7 @@ 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(); @@ -2524,6 +2592,16 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow, 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(); + h = match.captured(2).toInt(); + x = match.captured(3).toInt(); + 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(); @@ -2531,7 +2609,11 @@ 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 == '-') @@ -2643,7 +2725,11 @@ void GuiApplication::setGuiLanguage() // opposite. Therefore, long name should be used without truncation. // c.f. http://doc.trolltech.com/4.1/qtranslator.html#load if (!d->qt_trans_.load(language_name, +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { +#else QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { +#endif LYXERR(Debug::LOCALE, "Could not find Qt translations for locale " << language_name); } else {