Gtk2::Assistant page flow

View: New views
4 Messages — Rating Filter:   Alert me  

Gtk2::Assistant page flow

by Peter Juhasz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

There is one more thing (for now, anyway) I'd like to ask your help about.

I want to set up a Gtk2::Assistant. On the first page of the assistant
there is an Entry field. What I'm trying to achieve is that if the
value entered into this field is invalid (empty or already present in
the database), then an error message would pop up and the assistant
would reset to the first page, to let the user correct their mistake.

Here is a minimal example of what I tried:

#############################################
#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Gtk2 -init;
use Gtk2::Ex::Dialogs;
use Glib ':constants';

my %gui_strings = (
        id_empty_error_title => "Error: empty id",
        id_empty_error_text => "You did not give a valid identifier.",
        assistant1_title => "Id",
        assistant2_title => "Confirm",
        assistant2_label => "Well done!",
);


my $id;

my $assistant = Gtk2::Assistant->new;
Gtk2::Ex::Dialogs->set_parent_window( $assistant );
$assistant->signal_connect (delete_event => sub { Gtk2->main_quit; });

my $page = Gtk2::Entry->new();
$assistant->append_page ($page);
$assistant->set_page_title ($page, $gui_strings{assistant1_title});
$assistant->set_page_complete ($page, TRUE);
$assistant->set_page_type ($page, 'intro');
$page->show_all;

my $page2 = Gtk2::Label->new($gui_strings{assistant2_label});
$page2->show;
$assistant->append_page ($page2);
$assistant->set_page_title ($page2, $gui_strings{assistant2_title});
$assistant->set_page_complete ($page2, TRUE);
$assistant->set_page_type ($page2, 'confirm');

$assistant->signal_connect (cancel => \&cancel_callback);
$assistant->signal_connect (close => \&cancel_callback);
$assistant->signal_connect (apply => sub {
                # do whatever we have to do with the id, here we just print it
                print $id."\n";
        });
$assistant->signal_connect (prepare => sub {
    my $page_num = $assistant->get_current_page();
    $id = $page->get_text();
    if ($page_num == 1 and $id eq "") {
    new_and_run Gtk2::Ex::Dialogs::ErrorMsg ( title =>
$gui_strings{id_empty_error_title},
                                     text =>
$gui_strings{id_empty_error_text} );
                        $assistant->set_current_page(0);
                        return;
    }
    });

$assistant->show_all;
Gtk2->main;


sub cancel_callback {
  my $widget = shift;

  $widget->destroy;
  Gtk2->main_quit;
}
#############################################


However, there is a problem. When I leave the entry field empty, the
dialog pops up as expected. But what I get after pressing OK on the
dialog is a blank assistant page! Only after pressing Forward again do
I get back my original first page of the assistant.

What am I doing wrong? The problem is consistent on both Linux and
Windows by the way.

(This one is also reposted from Perlmonks)

Thanks:

Péter Juhász
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: Gtk2::Assistant page flow

by Peter Juhasz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 16, 2009 at 7:17 PM, Peter Juhasz<peter.juhasz83@...> wrote:
> There is one more thing (for now, anyway) I'd like to ask your help about.
>
> I want to set up a Gtk2::Assistant. On the first page of the assistant
> there is an Entry field. What I'm trying to achieve is that if the
> value entered into this field is invalid (empty or already present in
> the database), then an error message would pop up and the assistant
> would reset to the first page, to let the user correct their mistake.
>
[snip]

>
> However, there is a problem. When I leave the entry field empty, the
> dialog pops up as expected. But what I get after pressing OK on the
> dialog is a blank assistant page! Only after pressing Forward again do
> I get back my original first page of the assistant.
>
> What am I doing wrong? The problem is consistent on both Linux and
> Windows by the way.
>
>
> Thanks:
>
> Péter Juhász
>

Sorry for the shameless whining, but I still can't figure this one
out. Could you please give me some ideas on how to set up the
Assistant page flow correctly?

Thanks:

Péter Juhász
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: Gtk2::Assistant page flow

by muppet-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jul 16, 2009, at 1:17 PM, Peter Juhasz wrote:

> There is one more thing (for now, anyway) I'd like to ask your help  
> about.
>
> I want to set up a Gtk2::Assistant. On the first page of the assistant
> there is an Entry field. What I'm trying to achieve is that if the
> value entered into this field is invalid (empty or already present in
> the database), then an error message would pop up and the assistant
> would reset to the first page, to let the user correct their mistake.
>
> Here is a minimal example of what I tried:
>
> #############################################
> #!/usr/bin/perl
>
> use strict;
> use warnings;
> use utf8;
> use Gtk2 -init;
> use Gtk2::Ex::Dialogs;
> use Glib ':constants';
>
> my %gui_strings = (
> id_empty_error_title => "Error: empty id",
> id_empty_error_text => "You did not give a valid identifier.",
> assistant1_title => "Id",
> assistant2_title => "Confirm",
> assistant2_label => "Well done!",
> );
>
>
> my $id;
>
> my $assistant = Gtk2::Assistant->new;
> Gtk2::Ex::Dialogs->set_parent_window( $assistant );
> $assistant->signal_connect (delete_event => sub { Gtk2->main_quit; });
>
> my $page = Gtk2::Entry->new();
> $assistant->append_page ($page);
> $assistant->set_page_title ($page, $gui_strings{assistant1_title});
> $assistant->set_page_complete ($page, TRUE);
> $assistant->set_page_type ($page, 'intro');
> $page->show_all;
>
> my $page2 = Gtk2::Label->new($gui_strings{assistant2_label});
> $page2->show;
> $assistant->append_page ($page2);
> $assistant->set_page_title ($page2, $gui_strings{assistant2_title});
> $assistant->set_page_complete ($page2, TRUE);
> $assistant->set_page_type ($page2, 'confirm');
>
> $assistant->signal_connect (cancel => \&cancel_callback);
> $assistant->signal_connect (close => \&cancel_callback);
> $assistant->signal_connect (apply => sub {
> # do whatever we have to do with the id, here we just print it
> print $id."\n";
> });
> $assistant->signal_connect (prepare => sub {
>     my $page_num = $assistant->get_current_page();
>     $id = $page->get_text();
>     if ($page_num == 1 and $id eq "") {
>     new_and_run Gtk2::Ex::Dialogs::ErrorMsg ( title =>
> $gui_strings{id_empty_error_title},
>                                    text =>
> $gui_strings{id_empty_error_text} );
> $assistant->set_current_page(0);
> return;
>     }
>    });
>
> $assistant->show_all;
> Gtk2->main;
>
>
> sub cancel_callback {
>  my $widget = shift;
>
>  $widget->destroy;
>  Gtk2->main_quit;
> }
> #############################################
>
>
> However, there is a problem. When I leave the entry field empty, the
> dialog pops up as expected. But what I get after pressing OK on the
> dialog is a blank assistant page! Only after pressing Forward again do
> I get back my original first page of the assistant.
>
> What am I doing wrong? The problem is consistent on both Linux and
> Windows by the way.


The "prepare" signal is used to prepare the page before showing it.  
It cannot be used to abort a page, which your code seems to want to do.

Also, set_page_complete() is intended to sallow the "Forward" action  
once the contents of the page are set up correctly.  Your code sets  
the complete flag on each page at construction time, and i think this  
is your problem.  If, instead, you don't set the continue flag true  
until the first page contains a valid identifier, you won't even need  
your validation dialog.

When you create your entry, connect to its "changed" signal, and  
validate the input on each keystroke.  If the input is valid, set the  
page complete flag to true, and the "Forward" button will enable itself.

If the validation is too expensive (e.g. you have to check with a  
database or something), then you have options:

- In your handler for the entry's "changed" signal, set a timer to  
expire in half a second or so to defer the validation until the user  
stops typing.
- Do your validation in "apply" instead.


--
The trees on the bus go "pyoo pyoo pyoo..."
   -- Yvonne, singing, um, something

_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Re: Gtk2::Assistant page flow

by Peter Juhasz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 30, 2009 at 7:12 PM, muppet<scott@...> wrote:

>
> On Jul 16, 2009, at 1:17 PM, Peter Juhasz wrote:
>
>> There is one more thing (for now, anyway) I'd like to ask your help about.
>>
>> I want to set up a Gtk2::Assistant. On the first page of the assistant
>> there is an Entry field. What I'm trying to achieve is that if the
>> value entered into this field is invalid (empty or already present in
>> the database), then an error message would pop up and the assistant
>> would reset to the first page, to let the user correct their mistake.
>>
>> Here is a minimal example of what I tried:
>>
>> #############################################
>> #!/usr/bin/perl
>>
>> use strict;
>> use warnings;
>> use utf8;
>> use Gtk2 -init;
>> use Gtk2::Ex::Dialogs;
>> use Glib ':constants';
>>
>> my %gui_strings = (
>>        id_empty_error_title => "Error: empty id",
>>        id_empty_error_text => "You did not give a valid identifier.",
>>        assistant1_title => "Id",
>>        assistant2_title => "Confirm",
>>        assistant2_label => "Well done!",
>> );
>>
>>
>> my $id;
>>
>> my $assistant = Gtk2::Assistant->new;
>> Gtk2::Ex::Dialogs->set_parent_window( $assistant );
>> $assistant->signal_connect (delete_event => sub { Gtk2->main_quit; });
>>
>> my $page = Gtk2::Entry->new();
>> $assistant->append_page ($page);
>> $assistant->set_page_title ($page, $gui_strings{assistant1_title});
>> $assistant->set_page_complete ($page, TRUE);
>> $assistant->set_page_type ($page, 'intro');
>> $page->show_all;
>>
>> my $page2 = Gtk2::Label->new($gui_strings{assistant2_label});
>> $page2->show;
>> $assistant->append_page ($page2);
>> $assistant->set_page_title ($page2, $gui_strings{assistant2_title});
>> $assistant->set_page_complete ($page2, TRUE);
>> $assistant->set_page_type ($page2, 'confirm');
>>
>> $assistant->signal_connect (cancel => \&cancel_callback);
>> $assistant->signal_connect (close => \&cancel_callback);
>> $assistant->signal_connect (apply => sub {
>>                # do whatever we have to do with the id, here we just print
>> it
>>                print $id."\n";
>>        });
>> $assistant->signal_connect (prepare => sub {
>>        my $page_num = $assistant->get_current_page();
>>        $id = $page->get_text();
>>        if ($page_num == 1 and $id eq "") {
>>                new_and_run Gtk2::Ex::Dialogs::ErrorMsg ( title =>
>> $gui_strings{id_empty_error_title},
>>                                                                  text =>
>> $gui_strings{id_empty_error_text} );
>>                        $assistant->set_current_page(0);
>>                        return;
>>        }
>>   });
>>
>> $assistant->show_all;
>> Gtk2->main;
>>
>>
>> sub cancel_callback {
>>  my $widget = shift;
>>
>>  $widget->destroy;
>>  Gtk2->main_quit;
>> }
>> #############################################
>>
>>
>> However, there is a problem. When I leave the entry field empty, the
>> dialog pops up as expected. But what I get after pressing OK on the
>> dialog is a blank assistant page! Only after pressing Forward again do
>> I get back my original first page of the assistant.
>>
>> What am I doing wrong? The problem is consistent on both Linux and
>> Windows by the way.
>
>
> The "prepare" signal is used to prepare the page before showing it.  It
> cannot be used to abort a page, which your code seems to want to do.
>
> Also, set_page_complete() is intended to sallow the "Forward" action once
> the contents of the page are set up correctly.  Your code sets the complete
> flag on each page at construction time, and i think this is your problem.
>  If, instead, you don't set the continue flag true until the first page
> contains a valid identifier, you won't even need your validation dialog.
>
> When you create your entry, connect to its "changed" signal, and validate
> the input on each keystroke.  If the input is valid, set the page complete
> flag to true, and the "Forward" button will enable itself.
>
> If the validation is too expensive (e.g. you have to check with a database
> or something), then you have options:
>
> - In your handler for the entry's "changed" signal, set a timer to expire in
> half a second or so to defer the validation until the user stops typing.
> - Do your validation in "apply" instead.
>
>
> --
> The trees on the bus go "pyoo pyoo pyoo..."
>  -- Yvonne, singing, um, something
>
>

Thanks for the advice.

Validating the input on entry makes sense, I should've done that in
the first place.

However, in my real application validating this identifier field is
not the only thing that has to happen before proceeding to the second
page of the assistant: a large data file has to be opened, parsed, and
the data from it loaded to memory. Several options on the later pages
of the assistant depend on certain parameters that come from this data
file. So what I'm doing currently is running the data import routine
in the function that's connected to the assistant's prepare signal,
and depending on the result, either go on normally or put up an error
message and reset the assistant to page 0, to let the user choose a
different file.

It seems that this is the wrong thing (or one of the wrong things) to do.

How could I do this properly? Any further processing is pointless if
the data file is not loaded and parsed correctly, so that has to
happen there.

Should I make two assistants? The first one would have just one page,
and it could validate the id, the way you recommended, and in its
apply signal load the data file.
If that fails, I could simply restart this first assistant. And if it
succeeds, I would start the second assistant, which would handle the
rest of the user input.

This sounds a bit convoluted to me, but I can't see any better solution.

Thanks again for the answer:

Péter Juhász
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@...
http://mail.gnome.org/mailman/listinfo/gtk-perl-list