]> git.lyx.org Git - lyx.git/commitdiff
Limit the size of navigation menus for performance.
authorGuillaume Munch <gm@lyx.org>
Wed, 16 Dec 2015 16:34:54 +0000 (16:34 +0000)
committerGuillaume Munch <gm@lyx.org>
Thu, 17 Dec 2015 20:38:04 +0000 (20:38 +0000)
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

index b75221b8b397a2433ed208dc83aea596cf94dee0..7757b0d13ecfe8c6434d048323191d61c602038d 100644 (file)
@@ -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)")));
        }