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:
$saveDir_button
) and can be accessed via $saveDir_button->get_filename()
.$settings_xml->{'general'}->{'folder'}
)$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).
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).