Indexing class
Contents |
Current situation
Situation with indexing is unbearable: the progress dialog cannot have parent so it cannot be made windowmodal, it has to be application modal because if it is not modal it can be started many times and will crash. Just test indexing to see how it is not good to use.
Indexing is now done in an object which is a unique instance of CModuleIndexDialog class (which is not a dialog).
New solution
Indexing is done in a unique object. It does not open a dialog. User can create a widget with createWidget(). The widget has progress bar and text. There can be multiple widgets which all get signals from the indexer. Indexer widgets can be embedded in dialogs or in other widgets. (How to remove the widget from a parent - where it should be deleted? Maybe deleteWidget(Widget*) function?)
User can add modules to the indexer on the fly and cancel indexing. If modules are added the change could be reflected in all indexer widgets. However, it might be important to keep only some modules in one widget: the user doesn't want to see indexes from Bookshelf Manager in the Search dialog. But what happens if a module is already being indexed and is added second time?
It could be useful to append OR prepend modules to the queue because indexing which is started from the Search dialog is more important than the one started from the Bookshelf Manager.
Indexing happens in a thread to prevent all blocking. It could be possible to index the modules simultaneously in different threads but that would make notifications problematic (or can we just count all percent values together?).
Indexer widgets can be embedded for example in Bookshelf Manager Indices page and in Search dialog. Additionally we could add a status bar into the main application window which is updated with the indexing data. I propose a subclass (or a default instance?) of QStatusBar to which the indexer object can add a small status widget. That widget (which is different from the indexer widget) would flash when the indexing is done. This is how we could ensure the maximal flexibility for the user who could do other things while indexing and be notified gently.
The status bar could be used also for module installing.
Conclusions
Designing a multithreaded backround job which can be changed on the fly and used from different places is very difficult. There is quite much designing and coding work to solve a small problem. This is, however, an important part of the user experience and usability. At least I'm personally very frustrated when I start a job which takes long long time and during which I'm unable to do anything else.
Eelik 15:50, 5 December 2007 (CET)
Hi Eeli. Cool. You might want to evaluate QtConcurrent for this purpose. It will be in Qt 4.4 main. --mgruner
Update
Module installing is now done with threads. It is a good starting point for indexing, though it doesn't enable a concurrent UI (yet). QtConcurrent is not enough for these kinds of tasks, it's good only with processor intensive calculation algorithms etc.
The current indexing solution tries to use the old co-operative multitasking, it calls processEvents() to give timeslice to the UI event handling. I think this has never worked well with modern UI libraries (Qt, Gtk...). Real threads would improve usability, but I have to repeat what I said in Conclusions: this may be too much work for a smallish problem.
Eelik 01:42, 12 April 2008 (CDT)