From 8cec995573dc2ea1ab18aa2bfa52215e963c3dd2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Tue, 19 Apr 2022 18:23:51 +0200 Subject: [PATCH] UI scaling: fonts --- src/Makefile.am | 17 +++--- src/qtgui/guiutils.cpp | 89 +++++++++++++++++++++++++++++++- src/qtgui/guiutils.h | 9 ++++ src/qtgui/main.cpp | 25 ++++----- src/qtgui/preview_w.cpp | 7 ++- src/qtgui/rclm_wins.cpp | 3 +- src/qtgui/recoll.pro.in | 5 ++ src/qtgui/reslist.cpp | 28 +--------- src/qtgui/restable.cpp | 28 ++++------ src/qtgui/restable.h | 2 +- src/qtgui/snippets_w.cpp | 24 +++++---- src/qtgui/uiprefs.ui | 46 +++++++++++++++++ src/qtgui/uiprefs_w.cpp | 2 + src/sampleconf/recoll-common.css | 6 +++ src/sampleconf/recoll-common.qss | 8 +++ src/windows/mkinstdir.sh | 1 + 16 files changed, 219 insertions(+), 81 deletions(-) create mode 100644 src/sampleconf/recoll-common.css create mode 100644 src/sampleconf/recoll-common.qss diff --git a/src/Makefile.am b/src/Makefile.am index 9204c8ab..d71bc10e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -576,6 +576,7 @@ python/samples/recollqsd.py \ sampleconf/fields sampleconf/fragment-buttons.xml sampleconf/mimeconf \ sampleconf/mimemap sampleconf/mimeview sampleconf/macos/mimeview \ sampleconf/recoll.conf sampleconf/recoll.qss \ +sampleconf/recoll-common.css sampleconf/recoll-common.qss \ sampleconf/recoll-dark.qss sampleconf/recoll-dark.css \ \ testmains/Makefile.am \ @@ -660,17 +661,19 @@ defconfdir = $(pkgdatadir)/examples defconf_DATA = \ desktop/recollindex.desktop \ index/rclmon.sh \ -index/recollindex@.service \ index/recollindex.service \ -sampleconf/fragment-buttons.xml \ +index/recollindex@.service \ sampleconf/fields \ -sampleconf/recoll.conf \ +sampleconf/fragment-buttons.xml \ sampleconf/mimeconf \ -sampleconf/recoll.qss \ -sampleconf/recoll-dark.qss \ -sampleconf/recoll-dark.css \ sampleconf/mimemap \ -sampleconf/mimeview +sampleconf/mimeview \ +sampleconf/recoll-common.css \ +sampleconf/recoll-common.qss \ +sampleconf/recoll-dark.css \ +sampleconf/recoll-dark.qss \ +sampleconf/recoll.conf \ +sampleconf/recoll.qss filterdir = $(pkgdatadir)/filters dist_filter_DATA = \ diff --git a/src/qtgui/guiutils.cpp b/src/qtgui/guiutils.cpp index 00252e8c..bc574f42 100644 --- a/src/qtgui/guiutils.cpp +++ b/src/qtgui/guiutils.cpp @@ -19,6 +19,13 @@ #include #include +// Programs built with gcc 4.8.4 (e.g.: Ubuntu Trusty), crash at startup while initializing stdc++ +// regular expression objects (and also crash if we make them non-static). +#if defined(__clang__) || defined(_WIN32) || __GNUC__ > 4 +#define USE_REGEX +#include +#endif + #include "recoll.h" #include "log.h" #include "smallut.h" @@ -31,6 +38,7 @@ #include #include #ifdef BUILDING_RECOLLGUI +#include #include #endif @@ -289,6 +297,7 @@ void rwSettings(bool writing) SETTING_RW(prefs.showTrayIcon, "/Recoll/prefs/showTrayIcon", Bool, false); SETTING_RW(prefs.closeToTray, "/Recoll/prefs/closeToTray", Bool, false); SETTING_RW(prefs.trayMessages, "/Recoll/prefs/trayMessages", Bool, false); + SETTING_RW(prefs.wholeuiscale, "/Recoll/ui/wholeuiscale", Double, 1.0); /*INSERTHERE*/ // See qxtconfirmationmessage. Needs to be -1 for the dialog to show. @@ -415,6 +424,83 @@ void rwSettings(bool writing) havereadsettings = true; } +#ifdef USE_REGEX +/* font-size: 10pt; */ +static const std::string fntsz_exp( + R"((\s*font-size\s*:\s*)([0-9]+)(p[tx]\s*;\s*))" + ); + +static std::regex fntsz_regex(fntsz_exp); +#endif // USE_REGEX + +std::string PrefsPack::scaleFonts(const std::string& style, float multiplier) +{ + //cerr << "scale_fonts: multiplier: " << multiplier << "\n"; + std::vector lines; + stringToTokens(style, lines, "\n"); +#ifdef USE_REGEX + for (unsigned int ln = 0; ln < lines.size(); ln++) { + const string& line = lines[ln]; + std::smatch m; + //std::cerr << "LINE: " << line << "\n"; + if (regex_match(line, m, fntsz_regex) && m.size() == 4) { + //std::cerr << "Got match (sz " << m.size() << ") for " << line << "\n"; + int fs = atoi(m[2].str().c_str()); + int nfs = round(fs * multiplier); + char buf[20]; + snprintf(buf, 20, "%d", nfs); + lines[ln] = m[1].str() + buf + m[3].str(); + //std::cerr << "New line: [" << lines[ln] << "]\n"; + } + } +#endif + string nstyle = string(); + for (auto& ln : lines) { + nstyle += ln + "\n"; + } + return nstyle; +} + +int PrefsPack::fontsize() +{ + // While building the kio, we don't really care about QT Gui + // defaults and referencing QFont introduces a useless dependency +#ifdef BUILDING_RECOLLGUI + int fs; + if (prefs.reslistfontsize > 0) { + fs = prefs.reslistfontsize; + } else { + fs = QWidget().font().pixelSize(); + } + fs = round(fs * prefs.wholeuiscale); + return fs; +#else + return 12; +#endif +} + +std::string PrefsPack::htmlHeaderContents() +{ + auto comfn = path_cat(path_cat(theconfig->getDatadir(), "examples"), "recoll-common.css"); + std::string comcss; + file_to_string(comfn, comcss); + std::ostringstream oss; + oss << comcss << "\n"; + oss << "\n"; + oss << qs2utf8s(prefs.darkreslistheadertext) << qs2utf8s(prefs.reslistheadertext); + + auto css = PrefsPack::scaleFonts(oss.str(), prefs.wholeuiscale); + return css; +} + void PrefsPack::setupDarkCSS() { if (!darkMode) { @@ -424,8 +510,7 @@ void PrefsPack::setupDarkCSS() if (nullptr == theconfig) { return; } - string fn = path_cat( - path_cat(theconfig->getDatadir(), "examples"), "recoll-dark.css"); + string fn = path_cat(path_cat(theconfig->getDatadir(), "examples"), "recoll-dark.css"); string data; string reason; if (!file_to_string(fn, data, &reason)) { diff --git a/src/qtgui/guiutils.h b/src/qtgui/guiutils.h index e0d171fe..623d1b39 100644 --- a/src/qtgui/guiutils.h +++ b/src/qtgui/guiutils.h @@ -161,6 +161,7 @@ public: bool showTrayIcon{false}; bool closeToTray{false}; bool trayMessages{false}; + double wholeuiscale{1.0}; /*INSERTHERE*/ // See widgets/qxtconfirmationmessage. @@ -176,12 +177,20 @@ public: std::string stemlang(); void setupDarkCSS(); + + // HTML Header contents for both the result list, the snippets window and others + std::string htmlHeaderContents(); // MIME types for which we prefer to use stored text from preview // rather than extracting the possibly nicer HTML because the // extractor is very slow. This is compiled in and there is no UI // for now. std::set preferStoredTextMimes{"application/x-hwp"}; + + // Scale font-sizes inside css or qss input and return changed sheet. The font-size statements + // need to be on their own line. + static std::string scaleFonts(const std::string& style, float multiplier); + int fontsize(); }; /** Global preferences record */ diff --git a/src/qtgui/main.cpp b/src/qtgui/main.cpp index 011ab0c1..28a1d22a 100644 --- a/src/qtgui/main.cpp +++ b/src/qtgui/main.cpp @@ -161,17 +161,19 @@ static void recollCleanup() LOGDEB2("recollCleanup: done\n" ); } -void applyStyleSheet(const QString& ssfname) +void applyStyleSheet(const QString& qssfn) { - const std::string cfname = qs2path(ssfname); - LOGDEB0("Applying style sheet: [" << cfname << "]\n"); - if (!cfname.empty()) { - string stylesheet; - file_to_string(cfname, stylesheet); - qApp->setStyleSheet(QString::fromUtf8(stylesheet.c_str())); - } else { - qApp->setStyleSheet(QString()); + auto comfn = path_cat(path_cat(theconfig->getDatadir(), "examples"), "recoll-common.qss"); + std::string qss; + file_to_string(comfn, qss); + if (!qssfn.isEmpty()) { + LOGDEB0("Using custom style sheet: [" << qs2path(qssfn) << "]\n"); + string customqss; + file_to_string(qs2path(qssfn), customqss); + qss += customqss; } + qss = prefs.scaleFonts(qss, prefs.wholeuiscale); + qApp->setStyleSheet(u8s2qs(qss)); } extern void qInitImages_recoll(); @@ -370,9 +372,8 @@ int main(int argc, char **argv) rwSettings(false); // fprintf(stderr, "Settings done\n"); - if (!prefs.qssFile.isEmpty()) { - applyStyleSheet(prefs.qssFile); - } + applyStyleSheet(prefs.qssFile); + QIcon icon; icon.addFile(QString::fromUtf8(":/images/recoll.png")); app.setWindowIcon(icon); diff --git a/src/qtgui/preview_w.cpp b/src/qtgui/preview_w.cpp index bb879d2a..43d1e080 100644 --- a/src/qtgui/preview_w.cpp +++ b/src/qtgui/preview_w.cpp @@ -125,10 +125,13 @@ void Preview::init() } if (prefs.reslistfontfamily != "") { - m_font = QFont(prefs.reslistfontfamily, prefs.reslistfontsize); + m_font = QFont(prefs.reslistfontfamily); } else { m_font = QFont(); - m_font.setPointSize(prefs.reslistfontsize); + } + if (prefs.reslistfontsize || prefs.wholeuiscale) { + int fs = prefs.reslistfontsize ? prefs.reslistfontsize : m_font.pixelSize(); + m_font.setPixelSize(round(fs * prefs.wholeuiscale)); } (void)new HelpClient(this); diff --git a/src/qtgui/rclm_wins.cpp b/src/qtgui/rclm_wins.cpp index fe3f91f1..7c2d41dc 100644 --- a/src/qtgui/rclm_wins.cpp +++ b/src/qtgui/rclm_wins.cpp @@ -334,7 +334,8 @@ void RclMain::showExtIdxDialog() void RclMain::showAboutDialog() { - QString vstring = QString("") + prefs.darkreslistheadertext + "" + + QString vstring = QString("") + u8s2qs(prefs.htmlHeaderContents()) + + "" + u8s2qs(Rcl::version_string()) + "
www.recoll.org" + "
www.xapian.org"; diff --git a/src/qtgui/recoll.pro.in b/src/qtgui/recoll.pro.in index 358e0a48..9647b789 100644 --- a/src/qtgui/recoll.pro.in +++ b/src/qtgui/recoll.pro.in @@ -5,6 +5,11 @@ VPATH = @srcdir@ DEFINES += BUILDING_RECOLL DEFINES += BUILDING_RECOLLGUI +# Decide if we set font family and style with a css section in the html or with qwebsettings +# setfont... calls. We used to do it with websettings because it gave a faster redisplay, and the +# css has a tendancy to not find some system fonts. We currently do it with css anyway. +DEFINES += SETFONT_WITH_HEADSTYLE=1 + @QMAKE_ENABLE_WEBKIT@ QT += webkit @QMAKE_ENABLE_WEBKIT@ DEFINES += USING_WEBKIT diff --git a/src/qtgui/reslist.cpp b/src/qtgui/reslist.cpp index 6afafc19..621af709 100644 --- a/src/qtgui/reslist.cpp +++ b/src/qtgui/reslist.cpp @@ -121,13 +121,6 @@ bool RclWebPage::acceptNavigationRequest(const QUrl& url, #endif // WEBENGINE -// Decide if we set font family and style with a css section in the -// html or with qwebsettings setfont... calls. We currently do -// it with websettings because this gives an instant redisplay, and -// the css has a tendancy to not find some system fonts. Otoh, -// SetFontSize() needs a strange offset of 3, not needed with css. -#undef SETFONT_WITH_HEADSTYLE - class QtGuiResListPager : public ResListPager { public: QtGuiResListPager(ResList *p, int ps, bool alwayssnip) @@ -230,26 +223,7 @@ string QtGuiResListPager::prevUrl() string QtGuiResListPager::headerContent() { - string out; - - out = "\n"); -#if defined(USING_WEBENGINE) - out += "\n"; -#endif - out += qs2utf8s(prefs.darkreslistheadertext); - out += qs2utf8s(prefs.reslistheadertext); - return out; + return prefs.htmlHeaderContents(); } void QtGuiResListPager::suggest(const vectoruterms, diff --git a/src/qtgui/restable.cpp b/src/qtgui/restable.cpp index 536e71db..3fba08cb 100644 --- a/src/qtgui/restable.cpp +++ b/src/qtgui/restable.cpp @@ -69,7 +69,6 @@ static const int TEXTINCELLVTRANS = -4; // Adjust font size from prefs, display is slightly different here static const int fsadjustdetail = 1; -static const int fsadjusttable = 1; static PlainToRichQtReslist g_hiliter; @@ -93,6 +92,8 @@ public: virtual string absSep() override { return (const char *)(prefs.abssep.toUtf8());} virtual string headerContent() override { + // Note: the detail area is a qtextbrowser which gets confused by the general Html + // header. So we manage it differently from the snippets or main result list. return qs2utf8s(prefs.darkreslistheadertext) + qs2utf8s(prefs.reslistheadertext); } private: @@ -155,11 +156,7 @@ void ResTableDetailArea::createPopupMenu(const QPoint& pos) void ResTableDetailArea::setFont() { - int fs = prefs.reslistfontsize; - // fs shows slightly bigger in qtextbrowser? adjust. - if (prefs.reslistfontsize > fsadjustdetail) { - fs -= fsadjustdetail; - } + int fs = prefs.fontsize() - fsadjustdetail; if (prefs.reslistfontfamily != "") { QFont nfont(prefs.reslistfontfamily, fs); QTextBrowser::setFont(nfont); @@ -392,15 +389,12 @@ QVariant RecollModel::data(const QModelIndex& index, int role) const // The font is actually set in the custom delegate, but we need // this to adjust the row height (there is probably a better way // to do it in the delegate?) - if (role == Qt::FontRole && prefs.reslistfontsize > 0) { - if (m_reslfntszforcached != prefs.reslistfontsize) { - m_reslfntszforcached = prefs.reslistfontsize; + if (role == Qt::FontRole && (prefs.reslistfontsize > 0 || prefs.wholeuiscale != 1.0)) { + if (m_reslfntszforcached != prefs.fontsize() - fsadjustdetail) { + m_reslfntszforcached = prefs.fontsize() - fsadjustdetail; m_table->setDefRowHeight(); m_cachedfont = m_table->font(); - int fs = prefs.reslistfontsize <= fsadjusttable ? - prefs.reslistfontsize: prefs.reslistfontsize - fsadjusttable; - if (fs > 0) - m_cachedfont.setPointSize(fs); + m_cachedfont.setPixelSize(m_reslfntszforcached); } return m_cachedfont; } @@ -542,9 +536,8 @@ public: QString seltextcolor = opt.palette.color(QPalette::HighlightedText).name(); QString fstyle; - if (prefs.reslistfontsize > 0) { - int fs = prefs.reslistfontsize <= fsadjusttable ? - prefs.reslistfontsize : prefs.reslistfontsize - fsadjusttable; + if (prefs.reslistfontsize > 0 || prefs.wholeuiscale != 1.0) { + int fs = prefs.fontsize() - fsadjustdetail; fstyle = QString("font-size: %1pt").arg(fs); } QString ntxt("