This is an Engineering Notebook post, explaining how to greatly improve the performance of Leo's outline pane. I don't have plans to do this at present, but it's important to important to discuss the details now, while they are fresh in my mind. This will be pre-writing for an enhancement issue, with no particular due date.
*Note*: The ideas discussed below could apply to QGraphicsScene as well as Leo's existing QTreeWidget. *Background* At present, Leo's core calls c.redraw whenever the outline changes. There are also some shortcut calls, that update only icons. This is the approach that Leo has used from its earliest days, with only fairly minor evolutionary changes. This is usually plenty good enough, but significant improvements in speed are possible, and might be useful when scrolling rapidly through a large outline. *Incremental allocation* The name "c.redraw" is a misnomer. The actual code *reallocates* the entire tree, which then causes Qt to redraw it. Instead of reallocating the entire tree whenever any part of it changes, it would be significantly faster (for large outlines) to update only those parts of an outline that have actually changed. To do this, Leo's core would make *incremental calls* to update the outline. Something like the following calls would be needed: c.tree.delete(p) # Delete position p c.tree.insertAsNthChildOf(p, p2) # Insert p2 as the nth child of p. c.tree.insertAfter(p,p2) # Insert p2 after p. c.tree.clone(p) # Clone p, creating a following sibling node. c.tree.expand(p) # Expand p. c.tree.contract(p) # Contract p. *All the operations listed above are complicated*, because they all must support clones. For example, inserting an item (a QTreeWidgetItem <http://doc.qt.io/archives/qt-4.8/qtreewidgetitem.html>) anywhere in the outline must insert *copies* of the item if the position p is a child of any clone. Even the expand and contract operations can affect arbitrarily many *already allocated* items. The expansion state of each item must be set/cleared individually. The present redraw code in qtree.drawTopTree and helpers does this easily. It would be much more complicated to do this incrementally, but the performance payoff could be arbitrarily large. *Changing Leo's core* There are 210 calls to c.redraw* in Leo's core at present. Perhaps only a dozen or such calls would actually have to be replaced in order to yield significantly better performance. A mix of incremental and complete reallocation is possible. *QGraphicsScene vs QTreeWidget* Yesterday's work proves, imo, that the QTreeWidget should be always be fully populated with items, including items that aren't visible. This allows makes redraw work properly when the user has scrolled the outline pane by hand. If a QGraphicsScene were used, perhaps only the visible nodes would have to be allocated. The tradeoffs in doing so are complicated. In most cases, significantly few nodes/items would *actually* be allocated, but expanding and contracting nodes then becomes much more expensive. And of course the scrolling issues that bedevil QTreeWidget would have to be handled. *Summary* This project is feasible. The present data structures in the LeoQtTree class likely suffice to support these operations, and any required data could easily be added. Replacing just few calls to c.redraw might yield significantly better performance, and significantly less load on the GC. The approach described above applies to any implementation of Leo's outline pane, including one based on QGraphicsScene. I personally see no great need to do this project, but I would encourage anyone to investigate this approach if it appeals to them. Edward -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+unsubscr...@googlegroups.com. To post to this group, send email to leo-editor@googlegroups.com. Visit this group at https://groups.google.com/group/leo-editor. For more options, visit https://groups.google.com/d/optout.