[LyX/master] Win installer: 2 bugfixes
commit eb9a118553a24cde919f84876f21342bb174d6a1 Author: Uwe StöhrDate: Tue May 31 01:25:07 2016 +0200 Win installer: 2 bugfixes diff --git a/development/Win32/packaging/installer/ChangeLog.txt b/development/Win32/packaging/installer/ChangeLog.txt index ac21000..335530b 100644 --- a/development/Win32/packaging/installer/ChangeLog.txt +++ b/development/Win32/packaging/installer/ChangeLog.txt @@ -1,4 +1,8 @@ -Todo: add lyx.de to mirror list +Changelog for LyX-220-2: +- remove also the user dependent LyX settings from the registry if the user + preferences should be uninstalled +- calculate the required installation size correctly + Changelog for LyX.220-1: - installs LyX 2.2.0 diff --git a/development/Win32/packaging/installer/include/declarations.nsh b/development/Win32/packaging/installer/include/declarations.nsh index 554aef8..8cf8d98 100644 --- a/development/Win32/packaging/installer/include/declarations.nsh +++ b/development/Win32/packaging/installer/include/declarations.nsh @@ -57,7 +57,7 @@ Configuration of LyX installer !define APP_WEBPAGE_INFO "${APP_NAME} Website" !define APP_WIKI "http://wiki.lyx.org; !define APP_WIKI_INFO "${APP_NAME} Wiki" -!define APP_COPYRIGHT "LyX is Copyright © 1995 by Matthias Ettrich, 1995-2016 by the LyX Team" +!define APP_COPYRIGHT "LyX is Copyright © 1995 by Matthias Ettrich, 1995-${COPYRIGHT_YEAR} by the LyX Team" !define APP_RUN "bin\lyx.exe" !define BIN_LYX "lyx.exe" diff --git a/development/Win32/packaging/installer/include/init.nsh b/development/Win32/packaging/installer/include/init.nsh index cd2de30..6447734 100644 --- a/development/Win32/packaging/installer/include/init.nsh +++ b/development/Win32/packaging/installer/include/init.nsh @@ -46,6 +46,12 @@ FunctionEnd Section "!${APP_NAME}" SecCore SectionIn RO + !if ${SETUPTYPE} == BUNDLE + # if no TeX was found MiKTeX will be installed which requires space + !if $PathLaTeX == "" + AddSize 102 # size in KB + !endif + !endif SectionEnd Section "$(SecFileAssocTitle)" SecFileAssoc diff --git a/development/Win32/packaging/installer/settings.nsh b/development/Win32/packaging/installer/settings.nsh index 210c3d4..1af4a8e 100644 --- a/development/Win32/packaging/installer/settings.nsh +++ b/development/Win32/packaging/installer/settings.nsh @@ -14,10 +14,12 @@ These typically need to be modified for each LyX release !define APP_VERSION_REVISION 0 !define APP_VERSION_EMERGENCY "" # use "1" for an emergency release of LyX otherwise "" !define APP_EMERGENCY_DOT "" # use "." for an emergency release of LyX otherwise "" -!define APP_VERSION_BUILD 1 # Start with 1 for the installer releases of each version +!define APP_VERSION_BUILD 2 # Start with 1 for the installer releases of each version !define APP_VERSION "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_REVISION}${APP_EMERGENCY_DOT}${APP_VERSION_EMERGENCY}" # Version to display +!define COPYRIGHT_YEAR 2016 + # # Installer file name @@ -45,7 +47,6 @@ These typically need to be modified for each LyX release # # MiKTeX and JabRef -# Sizes in KB !define MiKTeXRepo "ftp://ftp.fernuni-hagen.de/pub/mirrors/www.ctan.org/systems/win32/miktex/tm/packages/; @@ -55,7 +56,7 @@ These typically need to be modified for each LyX release # definitions for the Complete installer !if ${SETUPTYPE} == BUNDLE !define JabRefInstall "external\JabRef_windows_3_3.exe" - !define SIZE_JABREF 25730 + !define SIZE_JABREF 25730 # size in KB !define MiKTeXInstall "$INSTDIR\external\basic-miktex-2.9.5987.exe" !endif diff --git a/development/Win32/packaging/installer/setup/uninstall.nsh b/development/Win32/packaging/installer/setup/uninstall.nsh index 1bef3f0..3a4777f 100644 --- a/development/Win32/packaging/installer/setup/uninstall.nsh +++ b/development/Win32/packaging/installer/setup/uninstall.nsh @@ -114,6 +114,8 @@ Section /o "un.$(UnLyXPreferencesTitle)" un.SecUnPreferences # remove LyX's config files StrCpy $AppSubfolder ${APP_DIR_USERDATA} Call un.DelAppPathSub # function from LyXUtils.nsh + # remove registry settings + DeleteRegKey HKCU "Software\LyX\LyX${APP_SERIES_NAME}" SectionEnd
[LyX/2.2.x] Win installer: fix mistake introduced with last commit
commit 1921baf88ca3b1a4981452f307fc5c71957707d1 Author: Uwe StöhrDate: Tue May 31 01:24:47 2016 +0200 Win installer: fix mistake introduced with last commit diff --git a/development/Win32/packaging/installer/settings.nsh b/development/Win32/packaging/installer/settings.nsh index c676372..1af4a8e 100644 --- a/development/Win32/packaging/installer/settings.nsh +++ b/development/Win32/packaging/installer/settings.nsh @@ -56,7 +56,7 @@ These typically need to be modified for each LyX release # definitions for the Complete installer !if ${SETUPTYPE} == BUNDLE !define JabRefInstall "external\JabRef_windows_3_3.exe" - !define SIZE_JABREF "25730" # size in KB + !define SIZE_JABREF 25730 # size in KB !define MiKTeXInstall "$INSTDIR\external\basic-miktex-2.9.5987.exe" !endif
[LyX/2.2.x] Win installer: 2 bugfixes
commit 52548a44369e80b9d1411d07fbf795007f78c703 Author: Uwe StöhrDate: Tue May 31 01:22:12 2016 +0200 Win installer: 2 bugfixes diff --git a/development/Win32/packaging/installer/ChangeLog.txt b/development/Win32/packaging/installer/ChangeLog.txt index aa6d835..335530b 100644 --- a/development/Win32/packaging/installer/ChangeLog.txt +++ b/development/Win32/packaging/installer/ChangeLog.txt @@ -1,8 +1,13 @@ -Todo: add lyx.de to mirror list +Changelog for LyX-220-2: +- remove also the user dependent LyX settings from the registry if the user + preferences should be uninstalled +- calculate the required installation size correctly -Changelog for LyX.220-RC2-1: -- installs LyX 2.2.0 RC2 -- updated to Imagemagick 6.9.4-1 + +Changelog for LyX.220-1: +- installs LyX 2.2.0 +- updated to MiKTeX 2.9 build 5987 +- updated to Imagemagick 6.9.4-4 - updated to JabRef 3.3 - new thesaurus for Norwegian (Nynorsk) - updated thesaurus for English (US) and Norwegian (Bokmal) diff --git a/development/Win32/packaging/installer/include/declarations.nsh b/development/Win32/packaging/installer/include/declarations.nsh index 6657ffc..8cf8d98 100644 --- a/development/Win32/packaging/installer/include/declarations.nsh +++ b/development/Win32/packaging/installer/include/declarations.nsh @@ -44,7 +44,7 @@ Configuration of LyX installer !define APP_NAME "LyX" !define APP_VERSION_NUMBER "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_REVISION}.${APP_VERSION_BUILD}" -# for the proposed install folder we use the scheme "LyX 2.0" while we need for the registry the scheme "LyX 2.0.4" +# for the proposed install folder we use the scheme "LyX 2.1" while we need for the registry the scheme "LyX 2.1.4" # to check if it is exactly this version (to support side by side installations) !define APP_SERIES_NAME "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}" !define APP_SERIES_KEY "${APP_VERSION_MAJOR}${APP_VERSION_MINOR}${APP_VERSION_REVISION}${APP_VERSION_EMERGENCY}" @@ -57,12 +57,12 @@ Configuration of LyX installer !define APP_WEBPAGE_INFO "${APP_NAME} Website" !define APP_WIKI "http://wiki.lyx.org; !define APP_WIKI_INFO "${APP_NAME} Wiki" -!define APP_COPYRIGHT "LyX is Copyright © 1995 by Matthias Ettrich, 1995-2016 by the LyX Team" +!define APP_COPYRIGHT "LyX is Copyright © 1995 by Matthias Ettrich, 1995-${COPYRIGHT_YEAR} by the LyX Team" !define APP_RUN "bin\lyx.exe" !define BIN_LYX "lyx.exe" -!define APP_REGKEY "Software\${APP_NAME}${APP_SERIES_KEY}" # like "LyX200" +!define APP_REGKEY "Software\${APP_NAME}${APP_SERIES_KEY}" # like "LyX220" !define APP_REGKEY_SETUP "${APP_REGKEY}\Setup" !define APP_REGKEY_SETTINGS "${APP_REGKEY}\Settings" diff --git a/development/Win32/packaging/installer/include/init.nsh b/development/Win32/packaging/installer/include/init.nsh index 9076a00..6447734 100644 --- a/development/Win32/packaging/installer/include/init.nsh +++ b/development/Win32/packaging/installer/include/init.nsh @@ -14,7 +14,7 @@ Var LyXLangName !macro EXTERNAL_INIT COMPONENT # APP_REGKEY_SETUP = "Software\${APP_NAME}${APP_SERIES_KEY}\Setup" - # where ${APP_NAME}${APP_SERIES_KEY} is something like LyX16 + # where ${APP_NAME}${APP_SERIES_KEY} is something like LyX22 ReadRegStr $ComponentPath SHELL_CONTEXT "${APP_REGKEY_SETUP}" "${COMPONENT} Path" # BIN_LATEX etc are defined in settings.nsh @@ -46,6 +46,12 @@ FunctionEnd Section "!${APP_NAME}" SecCore SectionIn RO + !if ${SETUPTYPE} == BUNDLE + # if no TeX was found MiKTeX will be installed which requires space + !if $PathLaTeX == "" + AddSize 102 # size in KB + !endif + !endif SectionEnd Section "$(SecFileAssocTitle)" SecFileAssoc diff --git a/development/Win32/packaging/installer/settings.nsh b/development/Win32/packaging/installer/settings.nsh index 9fb8dea..c676372 100644 --- a/development/Win32/packaging/installer/settings.nsh +++ b/development/Win32/packaging/installer/settings.nsh @@ -12,12 +12,14 @@ These typically need to be modified for each LyX release !define APP_VERSION_MAJOR 2 !define APP_VERSION_MINOR 2 !define APP_VERSION_REVISION 0 -!define APP_VERSION_EMERGENCY "RC1" # use "1" for an emergency release of LyX otherwise "" -!define APP_EMERGENCY_DOT "." # use "." for an emergency release of LyX otherwise "" +!define APP_VERSION_EMERGENCY "" # use "1" for an emergency release of LyX otherwise "" +!define APP_EMERGENCY_DOT "" # use "." for an emergency release of LyX otherwise "" !define APP_VERSION_BUILD 2 # Start with 1 for the installer releases of each version !define APP_VERSION "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_REVISION}${APP_EMERGENCY_DOT}${APP_VERSION_EMERGENCY}" # Version to display +!define COPYRIGHT_YEAR 2016 + # # Installer file name @@ -45,11 +47,8 @@ These typically need to be modified for each LyX release # # MiKTeX and JabRef -# Sizes in KB -# it
[LyX/2.1.x] Win installer: prepare for 2.1.5 and bugfixes
commit dd2aef2c333f4b4c43f779489ffd8bf55a484192 Author: Uwe StöhrDate: Tue May 31 01:20:09 2016 +0200 Win installer: prepare for 2.1.5 and bugfixes diff --git a/development/Win32/packaging/installer/ChangeLog.txt b/development/Win32/packaging/installer/ChangeLog.txt index bed957b..df03314 100644 --- a/development/Win32/packaging/installer/ChangeLog.txt +++ b/development/Win32/packaging/installer/ChangeLog.txt @@ -1,4 +1,11 @@ -Changelog for LyX-214-7: +Changelog for LyX-215-1: +- installs LyX 2.1.5 +- remove also the user dependent LyX settings from the registry if the user + preferences should be uninstalled +- calculate the required installation size correctly + + +Changelog for LyX-214-7: - use a new default download server for missing LaTeX packages - updated to MiKTeX 2.9 build 5987 - updated to Imagemagick 6.9.4-1 diff --git a/development/Win32/packaging/installer/include/declarations.nsh b/development/Win32/packaging/installer/include/declarations.nsh index fee8c86..315e507 100644 --- a/development/Win32/packaging/installer/include/declarations.nsh +++ b/development/Win32/packaging/installer/include/declarations.nsh @@ -57,7 +57,7 @@ Configuration of LyX installer !define APP_WEBPAGE_INFO "${APP_NAME} Website" !define APP_WIKI "http://wiki.lyx.org; !define APP_WIKI_INFO "${APP_NAME} Wiki" -!define APP_COPYRIGHT "LyX is Copyright © 1995 by Matthias Ettrich, 1995-2016 by the LyX Team" +!define APP_COPYRIGHT "LyX is Copyright © 1995 by Matthias Ettrich, 1995-${COPYRIGHT_YEAR} by the LyX Team" !define APP_RUN "bin\lyx.exe" !define BIN_LYX "lyx.exe" diff --git a/development/Win32/packaging/installer/include/init.nsh b/development/Win32/packaging/installer/include/init.nsh index de9bf25..395a869 100644 --- a/development/Win32/packaging/installer/include/init.nsh +++ b/development/Win32/packaging/installer/include/init.nsh @@ -46,6 +46,12 @@ FunctionEnd Section "!${APP_NAME}" SecCore SectionIn RO + !if ${SETUPTYPE} == BUNDLE + # if no TeX was found MiKTeX will be installed which requires space + !if $PathLaTeX == "" + AddSize 102 # size in KB + !endif + !endif SectionEnd Section "$(SecFileAssocTitle)" SecFileAssoc diff --git a/development/Win32/packaging/installer/settings.nsh b/development/Win32/packaging/installer/settings.nsh index a0d4b40..f4a869a 100644 --- a/development/Win32/packaging/installer/settings.nsh +++ b/development/Win32/packaging/installer/settings.nsh @@ -11,17 +11,19 @@ These typically need to be modified for each LyX release !define APP_VERSION_MAJOR 2 !define APP_VERSION_MINOR 1 -!define APP_VERSION_REVISION 4 +!define APP_VERSION_REVISION 5 !define APP_VERSION_EMERGENCY "" # use "1" for an emergency release of LyX otherwise "" !define APP_EMERGENCY_DOT "" # use "." for an emergency release of LyX otherwise "" -!define APP_VERSION_BUILD 7 # Start with 1 for the installer releases of each version +!define APP_VERSION_BUILD 1 # Start with 1 for the installer releases of each version !define APP_VERSION "${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_REVISION}${APP_EMERGENCY_DOT}${APP_VERSION_EMERGENCY}" # Version to display +!define COPYRIGHT_YEAR 2016 + # # Installer file name -# Typical names for the release are "LyX-201-Installer-1.exe" etc. +# Typical names for the release are "LyX-211-Installer-1.exe" etc. !ifndef ExeFile !define ExeFile "LyX-${APP_VERSION_MAJOR}${APP_VERSION_MINOR}${APP_VERSION_REVISION}${APP_VERSION_EMERGENCY}-Installer-${APP_VERSION_BUILD}.exe" @@ -45,7 +47,6 @@ These typically need to be modified for each LyX release # # MiKTeX and JabRef -# Sizes in KB !define MiKTeXRepo "ftp://ftp.fernuni-hagen.de/pub/mirrors/www.ctan.org/systems/win32/miktex/tm/packages/; @@ -56,7 +57,7 @@ These typically need to be modified for each LyX release # definitions for the Complete installer !if ${SETUPTYPE} == BUNDLE !define JabRefInstall "external\JabRef-2.11-setup.exe" - !define SIZE_JABREF 14100 + !define SIZE_JABREF 14100 # size in KB !define MiKTeXInstall "$INSTDIR\external\basic-miktex-2.9.5987.exe" !endif diff --git a/development/Win32/packaging/installer/setup/uninstall.nsh b/development/Win32/packaging/installer/setup/uninstall.nsh index cc96d61..d39f7aa 100644 --- a/development/Win32/packaging/installer/setup/uninstall.nsh +++ b/development/Win32/packaging/installer/setup/uninstall.nsh @@ -68,11 +68,13 @@ Section "un.LyX" un.SecUnProgramFiles SetOutPath "$TEMP" RMDir /r "$INSTDIR" - # Registry keys + # Registry keys and values DeleteRegKey SHCTX "${APP_REGKEY_SETUP}" DeleteRegKey SHCTX "${APP_REGKEY}" DeleteRegKey SHCTX "${APP_UNINST_KEY}" DeleteRegKey HKCR "Applications\lyx.exe" + DeleteRegValue HKCR "LyX.Document\Shell\open\command" "" + DeleteRegValue HKCR "LyX.Document\DefaultIcon" "" # File associations ReadRegStr $FileAssociation SHELL_CONTEXT
[LyX/master] ShortcutPrefs: clean-up
commit b53d07897b3e8f1e89e8d12005508b23921042b8 Author: Guillaume MunchDate: Sun May 29 20:58:33 2016 +0100 ShortcutPrefs: clean-up diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index 98dbd8c..91f8720 100644 --- a/src/frontends/qt4/GuiPrefs.cpp +++ b/src/frontends/qt4/GuiPrefs.cpp @@ -2822,6 +2822,13 @@ void PrefShortcuts::updateShortcutsTW() } +//static +KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item) +{ + return static_cast(item.data(0, Qt::UserRole).toInt()); +} + + void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag) { item->setData(0, Qt::UserRole, QVariant(tag)); @@ -2915,9 +2922,7 @@ void PrefShortcuts::on_shortcutsTW_itemSelectionChanged() if (items.isEmpty()) return; - KeyMap::ItemType tag = - static_cast(items[0]->data(0, Qt::UserRole).toInt()); - if (tag == KeyMap::UserUnbind) + if (itemType(*items[0]) == KeyMap::UserUnbind) removePB->setText(qt_("Res")); else removePB->setText(qt_("Remo")); @@ -2955,10 +2960,8 @@ void PrefShortcuts::removeShortcut() string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString()); string lfun = fromqstr(items[i]->text(0)); FuncRequest func = lyxaction.lookupFunc(lfun); - KeyMap::ItemType tag = - static_cast(items[i]->data(0, Qt::UserRole).toInt()); - switch (tag) { + switch (itemType(*items[i])) { case KeyMap::System: { // for system bind, we do not touch the item // but add an user unbind item @@ -3010,10 +3013,8 @@ void PrefShortcuts::deactivateShortcuts(QList const & items) string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString()); string lfun = fromqstr(items[i]->text(0)); FuncRequest func = lyxaction.lookupFunc(lfun); - KeyMap::ItemType tag = - static_cast(items[i]->data(0, Qt::UserRole).toInt()); - switch (tag) { + switch (itemType(*items[i])) { case KeyMap::System: // for system bind, we do not touch the item // but add an user unbind item diff --git a/src/frontends/qt4/GuiPrefs.h b/src/frontends/qt4/GuiPrefs.h index c2c4576..9f6c35e 100644 --- a/src/frontends/qt4/GuiPrefs.h +++ b/src/frontends/qt4/GuiPrefs.h @@ -456,6 +456,23 @@ public: void applyRC(LyXRC & rc) const; void updateRC(LyXRC const & rc); void updateShortcutsTW(); + +public Q_SLOTS: + void selectBind(); + void on_modifyPB_pressed(); + void on_newPB_pressed(); + void on_removePB_pressed(); + void on_searchLE_textEdited(); + /// + void on_shortcutsTW_itemSelectionChanged(); + void on_shortcutsTW_itemDoubleClicked(); + /// + void shortcutOkPressed(); + void shortcutCancelPressed(); + void shortcutClearPressed(); + void shortcutRemovePressed(); + +private: void modifyShortcut(); /// remove selected binding, restore default value void removeShortcut(); @@ -472,25 +489,11 @@ public: FuncRequest currentBinding(KeySequence const & k); /// void setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag); - QTreeWidgetItem * insertShortcutItem(FuncRequest const & lfun, - KeySequence const & shortcut, KeyMap::ItemType tag); - -public Q_SLOTS: - void selectBind(); - void on_modifyPB_pressed(); - void on_newPB_pressed(); - void on_removePB_pressed(); - void on_searchLE_textEdited(); /// - void on_shortcutsTW_itemSelectionChanged(); - void on_shortcutsTW_itemDoubleClicked(); + static KeyMap::ItemType itemType(QTreeWidgetItem & item); /// - void shortcutOkPressed(); - void shortcutCancelPressed(); - void shortcutClearPressed(); - void shortcutRemovePressed(); - -private: + QTreeWidgetItem * insertShortcutItem(FuncRequest const & lfun, + KeySequence const & shortcut, KeyMap::ItemType tag); /// GuiShortcutDialog * shortcut_; ///
[LyX/master] Show names of debug modes in the debug panel
commit 2b6d0ae3deae80558a73346d60739fa408cbe2c3 Author: Guillaume MunchDate: Sun May 29 23:33:12 2016 +0100 Show names of debug modes in the debug panel Sometimes it's hard to know which is which from a translation of the description alone. diff --git a/src/frontends/qt4/GuiProgressView.cpp b/src/frontends/qt4/GuiProgressView.cpp index af455f2..454148f 100644 --- a/src/frontends/qt4/GuiProgressView.cpp +++ b/src/frontends/qt4/GuiProgressView.cpp @@ -88,7 +88,9 @@ GuiProgressView::GuiProgressView(GuiView & parent, Qt::DockWidgetArea area, DebugVector dmap; for (int i = 1 ; i < level_count; i++) { Debug::Type const level = Debug::value(i); - QString const desc = qt_(Debug::description(level)); + QString const desc = + toqstr(from_ascii(Debug::name(level) + " - ")) + + qt_(Debug::description(level)); dmap.push_back(DebugMap(level, desc)); } sort(dmap.begin(), dmap.end(), DebugSorter);
[LyX/master] TocWidget: fix part of #9825
commit 78a5c877812a522534a79ab81eb37fe9df9bf5e5 Author: Guillaume MunchDate: Mon May 30 22:11:27 2016 +0100 TocWidget: fix part of #9825 diff --git a/src/frontends/qt4/TocWidget.cpp b/src/frontends/qt4/TocWidget.cpp index ff929c0..e98786b 100644 --- a/src/frontends/qt4/TocWidget.cpp +++ b/src/frontends/qt4/TocWidget.cpp @@ -246,6 +246,7 @@ void TocWidget::on_tocTV_pressed(QModelIndex const & index) if (button & Qt::LeftButton) { goTo(index); gui_view_.setFocus(); + gui_view_.activateWindow(); } }
[LyX/master] GuiDelimiter: Synchronise the vertical scrollbars
commit ef8b8ebcfd611b295c164f41450f74e0c0855ccc Author: Guillaume MunchDate: Tue May 10 18:34:39 2016 +0100 GuiDelimiter: Synchronise the vertical scrollbars diff --git a/src/frontends/qt4/GuiDelimiter.cpp b/src/frontends/qt4/GuiDelimiter.cpp index 1f96788..72e2296 100644 --- a/src/frontends/qt4/GuiDelimiter.cpp +++ b/src/frontends/qt4/GuiDelimiter.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -234,6 +235,8 @@ GuiDelimiter::GuiDelimiter(GuiView & lv) sizeCO->addItem(qt_(biggui[i])); on_leftLW_currentRowChanged(0); + // synchronise the scroll bars + on_matchCB_stateChanged(matchCB->checkState()); bc().setPolicy(ButtonPolicy::IgnorantPolicy); } @@ -361,9 +364,23 @@ void GuiDelimiter::on_rightLW_currentRowChanged(int item) void GuiDelimiter::on_matchCB_stateChanged(int state) { - if (state == Qt::Checked) + // Synchronise the vertical scroll bars when checked + QScrollBar * ls = leftLW->verticalScrollBar(); + QScrollBar * rs = rightLW->verticalScrollBar(); + + if (state == Qt::Checked) { on_leftLW_currentRowChanged(leftLW->currentRow()); + connect(ls, SIGNAL(valueChanged(int)), rs, SLOT(setValue(int)), + Qt::UniqueConnection); + connect(rs, SIGNAL(valueChanged(int)), ls, SLOT(setValue(int)), + Qt::UniqueConnection); + rs->setValue(ls->value()); + } else { + ls->disconnect(rs); + rs->disconnect(ls); + } + updateTeXCode(sizeCO->currentIndex()); }
[LyX/master] GuiDelimiters: display at least (and at most?) 4 columns
commit 6aceb3558aa40e9af6731010b90f8ae0f9d9c6cf Author: Guillaume MunchDate: Tue May 10 18:47:27 2016 +0100 GuiDelimiters: display at least (and at most?) 4 columns diff --git a/src/frontends/qt4/GuiDelimiter.cpp b/src/frontends/qt4/GuiDelimiter.cpp index 72e2296..94154f5 100644 --- a/src/frontends/qt4/GuiDelimiter.cpp +++ b/src/frontends/qt4/GuiDelimiter.cpp @@ -188,6 +188,9 @@ GuiDelimiter::GuiDelimiter(GuiView & lv) QFontMetrics fm(frontend::getFont(lyxfont)); QSize item_size(fm.maxWidth(), fm.height() + 8); + leftLW->setMinimumWidth(5 * item_size.width()); + rightLW->setMinimumWidth(5 * item_size.width()); + typedef map ListItems; ListItems list_items; // The last element is the empty one.
[LyX/master] TocModel: clean-up
commit 6a662cbb2717f8c11e4b5e77e7d6a6320a0fce85 Author: Guillaume MunchDate: Mon May 30 22:11:00 2016 +0100 TocModel: clean-up diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 6bfcdcb..c1c74d5 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -1664,6 +1664,8 @@ void GuiView::updateTocItem(string const & type, DocIterator const & dit) void GuiView::structureChanged() { + // FIXME: This is slightly expensive, though less than the tocBackend update + // (#9880). This also resets the view in the Toc Widget (#6675). d.toc_models_.reset(documentBufferView()); // Navigator needs more than a simple update in this case. It needs to be // rebuilt. diff --git a/src/frontends/qt4/TocModel.cpp b/src/frontends/qt4/TocModel.cpp index 7654983..9fb9481 100644 --- a/src/frontends/qt4/TocModel.cpp +++ b/src/frontends/qt4/TocModel.cpp @@ -38,6 +38,8 @@ namespace frontend { /// A QStandardItemModel that gives access to the reset methods. /// This is needed in order to fix http://www.lyx.org/trac/ticket/3740 +// FIXME: Better appropriately subclass QStandardItemModel and implement +// the toc-specific reset methods there. class TocTypeModel : public QStandardItemModel { public: @@ -47,27 +49,18 @@ public: /// void reset() { -#if (QT_VERSION < 0x05) - QStandardItemModel::reset(); -#else + QStandardItemModel::beginResetModel(); QStandardItemModel::endResetModel(); -#endif } /// void beginResetModel() - { - #if QT_VERSION >= 0x040600 - QStandardItemModel::beginResetModel(); - #endif + { + QStandardItemModel::beginResetModel(); } /// void endResetModel() - { - #if QT_VERSION >= 0x040600 - QStandardItemModel::endResetModel(); - #else - QStandardItemModel::reset(); - #endif + { + QStandardItemModel::endResetModel(); } }; diff --git a/src/frontends/qt4/TocModel.h b/src/frontends/qt4/TocModel.h index c959aba..f0f9efa 100644 --- a/src/frontends/qt4/TocModel.h +++ b/src/frontends/qt4/TocModel.h @@ -136,10 +136,6 @@ public: TocItem const currentItem(QString const & type, QModelIndex const & index) const; -Q_SIGNALS: - /// Signal that the internal toc_models_ has been reset. - void modelReset(); - private: typedef QHash ::const_iterator const_iterator; typedef QHash ::iterator iterator;
[LyX/master] TocWidget: fix an erroneous collapse and optimise updates based on profiling
commit 1cc14a31ca8320d881b674f93c34a09cf1666cca Author: Guillaume MunchDate: Mon May 30 21:42:08 2016 +0100 TocWidget: fix an erroneous collapse and optimise updates based on profiling TocModels::reset() in GuiView::structureChanged() collapses the TocWidget, and therefore requires an update right after, which was missing. In fact, profiling TocWidget::updateView() shows that delaying the update is good only for fast keypresses (essentially movement). It costs 5% of a char-forward operation in a document with approx. 100 table of contents items. The update optimisation has been rewritten to take this data into account. diff --git a/src/frontends/qt4/GuiToc.cpp b/src/frontends/qt4/GuiToc.cpp index 48349fc..29ec85c 100644 --- a/src/frontends/qt4/GuiToc.cpp +++ b/src/frontends/qt4/GuiToc.cpp @@ -67,7 +67,6 @@ void GuiToc::dispatchParams() void GuiToc::enableView(bool enable) { - widget_->checkModelChanged(); if (!enable) // In the opposite case, updateView() will be called anyway. widget_->updateViewNow(); diff --git a/src/frontends/qt4/TocWidget.cpp b/src/frontends/qt4/TocWidget.cpp index e98786b..c30d644 100644 --- a/src/frontends/qt4/TocWidget.cpp +++ b/src/frontends/qt4/TocWidget.cpp @@ -45,8 +45,7 @@ namespace frontend { TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) : QWidget(parent), depth_(0), persistent_(false), gui_view_(gui_view), - update_timer_short_(new QTimer(this)), - update_timer_long_(new QTimer(this)) + timer_(new QTimer(this)) { setupUi(this); @@ -88,21 +87,8 @@ TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) this, SLOT(filterContents())); // setting the update timer - update_timer_short_->setSingleShot(true); - update_timer_long_->setSingleShot(true); - update_timer_short_->setInterval(0); - update_timer_long_->setInterval(2000); - connect(update_timer_short_, SIGNAL(timeout()), - this, SLOT(realUpdateView())); - connect(update_timer_long_, SIGNAL(timeout()), - this, SLOT(realUpdateView())); - - // fix #9826: Outline disclosure of subsection content disappears one second - // after doubleclicking content item. - // This is only meant as a workaround. See #6675 for more general issues - // regarding unwanted collapse of the tree view. - connect(tocTV, SIGNAL(expanded(const QModelIndex &)), - update_timer_long_, SLOT(stop())); + timer_->setSingleShot(true); + connect(timer_, SIGNAL(timeout()), this, SLOT(finishUpdateView())); init(QString()); } @@ -396,26 +382,6 @@ void TocWidget::enableControls(bool enable) void TocWidget::updateView() { - // Subtler optimization for having the delay more UI invisible. - // We trigger update immediately for sparse editation actions, - // i.e. there was no editation/cursor movement in last 2 sec. - // At worst there will be +1 redraw after 2s in a such "calm" mode. - if (!update_timer_long_->isActive()) - update_timer_short_->start(); - // resets the timer to trigger after 2s - update_timer_long_->start(); -} - - -void TocWidget::updateViewNow() -{ - update_timer_long_->stop(); - update_timer_short_->start(); -} - - -void TocWidget::realUpdateView() -{ if (!gui_view_.documentBufferView()) { tocTV->setModel(0); depthSL->setMaximum(0); @@ -426,7 +392,7 @@ void TocWidget::realUpdateView() setEnabled(true); bool const is_sortable = isSortable(); sortCB->setEnabled(is_sortable); - bool focus_ = tocTV->hasFocus(); + bool focus = tocTV->hasFocus(); tocTV->setEnabled(false); tocTV->setUpdatesEnabled(false); @@ -444,8 +410,7 @@ void TocWidget::realUpdateView() && gui_view_.tocModels().isSorted(current_type_)); sortCB->blockSignals(false); - bool const can_navigate_ = canNavigate(); - persistentCB->setEnabled(can_navigate_); + persistentCB->setEnabled(canNavigate()); bool controls_enabled = toc_model && toc_model->rowCount() > 0 && !gui_view_.documentBufferView()->buffer().isReadonly(); @@ -453,25 +418,42 @@ void TocWidget::realUpdateView() depthSL->setMaximum(gui_view_.tocModels().depth(current_type_)); depthSL->setValue(depth_); - if (!persistent_ && can_navigate_) - setTreeDepth(depth_); - if (can_navigate_) { - persistentCB->setChecked(persistent_); - select(gui_view_.tocModels().currentIndex(current_type_)); - } - filterContents(); tocTV->setEnabled(true); tocTV->setUpdatesEnabled(true); - if (focus_) + if (focus) tocTV->setFocus(); + + // Expensive operations are
[LyX/master] ShortcutPrefs: hide empty lfuns for which there is already a binding
commit 8aaa79cfb64ad9eab8ba45dfcc21f07679404517 Author: Guillaume MunchDate: Tue Feb 23 22:02:02 2016 + ShortcutPrefs: hide empty lfuns for which there is already a binding diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index 91f8720..109de93 100644 --- a/src/frontends/qt4/GuiPrefs.cpp +++ b/src/frontends/qt4/GuiPrefs.cpp @@ -2813,7 +2813,7 @@ void PrefShortcuts::updateShortcutsTW() KeyMap::BindingList::const_iterator it = bindinglist.begin(); KeyMap::BindingList::const_iterator it_end = bindinglist.end(); for (; it != it_end; ++it) - insertShortcutItem(it->request, it->sequence, KeyMap::ItemType(it->tag)); + insertShortcutItem(it->request, it->sequence, it->tag); shortcutsTW->sortItems(0, Qt::AscendingOrder); on_shortcutsTW_itemSelectionChanged(); @@ -2829,6 +2829,14 @@ KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item) } +//static +bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item) +{ + // Hide rebound system settings that are empty + return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty(); +} + + void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag) { item->setData(0, Qt::UserRole, QVariant(tag)); @@ -2848,7 +2856,7 @@ void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag) font.setStrikeOut(true); break; } - + item->setHidden(isAlwaysHidden(*item)); item->setFont(1, font); } @@ -2951,6 +2959,23 @@ void PrefShortcuts::modifyShortcut() } +void PrefShortcuts::unhideEmpty(QString const & lfun, bool select) +{ + // list of items that match lfun + QList items = shortcutsTW->findItems(lfun, +Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0); + for (int i = 0; i < items.size(); ++i) { + QTreeWidgetItem * item = items[i]; + if (isAlwaysHidden(*item)) { + setItemType(item, KeyMap::System); + if (select) + shortcutsTW->setCurrentItem(item); + return; + } + } +} + + void PrefShortcuts::removeShortcut() { // it seems that only one item can be selected, but I am @@ -2980,6 +3005,9 @@ void PrefShortcuts::removeShortcut() else shortcutsTW->scrollToItem(parent); user_bind_.unbind(shortcut, func); + // If this user binding hid an empty system binding, unhide the + // latter and select it. + unhideEmpty(items[i]->text(0), true); break; } case KeyMap::UserUnbind: { @@ -3028,6 +3056,7 @@ void PrefShortcuts::deactivateShortcuts(QList const & items) int itemIdx = parent->indexOfChild(items[i]); parent->takeChild(itemIdx); user_bind_.unbind(shortcut, func); + unhideEmpty(items[i]->text(0), false); break; } default: @@ -3076,8 +3105,11 @@ void PrefShortcuts::on_searchLE_textEdited() if (searchLE->text().isEmpty()) { // show all hidden items QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden); - while (*it) - shortcutsTW->setItemHidden(*it++, false); + for (; *it; ++it) + shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it)); + // close all categories + for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i) + shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i)); return; } // search both columns @@ -3091,10 +3123,11 @@ void PrefShortcuts::on_searchLE_textEdited() while (*it) shortcutsTW->setItemHidden(*it++, true); // show matched items - for (int i = 0; i < matched.size(); ++i) { - shortcutsTW->setItemHidden(matched[i], false); - shortcutsTW->setItemExpanded(matched[i]->parent(), true); - } + for (int i = 0; i < matched.size(); ++i) + if (!isAlwaysHidden(*matched[i])) { + shortcutsTW->setItemHidden(matched[i], false); + shortcutsTW->setItemExpanded(matched[i]->parent(), true); + } } diff --git a/src/frontends/qt4/GuiPrefs.h b/src/frontends/qt4/GuiPrefs.h index 9f6c35e..1b37b32 100644 --- a/src/frontends/qt4/GuiPrefs.h +++ b/src/frontends/qt4/GuiPrefs.h @@ -491,6 +491,12 @@ private: void setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag); /// static
[LyX/master] UserGuide.lyx: update 2 images
commit b4ab19421691dca51c528fc75924ce7120053c46 Author: Uwe StöhrDate: Mon May 30 23:20:49 2016 +0200 UserGuide.lyx: update 2 images diff --git a/lib/doc/es/EmbeddedObjects.lyx b/lib/doc/es/EmbeddedObjects.lyx index a42c6aa..05d534b 100644 --- a/lib/doc/es/EmbeddedObjects.lyx +++ b/lib/doc/es/EmbeddedObjects.lyx @@ -24358,7 +24358,6 @@ arg "label-insert" y se inserta un cuadro gris como este: \begin_inset Graphics filename clipart/etiqueta.png - scale 85 \end_inset @@ -24410,7 +24409,6 @@ arg "dialog-show-new-inset ref" Se inserta un cuadro gris como este: \begin_inset Graphics filename clipart/referencia.png - scale 85 \end_inset diff --git a/lib/doc/es/UserGuide.lyx b/lib/doc/es/UserGuide.lyx index 17618d3..6a6c27f 100644 --- a/lib/doc/es/UserGuide.lyx +++ b/lib/doc/es/UserGuide.lyx @@ -18387,7 +18387,6 @@ verás un recuadro como este : \begin_inset Graphics filename clipart/notapie.png - scale 85 groupId botonesbh \end_inset @@ -22614,7 +22613,6 @@ Flotantes ! Leyenda Un recuadro se muestra así: \begin_inset Graphics filename clipart/flotante.png - scale 85 groupId botonesbh \end_inset @@ -24375,7 +24373,6 @@ b se ve \begin_inset Graphics filename ../clipart/SpaceMarker.png - scale 85 groupId botonesbh \end_inset @@ -26952,7 +26949,6 @@ Aceptar se inserta un cuadro gris parecido a este: \begin_inset Graphics filename clipart/etiqueta.png - scale 85 groupId botonesbh \end_inset @@ -27019,7 +27015,6 @@ Aceptar se inserta un recuadro gris parecido a este: \begin_inset Graphics filename clipart/referencia.png - scale 85 groupId botonesbh \end_inset diff --git a/lib/doc/es/clipart/etiqueta.png b/lib/doc/es/clipart/etiqueta.png index 743385a..2b97ebe 100644 Binary files a/lib/doc/es/clipart/etiqueta.png and b/lib/doc/es/clipart/etiqueta.png differ diff --git a/lib/doc/es/clipart/referencia.png b/lib/doc/es/clipart/referencia.png index 51f371c..3d810b3 100644 Binary files a/lib/doc/es/clipart/referencia.png and b/lib/doc/es/clipart/referencia.png differ diff --git a/lib/doc/ja/EmbeddedObjects.lyx b/lib/doc/ja/EmbeddedObjects.lyx index 470559e..d20dbc8 100644 --- a/lib/doc/ja/EmbeddedObjects.lyx +++ b/lib/doc/ja/EmbeddedObjects.lyx @@ -23553,7 +23553,6 @@ arg "dialog-show-new-inset ref" を使えば,ラベルを参照することができます. \begin_inset Graphics filename clipart/reference.png - scale 85 scaleBeforeRotation \end_inset diff --git a/lib/doc/ja/UserGuide.lyx b/lib/doc/ja/UserGuide.lyx index 363a79d..4d16697 100644 --- a/lib/doc/ja/UserGuide.lyx +++ b/lib/doc/ja/UserGuide.lyx @@ -22464,7 +22464,6 @@ arg "label-insert" を押して,第2項目にラベルを挿入します. \begin_inset Graphics filename clipart/label.png - scale 85 \end_inset @@ -22501,7 +22500,6 @@ arg "dialog-show-new-inset ref" を使用して,そのラベル名を参照してください. \begin_inset Graphics filename clipart/reference.png - scale 85 \end_inset diff --git a/lib/doc/ja/clipart/label.png b/lib/doc/ja/clipart/label.png index 64add63..2bad138 100644 Binary files a/lib/doc/ja/clipart/label.png and b/lib/doc/ja/clipart/label.png differ diff --git a/lib/doc/ja/clipart/reference.png b/lib/doc/ja/clipart/reference.png index e3cfdfc..86f3c6c 100644 Binary files a/lib/doc/ja/clipart/reference.png and b/lib/doc/ja/clipart/reference.png differ
[LyX/2.2.x] UserGuide.lyx: update 2 images
commit cbd103e159bb39c3d5293a687661eb09686b6064 Author: Uwe StöhrDate: Mon May 30 23:19:24 2016 +0200 UserGuide.lyx: update 2 images diff --git a/lib/doc/es/EmbeddedObjects.lyx b/lib/doc/es/EmbeddedObjects.lyx index a42c6aa..05d534b 100644 --- a/lib/doc/es/EmbeddedObjects.lyx +++ b/lib/doc/es/EmbeddedObjects.lyx @@ -24358,7 +24358,6 @@ arg "label-insert" y se inserta un cuadro gris como este: \begin_inset Graphics filename clipart/etiqueta.png - scale 85 \end_inset @@ -24410,7 +24409,6 @@ arg "dialog-show-new-inset ref" Se inserta un cuadro gris como este: \begin_inset Graphics filename clipart/referencia.png - scale 85 \end_inset diff --git a/lib/doc/es/UserGuide.lyx b/lib/doc/es/UserGuide.lyx index 17618d3..6a6c27f 100644 --- a/lib/doc/es/UserGuide.lyx +++ b/lib/doc/es/UserGuide.lyx @@ -18387,7 +18387,6 @@ verás un recuadro como este : \begin_inset Graphics filename clipart/notapie.png - scale 85 groupId botonesbh \end_inset @@ -22614,7 +22613,6 @@ Flotantes ! Leyenda Un recuadro se muestra así: \begin_inset Graphics filename clipart/flotante.png - scale 85 groupId botonesbh \end_inset @@ -24375,7 +24373,6 @@ b se ve \begin_inset Graphics filename ../clipart/SpaceMarker.png - scale 85 groupId botonesbh \end_inset @@ -26952,7 +26949,6 @@ Aceptar se inserta un cuadro gris parecido a este: \begin_inset Graphics filename clipart/etiqueta.png - scale 85 groupId botonesbh \end_inset @@ -27019,7 +27015,6 @@ Aceptar se inserta un recuadro gris parecido a este: \begin_inset Graphics filename clipart/referencia.png - scale 85 groupId botonesbh \end_inset diff --git a/lib/doc/es/clipart/etiqueta.png b/lib/doc/es/clipart/etiqueta.png index 743385a..2b97ebe 100644 Binary files a/lib/doc/es/clipart/etiqueta.png and b/lib/doc/es/clipart/etiqueta.png differ diff --git a/lib/doc/es/clipart/referencia.png b/lib/doc/es/clipart/referencia.png index 51f371c..3d810b3 100644 Binary files a/lib/doc/es/clipart/referencia.png and b/lib/doc/es/clipart/referencia.png differ diff --git a/lib/doc/ja/EmbeddedObjects.lyx b/lib/doc/ja/EmbeddedObjects.lyx index 470559e..d20dbc8 100644 --- a/lib/doc/ja/EmbeddedObjects.lyx +++ b/lib/doc/ja/EmbeddedObjects.lyx @@ -23553,7 +23553,6 @@ arg "dialog-show-new-inset ref" を使えば,ラベルを参照することができます. \begin_inset Graphics filename clipart/reference.png - scale 85 scaleBeforeRotation \end_inset diff --git a/lib/doc/ja/UserGuide.lyx b/lib/doc/ja/UserGuide.lyx index 363a79d..4d16697 100644 --- a/lib/doc/ja/UserGuide.lyx +++ b/lib/doc/ja/UserGuide.lyx @@ -22464,7 +22464,6 @@ arg "label-insert" を押して,第2項目にラベルを挿入します. \begin_inset Graphics filename clipart/label.png - scale 85 \end_inset @@ -22501,7 +22500,6 @@ arg "dialog-show-new-inset ref" を使用して,そのラベル名を参照してください. \begin_inset Graphics filename clipart/reference.png - scale 85 \end_inset diff --git a/lib/doc/ja/clipart/label.png b/lib/doc/ja/clipart/label.png index 64add63..2bad138 100644 Binary files a/lib/doc/ja/clipart/label.png and b/lib/doc/ja/clipart/label.png differ diff --git a/lib/doc/ja/clipart/reference.png b/lib/doc/ja/clipart/reference.png index e3cfdfc..86f3c6c 100644 Binary files a/lib/doc/ja/clipart/reference.png and b/lib/doc/ja/clipart/reference.png differ
[LyX/2.2.x] status.22x: undocument a bugfix
commit 4dd30bca570853983061253f2201391409de492b Author: Georg BaumDate: Mon May 30 21:34:33 2016 +0200 status.22x: undocument a bugfix This reverts c5e63f73b, since the fix is already in 2.2.0. diff --git a/status.22x b/status.22x index 05e71e5..c1ed4b4 100644 --- a/status.22x +++ b/status.22x @@ -62,8 +62,6 @@ What's new * LYXHTML -- Fix typo in XHTML output (bug #10124). - * TEX2LYX
[LyX/master] Only add inset postion to cache in paintInset
commit 77ef48d093d08ef3491e4f00a994f9709b41ccf2 Author: Jean-Marc LasgouttesDate: Mon Feb 29 14:34:55 2016 +0100 Only add inset postion to cache in paintInset It was also added in paintText and paintOnlyInsets. diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp index 2766642..40d2618 100644 --- a/src/RowPainter.cpp +++ b/src/RowPainter.cpp @@ -577,7 +577,6 @@ void RowPainter::paintOnlyInsets() Row::Element const & e = *cit; if (e.type == Row::INSET) { // If outer row has changed, nested insets are repainted completely. - pi_.base.bv->coordCache().insets().add(e.inset, int(x_), yo_); bool const nested_inset = (e.inset->asInsetMath() && !e.inset->asInsetMath()->asMacroTemplate()) || e.inset->asInsetText() || e.inset->asInsetTabular(); @@ -611,8 +610,7 @@ void RowPainter::paintText() paintMisspelledMark(orig_x, e); break; case Row::INSET: { - // If outer row has changed, nested insets are repaint completely. - pi_.base.bv->coordCache().insets().add(e.inset, int(x_), yo_); + // If outer row has changed, nested insets are repainted completely. paintInset(e); foreign_descent = e.dim.descent(); }
[LyX/master] Update PAINTING_ANALYSIS and add a new task
commit 095c390fe2d7c983ccb0228d73c09b8da58bc206 Author: Jean-Marc LasgouttesDate: Wed May 11 14:16:08 2016 +0200 Update PAINTING_ANALYSIS and add a new task diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index acb033d..78719f5 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -58,15 +58,14 @@ The global idea would be to extend FitCursor to cover also horizontal cursor. -* Proposals - - * Clean-up of drawing code The goal is to make painting with drawing disable fast enough that it can be used after every metrics computation. Then we can separate real drawing from metrics. +Other changes are only clean-ups. + ** DONE RowPainter Inset position is set in paintInset, paintOnlyInsets, and paintText. @@ -114,29 +113,14 @@ topBottomSpace parameter should be removed after that. The helper version should return a Row::Element instead of an InsetTable. -** TODO make Inset::display() more useful +** Do not make RowPainter operations update x_ -[This has been started in the features/betterbreak branch. Time will -tell whether it really helps. The question in particular is the -handling of separator insets] +It is better to make them const and update x_ separately. -Extending the DisplayType enum would allow to remove special cases -from the code. - -The enumeration could be like -: Inline = 0 -: BreakBefore = 1 // break row before this inset -: BreakAfter = 2 // break row after this inset -: CanBreakAfter = 4 // optionally break row after this inset -: AlignLeft = 8 -: AlignRight = 16 -: NoBoundary = 32 // do not allow cursor to go at the end of the row -: //before display inset -: Display = BreakBefore|BreakAfter - -A display equation would be Display, other could be Display|AlignLeft -BreakAfter can be used by Newline or separator insets -CanBreakAfter can be used by the optional hyphen InsetSpecialChar. +Then it will be possible to reorder the painting of the different +elements. In particular, if text is painted last, it will be more +visible in the presence of underlines (foreign language, change +tracking, spell check). ** Set inset position during metrics phase @@ -222,12 +206,8 @@ update flag is Update::None. ** Metrics computation This is triggered by bv::updateMetrics, which calls tm::redoParagraph for - + all visible paragraphs - + paragraph above the screen (up to one page) - + paragraphs below the screen (up to one page again) - -The paragraphs outside of the screen are required to make PageUp/Down -work. +all visible paragraphs. Paragraphs above or below the screen (needed +for page up/down) and computed as needed. tm::redoParagraph will call Inset::metrics for each inset. In the case of text insets, this will invoke recursively tm::metrics, which redoes
[LyX/master] Set vertical margins in redoParagraph, not setRowHeight
commit 656b7f5ab7de9d96a0ec3379dc47fd138b1caa4f Author: Jean-Marc LasgouttesDate: Fri Apr 8 16:34:46 2016 +0200 Set vertical margins in redoParagraph, not setRowHeight It is actually easier to set the 20 pixels margin in redoParagraph, since it is not necessary to take newlines in account when deciding what is the real last row of the paragraph. Moreover this solves the following bug (present in 2.1.x too): when the document ends with a newling, the bottom margin disappears. Update PAINTING_ANALYSIS with new tasks. diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index 74aaa99..acb033d 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -100,7 +100,25 @@ version. ==> more versions, no optional parameters. -** make Inset::display() more useful +** DONE When a document ends with a newline, add the bottom margin anyway + +The code that tests for a newline was added at 6bb98d07 in 2007. + +** When a paragraph ends with a newline, compute correctly the height of the extra row. +** Rewrite TextMetrics::completionPosAndDim using row information + +Currently it uses setRowHeight in a very weird way. In particular the +topBottomSpace parameter should be removed after that. + +** Rewrite TextMetrics::editXY, checkInsetHit using row information (getPosNearX)? + + The helper version should return a Row::Element instead of an InsetTable. + +** TODO make Inset::display() more useful + +[This has been started in the features/betterbreak branch. Time will +tell whether it really helps. The question in particular is the +handling of separator insets] Extending the DisplayType enum would allow to remove special cases from the code. diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 2aad0cc..a1f3892 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -471,6 +471,21 @@ bool TextMetrics::redoParagraph(pit_type const pit) pm.dim().des += row.height(); } while (first < par.size() || need_new_row); + // FIXME: It might be better to move this in another method + // specially tailored for the main text. + // Top and bottom margin of the document (only at top-level) + if (text_->isMainText()) { + if (pit == 0) { + pm.rows().front().dimension().asc += 20; + pm.dim().des += 20; + } + ParagraphList const & pars = text_->paragraphs(); + if (pit + 1 == pit_type(pars.size())) { + pm.rows().back().dimension().des += 20; + pm.dim().des += 20; + } + } + if (row_index < pm.rows().size()) pm.rows().resize(row_index); @@ -1044,19 +1059,6 @@ void TextMetrics::setRowHeight(Row & row, pit_type const pit, maxasc += int(layoutasc * 2 / (2 + pars[pit].getDepth())); maxdes += int(layoutdesc * 2 / (2 + pars[pit].getDepth())); - // FIXME: the correct way is to do the following is to move the - // following code in another method specially tailored for the - // main Text. The following test is thus bogus. - // Top and bottom margin of the document (only at top-level) - if (text_->isMainText() && topBottomSpace) { - if (pit == 0 && row.pos() == 0) - maxasc += 20; - if (pit + 1 == pit_type(pars.size()) && - row.endpos() == par.size() && - !(row.endpos() > 0 && par.isNewline(row.endpos() - 1))) - maxdes += 20; - } - row.dimension().asc = maxasc + labeladdon; row.dimension().des = maxdes; }
[LyX/master] Update PAINTING_ANALYSIS
commit 78eaf8333bacec8d735eae06c0745163d06a5122 Author: Jean-Marc LasgouttesDate: Sat Mar 5 00:09:34 2016 +0100 Update PAINTING_ANALYSIS Some things were wrong, and some new ideas are added (some are done in this branch already). diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index d1da54b..4934c5e 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -60,13 +60,75 @@ cursor. * Proposals -** set inset position during metrics phase +* Clean-up of drawing code -This implies to set inset positions relative to outer inset during -metrics phase and then in a second loop to descend into insets and -update positions correctly. +The goal is to make painting with drawing disable fast enough that it +can be used after every metrics computation. Then we can separate real +drawing from metrics. -Effect: avoid going through the painter machinery when it is not necessary. +** DONE RowPainter + +Inset position is set in paintInset, paintOnlyInsets, and paintText. +This should be done only once in paintInset + +** DONE TextMetrics::drawParagraph + +We can really simplify the code when drawing is disabled only +paintInset needs to be called. + + do right at the start when drawing is already disabled + + do it in the loop for rows that are not visible on screen. + +The only thing we want to do here is to set inset positions (for +text). The other insets still use the painter with drawing disabled. + +** Painter::text + +We cannot remove (or make private) the version that uses a +FontInfo because it is used by PainterInfo::draw. Document this and +remove unused arguments rtl and double spacing. This would become a specialized helper. +Proposed solution: keep the existing function, but private and without +optional arguments. + +Avoid to return (and thus compute) the width of strings? + + used by InsetSpecialChar (fixable) + + used by textDecoration() in text(): more difficult to fix + +Idea: add a version of text where wordspacing and textwidth (giving +the width of strings) are required parameters and remove optional +version. + +==> more versions, no optional parameters. + +** Set inset position during metrics phase + +In order to do that, a no-paint drawing will be initiated after every +redoParagraph. This code path will need to be made as fast as possible. + +Effect: avoid depending on actual drawing having taken place. In turn, +it will allow to do drawing on paint events, like any reasonable +application would do. + +** Cleanup after complete metrics + Then the following can be done: + + remove hack in InsetMathNest::drawSelection + + remove painting when not inside in drawParagraph + + remove Cursor::inCoordCache? + +** Use Row for MathData + +It may not be so difficult. Implement x2pos and pos2x from +the TM:cursorX and TM::getPosNearX, and use them for both text and +math. + +Will the strings display OK if drawing string-wise? + +Then it would be possible to streamline drawing with disabled painter. + +** Paint directly to screen + +Instead of using an intermediary pixmap. I have no idea of how +difficult it will prove. +One benefit will be that subpixel aliasing will work again (#9972) ** Merging bv::updateMetrics and tm::metrics @@ -75,16 +137,10 @@ paragraphs that are rebroken, the version that is used for inner inset does not try any such optimization. This can be very bad for very tall insets. We should re-use the bv::updateMetrics logic: + transfer all the logic of bv::updateMetrics to tm. - + Main InsetText should not be special. - -** Metrics outside of visible area - -Currently metrics are computed for current visible paet of text, the -page above and the page below. It should be possible to compute hidden -rows ony on demand, although it might be a bit slow. + + Main InsetText should not be special. -There was a proposal to always compute _all_ rows, but this may become -expensive for large files. This would though help scrolling. +The difficuly for a tall table cell for example, is that it may be +necessary to break the whole contents to know the width of the cell. * Description of current drawing mechanism
[LyX/master] Update PAINTING_ANALYSIS
commit 47c0b3cc052ece15dea5289b683bc57bb9cfc01a Author: Jean-Marc LasgouttesDate: Mon May 30 14:54:20 2016 +0200 Update PAINTING_ANALYSIS Remove all the tasks that have been performed. diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index e1b0b64..3ddfc74 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -66,62 +66,11 @@ drawing from metrics. Other changes are only clean-ups. -** DONE RowPainter - -Inset position is set in paintInset, paintOnlyInsets, and paintText. -This should be done only once in paintInset - -** DONE TextMetrics::drawParagraph - -We can really simplify the code when drawing is disabled only -paintInset needs to be called. - + do right at the start when drawing is already disabled - + do it in the loop for rows that are not visible on screen. - -The only thing we want to do here is to set inset positions (for -text). The other insets still use the painter with drawing disabled. - -** DONE Painter::text - -We cannot remove (or make private) the version that uses a -FontInfo because it is used by PainterInfo::draw. Document this and -remove unused arguments rtl and double spacing. This would become a specialized helper. -Proposed solution: keep the existing function, but private and without -optional arguments. - -Avoid to return (and thus compute) the width of strings? - + used by InsetSpecialChar (fixable) - + used by textDecoration() in text(): more difficult to fix - -Idea: add a version of text where wordspacing and textwidth (giving -the width of strings) are required parameters and remove optional -version. - -==> more versions, no optional parameters. - -** DONE When a document ends with a newline, add the bottom margin anyway - -The code that tests for a newline was added at 6bb98d07 in 2007. - ** When a paragraph ends with a newline, compute correctly the height of the extra row. ** Rewrite TextMetrics::editXY, checkInsetHit using row information (getPosNearX)? The helper version should return a Row::Element instead of an InsetTable. -** DONE Do not make RowPainter operations update x_ - -It is better to make them const and update x_ separately. - -** DONE remove pit argument to breakRow - -There are probably other places where the pit is not needed anymore: -computeRowMetrics, labelFill, setRowHeight, isLastRow, isFirstRow - -** DONE Split setRowHeight to separate the computation of space above/below paragraph - -This allows to remove the topBottomSpace parameter. The spacing is -computed in redoParagraph, where it feels more natural. - ** Remember rtl status in the row object This will avoid to pass a Paragraph object to methods that do not need it.
[LyX/master] Split TextMetrics::setRowHeight in three parts
commit 03117182154941a7d6fe73c3f86fc52553fafecd Author: Jean-Marc LasgouttesDate: Fri May 20 17:14:54 2016 +0200 Split TextMetrics::setRowHeight in three parts The new functions parBottomSpaging and parTopSapcing return below/above each paragraph. This allows to remove the TopBottomSpace argument and makes the code a bit clearer. diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index e4efe84..e1b0b64 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -104,11 +104,6 @@ version. The code that tests for a newline was added at 6bb98d07 in 2007. ** When a paragraph ends with a newline, compute correctly the height of the extra row. -** Rewrite TextMetrics::completionPosAndDim using row information - -Currently it uses setRowHeight in a very weird way. In particular the -topBottomSpace parameter should be removed after that. - ** Rewrite TextMetrics::editXY, checkInsetHit using row information (getPosNearX)? The helper version should return a Row::Element instead of an InsetTable. @@ -117,17 +112,16 @@ topBottomSpace parameter should be removed after that. It is better to make them const and update x_ separately. -** reorder the painting of the different elements. - -In particular, if text is painted last, it will be more visible in the -presence of underlines (foreign language, change tracking, spell -check). - ** DONE remove pit argument to breakRow There are probably other places where the pit is not needed anymore: computeRowMetrics, labelFill, setRowHeight, isLastRow, isFirstRow +** DONE Split setRowHeight to separate the computation of space above/below paragraph + +This allows to remove the topBottomSpace parameter. The spacing is +computed in redoParagraph, where it feels more natural. + ** Remember rtl status in the row object This will avoid to pass a Paragraph object to methods that do not need it. diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index c10348d..6345899 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -472,6 +472,9 @@ bool TextMetrics::redoParagraph(pit_type const pit) pm.dim().des += row.height(); } while (first < par.size() || need_new_row); + if (row_index < pm.rows().size()) + pm.rows().resize(row_index); + // FIXME: It might be better to move this in another method // specially tailored for the main text. // Top and bottom margin of the document (only at top-level) @@ -487,8 +490,12 @@ bool TextMetrics::redoParagraph(pit_type const pit) } } - if (row_index < pm.rows().size()) - pm.rows().resize(row_index); + // The space above and below the paragraph. + int const top = parTopSpacing(pit); + pm.rows().front().dimension().asc += top; + int const bottom = parBottomSpacing(pit); + pm.rows().back().dimension().des += bottom; + pm.dim().des += top + bottom; pm.dim().asc += pm.rows()[0].ascent(); pm.dim().des -= pm.rows()[0].ascent(); @@ -930,13 +937,109 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const return need_new_row; } +int TextMetrics::parTopSpacing(pit_type const pit) const +{ + Paragraph const & par = text_->getPar(pit); + Layout const & layout = par.layout(); + + int asc = 0; + ParagraphList const & pars = text_->paragraphs(); + double const dh = defaultRowHeight(); + + BufferParams const & bparams = bv_->buffer().params(); + Inset const & inset = text_->inset(); + // some parskips VERY EASY IMPLEMENTATION + if (bparams.paragraph_separation == BufferParams::ParagraphSkipSeparation + && !inset.getLayout().parbreakIsNewline() + && !par.layout().parbreak_is_newline + && pit > 0 + && ((layout.isParagraph() && par.getDepth() == 0) + || (pars[pit - 1].layout().isParagraph() + && pars[pit - 1].getDepth() == 0))) { + asc += bparams.getDefSkip().inPixels(*bv_); + } + + if (par.params().startOfAppendix()) + asc += int(3 * dh); + + // special code for the top label + if (layout.labelIsAbove() + && (!layout.isParagraphGroup() || text_->isFirstInSequence(pit)) + && !par.labelString().empty()) { + FontInfo labelfont = text_->labelFont(par); + FontMetrics const & lfm = theFontMetrics(labelfont); + asc += int(lfm.maxHeight() * layout.spacing.getValue() + * text_->spacing(par) + + (layout.topsep + layout.labelbottomsep) * dh); + } + + // Add the layout spaces, for example before and after + // a section, or between the items of a itemize or enumerate + // environment. + + pit_type
[LyX/master] Do not use the return value of Painter::text for logos
commit 51b1cfab721ea6d7c9f43853de987ad6f0157ea8 Author: Jean-Marc LasgouttesDate: Sat Mar 19 17:26:25 2016 +0100 Do not use the return value of Painter::text for logos This will allow to get rid of this return value (and avoid computing it). diff --git a/src/insets/InsetSpecialChar.cpp b/src/insets/InsetSpecialChar.cpp index 8fa6ead..8671d2b 100644 --- a/src/insets/InsetSpecialChar.cpp +++ b/src/insets/InsetSpecialChar.cpp @@ -135,7 +135,16 @@ void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const namespace { -void drawLogo(PainterInfo & pi, InsetSpecialChar::Kind kind, int & x, int & y) { +// helper function: draw text and update x. +void drawChar(PainterInfo & pi, int & x, int const y, char_type ch) +{ + pi.pain.text(x, y, ch, pi.base.font); + x += theFontMetrics(pi.base.font).width(ch); +} + + +void drawLogo(PainterInfo & pi, int & x, int const y, InsetSpecialChar::Kind kind) +{ FontInfo const & font = pi.base.font; int const em = theFontMetrics(font).em(); switch (kind) { @@ -143,11 +152,11 @@ void drawLogo(PainterInfo & pi, InsetSpecialChar::Kind kind, int & x, int & y) { /** Reference macro: * \providecommand{\LyX}{L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\\@}; */ - x += pi.pain.text(x, y, from_ascii("L"), font); + drawChar(pi, x, y, 'L'); x -= em / 6; - x += pi.pain.text(x, y + em / 4, from_ascii("Y"), font); + drawChar(pi, x, y + em / 4, 'Y'); x -= em / 8; - x += pi.pain.text(x, y, from_ascii("X"), font); + drawChar(pi, x, y, 'X'); break; case InsetSpecialChar::PHRASE_TEX: { @@ -155,11 +164,11 @@ void drawLogo(PainterInfo & pi, InsetSpecialChar::Kind kind, int & x, int & y) { * \def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@} */ int const ex = theFontMetrics(font).ascent('x'); - x += pi.pain.text(x, y, from_ascii("T"), font); + drawChar(pi, x, y, 'T'); x -= em / 6; - x += pi.pain.text(x, y + ex / 2, from_ascii("E"), font); + drawChar(pi, x, y + ex / 2, 'E'); x -= em / 8; - x += pi.pain.text(x, y, from_ascii("X"), font); + drawChar(pi, x, y, 'X'); break; } case InsetSpecialChar::PHRASE_LATEX2E: @@ -168,10 +177,10 @@ void drawLogo(PainterInfo & pi, InsetSpecialChar::Kind kind, int & x, int & y) { *\if b\expandafter\@car\f@series\@nil\boldmath\fi *\LaTeX\kern.15em2$_{\textstyle\varepsilon}$}} */ - drawLogo(pi, InsetSpecialChar::PHRASE_LATEX, x, y); + drawLogo(pi, x, y, InsetSpecialChar::PHRASE_LATEX); x += 3 * em / 20; - x += pi.pain.text(x, y, from_ascii("2"), font); - x += pi.pain.text(x, y + em / 4, char_type(0x03b5), font); + drawChar(pi, x, y, '2'); + drawChar(pi, x, y + em / 4, char_type(0x03b5)); break; case InsetSpecialChar::PHRASE_LATEX: { @@ -187,13 +196,13 @@ void drawLogo(PainterInfo & pi, InsetSpecialChar::Kind kind, int & x, int & y) { *\kern-.15em% *\TeX} */ - x += pi.pain.text(x, y, from_ascii("L"), font); + drawChar(pi, x, y, 'L'); x -= 9 * em / 25; - FontInfo smaller = font; - smaller.decSize().decSize(); - x += pi.pain.text(x, y - em / 5, from_ascii("A"), smaller); + PainterInfo pi2 = pi; + pi2.base.font.decSize().decSize(); + drawChar(pi2, x, y - em / 5, 'A'); x -= 3 * em / 20; - drawLogo(pi, InsetSpecialChar::PHRASE_TEX, x, y); + drawLogo(pi, x, y, InsetSpecialChar::PHRASE_TEX); break; } default: @@ -269,7 +278,7 @@ void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const case PHRASE_TEX: case PHRASE_LATEX2E: case PHRASE_LATEX: - drawLogo(pi, kind_, x, y); + drawLogo(pi, x, y, kind_); break; } }
[LyX/master] Simplify redoParagraph by merging duplicate code
commit 17516267769abde8c02ae44bd838e3fce373d9a4 Author: Jean-Marc LasgouttesDate: Sat Mar 5 23:11:45 2016 +0100 Simplify redoParagraph by merging duplicate code Let breakRow return a boolean indicating whether an additional row is required (after a newline) and use that to replace the code that added an extra row when a paragraph ends with a newline. diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 69ab7b5..2ce990b 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -437,6 +437,7 @@ bool TextMetrics::redoParagraph(pit_type const pit) par.setBeginOfBody(); pos_type first = 0; size_t row_index = 0; + bool need_new_row = false; // maximum pixel width of a row do { if (row_index == pm.rows().size()) @@ -444,7 +445,7 @@ bool TextMetrics::redoParagraph(pit_type const pit) Row & row = pm.rows()[row_index]; row.pit(pit); row.pos(first); - breakRow(row, right_margin, pit); + need_new_row = breakRow(row, right_margin, pit); setRowHeight(row, pit); row.setChanged(false); if (row_index || row.endpos() < par.size() @@ -468,26 +469,11 @@ bool TextMetrics::redoParagraph(pit_type const pit) pm.dim().wid = max(pm.dim().wid, row.width()); pm.dim().des += row.height(); - } while (first < par.size()); + } while (first < par.size() || need_new_row); if (row_index < pm.rows().size()) pm.rows().resize(row_index); - // Make sure that if a par ends in newline, there is one more row - // under it - if (first > 0 && par.isNewline(first - 1)) { - if (row_index == pm.rows().size()) - pm.rows().push_back(Row()); - Row & row = pm.rows()[row_index]; - row.pos(first); - breakRow(row, right_margin, pit); - setRowHeight(row, pit); - row.setChanged(false); - int const max_row_width = max(dim_.wid, row.width()); - computeRowMetrics(pit, row, max_row_width); - pm.dim().des += row.height(); - } - pm.dim().asc += pm.rows()[0].ascent(); pm.dim().des -= pm.rows()[0].ascent(); @@ -786,7 +772,7 @@ private: * very sensitive to small changes :) Note that part of the * intelligence is also in Row::shortenIfNeeded. */ -void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit) const +bool TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit) const { Paragraph const & par = text_->getPar(pit); pos_type const end = par.size(); @@ -806,7 +792,10 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit // the width available for the row. int const width = max_width_ - row.right_margin; - ParagraphList const & pars = text_->paragraphs(); + if (pos >= end || row.width() > width) { + row.endpos(end); + return need_new_row; + } #if 0 //FIXME: As long as leftMargin() is not correctly implemented for @@ -900,6 +889,7 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit row.endpos(i); // End of paragraph marker + ParagraphList const & pars = text_->paragraphs(); if (lyxrc.paragraph_markers && !need_new_row && i == end && size_type(pit + 1) < pars.size()) { // add a virtual element for the end-of-paragraph @@ -921,6 +911,8 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit // make sure that the RTL elements are in reverse ordering row.reverseRTL(is_rtl); //LYXERR0("breakrow: row is " << row); + + return need_new_row; } diff --git a/src/TextMetrics.h b/src/TextMetrics.h index eef00ff..8d2a12c 100644 --- a/src/TextMetrics.h +++ b/src/TextMetrics.h @@ -131,7 +131,8 @@ private: /// sets row.end to the pos value *after* which a row should break. /// for example, the pos after which isNewLine(pos) == true - void breakRow(Row & row, int right_margin, pit_type const pit) const; + /// \return true when another row is required (after a newline) + bool breakRow(Row & row, int right_margin, pit_type const pit) const; // Expand the alignment of row \param row in paragraph \param par LyXAlignment getAlign(Paragraph const & par, Row const & row) const;
[LyX/master] Make the non-drawing cases faster in TextMetrics::drawParagraph
commit fc73ebc16c4f0aca76360415a94eca57f283e44e Author: Jean-Marc LasgouttesDate: Mon Feb 29 16:07:35 2016 +0100 Make the non-drawing cases faster in TextMetrics::drawParagraph There are two main cases: * when drawing is disabled from the start, use a simplified code that only paints insets (in order to cache positions). * when the row is not visible, do the same. The goal of this optimization is to be able to always run a no-drawing draw after the metrics have been computed. diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 80ee0aa..69ab7b5 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -1864,15 +1864,31 @@ void TextMetrics::draw(PainterInfo & pi, int x, int y) const void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const x, int y) const { - BufferParams const & bparams = bv_->buffer().params(); ParagraphMetrics const & pm = par_metrics_[pit]; if (pm.rows().empty()) return; - - bool const original_drawing_state = pi.pain.isDrawingEnabled(); - int const ww = bv_->workHeight(); size_t const nrows = pm.rows().size(); + // Use fast lane when drawing is disabled. + if (!pi.pain.isDrawingEnabled()) { + for (size_t i = 0; i != nrows; ++i) { + + Row const & row = pm.rows()[i]; + // Adapt to cursor row scroll offset if applicable. + int row_x = x - bv_->horizScrollOffset(text_, pit, row.pos()); + if (i) + y += row.ascent(); + + RowPainter rp(pi, *text_, pit, row, row_x, y); + + rp.paintOnlyInsets(); + y += row.descent(); + } + return; + } + + BufferParams const & bparams = bv_->buffer().params(); + int const ww = bv_->workHeight(); Cursor const & cur = bv_->cursor(); DocIterator sel_beg = cur.selectionBegin(); DocIterator sel_end = cur.selectionEnd(); @@ -1909,10 +1925,18 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const RowPainter rp(pi, *text_, pit, row, row_x, y); + // It is not needed to draw on screen if we are not inside. bool const inside = (y + row.descent() >= 0 && y - row.ascent() < ww); - // It is not needed to draw on screen if we are not inside. - pi.pain.setDrawingEnabled(inside && original_drawing_state); + pi.pain.setDrawingEnabled(inside); + if (!inside) { + // Paint only the insets to set inset cache correctly + // FIXME: remove paintOnlyInsets when we know that positions + // have already been set. + rp.paintOnlyInsets(); + y += row.descent(); + continue; + } if (selection) row.setSelectionAndMargins(sel_beg_par, sel_end_par); @@ -1929,8 +1953,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const } // Row signature; has row changed since last paint? - if (pi.pain.isDrawingEnabled()) - row.setCrc(pm.computeRowSignature(row, bparams)); + row.setCrc(pm.computeRowSignature(row, bparams)); bool row_has_changed = row.changed() || bv_->hadHorizScrollOffset(text_, pit, row.pos()); @@ -1961,7 +1984,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const // Instrumentation for testing row cache (see also // 12 lines lower): - if (lyxerr.debugging(Debug::PAINTING) && inside + if (lyxerr.debugging(Debug::PAINTING) && (row.selection() || pi.full_repaint || row_has_changed)) { string const foreword = text_->isMainText() ? "main text redraw " : "inset text redraw: "; @@ -1999,7 +2022,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const pi.full_repaint = tmp; } // Re-enable screen drawing for future use of the painter. - pi.pain.setDrawingEnabled(original_drawing_state); + pi.pain.setDrawingEnabled(true); //LYXERR(Debug::PAINTING, "."); }
[LyX/master] Do not require an extra pit parameter when a row is available
commit e39e4cf96b23997c065a890c015138eb93a1d4fd Author: Jean-Marc LasgouttesDate: Wed May 18 09:39:47 2016 +0200 Do not require an extra pit parameter when a row is available Now that Row has a pit() member, it is possible to use it instead of passing an extra pit_type parameter to a function which already has access to a Row. diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index beb0fad..e4efe84 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -123,6 +123,11 @@ In particular, if text is painted last, it will be more visible in the presence of underlines (foreign language, change tracking, spell check). +** DONE remove pit argument to breakRow + +There are probably other places where the pit is not needed anymore: +computeRowMetrics, labelFill, setRowHeight, isLastRow, isFirstRow + ** Remember rtl status in the row object This will avoid to pass a Paragraph object to methods that do not need it. diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 9708a08..2739e00 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -2999,8 +2999,7 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi) bool const drawing = pi.pain.isDrawingEnabled(); pi.pain.setDrawingEnabled(false); // No need to care about vertical position. - RowPainter rp(pi, buffer().text(), d->cursor_.bottom().pit(), row, - -d->horiz_scroll_offset_, 0); + RowPainter rp(pi, buffer().text(), row, -d->horiz_scroll_offset_, 0); rp.paintText(); pi.pain.setDrawingEnabled(drawing); } diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp index 1c2b65d..a2ff309 100644 --- a/src/RowPainter.cpp +++ b/src/RowPainter.cpp @@ -54,12 +54,12 @@ using frontend::FontMetrics; RowPainter::RowPainter(PainterInfo & pi, - Text const & text, pit_type pit, Row const & row, int x, int y) + Text const & text, Row const & row, int x, int y) : pi_(pi), text_(text), text_metrics_(pi_.base.bv->textMetrics()), pars_(text.paragraphs()), - row_(row), pit_(pit), par_(text.paragraphs()[pit]), - pm_(text_metrics_.parMetrics(pit)), change_(pi_.change_), + row_(row), par_(text.paragraphs()[row.pit()]), + pm_(text_metrics_.parMetrics(row.pit())), change_(pi_.change_), xo_(x), yo_(y), width_(text_metrics_.width()), solid_line_thickness_(1), solid_line_offset_(1), dotted_line_thickness_(1) @@ -84,8 +84,8 @@ RowPainter::RowPainter(PainterInfo & pi, //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl; //row_.dump(); - LBUFERR(pit >= 0); - LBUFERR(pit < int(text.paragraphs().size())); + LBUFERR(row.pit() >= 0); + LBUFERR(row.pit() < int(text.paragraphs().size())); } @@ -280,7 +280,7 @@ void RowPainter::paintChangeBar() const if (start == end || !par_.isChanged(start, end)) return; - int const height = text_metrics_.isLastRow(pit_, row_) + int const height = text_metrics_.isLastRow(row_) ? row_.ascent() : row_.height(); @@ -312,16 +312,16 @@ void RowPainter::paintDepthBar() const return; depth_type prev_depth = 0; - if (!text_metrics_.isFirstRow(pit_, row_)) { - pit_type pit2 = pit_; + if (!text_metrics_.isFirstRow(row_)) { + pit_type pit2 = row_.pit(); if (row_.pos() == 0) --pit2; prev_depth = pars_[pit2].getDepth(); } depth_type next_depth = 0; - if (!text_metrics_.isLastRow(pit_, row_)) { - pit_type pit2 = pit_; + if (!text_metrics_.isLastRow(row_)) { + pit_type pit2 = row_.pit(); if (row_.endpos() >= pars_[pit2].size()) ++pit2; next_depth = pars_[pit2].getDepth(); @@ -396,7 +396,7 @@ void RowPainter::paintFirst() const paintAppendixStart(yo_ - row_.ascent() + 2 * defaultRowHeight()); bool const is_first = - text_.isFirstInSequence(pit_) || !layout.isParagraphGroup(); + text_.isFirstInSequence(row_.pit()) || !layout.isParagraphGroup(); //lyxerr << "paintFirst: " << par_.id() << " is_seq: " << is_seq << endl; if (layout.labelIsInline() @@ -500,7 +500,7 @@ static int getEndLabel(pit_type p, Text const & text) void RowPainter::paintLast() const { bool const is_rtl = text_.isRTL(par_); - int const endlabel = getEndLabel(pit_, text_); + int const endlabel = getEndLabel(row_.pit(), text_); // paint imaginary end-of-paragraph character @@ -626,11 +626,11 @@ void RowPainter::paintSelection() const return; Cursor const &
[LyX/master] RowPainter const cleanup
commit 4c19c5149df496ea327582f0934506d7e3dc6ef9 Author: Jean-Marc LasgouttesDate: Tue May 17 15:00:09 2016 +0200 RowPainter const cleanup Change the various paint* helpers to take a single row element as argument. Do not update x_ in the various paint* helpers. Constify them. Update x_ in paintText and paintOnlyInsets instead. Remove an empty call to paintForeignMark in paintInset (the call did nothing since orig_x == x_ at this point). diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index 78719f5..beb0fad 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -113,14 +113,24 @@ topBottomSpace parameter should be removed after that. The helper version should return a Row::Element instead of an InsetTable. -** Do not make RowPainter operations update x_ +** DONE Do not make RowPainter operations update x_ It is better to make them const and update x_ separately. -Then it will be possible to reorder the painting of the different -elements. In particular, if text is painted last, it will be more -visible in the presence of underlines (foreign language, change -tracking, spell check). +** reorder the painting of the different elements. + +In particular, if text is painted last, it will be more visible in the +presence of underlines (foreign language, change tracking, spell +check). + +** Remember rtl status in the row object + +This will avoid to pass a Paragraph object to methods that do not need it. + +** Rewrite RowPainter::paintSelection using row information + +Currently it uses some very complicated code. It should be possible to +reuse the logic of paintStringAndSel. ** Set inset position during metrics phase diff --git a/src/Row.h b/src/Row.h index 0bd4597..f69eeca 100644 --- a/src/Row.h +++ b/src/Row.h @@ -62,6 +62,7 @@ public: extra(0), font(f), change(ch), final(false) {} // Return total width of element, including separator overhead + // FIXME: Cache this value or the number of separators? double full_width() const { return dim.wid + extra * countSeparators(); } // Return the number of separator in the element (only STRING type) int countSeparators() const; diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp index e6c6353..1c2b65d 100644 --- a/src/RowPainter.cpp +++ b/src/RowPainter.cpp @@ -104,7 +104,7 @@ FontInfo RowPainter::labelFont() const // This draws green lines around each inset. -void RowPainter::paintInset(Row::Element const & e) +void RowPainter::paintInset(Row::Element const & e) const { // Handle selection bool const pi_selected = pi_.selected; @@ -135,12 +135,6 @@ void RowPainter::paintInset(Row::Element const & e) e.inset->drawSelection(pi_, x1, yo_); e.inset->draw(pi_, x1, yo_); - Dimension const & dim = pi_.base.bv->coordCache().insets().dim(e.inset); - - paintForeignMark(x_, e.font.language(), dim.descent()); - - x_ += dim.width(); - // Restore full_repaint status. pi_.full_repaint = pi_full_repaint; pi_.change_ = pi_change; @@ -148,6 +142,7 @@ void RowPainter::paintInset(Row::Element const & e) pi_.selected = pi_selected; #ifdef DEBUG_METRICS + Dimension const & dim = pi_.base.bv->coordCache().insets().dim(e.inset); int const x2 = x1 + dim.wid; int const y1 = yo_ + dim.des; int const y2 = yo_ - dim.asc; @@ -159,8 +154,9 @@ void RowPainter::paintInset(Row::Element const & e) } -void RowPainter::paintForeignMark(double orig_x, Language const * lang, int desc) const +void RowPainter::paintForeignMark(Row::Element const & e) const { + Language const * lang = e.font.language(); if (!lyxrc.mark_foreign_language) return; if (lang == latex_language) @@ -168,14 +164,14 @@ void RowPainter::paintForeignMark(double orig_x, Language const * lang, int desc if (lang == pi_.base.bv->buffer().params().language) return; + int const desc = e.inset ? e.dim.descent() : 0; int const y = yo_ + solid_line_offset_ + desc + solid_line_thickness_ / 2; - pi_.pain.line(int(orig_x), y, int(x_), y, Color_language, + pi_.pain.line(int(x_), y, int(x_ + e.full_width()), y, Color_language, Painter::line_solid, solid_line_thickness_); } -void RowPainter::paintMisspelledMark(double const orig_x, - Row::Element const & e) const +void RowPainter::paintMisspelledMark(Row::Element const & e) const { // if changed the misspelled marker gets placed slightly lower than normal // to avoid drawing at the same vertical offset @@ -224,15 +220,14 @@ void RowPainter::paintMisspelledMark(double const orig_x, if (x1 > x2) swap(x1, x2); -
[LyX/master] Make the different Painter::text void methods
commit 333f6fcf07b35f240bcc1190dd21b0dc068a9129 Author: Jean-Marc LasgouttesDate: Sat Mar 19 17:52:07 2016 +0100 Make the different Painter::text void methods The textwidth value that was returned is not used anymore. Now in some cases we can avoid to compute it at all. diff --git a/src/frontends/Painter.h b/src/frontends/Painter.h index c72d813..2106768 100644 --- a/src/frontends/Painter.h +++ b/src/frontends/Painter.h @@ -133,28 +133,29 @@ public: virtual void image(int x, int y, int w, int h, graphics::Image const & image) = 0; + /** draw a character at position x, y (y is the baseline) +*/ + virtual void text(int x, int y, char_type c, FontInfo const & f) = 0; + /** draw a string at position x, y (y is the baseline). The * text direction is given by \c rtl. -* \return the width of the drawn text. */ - virtual int text(int x, int y, docstring const & str, FontInfo const & f, - bool rtl = false, double wordspacing = 0.0) = 0; + virtual void text(int x, int y, docstring const & str, FontInfo const & f, + bool rtl = false, double wordspacing = 0.0) = 0; /** draw a string at position x, y (y is the baseline). The * text direction is enforced by the \c Font. -* \return the width of the drawn text. */ - virtual int text(int x, int y, docstring const & str, Font const & f, - double wordspacing = 0.0) = 0; + virtual void text(int x, int y, docstring const & str, Font const & f, + double wordspacing = 0.0) = 0; /** draw a string at position x, y (y is the baseline), but * make sure that the part between \c from and \c to is in * \c other color. The text direction is enforced by the \c Font. -* \return the width of the drawn text. */ - virtual int text(int x, int y, docstring const & str, Font const & f, - Color other, size_type from, size_type to, - double const wordspacing) = 0; + virtual void text(int x, int y, docstring const & str, Font const & f, + Color other, size_type from, size_type to, + double const wordspacing) = 0; void setDrawingEnabled(bool drawing_enabled) { drawing_enabled_ = drawing_enabled; } @@ -164,12 +165,6 @@ public: double pixelRatio() const { return pixel_ratio_; } - /// draw a char at position x, y (y is the baseline) - /** - * \return the width of the drawn text. - */ - virtual int text(int x, int y, char_type c, FontInfo const & f) = 0; - /// draw the underbar, strikeout, uuline and uwave font attributes virtual void textDecoration(FontInfo const & f, int x, int y, int width) = 0; diff --git a/src/frontends/qt4/GuiPainter.cpp b/src/frontends/qt4/GuiPainter.cpp index 5329624..12d4f72 100644 --- a/src/frontends/qt4/GuiPainter.cpp +++ b/src/frontends/qt4/GuiPainter.cpp @@ -327,9 +327,9 @@ void GuiPainter::image(int x, int y, int w, int h, graphics::Image const & i) } -int GuiPainter::text(int x, int y, char_type c, FontInfo const & f) +void GuiPainter::text(int x, int y, char_type c, FontInfo const & f) { - return text(x, y, docstring(1, c), f); + text(x, y, docstring(1, c), f); } @@ -368,13 +368,13 @@ void GuiPainter::do_drawText(int x, int y, QString str, bool rtl, FontInfo const } -int GuiPainter::text(int x, int y, docstring const & s, - FontInfo const & f, bool const rtl, - double const wordspacing) +void GuiPainter::text(int x, int y, docstring const & s, + FontInfo const & f, bool const rtl, + double const wordspacing) { //LYXERR0("text: x=" << x << ", s=" << s); - if (s.empty()) - return 0; + if (s.empty() || !isDrawingEnabled()) + return; /* Caution: The following ucs4 to QString conversions work for symbol fonts only because they are no real conversions but simple casts in reality. @@ -406,9 +406,6 @@ int GuiPainter::text(int x, int y, docstring const & s, // Note that we have to take in account space stretching (word spacing) int const textwidth = fm.width(s) + count(s.begin(), s.end(), ' ') * wordspacing; - if (!isDrawingEnabled()) - return textwidth; - textDecoration(f, x, y, textwidth); if (use_pixmap_cache_) { @@ -428,7 +425,7 @@ int GuiPainter::text(int x, int y, docstring const & s, if (QPixmapCache::find(key, pm)) { // Draw the cached pixmap. drawPixmap(x + lb, y - mA, pm); - return textwidth; + return; } // Only
[LyX/master] Rewrite setRowHeight using row information
commit ac759b4368e2a3477c8ef81ebf749a68280ef3d8 Author: Jean-Marc LasgouttesDate: Sun Mar 6 16:22:53 2016 +0100 Rewrite setRowHeight using row information The initial values for maxasc and maxdes (renamed from maxdesc) is obtained as a maximum of max ascents/descents of all row elements. This allows to get rid of Paragraph::highestFontInRange and FontList::highestInRange. Some auxilliary variables declarations are also moved to where they are needed. diff --git a/src/FontList.cpp b/src/FontList.cpp index e5a86db..1bfab76 100644 --- a/src/FontList.cpp +++ b/src/FontList.cpp @@ -180,31 +180,6 @@ void FontList::set(pos_type pos, Font const & font) } -FontSize FontList::highestInRange(pos_type startpos, pos_type endpos, - FontSize def_size) const -{ - if (list_.empty()) - return def_size; - - List::const_iterator end_it = fontIterator(endpos); - const_iterator const end = list_.end(); - if (end_it != end) - ++end_it; - - List::const_iterator cit = fontIterator(startpos); - - FontSize maxsize = FONT_SIZE_TINY; - for (; cit != end_it; ++cit) { - FontSize size = cit->font().fontInfo().size(); - if (size == FONT_SIZE_INHERIT) - size = def_size; - if (size > maxsize && size <= FONT_SIZE_HUGER) - maxsize = size; - } - return maxsize; -} - - void FontList::validate(LaTeXFeatures & features) const { const_iterator fcit = list_.begin(); diff --git a/src/FontList.h b/src/FontList.h index 9dfd527..6400f97 100644 --- a/src/FontList.h +++ b/src/FontList.h @@ -105,13 +105,6 @@ public: /// void decreasePosAfterPos(pos_type pos); - /// Returns the height of the highest font in range - FontSize highestInRange( - pos_type startpos, - pos_type endpos, - FontSize def_size - ) const; - /// void validate(LaTeXFeatures & features) const; diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index d6106b3..0fd673e 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -1837,14 +1837,6 @@ Font const Paragraph::getLayoutFont } -/// Returns the height of the highest font in range -FontSize Paragraph::highestFontInRange - (pos_type startpos, pos_type endpos, FontSize def_size) const -{ - return d->fontlist_.highestInRange(startpos, endpos, def_size); -} - - char_type Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const { char_type c = d->text_[pos]; diff --git a/src/Paragraph.h b/src/Paragraph.h index 50516d7..b4b8067 100644 --- a/src/Paragraph.h +++ b/src/Paragraph.h @@ -357,9 +357,6 @@ public: char_type getUChar(BufferParams const &, pos_type pos) const; /// pos <= size() (there is a dummy font change at the end of each par) void setFont(pos_type pos, Font const & font); - /// Returns the height of the highest font in range - FontSize highestFontInRange(pos_type startpos, - pos_type endpos, FontSize def_size) const; /// void insert(pos_type pos, docstring const & str, Font const & font, Change const & change); diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 2ce990b..2aad0cc 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -920,85 +920,53 @@ void TextMetrics::setRowHeight(Row & row, pit_type const pit, bool topBottomSpace) const { Paragraph const & par = text_->getPar(pit); - // get the maximum ascent and the maximum descent - double layoutasc = 0; - double layoutdesc = 0; - double const dh = defaultRowHeight(); - - // ok, let us initialize the maxasc and maxdesc value. - // Only the fontsize count. The other properties - // are taken from the layoutfont. Nicer on the screen :) Layout const & layout = par.layout(); - - // as max get the first character of this row then it can - // increase but not decrease the height. Just some point to - // start with so we don't have to do the assignment below too - // often. - Buffer const & buffer = bv_->buffer(); - Font font = displayFont(pit, row.pos()); - FontSize const tmpsize = font.fontInfo().size(); - font.fontInfo() = text_->layoutFont(pit); - FontSize const size = font.fontInfo().size(); - font.fontInfo().setSize(tmpsize); - - FontInfo labelfont = text_->labelFont(par); - - FontMetrics const & lfm = theFontMetrics(labelfont); - FontMetrics const & fm = theFontMetrics(font); - - // these are minimum values double const spacing_val = layout.spacing.getValue() * text_->spacing(par); - //lyxerr << "spacing_val = " << spacing_val << endl; - int maxasc =
[LyX/master] Move some horizontal scrolling code from TextMetrics to BufferView
commit 96fee0ed7acdd9d757d59b126f07631176e2d96f Author: Jean-Marc LasgouttesDate: Mon Feb 29 16:05:06 2016 +0100 Move some horizontal scrolling code from TextMetrics to BufferView It is better to have all the code in the same place, and it will avoid code duplication later. diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 1daee5c..9708a08 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -2914,15 +2914,26 @@ int BufferView::horizScrollOffset() const } -CursorSlice const & BufferView::currentRowSlice() const -{ - return d->current_row_slice_; +int BufferView::horizScrollOffset(Text const * text, + pit_type pit, pos_type pos) const +{ + // Is this a row that is currently scrolled? + if (!d->current_row_slice_.empty() + && >inset() == d->current_row_slice_.inset().asInsetText() + && pit == d->current_row_slice_.pit() + && pos == d->current_row_slice_.pos()) + return d->horiz_scroll_offset_; + return 0; } -CursorSlice const & BufferView::lastRowSlice() const +bool BufferView::hadHorizScrollOffset(Text const * text, + pit_type pit, pos_type pos) const { - return d->last_row_slice_; + return !d->last_row_slice_.empty() + && >inset() == d->last_row_slice_.inset().asInsetText() + && pit == d->last_row_slice_.pit() + && pos == d->last_row_slice_.pos(); } diff --git a/src/BufferView.h b/src/BufferView.h index 31b6e94..f57801f 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -125,12 +125,15 @@ public: // Returns the amount of horizontal scrolling applied to the // top-level row where the cursor lies int horizScrollOffset() const; - - // Points to the top-level row where the cursor lies (during draw). - CursorSlice const & currentRowSlice() const; - - // Points to the top-level row where the cursor lied at last draw event. - CursorSlice const & lastRowSlice() const; + // Returns the amount of horizontal scrolling applied to the + // row of text starting at (pit, pos) + int horizScrollOffset(Text const * text, + pit_type pit, pos_type pos) const; + + // Returns true if the row of text starting at (pit, pos) was scrolled + // at the last draw event. + bool hadHorizScrollOffset(Text const * text, + pit_type pit, pos_type pos) const; /// reset the scrollbar to reflect current view position. void updateScrollbar(); diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index e69ffe9..80ee0aa 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -1113,14 +1113,8 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x, int const xo = origin_.x_; x -= xo; - int offset = 0; - CursorSlice rowSlice(const_cast(text_->inset())); - rowSlice.pit() = row.pit(); - rowSlice.pos() = row.pos(); - // Adapt to cursor row scroll offset if applicable. - if (bv_->currentRowSlice() == rowSlice) - offset = bv_->horizScrollOffset(); + int const offset = bv_->horizScrollOffset(text_, row.pit(), row.pos()); x += offset; pos_type pos = row.pos(); @@ -1908,26 +1902,18 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const for (size_t i = 0; i != nrows; ++i) { Row const & row = pm.rows()[i]; - int row_x = x; + // Adapt to cursor row scroll offset if applicable. + int row_x = x - bv_->horizScrollOffset(text_, pit, row.pos()); if (i) y += row.ascent(); - CursorSlice rowSlice(const_cast(text_->inset())); - rowSlice.pit() = pit; - rowSlice.pos() = row.pos(); + RowPainter rp(pi, *text_, pit, row, row_x, y); bool const inside = (y + row.descent() >= 0 && y - row.ascent() < ww); - - // Adapt to cursor row scroll offset if applicable. - if (bv_->currentRowSlice() == rowSlice) - row_x -= bv_->horizScrollOffset(); - // It is not needed to draw on screen if we are not inside. pi.pain.setDrawingEnabled(inside && original_drawing_state); - RowPainter rp(pi, *text_, pit, row, row_x, y); - if (selection) row.setSelectionAndMargins(sel_beg_par, sel_end_par); else @@ -1946,7 +1932,7 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const if (pi.pain.isDrawingEnabled()) row.setCrc(pm.computeRowSignature(row, bparams)); bool row_has_changed = row.changed() -
[LyX/master] Cleanup Painter text() API
commit 598f7e4a45dc10232a42db34e5ca887615c5306f Author: Jean-Marc LasgouttesDate: Sun Mar 20 20:02:05 2016 +0100 Cleanup Painter text() API * remove optional arguments to the helpers that use a FontInfo * add a textwidth argument to the text() methods that are used by rowpainter. Now textwidth is only computed if a null value was passed to the text() method. This means that in the use case of rowpainter, no textwidth needs to be computed. diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index 4934c5e..74aaa99 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -60,6 +60,7 @@ cursor. * Proposals + * Clean-up of drawing code The goal is to make painting with drawing disable fast enough that it @@ -81,7 +82,7 @@ paintInset needs to be called. The only thing we want to do here is to set inset positions (for text). The other insets still use the painter with drawing disabled. -** Painter::text +** DONE Painter::text We cannot remove (or make private) the version that uses a FontInfo because it is used by PainterInfo::draw. Document this and @@ -99,6 +100,26 @@ version. ==> more versions, no optional parameters. +** make Inset::display() more useful + +Extending the DisplayType enum would allow to remove special cases +from the code. + +The enumeration could be like +: Inline = 0 +: BreakBefore = 1 // break row before this inset +: BreakAfter = 2 // break row after this inset +: CanBreakAfter = 4 // optionally break row after this inset +: AlignLeft = 8 +: AlignRight = 16 +: NoBoundary = 32 // do not allow cursor to go at the end of the row +: //before display inset +: Display = BreakBefore|BreakAfter + +A display equation would be Display, other could be Display|AlignLeft +BreakAfter can be used by Newline or separator insets +CanBreakAfter can be used by the optional hyphen InsetSpecialChar. + ** Set inset position during metrics phase In order to do that, a no-paint drawing will be initiated after every diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp index 40d2618..e6c6353 100644 --- a/src/RowPainter.cpp +++ b/src/RowPainter.cpp @@ -246,13 +246,14 @@ void RowPainter::paintStringAndSel(Row::Element const & e) Color const col = e.change.changed() ? e.change.color() : Color_selectiontext; copy.fontInfo().setPaintColor(col); - pi_.pain.text(int(x_), yo_, e.str, copy, e.extra); + pi_.pain.text(int(x_), yo_, e.str, copy, e.extra, e.full_width()); } else if (!some_sel) { - pi_.pain.text(int(x_), yo_, e.str, e.font, e.extra); + pi_.pain.text(int(x_), yo_, e.str, e.font, e.extra, e.full_width()); } else { pi_.pain.text(int(x_), yo_, e.str, e.font, Color_selectiontext, - max(row_.sel_beg, e.pos) - e.pos, -min(row_.sel_end, e.endpos) - e.pos, e.extra); + max(row_.sel_beg, e.pos) - e.pos, + min(row_.sel_end, e.endpos) - e.pos, + e.extra, e.full_width()); } x_ += e.full_width(); } diff --git a/src/frontends/Painter.h b/src/frontends/Painter.h index 2106768..b62a4e5 100644 --- a/src/frontends/Painter.h +++ b/src/frontends/Painter.h @@ -133,21 +133,17 @@ public: virtual void image(int x, int y, int w, int h, graphics::Image const & image) = 0; - /** draw a character at position x, y (y is the baseline) -*/ - virtual void text(int x, int y, char_type c, FontInfo const & f) = 0; + /// draw a string at position x, y (y is the baseline). + virtual void text(int x, int y, docstring const & str, FontInfo const & f) = 0; - /** draw a string at position x, y (y is the baseline). The -* text direction is given by \c rtl. -*/ - virtual void text(int x, int y, docstring const & str, FontInfo const & f, - bool rtl = false, double wordspacing = 0.0) = 0; + /// draw a char at position x, y (y is the baseline) + virtual void text(int x, int y, char_type c, FontInfo const & f) = 0; /** draw a string at position x, y (y is the baseline). The * text direction is enforced by the \c Font. */ virtual void text(int x, int y, docstring const & str, Font const & f, - double wordspacing = 0.0) = 0; + double wordspacing, double textwidth) = 0; /** draw a string at position x, y (y is the baseline), but * make sure that the part between \c from and \c to is in @@ -155,7 +151,7 @@ public: */ virtual void text(int x, int y, docstring const & str, Font const & f, Color other, size_type from, size_type to,
[LyX/master] Cmake xhtml export tests: Missing script for commit 416242476289d423eb392345555f3dad941df544
commit 30ef73ab662a90c39f17cf0b08db9dc33ee2679a Author: Kornel BenkoDate: Mon May 30 10:22:59 2016 +0200 Cmake xhtml export tests: Missing script for commit 416242476289d423eb39234f3dad941df544 diff --git a/development/autotests/examineXmllintOutput.pl b/development/autotests/examineXmllintOutput.pl new file mode 100755 index 000..36007e2 --- /dev/null +++ b/development/autotests/examineXmllintOutput.pl @@ -0,0 +1,77 @@ +#! /usr/bin/env perl +# -*- mode: perl; -*- + +# Examine output of 'xmllint --sax --html' + +my $file = $ARGV[0]; # file to examine + +my @tag = (); # tag entries = {"name" => strng, "count" => sequence number} +my $tagindex = 0; # next tag to be written +$tag[$tagindex] = {}; +my %errors = (); + +if (open(FI, $file)) { + my $line = 0; + my $saxchartoprint = 0; + while(my $l = ) { +$line++; +chomp($l); +if ($l =~ /^SAX.startElementNs\(([^, \)]+)/) { + # new tag + my $tag = $1; + $saxchartoprint = 0; + #print "Start tag $tag at line $line, tagindex = $tagindex\n"; + my $newentry = 1; + if (defined($tag[$tagindex]->{"name"})) { + if ($tag[$tagindex]->{"name"} eq $tag) { + $tag[$tagindex]->{"count"} = $tag[$tagindex]->{"count"}+1; + $newentry = 0; + } + } + if ($newentry) { + $tag[$tagindex] = {}; + $tag[$tagindex]->{"name"} = $tag; + $tag[$tagindex]->{"count"} = 1; + } + $tagindex++; + $tag[$tagindex] = {}; +} +elsif ($l =~ /^SAX.endElementNs\(([^, \)]+)/) { + $saxchartoprint = 0; + my $tag = $1; + $tagindex--; + #print "End tag $tag at line $line, tagindex = $tagindex\n"; + if ($tagindex < 0) { + die("tagindex < 0"); + } + if ($tag[$tagindex]->{"name"} ne $tag) { + die("End tag $tag does not match " . $tag[$tagindex]->{"name"} . " at line $line"); + } +} +elsif ($l =~ /^SAX.error: (.*)$/) { + my $err = $1; + if ($err =~ /Entity\s+'([a-zA-Z0-9]+)'\s+not defined$/) { + # Ignore Entity '' not defined + } + elsif (! defined($errors{$err})) { + my $errmsg = ""; + my $trenner = ""; + for (my $i = 0; $i < $tagindex; $i++) { + $errmsg .= $trenner . $tag[$i]->{"name"} . "(" . $tag[$i]->{"count"} . ")"; + $trenner = ", "; + } + $errors{$err} = $errmsg; + print "$err -> $errmsg\n"; + # Print the next 3 lines starting with 'SAX.characters(' + $saxchartoprint = 3; + } +} +elsif ($saxchartoprint > 0) { + $saxchartoprint--; + if ($l =~ /^SAX.characters\(([^\)]+)\)/) { + print "\t$1\n"; + } +} + } +} +exit(0);
[LyX/master] Cmake xhtml export tests: Use command xmllint to test the export result
commit 416242476289d423eb39234f3dad941df544 Author: Kornel BenkoDate: Mon May 30 09:50:22 2016 +0200 Cmake xhtml export tests: Use command xmllint to test the export result diff --git a/development/autotests/ExportTests.cmake b/development/autotests/ExportTests.cmake index f448d80..562c639 100644 --- a/development/autotests/ExportTests.cmake +++ b/development/autotests/ExportTests.cmake @@ -27,6 +27,7 @@ # find_package(Perl) +find_program(XMLLINT_EXECUTABLE xmllint) if(PERL_FOUND) set(DVI_FORMATS "dvi" "dvi3") @@ -401,6 +402,7 @@ foreach(libsubfolderx autotests/export lib/doc lib/examples lib/templates autote -Dinverted=${inverted} -DTOP_SRC_DIR=${TOP_SRC_DIR} -DPERL_EXECUTABLE=${PERL_EXECUTABLE} +-DXMLLINT_EXECUTABLE=${XMLLINT_EXECUTABLE} -P "${TOP_SRC_DIR}/development/autotests/export.cmake") setmarkedtestlabel(${TestName} ${mytestlabel}) # check for suspended pdf/dvi exports endif() diff --git a/development/autotests/export.cmake b/development/autotests/export.cmake index 29487d4..c89c3f6 100755 --- a/development/autotests/export.cmake +++ b/development/autotests/export.cmake @@ -25,6 +25,7 @@ # -Dinverted=[01] \ # -DTOP_SRC_DIR=${TOP_SRC_DIR} # -DPERL_EXECUTABLE=${PERL_EXECUTABLE} +# -DXMLLINT_EXECUTABLE=${XMLLINT_EXECUTABLE} # -P "${TOP_SRC_DIR}/development/autotests/export.cmake" # @@ -138,6 +139,30 @@ else() set(_err -1) else() message(STATUS "Expected result file \"${result_file_name}\" exists") + if (format MATCHES "xhtml") +if (XMLLINT_EXECUTABLE) + # check the created xhtml file + execute_process( +COMMAND ${XMLLINT_EXECUTABLE} --sax --html --valid "${result_file_name}" +OUTPUT_VARIABLE xmlout +ERROR_VARIABLE xmlerr +RESULT_VARIABLE _err) + file(WRITE "${result_file_name}.sax_out" ${xmlout}) + if (NOT _err) +# check if sax-parser output contains error messages +execute_process( + COMMAND ${PERL_EXECUTABLE} "${TOP_SRC_DIR}/development/autotests/examineXmllintOutput.pl" "${result_file_name}.sax_out" + OUTPUT_VARIABLE xmlout + RESULT_VARIABLE _err) + endif() + if (NOT _err) +if (NOT "${xmlout}" STREQUAL "") + message(STATUS "${xmlout}") + set(_err -1) +endif() + endif() +endif() + endif() endif() endif() endif() diff --git a/development/autotests/ignoredTests b/development/autotests/ignoredTests index 06e9b48..01bd26e 100644 --- a/development/autotests/ignoredTests +++ b/development/autotests/ignoredTests @@ -40,3 +40,7 @@ export/examples/(Literate|noweb2lyx)_lyx16 # Document class "Docbook article (SGML)" does not work with LaTeX: export/examples/docbook_article_(dvi3|pdf[245]).* export/templates/DocBook_article_(dvi3|pdf[245]).* + +# Ignore MergedManuals_xhtml because the test is very time-consuming +# and the underlying subdocuments are already tested +export/doc/(ja/|)MergedManuals_xhtml
[LyX/master] Dont use invalid tag '' in xhtml export
commit 161cf523631af91a0197aa3f2b321174d2ca6c4c Author: Kornel BenkoDate: Mon May 30 09:48:06 2016 +0200 Dont use invalid tag '' in xhtml export diff --git a/lib/layouts/jss.layout b/lib/layouts/jss.layout index 47e3dae..1055043 100644 --- a/lib/layouts/jss.layout +++ b/lib/layouts/jss.layout @@ -226,7 +226,7 @@ Style "Code" SeriesBold Color Green EndFont - HTMLTag + HTMLTag pre HTMLItemp End diff --git a/lib/layouts/stdlayouts.inc b/lib/layouts/stdlayouts.inc index 8be0d24..dbde134 100644 --- a/lib/layouts/stdlayouts.inc +++ b/lib/layouts/stdlayouts.inc @@ -91,7 +91,7 @@ Style Verbatim Font Family Typewriter EndFont - HTMLTag + HTMLTag pre HTMLItem p End
[LyX/master] Cmake tests: Allow test of LongestLabelWithUnderscore_xhtml
commit 6823115d17540968d96a0c10e6979264afe2abf1 Author: Kornel BenkoDate: Mon May 30 09:46:01 2016 +0200 Cmake tests: Allow test of LongestLabelWithUnderscore_xhtml diff --git a/development/autotests/suspiciousTests b/development/autotests/suspiciousTests index 98e7126..2949ead 100644 --- a/development/autotests/suspiciousTests +++ b/development/autotests/suspiciousTests @@ -82,7 +82,7 @@ check_load/mathmacros/testcases_speed # - escape special characters, # - convert to LaTeXString, # or just report this at Trac for now? -export/export/LongestLabelWithUnderscore.* +export/export/LongestLabelWithUnderscore_[^x].* Sublabel: lyxbugs
[LyX/master] Cmake: Allow test for X11 with QT5.6
commit 7a86fe3e0b70f944a2c99381ebf217609bf993e9 Author: Kornel BenkoDate: Mon May 30 08:22:15 2016 +0200 Cmake: Allow test for X11 with QT5.6 Used for key-test tests. diff --git a/development/cmake/ConfigureChecks.cmake b/development/cmake/ConfigureChecks.cmake index 825813b..2de915f 100644 --- a/development/cmake/ConfigureChecks.cmake +++ b/development/cmake/ConfigureChecks.cmake @@ -192,7 +192,10 @@ if(LYX_USE_QT MATCHES "QT5") get_target_property(_x11extra_link_libraries Qt5::X11Extras IMPORTED_LOCATION_${_x11extra_prop}) set(CMAKE_REQUIRED_LIBRARIES ${_x11extra_link_libraries}) set(CMAKE_REQUIRED_INCLUDES ${Qt5X11Extras_INCLUDE_DIRS}) -set(CMAKE_REQUIRED_FLAGS ${Qt5X11Extras_EXECUTABLE_COMPILE_FLAGS}) +set(CMAKE_REQUIRED_FLAGS "${Qt5X11Extras_EXECUTABLE_COMPILE_FLAGS} -fPIC -DQT_NO_VERSION_TAGGING") +#message(STATUS "CMAKE_REQUIRED_LIBRARIES = ${_x11extra_link_libraries}") +#message(STATUS "CMAKE_REQUIRED_INCLUDES = ${Qt5X11Extras_INCLUDE_DIRS}") +#message(STATUS "CMAKE_REQUIRED_FLAGS = ${CMAKE_REQUIRED_FLAGS}") check_cxx_source_compiles( " #include