diff --git a/config/lyxinclude.m4 b/config/lyxinclude.m4 index 4fb2a8d44e..5d6bb1da86 100644 --- a/config/lyxinclude.m4 +++ b/config/lyxinclude.m4 @@ -63,7 +63,16 @@ AC_MSG_RESULT([$withval]) ]) -dnl Check whether to configure for Qt4 or Qt5. Default is Qt5. +dnl Check whether to configure for Qt4, Qt5, or Qt6. Default is Qt5. +dnl +AC_DEFUN([LYX_CHECK_QT6],[ +AC_MSG_CHECKING([whether Qt6 is requested]) +AC_ARG_ENABLE([qt6], + [AS_HELP_STRING([--enable-qt6],[use Qt6 for building])], + USE_QT6=$enableval, USE_QT6=no) +AC_MSG_RESULT([$USE_QT6]) +AC_SUBST([USE_QT6]) +]) dnl AC_DEFUN([LYX_CHECK_QT5],[ AC_MSG_CHECKING([whether Qt5 is disabled]) @@ -372,7 +381,7 @@ if test x$GXX = xyes; then AM_CXXFLAGS="$AM_CXXFLAGS -fno-omit-frame-pointer" fi - if test x$USE_QT5 = xyes ; then + if test x$USE_QT5 = xyes -o x$USE_QT6 = xyes; then AS_CASE([$host], [*mingw*|*cygwin*], [], [AM_CXXFLAGS="-fPIC $AM_CXXFLAGS"]) fi dnl Warnings are for preprocessor too diff --git a/config/qt.m4 b/config/qt.m4 index 6e2d6bcd3f..4b1bfc4068 100644 --- a/config/qt.m4 +++ b/config/qt.m4 @@ -26,7 +26,10 @@ AC_DEFUN([QT_CHECK_COMPILE], CXXFLAGS="$CXXFLAGS $QT_INCLUDES $QT_LDFLAGS" qt_corelibs="-lQtCore -lQtCore4" qt_guilibs="'-lQtCore -lQtGui' '-lQtCore4 -lQtGui4'" - if test $USE_QT5 = "yes" ; then + if test $USE_QT6 = "yes" ; then + qt_corelibs="-lQt6Core -lQt6Core5Compat" + qt_guilibs="-lQt6Core -lQt6Core5Compat -lQt6Concurrent -lQt6Gui -lQt6Svg -lQt6Widgets" + elif test $USE_QT5 = "yes" ; then qt_corelibs="-lQt5Core" qt_guilibs="-lQt5Core -lQt5Concurrent -lQt5Gui -lQt5Svg -lQt5Widgets" fi @@ -52,7 +55,9 @@ AC_DEFUN([QT_CHECK_COMPILE], ]) if test -z "$qt_cv_libname"; then - if test x$USE_QT5 = xyes ; then + if test x$USE_QT6 = xyes ; then + AC_MSG_RESULT([failed, retrying with Qt5]) + elif test x$USE_QT5 = xyes ; then AC_MSG_RESULT([failed, retrying with Qt4]) else AC_MSG_RESULT([failed]) @@ -68,7 +73,9 @@ AC_DEFUN([QT_FIND_TOOL], [ $1= qt_ext=qt4 - if test "x$USE_QT5" != "xno" ; then + if test "x$USE_QT6" != "xno" ; then + qt_ext=qt6 + elif test "x$USE_QT5" != "xno" ; then qt_ext=qt5 fi @@ -161,17 +168,41 @@ AC_DEFUN([QT_DO_IT_ALL], dnl Check if it possible to do a pkg-config PKG_PROG_PKG_CONFIG - if test -n "$PKG_CONFIG" ; then - QT_DO_PKG_CONFIG - fi - if test "$pkg_failed" != "no" ; then - QT_DO_MANUAL_CONFIG + dnl Not possible with Qt6 (QTBUG-86080) + if test x$USE_QT6 = xno ; then + if test -n "$PKG_CONFIG" ; then + QT_DO_PKG_CONFIG + fi + if test "$pkg_failed" != "no" ; then + QT_DO_MANUAL_CONFIG + fi + else + QT6_QMAKE_CONFIG + if test -z "$QT_LIB"; then + QT_DO_MANUAL_CONFIG + fi fi if test -z "$QT_LIB"; then - dnl Try again with Qt4 if configuring for Qt5 fails - if test x$USE_QT5 = xyes ; then + dnl Try again with Qt5 and then Qt4 if configuring for Qt6/5 fails + if test x$USE_QT6 = xyes ; then + USE_QT6=no + USE_QT5=yes + AC_SUBST([USE_QT6]) + AC_SUBST([USE_QT5]) + if test -n "$PKG_CONFIG" ; then + QT_DO_PKG_CONFIG + fi + if test "$pkg_failed" != "no" ; then + QT_DO_MANUAL_CONFIG + fi + if test -z "$QT_LIB"; then + AC_MSG_ERROR([cannot find qt libraries.]) + fi + elif test x$USE_QT5 = xyes ; then + USE_QT6=no USE_QT5=no + AC_SUBST([USE_QT6]) AC_SUBST([USE_QT5]) if test -n "$PKG_CONFIG" ; then QT_DO_PKG_CONFIG @@ -197,8 +228,21 @@ AC_DEFUN([QT_DO_IT_ALL], AC_CHECK_HEADER(QtGui/qtgui-config.h, [lyx_qt5_config=QtGui/qtgui-config.h], [lyx_qt5_config=qconfig.h],[-]) + AC_CHECK_HEADER(QtGui/private/qtgui-config_p.h, + [lyx_qt6_config=QtGui/private/qtgui-config_p.h], + [lyx_qt6_config=qconfig.h],[-]) AC_MSG_CHECKING([whether Qt uses the X Window system]) - if test x$USE_QT5 = xyes ; then + if test x$USE_QT6 = xyes ; then + dnl FIXME: Check whether defining QPA_XCB makes sense with Qt6 + AC_PREPROC_IFELSE([AC_LANG_SOURCE([ + [#include <$lyx_qt6_config>] + [#if !defined(QT_FEATURE_xcb) || QT_FEATURE_xcb < 0] + [#error Fail] + [#endif]])], + [AC_MSG_RESULT(yes) + AC_DEFINE(QPA_XCB, 1, [Define if Qt uses the X Window System])], + [AC_MSG_RESULT(no)]) + elif test x$USE_QT5 = xyes ; then AC_EGREP_CPP(xcb, [#include <$lyx_qt5_config> QT_QPA_DEFAULT_PLATFORM_NAME], @@ -351,3 +395,75 @@ AC_DEFUN([QT_DO_MANUAL_CONFIG], QT_GET_VERSION fi ]) + +AC_DEFUN([QT6_QMAKE_CONFIG], +[ + AC_MSG_CHECKING([for Qt6]) + dnl Use first qmake in PATH + ver=`qmake -v | grep -o "Qt version ."` + if test "$ver" = "Qt version 6"; then + dnl Use a .pro file for getting qmake's variables + lyx_test_qt_dir=`mktemp -d` + lyx_test_qt_pro="$lyx_test_qt_dir/test.pro" + lyx_test_qt_mak="$lyx_test_qt_dir/Makefile" + cat > $lyx_test_qt_pro << EOF1 +qtHaveModule(core): QT += core +qtHaveModule(core5compat): QT += core5compat +percent.target = % +percent.commands = @echo -n "\$(\$(@))\ " +QMAKE_EXTRA_TARGETS += percent +EOF1 + qmake $lyx_test_qt_pro -o $lyx_test_qt_mak 1>/dev/null 2>&1 + QT_CORE_INCLUDES=`cd $lyx_test_qt_dir; make -s -f $lyx_test_qt_mak INCPATH | sed 's/-I\. //g'` + qt_corelibs=`cd $lyx_test_qt_dir; make -s -f $lyx_test_qt_mak LIBS` + QT_CORE_LDFLAGS=`echo $qt_corelibs | tr ' ' '\n' | grep -e "^-L" | tr '\n' ' '` + if test -z "$QT_CORE_LDFLAGS"; then + QT_CORE_LDFLAGS="-L`qmake -query QT_INSTALL_LIBS`" + QT_CORE_LIB="$qt_corelibs" + else + QT_CORE_LIB=`echo $qt_corelibs | tr ' ' '\n' | grep -e "^-l" | tr '\n' ' '` + fi + if test -z "$QT_CORE_LIB"; then + AC_MSG_RESULT(no) + else + AC_SUBST(QT_CORE_INCLUDES) + AC_SUBST(QT_CORE_LDFLAGS) + AC_SUBST(QT_CORE_LIB) + cat > $lyx_test_qt_pro << EOF2 +qtHaveModule(core): QT += core +qtHaveModule(core5compat): QT += core5compat +qtHaveModule(concurrent): QT += concurrent +qtHaveModule(gui): QT += gui +qtHaveModule(svg): QT += svg +qtHaveModule(widgets): QT += widgets +percent.target = % +percent.commands = @echo -n "\$(\$(@))\ " +QMAKE_EXTRA_TARGETS += percent +EOF2 + qmake $lyx_test_qt_pro -o $lyx_test_qt_mak 1>/dev/null 2>&1 + QT_INCLUDES=`cd $lyx_test_qt_dir; make -s -f $lyx_test_qt_mak INCPATH | sed 's/-I\. //g'` + qt_guilibs=`cd $lyx_test_qt_dir; make -s -f $lyx_test_qt_mak LIBS` + QT_LDFLAGS=`echo $qt_guilibs | tr ' ' '\n' | grep -e "^-L" | tr '\n' ' '` + if test -z "$QT_LDFLAGS"; then + QT_LDFLAGS="-L`qmake -query QT_INSTALL_LIBS`" + QT_LIB="$qt_guilibs" + else + QT_LIB=`echo $qt_guilibs | tr ' ' '\n' | grep -e "^-l" | tr '\n' ' '` + fi + QTLIB_VERSION=`qmake -v | grep "Qt version" | sed -e 's/.*\([[0-9]]\.[[0-9]]*\.[[0-9]]\).*/\1/'` + if test -z "$QT_LIB"; then + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + AC_SUBST(QT_INCLUDES) + AC_SUBST(QT_LDFLAGS) + AC_SUBST(QT_LIB) + AC_SUBST(QTLIB_VERSION) + fi + fi + rm $lyx_test_qt_pro $lyx_test_qt_mak $lyx_test_qt_dir/.qmake.stash + rmdir $lyx_test_qt_dir + else + AC_MSG_RESULT(no) + fi +]) diff --git a/configure.ac b/configure.ac index f7d52fa669..f258db9adf 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,10 @@ AC_CONFIG_AUX_DIR(config) # First check the version LYX_CHECK_VERSION LYX_VERSION_SUFFIX +LYX_CHECK_QT6 +if test x$USE_QT6 = xno ; then LYX_CHECK_QT5 +fi # Check how the files should be packaged AC_CANONICAL_TARGET LYX_USE_PACKAGING diff --git a/src/frontends/qt/CategorizedCombo.cpp b/src/frontends/qt/CategorizedCombo.cpp index 4aebcf6a91..1548ecf7e8 100644 --- a/src/frontends/qt/CategorizedCombo.cpp +++ b/src/frontends/qt/CategorizedCombo.cpp @@ -34,6 +34,9 @@ #include #include #include +#if QT_VERSION >= 0x060000 +#include +#endif using namespace lyx::support; @@ -270,7 +273,11 @@ QString CCItemDelegate::underlineFilter(QString const & s) const if (f.isEmpty()) return s; QString r(s); +#if QT_VERSION < 0x060000 QRegExp pattern(charFilterRegExpC(f)); +#else + QRegularExpression pattern(charFilterRegExpC(f)); +#endif r.replace(pattern, "\\1"); return r; } @@ -287,7 +294,11 @@ void CategorizedCombo::Private::setFilter(QString const & s) lastSel_ = filterModel_->mapToSource(filterModel_->index(sel, 0)).row(); filter_ = s; +#if QT_VERSION < 0x060000 filterModel_->setFilterRegExp(charFilterRegExp(filter_)); +#else + filterModel_->setFilterRegularExpression(charFilterRegExp(filter_)); +#endif countCategories(); // restore old selection diff --git a/src/frontends/qt/GuiAbout.cpp b/src/frontends/qt/GuiAbout.cpp index b066106ad8..d4173fae8b 100644 --- a/src/frontends/qt/GuiAbout.cpp +++ b/src/frontends/qt/GuiAbout.cpp @@ -59,7 +59,9 @@ static QString credits() out << qt_("Please install correctly to estimate the great\namount of work other people have done for the LyX project."); } else { QTextStream ts(&file); +#if QT_VERSION < 0x060000 ts.setCodec("UTF-8"); +#endif QString line; do { line = ts.readLine(); @@ -101,7 +103,9 @@ static QString release_notes() out << qt_("Please install correctly to see what has changed\nfor this version of LyX."); } else { QTextStream ts(&file); +#if QT_VERSION < 0x060000 ts.setCodec("UTF-8"); +#endif QString line; bool incomment = false; bool inlist = false; @@ -123,8 +127,13 @@ static QString release_notes() continue; // detect links to the tracker +#if QT_VERSION < 0x060000 line.replace(QRegExp("(bug )(\\#)(\\d+)*"), "\\1\\3"); +#else + line.replace(QRegularExpression("(bug )(\\#)(\\d+)*"), + "\\1\\3"); +#endif // headings if (line.startsWith("!!!")) { diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp index e500fa003c..a5cb3c8db8 100644 --- a/src/frontends/qt/GuiApplication.cpp +++ b/src/frontends/qt/GuiApplication.cpp @@ -89,7 +89,9 @@ #include #include #include +#if QT_VERSION < 0x060000 #include +#endif #include #include #include @@ -135,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 @@ -142,6 +145,7 @@ #include #define QWINDOWSMIME QWinMime #endif +#endif #ifdef Q_CC_GNU #include #endif @@ -808,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. @@ -974,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; @@ -1049,7 +1053,7 @@ struct GuiApplication::Private 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_; @@ -1080,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 @@ -2567,6 +2571,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(); @@ -2575,6 +2580,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(); @@ -2582,7 +2597,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 == '-') diff --git a/src/frontends/qt/GuiClipboard.cpp b/src/frontends/qt/GuiClipboard.cpp index 6c1d9816c4..37cda23a15 100644 --- a/src/frontends/qt/GuiClipboard.cpp +++ b/src/frontends/qt/GuiClipboard.cpp @@ -361,7 +361,11 @@ QString tidyHtml(QString const & input) // clutter. QTextDocument converter; converter.setHtml(input); +#if QT_VERSION < 0x060000 return converter.toHtml("utf-8"); +#else + return converter.toHtml(); +#endif } } // namespace diff --git a/src/frontends/qt/GuiCommandBuffer.cpp b/src/frontends/qt/GuiCommandBuffer.cpp index d6334280ff..80e57c048c 100644 --- a/src/frontends/qt/GuiCommandBuffer.cpp +++ b/src/frontends/qt/GuiCommandBuffer.cpp @@ -123,9 +123,17 @@ GuiCommandBuffer::GuiCommandBuffer(GuiView * view) layout->addWidget(upPB, 0); layout->addWidget(downPB, 0); layout->addWidget(edit_, 10); +#if QT_VERSION < 0x060000 layout->setMargin(0); +#else + layout->setContentsMargins(0, 0, 0, 0); +#endif top->addLayout(layout); +#if QT_VERSION < 0x060000 top->setMargin(0); +#else + top->setContentsMargins(0, 0, 0, 0); +#endif setFocusProxy(edit_); LastCommandsSection::LastCommands last_commands diff --git a/src/frontends/qt/GuiFontLoader.cpp b/src/frontends/qt/GuiFontLoader.cpp index a2d6d989aa..a47e555092 100644 --- a/src/frontends/qt/GuiFontLoader.cpp +++ b/src/frontends/qt/GuiFontLoader.cpp @@ -29,6 +29,8 @@ #include "support/Package.h" #include "support/os.h" +#include "GuiApplication.h" + #include #include @@ -207,14 +209,16 @@ QFont symbolFont(QString const & family, bool * ok) upper[0] = family[0].toUpper(); QFont font; -#if defined Q_WS_X11 || defined(QPA_XCB) - // On *nix we have to also specify the foundry to be able to - // discriminate our fonts when the texlive fonts are managed by - // fontconfig. Unfortunately, doing the same on Windows breaks things. - font.setFamily(family + QLatin1String(" [LyEd]")); -#else - font.setFamily(family); -#endif + if (guiApp->platformName() == "qt4x11" + || guiApp->platformName() == "xcb" + || guiApp->platformName().contains("wayland")) { + // On *nix we have to also specify the foundry to be able to + // discriminate our fonts when the texlive fonts are managed by + // fontconfig. Unfortunately, doing the same on Windows breaks things. + font.setFamily(family + QLatin1String(" [LyEd]")); + } else { + font.setFamily(family); + } font.setStyleStrategy(QFont::NoFontMerging); #if QT_VERSION >= 0x040800 font.setStyleName("LyX"); diff --git a/src/frontends/qt/GuiListings.cpp b/src/frontends/qt/GuiListings.cpp index 0b3cb24b3b..b1a1e8cac2 100644 --- a/src/frontends/qt/GuiListings.cpp +++ b/src/frontends/qt/GuiListings.cpp @@ -30,7 +30,11 @@ #include #include #include +#if QT_VERSION < 0x060000 #include +#else +#include +#endif using namespace std; using namespace lyx::support; @@ -232,7 +236,11 @@ GuiListings::GuiListings(GuiView & lv) numberStepLE->setValidator(new QIntValidator(0, 1000000, this)); firstlineLE->setValidator(new QIntValidator(0, 1000000, this)); lastlineLE->setValidator(new QIntValidator(0, 1000000, this)); +#if QT_VERSION < 0x060000 placementLE->setValidator(new QRegExpValidator(QRegExp("[\\*tbph]*"), this)); +#else + placementLE->setValidator(new QRegularExpressionValidator(QRegularExpression("[\\*tbph]*"), this)); +#endif bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); bc().setOK(buttonBox->button(QDialogButtonBox::Ok)); diff --git a/src/frontends/qt/GuiLog.cpp b/src/frontends/qt/GuiLog.cpp index aab671a91e..6fac3603e7 100644 --- a/src/frontends/qt/GuiLog.cpp +++ b/src/frontends/qt/GuiLog.cpp @@ -41,12 +41,21 @@ namespace frontend { // Regular expressions needed at several places // FIXME: These regexes are incomplete. It would be good if we could collect those used in LaTeX::scanLogFile // and LaTeX::scanBlgFile and re-use them here!(spitz, 2013-05-27) +#if QT_VERSION < 0x060000 // Information QRegExp exprInfo("^(Document Class:|LaTeX Font Info:|File:|Package:|Language:|.*> INFO - |\\(|\\\\).*$"); // Warnings QRegExp exprWarning("^(## Warning|LaTeX Warning|LaTeX Font Warning|Package [\\w\\.]+ Warning|Class \\w+ Warning|Warning--|Underfull|Overfull|.*> WARN - ).*$"); // Errors QRegExp exprError("^(ERROR: |!|.*---line [0-9]+ of file|.*> FATAL - |.*> ERROR - |Missing character: There is no ).*$"); +#else +// Information +QRegularExpression exprInfo("^(Document Class:|LaTeX Font Info:|File:|Package:|Language:|.*> INFO - |\\(|\\\\).*$"); +// Warnings +QRegularExpression exprWarning("^(## Warning|LaTeX Warning|LaTeX Font Warning|Package [\\w\\.]+ Warning|Class \\w+ Warning|Warning--|Underfull|Overfull|.*> WARN - ).*$"); +// Errors +QRegularExpression exprError("^(ERROR: |!|.*---line [0-9]+ of file|.*> FATAL - |.*> ERROR - |Missing character: There is no ).*$"); +#endif ///////////////////////////////////////////////////////////////////// @@ -82,6 +91,7 @@ LogHighlighter::LogHighlighter(QTextDocument * parent) void LogHighlighter::highlightBlock(QString const & text) { +#if QT_VERSION < 0x060000 // Info int index = exprInfo.indexIn(text); while (index >= 0) { @@ -103,6 +113,35 @@ void LogHighlighter::highlightBlock(QString const & text) setFormat(index, length, errorFormat); index = exprError.indexIn(text, index + length); } +#else + // Info + QRegularExpressionMatch match = exprInfo.match(text); + int index = match.capturedStart(1); + while (index >= 0) { + int length = match.capturedEnd(1) - index; + setFormat(index, length, infoFormat); + match = exprInfo.match(text, index + length); + index = match.capturedStart(1); + } + // LaTeX Warning: + match = exprWarning.match(text); + index = match.capturedStart(1); + while (index >= 0) { + int length = match.capturedEnd(1) - index; + setFormat(index, length, warningFormat); + match = exprWarning.match(text, index + length); + index = match.capturedStart(1); + } + // ! error + match = exprError.match(text); + index = match.capturedStart(1); + while (index >= 0) { + int length = match.capturedEnd(1) - index; + setFormat(index, length, errorFormat); + match = exprError.match(text, index + length); + index = match.capturedStart(1); + } +#endif } @@ -195,7 +234,11 @@ void GuiLog::on_openDirPB_clicked() } +#if QT_VERSION < 0x060000 void GuiLog::goTo(QRegExp const & exp) const +#else +void GuiLog::goTo(QRegularExpression const & exp) const +#endif { QTextCursor const newc = logTB->document()->find(exp, logTB->textCursor()); @@ -203,7 +246,11 @@ void GuiLog::goTo(QRegExp const & exp) const } +#if QT_VERSION < 0x060000 bool GuiLog::contains(QRegExp const & exp) const +#else +bool GuiLog::contains(QRegularExpression const & exp) const +#endif { return !logTB->document()->find(exp, logTB->textCursor()).isNull(); } diff --git a/src/frontends/qt/GuiLog.h b/src/frontends/qt/GuiLog.h index dc143f1ea7..cd62390fc2 100644 --- a/src/frontends/qt/GuiLog.h +++ b/src/frontends/qt/GuiLog.h @@ -66,10 +66,17 @@ private: docstring title() const; /// put the log file into the ostream void getContents(std::ostream & ss) const; +#if QT_VERSION < 0x060000 /// go to the next occurrence of the RegExp void goTo(QRegExp const & exp) const; /// does the document after cursor position contain the RegExp? bool contains(QRegExp const & exp) const; +#else + /// go to the next occurrence of the RegExp + void goTo(QRegularExpression const & exp) const; + /// does the document after cursor position contain the RegExp? + bool contains(QRegularExpression const & exp) const; +#endif private: /// Recognized log file-types diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp index c04ef83413..7537ead048 100644 --- a/src/frontends/qt/GuiPrefs.cpp +++ b/src/frontends/qt/GuiPrefs.cpp @@ -188,7 +188,11 @@ QString browseRelToSub(QString const & filename, QString const & relpath, toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath))); QString testname = reloutname; +#if QT_VERSION < 0x060000 testname.remove(QRegExp("^(\\.\\./)+")); +#else + testname.remove(QRegularExpression("^(\\.\\./)+")); +#endif if (testname.contains("/")) return outname; @@ -2424,7 +2428,11 @@ PrefLanguage::PrefLanguage(GuiPreferences * form) startCommandED->setValidator(new NoNewLineValidator(startCommandED)); endCommandED->setValidator(new NoNewLineValidator(endCommandED)); +#if QT_VERSION < 0x060000 defaultDecimalSepED->setValidator(new QRegExpValidator(QRegExp("\\S"), this)); +#else + defaultDecimalSepED->setValidator(new QRegularExpressionValidator(QRegularExpression("\\S"), this)); +#endif defaultDecimalSepED->setMaxLength(1); defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM); @@ -2584,9 +2592,12 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form) iconSetCO->addItem(qt_("Classic"), "classic"); iconSetCO->addItem(qt_("Oxygen"), "oxygen"); -#if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600) - useSystemThemeIconsCB->hide(); +#if QT_VERSION >= 0x040600 + if (guiApp->platformName() != "qt4x11" + && guiApp->platformName() != "xcb" + && !guiApp->platformName().contains("wayland")) #endif + useSystemThemeIconsCB->hide(); } diff --git a/src/frontends/qt/GuiTabular.cpp b/src/frontends/qt/GuiTabular.cpp index 138296fa3f..9526e9a0e9 100644 --- a/src/frontends/qt/GuiTabular.cpp +++ b/src/frontends/qt/GuiTabular.cpp @@ -176,7 +176,11 @@ GuiTabular::GuiTabular(QWidget * parent) connect(tabularWidthED, SIGNAL(textEdited(const QString &)), this, SLOT(checkEnabled())); +#if QT_VERSION < 0x060000 decimalPointED->setValidator(new QRegExpValidator(QRegExp("\\S"), this)); +#else + decimalPointED->setValidator(new QRegularExpressionValidator(QRegularExpression("\\S"), this)); +#endif decimalPointED->setMaxLength(1); // initialize the length validator diff --git a/src/frontends/qt/GuiThesaurus.cpp b/src/frontends/qt/GuiThesaurus.cpp index 81b3cf5504..f3219563b7 100644 --- a/src/frontends/qt/GuiThesaurus.cpp +++ b/src/frontends/qt/GuiThesaurus.cpp @@ -124,9 +124,14 @@ void GuiThesaurus::selectionChanged() QString item = meaningsTV->currentItem()->text(col); // cut out the classification in brackets: // "hominid (generic term)" -> "hominid" +#if QT_VERSION < 0x060000 QRegExp re("^([^\\(\\)]+)\\b\\(?.*\\)?.*$"); +#else + QRegularExpression re("^([^\\(\\)]+)\\b\\(?.*\\)?.*$"); +#endif // This is for items with classifications at the beginning: // "(noun) man" -> "man"; "(noun) male (generic term)" -> "male" +#if QT_VERSION < 0x060000 QRegExp rex("^(\\(.+\\))\\s*([^\\(\\)]+)\\s*\\(?.*\\)?.*$"); int pos = re.indexIn(item); if (pos > -1) @@ -134,6 +139,15 @@ void GuiThesaurus::selectionChanged() pos = rex.indexIn(item); if (pos > -1) item = rex.cap(2).trimmed(); +#else + QRegularExpression rex("^(\\(.+\\))\\s*([^\\(\\)]+)\\s*\\(?.*\\)?.*$"); + QRegularExpressionMatch match = re.match(item); + if (match.hasMatch()) + item = match.captured(1).trimmed(); + match = rex.match(item); + if (match.hasMatch()) + item = match.captured(2).trimmed(); +#endif replaceED->setText(item); replacePB->setEnabled(!isBufferReadonly()); changed(); @@ -151,9 +165,14 @@ void GuiThesaurus::selectionClicked(QTreeWidgetItem * item, int col) QString str = item->text(col); // cut out the classification in brackets: // "hominid (generic term)" -> "hominid" +#if QT_VERSION < 0x060000 QRegExp re("^([^\\(\\)]+)\\b\\(?.*\\)?.*$"); +#else + QRegularExpression re("^([^\\(\\)]+)\\b\\(?.*\\)?.*$"); +#endif // This is for items with classifications at the beginning: // "(noun) man" -> "man"; "(noun) male (generic term)" -> "male" +#if QT_VERSION < 0x060000 QRegExp rex("^(\\(.+\\))\\s*([^\\(\\)]+)\\s*\\(?.*\\)?.*$"); int pos = re.indexIn(str); if (pos > -1) @@ -161,6 +180,15 @@ void GuiThesaurus::selectionClicked(QTreeWidgetItem * item, int col) pos = rex.indexIn(str); if (pos > -1) str = rex.cap(2).trimmed(); +#else + QRegularExpression rex("^(\\(.+\\))\\s*([^\\(\\)]+)\\s*\\(?.*\\)?.*$"); + QRegularExpressionMatch match = re.match(str); + if (match.hasMatch()) + str = match.captured(1).trimmed(); + match = rex.match(str); + if (match.hasMatch()) + str = match.captured(2).trimmed(); +#endif entryCO->insertItem(0, str); entryCO->setCurrentIndex(0); diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp index 7f2860f029..a5925f0c55 100644 --- a/src/frontends/qt/GuiView.cpp +++ b/src/frontends/qt/GuiView.cpp @@ -655,7 +655,7 @@ GuiView::GuiView(int id) zoom_in_->setFlat(true); zoom_in_->setFixedSize(QSize(fm.height(), fm.height())); zoom_out_ = new QPushButton(statusBar()); - zoom_out_->setText(QString(0x2212)); + zoom_out_->setText(QString(QChar(0x2212))); zoom_out_->setFixedSize(QSize(fm.height(), fm.height())); zoom_out_->setFlat(true); diff --git a/src/frontends/qt/IconPalette.cpp b/src/frontends/qt/IconPalette.cpp index 325a96e881..3c5eb7a546 100644 --- a/src/frontends/qt/IconPalette.cpp +++ b/src/frontends/qt/IconPalette.cpp @@ -19,7 +19,9 @@ #include #include #include +#if QT_VERSION < 0x060000 #include +#endif #include #include #include @@ -76,7 +78,9 @@ void TearOff::paintEvent(QPaintEvent * /*event*/) menuOpt.checkType = QStyleOptionMenuItem::NotCheckable; menuOpt.menuRect = rect(); menuOpt.maxIconWidth = 0; +#if QT_VERSION < 0x060000 menuOpt.tabWidth = 0; +#endif menuOpt.menuItemType = QStyleOptionMenuItem::TearOff; menuOpt.rect.setRect(fw, fw, width() - (fw * 2), style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this)); @@ -92,12 +96,20 @@ IconPalette::IconPalette(QWidget * parent) : QWidget(parent, Qt::Popup), tornoff_(false) { QVBoxLayout * v = new QVBoxLayout(this); +#if QT_VERSION < 0x060000 v->setMargin(0); +#else + v->setContentsMargins(0, 0, 0, 0); +#endif v->setSpacing(0); layout_ = new QGridLayout; layout_->setSpacing(0); const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this); +#if QT_VERSION < 0x060000 layout_->setMargin(fw); +#else + layout_->setContentsMargins(0, 0, 0, 0); +#endif tearoffwidget_ = new TearOff(this); connect(tearoffwidget_, SIGNAL(tearOff()), this, SLOT(tearOff())); v->addWidget(tearoffwidget_); @@ -166,7 +178,11 @@ void IconPalette::showEvent(QShowEvent * /*event*/) voffset -= parheight; } +#if QT_VERSION < 0x060000 QRect const screen = qApp->desktop()->availableGeometry(this); +#else + QRect const screen = qApp->primaryScreen()->availableGeometry(); +#endif QPoint const gpos = parentWidget()->mapToGlobal( parentWidget()->geometry().bottomLeft()); diff --git a/src/frontends/qt/IconPalette.h b/src/frontends/qt/IconPalette.h index 5e78ff6698..50c68a3583 100644 --- a/src/frontends/qt/IconPalette.h +++ b/src/frontends/qt/IconPalette.h @@ -27,7 +27,11 @@ class TearOff : public QWidget { Q_OBJECT public: TearOff(QWidget * parent); +#if QT_VERSION < 0x060000 void enterEvent(QEvent *) override; +#else + void enterEvent(QEvent *); +#endif void leaveEvent(QEvent *) override; void mouseReleaseEvent (QMouseEvent *) override; Q_SIGNALS: diff --git a/src/frontends/qt/LaTeXHighlighter.cpp b/src/frontends/qt/LaTeXHighlighter.cpp index 5ab349e485..d199fb19a2 100644 --- a/src/frontends/qt/LaTeXHighlighter.cpp +++ b/src/frontends/qt/LaTeXHighlighter.cpp @@ -43,6 +43,7 @@ LaTeXHighlighter::LaTeXHighlighter(QTextDocument * parent, bool at_letter) void LaTeXHighlighter::highlightBlock(QString const & text) { +#if QT_VERSION < 0x060000 // $ $ static const QRegExp exprMath("\\$[^\\$]*\\$"); int index = exprMath.indexIn(text); @@ -127,6 +128,102 @@ void LaTeXHighlighter::highlightBlock(QString const & text) setFormat(index, length, warningFormat); index = exprWarning.indexIn(text, index + length); } +#else + // $ $ + static const QRegularExpression exprMath("\\$[^\\$]*\\$"); + QRegularExpressionMatch match = exprMath.match(text); + int index = match.capturedStart(1); + while (index >= 0) { + int length = match.capturedEnd(1) - index; + setFormat(index, length, mathFormat); + match = exprMath.match(text, index + length); + int index = match.capturedStart(1); + } + // [ ] + static const QRegularExpression exprStartDispMath("(\\\\\\[|" + "\\\\begin\\{equation\\**\\}|" + "\\\\begin\\{eqnarray\\**\\}|" + "\\\\begin\\{align(ed|at)*\\**\\}|" + "\\\\begin\\{flalign\\**\\}|" + "\\\\begin\\{gather\\**\\}|" + "\\\\begin\\{multline\\**\\}|" + "\\\\begin\\{array\\**\\}|" + "\\\\begin\\{cases\\**\\}" + ")"); + static const QRegularExpression exprEndDispMath("(\\\\\\]|" + "\\\\end\\{equation\\**\\}|" + "\\\\end\\{eqnarray\\**\\}|" + "\\\\end\\{align(ed|at)*\\**\\}|" + "\\\\end\\{flalign\\**\\}|" + "\\\\end\\{gather\\**\\}|" + "\\\\end\\{multline\\**\\}|" + "\\\\end\\{array\\**\\}|" + "\\\\end\\{cases\\**\\}" + ")"); + int startIndex = 0; + // if previous block was in 'disp math' + // start search from 0 (for end disp math) + // otherwise, start search from 'begin disp math' + if (previousBlockState() != 1) { + match = exprStartDispMath.match(text); + startIndex = match.capturedStart(1); + } + while (startIndex >= 0) { + match = exprEndDispMath.match(text, startIndex); + int endIndex = match.capturedStart(1); + int length; + if (endIndex == -1) { + setCurrentBlockState(1); + length = text.length() - startIndex; + } else { + length = match.capturedEnd(1) - startIndex; + } + setFormat(startIndex, length, mathFormat); + match = exprStartDispMath.match(text, startIndex + length); + startIndex = match.capturedStart(1); + } + // \whatever + static const QRegularExpression exprKeywordAtOther("\\\\[A-Za-z]+"); + // \wh@tever + static const QRegularExpression exprKeywordAtLetter("\\\\[A-Za-z@]+"); + QRegularExpression const & exprKeyword = at_letter_ + ? exprKeywordAtLetter : exprKeywordAtOther; + match = exprKeyword.match(text); + index = match.capturedStart(1); + while (index >= 0) { + int length = match.capturedEnd(1) - index; + setFormat(index, length, keywordFormat); + match = exprKeyword.match(text, index + length); + index = match.capturedStart(1); + } + // %comment + // Treat a line as a comment starting at a percent sign + // * that is the first character in a line + // * that is preceded by + // ** an even number of backslashes + // ** any character other than a backslash + QRegularExpression exprComment("(?:^|[^\\\\])(?:\\\\\\\\)*(%).*$"); + match = exprComment.match(text); + index = match.capturedStart(1); + while (index >= 0) { + int const length = match.capturedEnd(1) - index + - (index - match.capturedStart(0)); + setFormat(index, length, commentFormat); + match = exprComment.match(text, index + length); + index = match.capturedStart(1); + } + // + QString lyxwarn = qt_("LyX Warning: "); + QRegularExpression exprWarning("<" + lyxwarn + "[^<]*>"); + match = exprWarning.match(text); + index = match.capturedStart(1); + while (index >= 0) { + int length = match.capturedEnd(1) - index; + setFormat(index, length, warningFormat); + match = exprWarning.match(text, index + length); + index = match.capturedStart(1); + } +#endif } } // namespace frontend diff --git a/src/frontends/qt/LayoutBox.cpp b/src/frontends/qt/LayoutBox.cpp index 719a2d324d..49d3086415 100644 --- a/src/frontends/qt/LayoutBox.cpp +++ b/src/frontends/qt/LayoutBox.cpp @@ -300,7 +300,11 @@ QString LayoutItemDelegate::underlineFilter(QString const & s) const if (f.isEmpty()) return s; QString r(s); +#if QT_VERSION < 0x060000 QRegExp pattern(charFilterRegExpC(f)); +#else + QRegularExpression pattern(charFilterRegExpC(f)); +#endif r.replace(pattern, "\\1"); return r; } @@ -321,7 +325,11 @@ void LayoutBox::Private::setFilter(QString const & s) lastSel_ = filterModel_->mapToSource(filterModel_->index(sel, 0)).row(); filter_ = s; +#if QT_VERSION < 0x060000 filterModel_->setFilterRegExp(charFilterRegExp(filter_)); +#else + filterModel_->setFilterRegularExpression(charFilterRegExp(filter_)); +#endif countCategories(); // restore old selection diff --git a/src/frontends/qt/Validator.cpp b/src/frontends/qt/Validator.cpp index c938f0ed5a..0d3b672f12 100644 --- a/src/frontends/qt/Validator.cpp +++ b/src/frontends/qt/Validator.cpp @@ -182,7 +182,11 @@ NoNewLineValidator::NoNewLineValidator(QWidget * parent) QValidator::State NoNewLineValidator::validate(QString & qtext, int &) const { +#if QT_VERSION < 0x060000 qtext.remove(QRegExp("[\\n\\r]")); +#else + qtext.remove(QRegularExpression("[\\n\\r]")); +#endif return QValidator::Acceptable; } diff --git a/src/support/mutex.cpp b/src/support/mutex.cpp index 481f0f9552..89ee2b8e23 100644 --- a/src/support/mutex.cpp +++ b/src/support/mutex.cpp @@ -20,12 +20,20 @@ namespace lyx { struct Mutex::Private { +#if QT_VERSION < 0x060000 // QMutex::Recursive: less risks for dead-locks Private() : qmutex_(QMutex::Recursive) { } QMutex qmutex_; +#else + Private() : qmutex_() + { + } + + QRecursiveMutex qmutex_; +#endif };