package GCOptions; ################################################### # # Copyright 2005-2010 Christian Jodar # # This file is part of GCstar. # # GCstar is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # GCstar is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GCstar; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA # ################################################### use strict; use Gtk2; our $DEFAULT_IMG_DIR='./.%FILE_BASE%_pictures/'; { package GCOptionLoader; my $DEFAULT_LANG='EN'; #my $DEFAULT_IMG_DIR=$ENV{GCS_DATA_HOME}.'/images/'; use XML::Simple; use IO::File; use POSIX (':errno_h'); use GCLang; sub new { # fallbackOptions has been added in 1.7.0. Previous versions stored some collection # specific settings at global level. This has been moved to collection level, but to # let users keep their previous settings, it will try to find it at global level if not found # at collection level. my ($proto, $file, $main, $fallbackOptions) = @_; my $class = ref($proto) || $proto; my $self = {created => 0, fallbackOptions => $fallbackOptions}; #GCLang::loadLangs; bless ($self, $class); $self->load($file, $main) if $file; return $self; } sub newFromXmlString { my ($proto, $string) = @_; my $class = ref($proto) || $proto; my $self = {created => 0}; bless ($self, $class); if ($string) { my $xs = XML::Simple->new; $self->{options} = $xs->XMLin($string, SuppressEmpty => 1); } return $self; } sub toXmlString { my $self = shift; my $result = ' '; while (my ($key,$value) = each(%{$self->{options}})) { $result .= " <$key>".GCUtils::encodeEntities($value)."\n"; } $result .= ''; return $result; } sub error { my ($self, $type, $errmsg) = @_; if ($self->{parent}) { $self->{parent}->optionsError($type, $errmsg); } else { print "Error performing $type for ".$self->{file}.": $errmsg\n"; } } sub setParent { my ($self, $parent) = @_; $self->{parent} = $parent; } sub load { my ( $self, $file, $main ) = @_; my %defaults; if ( $main ) { my $lang = $ENV{LANG}; if ($lang) { $lang =~ s/(..)_?.*/\U$1\E/; } else { $lang = $DEFAULT_LANG; }; # if %defaults = ( images => $GCOptions::DEFAULT_IMG_DIR, autosave => 1, noautoload => 0, programs => "system", browser => "firefox", player => "mplayer", audio => "xmms", imageEditor => "gimp", file => "", split => 300, width => 920, height => 640, confirm => 1, lang => $lang, status => 1, splash => 1, tearoffMenus => 0, toolbar => 3, toolbarPosition => 0, transform => 1, articles => "le,la,les,l,un,une,des,a,the,der,die,das,ein,eine,el,los,una", askImport => 0, searchStop => 1, alwaysOriginal => 0, proxy => "", cookieJar => "", borrowers => "", emails => "", view => 0, columns => 3, resizeImgList => 1, animateImgList => 1, listBgPicture => 1, useOverlays => 1, mailer => "Sendmail", from => "", subject => "GCstar email", smtp => "", template => "Hello %1,

You have borrowed my %2 since %3. I\'d like to get it back shortly.", history => "none|none|none|none|none", historysize => "5", useRelativePaths => 1, useTitleForPics => 1, expandersMode => 'cut', dateFormat => '%d/%m/%Y', spellCheck => 1, cdDevice => '/dev/cd', useStars => 1, bigPics => 0, listPaneSplit => 10000, # Big value to make sure it's hidden by default displayMenuBar => 1 ); }; # if $self->{file} = $file; $self->{options} = \%defaults; # Use default values for now. my $handle = IO::File->new($file, "<:utf8"); if (defined( $handle)) { # File opened succesfully, read it. my $options = \%defaults; while (my $line = $handle->getline()) { # Remove last character if white space # This includes carriage return and fix an issue when using DOS-encoded file on Unix system $line =~ s/\s$//; if ($line =~ m{^(.*?)=(.*)$}) { $options->{$1} = $2; } else { # TODO: Report an error in config file. } # if } # while # Close file, check errors. my $rc = $handle->close(); if ($rc) { # File was read successfully, update options. $self->{options} = $options; } else { # File was not read, do not change default values and report error. $self->error( 'read', $! ); } #if } else { # File is not opened. Check the reason. if ($! == ENOENT) { # File does not exist -- not a problem, just continue with defaults. $self->{options} = \%defaults; } else { # It is a real error, report it. # ???: Why report goes to stdout? # TODO: Open a error window. $self->error('read', $!); } # if } # if if (!GCLang::loadLangs($self->lang) && $main) { $self->lang($DEFAULT_LANG); GCLang::loadLangs($self->lang); } } sub getFullLang { my $self = shift; (my $lang = $self->lang) =~ s/(.*)/\L$1\E_$1/; $lang =~ s/_EN/_US/; # Fix for english $lang =~ s/_CS/_CZ/; # Fix for Czech $lang =~ s/_cn_ZH//; # Fix for Simplified Chinese $lang =~ s/_ZH/_TW/; # Fix for Traditional Chinese $lang .= '.UTF-8'; $lang = 'sr@Latn' if $lang =~ /^sr/; # Fix for serbian return $lang; } sub save { my $self = shift; return if !$self->{file}; my $handle = IO::File->new($self->{file}, ">:utf8"); if (defined($handle)) { while ( my ( $key, $value ) = each( %{ $self->{options} } ) ) { if ($key) { $handle->print( "$key=$value\n" ); } # if } # while $handle->close() or $self->error('save', $!); } else { $self->error( 'save', $! ); }; # if } sub exists { my ($self, $name) = @_; return exists $self->{options}->{$name}; } sub AUTOLOAD { my $self = shift; my $name = our $AUTOLOAD; return if $name =~ /::DESTROY$/; my @comp = split('::', $name); $name = $comp[-1]; if (@_) { $self->{options}->{$name} = shift; } else { if (!exists $self->{options}->{$name} && $self->{fallbackOptions}) { $self->{options}->{$name} = $self->{fallbackOptions}->$name; } return $self->{options}->{$name}; } } sub checkPreviousGCfilms { my ($self, $parent) = @_; $self->{modelsFactory} = $parent->{modelsFactory}; my $gcfilmsconf = $ENV{XDG_CONFIG_HOME}.'/gcfilms/gcfilms.conf'; if ( -e $gcfilmsconf) { my $dialog = Gtk2::MessageDialog->new($parent, [qw/modal destroy-with-parent/], 'question', 'ok-cancel', $parent->{lang}->{GCfilmsImportQuestion}); my $withOptionsCb = new Gtk2::CheckButton($parent->{lang}->{GCfilmsImportOptions}); my $withDataCb = new Gtk2::CheckButton($parent->{lang}->{GCfilmsImportData}); $dialog->vbox->pack_start($withOptionsCb, 0, 0, 0); $dialog->vbox->pack_start($withDataCb, 0, 0, 0); $dialog->vbox->show_all; #$parent->{splash}->hide if $parent->{splash}; my $response = $dialog->run; my $withOptions = $withOptionsCb->get_active; my $withData = $withDataCb->get_active; $dialog->destroy; return if $response ne 'ok'; my $gcfilmsOptions = GCOptionLoader->new($gcfilmsconf, 0); $self->importGCfilmsOptions($gcfilmsOptions) if $withOptions; $self->importGCfilmsData($gcfilmsOptions) if $withData; } } sub importGCfilmsOptions { my ($self, $options) = @_; my @commonOptions = ( 'listImgSize', 'historysize', 'browser', 'listBgColor', 'listFgColor', 'searchStop', 'groupItems', 'view', 'split', 'autosave', 'articles', 'lang', 'template', 'askImport', 'subject', 'toolbar', 'listImgSkin', 'columns', 'proxy', 'width', 'mailer', 'smtp', 'status', 'borrowers', 'confirm', 'itemWindowHeight', 'from', 'useRelativePaths', 'toolbarPosition', 'transform', 'itemWindowWidth', 'player', 'height', 'listBgPicture', 'emails', 'splash' ); my @specificOptions = ( 'sortOrder', 'details', 'sortField', 'plugin', 'multisite', ); foreach (@commonOptions) { (my $gcfilmsOption = $_) =~ s/item/movie/; my $value = $options->$gcfilmsOption; $value =~ s|
|
|gm; $self->$_($value); } my $newOptions = $self->{modelsFactory}->getModel('GCfilms')->{preferences}; foreach (@specificOptions) { $newOptions->$_($options->$_); } # Special processing for order -> layout my $layout = 'form'; my $order = $options->order; $layout = 'compact' if ($order == 1) || ($order == 2); $layout = 'readonly' if ($order == 3) || ($order == 4); $newOptions->layout($layout); $newOptions->save; } sub importGCfilmsData { my ($self, $options) = @_; $self->{parent}->importWithDetect($options->file, 1); $self->{options}->{file} = $ENV{GCS_DATA_HOME}.'/films.gcs'; $self->{parent}->{items}->save($self->{parent}); #$self->{parent}->setFileName($self->{options}->{file}); $self->{parent}->refreshTitle; } } { package GCOptionsDialog; use Glib::Object::Subclass Gtk2::Dialog:: ; @GCOptionsDialog::ISA = ('GCModalDialog'); use GCPlugins; use GCLang; use GCStyle; use GCMail; sub on_destroy { my ($widget, $self) = @_; return 1; } sub initValues { my $self = shift; $self->{viewChanged} = 0; $self->{viewOptionsChanged} = 0; $self->{expert}->set_active($self->{options}->expert); if ($self->{options}->programs eq 'system') { $self->{systemPrograms}->set_active(1); } else { $self->{userPrograms}->set_active(1); } $self->{defineProgramsButton}->lock($self->{systemPrograms}->get_active); $self->{browser} = $self->{options}->browser; $self->{player} = $self->{options}->player; $self->{audio} = $self->{options}->audio; $self->{imageEditor} = $self->{options}->imageEditor; $self->{cdDevice}->setValue($self->{options}->cdDevice); $self->{images}->setValue($self->{options}->images); $self->{confirm}->set_active($self->{options}->confirm); $self->{autosave}->set_active($self->{options}->autosave); $self->{autoload}->set_active(! $self->{options}->noautoload); $self->{splash}->set_active($self->{options}->splash); $self->{tearoffMenus}->set_active($self->{options}->tearoffMenus); $self->{options}->spellCheck(1) if ! $self->{options}->exists('spellCheck'); $self->{spellCheck}->set_active($self->{options}->spellCheck) if $self->{spellCheck}; $self->{useRelativePaths}->set_active($self->{options}->useRelativePaths); $self->{useStars}->set_active($self->{options}->useStars); $self->{proxycb}->set_active($self->{options}->proxy); $self->{proxyurl}->set_text($self->{options}->proxy); $self->{cookieJarcb}->set_active($self->{options}->cookieJar); $self->{cookieJarPath}->setValue($self->{options}->cookieJar); $self->{transform}->set_active($self->{options}->transform); $self->{articles}->set_text($self->{options}->articles); if ($self->{options}->useTitleForPics) { $self->{picturesNameTitle}->set_active(1); } else { $self->{picturesNameAuto}->set_active(1); } $self->{options}->columns(3) if ! $self->{options}->exists('columns'); $self->{columns} = $self->{options}->columns; $self->{options}->resizeImgList(0) if ! $self->{options}->exists('resizeImgList'); $self->{resizeImgList} = $self->{options}->resizeImgList; $self->{options}->animateImgList(1) if ! $self->{options}->exists('animateImgList'); $self->{animateImgList} = $self->{options}->animateImgList; $self->{options}->toolbar(3) if ! $self->{options}->exists('toolbar'); $self->{toolbarOption}->setValue($self->{options}->toolbar); $self->{options}->toolbarPosition(0) if ! $self->{options}->exists('toolbarPosition'); $self->{toolbarPositionOption}->setValue($self->{options}->toolbarPosition); $self->{options}->expandersMode('cut') if ! $self->{options}->exists('expandersMode'); $self->{expandersMode}->setValue($self->{options}->expandersMode); $self->{dateFormat}->setValue($self->{options}->dateFormat) if $self->{dateFormat}; $self->{options}->view(0) if ! $self->{options}->exists('view'); $self->{viewOption}->setValue($self->{options}->view); $self->{model}->{preferences}->plugin('ask') if ! $self->{model}->{preferences}->exists('plugin'); $self->{pluginOption}->setValue($self->{model}->{preferences}->plugin); $self->{askImport}->set_active($self->{options}->askImport); $self->{searchStop}->set_active($self->{options}->searchStop); $self->{bigPics}->set_active($self->{options}->bigPics); $self->{langOption}->setValue($self->{options}->lang); $self->{styleOption}->setValue($self->{options}->style); $self->{layoutOption}->setValue($self->{model}->{preferences}->layout); $self->{panelStyleOption}->setValue($self->{options}->panelStyle); $self->{options}->mailer('Sendmail') if ! $self->{options}->exists('mailer'); $self->{mailerOption}->setValue($self->{options}->mailer); $self->{from}->set_text($self->{options}->from); # Picture size for image mode $self->{options}->listImgSize(2) if ! $self->{options}->exists('listImgSize'); $self->{listImgSize} = $self->{options}->listImgSize; $self->{options}->listImgSkin($GCStyle::defaultList) if ! $self->{options}->exists('listImgSkin'); $self->{listImgSkin} = $self->{options}->listImgSkin; $self->{options}->listBgColor('65535,65535,65535') if ! $self->{options}->exists('listBgColor'); $self->{options}->listFgColor('0,0,0') if ! $self->{options}->exists('listFgColor'); $self->{mlbg} = $self->{options}->listBgColor; $self->{mlfg} = $self->{options}->listFgColor; $self->{useOverlays} = $self->{options}->useOverlays; $self->{listBgPicture} = $self->{options}->listBgPicture; $self->{proxyurl}->set_editable(0) if ! $self->{proxycb}->get_active; $self->{proxyurl}->set_editable(1) if $self->{proxycb}->get_active; $self->{cookieJarPath}->lock(1) if ! $self->{cookieJarcb}->get_active; $self->{cookieJarPath}->lock(0) if $self->{cookieJarcb}->get_active; $self->{historysize}->set_value($self->{options}->historysize); # Picture size for detailed mode $self->{options}->detailImgSize($self->{options}->listImgSize) if ! $self->{options}->exists('detailImgSize'); $self->{model}->{preferences}->details($self->{model}->{commonFields}->{title}) if ! $self->{model}->{preferences}->exists('details'); $self->{details} = $self->{model}->{preferences}->details; $self->{detailImgSize} = $self->{options}->detailImgSize; $self->{groupBy} = $self->{model}->{preferences}->groupBy; $self->{secondarySort} = $self->{model}->{preferences}->secondarySort; $self->{groupedFirst} = $self->{model}->{preferences}->groupedFirst; $self->{addCount} = $self->{model}->{preferences}->addCount; } sub saveValues { my $self = shift; $self->{options}->expert(($self->{expert}->get_active) ? 1 : 0); $self->{options}->programs(($self->{systemPrograms}->get_active) ? 'system' : 'user'); $self->{options}->browser($self->{browser}); $self->{options}->player($self->{player}); $self->{options}->audio($self->{audio}); $self->{options}->imageEditor($self->{imageEditor}); $self->{options}->cdDevice($self->{cdDevice}->getValue); $self->{options}->images($self->{images}->getValue); $self->{options}->confirm(($self->{confirm}->get_active) ? 1 : 0); $self->{options}->autosave(($self->{autosave}->get_active) ? 1 : 0); $self->{options}->noautoload(($self->{autoload}->get_active) ? 0 : 1); $self->{options}->splash(($self->{splash}->get_active) ? 1 : 0); $self->{options}->tearoffMenus(($self->{tearoffMenus}->get_active) ? 1 : 0); $self->{options}->spellCheck(($self->{spellCheck}->get_active) ? 1 : 0) if $self->{spellCheck}; $self->{options}->useStars(($self->{useStars}->get_active) ? 1 : 0); $self->{options}->useRelativePaths(($self->{useRelativePaths}->get_active) ? 1 : 0); $self->{options}->useTitleForPics(($self->{picturesNameTitle}->get_active) ? 1 : 0); $self->{options}->transform(($self->{transform}->get_active) ? 1 : 0); $self->{options}->articles($self->{articles}->get_text); if ($self->{proxycb}->get_active) { $self->{options}->proxy($self->{proxyurl}->get_text); } else { $self->{options}->proxy(''); } if ($self->{cookieJarcb}->get_active) { $self->{options}->cookieJar($self->{cookieJarPath}->getValue); } else { $self->{options}->cookieJar(''); } $self->{options}->lang($self->{langOption}->getValue); $self->{options}->style($self->{styleOption}->getValue); $self->{model}->{preferences}->layout($self->{layoutOption}->getValue); $self->{options}->panelStyle($self->{panelStyleOption}->getValue); $self->{options}->toolbar($self->{toolbarOption}->getValue); $self->{options}->toolbarPosition($self->{toolbarPositionOption}->getValue); $self->{options}->expandersMode($self->{expandersMode}->getValue); $self->{options}->dateFormat($self->{dateFormat}->getValue) if $self->{dateFormat}; my $currentView = $self->{options}->view; $self->{options}->view($self->{viewOption}->getValue); if (($currentView != $self->{options}->view) || ($self->{viewOptionsChanged})) { $self->{parent}->setItemsList(0, 1); $self->{viewChanged} = 1; } $self->{model}->{preferences}->plugin($self->{pluginOption}->getValue); $self->{options}->askImport(($self->{askImport}->get_active) ? 1 : 0); $self->{options}->searchStop(($self->{searchStop}->get_active) ? 1 : 0); $self->{options}->bigPics(($self->{bigPics}->get_active) ? 1 : 0); #$self->{options}->alwaysOriginal(($self->{alwaysOriginal}->get_active) ? 1 : 0); $self->{options}->mailer($self->{mailerOption}->getValue); $self->{options}->smtp($self->{smtp}->get_text); $self->{options}->from($self->{from}->get_text); $self->{parent}->checkImagesDirectory(1); $self->{options}->historysize($self->{historysize}->get_value); $self->{parent}->{menubar}->{menuHistoryItem}->remove_submenu(); $self->{parent}->{menubar}->{menuHistory} = Gtk2::Menu->new(); $self->{parent}->{menubar}->addHistoryMenu(); #$self->{model}->{preferences}->details($self->{details}); $self->{options}->save; } sub checkValues { my $self = shift; return $self->{parent}->{lang}->{OptionsPicturesWorkingDirError} if $self->{images}->getValue =~ /.%WORKING_DIR%/; return undef; } sub activateInternetOptions { my ($self, $value) = @_; $self->{dataGroupLabel}->set_sensitive($value); $self->{pluginLabel}->set_sensitive($value); $self->{pluginOption}->set_sensitive($value); $self->{pluginList}->set_sensitive($value); $self->{askImport}->set_sensitive($value); $self->{searchStop}->set_sensitive($value); $self->{bigPics}->set_sensitive($value); } sub show_all { my $self = shift; $self->SUPER::show_all; $self->{hboxImages}->hide; $self->{hboxDetails}->hide; $self->{hboxSMTP}->hide if $self->{mailerOption}->getValue ne 'SMTP'; if ($self->{expert}->get_active) { $self->{hboxImages}->show_all if ($self->{options}->view == 1); $self->{hboxDetails}->show_all if ($self->{options}->view == 2); } else { # Toolbar and status bar $self->{labelToolbar}->hide_all; $self->{toolbarOption}->hide_all; $self->{labelToolbarPosition}->hide_all; $self->{toolbarPositionOption}->hide_all; $self->{labelExpandersMode}->hide_all; $self->{expandersMode}->hide_all; if ($self->{dateFormat}) { $self->{labelDateFormat}->hide_all; $self->{dateFormat}->hide_all; } $self->{useStars}->hide_all; # CD Device $self->{cdDeviceLabel}->hide_all; $self->{cdDevice}->hide_all; # Pictures $self->{picturesNameFormat}->hide_all; $self->{picturesNameAuto}->hide_all; $self->{picturesNameTitle}->hide_all; $self->{useRelativePaths}->hide_all; # Internet searches $self->{searchStop}->hide_all; # Internet access $self->{proxycb}->hide_all; $self->{proxyurl}->hide_all; $self->{cookieJarcb}->hide_all; $self->{cookieJarPath}->hide_all; $self->{mailerLabel}->hide_all; $self->{mailerOption}->hide_all; $self->{hboxSMTP}->hide_all; $self->{hboxMua}->hide_all; # Features $self->{tearoffMenus}->hide_all; $self->{autoload}->hide_all; $self->{OptionsRestoreAccelerators}->hide_all; # History $self->{fileHistoryLabel}->hide_all; $self->{labelHistorysize}->hide_all; $self->{historysize}->hide_all; $self->{buttonClearHistory}->hide_all; } $self->{allShown} = 1; $self->{layoutOption}->signal_emit('changed'); } sub show { my $self = shift; my $tabToShow= shift; $self->initValues; $self->show_all if !$self->{allShown}; $self->{optionstabs}->set_current_page ($tabToShow) if $tabToShow; $self->activateInternetOptions(! $self->{model}->isPersonal); $self->{hboxSMTP}->hide if $self->{options}->mailer ne 'SMTP'; $self->{pluginList}->hide if (($self->{model}->{preferences}->plugin ne 'multi') && ($self->{model}->{preferences}->plugin ne 'multiperfield') && ($self->{model}->{preferences}->plugin ne 'multiask')); while (1) { my $code = $self->run; last if $code ne 'ok'; my $errorMessage = $self->checkValues; if (!$errorMessage) { $self->saveValues; last; } else { my $dialog = Gtk2::MessageDialog->new_with_markup($self->{parent}, [qw/modal destroy-with-parent/], 'error', 'ok', $errorMessage); $dialog->run; $dialog->destroy; next; } } $self->hide; } sub changeDetails { my $self = shift; my $parent = $self->{parent}; my @tmpOptionsArray = split m/\|/, $self->{details}; my $fieldsDialog = new GCDetailedOptionsDialog($self, \@tmpOptionsArray); $fieldsDialog->show; $fieldsDialog->destroy; } sub setModel { my ($self, $model) = @_; $self->{model} = $model; my @plugins = map {{value => $_, displayed => $_}} @{$model->getPluginsNames}; unshift @plugins, ( {value => 'ask', displayed => $self->{parent}->{lang}->{OptionsAskPlugins}}, {value => 'multiask', displayed => $self->{parent}->{lang}->{OptionsPluginsMultiAsk}}, {value => 'multi', displayed => $self->{parent}->{lang}->{OptionsPluginsMulti}}, {value => 'multiperfield', displayed => $self->{parent}->{lang}->{OptionsPluginsMultiPerField}}, ); $self->{pluginOption}->setValues(\@plugins); my @panels = map {{value => $_, displayed => $model->getDisplayedText($model->{panels}->{$_}->{label})}} @{$model->{panelsNames}}; $self->{layoutOption}->setValues(\@panels); } sub initMailerOption { my $self = shift; use locale; my @mailers = ({value => 'Sendmail', displayed => 'Sendmail'}, {value => 'SMTP', displayed => 'SMTP'}); my $mailPrograms = GCMail::getMailers; foreach (sort keys %{$mailPrograms}) { push @mailers, {value => $_, displayed => $_}; } $self->{mailerOption}->setValues(\@mailers, 2); } sub new { my ($proto, $parent, $options) = @_; my $class = ref($proto) || $proto; my $self = $class->SUPER::new($parent, $parent->{lang}->{OptionsTitle}, ); bless ($self, $class); $self->{allShown} = 0; $self->set_has_separator(0); $options = $parent->{options} if !$options; $self->{options} = $options; $self->{parent} = $parent; $self->{lang} = $parent->{lang}; $self->{tooltips} = $parent->{tooltips}; ################ # Main options ################ my $tableMain = new Gtk2::Table(3,2,0); $tableMain->set_row_spacings($GCUtils::halfMargin); $tableMain->set_col_spacings($GCUtils::margin); $tableMain->set_border_width($GCUtils::margin); my $labelLang = new GCLabel($parent->{lang}->{OptionsLang}); $self->{langOption} = new GCMenuList; my @langValues; push @langValues, {value => $_, displayed => $GCLang::langs{$_}->{LangName}} foreach (keys %GCLang::langs); @langValues = sort {$a->{displayed} cmp $b->{displayed}} @langValues; $self->{langOption}->setValues(\@langValues); $tableMain->attach($labelLang, 0, 1, 1, 2, 'fill', 'fill', 0, 0); $tableMain->attach($self->{langOption}, 1, 2, 1, 2, 'fill', 'fill', 0, 0); my $labelStyle = new GCLabel($parent->{lang}->{OptionsStyle}); $self->{styleOption} = new GCMenuList; my @styleValues; push @styleValues, {value => $_, displayed => $_} foreach (sort keys %GCStyle::styles); $self->{styleOption}->setValues(\@styleValues); $tableMain->attach($labelStyle, 0, 1, 2, 3, 'fill', 'fill', 0, 0); $tableMain->attach($self->{styleOption}, 1, 2, 2, 3, 'fill', 'fill', 0, 0); $self->{tearoffMenus} = new Gtk2::CheckButton($parent->{lang}->{OptionsTearoffMenus}); $self->{tearoffMenus}->set_active($options->tearoffMenus); $self->{tearoffMenus}->set_active(1) if (! $options->exists('tearoffMenus')); $tableMain->attach($self->{tearoffMenus}, 0, 2, 3, 4, 'fill', 'fill', 0, 0); my $labelWarning = new Gtk2::Label; $labelWarning->set_markup(''.$parent->{lang}->{OptionsWarning}.''); $labelWarning->set_use_underline(1); $labelWarning->set_line_wrap(1); $labelWarning->set_justify('center'); my $vboxMain = new Gtk2::VBox(0,0); $vboxMain->set_border_width(20); $vboxMain->pack_start($tableMain,1,1,0); #$vboxMain->pack_start(Gtk2::HSeparator->new,1,1,10); $vboxMain->pack_start($labelWarning,1,1,0); ################## # Display options ################## my $tableDisplay = new Gtk2::Table(10, 6, 0); $tableDisplay->set_row_spacings($GCUtils::halfMargin); $tableDisplay->set_col_spacings($GCUtils::margin); $tableDisplay->set_border_width($GCUtils::margin); my $labelDisplayInformationGroup = new GCHeaderLabel($parent->{lang}->{OptionsDisplayInformationGroup}); $tableDisplay->attach($labelDisplayInformationGroup, 0, 6, 0, 1, 'fill', 'fill', 0, 0); my $labelView = new GCLabel($parent->{lang}->{OptionsView}); my %views = %{$parent->{lang}->{OptionsViews}}; $self->{viewOption} = new GCMenuList; my @viewsOptions = map {{value => $_, displayed => $views{$_}}} (sort keys %views); $self->{viewOption}->setValues(\@viewsOptions); $tableDisplay->attach($labelView, 2, 3, 1, 2, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{viewOption}, 3, 4, 1, 2, 'fill', 'fill', 0, 0); $self->{hboxImages} = new Gtk2::HBox(0,0); $self->{imagesButton} = new Gtk2::Button($parent->{lang}->{ImagesOptionsButton}); $self->{imagesButton}->signal_connect('clicked', sub { $self->{imagesOptionsDialog} = new GCImagesOptionsDialog($self) if ! $self->{imagesOptionsDialog}; $self->{imagesOptionsDialog}->show; }); $self->{hboxImages}->pack_start($self->{imagesButton}, 0, 0, 0); $self->{hboxDetails} = new Gtk2::HBox(0,0); $self->{buttonDetails} = new Gtk2::Button($parent->{lang}->{ImagesOptionsButton}); $self->{buttonDetails}->signal_connect('clicked' => sub { $self->changeDetails; }); $self->{hboxDetails}->pack_start($self->{buttonDetails}, 0, 0, 0); $self->{viewOption}->signal_connect('changed' => sub { my $i = $self->{viewOption}->getValue; $self->{hboxImages}->hide; $self->{hboxDetails}->hide; if ($self->{expert}->get_active) { $self->{hboxImages}->show_all if ($i == 1); $self->{hboxDetails}->show_all if ($i == 2); } }); $tableDisplay->attach($self->{hboxImages}, 4, 6, 1, 2, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{hboxDetails}, 4, 6, 1, 2, 'fill', 'fill', 0, 0); my $labelLayout = new GCLabel($parent->{lang}->{OptionsLayout}); $self->{layoutOption} = new GCMenuList; $self->{layoutOption}->signal_connect('changed' => sub { my $panelName = $self->{layoutOption}->getValue; my $readonly = ($self->{model}->{panels}->{$panelName}->{editable} eq 'false'); if ($readonly) { $self->{labelPanelStyle}->show; $self->{panelStyleOption}->show; } else { $self->{labelPanelStyle}->hide; $self->{panelStyleOption}->hide; } }); $tableDisplay->attach($labelLayout, 2, 3, 2, 3, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{layoutOption}, 3, 4, 2, 3, 'fill', 'fill', 0, 0); $self->{labelPanelStyle} = new GCLabel($parent->{lang}->{OptionsStyle}); $self->{panelStyleOption} = new GCMenuList; my @panelStyles = map {{value => $_, displayed => $_}} (sort @GCStyle::readOnlyStyles); $self->{panelStyleOption}->setValues(\@panelStyles); $tableDisplay->attach($self->{labelPanelStyle}, 4, 5, 2, 3, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{panelStyleOption}, 5, 6, 2, 3, ['fill', 'expand'], 'fill', 0, 0); $self->{labelToolbar} = new GCLabel($parent->{lang}->{OptionsToolbar}); $self->{toolbarOption} = new GCMenuList; my %toolbars = %{$parent->{lang}->{OptionsToolbars}}; my @toolbarValues = map {{value => $_, displayed => $toolbars{$_}}} (sort keys %toolbars); $self->{toolbarOption}->setValues(\@toolbarValues); $tableDisplay->attach($self->{labelToolbar}, 2, 3, 3, 4, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{toolbarOption}, 3, 4, 3, 4, 'fill', 'fill', 0, 0); $self->{labelToolbarPosition} = new GCLabel($parent->{lang}->{OptionsToolbarPosition}); $self->{toolbarPositionOption} = new GCMenuList; my %toolbarPositions = %{$parent->{lang}->{OptionsToolbarPositions}}; my @positionValues = map {{value => $_, displayed => $toolbarPositions{$_}}} (sort keys %toolbarPositions); $self->{toolbarPositionOption}->setValues(\@positionValues); $tableDisplay->attach($self->{labelToolbarPosition}, 4, 5, 3, 4, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{toolbarPositionOption}, 5, 6, 3, 4, ['fill', 'expand'], 'fill', 0, 0); $self->{labelExpandersMode} = new GCLabel($parent->{lang}->{OptionsExpandersMode}); $self->{expandersMode} = new GCMenuList; my %expandersModes = %{$parent->{lang}->{OptionsExpandersModes}}; my @ExpandersModeValues = map {{value => $_, displayed => $expandersModes{$_}}} (sort keys %expandersModes); $self->{expandersMode}->setValues(\@ExpandersModeValues); $tableDisplay->attach($self->{labelExpandersMode}, 2, 3, 4, 5, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{expandersMode}, 3, 4, 4, 5, 'fill', 'fill', 0, 0); $self->{useStars} = new Gtk2::CheckButton($parent->{lang}->{OptionsUseStars}); $tableDisplay->attach($self->{useStars}, 4, 6, 4, 5, ['expand', 'fill'], 'fill', 0, 0); if ($GCUtils::hasTimeConversion) { $self->{labelDateFormat} = new GCLabel($parent->{lang}->{OptionsDateFormat}); $self->{dateFormat} = new GCShortText; $self->{dateFormat}->set_width_chars(10); $self->{tooltips}->set_tip($self->{dateFormat}, $parent->{lang}->{OptionsDateFormatTooltip}); $tableDisplay->attach($self->{labelDateFormat}, 2, 3, 5, 6, 'fill', 'fill', 0, 0); $tableDisplay->attach($self->{dateFormat}, 3, 6, 5, 6, 'fill', 'fill', 0, 0); } my $labelDisplayArticlesGroup = new GCHeaderLabel($parent->{lang}->{OptionsDisplayArticlesGroup}); $tableDisplay->attach($labelDisplayArticlesGroup, 0, 6, 7, 8, 'fill', 'fill', 0, 0); $self->{transform} = new Gtk2::CheckButton($parent->{lang}->{OptionsTransform}); $tableDisplay->attach($self->{transform}, 2, 6, 8, 9, 'fill', 'fill', 0, 0); my $labelArticles = new GCLabel($parent->{lang}->{OptionsArticles}); $tableDisplay->attach($labelArticles, 2, 4, 9, 10, 'fill', 'fill', 0, 0); $self->{articles} = new Gtk2::Entry; $self->{articles}->set_width_chars(10); $tableDisplay->attach($self->{articles}, 4, 6, 9, 10, ['expand', 'fill'], 'fill', 0, 0); $options->articles('le,la,les,l,un,une,des,a,the') if (! $options->exists('articles')); my $vboxDisplay = new Gtk2::VBox(0,0); $vboxDisplay->set_border_width(0); $vboxDisplay->pack_start($tableDisplay, 0, 0, 0); ################# # Paths options ################# my $vboxPath = new Gtk2::VBox(0,0); my $tablePath = new Gtk2::Table(14, 4, 0); my $pathRow = -1; $tablePath->set_row_spacings($GCUtils::halfMargin); $tablePath->set_col_spacings($GCUtils::margin); $tablePath->set_border_width($GCUtils::margin); my $labelProgramsGroup = new GCHeaderLabel($parent->{lang}->{OptionsPathProgramsGroup}); $pathRow++; $tablePath->attach($labelProgramsGroup, 0, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $self->{systemPrograms} = new Gtk2::RadioButton(undef, $parent->{lang}->{OptionsProgramsSystem}); $pathRow++; $tablePath->attach($self->{systemPrograms}, 2, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $self->{programTypeGroup} = $self->{systemPrograms}->get_group; $self->{userPrograms} = new Gtk2::RadioButton($self->{programTypeGroup}, $parent->{lang}->{OptionsProgramsUser}); $self->{defineProgramsButton} = new GCButton($parent->{lang}->{OptionsProgramsSet}); $self->{defineProgramsButton}->signal_connect('clicked' => sub { $self->{programsDialog} = new GCProgramsOptionsDialog($self) if ! $self->{programsDialog}; $self->{programsDialog}->show; }); my $hboxDefinePrograms = new Gtk2::HBox(0,0); $hboxDefinePrograms->pack_start($self->{userPrograms}, 0, 0, 0); $hboxDefinePrograms->pack_start($self->{defineProgramsButton}, 0, 0, 2*$GCUtils::margin); $pathRow++; $tablePath->attach($hboxDefinePrograms, 2, 4, $pathRow, $pathRow + 1, 'fill', [], 0, 0); $self->{userPrograms}->signal_connect('toggled' => sub { $self->{defineProgramsButton}->lock(! $self->{userPrograms}->get_active); }); $self->{cdDeviceLabel} = new GCLabel($parent->{lang}->{OptionsCdDevice}); $self->{cdDevice} = new GCFile($self, $self->{parent}->{lang}->{FileChooserOpenDirectory}, 'select-folder'); $pathRow++; $tablePath->attach($self->{cdDeviceLabel}, 2, 3, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $tablePath->attach($self->{cdDevice}, 3, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $self->{labelImagesGroup} = new GCHeaderLabel($parent->{lang}->{OptionsPathImagesGroup}); $pathRow += 2; $tablePath->attach($self->{labelImagesGroup}, 0, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $self->{labelImages} = new GCLabel($parent->{lang}->{OptionsImages}); $pathRow++; $tablePath->attach($self->{labelImages}, 2, 3, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $self->{images} = new GCFile($self, $self->{parent}->{lang}->{FileChooserOpenDirectory}, 'select-folder', 0, $GCOptions::DEFAULT_IMG_DIR); $self->{images}->setWidth(40); $tablePath->attach($self->{images}, 3, 4, $pathRow, $pathRow + 1, ['expand', 'fill'], 'fill', 0, 0); $self->{labelPicturesWorkingDir} = new GCLabel($parent->{lang}->{OptionsPicturesWorkingDir}); $pathRow++; $tablePath->attach($self->{labelPicturesWorkingDir}, 2, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 2*$GCUtils::margin, 0); $self->{labelPicturesFileBase} = new GCLabel($parent->{lang}->{OptionsPicturesFileBase}); $pathRow++; $tablePath->attach($self->{labelPicturesFileBase}, 2, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 2*$GCUtils::margin, 0); $self->{picturesNameFormat} = new GCLabel($parent->{lang}->{OptionsPicturesFormat}); $pathRow += 2; $tablePath->attach($self->{picturesNameFormat}, 2, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $self->{picturesNameAuto} = new Gtk2::RadioButton(undef, $parent->{lang}->{OptionsPicturesFormatInternal}); $pathRow++; $tablePath->attach($self->{picturesNameAuto}, 2, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 2*$GCUtils::margin, 0); $self->{picturesNameGroup} = $self->{picturesNameAuto}->get_group; $self->{picturesNameTitle} = new Gtk2::RadioButton($self->{picturesNameGroup}, $parent->{lang}->{OptionsPicturesFormatTitle}); $pathRow++; $tablePath->attach($self->{picturesNameTitle}, 2, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 2*$GCUtils::margin, 0); $self->{useRelativePaths} = new Gtk2::CheckButton($parent->{lang}->{OptionsUseRelativePaths}); $self->{useRelativePaths}->set_active($options->useRelativePaths); $self->{useRelativePaths}->set_active(0) if (! $options->exists('useRelativePaths')); $pathRow++; $tablePath->attach($self->{useRelativePaths}, 2, 4, $pathRow, $pathRow + 1, 'fill', 'fill', 0, 0); $vboxPath->pack_start($tablePath, 0, 0, 0); ################### # Internet options ################### my $tableInternet = new Gtk2::Table(12, 5, 0); $tableInternet->set_row_spacings($GCUtils::halfMargin); $tableInternet->set_col_spacings($GCUtils::margin); $tableInternet->set_border_width($GCUtils::margin); $self->{dataGroupLabel} = new GCHeaderLabel($parent->{lang}->{OptionsInternetDataGroup}); $tableInternet->attach($self->{dataGroupLabel}, 0, 5, 0, 1, 'fill', 'fill', 0, 0); $self->{pluginLabel} = new GCLabel($parent->{lang}->{OptionsPlugins}); $self->{pluginOption} = new GCMenuList; $self->{pluginList} = new Gtk2::Button($parent->{lang}->{OptionsPluginsList}); $self->{pluginList}->signal_connect('clicked' => sub { $parent->getDialog('MultiSite')->show if (($self->{pluginOption}->getValue eq 'multi') || ($self->{pluginOption}->getValue eq 'multiask')); $parent->getDialog('MultiSitePerField')->show if (($self->{pluginOption}->getValue eq 'multiperfield')); }); $self->{pluginOption}->signal_connect('changed' => sub { if (($self->{pluginOption}->getValue eq 'multi') || ($self->{pluginOption}->getValue eq 'multiask') || ($self->{pluginOption}->getValue eq 'multiperfield')) { $self->{pluginList}->show; } else { $self->{pluginList}->hide; } }); $self->{askImport} = new Gtk2::CheckButton($parent->{lang}->{OptionsAskImport}); $tableInternet->attach($self->{pluginLabel}, 2, 3, 1, 2, 'fill', 'fill', 0, 0); $tableInternet->attach($self->{pluginOption}, 3, 4, 1, 2, 'fill', 'fill', 0, 0); $tableInternet->attach($self->{pluginList}, 4, 5, 1, 2, 'fill', 'fill', 20, 0); $tableInternet->attach($self->{askImport}, 2, 5, 2, 3, 'fill', 'fill', 0, 0); $self->{bigPics} = new Gtk2::CheckButton($parent->{lang}->{OptionsBigPics}); $tableInternet->attach($self->{bigPics}, 2, 5, 3, 4, 'fill', 'fill', 0, 0); $self->{searchStop} = new Gtk2::CheckButton($parent->{lang}->{OptionsSearchStop}); $tableInternet->attach($self->{searchStop}, 2, 5, 4, 5, 'fill', 'fill', 0, 0) if ($^O !~ /win32/i); my $settingsGroupLabel = new GCHeaderLabel($parent->{lang}->{OptionsInternetSettingsGroup}); $tableInternet->attach($settingsGroupLabel, 0, 5, 6, 7, 'fill', 'fill', 0, 0); $self->{proxycb} = new Gtk2::CheckButton($parent->{lang}->{OptionsProxy}); $self->{proxycb}->set_active($options->proxy); $self->{proxyurl} = new Gtk2::Entry; $self->{proxyurl}->set_text($options->proxy); $self->{proxycb}->signal_connect('clicked' => sub { if ($self->{proxycb}->get_active) { $self->{proxyurl}->set_editable(1); } else { $self->{proxyurl}->set_editable(0); } }); $tableInternet->attach($self->{proxycb}, 2, 3, 7, 8, 'fill', 'fill', 0, 0); $tableInternet->attach($self->{proxyurl}, 3, 4, 7, 8, 'fill', 'shrink', 0, 0); $self->{cookieJarcb} = new Gtk2::CheckButton($parent->{lang}->{OptionsCookieJar}); $self->{cookieJarcb}->set_active($options->cookieJar); $self->{cookieJarcb}->signal_connect('clicked' => sub { if ($self->{cookieJarcb}->get_active) { $self->{cookieJarPath}->lock(0); } else { $self->{cookieJarPath}->lock(1); } }); $tableInternet->attach($self->{cookieJarcb}, 2, 3, 8, 9, 'fill', 'fill', 0, 0); $self->{cookieJarPath} = new GCFile($self, $self->{parent}->{lang}->{OptionsCookieJar}, 'open', 0 ); $tableInternet->attach($self->{cookieJarPath}, 3, 4, 8, 9, 'fill', 'fill', 0, 0); my $labelFrom = new GCLabel($self->{parent}->{lang}->{OptionsFrom}); $self->{from} = new Gtk2::Entry; $tableInternet->attach($labelFrom, 2, 3, 9, 10, 'fill', 'fill', 0, 0); $tableInternet->attach($self->{from}, 3, 4, 9, 10, 'fill', 'fill', 0, 0); $self->{mailerLabel} = new GCLabel($parent->{lang}->{OptionsMailer}); $self->{mailerOption} = new GCMenuList; $self->initMailerOption; $tableInternet->attach($self->{mailerLabel}, 2, 3, 10, 11, 'fill', 'fill', 0, 0); $tableInternet->attach($self->{mailerOption}, 3, 4, 10, 11, 'fill', 'fill', 0, 0); $self->{hboxSMTP} = new Gtk2::HBox(0,0); my $SMTPLabel = new GCLabel($parent->{lang}->{OptionsSMTP}); $self->{smtp} = new Gtk2::Entry; $self->{smtp}->set_text($options->smtp); $self->{smtp}->set_width_chars(20); $self->{hboxSMTP}->pack_start($SMTPLabel,0,0,0); $self->{hboxSMTP}->pack_start($self->{smtp},0,0,5); $tableInternet->attach($self->{hboxSMTP}, 4, 5, 10, 11, 'fill', 'fill', 0, 0); $self->{mailerOption}->signal_connect('changed' => sub { if ('SMTP' eq $self->{mailerOption}->getValue) { $self->{hboxSMTP}->show; } else { $self->{hboxSMTP}->hide; } }); my $mailersButton = new GCButton($parent->{lang}->{OptionsConfigureMailers}); $self->{hboxMua} = new Gtk2::HBox(0,0); $self->{hboxMua}->pack_start($mailersButton,0,0,0); $tableInternet->attach($self->{hboxMua}, 2, 4, 11, 12, 'fill', 'fill', 0, 0); $mailersButton->signal_connect('clicked' => sub { my $dialog = $self->{parent}->getDialog('MailPrograms'); $self->initMailerOption if $dialog->show; }); my $vboxInternet = new Gtk2::VBox(0,0); $vboxInternet->set_border_width(0); $vboxInternet->pack_start($tableInternet,0,0,0); ################### # Features options ################### my $vboxConvenience = new Gtk2::VBox(0,0); my $tableFeature = new Gtk2::Table(11, 5, 0); $tableFeature->set_row_spacings($GCUtils::halfMargin); $tableFeature->set_col_spacings($GCUtils::margin); $tableFeature->set_border_width($GCUtils::margin); $self->{confirm} = new Gtk2::CheckButton($parent->{lang}->{OptionsRemoveConfirm}); $self->{confirm}->set_active($options->confirm); $self->{autosave} = new Gtk2::CheckButton($parent->{lang}->{OptionsAutoSave}); $self->{autosave}->set_active($options->autosave); $self->{autoload} = new Gtk2::CheckButton($parent->{lang}->{OptionsAutoLoad}); $self->{autoload}->set_active(! $options->noautoload); $self->{splash} = new Gtk2::CheckButton($parent->{lang}->{OptionsSplash}); $self->{splash}->set_active($options->splash); $self->{splash}->set_active(1) if (! $options->exists('splash')); $self->{spellCheck} = 0; my $restoreAccelOffset = 0; if ($GCBaseWidgets::hasSpellChecker) { $self->{spellCheck} = new Gtk2::CheckButton($parent->{lang}->{OptionsSpellCheck}); $self->{spellCheck}->set_active($options->spellCheck); $restoreAccelOffset = 1; } $self->{OptionsRestoreAccelerators} = new Gtk2::Button($parent->{lang}->{OptionsRestoreAccelerators}); $self->{OptionsRestoreAccelerators}->signal_connect('clicked' => sub { $self->{parent}->{menubar}->restoreDefaultAccels; }); my $conveniencesLabel = new GCHeaderLabel($parent->{lang}->{OptionsFeaturesConveniencesGroup}); $tableFeature->attach($conveniencesLabel, 0, 4, 0, 1, 'fill', 'fill', 0, 0); $tableFeature->attach($self->{splash}, 2, 4, 1, 2, 'fill', 'fill', 0, 0); $tableFeature->attach($self->{confirm}, 2, 4, 2, 3, 'fill', 'fill', 0, 0); $tableFeature->attach($self->{autosave}, 2, 4, 3, 4, 'fill', 'fill', 0, 0); $tableFeature->attach($self->{autoload}, 2, 4, 4, 5, 'fill', 'fill', 0, 0); $tableFeature->attach($self->{spellCheck}, 2, 4, 5, 6, 'fill', 'fill', 0, 0) if $self->{spellCheck}; $tableFeature->attach($self->{OptionsRestoreAccelerators}, 2, 3, 5 + $restoreAccelOffset, 6 + $restoreAccelOffset, 'fill', 'fill', 0, 0); my $fileHistoryLabelText = $parent->{lang}->{MenuHistory}; $fileHistoryLabelText =~ s/_//g; $self->{fileHistoryLabel} = new GCHeaderLabel($fileHistoryLabelText); $tableFeature->attach($self->{fileHistoryLabel}, 0, 4, 9, 10, 'fill', 'fill', 0, 0); $self->{labelHistorysize} = new GCLabel($parent->{lang}->{OptionsHistory}); my $adjHistory = Gtk2::Adjustment->new(0, 1, 20, 1, 1, 0) ; $self->{historysize} = Gtk2::SpinButton->new($adjHistory, 0, 0); $self->{buttonClearHistory} = new Gtk2::Button($parent->{lang}->{OptionsClearHistory}); $self->{buttonClearHistory}->signal_connect('clicked' => sub { $self->{options}->history(''); }); $tableFeature->attach($self->{labelHistorysize}, 2, 3, 10, 11, 'fill', 'fill', 0, 0); $tableFeature->attach($self->{historysize}, 3, 4, 10, 11, 'fill', 'fill', 0, 0); $tableFeature->attach($self->{buttonClearHistory}, 2, 3, 11, 12, 'fill', 'fill', 0, 0); $vboxConvenience->pack_start($tableFeature,0,0,0); ################### # Tab Gesture Stuff ################### my $tabs = Gtk2::Notebook->new(); $tabs->set_name('GCOptionsTabs'); $tabs->set_tab_pos('left'); $tabs->set_show_border(0); my ($mainButton, $displayButton, $pathButton, $internetButton, $conveniencesButton); $mainButton = GCImageBox->new_from_stock('gtk-home', $parent->{lang}->{OptionsMain}); $displayButton = GCImageBox->new_from_stock('gtk-select-color', $parent->{lang}->{OptionsDisplay}); $pathButton = GCImageBox->new_from_stock('gtk-directory', $parent->{lang}->{OptionsPaths}); $internetButton = GCImageBox->new_from_stock('gtk-network', $parent->{lang}->{OptionsInternet}); $conveniencesButton = GCImageBox->new_from_stock('gtk-properties', $parent->{lang}->{OptionsConveniences}); $tabs->append_page_menu($vboxMain, $mainButton, Gtk2::Label->new($parent->{lang}->{OptionsMain})); $tabs->append_page_menu($vboxDisplay, $displayButton, Gtk2::Label->new($parent->{lang}->{OptionsDisplay})); $tabs->append_page_menu($vboxPath, $pathButton, Gtk2::Label->new($parent->{lang}->{OptionsPaths})); $tabs->append_page_menu($vboxInternet, $internetButton, Gtk2::Label->new($parent->{lang}->{OptionsInternet})); $tabs->append_page_menu($vboxConvenience, $conveniencesButton, Gtk2::Label->new($parent->{lang}->{OptionsConveniences})); $tabs->set_tab_label_packing ($vboxMain, 1, 0, 'start'); $tabs->set_tab_label_packing ($vboxDisplay, 1, 0, 'start'); $tabs->set_tab_label_packing ($vboxPath, 1, 0, 'start'); $tabs->set_tab_label_packing ($vboxInternet, 1, 0, 'start'); $tabs->set_tab_label_packing ($vboxConvenience, 1, 0, 'start'); $self->vbox->pack_start($tabs, 1, 1, 0); $self->{optionstabs}=$tabs; $self->{expert} = new Gtk2::CheckButton($parent->{lang}->{OptionsExpertMode}); $self->{expert}->signal_connect('toggled' => sub { $self->show_all; }); $self->{expert}->set_border_width($GCUtils::margin); $self->vbox->pack_start($self->{expert}, 0, 1, 0); $self->{lang} = $parent->{lang}; return $self; } } { # Class used to let user select images options package GCImagesOptionsDialog; use base "GCModalDialog"; use GCItemsLists::GCListOptions; sub show { my $self = shift; $self->{panel}->initValues; $self->show_all; my $code = $self->run; if ($code eq 'ok') { $self->{panel}->saveValues; $self->{parent}->{viewOptionsChanged} = 1; } $self->hide; } sub new { my ($proto, $parent) = @_; my $class = ref($proto) || $proto; my $self = $class->SUPER::new($parent, $parent->{lang}->{ImagesOptionsTitle}, ); $self->{panel} = new GCImagesOptionsPanel($parent->{model}->{preferences}, $parent->{parent}); $self->{parent} = $parent; $self->vbox->pack_start($self->{panel},1,1,0); bless ($self, $class); return $self; } } { # Class used to let user select detailed options package GCDetailedOptionsDialog; use base "GCModalDialog"; use GCItemsLists::GCListOptions; sub show { my $self = shift; $self->{panel}->initValues; $self->show_all; my $code = $self->run; if ($code eq 'ok') { $self->{panel}->saveValues; $self->{parent}->{viewOptionsChanged} = 1; } $self->hide; } sub new { my ($proto, $parent) = @_; my $class = ref($proto) || $proto; my $self = $class->SUPER::new($parent, $parent->{lang}->{DetailedOptionsTitle}, ); $self->{panel} = new GCDetailedOptionsPanel($parent->{model}->{preferences}, $parent->{parent}); $self->{parent} = $parent; $self->vbox->pack_start($self->{panel},1,1,0); bless ($self, $class); return $self; } } { # Class used to let user select program to run package GCProgramsOptionsDialog; use base "GCModalDialog"; sub initValues { my $self = shift; foreach (@{$self->{programs}}) { $self->{paths}->{$_}->setValue($self->{parent}->{$_}); } } sub saveValues { my $self = shift; foreach (@{$self->{programs}}) { $self->{parent}->{$_} = $self->{paths}->{$_}->getValue; } } sub show { my $self = shift; $self->initValues; $self->show_all; my $code = $self->run; if ($code eq 'ok') { $self->saveValues; } $self->hide; } sub new { my ($proto, $parent) = @_; my $class = ref($proto) || $proto; my $self = $class->SUPER::new($parent, $parent->{lang}->{OptionsProgramsSet}, ); $self->{programs} = ['browser', 'player', 'audio', 'imageEditor']; my $tablePath = new Gtk2::Table(scalar @{$self->{programs}} + 1, 4); $tablePath->set_row_spacings($GCUtils::halfMargin); $tablePath->set_col_spacings($GCUtils::margin); $tablePath->set_border_width($GCUtils::margin); $self->{labelPrograms} = new GCHeaderLabel($parent->{lang}->{OptionsPrograms}); $tablePath->attach($self->{labelPrograms}, 0, 4, 0, 1, 'fill', 'fill', 0, $GCUtils::halfMargin); my $line = 1; foreach my $program(@{$self->{programs}}) { my $label = new GCLabel($parent->{lang}->{'Options'.ucfirst($program)}); $tablePath->attach($label, 2, 3, $line, $line + 1, 'fill', 'fill', 0, 0); $self->{paths}->{$program} = new GCFile($parent, $parent->{lang}->{OptionsProgramTitle}); $self->{paths}->{$program}->setWidth(40); $tablePath->attach($self->{paths}->{$program}, 3, 4, $line, $line + 1, ['expand', 'fill'], 'fill', 0, 0); $line++; } $tablePath->show_all; $self->vbox->pack_start($tablePath,1,1,0); bless ($self, $class); return $self; } } { # Class used to let user select information to be displayed package GCDisplayOptionsDialog; use base "Gtk2::Dialog"; sub show { my $self = shift; $self->initValues; $self->show_all; my $code = $self->run; if ($code eq 'ok') { $self->saveValues; } $self->hide; } sub new { my ($proto, $parent) = @_; my $class = ref($proto) || $proto; my $self = $class->SUPER::new($parent->{lang}->{DisplayOptionsTitle}, $parent, [qw/modal destroy-with-parent/], @GCDialogs::okCancelButtons ); bless($self, $class); $self->{show} = {}; $self->{options} = $parent->{model}->{preferences}; $self->{parent} = $parent; $self->{lang} = $parent->{lang}; $self->set_default_size(-1,480); return $self; } sub createContent { my ($self, $model) = @_; $self->{options} = $model->{preferences}; if ($self->{tabs}) { $self->vbox->remove($self->{hboxActions}); $self->{hboxActions}->destroy; $self->vbox->remove($self->{tabs}); $self->{tabs}->destroy; } $self->{fieldsInfo} = $model->getDisplayedInfo; $self->{fields} = $model->getFieldsCopy; #Add special items if (! $model->isPersonal) { unshift @{$self->{fields}}, 'searchButton'; unshift @{$self->{fieldsInfo}->[0]->{items}}, {id => 'searchButton', label => $model->getDisplayedText('PanelSearchButton')}; } $self->createComponents; $self->initValues; } sub initValues { my $self = shift; $self->{show} = {}; foreach (@{$self->{fields}}) { my $isShown = 1; $isShown = 0 if ($self->{options}->hidden =~ m/\|$_\|/); $self->{show}->{$_} = $isShown; # Only set active if field exists. Works around problems caused trying # to open corrupted collections $self->{$_}->set_active($isShown) if exists $self->{$_}; } } sub saveValues { my $self = shift; $self->{show} = {}; my $hidden = '|'; foreach (@{$self->{fields}}) { my $isShown = 0; $isShown = 1 if $self->{$_}->get_active; $self->{show}->{$_} = $isShown; $hidden .= $_.'|' if !$isShown; } $self->{options}->hidden($hidden); $self->{options}->save; } sub selectAll { my $self = shift; foreach (@{$self->{fields}}) { $self->{$_}->set_active(1); } } sub initBox { my ($self, $box, $values) = @_; $box->set_border_width(2); foreach (@$values) { $self->{$_->{id}} = new Gtk2::CheckButton($_->{label}); $box->pack_start($self->{$_->{id}}, 0,0,5); } } sub createComponents { my $self = shift; $self->{tabs} = Gtk2::Notebook->new(); $self->{tabs}->set_border_width(12); foreach (@{$self->{fieldsInfo}}) { my $frame = new Gtk2::Frame(); $frame->set_shadow_type('none'); $frame->set_border_width($GCUtils::margin); $frame->set_label_align(1.0, 0.0); my $vbox = new Gtk2::VBox(0,0); $self->initBox($vbox, $_->{items}); my $scroll = new Gtk2::ScrolledWindow; $scroll->set_policy ('automatic', 'automatic'); $frame->add($scroll); $scroll->add_with_viewport($vbox); $scroll->set_shadow_type('none'); $scroll->child->set_shadow_type('none'); $self->{tabs}->append_page($frame, $_->{title}); } $self->{hboxActions} = new Gtk2::HBox(0,0); my $allButton = new Gtk2::Button($self->{lang}->{DisplayOptionsAll}); $allButton->signal_connect( clicked => sub { $self->selectAll; }); $self->{hboxActions}->pack_end($allButton,1,0,20); $self->vbox->pack_start($self->{tabs}, 1, 1, 2); $self->vbox->pack_start($self->{hboxActions}, 0, 0, 10); } } 1;