From 2dfb5f80ce6500bd8da60a6e170227cc710c818f Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Wed, 16 Dec 2015 16:34:54 +0000 Subject: [PATCH] Limit the size of navigation menus for performance. After d5a5fbb8, as indicated in the commit log, it remained to make sure that the sub-menus of the navigation menu showing the TOCs are generated in a delayed fashion, to avoid corner cases regarding performance when documents have very lengthy tocs (e.g. in a document with 1000 sections it takes a few hundreds milliseconds for the menu to be refreshed). But this idea actually requires substantial changes to the way menus are computed, so it is not for now. In the meanwhile, I reintroduce a max size for menus, after which it is cut off. This differs from the one that I removed at d5a5fbb8 in two ways: 1) if there are more items than the max size, then we still show something instead of nothing, 2) we allow ourselves to rely on qt's scrollable menus and therefore allow bigger menus than before the above commit. The philosophy is that it is better to show something than nothing, that it's better to show a scrollable menu than to cut the menu to fit the screen, and that beyond a certain size the scrollable menu becomes useless anyways. --- src/frontends/qt4/Menus.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/frontends/qt4/Menus.cpp b/src/frontends/qt4/Menus.cpp index b75221b8b3..7757b0d13e 100644 --- a/src/frontends/qt4/Menus.cpp +++ b/src/frontends/qt4/Menus.cpp @@ -354,7 +354,7 @@ public: void expandFloatListInsert(Buffer const * buf); void expandFloatInsert(Buffer const * buf); void expandFlexInsert(Buffer const * buf, InsetLayout::InsetLyXType type); - void expandToc2(Toc const & toc_list, size_t from, size_t to, int depth); + void expandToc2(Toc const & toc_list, size_t from, size_t to, int depth, string toc_type); void expandToc(Buffer const * buf); void expandPasteRecent(Buffer const * buf); void expandToolbars(); @@ -1217,10 +1217,18 @@ void MenuDefinition::expandFlexInsert( } +// Threshold before we stop displaying sub-items alongside items +// (for display purposes). Ideally this should fit on a screen. size_t const max_number_of_items = 30; +// Size limit for the menu. This is for performance purposes, +// because qt already displays a scrollable menu when necessary. +// Ideally this should be the menu size from which scrollable +// menus become unpractical. +size_t const menu_size_limit = 80; void MenuDefinition::expandToc2(Toc const & toc_list, - size_t from, size_t to, int depth) + size_t from, size_t to, int depth, + string toc_type) { int shortcut_count = 0; @@ -1250,6 +1258,7 @@ void MenuDefinition::expandToc2(Toc const & toc_list, } } else { size_t pos = from; + size_t size = 1; while (pos < to) { size_t new_pos = pos + 1; while (new_pos < to && toc_list[new_pos].depth() > depth) @@ -1264,16 +1273,22 @@ void MenuDefinition::expandToc2(Toc const & toc_list, label += QString::number(++shortcut_count); } } + if (size >= menu_size_limit) { + FuncRequest f(LFUN_DIALOG_SHOW, "toc " + toc_type); + add(MenuItem(MenuItem::Command, "...", f)); + break; + } if (new_pos == pos + 1) { add(MenuItem(MenuItem::Command, label, FuncRequest(toc_list[pos].action()))); } else { MenuDefinition sub; - sub.expandToc2(toc_list, pos, new_pos, depth + 1); + sub.expandToc2(toc_list, pos, new_pos, depth + 1, toc_type); MenuItem item(MenuItem::Submenu, label); item.setSubmenu(sub); add(item); } + ++size; pos = new_pos; } } @@ -1314,7 +1329,7 @@ void MenuDefinition::expandToc(Buffer const * buf) submenu.add(MenuItem(MenuItem::Command, qt_("Open Outliner..."), f)); submenu.add(MenuItem(MenuItem::Separator)); // add entries - submenu.expandToc2(* cit->second, 0, cit->second->size(), 0); + submenu.expandToc2(*cit->second, 0, cit->second->size(), 0, cit->first); MenuItem item(MenuItem::Submenu, guiName(cit->first, buf->params())); item.setSubmenu(submenu); // deserves to be in the main menu? @@ -1335,7 +1350,8 @@ void MenuDefinition::expandToc(Buffer const * buf) LYXERR(Debug::GUI, "No table of contents."); else { if (!cit->second->empty()) - expandToc2(* cit->second, 0, cit->second->size(), 0); + expandToc2(*cit->second, 0, cit->second->size(), 0, + "tableofcontents"); else add(MenuItem(MenuItem::Info, qt_("(Empty Table of Contents)"))); }