GNOME Bugzilla – Bug 596428
GtkAssistant: Support ending with a progress page
Last modified: 2010-06-03 21:29:32 UTC
I was reworking Evolution's import assistant to show import progress in a GTK_ASSISTANT_PAGE_PROGRESS page instead of in a separate dialog window. The import happens at the end of the page sequence, after the confirmation page. The import should be cancellable, so I wanted the Cancel button visible and sensitive. But I found that progress pages also show the Back and Forward buttons, which don't make sense in this context. I was able to work around the problem by manually hiding the assistant->back and assistant->forward widgets, but as these struct fields are sealed that's not a viable long-term solution. I suggest adding a new page type -- GTK_ASSISTANT_PAGE_PROGRESS_LAST perhaps -- which acts like a GTK_ASSISTANT_PAGE_PROGRESS but hides the navigation buttons so that only Cancel is visible.
I think a way to do this that would fit in the spirit of the GtkAssitant api would be to mark individual pages as 'sealed' or similar, and have the assitant code figure out which navigation buttons make sense based on that. For your situation, you would mark the confirmation page as sealed when moving to the final progress, and that would tell gtk that the confirmation page cannot be revisited, and a back button makes no sense.
The term "commit" comes to mind for me, but yeah that sounds like a cleaner solution. The forward button also needs dealt with, but that just requires a bit more smarts in GtkAssistant -- no new API needed for that.
While I'm thinking about it, another use case for your 'sealed' idea would be the ability to jump into the middle of an assistant page sequence. Going back to the example of Evolution's import assistant, we're adding the ability import files from the command-line, so that double-clicking an mbox or iCalendar file will finally do something useful. It would be nice to jump straight to the "where do you want to import to?" page with the Back button hidden -- having sealed the "welcome" and "choose a file" pages up front.
So how can this be solved, having GTK 3 in mind?
Coming back to this after half a year, I realized I'm abusing GtkAssistant's cancel button in my original use case. That cancel button is meant for cancelling the whole assistant, not whatever operation is running on a progress page. A progress page that's tracking a cancellable operation should really provide its own descriptive cancel button (e.g. "Cancel Import"). Also with respect to GtkAssistant's cancel button, would it make sense to assert that once the user clicks Apply on a confirmation page, the assistant can no longer be cancelled (presumably because changes have already been written) and subsequent pages should not show a Cancel button? Furthermore, once we're able to seal pages as described in comment #1, should a confirmation page be implicitly sealed when the user clicks Apply?
Created attachment 162582 [details] [review] Proposed patch (1/2) I solved this as simply as I could in two patches which should be evaluated separately as they solve different problems. The first patch implements comment #1, but instead of sealing individual pages you simply call gtk_assistant_commit(), which does two things: 1) Discards the visited page list and updates the buttons state, which effectively hides the back button on the current page. This would most likely be called from a "prepare" handler. Applications can still jump back to earlier pages programmatically. 2) Sets an internal flag which prevents the cancel button from being shown on subsequent pages, the idea being that committing is a non-reversible action, and thus it's too late to cancel the assistant at that point. (I think we might also want to prevent the "delete-event" handler from emitting a cancel signal if the commit flag is set. That part is not in the patch.) So that deals with the Back and Cancel button for my use case.
Created attachment 162583 [details] [review] Proposed patch (2/2) I'm less sure of this one, but it seems the most conservative approach. When a progress page appears last in a GtkAssistant, hide the forward button. This uses GtkAssistantPageFunc to determine whether the progress page is last. I debated whether to add a close button in its stead, but decided against it because a close button doesn't really fit my use case (track importing progress then close automatically), and if a close button -is- desired there's always gtk_assistant_add_action_widget().
Review of attachment 162582 [details] [review]: This is a nice an simple way to implement the seal idea. It might be nice to mention your use case (of having a progress page at the end) as an example in the docs. It would also be nice to have a case involving this function in the assistant demo in gtk3-demo, but that is not a blocker.
(In reply to comment #8) Okay, I'll work on the demo and docs. Do you think hiding the Cancel button makes sense or should that be controlled separately?
Review of attachment 162583 [details] [review]: Makes sense to me. But you probably need to update the documentation in gtkassistant.h that currently states "Note that an assistant needs to end its page flow with a page of type %GTK_ASSISTANT_PAGE_CONFIRM or %GTK_ASSISTANT_PAGE_SUMMARY to be correct."
I think hiding the cancel button makes sense.
Created attachment 162664 [details] [review] Documentation updates This applies on top of the other two patches. I noticed also the docs for GtkAssistant::apply already implies using a progress page last.
Comment on attachment 162664 [details] [review] Documentation updates Thanks, looks great
Created attachment 162678 [details] [review] Demo This adds an animated progress page to the end of the GtkAssistant demo. Works fine on the gtk-2-22 branch but for some reason the progress bar doesn't want to redraw on master. I assume that's a separate bug...
Comment on attachment 162678 [details] [review] Demo Looks good
Progress bar rendering is broken before your patch, as it turns out.
Yeah, I can confirm here too. Filled bug #620509
Patches squashed and committed to master and gtk-2-22 branches: http://git.gnome.org/browse/gtk+/commit/?id=bb5c585777cede12bd1a7cf9fd1c5082e2debc22 http://git.gnome.org/browse/gtk+/commit/?h=gtk-2-22&id=01e2fc5b5a99fc9c5096b13bfe6323174465fd35