perlgtkfilechooser

How to change the folder in Gtk3::FileChooserButton programmatically?


I am trying to fix a bug in a Perl GTK3 app. In the settings dialog there is a FileChooserButton which is being used to set the path where files will be saved. The app also has the ability to save all settings in profiles (.xml files) and then load these profiles when necessary.

The saving location is present in three variables:

  1. The FileChooserButton object (it is called $saveDir_button) and can be accessed via $saveDir_button->get_filename().
  2. The profile's .xml object which is read from an .xml file (it is called $settings_xml->{'general'}->{'folder'})
  3. The current settings value (it is called $settings{'general'}->{'folder'})

When the user clicks the FileChooserButton, the path in $saveDir_button is updated.

When the user saves the settings to a profile, the current settings $settings{'general'}->{'folder'} and also the profile's .xml $settingsfile is updated (which is then read into the $settings_xml object):

        $settings{'general'}->{'folder'}   = Glib::filename_to_unicode($saveDir_button->get_filename());


        eval {
            my ($tmpfh, $tmpfilename) = tempfile(UNLINK => 1);
            XMLout(\%settings, OutputFile => $tmpfilename);

            #and finally move the file
            mv($tmpfilename, $settingsfile);
        };

When the profile is being loaded, the value is loaded from the .xml file into the $settings_xml object and then written into the button object $saveDir_button:

                $settings_xml = XMLin(IO::File->new($settingsfile));
                utf8::decode $settings_xml->{'general'}->{'folder'};
                $saveDir_button->set_current_folder($settings_xml->{'general'}->{'folder'});

So, the relevant part is, that the correct value is now in the button object. When saving files, the path is read from there. But, for some reason, the set_current_folder call isn't executed properly. When loading a profile, the button doesn't change its value. As far as I understand, the value can only be changed by the user, when he clicks the button and selects the folder in the file chooser dialog. But I'd need to set the value programmatically when loading a profile. Is this possible?

I was thinking about writing the value into $settings{'general'}->{'folder'} and then reading it from there when actually saving files. But this has two drawbacks:

Firstly, the shown value in the settings dialog is then still wrong after loading a profile. Secondly, I'd need to change the saving procedure on many places in the code and I'm a bit scared to mess up stuff (I'm just learning Perl and we are speaking about >10k lines of code, I'm currently only making small changes).


Solution

  • But, for some reason, the set_current_folder call isn't executed properly. When loading a profile, the button doesn't change its value. When loading a profile, the button doesn't change its value. As far as I understand, the value can only be changed by the user, when he clicks the button and selects the folder in the file chooser dialog. But I'd need to set the value programmatically when loading a profile. Is this possible?

    Here is an example of how you can use set_filename() method to change the buttons value (note that for this example, the button will only change its value if the file exists in the file system):

    use v5.36;  # strict + warnings + say
    use Gtk3 -init;
    
    my $window = Gtk3::Window->new( 'toplevel' );
    $window->signal_connect( destroy  => sub { Gtk3->main_quit() } );
    my $grid = Gtk3::Grid->new();
    $window->add( $grid );
    my $button1 = Gtk3::Button->new();
    $button1->set_label('Change file chooser label');
    my $file_chooser;
    $button1->signal_connect('clicked' => sub {
        $file_chooser->set_filename('/etc/anacrontab');
    } );
    $grid->attach($button1, 0,0,1,1);
    my $file_chooser_action = 'open';
    $file_chooser = Gtk3::FileChooserButton->new("Open file", $file_chooser_action);
    $file_chooser->set_current_folder("/etc");
    $grid->attach($file_chooser, 0, 1, 1, 1);
    $window->set_default_size( 200, 200 );
    $window->set_position('center_always');
    $window->show_all();
    Gtk3->main();
    

    If you click the topmost button "Change file chooser label", the bottom file chooser button should change its name to anacrontab (if that file /etc/anacrontab exists in you filesystem).