#! /usr/bin/perl

###################################################
#
#  Copyright (C) 2008-2013 Mario Kemper <mario.kemper@gmail.com>
#
#  This file is part of Shutter.
#
#  Shutter 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 3 of the License, or
#  (at your option) any later version.
#
#  Shutter 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 Shutter; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
#
###################################################

#perl -x -S perltidy -l=0 -b "%f"

#modules
#--------------------------------------
use utf8;
use strict;
use warnings;

#Gnome2 libraries
use Gnome2;
use Gnome2::Wnck;
use Gnome2::VFS '-init';

#Use AuthenticationManager to handle user credentials easily
Gnome2::AuthenticationManager->init;

#Gtk2 and Gtk2::ImageView
use Gtk2 '-init';
use Gtk2::Pango;
use Gtk2::ImageView;

#Use single instance applications
use Gtk2::Unique;

#Glib
use Glib qw/TRUE FALSE/;

#filename parsing
use POSIX qw/ strftime /;

#File operations
use File::Copy qw/ cp mv /;
use File::Glob qw/ glob /;
use File::Basename qw/ fileparse dirname basename /;
use File::Temp qw/ tempfile tempdir /;
use File::Spec;
use File::Which;
use File::Copy::Recursive;
use IO::File();

#A selection of general-utility list subroutines
use List::Util qw/ max min /;

#load and save settings
use XML::Simple;

#DBus message system
use Net::DBus qw/ dbus_string dbus_boolean /;

#HTTP Status code processing
use HTTP::Status;

#timing issues
use Time::HiRes qw/ time usleep /;

#Locate directory of original perl script
use FindBin '$Bin';

#stringified perl data structures, suitable for both printing and eval
use Data::Dumper;

#md5 hash library
use Digest::MD5 qw(md5_hex);

#proc
use Proc::Simple;

#sort lexically, but sort numeral parts numerically
use Sort::Naturally;

#--------------------------------------

#print UTF-8 to standard output
#--------------------------------------
binmode STDOUT, ":utf8";

#--------------------------------------

#define constants
#--------------------------------------
use constant MAX_ERROR       => 5;
use constant SHUTTER_REV     => 'Rev.1278';
use constant SHUTTER_NAME    => 'Shutter';
use constant SHUTTER_VERSION => '0.93.1';
#--------------------------------------

#configure path settings
#--------------------------------------
my $shutter_root = undef;
if ( $ENV{PAR_TEMP} ) {
    $shutter_root = $ENV{PAR_TEMP};
}
else {
    $Bin =~ m/(.*)\//;
    $shutter_root = $1;
}

my $shutter_path = $Bin . "/shutter";
$ENV{'SHUTTER_ROOT'} = $shutter_root;    #used by some plugins

#--------------------------------------

#check optional components
#--------------------------------------
my $gnome_web_photo = TRUE;
my $nautilus_sendto = TRUE;
my $goocanvas       = TRUE;
my $exiftool        = TRUE;
my $appindicator    = TRUE;
&fct_init_depend;

#--------------------------------------

#load shutter's modules
#--------------------------------------
require lib;
import lib "$shutter_root/share/shutter/resources/modules";

#app classes
require Shutter::App::AboutDialog;
require Shutter::App::Common;
require Shutter::App::GlobalSettings;
require Shutter::App::SimpleDialogs;
require Shutter::App::HelperFunctions;
require Shutter::App::Options;
require Shutter::App::Directories;
require Shutter::App::TrashInfo;
require Shutter::App::Autostart;
require Shutter::App::Menu;
require Shutter::App::Notification;
require Shutter::App::ShutterNotification;
require Shutter::App::Toolbar;
require Shutter::App::Optional::Exif;

#region
require Shutter::Geometry::Region;

#pixbuf operations
require Shutter::Pixbuf::Save;
require Shutter::Pixbuf::Load;
require Shutter::Pixbuf::Thumbnail;
require Shutter::Pixbuf::Border;

#drawing classes
if ($goocanvas) {
    require Shutter::Draw::DrawingTool;
}

#screenshot classes
require Shutter::Screenshot::SelectorAdvanced;
require Shutter::Screenshot::SelectorAuto;
require Shutter::Screenshot::Workspace;
require Shutter::Screenshot::Web;
require Shutter::Screenshot::Window;
require Shutter::Screenshot::WindowXid;
require Shutter::Screenshot::WindowName;
require Shutter::Screenshot::Error;

#upload classes
require Shutter::Upload::FTP;

#--------------------------------------

#main window
#--------------------------------------
my $window = Gtk2::Window->new('toplevel');

#--------------------------------------

#create app objects
#--------------------------------------
my $sc     = Shutter::App::Common->new( $shutter_root, $window, SHUTTER_NAME, SHUTTER_VERSION, SHUTTER_REV, $$ );
my $shf    = Shutter::App::HelperFunctions->new($sc);
my $so     = Shutter::App::Options->new( $sc, $shf );
my $sdir   = Shutter::App::Directories->new();
my $strash = Shutter::App::TrashInfo->new();
my $sas    = Shutter::App::Autostart->new();
my $sm     = Shutter::App::Menu->new($sc);
my $st     = Shutter::App::Toolbar->new($sc);
my $sd     = Shutter::App::SimpleDialogs->new($window);

my $sp     = Shutter::Pixbuf::Save->new($sc);
my $lp     = Shutter::Pixbuf::Load->new($sc);
my $lp_ne  = Shutter::Pixbuf::Load->new( $sc, undef, TRUE );
my $sthumb = Shutter::Pixbuf::Thumbnail->new($sc);

#--------------------------------------

#set home
#--------------------------------------
$ENV{'HOME'} = $sdir->get_home_dir;

#--------------------------------------

my $app = Gtk2::UniqueApp->new(
    "org.shutter-project.Shutter", undef,
    select         => 1,
    full           => 2,
    window         => 3,
    awindow        => 4,
    section        => 5,
    menu           => 6,
    tooltip        => 7,
    web            => 8,
    redoshot       => 9,
    profile        => 10,
    fopen          => 11,
    exitac         => 12,
    exfilename     => 13,
    delay          => 14,
    include_cursor => 15,
    remove_cursor  => 16,
    nosession      => 17,
);

#load command line arguments
#as well as file to open when starting
my $init_files = $so->get_options;
my @init_files = @$init_files;

#The application is already running, send it a message
if ( $app->is_running ) {

    my ( $cmdname, $extra ) = $sc->get_start_with;
    my $profile        = $sc->get_profile_to_start_with;
    my $exitac         = $sc->get_exit_after_capture;
    my $exfilename     = $sc->get_export_filename;
    my $delay          = $sc->get_delay;
    my $include_cursor = $sc->get_include_cursor;
    my $remove_cursor  = $sc->get_remove_cursor;
    my $nosession      = $sc->get_no_session;

    my $cmdid = undef;
    if ( defined $cmdname ) {
        if ( $cmdname eq 'select' ) {
            $cmdid = 1;
        }
        elsif ( $cmdname eq 'full' ) {
            $cmdid = 2;
        }
        elsif ( $cmdname eq 'window' ) {
            $cmdid = 3;
        }
        elsif ( $cmdname eq 'awindow' ) {
            $cmdid = 4;
        }
        elsif ( $cmdname eq 'section' ) {
            $cmdid = 5;
        }
        elsif ( $cmdname eq 'menu' ) {
            $cmdid = 6;
        }
        elsif ( $cmdname eq 'tooltip' ) {
            $cmdid = 7;
        }
        elsif ( $cmdname eq 'web' ) {
            $cmdid = 8;
        }
        elsif ( $cmdname eq 'redoshot' ) {
            $cmdid = 9;
        }
    }

    #change profile in running application
    if ( defined $profile && $profile ) {
        $app->send_message( 10, text => $profile );
    }

    #set exit flag in running application
    if ( defined $exitac && $exitac ) {
        $app->send_message( 12, text => '' );
    }

    #set export_filename (parameter -o) in running application
    if ( defined $exfilename && $exfilename ) {
        $app->send_message( 13, text => $shf->utf8_decode($exfilename) );
    }

    #change delay in running application
    if ( defined $delay && $delay ) {
        $app->send_message( 14, text => $delay );
    }

    #change include_cursor in running application
    if ( defined $include_cursor && $include_cursor ) {
        $app->send_message( 15, text => '' );
    }

    #change remove_cursor in running application
    if ( defined $remove_cursor && $remove_cursor ) {
        $app->send_message( 16, text => '' );
    }

    #set nosession flag in running application
    if ( defined $nosession && $nosession ) {
        $app->send_message( 17, text => '' );
    }

    #send $cmdid
    if ( defined $cmdid && defined $extra ) {
        $app->send_message( $cmdid, text => $extra );
    }
    elsif ( defined $cmdid ) {
        $app->send_message( $cmdid, text => 'shutter' );
    }
    else {

        #escape all filenames, see Bug #737428
        my @escaped_filenames;
        foreach my $file (@init_files) {
            push @escaped_filenames, Gnome2::VFS->escape_string($file);
        }
        $app->send_message( 11, uris => \@escaped_filenames );
    }

    print "\nINFO: There is already another instance of Shutter running!\n";

    #Create the single application instance and wait for other requests
}
else {

    #Clipboard
    my $clipboard = Gtk2::Clipboard->get( Gtk2::Gdk->SELECTION_CLIPBOARD );

    #Gettext
    my $d = $sc->get_gettext;

    #Page Setup
    my $pagesetup = undef;

    #Tooltips
    my $tooltips = $sc->get_tooltips;

    #data structures
    #--------------------------------------
    my %plugins;     #hash to store plugin infos
    my %accounts;    #hash to store account infos
    my %settings;    #hash to store settings

    #HELPERS
    my $current_profile_indx = 0;       #current profile index
    my $is_hidden            = TRUE;    #main window hidden flag

    # Watch the main window and register a handler that will be called each time
    # that there's a new message.
    $app->watch_window($window);
    my $app_watch_id = $app->signal_connect(
        'message-received' => sub {
            my ( $app, $cmd, $message, $time ) = @_;

            #map $cmd id
            if ( $cmd =~ /^-*[0-9]+$/ ) {
                if ( $cmd == 1 ) {
                    $cmd = 'select';
                }
                elsif ( $cmd == 2 ) {
                    $cmd = 'full';
                }
                elsif ( $cmd == 3 ) {
                    $cmd = 'window';
                }
                elsif ( $cmd == 4 ) {
                    $cmd = 'awindow';
                }
                elsif ( $cmd == 5 ) {
                    $cmd = 'section';
                }
                elsif ( $cmd == 6 ) {
                    $cmd = 'menu';
                }
                elsif ( $cmd == 7 ) {
                    $cmd = 'tooltip';
                }
                elsif ( $cmd == 8 ) {
                    $cmd = 'web';
                }
                elsif ( $cmd == 9 ) {
                    $cmd = 'redoshot';
                }
                elsif ( $cmd == 10 ) {
                    $cmd = 'profile';
                }
                elsif ( $cmd == 11 ) {
                    $cmd = 'fopen';
                }
                elsif ( $cmd == 12 ) {
                    $cmd = 'exitac';
                }
                elsif ( $cmd == 13 ) {
                    $cmd = 'exfilename';
                }
                elsif ( $cmd == 14 ) {
                    $cmd = 'delay';
                }
                elsif ( $cmd == 15 ) {
                    $cmd = 'include_cursor';
                }
                elsif ( $cmd == 16 ) {
                    $cmd = 'remove_cursor';
                }
                elsif ( $cmd == 17 ) {
                    $cmd = 'nosession';
                }
                else {
                    $cmd = 'fopen';
                }
            }

            #shutter window is presented automatically, sync our flag
            $is_hidden = FALSE;

            if ( defined $cmd ) {

                #set exit flag
                if ( $cmd eq 'exitac' ) {
                    $sc->set_exit_after_capture(TRUE);

                    #set export filename
                }
                elsif ( $cmd eq 'exfilename' ) {
                    $sc->set_export_filename( $message->get_text );

                    #set delay
                }
                elsif ( $cmd eq 'delay' ) {
                    $sc->set_delay( $message->get_text );

                    #set include_cursor flag
                }
                elsif ( $cmd eq 'include_cursor' ) {
                    $sc->set_include_cursor(TRUE);
                    $sc->set_remove_cursor(FALSE);

                    #set remove_cursor flag
                }
                elsif ( $cmd eq 'remove_cursor' ) {
                    $sc->set_remove_cursor(TRUE);
                    $sc->set_include_cursor(FALSE);

                    #set nosession flag
                }
                elsif ( $cmd eq 'nosession' ) {
                    $sc->set_no_session( $message->get_text );

                    #open new files
                }
                elsif ( $cmd eq 'fopen' ) {
                    my @init_files = $message->get_uris;
                    if ( scalar @init_files > 0 ) {
                        &fct_open_files(@init_files);
                    }
                    &fct_control_main_window('show');

                    #load profile
                }
                elsif ( $cmd eq 'profile' ) {
                    print "FIXME: switching profiles via IPC is not implemented yet\n";

                    #take screenshot
                }
                else {
                    &evt_take_screenshot( 'global_keybinding', $cmd, undef, $message->get_text );
                }
            }

            return 'ok';
        }
    );

    #create needed directories etc.
    &fct_init_environment;

    #print debug output
    &fct_init_debug_output if $sc->get_debug;

    #shutdown Shutter carefully when INT or TERM are detected
    # => save settings
    $SIG{INT}  = sub { &evt_delete_window( '', 'quit' ) };
    $SIG{TERM} = sub { &evt_delete_window( '', 'quit' ) };

    #hash of screenshots during session
    my %session_screens;
    my %session_start_screen;

    #main window gui
    #--------------------------------------
    $window->set_default_icon_name("shutter");
    $window->signal_connect( 'delete-event' => \&evt_delete_window );
    $window->set_border_width(0);
    $window->set_resizable(TRUE);
    $window->set_focus_on_map(TRUE);
    $window->set_default_size( -1, 500 );

    #UPDATE WINDOW LIST (signal is connected when GUI is loaded)
    my $wnck_screen = Gnome2::Wnck::Screen->get_default;
    $wnck_screen->force_update;

    #TRAY ICON AND MENU
    my $tray      = undef;
    my $tray_box  = undef;                #Gtk2::TrayIcon needs and Gtk2::EventBox
    my $tray_menu = &fct_ret_tray_menu;

    #SESSION NOTEBOOK
    my $notebook = Gtk2::Notebook->new;
    $notebook = &fct_create_session_notebook;

    #STATUSBAR
    my $status = Gtk2::Statusbar->new;
    $status->set_name('main-window-statusbar');

    #customize the statusbar style
    Gtk2::Rc->parse_string(
        "style 'statusbar-style' {
			GtkStatusbar::shadow-type = GTK_SHADOW_NONE
		}
		widget '*.main-window-statusbar' style 'statusbar-style'"
    );

    my $combobox_status_profiles_label = Gtk2::Label->new( $d->get("Profile") . ":" );
    my $combobox_status_profiles       = Gtk2::ComboBox->new_text;

    #arrange settings in notebook
    my $notebook_settings = Gtk2::Notebook->new;
    $notebook_settings->set_tab_pos('left');

    my $settings_dialog = Gtk2::Dialog->new( SHUTTER_NAME . " - " . $d->get("Preferences"), $window, [qw/modal destroy-with-parent/], 'gtk-close' => 'close' );
    $settings_dialog->set_has_separator(FALSE);

    my $vbox = Gtk2::VBox->new( FALSE, 0 );
    $window->add($vbox);

    #attach signal handlers to subroutines and pack menu
    #--------------------------------------
    $vbox->pack_start( $sm->create_menu, FALSE, TRUE, 0 );

    $sm->{_menuitem_open}->signal_connect( 'activate', \&dlg_open, 'menu_open' );

    #recent manager and menu entry
    $sm->{_menu_recent} = Gtk2::RecentChooserMenu->new_for_manager( Gtk2::RecentManager->get_default );
    $sm->{_menu_recent}->set_sort_type('mru');
    $sm->{_menu_recent}->set_local_only(TRUE);
    $sm->{_menu_recent}->set_show_numbers(TRUE);
    $sm->{_menu_recent}->set_show_not_found(FALSE);

    my $recentfilter = Gtk2::RecentFilter->new;
    $recentfilter->add_pixbuf_formats;
    $sm->{_menu_recent}->add_filter($recentfilter);
    $sm->{_menu_recent}->signal_connect(
        'item-activated' => \&dlg_open,
        $sm->{_menu_recent}->get_current_uri
    );
    $sm->{_menuitem_recent}->set_submenu( $sm->{_menu_recent} );

    $sm->{_menuitem_redoshot}->signal_connect( 'activate', \&evt_take_screenshot, 'redoshot' );
    $sm->{_menuitem_selection}->signal_connect( 'activate', \&evt_take_screenshot, 'select' );
    $sm->{_menuitem_full}->signal_connect( 'activate', \&evt_take_screenshot, 'full' );
    $sm->{_menuitem_awindow}->signal_connect( 'activate', \&evt_take_screenshot, 'awindow' );
    $sm->{_menuitem_window}->signal_connect( 'activate', \&evt_take_screenshot, 'window' );
    $sm->{_menuitem_section}->signal_connect( 'activate', \&evt_take_screenshot, 'section' );
    $sm->{_menuitem_menu}->signal_connect( 'activate', \&evt_take_screenshot, 'menu' );
    $sm->{_menuitem_tooltip}->signal_connect( 'activate', \&evt_take_screenshot, 'tooltip' );
    $sm->{_menuitem_iclipboard}->signal_connect( 'activate', \&fct_clipboard_import );

    #gnome web photo is optional, don't enable it when gnome-web-photo is not in PATH
    if ($gnome_web_photo) {
        $sm->{_menuitem_web}->set_sensitive(TRUE);
        $sm->{_menuitem_web}->signal_connect( 'activate', \&evt_take_screenshot, 'web' );
    }
    else {
        $sm->{_menuitem_web}->set_sensitive(FALSE);
    }

    #~ $sm->{_menuitem_save}->signal_connect( 'activate', \&evt_save_as, 'menu_save' );
    $sm->{_menuitem_save_as}->signal_connect( 'activate', \&evt_save_as, 'menu_save_as' );

    #~ $sm->{_menuitem_export_svg}->signal_connect( 'activate', \&evt_save_as, 'menu_export_svg' );
    $sm->{_menuitem_export_pdf}->signal_connect( 'activate', \&evt_save_as, 'menu_export_pdf' );
    $sm->{_menuitem_export_pscript}->signal_connect( 'activate', \&evt_save_as, 'menu_export_ps' );
    $sm->{_menuitem_print}->signal_connect( 'activate', \&fct_print, 'menu_print' );
    $sm->{_menuitem_pagesetup}->signal_connect( 'activate', \&evt_page_setup, 'menu_pagesetup' );
    $sm->{_menuitem_email}->signal_connect( 'activate', \&fct_email, 'menu_email' );
    $sm->{_menuitem_close}->signal_connect( 'activate', sub { &fct_remove( undef, 'menu_close' ); } );
    $sm->{_menuitem_close_all}->signal_connect( 'activate', sub { &fct_select_all; &fct_remove( undef, 'menu_close_all' ); } );
    $sm->{_menuitem_quit}->signal_connect( 'activate', \&evt_delete_window, 'quit' );

    $sm->{_menuitem_undo}->signal_connect( 'activate', \&fct_undo );
    $sm->{_menuitem_redo}->signal_connect( 'activate', \&fct_redo );
    $sm->{_menuitem_copy}->signal_connect( 'activate', \&fct_clipboard, 'image' );
    $sm->{_menuitem_copy_filename}->signal_connect( 'activate', \&fct_clipboard, 'text' );
    $sm->{_menuitem_trash}->signal_connect( 'activate', sub { &fct_delete(undef); } );
    $sm->{_menuitem_select_all}->signal_connect( 'activate', \&fct_select_all );
    $sm->{_menuitem_settings}->signal_connect( 'activate', \&evt_show_settings );

    $sm->{_menuitem_btoolbar}->signal_connect( 'toggled', \&fct_navigation_toolbar );
    $sm->{_menuitem_zoom_in}->signal_connect( 'activate', \&fct_zoom_in );
    $sm->{_menuitem_zoom_out}->signal_connect( 'activate', \&fct_zoom_out );
    $sm->{_menuitem_zoom_100}->signal_connect( 'activate', \&fct_zoom_100 );
    $sm->{_menuitem_zoom_best}->signal_connect( 'activate', \&fct_zoom_best );
    $sm->{_menuitem_fullscreen}->signal_connect( 'toggled', \&fct_fullscreen );

    #screenshot menu
    #~ $sm->{_menu_actions}->signal_connect( 'focus', sub { $sm->{_menuitem_reopen}->set_submenu(&fct_ret_program_menu); });
    $sm->{_menuitem_reopen}->set_submenu(&fct_ret_program_menu);
    $sm->{_menuitem_show_in_folder}->signal_connect( 'activate', \&fct_show_in_folder );
    $sm->{_menuitem_rename}->signal_connect( 'activate', \&fct_rename );
    $sm->{_menuitem_upload}->signal_connect( 'activate', \&fct_upload );

    #nautilus-sendto is optional, don't enable it when not installed
    if ($nautilus_sendto) {
        $sm->{_menuitem_send}->signal_connect( 'activate', \&fct_send );
    }
    else {
        $sm->{_menuitem_send}->set_sensitive(FALSE);
    }

    #goocanvas is optional, don't enable it when not installed
    if ($goocanvas) {
        $sm->{_menuitem_draw}->signal_connect( 'activate', \&fct_draw );
    }
    else {
        $sm->{_menuitem_draw}->set_sensitive(FALSE);
    }

    $sm->{_menuitem_plugin}->signal_connect( 'activate', \&fct_plugin );
    $sm->{_menuitem_redoshot_this}->signal_connect( 'activate', \&evt_take_screenshot, 'redoshot_this' );

    #large screenshot menu
    $sm->{_menu_large_actions}->signal_connect(
        'focus',
        sub {
            $sm->{_menuitem_large_reopen}->set_submenu( &fct_ret_program_menu( $sm->{_menuitem_large_reopen}->get_submenu ) );
        }
    );
    $sm->{_menuitem_large_reopen}->set_submenu(&fct_ret_program_menu);
    $sm->{_menuitem_large_show_in_folder}->signal_connect( 'activate', \&fct_show_in_folder );
    $sm->{_menuitem_large_rename}->signal_connect( 'activate', \&fct_rename );
    $sm->{_menuitem_large_copy}->signal_connect( 'activate', \&fct_clipboard, 'image' );
    $sm->{_menuitem_large_copy_filename}->signal_connect( 'activate', \&fct_clipboard, 'text' );
    $sm->{_menuitem_large_trash}->signal_connect( 'activate', sub { &fct_delete(undef); } );
    $sm->{_menuitem_large_upload}->signal_connect( 'activate', \&fct_upload );

    #nautilus-sendto is optional, don't enable it when not installed
    if ($nautilus_sendto) {
        $sm->{_menuitem_large_send}->signal_connect( 'activate', \&fct_send );
    }
    else {
        $sm->{_menuitem_large_send}->set_sensitive(FALSE);
    }

    #goocanvas is optional, don't enable it when not installed
    if ($goocanvas) {
        $sm->{_menuitem_large_draw}->signal_connect( 'activate', \&fct_draw );
    }
    else {
        $sm->{_menuitem_large_draw}->set_sensitive(FALSE);
    }

    $sm->{_menuitem_large_plugin}->signal_connect( 'activate', \&fct_plugin );
    $sm->{_menuitem_large_redoshot_this}->signal_connect( 'activate', \&evt_take_screenshot, 'redoshot_this' );

    #go to menu
    $sm->{_menuitem_back}->signal_connect(
        'activate' => sub {
            $notebook->prev_page;
        }
    );
    $sm->{_menuitem_forward}->signal_connect(
        'activate' => sub {
            $notebook->next_page;
        }
    );
    $sm->{_menuitem_first}->signal_connect(
        'activate' => sub {
            $notebook->set_current_page(0);
        }
    );
    $sm->{_menuitem_last}->signal_connect(
        'activate' => sub {
            $notebook->set_current_page( $notebook->get_n_pages - 1 );
        }
    );

    #help
    $sm->{_menuitem_question}->signal_connect( 'activate', \&evt_question );
    $sm->{_menuitem_translate}->signal_connect( 'activate', \&evt_translate );
    $sm->{_menuitem_bug}->signal_connect( 'activate', \&evt_bug );
    $sm->{_menuitem_about}->signal_connect( 'activate', \&evt_about );

    #--------------------------------------

    #trayicon
    #--------------------------------------
    #command line param set to disable tray icon?
    unless ( $sc->get_disable_systray ) {

        if ($appindicator) {
            $tray = Gtk2::AppIndicator->new( "Shutter", "shutter-panel" );
            $tray->set_menu($tray_menu);
            $tray->set_active();
        }
        else {
            if ( Gtk2->CHECK_VERSION( 2, 10, 0 ) ) {
                $tray = Gtk2::StatusIcon->new();

                $tray->set_from_icon_name("shutter-panel");
                $tray->set_visible(1);
                $tray->{'hid'} = $tray->signal_connect(
                    'popup-menu' => sub { &evt_show_systray_statusicon; },
                    $tray
                );
                $tray->{'hid2'} = $tray->signal_connect(
                    'activate' => sub {
                        &evt_activate_systray_statusicon;
                        $tray;
                    },
                    $tray
                );
            }
            else {

                my $tray_image = Gtk2::Image->new_from_icon_name( 'shutter-panel', 'large-toolbar' );

                #eventbox with shutter logo
                $tray_box = Gtk2::EventBox->new;
                $tray_box->add($tray_image);

                #tray icon
                require Gtk2::TrayIcon;
                $tray = Gtk2::TrayIcon->new('Shutter TrayIcon');
                $tray->add($tray_box);
                $tray_box->{'hid'} = $tray_box->signal_connect( 'button_release_event', \&evt_show_systray );
                $tray->show_all;
            }
        }

    }

    #--------------------------------------

    #settings
    #--------------------------------------
    my $vbox_settings  = Gtk2::VBox->new( FALSE, 12 );
    my $hbox_settings  = Gtk2::HBox->new( FALSE, 12 );
    my $vbox_basic     = Gtk2::VBox->new( FALSE, 12 );
    my $vbox_advanced  = Gtk2::VBox->new( FALSE, 12 );
    my $vbox_actions   = Gtk2::VBox->new( FALSE, 12 );
    my $vbox_imageview = Gtk2::VBox->new( FALSE, 12 );
    my $vbox_behavior  = Gtk2::VBox->new( FALSE, 12 );
    my $vbox_keyboard  = Gtk2::VBox->new( FALSE, 12 );
    my $vbox_accounts  = Gtk2::VBox->new( FALSE, 12 );

    #profiles
    my $profiles_box = Gtk2::HBox->new( FALSE, 0 );

    #main
    my $file_vbox    = Gtk2::VBox->new( FALSE, 0 );
    my $save_vbox    = Gtk2::VBox->new( FALSE, 0 );
    my $capture_vbox = Gtk2::VBox->new( FALSE, 0 );

    my $scale_box          = Gtk2::HBox->new( FALSE, 0 );
    my $filetype_box       = Gtk2::HBox->new( FALSE, 0 );
    my $filename_box       = Gtk2::HBox->new( FALSE, 0 );
    my $saveDir_box        = Gtk2::HBox->new( FALSE, 0 );
    my $save_ask_box       = Gtk2::HBox->new( FALSE, 0 );
    my $save_no_box        = Gtk2::HBox->new( FALSE, 0 );
    my $save_auto_box      = Gtk2::HBox->new( FALSE, 0 );
    my $no_autocopy_box    = Gtk2::HBox->new( FALSE, 0 );
    my $image_autocopy_box = Gtk2::HBox->new( FALSE, 0 );
    my $fname_autocopy_box = Gtk2::HBox->new( FALSE, 0 );
    my $delay_box          = Gtk2::HBox->new( FALSE, 0 );
    my $cursor_box         = Gtk2::HBox->new( FALSE, 0 );

    #actions
    my $actions_vbox = Gtk2::VBox->new( FALSE, 0 );

    my $progname_box     = Gtk2::HBox->new( FALSE, 0 );
    my $im_colors_box    = Gtk2::HBox->new( FALSE, 0 );
    my $thumbnail_box    = Gtk2::HBox->new( FALSE, 0 );
    my $bordereffect_box = Gtk2::HBox->new( FALSE, 0 );

    #advanced
    my $sel_capture_vbox    = Gtk2::VBox->new( FALSE, 0 );
    my $window_capture_vbox = Gtk2::VBox->new( FALSE, 0 );
    my $menu_capture_vbox   = Gtk2::VBox->new( FALSE, 0 );
    my $web_capture_vbox    = Gtk2::VBox->new( FALSE, 0 );

    my $zoom_box            = Gtk2::HBox->new( FALSE, 0 );
    my $as_help_box         = Gtk2::HBox->new( FALSE, 0 );
    my $asel_isize_box      = Gtk2::HBox->new( FALSE, 0 );
    my $asel_isize_box2     = Gtk2::HBox->new( FALSE, 0 );
    my $border_box          = Gtk2::HBox->new( FALSE, 0 );
    my $winresize_box       = Gtk2::HBox->new( FALSE, 0 );
    my $autoshape_box       = Gtk2::HBox->new( FALSE, 0 );
    my $visible_windows_box = Gtk2::HBox->new( FALSE, 0 );
    my $menu_delay_box      = Gtk2::HBox->new( FALSE, 0 );
    my $menu_waround_box    = Gtk2::HBox->new( FALSE, 0 );
    my $web_width_box       = Gtk2::HBox->new( FALSE, 0 );

    #imageview
    my $transparent_vbox = Gtk2::VBox->new( FALSE, 0 );
    my $imageview_hbox1  = Gtk2::HBox->new( FALSE, 0 );
    my $imageview_hbox2  = Gtk2::HBox->new( FALSE, 0 );
    my $imageview_hbox3  = Gtk2::HBox->new( FALSE, 0 );

    my $session_vbox  = Gtk2::VBox->new( FALSE, 0 );
    my $session_hbox1 = Gtk2::HBox->new( FALSE, 0 );
    my $session_hbox2 = Gtk2::HBox->new( FALSE, 0 );

    #behavior
    my $first_vbox      = Gtk2::VBox->new( FALSE, 0 );
    my $window_vbox     = Gtk2::VBox->new( FALSE, 0 );
    my $notify_vbox     = Gtk2::VBox->new( FALSE, 0 );
    my $trash_vbox      = Gtk2::VBox->new( FALSE, 0 );
    my $keybinding_vbox = Gtk2::VBox->new( FALSE, 0 );

    my $fs_active_hbox       = Gtk2::HBox->new( FALSE, 0 );
    my $fs_min_active_hbox   = Gtk2::HBox->new( FALSE, 0 );
    my $fs_nonot_active_hbox = Gtk2::HBox->new( FALSE, 0 );
    my $hide_active_hbox     = Gtk2::HBox->new( FALSE, 0 );
    my $pafter_active_hbox   = Gtk2::HBox->new( FALSE, 0 );
    my $cac_hbox             = Gtk2::HBox->new( FALSE, 0 );
    my $hide_time_hbox       = Gtk2::HBox->new( FALSE, 0 );
    my $na_active_hbox       = Gtk2::HBox->new( FALSE, 0 );
    my $nt_active_hbox       = Gtk2::HBox->new( FALSE, 0 );
    my $npt_active_hbox      = Gtk2::HBox->new( FALSE, 0 );
    my $ns_combo_hbox        = Gtk2::HBox->new( FALSE, 0 );
    my $aod_active_hbox      = Gtk2::HBox->new( FALSE, 0 );
    my $doc_active_hbox      = Gtk2::HBox->new( FALSE, 0 );
    my $aofsd_active_hbox    = Gtk2::HBox->new( FALSE, 0 );

    #upload
    my $accounts_vbox = Gtk2::VBox->new( FALSE, 0 );
    my $ftp_vbox      = Gtk2::VBox->new( FALSE, 0 );

    my $accounts_hbox = Gtk2::HBox->new( FALSE, 0 );
    my $ftp_hbox1     = Gtk2::HBox->new( FALSE, 0 );
    my $ftp_hbox2     = Gtk2::HBox->new( FALSE, 0 );
    my $ftp_hbox3     = Gtk2::HBox->new( FALSE, 0 );
    my $ftp_hbox4     = Gtk2::HBox->new( FALSE, 0 );
    my $ftp_hbox5     = Gtk2::HBox->new( FALSE, 0 );

    #plugins
    my $effects_vbox = Gtk2::VBox->new( FALSE, 0 );

    #load settings
    #--------------------------------------
    my $settings_xml = &fct_load_settings("start");

    #load accounts for hosting services
    &fct_load_accounts;

    #load requested profile (argv)
    if ( defined $sc->get_profile_to_start_with ) {
        $settings_xml = &fct_load_settings( "start", $sc->get_profile_to_start_with );
    }
    else {

        #or load last used profile
        if ( defined $settings_xml->{'general'}->{'last_profile'} ) {
            if ( $settings_xml->{'general'}->{'last_profile'} != -1 ) {
                $settings_xml = &fct_load_settings( "start", $settings_xml->{'general'}->{'last_profile_name'} );
            }
        }
    }

    #--------------------------------------

    #block signals while checking plugins / opening files
    &fct_control_signals('block');

    #check plugins
    #--------------------------------------
    #not used in a standalone environment
    unless ( $ENV{PAR_TEMP} ) {
        &fct_check_installed_plugins;
    }

    #check upload plugins
    #--------------------------------------
    #not used in a standalone environment
    unless ( $ENV{PAR_TEMP} ) {
        &fct_check_installed_upload_plugins;
    }

    $vbox->pack_start( $st->create_toolbar, FALSE, TRUE, 0 );

    $st->{_redoshot}->signal_connect( 'clicked' => \&evt_take_screenshot, 'redoshot' );
    $st->{_redoshot}->set_sensitive(FALSE);

    $st->{_select}->signal_connect( 'clicked' => \&evt_take_screenshot, 'select' );

    my $current_monitor_active = undef;
    $st->{_full}->signal_connect( 'clicked' => \&evt_take_screenshot, 'full' );

    #init menus
    $st->{_full}->set_menu( &fct_ret_workspace_menu(TRUE) );
    $st->{_window}->set_menu(&fct_ret_window_menu);

    #and attach signal handlers
    $st->{_full}->signal_connect( 'show-menu' => sub { $st->{_full}->set_menu( &fct_ret_workspace_menu(FALSE) ) } );
    $st->{_window}->signal_connect( 'clicked' => \&evt_take_screenshot, 'window' );

    $st->{_window}->signal_connect( 'show-menu' => sub { $st->{_window}->set_menu(&fct_ret_window_menu) } );
    $st->{_section}->signal_connect( 'clicked' => \&evt_take_screenshot, 'section' );
    $st->{_menu}->signal_connect( 'clicked' => \&evt_take_screenshot, 'menu' );
    $st->{_tooltip}->signal_connect( 'clicked' => \&evt_take_screenshot, 'tooltip' );

    #gnome-web-photo is optional, don't enable it when gnome-web-photo is not in PATH
    if ($gnome_web_photo) {
        $st->{_web}->set_sensitive(TRUE);
        $st->{_web}->signal_connect( 'clicked' => \&evt_take_screenshot, 'web' );
        $st->{_web}->set_menu(&fct_ret_web_menu);
        $st->{_web}->signal_connect( 'show-menu' => \&fct_ret_web_menu );
    }
    else {
        $tooltips->set_tip( $st->{_web}, $d->get("gnome-web-photo needs to be installed for this feature") );
        $st->{_web}->set_arrow_tooltip( $tooltips, $d->get("gnome-web-photo needs to be installed for this feature"), '' );
        $st->{_web}->set_sensitive(FALSE);
    }

    #goocanvas is optional, don't enable it when not installed
    if ($goocanvas) {
        $st->{_edit}->signal_connect( 'clicked' => \&fct_draw );
    }
    else {
        $tooltips->set_tip( $st->{_edit}, $d->get("Goo::Canvas/libgoo-canvas-perl needs to be installed for this feature") );
    }
    $st->{_edit}->set_sensitive(FALSE);

    $st->{_upload}->signal_connect( 'clicked' => \&fct_upload );
    $st->{_upload}->set_sensitive(FALSE);

    #--------------------------------------

    #handle profiles
    #--------------------------------------
    my $combobox_settings_profiles = Gtk2::ComboBox->new_text;
    my @current_profiles;
    my $current_index = 0;
    foreach my $pfile ( sort glob("$ENV{'HOME'}/.shutter/profiles/*.xml") ) {
        utf8::decode $pfile;
        next
          if $pfile =~ /\_accounts.xml/;    #accounts file - we are looking for "real" profiles
        $pfile =~ /.*\/(.*)\.xml/;          #get profiles name
        my $last_profile_name = $1;
        $combobox_settings_profiles->append_text($last_profile_name);

        #set active profile
        if ( exists $settings_xml->{'general'}->{'last_profile_name'} ) {
            if ( $settings_xml->{'general'}->{'last_profile_name'} eq $last_profile_name ) {
                $combobox_settings_profiles->set_active($current_index);
                $current_profile_indx = $current_index;
            }
        }

        push( @current_profiles, $last_profile_name );
        $current_index++;
    }
    $tooltips->set_tip( $combobox_settings_profiles, $d->get("Choose a profile") );

    #set 0 if nothing is selected yet
    if ( !$combobox_settings_profiles->get_active_text ) {
        $combobox_settings_profiles->set_active(0);
        $current_profile_indx = 0;
    }

    my $button_profile_save = Gtk2::Button->new;
    $button_profile_save->signal_connect(
        'clicked' => sub {
            my $widget = shift;
            &evt_save_profile( $widget, $combobox_settings_profiles, \@current_profiles );
        }
    );
    $button_profile_save->set_image( Gtk2::Image->new_from_stock( 'gtk-save', 'button' ) );
    $tooltips->set_tip( $button_profile_save, $d->get("Save configuration as profile") );

    my $button_profile_delete = Gtk2::Button->new;
    $button_profile_delete->signal_connect(
        'clicked' => sub {
            my $widget = shift;
            &evt_delete_profile( $widget, $combobox_settings_profiles, \@current_profiles );
        }
    );
    $button_profile_delete->set_image( Gtk2::Image->new_from_stock( 'gtk-delete', 'button' ) );
    $tooltips->set_tip( $button_profile_delete, $d->get("Delete profile") );
    my $button_profile_apply = Gtk2::Button->new;
    $button_profile_apply->signal_connect(
        'clicked' => sub {
            my $widget = shift;
            &evt_apply_profile( $widget, $combobox_settings_profiles, \@current_profiles );
        }
    );
    $button_profile_apply->set_image( Gtk2::Image->new_from_stock( 'gtk-apply', 'button' ) );
    $tooltips->set_tip( $button_profile_apply, $d->get("Load the selected profile's configuration") );

    #--------------------------------------

    #frames and label for settings dialog
    #--------------------------------------
    my $file_frame_label = Gtk2::Label->new;
    $file_frame_label->set_markup( "<b>" . $d->get("Image format") . "</b>" );

    my $file_frame = Gtk2::Frame->new();
    $file_frame->set_label_widget($file_frame_label);
    $file_frame->set_shadow_type('none');

    my $save_frame_label = Gtk2::Label->new;
    $save_frame_label->set_markup( "<b>" . $d->get("Save") . "</b>" );

    my $save_frame = Gtk2::Frame->new();
    $save_frame->set_label_widget($save_frame_label);
    $save_frame->set_shadow_type('none');

    my $firstlaunch_frame_label = Gtk2::Label->new;
    $firstlaunch_frame_label->set_markup( "<b>" . $d->get("First-launch Behavior") . "</b>" );

    my $firstlaunch_frame = Gtk2::Frame->new();
    $firstlaunch_frame->set_label_widget($firstlaunch_frame_label);
    $firstlaunch_frame->set_shadow_type('none');

    my $window_frame_label = Gtk2::Label->new;
    $window_frame_label->set_markup( "<b>" . $d->get("Window Preferences") . "</b>" );

    my $window_frame = Gtk2::Frame->new();
    $window_frame->set_label_widget($window_frame_label);
    $window_frame->set_shadow_type('none');

    my $notify_frame_label = Gtk2::Label->new;
    $notify_frame_label->set_markup( "<b>" . $d->get("Notifications") . "</b>" );

    my $notify_frame = Gtk2::Frame->new();
    $notify_frame->set_label_widget($notify_frame_label);
    $notify_frame->set_shadow_type('none');

    my $trash_frame_label = Gtk2::Label->new;
    $trash_frame_label->set_markup( "<b>" . $d->get("Trash") . "</b>" );

    my $trash_frame = Gtk2::Frame->new();
    $trash_frame->set_label_widget($trash_frame_label);
    $trash_frame->set_shadow_type('none');

    my $keybinding_frame_label = Gtk2::Label->new;
    $keybinding_frame_label->set_markup( "<b>" . $d->get("Gnome-Keybinding") . "</b>" );

    my $keybinding_frame = Gtk2::Frame->new();
    $keybinding_frame->set_label_widget($keybinding_frame_label);
    $keybinding_frame->set_shadow_type('none');

    my $actions_frame_label = Gtk2::Label->new;
    $actions_frame_label->set_markup( "<b>" . $d->get("Actions") . "</b>" );

    my $actions_frame = Gtk2::Frame->new();
    $actions_frame->set_label_widget($actions_frame_label);
    $actions_frame->set_shadow_type('none');

    my $capture_frame_label = Gtk2::Label->new;
    $capture_frame_label->set_markup( "<b>" . $d->get("Capture") . "</b>" );

    my $capture_frame = Gtk2::Frame->new();
    $capture_frame->set_label_widget($capture_frame_label);
    $capture_frame->set_shadow_type('none');

    my $sel_capture_frame_label = Gtk2::Label->new;
    $sel_capture_frame_label->set_markup( "<b>" . $d->get("Selection Capture") . "</b>" );

    my $sel_capture_frame = Gtk2::Frame->new();
    $sel_capture_frame->set_label_widget($sel_capture_frame_label);
    $sel_capture_frame->set_shadow_type('none');

    my $window_capture_frame_label = Gtk2::Label->new;
    $window_capture_frame_label->set_markup( "<b>" . $d->get("Window Capture") . "</b>" );

    my $window_capture_frame = Gtk2::Frame->new();
    $window_capture_frame->set_label_widget($window_capture_frame_label);
    $window_capture_frame->set_shadow_type('none');

    my $menu_capture_frame_label = Gtk2::Label->new;
    $menu_capture_frame_label->set_markup( "<b>" . $d->get("Menu/Tooltip Capture") . "</b>" );

    my $menu_capture_frame = Gtk2::Frame->new();
    $menu_capture_frame->set_label_widget($menu_capture_frame_label);
    $menu_capture_frame->set_shadow_type('none');

    my $web_capture_frame_label = Gtk2::Label->new;
    $web_capture_frame_label->set_markup( "<b>" . $d->get("Website Capture") . "</b>" );

    my $web_capture_frame = Gtk2::Frame->new();
    $web_capture_frame->set_label_widget($web_capture_frame_label);
    $web_capture_frame->set_shadow_type('none');

    my $accounts_frame_label = Gtk2::Label->new;
    $accounts_frame_label->set_markup( "<b>" . $d->get("Accounts") . "</b>" );

    my $accounts_frame = Gtk2::Frame->new();
    $accounts_frame->set_label_widget($accounts_frame_label);
    $accounts_frame->set_shadow_type('none');

    my $ftp_frame_label = Gtk2::Label->new;
    $ftp_frame_label->set_markup( "<b>" . $d->get("File Transfer Protocol (FTP)") . "</b>" );

    my $ftp_frame = Gtk2::Frame->new();
    $ftp_frame->set_label_widget($ftp_frame_label);
    $ftp_frame->set_shadow_type('none');

    my $transparent_frame_label = Gtk2::Label->new;
    $transparent_frame_label->set_markup( "<b>" . $d->get("Transparent Parts") . "</b>" );

    my $transparent_frame = Gtk2::Frame->new();
    $transparent_frame->set_label_widget($transparent_frame_label);
    $transparent_frame->set_shadow_type('none');

    my $session_frame_label = Gtk2::Label->new;
    $session_frame_label->set_markup( "<b>" . $d->get("Session View") . "</b>" );

    my $session_frame = Gtk2::Frame->new();
    $session_frame->set_label_widget($session_frame_label);
    $session_frame->set_shadow_type('none');

    #filename
    #--------------------------------------
    my $filename_label = Gtk2::Label->new( $d->get("Filename") . ":" );

    my $filename = Gtk2::Entry->new;
    if ( defined $settings_xml->{'general'}->{'filename'} ) {
        $filename->set_text( $settings_xml->{'general'}->{'filename'} );
    }
    else {
        $filename->set_text("\$name_\%NNN");
    }

    #do some input validation
    #here are all invalid char codes
    my @invalid_codes = ( 47, 92, 63, 42, 58, 124, 34, 60, 62, 44, 59, 35, 38 );
    my $filename_hint = Gtk2::Label->new;
    $filename_hint->set_no_show_all(TRUE);
    $filename->signal_connect(
        'key-press-event' => sub {
            my $filename = shift;
            my $event    = shift;

            my $input = Gtk2::Gdk->keyval_to_unicode( $event->keyval );

            #invalid input
            #~ print $input."\n";
            if ( grep( $input == $_, @invalid_codes ) ) {
                my $char = chr($input);
                $char = '&amp;' if $char eq '&';
                $filename_hint->set_markup( "<span size='small'>" . sprintf( $d->get("Reserved character %s is not allowed to be in a filename."), "'" . $char . "'" ) . "</span>" );

                $filename_hint->show;
                return TRUE;
            }
            else {

                #clear possible message when valid char is entered
                $filename_hint->set_markup("<span size='small'></span>");
                $filename_hint->hide;
                return FALSE;
            }
        }
    );

    my $filename_tooltip_string = $d->get("There are several wildcards available, like\n") . $d->get("%Y = year\n") . $d->get("%m = month\n") . $d->get("%d = day\n") . $d->get("%T = time\n") . $d->get("\$w = width\n") . $d->get("\$h = height\n") . $d->get("\$name = multi-purpose (e.g. window title)\n") . $d->get("\$nb_name = like \$name but without blanks in resulting strings\n") . $d->get("\$profile = name of current profile\n") . $d->get("\$R = random char (e.g. \$RRRR = ag4r)\n") . $d->get("%NN = counter");

    $tooltips->set_tip( $filename,       $filename_tooltip_string );
    $tooltips->set_tip( $filename_label, $filename_tooltip_string );

    $filename_box->pack_start( $filename_label, FALSE, TRUE, 12 );
    $filename_box->pack_start( $filename,       TRUE,  TRUE, 0 );

    #end - filename
    #--------------------------------------

    #filetype and scale
    #--------------------------------------
    my $scale = Gtk2::HScale->new_with_range( 0, 9, 1 );
    my $scale_label = Gtk2::Label->new( $d->get("Compression") . ":" );
    $scale->set_value_pos('right');
    $scale->set_value(1);

    #we don't need a default here because it will be set through signal handling (filetype)
    if ( defined $settings_xml->{'general'}->{'quality'} ) {
        $scale->set_value( $settings_xml->{'general'}->{'quality'} );
    }

    $tooltips->set_tip( $scale,       $d->get("Adjust quality/compression value") );
    $tooltips->set_tip( $scale_label, $d->get("Adjust quality/compression value") );

    $scale_box->pack_start( $scale_label, FALSE, TRUE, 12 );
    $scale_box->pack_start( $scale,       TRUE,  TRUE, 0 );

    #add compatile, writeable file types
    my $combobox_type = Gtk2::ComboBox->new_text;
    my ( $int_png, $int_jpeg, $int_bmp ) = ( -1, -1, -1 );
    my $format_counter = 0;

    foreach my $format ( Gtk2::Gdk::Pixbuf->get_formats ) {
        if (   $format->{name} eq "jpeg"
            || $format->{name} eq "png"
            || $format->{name} eq "bmp" )
        {

            #we want jpg not jpeg
            if ( $format->{name} eq "jpeg" || $format->{name} eq "jpg" ) {
                $combobox_type->append_text( "jpg" . " - " . $format->{description} );
            }
            else {
                $combobox_type->append_text( $format->{name} . " - " . $format->{description} );
            }

            #a little ugly here, maybe the values are in alternative order on several machine...
            #just remember the number when appending, so we can set png as default for example
            if ( $format->{name} eq "jpeg" || $format->{name} eq "jpg" ) {
                $int_jpeg = $format_counter;
            }
            elsif ( $format->{name} eq "png" ) {
                $int_png = $format_counter;
            }
            elsif ( $format->{name} eq "bmp" ) {
                $int_bmp = $format_counter;
            }

            $format_counter++;

        }
    }
    $combobox_type->signal_connect(
        'changed' => \&evt_value_changed,
        'type_changed'
    );
    $scale->signal_connect(
        'value-changed' => \&evt_value_changed,
        'qvalue_changed'
    );

    if ( defined $settings_xml->{'general'}->{'filetype'} ) {

        #migration from gscrot to shutter
        #maybe we can drop this in future releases
        # 0 := jpeg (jpg)
        # 1 := png
        unless ( defined $settings_xml->{'general'}->{'app_version'} ) {
            if ( $settings_xml->{'general'}->{'filetype'} == 0 ) {
                $combobox_type->set_active($int_jpeg);
            }
            elsif ( $settings_xml->{'general'}->{'filetype'} == 1 ) {
                $combobox_type->set_active($int_png);
            }

            #shutter
        }
        else {
            $combobox_type->set_active( $settings_xml->{'general'}->{'filetype'} );
        }

        #set saved quality/compression value if there is one
        if ( defined $settings_xml->{'general'}->{'quality'} ) {
            $scale->set_value( $settings_xml->{'general'}->{'quality'} );
        }

    }
    else {

        #we will try to set a default value in this order
        foreach my $cformat ( @{ [ $int_png, $int_jpeg, $int_bmp ] } ) {
            if ( $cformat > -1 ) {
                $combobox_type->set_active($cformat);
                last;
            }
        }

    }

    my $filetype_label = Gtk2::Label->new( $d->get("Image format") . ":" );
    $tooltips->set_tip( $combobox_type,  $d->get("Select a file format") );
    $tooltips->set_tip( $filetype_label, $d->get("Select a file format") );
    $filetype_box->pack_start( $filetype_label, FALSE, TRUE, 12 );
    $filetype_box->pack_start( $combobox_type,  TRUE,  TRUE, 0 );

    #end - filetype and scale
    #--------------------------------------

    #saveDir
    #--------------------------------------
    my $saveDir_label = Gtk2::Label->new( $d->get("Directory") . ":" );
    my $saveDir_button = Gtk2::FileChooserButton->new( "Shutter - " . $d->get("Choose folder"), 'select-folder' );
    if ( defined $settings_xml->{'general'}->{'folder'} ) {
        $saveDir_button->set_current_folder( $settings_xml->{'general'}->{'folder'} );
    }
    else {
        $saveDir_button->set_current_folder( Glib::get_user_special_dir('pictures') );
    }

    $tooltips->set_tip( $saveDir_button, $d->get("Your screenshots will be saved to this directory") );
    $tooltips->set_tip( $saveDir_label,  $d->get("Your screenshots will be saved to this directory") );
    $saveDir_box->pack_start( $saveDir_label,  FALSE, TRUE, 12 );
    $saveDir_box->pack_start( $saveDir_button, TRUE,  TRUE, 0 );

    #end - saveDir
    #--------------------------------------

    #save options
    #--------------------------------------
    my $save_ask_active = Gtk2::RadioButton->new_with_label( undef, $d->get("Browse for save folder every time") );
    $save_ask_box->pack_start( $save_ask_active, FALSE, TRUE, 12 );

    $tooltips->set_tip( $save_ask_active, $d->get("Browse for save folder every time") );

    my $save_no_active = Gtk2::RadioButton->new_with_label( $save_ask_active, $d->get("Do not save file automatically") );
    $save_no_box->pack_start( $save_no_active, FALSE, TRUE, 12 );

    $tooltips->set_tip( $save_no_active, $d->get("Do not save file automatically") );

    my $save_auto_active = Gtk2::RadioButton->new_with_label( $save_ask_active, $d->get("Automatically save file") );
    $save_auto_box->pack_start( $save_auto_active, FALSE, TRUE, 12 );

    $tooltips->set_tip( $save_auto_active, $d->get("Automatically save file") );

    #default state
    $save_ask_active->set_active(FALSE);
    $save_no_active->set_active(FALSE);
    $save_auto_active->set_active(TRUE);

    if ( defined $settings_xml->{'general'}->{'save_auto'} ) {
        $save_auto_active->set_active( $settings_xml->{'general'}->{'save_auto'} );
    }

    if ( defined $settings_xml->{'general'}->{'save_ask'} ) {
        $save_ask_active->set_active( $settings_xml->{'general'}->{'save_ask'} );
    }

    if ( defined $settings_xml->{'general'}->{'save_no'} ) {
        $save_no_active->set_active( $settings_xml->{'general'}->{'save_no'} );
    }

    #end - save options
    #--------------------------------------

    #image_autocopy
    #--------------------------------------
    my $image_autocopy_active = Gtk2::RadioButton->new_with_label( undef, $d->get("Automatically copy screenshot to clipboard") );
    $image_autocopy_box->pack_start( $image_autocopy_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'image_autocopy'} ) {
        $image_autocopy_active->set_active( $settings_xml->{'general'}->{'image_autocopy'} );
    }
    else {
        $image_autocopy_active->set_active(TRUE);
    }

    $tooltips->set_tip( $image_autocopy_active, $d->get("Automatically copy screenshot to clipboard") );

    #end - image_autocopy
    #--------------------------------------

    #fname_autocopy
    #--------------------------------------
    my $fname_autocopy_active = Gtk2::RadioButton->new_with_label( $image_autocopy_active, $d->get("Automatically copy filename to clipboard") );
    $fname_autocopy_box->pack_start( $fname_autocopy_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'fname_autocopy'} ) {
        $fname_autocopy_active->set_active( $settings_xml->{'general'}->{'fname_autocopy'} );
    }
    else {
        $fname_autocopy_active->set_active(FALSE);
    }

    $tooltips->set_tip( $fname_autocopy_active, $d->get("Automatically copy filename to clipboard") );

    #end - fname_autocopy
    #--------------------------------------

    #no_autocopy
    #--------------------------------------
    my $no_autocopy_active = Gtk2::RadioButton->new_with_label( $image_autocopy_active, $d->get("Do not copy anything to clipboard") );
    $no_autocopy_box->pack_start( $no_autocopy_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'no_autocopy'} ) {
        $no_autocopy_active->set_active( $settings_xml->{'general'}->{'no_autocopy'} );
    }
    else {
        $no_autocopy_active->set_active(FALSE);
    }

    $tooltips->set_tip( $no_autocopy_active, $d->get("Do not copy anything to clipboard") );

    #end - no_autocopy
    #--------------------------------------

    #delay
    #--------------------------------------

    #delay statusbar
    my $delay_status_label  = Gtk2::Label->new( $d->get("Delay") . ":" );
    my $delay_status        = Gtk2::SpinButton->new_with_range( 0, 99, 1 );
    my $delay_status_vlabel = Gtk2::Label->new( $d->nget( "second", "seconds", $delay_status->get_value ) );
    $delay_status->signal_connect(
        'value-changed' => \&evt_value_changed,
        'delay_status_changed'
    );

    #delay settings dialog
    my $delay_label  = Gtk2::Label->new( $d->get("Capture after a delay of") );
    my $delay        = Gtk2::SpinButton->new_with_range( 0, 99, 1 );
    my $delay_vlabel = Gtk2::Label->new( $d->nget( "second", "seconds", $delay->get_value ) );
    $delay->signal_connect(
        'value-changed' => \&evt_value_changed,
        'delay_changed'
    );

    if ( defined $settings_xml->{'general'}->{'delay'} ) {
        $delay->set_value( $settings_xml->{'general'}->{'delay'} );
    }
    else {
        $delay->set_value(0);
    }

    $tooltips->set_tip( $delay,        $d->get("Wait n seconds before taking a screenshot") );
    $tooltips->set_tip( $delay_label,  $d->get("Wait n seconds before taking a screenshot") );
    $tooltips->set_tip( $delay_vlabel, $d->get("Wait n seconds before taking a screenshot") );

    $tooltips->set_tip( $delay_status,        $d->get("Wait n seconds before taking a screenshot") );
    $tooltips->set_tip( $delay_status_label,  $d->get("Wait n seconds before taking a screenshot") );
    $tooltips->set_tip( $delay_status_vlabel, $d->get("Wait n seconds before taking a screenshot") );

    $delay_box->pack_start( $delay_label,  FALSE, FALSE, 12 );
    $delay_box->pack_start( $delay,        FALSE, FALSE, 0 );
    $delay_box->pack_start( $delay_vlabel, FALSE, FALSE, 2 );

    #end - delay
    #--------------------------------------

    #cursor
    #--------------------------------------
    my $cursor_status_active = Gtk2::CheckButton->new_with_label( $d->get("Include Cursor") );
    $tooltips->set_tip( $cursor_status_active, $d->get("Include cursor when taking a screenshot") );
    $cursor_status_active->signal_connect(
        'toggled' => \&evt_value_changed,
        'cursor_status_toggled'
    );

    my $cursor_active = Gtk2::CheckButton->new_with_label( $d->get("Include cursor when taking a screenshot") );
    $tooltips->set_tip( $cursor_active, $d->get("Include cursor when taking a screenshot") );
    $cursor_active->signal_connect(
        'toggled' => \&evt_value_changed,
        'cursor_toggled'
    );

    $cursor_box->pack_start( $cursor_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'cursor'} ) {
        $cursor_active->set_active( $settings_xml->{'general'}->{'cursor'} );
    }
    else {
        $cursor_active->set_active(FALSE);
    }

    #end - cursor
    #--------------------------------------

    #program
    #--------------------------------------
    my $model    = &fct_get_program_model;
    my $progname = Gtk2::ComboBox->new($model);

    #add pixbuf renderer for icon
    my $renderer_pix = Gtk2::CellRendererPixbuf->new;
    $progname->pack_start( $renderer_pix, FALSE );
    $progname->add_attribute( $renderer_pix, pixbuf => 0 );

    #add text renderer for app name
    my $renderer_text = Gtk2::CellRendererText->new;
    $progname->pack_start( $renderer_text, FALSE );
    $progname->add_attribute( $renderer_text, text => 1 );

    #try to set the saved value
    if ( defined $settings_xml->{'general'}->{'prog'} ) {
        $model->foreach( \&fct_iter_programs, $settings_xml->{'general'}->{'prog'} );
    }
    else {
        $progname->set_active(0);
    }

    #nothing has been set
    if ( $progname->get_active == -1 ) {
        $progname->set_active(0);
    }

    my $progname_active = Gtk2::CheckButton->new;
    $progname_active->set_active(TRUE);
    $progname_active->signal_connect(
        'toggled' => \&evt_value_changed,
        'progname_toggled'
    );
    if ( defined $settings_xml->{'general'}->{'prog_active'} ) {
        $progname_active->set_active( $settings_xml->{'general'}->{'prog_active'} );
    }
    else {
        $progname_active->set_active(FALSE);
    }
    my $progname_label = Gtk2::Label->new( $d->get("Open with") . ":" );
    $tooltips->set_tip( $progname,        $d->get("Open your screenshot with this program after capturing") );
    $tooltips->set_tip( $progname_active, $d->get("Open your screenshot with this program after capturing") );
    $tooltips->set_tip( $progname_label,  $d->get("Open your screenshot with this program after capturing") );
    $progname_box->pack_start( $progname_label,  FALSE, TRUE, 12 );
    $progname_box->pack_start( $progname_active, FALSE, TRUE, 0 );
    $progname_box->pack_start( $progname,        TRUE,  TRUE, 0 );

    #end - program
    #--------------------------------------

    #im_colors
    #--------------------------------------
    my $combobox_im_colors = Gtk2::ComboBox->new_text;
    $combobox_im_colors->insert_text( 0, $d->get("16 colors   - (4bit) ") );
    $combobox_im_colors->insert_text( 1, $d->get("64 colors   - (6bit) ") );
    $combobox_im_colors->insert_text( 2, $d->get("256 colors  - (8bit) ") );
    $combobox_im_colors->signal_connect(
        'changed' => \&evt_value_changed,
        'im_colors_changed'
    );

    if ( defined $settings_xml->{'general'}->{'im_colors'} ) {
        $combobox_im_colors->set_active( $settings_xml->{'general'}->{'im_colors'} );
    }
    else {
        $combobox_im_colors->set_active(2);
    }

    my $im_colors_active = Gtk2::CheckButton->new;
    $im_colors_active->set_active(TRUE);
    $im_colors_active->signal_connect(
        'toggled' => \&evt_value_changed,
        'im_colors_toggled'
    );

    if ( defined $settings_xml->{'general'}->{'im_colors_active'} ) {
        $im_colors_active->set_active( $settings_xml->{'general'}->{'im_colors_active'} );
    }
    else {
        $im_colors_active->set_active(FALSE);
    }

    my $im_colors_label = Gtk2::Label->new( $d->get("Reduce colors") . ":" );
    $tooltips->set_tip( $combobox_im_colors, $d->get("Automatically reduce colors after taking a screenshot") );
    $tooltips->set_tip( $im_colors_active,   $d->get("Automatically reduce colors after taking a screenshot") );
    $tooltips->set_tip( $im_colors_label,    $d->get("Automatically reduce colors after taking a screenshot") );
    $im_colors_box->pack_start( $im_colors_label,    FALSE, TRUE, 12 );
    $im_colors_box->pack_start( $im_colors_active,   FALSE, TRUE, 0 );
    $im_colors_box->pack_start( $combobox_im_colors, TRUE,  TRUE, 0 );

    #end - colors
    #--------------------------------------

    #thumbnail
    #--------------------------------------
    my $thumbnail_label = Gtk2::Label->new( $d->get("Thumbnail") . ":" );
    my $thumbnail = Gtk2::HScale->new_with_range( 1, 100, 1 );
    $thumbnail->signal_connect(
        'value-changed' => \&evt_value_changed,
        'thumbnail_changed'
    );
    $thumbnail->set_value_pos('right');

    if ( defined $settings_xml->{'general'}->{'thumbnail'} ) {
        $thumbnail->set_value( $settings_xml->{'general'}->{'thumbnail'} );
    }
    else {
        $thumbnail->set_value(50);
    }
    my $thumbnail_active = Gtk2::CheckButton->new;
    $thumbnail_active->set_active(TRUE);
    $thumbnail_active->signal_connect(
        'toggled' => \&evt_value_changed,
        'thumbnail_toggled'
    );

    if ( defined $settings_xml->{'general'}->{'thumbnail_active'} ) {
        $thumbnail_active->set_active( $settings_xml->{'general'}->{'thumbnail_active'} );
    }
    else {
        $thumbnail_active->set_active(FALSE);
    }
    $tooltips->set_tip( $thumbnail,        $d->get("Generate thumbnail too.\nselect the percentage of the original size for the thumbnail to be") );
    $tooltips->set_tip( $thumbnail_active, $d->get("Generate thumbnail too.\nselect the percentage of the original size for the thumbnail to be") );
    $tooltips->set_tip( $thumbnail_label,  $d->get("Generate thumbnail too.\nselect the percentage of the original size for the thumbnail to be") );
    $thumbnail_box->pack_start( $thumbnail_label,  FALSE, TRUE,  12 );
    $thumbnail_box->pack_start( $thumbnail_active, FALSE, FALSE, 0 );
    $thumbnail_box->pack_start( $thumbnail,        TRUE,  TRUE,  0 );

    #end - thumbnail
    #--------------------------------------

    #bordereffect
    #--------------------------------------
    my $bordereffect_active = Gtk2::CheckButton->new;
    $bordereffect_active->set_active(TRUE);

    my $bordereffect_label  = Gtk2::Label->new( $d->get("Border") . ":" );
    my $bordereffect        = Gtk2::SpinButton->new_with_range( 1, 100, 1 );
    my $bordereffect_vlabel = Gtk2::Label->new( $d->get("pixels") );

    my $bordereffect_clabel = Gtk2::Label->new( $d->get("Color") . ":" );
    my $bordereffect_cbtn   = Gtk2::ColorButton->new();
    $bordereffect_cbtn->set_use_alpha(FALSE);
    $bordereffect_cbtn->set_title( $d->get("Choose border color") );

    $tooltips->set_tip( $bordereffect_active, $d->get("Adds a border effect to the screenshot") );
    $tooltips->set_tip( $bordereffect,        $d->get("Adds a border effect to the screenshot") );
    $tooltips->set_tip( $bordereffect_label,  $d->get("Adds a border effect to the screenshot") );

    $tooltips->set_tip( $bordereffect_clabel, $d->get("Choose border color") );
    $tooltips->set_tip( $bordereffect_cbtn,   $d->get("Choose border color") );

    $bordereffect_box->pack_start( $bordereffect_label,  FALSE, TRUE,  12 );
    $bordereffect_box->pack_start( $bordereffect_active, FALSE, FALSE, 0 );
    $bordereffect_box->pack_start( $bordereffect,        TRUE,  TRUE,  2 );
    $bordereffect_box->pack_start( $bordereffect_vlabel, FALSE, FALSE, 2 );
    $bordereffect_box->pack_start( $bordereffect_clabel, FALSE, FALSE, 12 );
    $bordereffect_box->pack_start( $bordereffect_cbtn,   FALSE, FALSE, 0 );

    $bordereffect_active->signal_connect(
        'toggled' => \&evt_value_changed,
        'bordereffect_toggled'
    );

    $bordereffect->signal_connect(
        'value-changed' => \&evt_value_changed,
        'bordereffect_changed'
    );

    if ( defined $settings_xml->{'general'}->{'bordereffect_active'} ) {
        $bordereffect_active->set_active( $settings_xml->{'general'}->{'bordereffect_active'} );
    }
    else {
        $bordereffect_active->set_active(FALSE);
    }

    if ( defined $settings_xml->{'general'}->{'bordereffect'} ) {
        $bordereffect->set_value( $settings_xml->{'general'}->{'bordereffect'} );
    }
    else {
        $bordereffect->set_value(2);
    }

    if ( defined $settings_xml->{'general'}->{'bordereffect_col'} ) {
        $bordereffect_cbtn->set_color( Gtk2::Gdk::Color->parse( $settings_xml->{'general'}->{'bordereffect_col'} ) );
    }
    else {
        $bordereffect_cbtn->set_color( Gtk2::Gdk::Color->parse('black') );
    }

    #end - bordereffect
    #--------------------------------------

    #zoom window
    #--------------------------------------
    my $zoom_active = Gtk2::CheckButton->new_with_label( $d->get("Enable zoom window") );

    if ( defined $settings_xml->{'general'}->{'zoom_active'} ) {
        $zoom_active->set_active( $settings_xml->{'general'}->{'zoom_active'} );
    }
    else {
        $zoom_active->set_active(TRUE);
    }

    $tooltips->set_tip( $zoom_active, $d->get("Enable zoom window") );

    $zoom_box->pack_start( $zoom_active, FALSE, TRUE, 12 );

    #end - zoom window
    #--------------------------------------

    #initial size for selection tool
    #--------------------------------------
    my $asel_size_label1  = Gtk2::Label->new( $d->get("Start with selection size of") );
    my $asel_size_label2  = Gtk2::Label->new("x");
    my $asel_size_label3  = Gtk2::Label->new( $d->get("at") );
    my $asel_size_label4  = Gtk2::Label->new(",");
    my $asel_size1        = Gtk2::SpinButton->new_with_range( 0, 10000, 1 );
    my $asel_size2        = Gtk2::SpinButton->new_with_range( 0, 10000, 1 );
    my $asel_size3        = Gtk2::SpinButton->new_with_range( 0, 10000, 1 );
    my $asel_size4        = Gtk2::SpinButton->new_with_range( 0, 10000, 1 );
    my $asel_size_vlabel1 = Gtk2::Label->new( $d->get("pixels") );
    my $asel_size_vlabel2 = Gtk2::Label->new( $d->get("pixels") );

    if ( defined $settings_xml->{'general'}->{'asel_x'} ) {
        $asel_size3->set_value( $settings_xml->{'general'}->{'asel_x'} );
    }
    else {
        $asel_size3->set_value(0);
    }
    if ( defined $settings_xml->{'general'}->{'asel_y'} ) {
        $asel_size4->set_value( $settings_xml->{'general'}->{'asel_y'} );
    }
    else {
        $asel_size4->set_value(0);
    }
    if ( defined $settings_xml->{'general'}->{'asel_w'} ) {
        $asel_size1->set_value( $settings_xml->{'general'}->{'asel_w'} );
    }
    else {
        $asel_size1->set_value(0);
    }
    if ( defined $settings_xml->{'general'}->{'asel_h'} ) {
        $asel_size2->set_value( $settings_xml->{'general'}->{'asel_h'} );
    }
    else {
        $asel_size2->set_value(0);
    }

    $tooltips->set_tip( $asel_size_label1,  $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size_label2,  $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size_label3,  $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size_label4,  $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size1,        $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size2,        $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size3,        $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size4,        $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size_vlabel1, $d->get("Start Selection Tool with a customized selection size") );
    $tooltips->set_tip( $asel_size_vlabel2, $d->get("Start Selection Tool with a customized selection size") );

    $asel_isize_box->pack_start( $asel_size_label1,  FALSE, FALSE, 12 );
    $asel_isize_box->pack_start( $asel_size1,        FALSE, FALSE, 0 );
    $asel_isize_box->pack_start( $asel_size_label2,  FALSE, FALSE, 0 );
    $asel_isize_box->pack_start( $asel_size2,        FALSE, FALSE, 0 );
    $asel_isize_box->pack_start( $asel_size_vlabel1, FALSE, FALSE, 2 );
    $asel_isize_box2->pack_start( $asel_size_label3,  FALSE, FALSE, 12 );
    $asel_isize_box2->pack_start( $asel_size3,        FALSE, FALSE, 0 );
    $asel_isize_box2->pack_start( $asel_size_label4,  FALSE, FALSE, 0 );
    $asel_isize_box2->pack_start( $asel_size4,        FALSE, FALSE, 0 );
    $asel_isize_box2->pack_start( $asel_size_vlabel2, FALSE, FALSE, 2 );

    #end - initial size for advanced selection tool
    #--------------------------------------

    #show help text when using advanced selection tool
    #--------------------------------------
    my $as_help_active = Gtk2::CheckButton->new_with_label( $d->get("Show help text") );

    if ( defined $settings_xml->{'general'}->{'as_help_active'} ) {
        $as_help_active->set_active( $settings_xml->{'general'}->{'as_help_active'} );
    }
    else {
        $as_help_active->set_active(TRUE);
    }

    $tooltips->set_tip( $as_help_active, $d->get("Enables the help text") );

    $as_help_box->pack_start( $as_help_active, FALSE, TRUE, 12 );

    #end - show help text when using advanced selection tool
    #--------------------------------------

    #border
    #--------------------------------------
    my $border_active = Gtk2::CheckButton->new_with_label( $d->get("Include window decoration when capturing a window") );
    $tooltips->set_tip( $border_active, $d->get("Include window decoration when capturing a window") );

    $border_box->pack_start( $border_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'border'} ) {
        $border_active->set_active( $settings_xml->{'general'}->{'border'} );
    }
    else {
        $border_active->set_active(TRUE);
    }

    #end - border
    #--------------------------------------

    #window resize
    #--------------------------------------
    my ( $x, $y, $w, $h ) = Gtk2::Gdk->get_default_root_window->get_geometry;

    my $winresize_active = Gtk2::CheckButton->new_with_label( $d->get("Automatically resize window to") );
    my $winresize_label  = Gtk2::Label->new("x");
    my $winresize_w      = Gtk2::SpinButton->new_with_range( 0, $w, 1 );
    my $winresize_h      = Gtk2::SpinButton->new_with_range( 0, $h, 1 );
    my $winresize_vlabel = Gtk2::Label->new( $d->get("pixels") );

    if ( defined $settings_xml->{'general'}->{'winresize_active'} ) {
        $winresize_active->set_active( $settings_xml->{'general'}->{'winresize_active'} );
    }
    else {
        $winresize_active->set_active(FALSE);
    }

    if ( defined $settings_xml->{'general'}->{'winresize_w'} ) {
        $winresize_w->set_value( $settings_xml->{'general'}->{'winresize_w'} );
    }
    else {
        $winresize_w->set_value(500);
    }

    if ( defined $settings_xml->{'general'}->{'winresize_h'} ) {
        $winresize_h->set_value( $settings_xml->{'general'}->{'winresize_h'} );
    }
    else {
        $winresize_h->set_value(500);
    }

    $tooltips->set_tip( $winresize_active, $d->get("This resizes the window automatically to the specified width and height. This method asks the window manager to resize the window. However, the window manager may not allow the resize.") );
    $tooltips->set_tip( $winresize_w,      $d->get("This resizes the window automatically to the specified width and height. This method asks the window manager to resize the window. However, the window manager may not allow the resize.") );
    $tooltips->set_tip( $winresize_label,  $d->get("This resizes the window automatically to the specified width and height. This method asks the window manager to resize the window. However, the window manager may not allow the resize.") );
    $tooltips->set_tip( $winresize_h,      $d->get("This resizes the window automatically to the specified width and height. This method asks the window manager to resize the window. However, the window manager may not allow the resize.") );
    $tooltips->set_tip( $winresize_vlabel, $d->get("This resizes the window automatically to the specified width and height. This method asks the window manager to resize the window. However, the window manager may not allow the resize.") );

    $winresize_box->pack_start( $winresize_active, FALSE, FALSE, 12 );
    $winresize_box->pack_start( $winresize_w,      FALSE, FALSE, 0 );
    $winresize_box->pack_start( $winresize_label,  FALSE, FALSE, 0 );
    $winresize_box->pack_start( $winresize_h,      FALSE, FALSE, 0 );
    $winresize_box->pack_start( $winresize_vlabel, FALSE, FALSE, 2 );

    #end - window resize
    #--------------------------------------

    #window autoshape
    #--------------------------------------
    my $autoshape_active = Gtk2::CheckButton->new_with_label( $d->get("Force rounded window corners") );

    if ( defined $settings_xml->{'general'}->{'autoshape_active'} ) {
        $autoshape_active->set_active( $settings_xml->{'general'}->{'autoshape_active'} );
    }
    else {
        $autoshape_active->set_active(FALSE);
    }

    $tooltips->set_tip( $autoshape_active, sprintf( $d->get( "Shutter uses the XShape extension to determine the window's shape, " . "but this does not work under some circumstances, e.g. when running compiz.\n\n" . "When this option is activated Shutter uses fixed parameters to round the window corners. " . "You can overwrite the default parameters by creating a file named ~/.shutter/shape.conf and put custom values in it. " . "The default values are stored in %s." ), "$shutter_root/share/shutter/resources/conf/shape.conf" ) );

    $autoshape_box->pack_start( $autoshape_active, FALSE, FALSE, 12 );

    #end - window autoshape
    #--------------------------------------

    #visible windows only
    #--------------------------------------
    my $visible_windows_active = Gtk2::CheckButton->new_with_label( $d->get("Select only visible windows") );
    $tooltips->set_tip( $visible_windows_active, $d->get("Select only visible windows") );

    $visible_windows_box->pack_start( $visible_windows_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'visible_windows'} ) {
        $visible_windows_active->set_active( $settings_xml->{'general'}->{'visible_windows'} );
    }
    else {
        $visible_windows_active->set_active(FALSE);
    }

    #end - visible windows only
    #--------------------------------------

    #menu capture delay
    #--------------------------------------
    #delay settings dialog
    my $menu_delay_label  = Gtk2::Label->new( $d->get("Pre-Capture Delay") . ":" );
    my $menu_delay        = Gtk2::SpinButton->new_with_range( 1, 99, 1 );
    my $menu_delay_vlabel = Gtk2::Label->new( $d->nget( "second", "seconds", $delay->get_value ) );
    $menu_delay->signal_connect(
        'value-changed' => \&evt_value_changed,
        'menu_delay_changed'
    );

    if ( defined $settings_xml->{'general'}->{'menu_delay'} ) {
        $menu_delay->set_value( $settings_xml->{'general'}->{'menu_delay'} );
    }
    else {
        $menu_delay->set_value(10);
    }

    $tooltips->set_tip( $menu_delay,        $d->get("Capture menu/tooltip after a delay of n seconds") );
    $tooltips->set_tip( $menu_delay_label,  $d->get("Capture menu/tooltip after a delay of n seconds") );
    $tooltips->set_tip( $menu_delay_vlabel, $d->get("Capture menu/tooltip after a delay of n seconds") );

    $menu_delay_box->pack_start( $menu_delay_label,  FALSE, TRUE, 12 );
    $menu_delay_box->pack_start( $menu_delay,        FALSE, TRUE, 0 );
    $menu_delay_box->pack_start( $menu_delay_vlabel, FALSE, TRUE, 2 );

    #end - menu capture delay
    #--------------------------------------

    #menu/tooltip workaround
    #--------------------------------------
    my $menu_waround_active = Gtk2::CheckButton->new_with_label( $d->get("Ignore possibly wrong type hints") );
    $tooltips->set_tip( $menu_waround_active, $d->get("The type hint constants specify hints for the window manager that indicate what type of function the window has. Sometimes these type hints are not correctly set. By enabling this option Shutter will not insist on the requested type hint.") );

    $menu_waround_box->pack_start( $menu_waround_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'menu_waround'} ) {
        $menu_waround_active->set_active( $settings_xml->{'general'}->{'menu_waround'} );
    }
    else {
        $menu_waround_active->set_active(TRUE);
    }

    #end - menu/tooltip workaround
    #--------------------------------------

    #web width
    #--------------------------------------
    my $web_width_label    = Gtk2::Label->new( $d->get("Virtual browser width") . ":" );
    my $combobox_web_width = Gtk2::ComboBox->new_text;
    $combobox_web_width->insert_text( 0,  "640" );
    $combobox_web_width->insert_text( 1,  "800" );
    $combobox_web_width->insert_text( 2,  "1024" );
    $combobox_web_width->insert_text( 3,  "1152" );
    $combobox_web_width->insert_text( 4,  "1280" );
    $combobox_web_width->insert_text( 5,  "1366" );
    $combobox_web_width->insert_text( 6,  "1440" );
    $combobox_web_width->insert_text( 7,  "1600" );
    $combobox_web_width->insert_text( 8,  "1680" );
    $combobox_web_width->insert_text( 9,  "1920" );
    $combobox_web_width->insert_text( 10, "2048" );
    my $web_width_vlabel = Gtk2::Label->new( $d->get("pixels") );

    if ( defined $settings_xml->{'general'}->{'web_width'} ) {
        $combobox_web_width->set_active( $settings_xml->{'general'}->{'web_width'} );
    }
    else {
        $combobox_web_width->set_active(2);
    }

    $tooltips->set_tip( $web_width_label,    $d->get("Virtual browser width when taking a website screenshot") );
    $tooltips->set_tip( $combobox_web_width, $d->get("Virtual browser width when taking a website screenshot") );
    $tooltips->set_tip( $web_width_vlabel,   $d->get("Virtual browser width when taking a website screenshot") );

    $web_width_box->pack_start( $web_width_label,    FALSE, TRUE, 12 );
    $web_width_box->pack_start( $combobox_web_width, FALSE, TRUE, 0 );
    $web_width_box->pack_start( $web_width_vlabel,   FALSE, TRUE, 2 );

    #end - web width
    #--------------------------------------

    #imageview
    #--------------------------------------
    my $trans_check  = Gtk2::RadioButton->new( undef,        $d->get("Show as check pattern") );
    my $trans_custom = Gtk2::RadioButton->new( $trans_check, $d->get("Show as custom color:") );
    my $trans_custom_btn = Gtk2::ColorButton->new();
    $trans_custom_btn->set_use_alpha(FALSE);
    $trans_custom_btn->set_title( $d->get("Choose fill color") );

    my $trans_backg = Gtk2::RadioButton->new( $trans_custom, $d->get("Show as background") );

    $imageview_hbox1->pack_start( $trans_check,      FALSE, TRUE, 12 );
    $imageview_hbox2->pack_start( $trans_custom,     FALSE, TRUE, 12 );
    $imageview_hbox2->pack_start( $trans_custom_btn, FALSE, TRUE, 0 );
    $imageview_hbox3->pack_start( $trans_backg,      FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'trans_custom_col'} ) {
        $trans_custom_btn->set_color( Gtk2::Gdk::Color->parse( $settings_xml->{'general'}->{'trans_custom_col'} ) );
    }
    else {
        $trans_custom_btn->set_color( Gtk2::Gdk::Color->parse('black') );
    }

    if (   defined $settings_xml->{'general'}->{'trans_check'}
        && defined $settings_xml->{'general'}->{'trans_custom'}
        && defined $settings_xml->{'general'}->{'trans_backg'} )
    {
        $trans_check->set_active( $settings_xml->{'general'}->{'trans_check'} );
        $trans_custom->set_active( $settings_xml->{'general'}->{'trans_custom'} );
        $trans_backg->set_active( $settings_xml->{'general'}->{'trans_backg'} );
    }
    else {
        $trans_check->set_active(TRUE);
    }

    $tooltips->set_tip( $trans_check,  $d->get("Displays any transparent parts of the image in a check pattern") );
    $tooltips->set_tip( $trans_custom, $d->get("Displays any transparent parts of the image in a solid color that you specify") );
    $tooltips->set_tip( $trans_backg,  $d->get("Displays any transparent parts of the image in the background color of the application") );

    #connect signals after restoring the saved state
    $trans_check->signal_connect(
        'toggled' => \&evt_value_changed,
        'transp_toggled'
    );

    $trans_custom->signal_connect(
        'toggled' => \&evt_value_changed,
        'transp_toggled'
    );

    $trans_custom_btn->signal_connect(
        'color-set' => \&evt_value_changed,
        'transp_toggled'
    );

    $trans_backg->signal_connect(
        'toggled' => \&evt_value_changed,
        'transp_toggled'
    );

    #session view
    my $session_asc = Gtk2::RadioButton->new( undef, $d->get("Sort ascending by") );
    my $session_asc_combo = Gtk2::ComboBox->new_text();
    $session_asc_combo->insert_text( 0, $d->get("Filename") );
    $session_asc_combo->insert_text( 1, $d->get("Key/Time Created") );
    my $session_desc = Gtk2::RadioButton->new( $session_asc, $d->get("Sort descending by") );
    my $session_desc_combo = Gtk2::ComboBox->new_text();
    $session_desc_combo->insert_text( 0, $d->get("Filename") );
    $session_desc_combo->insert_text( 1, $d->get("Key/Time Created") );

    $session_hbox1->pack_start( $session_asc,        FALSE, TRUE, 12 );
    $session_hbox1->pack_start( $session_asc_combo,  FALSE, TRUE, 0 );
    $session_hbox2->pack_start( $session_desc,       FALSE, TRUE, 12 );
    $session_hbox2->pack_start( $session_desc_combo, FALSE, TRUE, 0 );

    if (   defined $settings_xml->{'general'}->{'session_asc'}
        && defined $settings_xml->{'general'}->{'session_desc'} )
    {
        $session_asc->set_active( $settings_xml->{'general'}->{'session_asc'} );
        $session_desc->set_active( $settings_xml->{'general'}->{'session_desc'} );
    }
    else {
        $session_desc->set_active(TRUE);
    }

    if ( defined $settings_xml->{'general'}->{'session_asc_combo'} ) {
        $session_asc_combo->set_active( $settings_xml->{'general'}->{'session_asc_combo'} );
    }
    else {
        $session_asc_combo->set_active(1);
    }

    if ( defined $settings_xml->{'general'}->{'session_desc_combo'} ) {
        $session_desc_combo->set_active( $settings_xml->{'general'}->{'session_desc_combo'} );
    }
    else {
        $session_desc_combo->set_active(1);
    }

    $session_asc->signal_connect(
        'toggled',
        sub {
            $st->{_sorta}->set_active( $session_asc->get_active );
        }
    );

    $session_desc->signal_connect(
        'toggled',
        sub {
            $st->{_sortd}->set_active( $session_desc->get_active );
        }
    );

    $session_asc_combo->signal_connect(
        'changed',
        sub {
            $st->{_sorta}->signal_emit('toggled') if $session_asc->get_active;
        }
    );

    $session_desc_combo->signal_connect(
        'changed',
        sub {
            $st->{_sortd}->signal_emit('toggled') if $session_desc->get_active;
        }
    );

    $tooltips->set_tip( $session_asc,        $d->get("Configure sort criteria") );
    $tooltips->set_tip( $session_asc_combo,  $d->get("Configure sort criteria") );
    $tooltips->set_tip( $session_desc,       $d->get("Configure sort criteria") );
    $tooltips->set_tip( $session_desc_combo, $d->get("Configure sort criteria") );

    #end - imageview
    #--------------------------------------

    #behavior
    #--------------------------------------
    my $fs_active       = Gtk2::CheckButton->new_with_label( $d->get("Start Shutter at login") );
    my $fs_min_active   = Gtk2::CheckButton->new_with_label( $d->get("Hide window on first launch") );
    my $fs_nonot_active = Gtk2::CheckButton->new_with_label( $d->get("Hide notification icon") );

    my $hide_active      = Gtk2::CheckButton->new_with_label( $d->get("Autohide main window when taking a screenshot") );
    my $hide_time_label  = Gtk2::Label->new( $d->get("Redraw Delay") . ":" );
    my $hide_time_vlabel = Gtk2::Label->new;
    my $hide_time        = Gtk2::SpinButton->new_with_range( 100, 1000, 50 );
    $hide_time_vlabel->set_text( $d->nget( "millisecond", "milliseconds", $hide_time->get_value ) );
    $hide_time->signal_connect(
        'value-changed' => \&evt_value_changed,
        'hide_time_changed'
    );

    my $present_after_active  = Gtk2::CheckButton->new_with_label( $d->get("Present main window after taking a screenshot") );
    my $close_at_close_active = Gtk2::CheckButton->new_with_label( $d->get("Minimize to tray when closing main window") );

    my $notify_after_active    = Gtk2::CheckButton->new_with_label( $d->get("Display pop-up notification after taking a screenshot") );
    my $notify_timeout_active  = Gtk2::CheckButton->new_with_label( $d->get("Display pop-up notification when using a delay") );
    my $notify_ptimeout_active = Gtk2::CheckButton->new_with_label( $d->get("Display pop-up notification when using a pre-capture delay") );

    my $ns_label    = Gtk2::Label->new( $d->get("Notification agent") . ":" );
    my $combobox_ns = Gtk2::ComboBox->new_text;
    $combobox_ns->append_text( $d->get("Desktop Notifications") );
    $combobox_ns->append_text( $d->get("Built-In Notifications") );

    $combobox_ns->signal_connect(
        'changed' => \&evt_value_changed,
        'ns_changed'
    );

    my $ask_on_delete_active    = Gtk2::CheckButton->new_with_label( $d->get("Ask before moving files to trash") );
    my $delete_on_close_active  = Gtk2::CheckButton->new_with_label( $d->get("Move file to trash when closing tab") );
    my $ask_on_fs_delete_active = Gtk2::CheckButton->new_with_label( $d->get("Notify when file was deleted from filesystem") );

    $fs_active_hbox->pack_start( $fs_active, FALSE, TRUE, 12 );
    $fs_min_active_hbox->pack_start( $fs_min_active, FALSE, TRUE, 12 );
    $fs_nonot_active_hbox->pack_start( $fs_nonot_active, FALSE, TRUE, 12 );
    $hide_active_hbox->pack_start( $hide_active, FALSE, TRUE, 12 );
    $pafter_active_hbox->pack_start( $present_after_active, FALSE, TRUE, 12 );
    $cac_hbox->pack_start( $close_at_close_active, FALSE, TRUE, 12 );
    $hide_time_hbox->pack_start( $hide_time_label,       FALSE, TRUE, 12 );
    $hide_time_hbox->pack_start( $hide_time,             FALSE, TRUE, 6 );
    $hide_time_hbox->pack_start( $hide_time_vlabel,      FALSE, TRUE, 0 );
    $na_active_hbox->pack_start( $notify_after_active,   FALSE, TRUE, 12 );
    $nt_active_hbox->pack_start( $notify_timeout_active, FALSE, TRUE, 12 );
    $npt_active_hbox->pack_start( $notify_ptimeout_active, FALSE, TRUE, 12 );
    $ns_combo_hbox->pack_start( $ns_label,    FALSE, TRUE, 12 );
    $ns_combo_hbox->pack_start( $combobox_ns, FALSE, TRUE, 0 );
    $aod_active_hbox->pack_start( $ask_on_delete_active,   FALSE, TRUE, 12 );
    $doc_active_hbox->pack_start( $delete_on_close_active, FALSE, TRUE, 12 );
    $aofsd_active_hbox->pack_start( $ask_on_fs_delete_active, FALSE, TRUE, 12 );

    if ( defined $settings_xml->{'general'}->{'autofs'} ) {
        $fs_active->set_active( $settings_xml->{'general'}->{'autofs'} );
    }
    else {
        $fs_active->set_active(FALSE);
    }

    $tooltips->set_tip( $fs_active, $d->get("Start Shutter at login") );

    if ( defined $settings_xml->{'general'}->{'autofs_min'} ) {
        $fs_min_active->set_active( $settings_xml->{'general'}->{'autofs_min'} );
    }
    else {
        $fs_min_active->set_active(FALSE);
    }

    $tooltips->set_tip( $fs_min_active, $d->get("Hide window on first launch") );

    if ( defined $settings_xml->{'general'}->{'autofs_not'} ) {
        $fs_nonot_active->set_active( $settings_xml->{'general'}->{'autofs_not'} );
    }
    else {
        $fs_nonot_active->set_active(FALSE);
    }

    $tooltips->set_tip( $fs_nonot_active, $d->get("Hide notification icon") );

    if ( defined $settings_xml->{'general'}->{'autohide'} ) {
        $hide_active->set_active( $settings_xml->{'general'}->{'autohide'} );
    }
    else {
        $hide_active->set_active(TRUE);
    }

    $tooltips->set_tip( $hide_active, $d->get("Autohide main window when taking a screenshot") );

    if ( defined $settings_xml->{'general'}->{'autohide_time'} ) {
        $hide_time->set_value( $settings_xml->{'general'}->{'autohide_time'} );
    }
    else {
        $hide_time->set_value(400);
    }

    $tooltips->set_tip( $hide_time_label,  $d->get("Configure a short timeout to give the Xserver a chance to redraw areas that were obscured by Shutter's windows before taking a screenshot.") );
    $tooltips->set_tip( $hide_time,        $d->get("Configure a short timeout to give the Xserver a chance to redraw areas that were obscured by Shutter's windows before taking a screenshot.") );
    $tooltips->set_tip( $hide_time_vlabel, $d->get("Configure a short timeout to give the Xserver a chance to redraw areas that were obscured by Shutter's windows before taking a screenshot.") );

    #If get_exit_after_capture is TRUE, overwrite any saved setting
    #because presenting the window does not make sense here
    if ( $sc->get_exit_after_capture ) {
        $present_after_active->set_active(FALSE);
    }
    else {
        if ( defined $settings_xml->{'general'}->{'present_after'} ) {
            $present_after_active->set_active( $settings_xml->{'general'}->{'present_after'} );
        }
        else {
            $present_after_active->set_active(TRUE);
        }
    }

    $tooltips->set_tip( $present_after_active, $d->get("Present main window after taking a screenshot") );

    if ( defined $settings_xml->{'general'}->{'notify_after'} ) {
        $notify_after_active->set_active( $settings_xml->{'general'}->{'notify_after'} );
    }
    else {
        $notify_after_active->set_active(TRUE);
    }

    $tooltips->set_tip( $notify_after_active, $d->get("Display pop-up notification after taking a screenshot") );

    if ( defined $settings_xml->{'general'}->{'notify_timeout'} ) {
        $notify_timeout_active->set_active( $settings_xml->{'general'}->{'notify_timeout'} );
    }
    else {
        $notify_timeout_active->set_active(TRUE);
    }

    $tooltips->set_tip( $notify_timeout_active, $d->get("Display pop-up notification when using a delay") );

    if ( defined $settings_xml->{'general'}->{'notify_ptimeout'} ) {
        $notify_ptimeout_active->set_active( $settings_xml->{'general'}->{'notify_ptimeout'} );
    }
    else {
        $notify_ptimeout_active->set_active(TRUE);
    }

    $tooltips->set_tip( $notify_timeout_active, $d->get("Display pop-up notification when using a delay") );

    if ( defined $settings_xml->{'general'}->{'notify_agent'} ) {
        $combobox_ns->set_active( $settings_xml->{'general'}->{'notify_agent'} );
    }
    else {
        $combobox_ns->set_active(TRUE);
    }

    $tooltips->set_tip( $ns_label,    $d->get("You can either choose the system-wide desktop notifications (e.g. Ubuntu's Notify-OSD) or Shutter's built-in notification system") );
    $tooltips->set_tip( $combobox_ns, $d->get("You can either choose the system-wide desktop notifications (e.g. Ubuntu's Notify-OSD) or Shutter's built-in notification system") );

    if ( defined $settings_xml->{'general'}->{'close_at_close'} ) {
        $close_at_close_active->set_active( $settings_xml->{'general'}->{'close_at_close'} );
    }
    else {
        $close_at_close_active->set_active(TRUE);
    }

    $tooltips->set_tip( $close_at_close_active, $d->get("Minimize to tray when closing main window") );

    if ( defined $settings_xml->{'general'}->{'ask_on_delete'} ) {
        $ask_on_delete_active->set_active( $settings_xml->{'general'}->{'ask_on_delete'} );
    }
    else {
        $ask_on_delete_active->set_active(FALSE);
    }

    $tooltips->set_tip( $ask_on_delete_active, $d->get("Ask before moving files to trash") );

    if ( defined $settings_xml->{'general'}->{'delete_on_close'} ) {
        $delete_on_close_active->set_active( $settings_xml->{'general'}->{'delete_on_close'} );
    }
    else {
        $delete_on_close_active->set_active(FALSE);
    }

    $tooltips->set_tip( $delete_on_close_active, $d->get("Move file to trash when closing tab") );

    if ( defined $settings_xml->{'general'}->{'ask_on_fs_delete'} ) {
        $ask_on_fs_delete_active->set_active( $settings_xml->{'general'}->{'ask_on_fs_delete'} );
    }
    else {
        $ask_on_fs_delete_active->set_active(FALSE);
    }

    $tooltips->set_tip( $ask_on_fs_delete_active, $d->get("Notify when file was deleted from filesystem") );

    #end - behavior
    #--------------------------------------

    #accounts
    #--------------------------------------
    my $accounts_model = undef;
    &fct_load_accounts_tree;

    my $accounts_tree = Gtk2::TreeView->new_with_model($accounts_model);

    $accounts_tree->signal_connect(
        'row-activated' => \&evt_accounts,
        'row_activated'
    );

    &fct_set_model_accounts($accounts_tree);

    #some notes related to uploading
    my $pub_hint_pref = Gtk2::Label->new();
    $pub_hint_pref->set_line_wrap(TRUE);
    if ( Gtk2->CHECK_VERSION( 2, 9, 0 ) ) {
        $pub_hint_pref->set_line_wrap_mode('word-char');
    }

    $pub_hint_pref->set_markup( "<span size='small'>" . $d->get("<b>Please note:</b> If a plugin allows authorized uploading you can enter your credentials above. Plugins with OAuth support are configured automatically the first time you use them.") . "</span>" );

    #ftp uri
    my $ftp_entry_label = Gtk2::Label->new( $d->get("URI") . ":" );

    my $ftp_remote_entry = Gtk2::Entry->new;
    if ( defined $settings_xml->{'general'}->{'ftp_uri'} ) {
        $ftp_remote_entry->set_text( $settings_xml->{'general'}->{'ftp_uri'} );
    }
    else {
        $ftp_remote_entry->set_text("ftp://host:port/path");
    }

    $tooltips->set_tip( $ftp_entry_label, $d->get("URI\nExample: ftp://host:port/path") );

    $tooltips->set_tip( $ftp_remote_entry, $d->get("URI\nExample: ftp://host:port/path") );

    $ftp_hbox1->pack_start( $ftp_entry_label,  FALSE, TRUE, 12 );
    $ftp_hbox1->pack_start( $ftp_remote_entry, TRUE,  TRUE, 0 );

    #connection mode
    my $ftp_mode_label = Gtk2::Label->new( $d->get("Connection mode") . ":" );

    my $ftp_mode_combo = Gtk2::ComboBox->new_text;
    $ftp_mode_combo->insert_text( 0, $d->get("Active mode") );
    $ftp_mode_combo->insert_text( 1, $d->get("Passive mode") );
    if ( defined $settings_xml->{'general'}->{'ftp_mode'} ) {
        $ftp_mode_combo->set_active( $settings_xml->{'general'}->{'ftp_mode'} );
    }
    else {
        $ftp_mode_combo->set_active(0);
    }

    $tooltips->set_tip( $ftp_mode_label, $d->get("Connection mode") );

    $tooltips->set_tip( $ftp_mode_combo, $d->get("Connection mode") );

    $ftp_hbox2->pack_start( $ftp_mode_label, FALSE, TRUE, 12 );
    $ftp_hbox2->pack_start( $ftp_mode_combo, TRUE,  TRUE, 0 );

    #username
    my $ftp_username_label = Gtk2::Label->new( $d->get("Username") . ":" );

    my $ftp_username_entry = Gtk2::Entry->new;
    if ( defined $settings_xml->{'general'}->{'ftp_username'} ) {
        $ftp_username_entry->set_text( $settings_xml->{'general'}->{'ftp_username'} );
    }
    else {
        $ftp_username_entry->set_text("");
    }

    $tooltips->set_tip( $ftp_username_label, $d->get("Username") );

    $tooltips->set_tip( $ftp_username_entry, $d->get("Username") );

    $ftp_hbox3->pack_start( $ftp_username_label, FALSE, TRUE, 12 );
    $ftp_hbox3->pack_start( $ftp_username_entry, TRUE,  TRUE, 0 );

    #password
    my $ftp_password_label = Gtk2::Label->new( $d->get("Password") . ":" );

    my $ftp_password_entry = Gtk2::Entry->new;
    $ftp_password_entry->set_invisible_char("*");
    $ftp_password_entry->set_visibility(FALSE);
    if ( defined $settings_xml->{'general'}->{'ftp_password'} ) {
        $ftp_password_entry->set_text( $settings_xml->{'general'}->{'ftp_password'} );
    }
    else {
        $ftp_password_entry->set_text("");
    }

    $tooltips->set_tip( $ftp_password_label, $d->get("Password") );

    $tooltips->set_tip( $ftp_password_entry, $d->get("Password") );

    $ftp_hbox4->pack_start( $ftp_password_label, FALSE, TRUE, 12 );
    $ftp_hbox4->pack_start( $ftp_password_entry, TRUE,  TRUE, 0 );

    #website url
    my $ftp_wurl_label = Gtk2::Label->new( $d->get("Website URL") . ":" );

    my $ftp_wurl_entry = Gtk2::Entry->new;
    if ( defined $settings_xml->{'general'}->{'ftp_wurl'} ) {
        $ftp_wurl_entry->set_text( $settings_xml->{'general'}->{'ftp_wurl'} );
    }
    else {
        $ftp_wurl_entry->set_text("http://example.com/screenshots");
    }

    $tooltips->set_tip( $ftp_wurl_label, $d->get("Website URL") );

    $tooltips->set_tip( $ftp_wurl_entry, $d->get("Website URL") );

    $ftp_hbox5->pack_start( $ftp_wurl_label, FALSE, TRUE, 12 );
    $ftp_hbox5->pack_start( $ftp_wurl_entry, TRUE,  TRUE, 0 );

    #--------------------------------------

    #packing
    #--------------------------------------

    #settings main tab
    my $label_basic = Gtk2::Label->new;
    $label_basic->set_markup( $d->get("Main") );

    $file_vbox->pack_start( $scale_box,    TRUE,  TRUE, 3 );
    $file_vbox->pack_start( $filetype_box, FALSE, TRUE, 3 );
    $file_frame->add($file_vbox);

    $save_vbox->pack_start( $save_ask_box,       TRUE,  TRUE, 3 );
    $save_vbox->pack_start( $save_no_box,        TRUE,  TRUE, 3 );
    $save_vbox->pack_start( $save_auto_box,      TRUE,  TRUE, 3 );
    $save_vbox->pack_start( $filename_box,       TRUE,  TRUE, 3 );
    $save_vbox->pack_start( $saveDir_box,        FALSE, TRUE, 3 );
    $save_vbox->pack_start( $filename_hint,      TRUE,  TRUE, 3 );
    $save_vbox->pack_start( $fname_autocopy_box, TRUE,  TRUE, 3 );
    $save_vbox->pack_start( $image_autocopy_box, TRUE,  TRUE, 3 );
    $save_vbox->pack_start( $no_autocopy_box,    TRUE,  TRUE, 3 );
    $save_frame->add($save_vbox);

    $capture_vbox->pack_start( $cursor_box, FALSE, TRUE, 3 );
    $capture_vbox->pack_start( $delay_box,  TRUE,  TRUE, 3 );
    $capture_frame->add($capture_vbox);

    #all labels = one size
    $scale_label->set_alignment( 0, 0.5 );
    $filetype_label->set_alignment( 0, 0.5 );
    $filename_label->set_alignment( 0, 0.5 );
    $saveDir_label->set_alignment( 0, 0.5 );

    my $sg_main = Gtk2::SizeGroup->new('horizontal');
    $sg_main->add_widget($scale_label);
    $sg_main->add_widget($filetype_label);
    $sg_main->add_widget($filename_label);
    $sg_main->add_widget($saveDir_label);

    $vbox_basic->pack_start( $file_frame,    FALSE, TRUE, 3 );
    $vbox_basic->pack_start( $save_frame,    FALSE, TRUE, 3 );
    $vbox_basic->pack_start( $capture_frame, FALSE, TRUE, 3 );
    $vbox_basic->set_border_width(5);

    #settings actions tab
    my $label_actions = Gtk2::Label->new;
    $label_actions->set_markup( $d->get("Actions") );

    $actions_vbox->pack_start( $progname_box,     FALSE, TRUE, 3 );
    $actions_vbox->pack_start( $im_colors_box,    FALSE, TRUE, 3 );
    $actions_vbox->pack_start( $thumbnail_box,    FALSE, TRUE, 3 );
    $actions_vbox->pack_start( $bordereffect_box, FALSE, TRUE, 3 );
    $actions_frame->add($actions_vbox);

    #all labels = one size
    $progname_label->set_alignment( 0, 0.5 );
    $im_colors_label->set_alignment( 0, 0.5 );
    $thumbnail_label->set_alignment( 0, 0.5 );
    $bordereffect_label->set_alignment( 0, 0.5 );

    my $sg_actions = Gtk2::SizeGroup->new('horizontal');
    $sg_actions->add_widget($progname_label);
    $sg_actions->add_widget($im_colors_label);
    $sg_actions->add_widget($thumbnail_label);
    $sg_actions->add_widget($bordereffect_label);

    $vbox_actions->pack_start( $actions_frame, FALSE, TRUE, 3 );
    $vbox_actions->set_border_width(5);

    #settings advanced tab
    my $label_advanced = Gtk2::Label->new;
    $label_advanced->set_markup( $d->get("Advanced") );

    #all labels = one size
    $asel_size_label3->set_alignment( 1, 0.5 );

    my $sg_asel = Gtk2::SizeGroup->new('horizontal');
    $sg_asel->add_widget($asel_size_label1);
    $sg_asel->add_widget($asel_size_label3);

    my $sg_asel2 = Gtk2::SizeGroup->new('horizontal');
    $sg_asel2->add_widget($asel_size_label2);
    $sg_asel2->add_widget($asel_size_label4);

    $sel_capture_vbox->pack_start( $zoom_box,        FALSE, TRUE, 3 );
    $sel_capture_vbox->pack_start( $as_help_box,     FALSE, TRUE, 3 );
    $sel_capture_vbox->pack_start( $asel_isize_box,  FALSE, TRUE, 3 );
    $sel_capture_vbox->pack_start( $asel_isize_box2, FALSE, TRUE, 3 );
    $sel_capture_frame->add($sel_capture_vbox);

    $window_capture_vbox->pack_start( $border_box,          FALSE, TRUE, 3 );
    $window_capture_vbox->pack_start( $winresize_box,       FALSE, TRUE, 3 );
    $window_capture_vbox->pack_start( $autoshape_box,       FALSE, TRUE, 3 );
    $window_capture_vbox->pack_start( $visible_windows_box, FALSE, TRUE, 3 );
    $window_capture_frame->add($window_capture_vbox);

    $menu_capture_vbox->pack_start( $menu_delay_box,   TRUE, TRUE, 3 );
    $menu_capture_vbox->pack_start( $menu_waround_box, TRUE, TRUE, 3 );
    $menu_capture_frame->add($menu_capture_vbox);

    $web_capture_vbox->pack_start( $web_width_box, FALSE, TRUE, 3 );
    $web_capture_frame->add($web_capture_vbox);

    #all labels = one size
    $menu_delay_label->set_alignment( 0, 0.5 );
    $web_width_label->set_alignment( 0, 0.5 );

    my $sg_adv = Gtk2::SizeGroup->new('horizontal');
    $sg_adv->add_widget($menu_delay_label);
    $sg_adv->add_widget($web_width_label);

    $vbox_advanced->pack_start( $sel_capture_frame,    FALSE, TRUE, 3 );
    $vbox_advanced->pack_start( $window_capture_frame, FALSE, TRUE, 3 );
    $vbox_advanced->pack_start( $menu_capture_frame,   FALSE, TRUE, 3 );
    $vbox_advanced->pack_start( $web_capture_frame,    FALSE, TRUE, 3 );
    $vbox_advanced->set_border_width(5);

    #settings image view tab
    my $label_imageview = Gtk2::Label->new;
    $label_imageview->set_markup( $d->get("Image View") );

    $transparent_vbox->pack_start( $imageview_hbox1, TRUE, TRUE, 3 );
    $transparent_vbox->pack_start( $imageview_hbox2, TRUE, TRUE, 3 );
    $transparent_vbox->pack_start( $imageview_hbox3, TRUE, TRUE, 3 );
    $transparent_frame->add($transparent_vbox);

    my $sg_session = Gtk2::SizeGroup->new('horizontal');
    $sg_session->add_widget($session_asc);
    $sg_session->add_widget($session_desc);

    $session_vbox->pack_start( $session_hbox1, TRUE, TRUE, 3 );
    $session_vbox->pack_start( $session_hbox2, TRUE, TRUE, 3 );
    $session_frame->add($session_vbox);

    $vbox_imageview->pack_start( $transparent_frame, FALSE, TRUE, 3 );
    $vbox_imageview->pack_start( $session_frame,     FALSE, TRUE, 3 );
    $vbox_imageview->set_border_width(5);

    #settings behavior tab
    my $label_behavior = Gtk2::Label->new;
    $label_behavior->set_markup( $d->get("Behavior") );

    $first_vbox->pack_start( $fs_active_hbox,       TRUE, TRUE, 3 );
    $first_vbox->pack_start( $fs_min_active_hbox,   TRUE, TRUE, 3 );
    $first_vbox->pack_start( $fs_nonot_active_hbox, TRUE, TRUE, 3 );
    $firstlaunch_frame->add($first_vbox);

    $window_vbox->pack_start( $hide_active_hbox,   TRUE, TRUE, 3 );
    $window_vbox->pack_start( $pafter_active_hbox, TRUE, TRUE, 3 );
    $window_vbox->pack_start( $cac_hbox,           TRUE, TRUE, 3 );
    $window_vbox->pack_start( $hide_time_hbox,     TRUE, TRUE, 3 );
    $window_frame->add($window_vbox);

    $notify_vbox->pack_start( $na_active_hbox,  TRUE, TRUE, 3 );
    $notify_vbox->pack_start( $nt_active_hbox,  TRUE, TRUE, 3 );
    $notify_vbox->pack_start( $npt_active_hbox, TRUE, TRUE, 3 );
    $notify_vbox->pack_start( $ns_combo_hbox,   TRUE, TRUE, 3 );
    $notify_frame->add($notify_vbox);

    $trash_vbox->pack_start( $aod_active_hbox,   TRUE, TRUE, 3 );
    $trash_vbox->pack_start( $doc_active_hbox,   TRUE, TRUE, 3 );
    $trash_vbox->pack_start( $aofsd_active_hbox, TRUE, TRUE, 3 );
    $trash_frame->add($trash_vbox);

    #all labels = one size
    $hide_time_label->set_alignment( 0, 0.5 );

    my $sg_behav = Gtk2::SizeGroup->new('horizontal');
    $sg_behav->add_widget($hide_time_label);

    $vbox_behavior->pack_start( $firstlaunch_frame, FALSE, TRUE, 3 );
    $vbox_behavior->pack_start( $window_frame,      FALSE, TRUE, 3 );
    $vbox_behavior->pack_start( $notify_frame,      FALSE, TRUE, 3 );
    $vbox_behavior->pack_start( $trash_frame,       FALSE, TRUE, 3 );
    $vbox_behavior->set_border_width(5);

    #settings upload tab
    my $label_accounts = Gtk2::Label->new;
    $label_accounts->set_markup( $d->get("Upload") );

    #align the hint
    $pub_hint_pref->set_alignment( 0, 0.5 );

    my $scrolled_accounts_window = Gtk2::ScrolledWindow->new;
    $scrolled_accounts_window->set_policy( 'automatic', 'automatic' );
    $scrolled_accounts_window->set_shadow_type('in');
    $scrolled_accounts_window->add($accounts_tree);
    $accounts_hbox->pack_start( $scrolled_accounts_window, TRUE,  TRUE,  3 );
    $accounts_vbox->pack_start( $accounts_hbox,            TRUE,  TRUE,  3 );
    $accounts_vbox->pack_start( $pub_hint_pref,            FALSE, FALSE, 3 );
    $accounts_frame->add($accounts_vbox);

    $ftp_vbox->pack_start( $ftp_hbox1, FALSE, TRUE, 3 );
    $ftp_vbox->pack_start( $ftp_hbox2, FALSE, TRUE, 3 );
    $ftp_vbox->pack_start( $ftp_hbox3, FALSE, TRUE, 3 );
    $ftp_vbox->pack_start( $ftp_hbox4, FALSE, TRUE, 3 );
    $ftp_vbox->pack_start( $ftp_hbox5, FALSE, TRUE, 3 );
    $ftp_frame->add($ftp_vbox);

    #all labels = one size
    $ftp_entry_label->set_alignment( 0, 0.5 );
    $ftp_mode_label->set_alignment( 0, 0.5 );
    $ftp_username_label->set_alignment( 0, 0.5 );
    $ftp_password_label->set_alignment( 0, 0.5 );
    $ftp_wurl_label->set_alignment( 0, 0.5 );

    my $sg_acc = Gtk2::SizeGroup->new('horizontal');
    $sg_acc->add_widget($ftp_entry_label);
    $sg_acc->add_widget($ftp_mode_label);
    $sg_acc->add_widget($ftp_username_label);
    $sg_acc->add_widget($ftp_password_label);
    $sg_acc->add_widget($ftp_wurl_label);

    $vbox_accounts->pack_start( $accounts_frame, TRUE,  TRUE, 3 );
    $vbox_accounts->pack_start( $ftp_frame,      FALSE, TRUE, 3 );
    $vbox_accounts->set_border_width(5);

    #append pages to notebook
    $notebook_settings->append_page( $vbox_basic,     $label_basic );
    $notebook_settings->append_page( $vbox_advanced,  $label_advanced );
    $notebook_settings->append_page( $vbox_actions,   $label_actions );
    $notebook_settings->append_page( $vbox_imageview, $label_imageview );
    $notebook_settings->append_page( $vbox_behavior,  $label_behavior );
    $notebook_settings->append_page( $vbox_accounts,  $label_accounts );

    #plugins
    #not used in a standalone environment
    if ( keys(%plugins) > 0 && !$ENV{PAR_TEMP} ) {

        my $effects_tree = Gtk2::TreeView->new_with_model(&fct_load_plugin_tree);
        &fct_set_model_plugins($effects_tree);

        my $scrolled_plugins_window = Gtk2::ScrolledWindow->new;
        $scrolled_plugins_window->set_policy( 'automatic', 'automatic' );
        $scrolled_plugins_window->set_shadow_type('in');
        $scrolled_plugins_window->add($effects_tree);

        my $label_plugins = Gtk2::Label->new;
        $label_plugins->set_markup( $d->get("Plugins") );

        my $label_treeview = Gtk2::Label->new( $d->get("The following plugins are installed") );
        $label_treeview->set_alignment( 0, 0.5 );
        $effects_vbox->pack_start( $label_treeview,          FALSE, TRUE, 1 );
        $effects_vbox->pack_start( $scrolled_plugins_window, TRUE,  TRUE, 1 );

        my $vbox_plugins = Gtk2::VBox->new( FALSE, 12 );
        $vbox_plugins->set_border_width(5);
        $vbox_plugins->pack_start( $effects_vbox, TRUE, TRUE, 1 );

        $notebook_settings->append_page( $vbox_plugins, $label_plugins );
    }

    #profiles
    $profiles_box->pack_start( Gtk2::Label->new( $d->get("Profile") . ":" ), FALSE, TRUE, 1 );
    $profiles_box->pack_start( $combobox_settings_profiles,                  TRUE,  TRUE, 6 );
    $profiles_box->pack_start( $button_profile_save,                         FALSE, TRUE, 1 );
    $profiles_box->pack_start( $button_profile_delete,                       FALSE, TRUE, 1 );
    $profiles_box->pack_start( $button_profile_apply,                        FALSE, TRUE, 1 );

    $vbox_settings->pack_start( $profiles_box,      FALSE, TRUE, 1 );
    $vbox_settings->pack_start( $notebook_settings, TRUE,  TRUE, 1 );

    #settings
    $hbox_settings->pack_start( $vbox_settings, TRUE, TRUE, 6 );
    $settings_dialog->vbox->add($hbox_settings);
    $settings_dialog->set_default_response('apply');

    #~ #iconview
    #~ my $iconview = Gtk2::IconView->new_with_model($session_start_screen{'first_page'}->{'model'});
    #~ $iconview->set_item_width (150);
    #~ $iconview->set_pixbuf_column(0);
    #~ $iconview->set_text_column(1);
    #~ $iconview->set_selection_mode('multiple');
    #~ $iconview->signal_connect( 'selection-changed', \&evt_iconview_sel_changed );
    #~ $iconview->signal_connect( 'item-activated', \&evt_iconview_item_activated );
    #~
    #~ my $scrolled_window_view = Gtk2::ScrolledWindow->new;
    #~ $scrolled_window_view->set_policy( 'automatic', 'automatic' );
    #~ $scrolled_window_view->set_shadow_type('in');
    #~ $scrolled_window_view->add($iconview);
    #~
    #~ #add an event box to show a context menu on right-click
    #~ my $view_event = Gtk2::EventBox->new;
    #~ $view_event->add($scrolled_window_view);
    #~ $view_event->signal_connect( 'button-press-event', \&evt_iconview_button_press, $iconview );
    #~
    #~
    #~ #pack notebook and iconview into vpaned#
    #~ my $vpaned = Gtk2::VPaned->new;
    #~ $vpaned->add1($notebook);
    #~ $vpaned->add2($view_event);
    #~
    #~ #vpaned into vbox
    #~ $vbox->pack_start( $vpaned, TRUE, TRUE, 0 );

    #notebook
    $vbox->pack_start( $notebook, TRUE, TRUE, 0 );

    #bottom toolbar
    my $nav_toolbar = $st->create_btoolbar;
    $vbox->pack_start( $nav_toolbar, FALSE, FALSE, 0 );

    #signal handler
    $st->{_back}->signal_connect(
        'clicked' => sub {
            $notebook->prev_page;
        }
    );
    $st->{_forw}->signal_connect(
        'clicked' => sub {
            $notebook->next_page;
        }
    );
    $st->{_home}->signal_connect(
        'clicked' => sub {
            $notebook->set_current_page(0);
        }
    );

    #signal handler for sort buttons
    $st->{_sorta}->signal_connect(
        'toggled' => sub {
            my $this_button = shift;
            if ( $this_button->get_active ) {
                $session_start_screen{'first_page'}->{'model'}->set_sort_func(
                    2,
                    sub {

                        #The comparison callback should return
                        #	-1 if the iter1 row should come before the iter2 row,
                        #	0 if the rows are equal, or
                        #	1 if the iter1 row should come after the iter2 row.
                        my ( $liststore, $a, $b ) = @_;

                        my $ka = $liststore->get_value( $a, $session_asc_combo->get_active + 1 );
                        my $kb = $liststore->get_value( $b, $session_asc_combo->get_active + 1 );

                        if ( defined $ka && defined $kb ) {

                            #negate result in this case
                            return Sort::Naturally::ncmp( $ka, $kb ) * -1;
                        }

                        return -1;
                    }
                );
                $session_asc->set_active(TRUE);
                $st->{_sortd}->set_active(FALSE);
            }
            else {
                $st->{_sortd}->set_active(TRUE);
            }
        }
    );

    $st->{_sortd}->signal_connect(
        'toggled' => sub {
            my $this_button = shift;
            if ( $this_button->get_active ) {
                $session_start_screen{'first_page'}->{'model'}->set_sort_func(
                    2,
                    sub {

                        #see above
                        my ( $liststore, $a, $b ) = @_;

                        my $ka = $liststore->get_value( $a, $session_desc_combo->get_active + 1 );
                        my $kb = $liststore->get_value( $b, $session_desc_combo->get_active + 1 );

                        if ( defined $ka && defined $kb ) {
                            return Sort::Naturally::ncmp( $ka, $kb );
                        }

                        return -1;
                    }
                );
                $session_desc->set_active(TRUE);
                $st->{_sorta}->set_active(FALSE);
            }
            else {
                $st->{_sorta}->set_active(TRUE);
            }
        }
    );

    #set saved value
    if ( $session_asc->get_active ) {
        $st->{_sorta}->set_active(TRUE);
    }
    else {
        $st->{_sortd}->set_active(TRUE);
    }

    #pack statusbar
    $status->pack_start( $cursor_status_active, FALSE, FALSE, 0 );
    $status->pack_start( Gtk2::HSeparator->new, FALSE, FALSE, 3 );

    $status->pack_start( $delay_status_label,   FALSE, FALSE, 0 );
    $status->pack_start( $delay_status,         FALSE, FALSE, 0 );
    $status->pack_start( Gtk2::HSeparator->new, FALSE, FALSE, 6 );

    $vbox->pack_start( $status, FALSE, FALSE, 0 );

    #--------------------------------------

    #populate quick selector (profiles)
    #--------------------------------------
    &fct_update_profile_selectors( $combobox_settings_profiles, \@current_profiles );

    #restore session
    #clean 'unsaved' files directory
    #save settings directly when cache was cleared (see Bug #909195)
    #--------------------------------------
    Glib::Idle->add(
        sub {
            &fct_load_session;
            &fct_init_unsaved_files;
            if ( $sc->get_clear_cache ) {
                &fct_post_settings();
            }
            return FALSE;
        }
    );

    #open init files (cmd arguments)
    #--------------------------------------
    if ( scalar @init_files > 0 ) {
        &fct_open_files(@init_files);
    }

    #unblock controls
    &fct_control_signals('unblock');

    #start minimized?
    #--------------------------------------
    unless ( $sc->get_min ) {
        &fct_control_main_window('show');
    }
    else {
        &fct_control_main_window('hide');
    }

    #restore menu/toolbar settings
    #--------------------------------------
    if ( defined $settings_xml->{'gui'}->{'btoolbar_active'} ) {
        $sm->{_menuitem_btoolbar}->set_active( $settings_xml->{'gui'}->{'btoolbar_active'} );
    }
    else {
        $sm->{_menuitem_btoolbar}->set_active(FALSE);
    }

    #--------------------------------------

    #FIXME
    #this is an ugly fix when 'tranparent parts' is set to background
    #we don't get the corret background color until the main window is shown
    #so we change it now
    if ( $trans_backg->get_active ) {
        &evt_value_changed( undef, 'transp_toggled' );
    }

    #update the first tab on startup
    &fct_update_info_and_tray();

    #load saved settings
    #--------------------------------------
    my $folder_to_save = $settings_xml->{'general'}->{'folder'} || $ENV{'HOME'};
    my ( $cmdname, $extra ) = $sc->get_start_with;
    if ( $cmdname && $folder_to_save ) {
        &evt_take_screenshot( 'global_keybinding', $cmdname, $folder_to_save, $extra );
    }

    #keep list of windows up-to-date (tray)
    Glib::Idle->add(
        sub {
            $wnck_screen->signal_connect( 'window-stacking-changed' => sub { &fct_update_tray_menu; } );
            return FALSE;
        }
    );

    Gtk2->main;

    0;

    #events
    #--------------------------------------
    sub evt_value_changed {
        my ( $widget, $data ) = @_;
        print "\n$data was emitted by widget $widget\n"
          if $sc->get_debug;

        return FALSE unless $data;

        #checkbox for "open with" -> entry active/inactive
        if ( $data eq "progname_toggled" ) {
            if ( $progname_active->get_active ) {
                $progname->set_sensitive(TRUE);
            }
            else {
                $progname->set_sensitive(FALSE);
            }
        }

        #checkbox for "color depth" -> entry active/inactive
        if ( $data eq "im_colors_toggled" ) {
            if ( $im_colors_active->get_active ) {
                $combobox_im_colors->set_sensitive(TRUE);
            }
            else {
                $combobox_im_colors->set_sensitive(FALSE);
            }
        }

        #radiobuttons for "transparent parts"
        if ( $data eq "transp_toggled" ) {

            #Sets how the view should draw transparent parts of images with an alpha channel
            my $color = $trans_custom_btn->get_color;
            my $color_string = sprintf( "%02x%02x%02x", $color->red / 257, $color->green / 257, $color->blue / 257 );

            my $mode;
            if ( $trans_check->get_active ) {
                $mode = 'grid';
            }
            elsif ( $trans_custom->get_active ) {
                $mode = 'color';
            }
            elsif ( $trans_backg->get_active ) {
                $mode = 'color';
                my $bg = $window->get_style->bg('normal');
                $color_string = sprintf( "%02x%02x%02x", $bg->red / 257, $bg->green / 257, $bg->blue / 257 );
            }

            #change all imageviews in session
            foreach my $key ( keys %session_screens ) {
                if ( $session_screens{$key}->{'image'} ) {
                    $session_screens{$key}->{'image'}->set_transp( $mode, hex $color_string );
                }
            }

        }

        #"cursor_status" toggled
        if ( $data eq "cursor_status_toggled" ) {
            $cursor_active->set_active( $cursor_status_active->get_active );
        }

        #"cursor" toggled
        if ( $data eq "cursor_toggled" ) {
            $cursor_status_active->set_active( $cursor_active->get_active );
        }

        #value for "delay" -> update text
        if ( $data eq "delay_changed" ) {
            $delay_status->set_value( $delay->get_value );
            $delay_vlabel->set_text( $d->nget( "second", "seconds", $delay->get_value ) );
        }

        #value for "delay" -> update text
        if ( $data eq "delay_status_changed" ) {
            $delay->set_value( $delay_status->get_value );
            $delay_status_vlabel->set_text( $d->nget( "second", "seconds", $delay_status->get_value ) );
        }

        #value for "menu_delay" -> update text
        if ( $data eq "menu_delay_changed" ) {
            $menu_delay_vlabel->set_text( $d->nget( "second", "seconds", $menu_delay->get_value ) );
        }

        #value for "hide_time" -> update text
        if ( $data eq "hide_time_changed" ) {
            $hide_time_vlabel->set_text( $d->nget( "millisecond", "milliseconds", $hide_time->get_value ) );
        }

        #checkbox for "thumbnail" -> HScale active/inactive
        if ( $data eq "thumbnail_toggled" ) {
            if ( $thumbnail_active->get_active ) {
                $thumbnail->set_sensitive(TRUE);
            }
            else {
                $thumbnail->set_sensitive(FALSE);
            }
        }

        #quality value changed
        if ( $data eq "qvalue_changed" ) {
            my $settings = undef;
            if ( defined $sc->get_globalsettings_object ) {
                $settings = $sc->get_globalsettings_object;
            }
            else {
                $settings = Shutter::App::GlobalSettings->new();
                $sc->set_globalsettings_object($settings);
            }
            if ( $combobox_type->get_active_text =~ /jpeg/ ) {
                $settings->set_jpg_quality( $scale->get_value );
            }
            elsif ( $combobox_type->get_active_text =~ /jpg/ ) {
                $settings->set_jpg_quality( $scale->get_value );
            }
            elsif ( $combobox_type->get_active_text =~ /png/ ) {
                $settings->set_png_quality( $scale->get_value );
            }
            else {
                $settings->clear_quality_settings();
            }
        }

        #checkbox for "bordereffect" -> HScale active/inactive
        if ( $data eq "bordereffect_toggled" ) {
            if ( $bordereffect_active->get_active ) {
                $bordereffect->set_sensitive(TRUE);
            }
            else {
                $bordereffect->set_sensitive(FALSE);
            }
        }

        #value for "bordereffect" -> update text
        if ( $data eq "bordereffect_changed" ) {
            $bordereffect_vlabel->set_text( $d->nget( "pixel", "pixels", $bordereffect->get_value ) );
        }

        #filetype changed
        if ( $data eq "type_changed" ) {
            if ( $combobox_type->get_active_text =~ /jpeg/ ) {
                $scale->set_sensitive(TRUE);
                $scale_label->set_sensitive(TRUE);
                $scale->set_range( 1, 100 );
                $scale->set_value(90);
                $scale_label->set_text( $d->get("Quality") . ":" );
            }
            elsif ( $combobox_type->get_active_text =~ /jpg/ ) {
                $scale->set_sensitive(TRUE);
                $scale_label->set_sensitive(TRUE);
                $scale->set_range( 1, 100 );
                $scale->set_value(90);
                $scale_label->set_text( $d->get("Quality") . ":" );
            }
            elsif ( $combobox_type->get_active_text =~ /png/ ) {
                $scale->set_sensitive(TRUE);
                $scale_label->set_sensitive(TRUE);
                $scale->set_range( 0, 9 );
                $scale->set_value(9);
                $scale_label->set_text( $d->get("Compression") . ":" );
            }
            else {
                $scale->set_sensitive(FALSE);
                $scale_label->set_sensitive(FALSE);
            }
        }

        #notify agent changed
        if ( $data eq "ns_changed" ) {
            if ( $combobox_ns->get_active == 0 ) {
                $sc->set_notification_object( Shutter::App::Notification->new );
            }
            else {
                $sc->set_notification_object( Shutter::App::ShutterNotification->new($sc) );
            }
        }

        return TRUE;
    }

    sub evt_take_screenshot {
        my ( $widget, $data, $folder_from_config, $extra ) = @_;

        #get xid if any window was selected from the submenu...
        my $selfcapture = FALSE;
        if ( $data =~ /^shutter_window_direct(.*)/ ) {
            my $xid = $1;
            $selfcapture = TRUE if $xid == $window->window->XID;
        }

        #hide mainwindow
        if (   $hide_active->get_active
            && $data ne "web"
            && $data ne "tray_web"
            && !$is_hidden
            && !$selfcapture )
        {

            &fct_control_main_window('hide');

        }
        else {

            #save current position of main window
            ( $window->{x}, $window->{y} ) = $window->get_position;

        }

        #close last message displayed
        my $notify = $sc->get_notification_object;
        $notify->close;

        #disable signal-handler
        &fct_control_signals('block');

        if ( $data eq "web" || $data eq "tray_web" ) {
            &fct_take_screenshot( $widget, $data, $folder_from_config, $extra );

            #unblock signal handler
            &fct_control_signals('unblock');
        }
        elsif ($data eq "menu"
            || $data eq "tray_menu"
            || $data eq "tooltip"
            || $data eq "tray_tooltip" )
        {

            my $scd_text;
            if ( $data eq "menu" || $data eq "tray_menu" ) {
                $scd_text = $d->get("Please activate the menu you want to capture");
            }
            elsif ( $data eq "tooltip" || $data eq "tray_tooltip" ) {
                $scd_text = $d->get("Please activate the tooltip you want to capture");
            }

            #show notification messages displaying the countdown
            if ( $notify_ptimeout_active->get_active ) {
                my $notify = $sc->get_notification_object;
                my $ttw    = $menu_delay->get_value;

                #first notification immediately
                $notify->show( sprintf( $d->nget( "Screenshot will be taken in %s second", "Screenshot will be taken in %s seconds", $ttw ), $ttw ), $scd_text );
                $ttw--;

                #delay is only 1 second
                #do not show any further messages
                if ( $ttw >= 1 ) {

                    #then controlled via timeout
                    Glib::Timeout->add(
                        1000,
                        sub {
                            $notify->show( sprintf( $d->nget( "Screenshot will be taken in %s second", "Screenshot will be taken in %s seconds", $ttw ), $ttw ), $scd_text );
                            $ttw--;
                            if ( $ttw == 0 ) {

                                #close last message with a short delay (less than a second)
                                Glib::Timeout->add(
                                    500,
                                    sub {
                                        $notify->close;
                                        return FALSE;
                                    }
                                );

                                return FALSE;

                            }
                            else {

                                return TRUE;

                            }
                        }
                    );
                }
                else {

                    #close last message with a short delay (less than a second)
                    Glib::Timeout->add(
                        500,
                        sub {
                            $notify->close;
                            return FALSE;
                        }
                    );
                }
            }    #notify not activated

            #capture with delay
            Glib::Timeout->add(
                $menu_delay->get_value * 1000,
                sub {
                    &fct_take_screenshot( $widget, $data, $folder_from_config, $extra );

                    #unblock signal handler
                    &fct_control_signals('unblock');
                    return FALSE;
                }
            );
        }
        else {

            #A short timeout to give the server a chance to
            #redraw the area that was obscured by our dialog.
            Glib::Timeout->add(
                $hide_time->get_value,
                sub {
                    &fct_take_screenshot( $widget, $data, $folder_from_config, $extra );

                    #unblock signal handler
                    &fct_control_signals('unblock');
                    return FALSE;
                }
            );
        }

        return TRUE;
    }

    sub evt_notebook_switch {
        my ( $widget, $pointer, $int ) = @_;

        my $key = &fct_get_file_by_index($int);
        if ($key) {
            Glib::Idle->add(
                sub {

                    #is key still current page?
                    if ( defined $key ) {
                        return FALSE unless exists $session_screens{$key};
                        return FALSE
                          unless $session_screens{$key}->{'tab_child'} == $notebook->get_nth_page( $notebook->get_current_page );

                        #~ print "update tab for $key\n";
                    }
                    foreach my $ckey ( keys %session_screens ) {

                        #set pixbuf for current item
                        if ( $ckey eq $key ) {
                            if ( $session_screens{$key}->{'long'} ) {

                                #update window title
                                &fct_update_info_and_tray($key);

                                #do nothing if the view does already show a pixbuf
                                if ( exists $session_screens{$ckey}
                                    && defined $session_screens{$ckey}->{'image'} )
                                {
                                    unless ( $session_screens{$ckey}->{'image'}->get_pixbuf ) {
                                        $session_screens{$ckey}->{'image'}->set_pixbuf( $lp->load( $session_screens{$key}->{'long'}, undef, undef, undef, TRUE ) );
                                    }
                                }
                            }
                            next;
                        }

                        #unset imageview for all other items
                        if ( exists $session_screens{$ckey}
                            && defined $session_screens{$ckey}->{'image'} )
                        {
                            if ( $session_screens{$ckey}->{'image'}->get_pixbuf ) {
                                $session_screens{$ckey}->{'image'}->set_pixbuf(undef);
                            }
                        }
                    }
                    return FALSE;
                }
            );
        }
        else {
            Glib::Idle->add(
                sub {
                    &fct_update_info_and_tray("session");
                    return FALSE;
                }
            );
        }

        #unselect all items in session tab
        #when we move away
        if ( $int == 0 ) {
            $session_start_screen{'first_page'}->{'view'}->unselect_all;
        }

        #enable/disable menu entry when we switch tabs
        &fct_update_actions( $int, $key );

        return TRUE;
    }

    sub evt_delete_window {
        my ( $widget, $data, $scounter ) = @_;
        print "\n$data was emitted by widget $widget\n"
          if $sc->get_debug;

        if (   $data ne "quit"
            && $close_at_close_active->get_active
            && !$sc->get_disable_systray )
        {
            $window->hide;
            $is_hidden = TRUE;
            return TRUE;
        }

        Glib::Idle->add(
            sub {

                #hide window and block sontrols
                $window->hide;
                &fct_control_signals('block');

                #wait if there are still files that need to be loaded
                #they would not be saved in session
                unless ( defined $scounter ) {
                    $scounter = 0;
                }
                while ( defined $session_start_screen{'first_page'}->{'num_session_files'} && $scounter <= 15 ) {
                    $scounter++;

                    #try again in a second
                    Glib::Timeout->add(
                        1000,
                        sub {
                            &evt_delete_window( '', 'quit', $scounter );
                            return FALSE;
                        }
                    );
                    return FALSE;
                }

                #save settings
                &fct_save_settings(undef);
                &fct_save_settings( $combobox_settings_profiles->get_active_text )
                  if $combobox_settings_profiles->get_active != -1;

                #autostart
                $sas->create_autostart_file( $sdir->get_autostart_dir, $fs_active->get_active, $fs_min_active->get_active, $fs_nonot_active->get_active );

                Gtk2->main_quit;

                return FALSE;
            }
        );

        return TRUE;
    }

    sub evt_bug {
        $shf->xdg_open( undef, "https://bugs.launchpad.net/shutter", undef );
    }

    sub evt_question {
        $shf->xdg_open( undef, "https://answers.launchpad.net/shutter", undef );
    }

    sub evt_translate {
        $shf->xdg_open( undef, "https://translations.launchpad.net/shutter", undef );
    }

    sub evt_about {
        Shutter::App::AboutDialog->new($sc)->show;
    }

    sub evt_show_systray {
        my ( $widget, $data ) = @_;
        if ( $sc->get_debug ) {
            print "\n$data was emitted by widget $widget\n";
        }

        #left button (mouse)
        if ( $_[1]->button == 1 ) {
            if ( $window->visible ) {
                &fct_control_main_window('hide');
            }
            else {
                &fct_control_main_window('show');
            }
        }

        #right button (mouse)
        elsif ( $_[1]->button == 3 ) {
            $tray_menu->popup(
                undef,    # parent menu shell
                undef,    # parent menu item
                undef,    # menu pos func
                undef,    # data
                $data->button,
                $data->time
            );
        }
        return TRUE;
    }

    sub evt_show_systray_statusicon {
        my ( $widget, $button, $time, $tray ) = @_;
        if ( $sc->get_debug ) {
            print "\n$button, $time was emitted by widget $widget\n";
        }

        $tray_menu->popup(
            undef,    # parent menu shell
            undef,    # parent menu item
            sub {
                return Gtk2::StatusIcon::position_menu( $tray_menu, 0, 0, $tray );
            },        # menu pos func
            undef,    # data
            $time ? $button : 0,
            $time
        );

        return TRUE;
    }

    sub evt_activate_systray_statusicon {
        my ( $widget, $data, $tray ) = @_;
        if ( $sc->get_debug ) {
            print "\n$data was emitted by widget $widget\n";
        }

        unless ($is_hidden) {
            &fct_control_main_window('hide');
        }
        else {
            &fct_control_main_window('show');
        }
        return TRUE;
    }

    sub evt_accounts {
        my ( $tree, $path, $column ) = @_;

        #open browser if register url is clicked
        if ( $column->get_title eq $d->get("Register") ) {
            my $model         = $tree->get_model();
            my $account_iter  = $model->get_iter($path);
            my $account_value = $model->get_value( $account_iter, 5 );
            $shf->xdg_open( undef, $account_value, undef );
        }
        return TRUE;
    }

    sub evt_tab_button_press {
        my ( $ev_box, $ev, $key ) = @_;

        #right click
        if ( $key && $ev->button == 3 && $ev->type eq 'button-press' ) {
            $sm->{_menu_large_actions}->popup(
                undef,    # parent menu shell
                undef,    # parent menu item
                undef,    # menu pos func
                undef,    # data
                $ev->button,
                $ev->time
            );
        }

        return TRUE;
    }

    sub evt_iconview_button_press {
        my $ev_box = shift;
        my $ev     = shift;
        my $view   = shift;

        my $path = $view->get_path_at_pos( $ev->x, $ev->y );

        if ($path) {

            #select item
            $view->select_path($path);

            $sm->{_menu_large_actions}->popup(
                undef,    # parent menu shell
                undef,    # parent menu item
                undef,    # menu pos func
                undef,    # data
                $ev->button,
                $ev->time
            );

        }

        return TRUE;
    }

    sub evt_iconview_sel_changed {
        my ( $view, $data ) = @_;

        #we don't handle selection changes
        #if we are not in the session tab
        if (&fct_get_current_file) {

            return FALSE;
        }

        my @sel_items = $view->get_selected_items;

        #enable/disable menu entry when we are in the session tab and selection changes
        if ( scalar @sel_items == 1 ) {
            my $key = undef;
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                    }
                },
                undef
            );
            &fct_update_actions( scalar @sel_items, $key );
        }
        else {
            &fct_update_actions( scalar @sel_items );
        }

        return TRUE;
    }

    sub fct_get_last_capture {

        #~ #determine last capture and return the relevant key
        #~ my $last_capture_tstamp = 0;
        #~ my $last_capture_key 	= 0;
        #~ foreach my $key (keys %session_screens){
        #~ if(exists $session_screens{$key}->{'history'} && defined $session_screens{$key}->{'history'}){
        #~ if(exists $session_screens{$key}->{'history_timestamp'} && defined $session_screens{$key}->{'history_timestamp'}){
        #~ if($session_screens{$key}->{'history_timestamp'} > $last_capture_tstamp){
        #~ $last_capture_tstamp = $session_screens{$key}->{'history_timestamp'};
        #~ $last_capture_key = $key;
        #~ }
        #~ }
        #~ }
        #~ }
        #~ return $last_capture_key;
        if ( exists $session_start_screen{'first_page'}->{'history'}
            && defined $session_start_screen{'first_page'}->{'history'} )
        {
            return $session_start_screen{'first_page'}->{'history'};
        }
        return FALSE;
    }

    sub fct_ret_upload_links_menu {
        my $key        = shift;
        my $menu_links = shift;

        my $traytheme = $sc->get_theme;

        if ( defined $menu_links ) {
            foreach my $child ( $menu_links->get_children ) {
                $child->destroy;
            }
        }
        else {
            $menu_links = Gtk2::Menu->new;
        }

        my $nmenu_entries = 0;

        if ( defined $key && exists $session_screens{$key}->{'links'} ) {
            foreach my $hoster ( keys %{ $session_screens{$key}->{'links'} } ) {

                #no longer valid
                next
                  unless defined $session_screens{$key}->{'links'}->{$hoster};
                next
                  unless scalar keys %{ $session_screens{$key}->{'links'}->{$hoster} } > 0;
                next
                  unless defined $session_screens{$key}->{'links'}->{$hoster}->{'menuentry'};

                #create menu entry
                my $menuitem_hoster = Gtk2::ImageMenuItem->new_with_mnemonic( $session_screens{$key}->{'links'}->{$hoster}->{'menuentry'} );
                if ( defined $session_screens{$key}->{'links'}->{$hoster}->{'menuimage'} ) {
                    if ( $traytheme->has_icon( $session_screens{$key}->{'links'}->{$hoster}->{'menuimage'} ) ) {
                        $menuitem_hoster->set_image( Gtk2::Image->new_from_icon_name( $session_screens{$key}->{'links'}->{$hoster}->{'menuimage'}, 'menu' ) );
                    }
                }

                #create submenu with urls
                my $menu_urls = Gtk2::Menu->new;
                foreach my $url ( keys %{ $session_screens{$key}->{'links'}->{$hoster} } ) {
                    next if $url eq 'menuimage';
                    next if $url eq 'menuentry';
                    next if $url eq 'pubfile';

                    #create item
                    my $menuitem_url = Gtk2::MenuItem->new_with_label( $session_screens{$key}->{'links'}->{$hoster}->{$url} );
                    foreach my $child ( $menuitem_url->get_children ) {
                        if ( $child =~ m/Gtk2::AccelLabel/ ) {
                            $child->set_ellipsize('middle');
                            $child->set_width_chars(20);
                            last;
                        }
                    }
                    $menuitem_url->signal_connect(
                        activate => sub {
                            $clipboard->set_text( $session_screens{$key}->{'links'}->{$hoster}->{$url} );
                        }
                    );

                    #prepare identifier for tooltiup
                    #e.g. direct_link => Direct link
                    my $prep_url = $url;
                    $prep_url =~ s/_/ /ig;
                    $prep_url = ucfirst $prep_url;
                    $tooltips->set_tip( $menuitem_url, $prep_url );

                    $menu_urls->append($menuitem_url);
                }

                $menuitem_hoster->set_submenu($menu_urls);

                $menu_links->append($menuitem_hoster);

                $nmenu_entries++;

            }
        }

        $menu_links->show_all;

        return ( $nmenu_entries, $menu_links );
    }

    sub fct_update_actions {
        my $n_items = shift;
        my $key     = shift;

        Glib::Idle->add(
            sub {

                #does the file still exist?
                if ( defined $key ) {
                    return FALSE unless exists $session_screens{$key};
                }

                #does the file still exist?
                if ( defined $key ) {
                    return FALSE unless exists $session_screens{$key};
                }

                #is key still current page?
                if ( defined $key && $notebook->get_current_page != 0 ) {
                    return FALSE unless exists $session_screens{$key};
                    return FALSE
                      unless $session_screens{$key}->{'tab_child'} == $notebook->get_nth_page( $notebook->get_current_page );

                    #~ print "update actions for $key\n";
                }

                #MENU
                #--------------------------------------
                $sm->{_menuitem_reopen}->set_submenu( &fct_ret_program_menu( $sm->{_menuitem_reopen}->get_submenu ) );

                #NAVIGATION BAR
                #--------------------------------------
                if ( defined $key && $notebook->get_current_page != 0 ) {

                    #does the file still exist?
                    return FALSE unless exists $session_screens{$key};

                    #disable sort buttons when session tab is active
                    $st->{_sorta}->set_sensitive(FALSE);
                    $st->{_sortd}->set_sensitive(FALSE);
                }
                else {

                    #enable sort buttons when session tab is active
                    $st->{_sorta}->set_sensitive(TRUE);
                    $st->{_sortd}->set_sensitive(TRUE);
                }

                #TRAY
                #--------------------------------------

                #last capture
                foreach my $child ( $tray_menu->get_children ) {
                    if ( $child->get_name eq 'redoshot' ) {
                        $child->set_sensitive(&fct_get_last_capture);
                        last;
                    }
                }

                #TOOLBAR
                #--------------------------------------

                #last capture
                $st->{_redoshot}->set_sensitive(&fct_get_last_capture);

                #goocanvas is optional, don't enable it when not installed
                if ($goocanvas) {
                    $st->{_edit}->set_sensitive($n_items);
                }
                else {
                    $st->{_edit}->set_sensitive(FALSE);
                }

                #upload links
                my ( $nmenu_entries_tb, $menu_links_tb ) = &fct_ret_upload_links_menu( $key, $st->{_upload}->get_menu );
                if ($nmenu_entries_tb) {
                    $st->{_upload}->set_menu($menu_links_tb);
                }
                else {
                    $st->{_upload}->set_menu(undef);
                }
                $st->{_upload}->set_sensitive($n_items);

                #MENU
                #--------------------------------------

                #last capture
                $sm->{_menuitem_redoshot}->set_sensitive( $st->{_redoshot}->is_sensitive );

                #file
                #~ if(defined $key && defined $session_screens{$key}->{'is_unsaved'} && $session_screens{$key}->{'is_unsaved'}){
                #~ $sm->{_menuitem_save}->set_sensitive($n_items);
                #~ }elsif(defined $key){
                #~ $sm->{_menuitem_save}->set_sensitive(FALSE);
                #~ }else{
                #~ $sm->{_menuitem_save}->set_sensitive($n_items);
                #~ }
                $sm->{_menuitem_save_as}->set_sensitive($n_items);

                #~ $sm->{_menuitem_export_svg}->set_sensitive($n_items);
                $sm->{_menuitem_export_pdf}->set_sensitive($n_items);
                $sm->{_menuitem_export_pscript}->set_sensitive($n_items);
                $sm->{_menuitem_pagesetup}->set_sensitive($n_items);
                $sm->{_menuitem_print}->set_sensitive($n_items);
                $sm->{_menuitem_email}->set_sensitive($n_items);
                $sm->{_menuitem_close}->set_sensitive($n_items);
                $sm->{_menuitem_close_all}->set_sensitive($n_items);

                #edit
                if (   $n_items
                    && defined $key
                    && defined $session_screens{$key}->{'undo'} 
                    && scalar @{ $session_screens{$key}->{'undo'} } > 1 )
                {
                    $sm->{_menuitem_undo}->set_sensitive(TRUE);
                }
                else {
                    $sm->{_menuitem_undo}->set_sensitive(FALSE);
                }

                if (   $n_items
                    && defined $key
                    && defined $session_screens{$key}->{'redo'}
                    && scalar @{ $session_screens{$key}->{'redo'} } > 0 )
                {
                    $sm->{_menuitem_redo}->set_sensitive(TRUE);
                }
                else {
                    $sm->{_menuitem_redo}->set_sensitive(FALSE);
                }

                $sm->{_menuitem_trash}->set_sensitive($n_items);
                $sm->{_menuitem_copy}->set_sensitive($n_items);
                $sm->{_menuitem_copy_filename}->set_sensitive($n_items);

                #view
                $sm->{_menuitem_zoom_in}->set_sensitive($n_items);
                $sm->{_menuitem_zoom_out}->set_sensitive($n_items);
                $sm->{_menuitem_zoom_100}->set_sensitive($n_items);
                $sm->{_menuitem_zoom_best}->set_sensitive($n_items);

                #screenshot
                $sm->{_menuitem_reopen}->set_sensitive($n_items);
                $sm->{_menuitem_show_in_folder}->set_sensitive($n_items);
                $sm->{_menuitem_rename}->set_sensitive($n_items);

                #upload links
                #~ $sm->{_menuitem_links}->set_sensitive(&fct_get_upload_links($key));
                #upload links
                my ( $nmenu_entries, $menu_links ) = &fct_ret_upload_links_menu( $key, $sm->{_menuitem_links}->get_submenu );

                #~ if($nmenu_entries){
                $sm->{_menuitem_links}->set_submenu($menu_links);

                #~ }else{
                #~ $sm->{_menuitem_links}->set_submenu(undef);
                #~ }
                $sm->{_menuitem_links}->set_sensitive($nmenu_entries);

                #nautilus-sendto is optional, don't enable it when not installed
                if ($nautilus_sendto) {
                    $sm->{_menuitem_send}->set_sensitive($n_items);
                }
                else {
                    $sm->{_menuitem_send}->set_sensitive(FALSE);
                }

                $sm->{_menuitem_upload}->set_sensitive($n_items);

                #goocanvas is optional, don't enable it when not installed
                if ($goocanvas) {
                    $sm->{_menuitem_draw}->set_sensitive($n_items);
                }
                else {
                    $sm->{_menuitem_draw}->set_sensitive(FALSE);
                }

                $sm->{_menuitem_plugin}->set_sensitive($n_items);

                #redoshot_this
                if (   defined $key
                    && exists $session_screens{$key}->{'history'}
                    && defined $session_screens{$key}->{'history'} )
                {
                    $sm->{_menuitem_redoshot_this}->set_sensitive($n_items);
                }
                else {
                    $sm->{_menuitem_redoshot_this}->set_sensitive(FALSE);
                }

                #right-click menu
                $sm->{_menuitem_large_reopen}->set_sensitive($n_items);
                $sm->{_menuitem_large_show_in_folder}->set_sensitive($n_items);
                $sm->{_menuitem_large_rename}->set_sensitive($n_items);
                $sm->{_menuitem_large_trash}->set_sensitive($n_items);
                $sm->{_menuitem_large_copy}->set_sensitive($n_items);
                $sm->{_menuitem_large_copy_filename}->set_sensitive($n_items);

                #upload links
                my ( $nmenu_entries_large, $menu_links_large ) = &fct_ret_upload_links_menu( $key, $sm->{_menuitem_large_links}->get_submenu );

                #~ if($nmenu_entries_large){
                $sm->{_menuitem_large_links}->set_submenu($menu_links_large);

                #~ }else{
                #~ $sm->{_menuitem_large_links}->set_submenu(undef);
                #~ }
                $sm->{_menuitem_large_links}->set_sensitive($nmenu_entries_large);

                #nautilus-sendto is optional, don't enable it when not installed
                if ($nautilus_sendto) {
                    $sm->{_menuitem_large_send}->set_sensitive($n_items);
                }
                else {
                    $sm->{_menuitem_large_send}->set_sensitive(FALSE);
                }

                $sm->{_menuitem_large_upload}->set_sensitive($n_items);

                #goocanvas is optional, don't enable it when not installed
                if ($goocanvas) {
                    $sm->{_menuitem_large_draw}->set_sensitive($n_items);
                }
                else {
                    $sm->{_menuitem_large_draw}->set_sensitive(FALSE);
                }

                $sm->{_menuitem_large_plugin}->set_sensitive($n_items);

                #redoshot_this
                if (   defined $key
                    && exists $session_screens{$key}->{'history'}
                    && defined $session_screens{$key}->{'history'} )
                {
                    $sm->{_menuitem_large_redoshot_this}->set_sensitive($n_items);
                }
                else {
                    $sm->{_menuitem_large_redoshot_this}->set_sensitive(FALSE);
                }

                return FALSE;
            }
        );

        return TRUE;
    }

    sub evt_iconview_item_activated {
        my ( $view, $path, $data ) = @_;

        my $model = $view->get_model;

        my $iter = $model->get_iter($path);
        my $key = $model->get_value( $iter, 2 );

        $notebook->set_current_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );

        return TRUE;
    }

    sub evt_show_settings {
        &fct_check_installed_programs;

        $settings_dialog->show_all;
        my $settings_dialog_response = $settings_dialog->run;

        &fct_post_settings($settings_dialog);

        if ( $settings_dialog_response eq "close" ) {
            return TRUE;
        }
        else {
            return FALSE;
        }
    }

    sub fct_post_settings {
        my $settings_dialog = shift;

        #unset profile combobox when profile was not applied
        if ( $current_profile_indx != $combobox_settings_profiles->get_active ) {
            $combobox_settings_profiles->set_active($current_profile_indx);
        }

        if ( defined $settings_dialog && $settings_dialog ) {
            $settings_dialog->hide();
        }

        #save directly
        &fct_save_settings(undef);
        &fct_save_settings( $combobox_settings_profiles->get_active_text )
          if $combobox_settings_profiles->get_active != -1;

        #autostart
        $sas->create_autostart_file( $sdir->get_autostart_dir, $fs_active->get_active, $fs_min_active->get_active, $fs_nonot_active->get_active );

        #we need to update the first tab here
        #because the profile might have changed
        &fct_update_info_and_tray();

        return TRUE;
    }

    sub evt_page_setup {
        my ( $widget, $data ) = @_;

        #restore settings if prossible
        my $ssettings = Gtk2::PrintSettings->new;
        if ( $shf->file_exists("$ENV{ HOME }/.shutter/printing.xml") ) {
            eval { $ssettings = Gtk2::PrintSettings->new_from_file("$ENV{ HOME }/.shutter/printing.xml"); };
        }

        $pagesetup = Gtk2::Print->run_page_setup_dialog( $window, $pagesetup, $ssettings );

        return TRUE;
    }

    sub evt_save_as {
        my ( $widget, $data ) = @_;
        print "\n$data was emitted by widget $widget\n"
          if $sc->get_debug;

        my $key = &fct_get_current_file;

        my @save_as_files;

        #single file
        if ($key) {

            push @save_as_files, $key;

            #session tab
        }
        else {

            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push @save_as_files, $key;
                    }
                },
                undef
            );

        }

        #determine requested filetype
        my $rfiletype = undef;
        if ( $data eq 'menu_export_svg' ) {
            $rfiletype = 'svg';
        }
        elsif ( $data eq 'menu_export_ps' ) {
            $rfiletype = 'ps';
        }
        elsif ( $data eq 'menu_export_pdf' ) {
            $rfiletype = 'pdf';
        }

        foreach my $file (@save_as_files) {
            &dlg_save_as( $file, $rfiletype );
        }

        return TRUE;

    }

    sub evt_save_profile {
        my ( $widget, $combobox_settings_profiles, $current_profiles_ref ) = @_;
        my $curr_profile_name = $combobox_settings_profiles->get_active_text
          || "";
        my $new_profile_name = &dlg_profile_name( $curr_profile_name, $combobox_settings_profiles );

        if ($new_profile_name) {
            if ( $curr_profile_name ne $new_profile_name ) {
                $combobox_settings_profiles->prepend_text($new_profile_name);
                $combobox_settings_profiles->set_active(0);
                $current_profile_indx = 0;

                #unshift to array as well
                unshift( @{$current_profiles_ref}, $new_profile_name );

                &fct_update_profile_selectors( $combobox_settings_profiles, $current_profiles_ref );

            }

            #save settings
            &fct_save_settings($new_profile_name);

            #autostart
            $sas->create_autostart_file( $sdir->get_autostart_dir, $fs_active->get_active, $fs_min_active->get_active, $fs_nonot_active->get_active );
        }
        return TRUE;
    }

    sub evt_delete_profile {
        my ( $widget, $combobox_settings_profiles, $current_profiles_ref ) = @_;
        if ( $combobox_settings_profiles->get_active_text ) {
            my $active_text  = $combobox_settings_profiles->get_active_text;
            my $active_index = $combobox_settings_profiles->get_active;
            unlink( "$ENV{'HOME'}/.shutter/profiles/" . $active_text . ".xml" );
            unlink( "$ENV{'HOME'}/.shutter/profiles/" . $active_text . "_accounts.xml" );

            unless ( $shf->file_exists( "$ENV{'HOME'}/.shutter/profiles/" . $active_text . ".xml" )
                || $shf->file_exists( "$ENV{'HOME'}/.shutter/profiles/" . $active_text . "_accounts.xml" ) )
            {
                $combobox_settings_profiles->remove_text($active_index);
                $combobox_settings_profiles->set_active( $combobox_settings_profiles->get_active + 1 );
                $current_profile_indx = $combobox_settings_profiles->get_active;

                #remove from array as well
                splice( @{$current_profiles_ref}, $active_index, 1 );

                &fct_update_profile_selectors( $combobox_settings_profiles, $current_profiles_ref );

                &fct_show_status_message( 1, $d->get("Profile deleted") );
            }
            else {
                $sd->dlg_error_message( $d->get("Profile could not be deleted"), $d->get("Failed") );
                &fct_show_status_message( 1, $d->get("Profile could not be deleted") );
            }
        }
        return TRUE;
    }

    sub evt_apply_profile {
        my ( $widget, $combobox_settings_profiles, $current_profiles_ref ) = @_;

        if ( $combobox_settings_profiles->get_active_text ) {
            $settings_xml = &fct_load_settings( 'profile_load', $combobox_settings_profiles->get_active_text );
            $current_profile_indx = $combobox_settings_profiles->get_active;
            my $current_profile_text = $combobox_settings_profiles->get_active_text;

            &fct_update_profile_selectors( $combobox_settings_profiles, $current_profiles_ref, $widget );

            &fct_update_info_and_tray();

            &fct_show_status_message( 1, sprintf( $d->get("Profile %s loaded successfully"), "'" . $current_profile_text . "'" ) );
        }

        return TRUE;
    }

    #--------------------------------------

    #functions
    #--------------------------------------

    sub fct_create_session_notebook {

        #~ $notebook->set( 'homogeneous' => TRUE );
        $notebook->set( 'scrollable' => TRUE );

        #enable dnd for it
        $notebook->drag_dest_set( 'all', [ 'copy', 'private', 'default', 'move', 'link', 'ask' ] );
        $notebook->signal_connect( drag_data_received => \&fct_drop_handler );

        my $target_list = Gtk2::TargetList->new();
        my $atom_dest   = Gtk2::Gdk::Atom->new('text/uri-list');
        $target_list->add( $atom_dest, 0, 0 );
        $notebook->drag_dest_set_target_list($target_list);

        #packing and first page
        my $hbox_first_label = Gtk2::HBox->new( FALSE, 0 );
        my $thumb_first_icon = Gtk2::Image->new_from_stock( 'gtk-index', 'menu' );
        my $tab_first_label = Gtk2::Label->new();
        $tab_first_label->set_markup( "<b>" . $d->get("Session") . "</b>" );
        $hbox_first_label->pack_start( $thumb_first_icon, FALSE, FALSE, 1 );
        $hbox_first_label->pack_start( $tab_first_label,  FALSE, FALSE, 1 );
        $hbox_first_label->show_all;

        my $new_index = $notebook->append_page( fct_create_tab( "", TRUE ), $hbox_first_label );
        $session_start_screen{'first_page'}->{'tab_child'} = $notebook->get_nth_page($new_index);

        $notebook->signal_connect( 'switch-page' => \&evt_notebook_switch );

        return $notebook;
    }

    sub fct_integrate_screenshot_in_notebook {
        my ( $uri, $pixbuf, $history, $count ) = @_;

        #check parameters
        return FALSE unless $uri;
        unless ( $uri->exists ) {
            &fct_show_status_message( 1, $uri->get_path . " " . $d->get("not found") );
            return FALSE;
        }

        #check mime type
        my $mime_type = Gnome2::VFS->get_mime_type_for_name( $uri->to_string );
        $mime_type =~ s/image\/x\-apple\-ios\-png/image\/png/; #FIXME
        if ( $mime_type =~ m/(pdf|ps|svg)/ig ) {

            #not a supported mime type
            #~ my $response = $sd->dlg_error_message(
            #~ sprintf ( $d->get(  "Error while opening image %s." ), "'" . $uri->to_string . "'" ) ,
            #~ $d->get( "There was an error opening the image." ),
            #~ undef, undef, undef,
            #~ undef, undef, undef,
            #~ $d->get( "MimeType not supported." )
            #~ );
            #~ &fct_show_status_message( 1, $uri->to_string . " " . $d->get("not supported") );
            return FALSE;
        }

        #~ my $mime_type = Gnome2::VFS->get_mime_type_for_name( $uri->to_string );
        #~ unless ($mime_type && &fct_check_valid_mime_type($mime_type)){
        #~ #not a supported mime type
        #~ my $response = $sd->dlg_error_message(
        #~ sprintf ( $d->get(  "Error while opening image %s." ), "'" . $uri->to_string . "'" ) ,
        #~ $d->get( "There was an error opening the image." ),
        #~ undef, undef, undef,
        #~ undef, undef, undef,
        #~ $d->get( "MimeType not supported." )
        #~ );
        #~ &fct_show_status_message( 1, $uri->to_string . " " . $d->get("not supported") );
        #~ return FALSE;
        #~ }

        #add to recentmanager
        Gtk2::RecentManager->get_default->add_item( $uri->to_string );

        #FIXME
        my $num_files = $session_start_screen{'first_page'}->{'num_session_files'};

        #append a page to notebook using with label == filename
        my $fname = $shf->utf8_decode( Gnome2::VFS->unescape_string_for_display( $uri->extract_short_name ) );
        my $key   = 0;
        my $indx  = 0;
        if ( defined $num_files && $num_files > 0 ) {
            if ( defined $history && $history->get_history ) {
                $indx = $num_files + 1;

                #update it (e.g. when taking more than one screenshot when still loading session)
                $session_start_screen{'first_page'}->{'num_session_files'} = $indx;
            }
            elsif ( defined $count ) {
                $indx = $count;
            }
            else {
                $indx = $num_files + 1;
                while ( $indx < &fct_get_latest_tab_key ) {
                    $indx++;
                }

                #update it (e.g. when taking more than one screenshot when still loading session)
                $session_start_screen{'first_page'}->{'num_session_files'} = $indx;
            }
        }
        else {
            $indx = &fct_get_latest_tab_key;
        }

        $key = "[" . $indx . "] - $fname";

        #~ print $key, "-", $uri->to_string, "\n";

        #store the history object
        if ( defined $history && $history->get_history ) {
            $session_screens{$key}->{'history'}              = $history;
            $session_start_screen{'first_page'}->{'history'} = $history;
            $session_screens{$key}->{'history_timestamp'}    = time;
        }

        #setup tab label (thumb, preview etc.)
        my $hbox_tab_label = Gtk2::HBox->new( FALSE, 0 );
        my $close_icon = Gtk2::Image->new_from_icon_name( 'gtk-close', 'menu' );

        $session_screens{$key}->{'tab_icon'} = Gtk2::Image->new;

        #setup tab label
        my $tab_close_button = Gtk2::Button->new;
        $tab_close_button->set_relief('none');
        $tab_close_button->set_image($close_icon);
        $tab_close_button->set_name('tab-close-button');

        #customize the button style
        Gtk2::Rc->parse_string(
            "style 'tab-close-button-style' {
				 GtkWidget::focus-padding = 0
				 GtkWidget::focus-line-width = 0
				 xthickness = 0
				 ythickness = 0
			 }
			 widget '*.tab-close-button' style 'tab-close-button-style'"
        );

        my $tab_label = Gtk2::Label->new($key);
        $tab_label->set_ellipsize('middle');
        $tab_label->set_width_chars(20);
        $hbox_tab_label->pack_start( $session_screens{$key}->{'tab_icon'}, FALSE, FALSE, 1 );
        $hbox_tab_label->pack_start( $tab_label,                           TRUE,  TRUE,  1 );
        $hbox_tab_label->pack_start( Gtk2::HBox->new,                      TRUE,  TRUE,  1 );
        $hbox_tab_label->pack_start( $tab_close_button,                    FALSE, FALSE, 1 );
        $hbox_tab_label->show_all;

        #and append page with label == key
        my $new_index = 0;
        if ( defined $num_files && $num_files > 0 ) {
            if ( defined $history && $history->get_history ) {
                $new_index = $notebook->insert_page( &fct_create_tab( $key, FALSE ), $hbox_tab_label, $indx );
            }
            elsif ( defined $count ) {
                $new_index = $notebook->insert_page( &fct_create_tab( $key, FALSE ), $hbox_tab_label, $count );
            }
            else {
                $new_index = $notebook->insert_page( &fct_create_tab( $key, FALSE ), $hbox_tab_label, $indx );
            }
        }
        else {
            $new_index = $notebook->append_page( &fct_create_tab( $key, FALSE ), $hbox_tab_label );
        }
        $session_screens{$key}->{'tab_indx'}       = $indx;
        $session_screens{$key}->{'tab_label'}      = $tab_label;
        $session_screens{$key}->{'hbox_tab_label'} = $hbox_tab_label;
        $session_screens{$key}->{'tab_child'}      = $notebook->get_nth_page($new_index);
        $tab_close_button->signal_connect( clicked => sub { &fct_remove($key); } );

        #this value is undefined when all files are loaded
        #in this case we switch to any new image
        unless ( defined $session_start_screen{'first_page'}->{'num_session_files'} ) {
            $notebook->set_current_page($new_index);
        }
        else {

            #if there is a history we recently took a screenshot
            #switch to that page
            #(even though the session is still loading)
            if ( defined $history && $history->get_history ) {
                $notebook->set_current_page($new_index);
            }
        }

        if ( &fct_update_tab( $key, $pixbuf, $uri ) ) {

            #setup a filemonitor, so we get noticed if the file changed
            &fct_add_file_monitor($key);
        }

        return $key;
    }

    sub fct_add_file_monitor {
        my $key = shift;

        $session_screens{$key}->{'changed'} = FALSE;
        $session_screens{$key}->{'deleted'} = FALSE;
        $session_screens{$key}->{'created'} = FALSE;

        my $result;
        if ( defined $session_screens{$key}->{'uri'} ) {
            ( $result, $session_screens{$key}->{'handle'} ) = Gnome2::VFS::Monitor->add(
                $session_screens{$key}->{'uri'}->to_string,
                'file',
                sub {
                    my $handle = shift;
                    my $file1  = shift;
                    my $file2  = shift;
                    my $event  = shift;
                    my $key    = shift;

                    print $event. " - $key\n" if $sc->get_debug;

                    if ( $event eq 'deleted' ) {

                        $handle->cancel;

                        if ( exists $session_screens{$key} ) {
                            $session_screens{$key}->{'deleted'} = TRUE;
                            $session_screens{$key}->{'changed'} = TRUE;
                            &fct_update_tab($key);
                        }

                    }
                    elsif ( $event eq 'changed' ) {

                        print $session_screens{$key}->{'uri'}->to_string . " - " . $event . "\n"
                          if $sc->get_debug;
                        $session_screens{$key}->{'changed'} = TRUE;
                        &fct_update_tab($key);

                    }

                },
                $key
            );
        }
        else {
            $result = 'error-generic';
        }

        #show error dialog when installing the file
        #monitor failed
        unless ( $result eq 'ok' ) {
            $sd->dlg_error_message( Gnome2::VFS->result_to_string($result), $d->get("Error while adding the file monitor.") );
            return FALSE;
        }

        return TRUE;
    }

    sub fct_control_signals {
        my $action = shift;

        my $sensitive = undef;
        if ( $action eq 'block' ) {

            $sensitive = FALSE;

            #block signals
            if ( $app->signal_handler_is_connected($app_watch_id) ) {
                $app->signal_handler_block($app_watch_id);
            }

            #and block status icon handler
            if ( $tray && $tray->isa('Gtk2::StatusIcon') ) {
                if ( $tray->signal_handler_is_connected( $tray->{'hid'} ) ) {
                    $tray->signal_handler_block( $tray->{'hid'} );
                }
                if ( $tray->signal_handler_is_connected( $tray->{'hid2'} ) ) {
                    $tray->signal_handler_block( $tray->{'hid2'} );
                }
            }
            elsif ( $tray && $tray->isa('Gtk2::AppIndicator') ) {
                if ( Gtk2::AppIndicator->VERSION > 0.12 ) {
                    $tray->set_passive();
                }
            }
            elsif ($tray) {
                if ( $tray_box->signal_handler_is_connected( $tray_box->{'hid'} ) ) {
                    $tray_box->signal_handler_block( $tray_box->{'hid'} );
                }
            }

        }
        elsif ( $action eq 'unblock' ) {

            $sensitive = TRUE;

            #attach signal-handler again
            if ( $app->signal_handler_is_connected($app_watch_id) ) {
                $app->signal_handler_unblock($app_watch_id);
            }

            #and unblock status icon handler
            if ( $tray && $tray->isa('Gtk2::StatusIcon') ) {
                if ( $tray->signal_handler_is_connected( $tray->{'hid'} ) ) {
                    $tray->signal_handler_unblock( $tray->{'hid'} );
                }
                if ( $tray->signal_handler_is_connected( $tray->{'hid2'} ) ) {
                    $tray->signal_handler_unblock( $tray->{'hid2'} );
                }
            }
            elsif ( $tray && $tray->isa('Gtk2::AppIndicator') ) {
                if ( Gtk2::AppIndicator->VERSION > 0.12 ) {
                    $tray->set_active();
                }
            }
            elsif ($tray) {
                if ( $tray_box->signal_handler_is_connected( $tray_box->{'hid'} ) ) {
                    $tray_box->signal_handler_unblock( $tray_box->{'hid'} );
                }
            }

        }

        #enable/disable controls
        if ( $st->{_select} && $sm->{_menuitem_selection} ) {

            #menu
            $sm->{_menuitem_selection}->set_sensitive($sensitive);
            $sm->{_menuitem_full}->set_sensitive($sensitive);
            $sm->{_menuitem_window}->set_sensitive($sensitive);
            $sm->{_menuitem_section}->set_sensitive($sensitive);
            $sm->{_menuitem_menu}->set_sensitive($sensitive);
            $sm->{_menuitem_tooltip}->set_sensitive($sensitive);
            $sm->{_menuitem_web}->set_sensitive($sensitive)
              if ($gnome_web_photo);
            $sm->{_menuitem_iclipboard}->set_sensitive($sensitive);

            #toolbar
            $st->{_select}->set_sensitive($sensitive);
            $st->{_full}->set_sensitive($sensitive);
            $st->{_window}->set_sensitive($sensitive);
            $st->{_section}->set_sensitive($sensitive);
            $st->{_menu}->set_sensitive($sensitive);
            $st->{_tooltip}->set_sensitive($sensitive);
            $st->{_web}->set_sensitive($sensitive) if ($gnome_web_photo);

            #special case: redoshot (toolbar and menu)
            if (&fct_get_last_capture) {
                $st->{_redoshot}->set_sensitive($sensitive);
                $sm->{_menuitem_redoshot}->set_sensitive($sensitive);
            }

        }

        return TRUE;
    }

    sub fct_control_main_window {
        my $mode = shift;

        #default value for present is TRUE
        my $present = TRUE;
        $present = shift if @_;

        #this is an unusual method for raising the window
        #to the top within the stacking order (z-axis)
        #but it works best here
        if ( $mode eq 'show' && $is_hidden && $present ) {

            #move window to saved position
            $window->move( $window->{x}, $window->{y} )
              if ( defined $window->{x} && defined $window->{y} );

            $window->show_all;
            $window->window->focus( Gtk2->get_current_event_time )
              if defined $window->window;
            $window->present;

            #set flag
            $is_hidden = FALSE;

            #toolbar->set_show_arrow is FALSE at startup
            #to automatically adjust the main window width
            #we change the setting to TRUE if it is still false,
            #so the window/toolbar is resizable again
            if ( $st->{_toolbar} ) {
                unless ( $st->{_toolbar}->get_show_arrow ) {
                    $st->{_toolbar}->set_show_arrow(TRUE);

                    #add a small margin
                    my ( $rw, $rh ) = $window->get_size;
                    $window->resize( $rw + 50, $rh );
                }
            }

        }
        elsif ( $mode eq 'hide' ) {

            #save current position of main window
            ( $window->{x}, $window->{y} ) = $window->get_position;

            $window->hide;

            $is_hidden = TRUE;

        }

        return TRUE;
    }

    sub fct_create_tab {
        my ( $key, $is_all ) = @_;

        my $vbox     = Gtk2::VBox->new( FALSE, 0 );
        my $vbox_tab = Gtk2::VBox->new( FALSE, 0 );
        my $vbox_tab_event = Gtk2::EventBox->new;

        unless ($is_all) {

            #Gtk2::ImageView - empty at first
            $session_screens{$key}->{'image'} = Gtk2::ImageView->new();
            $session_screens{$key}->{'image'}->set_interpolation('tiles');
            $session_screens{$key}->{'image'}->set_show_frame(FALSE);

            #Sets how the view should draw transparent parts of images with an alpha channel
            my $color = $trans_custom_btn->get_color;
            my $color_string = sprintf( "%02x%02x%02x", $color->red / 257, $color->green / 257, $color->blue / 257 );

            my $mode;
            if ( $trans_check->get_active ) {
                $mode = 'grid';
            }
            elsif ( $trans_custom->get_active ) {
                $mode = 'color';
            }
            elsif ( $trans_backg->get_active ) {
                $mode = 'color';
                my $bg = $window->get_style->bg('normal');
                $color_string = sprintf( "%02x%02x%02x", $bg->red / 257, $bg->green / 257, $bg->blue / 257 );
            }

            $session_screens{$key}->{'image'}->set_transp( $mode, hex $color_string );

            #Gtk2::ImageView::ScrollWin packaged in a Gtk2::ScrolledWindow
            my $scrolled_window_image = Gtk2::ImageView::ScrollWin->new( $session_screens{$key}->{'image'} );

            #WORKAROUND
            #upstream bug
            #http://trac.bjourne.webfactional.com/ticket/21
            #left  => zoom in
            #right => zoom out
            $session_screens{$key}->{'image'}->signal_connect(
                'scroll-event',
                sub {
                    my ( $view, $ev ) = @_;
                    if ( $ev->direction eq 'left' ) {
                        $ev->direction('up');
                    }
                    elsif ( $ev->direction eq 'right' ) {
                        $ev->direction('down');
                    }
                    return FALSE;
                }
            );

            $session_screens{$key}->{'image'}->signal_connect(
                'button-press-event',
                sub {
                    my ( $view, $ev ) = @_;
                    if ( $ev->button == 1 && $ev->type eq '2button-press' ) {
                        &fct_zoom_best;
                        return TRUE;
                    }
                    else {
                        return FALSE;
                    }
                }
            );

            #dnd
            $session_screens{$key}->{'image'}->drag_source_set( 'button1-mask', ['copy'], { 'target' => "text/uri-list", 'flags' => [], 'info' => 0 } );
            $session_screens{$key}->{'image'}->signal_connect(
                'drag-data-get',
                sub {
                    my ( $widget, $context, $data, $info, $time ) = @_;
                    if ( exists $session_screens{$key}->{'uri'}
                        && defined $session_screens{$key}->{'uri'} )
                    {
                        $data->set( $data->target, 8, $session_screens{$key}->{'uri'}->to_string );
                    }
                }
            );

            #maybe we need to disable dnd to allow scrolling
            $session_screens{$key}->{'image'}->signal_connect(
                'expose-event',
                sub {
                    my ($view) = @_;
                    my $block_dnd = FALSE;
                    foreach my $child ( $scrolled_window_image->get_children ) {
                        if ( $child =~ /Scrollbar/ ) {
                            if ( $child->visible ) {
                                $block_dnd = TRUE;
                                last;
                            }
                        }
                    }
                    if ($block_dnd) {
                        $view->drag_source_unset;
                    }
                    else {
                        $view->drag_source_set(
                            'button1-mask',
                            ['copy'],
                            {
                                'target' => "text/uri-list",
                                'flags'  => [],
                                'info'   => 0
                            }
                        );
                    }
                }
            );

            $vbox_tab->pack_start( $scrolled_window_image, TRUE, TRUE, 0 );

            $vbox->pack_start_defaults($vbox_tab);

            #pack vbox into an event box so we can listen
            #to various key and button events
            $vbox_tab_event->add($vbox);
            $vbox_tab_event->show_all;
            $vbox_tab_event->signal_connect( 'button-press-event', \&evt_tab_button_press, $key );

            return $vbox_tab_event;

        }
        else {

            #create iconview for session
            $session_start_screen{'first_page'}->{'model'} = Gtk2::ListStore->new( 'Gtk2::Gdk::Pixbuf', 'Glib::String', 'Glib::String' );
            $session_start_screen{'first_page'}->{'model'}->set_sort_column_id( 2, 'descending' );
            $session_start_screen{'first_page'}->{'view'} = Gtk2::IconView->new_with_model( $session_start_screen{'first_page'}->{'model'} );

            #~ $session_start_screen{'first_page'}->{'view'}->set_orientation('horizontal');
            $session_start_screen{'first_page'}->{'view'}->set_item_width(150);
            $session_start_screen{'first_page'}->{'view'}->set_pixbuf_column(0);
            $session_start_screen{'first_page'}->{'view'}->set_text_column(1);
            $session_start_screen{'first_page'}->{'view'}->set_selection_mode('multiple');

            #~ $session_start_screen{'first_page'}->{'view'}->set_columns(0);
            $session_start_screen{'first_page'}->{'view'}->signal_connect( 'selection-changed', \&evt_iconview_sel_changed,    'sel_changed' );
            $session_start_screen{'first_page'}->{'view'}->signal_connect( 'item-activated',    \&evt_iconview_item_activated, 'item_activated' );

            #pack into scrolled window
            my $scrolled_window_view = Gtk2::ScrolledWindow->new;
            $scrolled_window_view->set_policy( 'automatic', 'automatic' );
            $scrolled_window_view->set_shadow_type('in');
            $scrolled_window_view->add( $session_start_screen{'first_page'}->{'view'} );

            #add an event box to show a context menu on right-click
            my $view_event = Gtk2::EventBox->new;
            $view_event->add($scrolled_window_view);
            $view_event->signal_connect( 'button-press-event', \&evt_iconview_button_press, $session_start_screen{'first_page'}->{'view'} );

            #dnd
            $session_start_screen{'first_page'}->{'view'}->enable_model_drag_source( 'button1-mask', ['copy'], { 'target' => "text/uri-list", 'flags' => [], 'info' => 0 } );
            $session_start_screen{'first_page'}->{'view'}->signal_connect(
                'drag-data-get',
                sub {
                    my ( $widget, $context, $data, $info, $time ) = @_;

                    my $target_list;
                    $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                        sub {
                            my ( $view, $path ) = @_;
                            my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                            if ( defined $iter ) {
                                my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                                if ( exists $session_screens{$key}->{'uri'}
                                    && defined $session_screens{$key}->{'uri'} )
                                {
                                    $target_list .= $session_screens{$key}->{'uri'}->to_string . "\n";
                                }
                            }
                        }
                    );

                    $data->set( $data->target, 8, $target_list );

                }
            );

            $vbox_tab->pack_start( $view_event, TRUE, TRUE, 0 );

            $vbox->pack_start_defaults($vbox_tab);
            $vbox->show_all;

            return $vbox;

        }

    }

    sub fct_save_settings {
        my ($profilename) = @_;

        #settings file
        my $settingsfile = "$ENV{ HOME }/.shutter/settings.xml";
        if ( defined $profilename ) {
            $settingsfile = "$ENV{ HOME }/.shutter/profiles/$profilename.xml"
              if ( $profilename ne "" );
        }

        #session file
        my $sessionfile = "$ENV{ HOME }/.shutter/session.xml";

        #accounts file
        my $accountsfile = "$ENV{ HOME }/.shutter/accounts.xml";
        if ( defined $profilename ) {
            $accountsfile = "$ENV{ HOME }/.shutter/profiles/$profilename\_accounts.xml"
              if ( $profilename ne "" );
        }

        #we store the version info, so we know if there was a new version installed
        #when starting new version we clear the cache on first startup
        $settings{'general'}->{'app_version'} = $sc->get_version . $sc->get_rev;

        $settings{'general'}->{'last_profile'} = $combobox_settings_profiles->get_active;
        $settings{'general'}->{'last_profile_name'} = $combobox_settings_profiles->get_active_text || "";

        #menu
        $settings{'gui'}->{'btoolbar_active'} = $sm->{_menuitem_btoolbar}->get_active();

        #recently used
        $settings{'recent'}->{'ruu_tab'}     = $sc->get_ruu_tab;
        $settings{'recent'}->{'ruu_hosting'} = $sc->get_ruu_hosting;
        $settings{'recent'}->{'ruu_places'}  = $sc->get_ruu_places;

        #main
        $settings{'general'}->{'filetype'} = $combobox_type->get_active;
        $settings{'general'}->{'quality'}  = $scale->get_value();
        $settings{'general'}->{'filename'} = $filename->get_text();
        $settings{'general'}->{'folder'}   = $saveDir_button->get_filename();

        #~ print "Pfad ".$saveDir_button->get_filename()."\n";
        #~ print "Pfad ".$saveDir_button->get_uri()."\n";
        $settings{'general'}->{'save_auto'}      = $save_auto_active->get_active();
        $settings{'general'}->{'save_ask'}       = $save_ask_active->get_active();
        $settings{'general'}->{'save_no'}        = $save_no_active->get_active();
        $settings{'general'}->{'image_autocopy'} = $image_autocopy_active->get_active();
        $settings{'general'}->{'fname_autocopy'} = $fname_autocopy_active->get_active();
        $settings{'general'}->{'no_autocopy'}    = $no_autocopy_active->get_active();
        $settings{'general'}->{'cursor'}         = $cursor_active->get_active();
        $settings{'general'}->{'delay'}          = $delay->get_value();

        #wrksp -> submenu
        $settings{'general'}->{'current_monitor_active'} = $current_monitor_active->get_active;

        #determining timeout
        if ($gnome_web_photo) {
            my $web_menu = $st->{_web}->get_menu;
            my @timeouts = $web_menu->get_children;
            my $timeout  = undef;
            foreach my $to (@timeouts) {
                if ( $to->get_active ) {
                    $timeout = $to->get_name;
                    $timeout =~ /([0-9]+)/;
                    $timeout = $1;
                }
            }
            $settings{'general'}->{'web_timeout'} = $timeout;
        }

        my $model         = $progname->get_model();
        my $progname_iter = $progname->get_active_iter();

        if ( defined $progname_iter ) {
            my $progname_value = $model->get_value( $progname_iter, 1 );
            $settings{'general'}->{'prog'} = $progname_value;
        }

        #actions
        $settings{'general'}->{'prog_active'}         = $progname_active->get_active();
        $settings{'general'}->{'im_colors'}           = $combobox_im_colors->get_active();
        $settings{'general'}->{'im_colors_active'}    = $im_colors_active->get_active();
        $settings{'general'}->{'thumbnail'}           = $thumbnail->get_value();
        $settings{'general'}->{'thumbnail_active'}    = $thumbnail_active->get_active();
        $settings{'general'}->{'bordereffect'}        = $bordereffect->get_value();
        $settings{'general'}->{'bordereffect_active'} = $bordereffect_active->get_active();
        my $bcolor = $bordereffect_cbtn->get_color;
        $settings{'general'}->{'bordereffect_col'} = sprintf( "#%02x%02x%02x", $bcolor->red / 257, $bcolor->green / 257, $bcolor->blue / 257 );

        #advanced
        $settings{'general'}->{'zoom_active'}      = $zoom_active->get_active();
        $settings{'general'}->{'as_help_active'}   = $as_help_active->get_active();
        $settings{'general'}->{'asel_x'}           = $asel_size3->get_value();
        $settings{'general'}->{'asel_y'}           = $asel_size4->get_value();
        $settings{'general'}->{'asel_w'}           = $asel_size1->get_value();
        $settings{'general'}->{'asel_h'}           = $asel_size2->get_value();
        $settings{'general'}->{'border'}           = $border_active->get_active();
        $settings{'general'}->{'winresize_active'} = $winresize_active->get_active();
        $settings{'general'}->{'winresize_w'}      = $winresize_w->get_value();
        $settings{'general'}->{'winresize_h'}      = $winresize_h->get_value();
        $settings{'general'}->{'autoshape_active'} = $autoshape_active->get_active();
        $settings{'general'}->{'visible_windows'}  = $visible_windows_active->get_active();
        $settings{'general'}->{'menu_delay'}       = $menu_delay->get_value();
        $settings{'general'}->{'menu_waround'}     = $menu_waround_active->get_active();
        $settings{'general'}->{'web_width'}        = $combobox_web_width->get_active();

        #imageview
        $settings{'general'}->{'trans_check'}  = $trans_check->get_active();
        $settings{'general'}->{'trans_custom'} = $trans_custom->get_active();
        my $tcolor = $trans_custom_btn->get_color;
        $settings{'general'}->{'trans_custom_col'} = sprintf( "#%02x%02x%02x", $tcolor->red / 257, $tcolor->green / 257, $tcolor->blue / 257 );
        $settings{'general'}->{'trans_backg'} = $trans_backg->get_active();

        $settings{'general'}->{'session_asc'}        = $session_asc->get_active();
        $settings{'general'}->{'session_asc_combo'}  = $session_asc_combo->get_active();
        $settings{'general'}->{'session_desc'}       = $session_desc->get_active();
        $settings{'general'}->{'session_desc_combo'} = $session_desc_combo->get_active();

        #behavior
        $settings{'general'}->{'autofs'}           = $fs_active->get_active();
        $settings{'general'}->{'autofs_min'}       = $fs_min_active->get_active();
        $settings{'general'}->{'autofs_not'}       = $fs_nonot_active->get_active();
        $settings{'general'}->{'autohide'}         = $hide_active->get_active();
        $settings{'general'}->{'autohide_time'}    = $hide_time->get_value();
        $settings{'general'}->{'present_after'}    = $present_after_active->get_active();
        $settings{'general'}->{'close_at_close'}   = $close_at_close_active->get_active();
        $settings{'general'}->{'notify_after'}     = $notify_after_active->get_active();
        $settings{'general'}->{'notify_timeout'}   = $notify_timeout_active->get_active();
        $settings{'general'}->{'notify_ptimeout'}  = $notify_ptimeout_active->get_active();
        $settings{'general'}->{'notify_agent'}     = $combobox_ns->get_active();
        $settings{'general'}->{'ask_on_delete'}    = $ask_on_delete_active->get_active();
        $settings{'general'}->{'delete_on_close'}  = $delete_on_close_active->get_active();
        $settings{'general'}->{'ask_on_fs_delete'} = $ask_on_fs_delete_active->get_active();

        #ftp upload
        $settings{'general'}->{'ftp_uri'}      = $ftp_remote_entry->get_text();
        $settings{'general'}->{'ftp_mode'}     = $ftp_mode_combo->get_active();
        $settings{'general'}->{'ftp_username'} = $ftp_username_entry->get_text();
        $settings{'general'}->{'ftp_password'} = $ftp_password_entry->get_text();
        $settings{'general'}->{'ftp_wurl'}     = $ftp_wurl_entry->get_text();

        #plugins
        foreach my $plugin_key ( sort keys %plugins ) {
            $settings{'plugins'}->{$plugin_key}->{'name'}        = $plugin_key;
            $settings{'plugins'}->{$plugin_key}->{'binary'}      = $plugins{$plugin_key}->{'binary'};
            $settings{'plugins'}->{$plugin_key}->{'name_plugin'} = $plugins{$plugin_key}->{'name'};
            $settings{'plugins'}->{$plugin_key}->{'category'}    = $plugins{$plugin_key}->{'category'};

            #keep newlines => switch them to <![CDATA[<br>]]> tags
            #the load routine does it the other way round
            my $temp_tooltip = $plugins{$plugin_key}->{'tooltip'};
            $temp_tooltip =~ s/\n/\<\!\[CDATA\[\<br\>\]\]\>/g;
            $settings{'plugins'}->{$plugin_key}->{'tooltip'} = $temp_tooltip;
            $settings{'plugins'}->{$plugin_key}->{'lang'}    = $plugins{$plugin_key}->{'lang'};
            $settings{'plugins'}->{$plugin_key}->{'recent'}  = $plugins{$plugin_key}->{'recent'}
              if defined $plugins{$plugin_key}->{'recent'};
        }

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

            #and finally move the file
            mv( $tmpfilename, $settingsfile );
        };
        if ($@) {
            $sd->dlg_error_message( $@, $d->get("Settings could not be saved!") );
        }
        else {
            &fct_show_status_message( 1, $d->get("Settings saved successfully!") );
        }

        #we need to clean the hashkeys, so they become parseable
        my %clean_files;
        my $counter = 0;
        foreach my $key ( Sort::Naturally::nsort( keys %session_screens ) ) {
            next unless exists $session_screens{$key}->{'long'};

            #8 leading zeros to counter
            $counter = sprintf( "%08d", $counter );
            if ( $shf->file_exists( $session_screens{$key}->{'long'} ) ) {
                $clean_files{ "file" . $counter }{'filename'} = $session_screens{$key}->{'long'};
                $counter++;
            }
        }

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

            #and finally move the file
            mv( $tmpfilename, $sessionfile );
        };
        if ($@) {
            $sd->dlg_error_message( $@, $d->get("Session could not be saved!") );
        }

        #accounts
        #~ print Dumper %accounts;
        my %clean_accounts;
        foreach my $ac ( keys %accounts ) {
            $clean_accounts{$ac}->{'path'}                       = $accounts{$ac}->{'path'};
            $clean_accounts{$ac}->{'host'}                       = $accounts{$ac}->{'host'};
            $clean_accounts{$ac}->{'password'}                   = $accounts{$ac}->{'password'};
            $clean_accounts{$ac}->{'username'}                   = $accounts{$ac}->{'username'};
            $clean_accounts{$ac}->{'module'}                     = $accounts{$ac}->{'module'};
            $clean_accounts{$ac}->{'folder'}                     = $accounts{$ac}->{'folder'};
            $clean_accounts{$ac}->{'description'}                = $accounts{$ac}->{'description'};
            $clean_accounts{$ac}->{'register_text'}              = $accounts{$ac}->{'register_text'};
            $clean_accounts{$ac}->{'register_color'}             = $accounts{$ac}->{'register_color'};
            $clean_accounts{$ac}->{'supports_anonymous_upload'}  = $accounts{$ac}->{'supports_anonymous_upload'};
            $clean_accounts{$ac}->{'supports_authorized_upload'} = $accounts{$ac}->{'supports_authorized_upload'};
            $clean_accounts{$ac}->{'supports_oauth_upload'}      = $accounts{$ac}->{'supports_oauth_upload'};
        }

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

            #and finally move the file
            mv( $tmpfilename, $accountsfile );
        };
        if ($@) {
            $sd->dlg_error_message( $@, $d->get("Account-settings could not be saved!") );
        }

        return TRUE;
    }

    sub fct_load_settings {
        my ( $data, $profilename ) = @_;

        #settings file
        my $settingsfile = "$ENV{ HOME }/.shutter/settings.xml";
        $settingsfile = "$ENV{ HOME }/.shutter/profiles/$profilename.xml"
          if ( defined $profilename );

        my $settings_xml;
        if ( $shf->file_exists($settingsfile) ) {
            eval {
                $settings_xml = XMLin( IO::File->new($settingsfile) );

                if ( $data eq 'profile_load' ) {

                    #migration from gscrot to shutter
                    #maybe we can drop this in future releases
                    # 0 := jpeg
                    # 1 := png
                    unless ( defined $settings_xml->{'general'}->{'app_version'} ) {
                        if ( $settings_xml->{'general'}->{'filetype'} == 0 ) {
                            $combobox_type->set_active($int_jpeg);
                        }
                        elsif ( $settings_xml->{'general'}->{'filetype'} == 1 ) {
                            $combobox_type->set_active($int_png);
                        }

                        #shutter
                    }
                    else {
                        $combobox_type->set_active( $settings_xml->{'general'}->{'filetype'} );
                    }

                    #main
                    $scale->set_value( $settings_xml->{'general'}->{'quality'} );
                    utf8::decode $settings_xml->{'general'}->{'filename'};
                    $filename->set_text( $settings_xml->{'general'}->{'filename'} );

                    utf8::decode $settings_xml->{'general'}->{'folder'};
                    $saveDir_button->set_current_folder( $settings_xml->{'general'}->{'folder'} );

                    $save_auto_active->set_active( $settings_xml->{'general'}->{'save_auto'} );
                    $save_ask_active->set_active( $settings_xml->{'general'}->{'save_ask'} );
                    $save_no_active->set_active( $settings_xml->{'general'}->{'save_no'} );

                    $image_autocopy_active->set_active( $settings_xml->{'general'}->{'image_autocopy'} );
                    $fname_autocopy_active->set_active( $settings_xml->{'general'}->{'fname_autocopy'} );
                    $no_autocopy_active->set_active( $settings_xml->{'general'}->{'no_autocopy'} );

                    $cursor_active->set_active( $settings_xml->{'general'}->{'cursor'} );
                    $delay->set_value( $settings_xml->{'general'}->{'delay'} );

                    #FIXME
                    #this is a dirty hack to force the setting to be enabled in session tab
                    #at the moment i simply dont know why the filechooser "caches" the old value
                    # => weird...
                    $settings_xml->{'general'}->{'folder_force'} = TRUE;

                    #wrksp -> submenu
                    $current_monitor_active->set_active( $settings_xml->{'general'}->{'current_monitor_active'} );

                    #determining timeout
                    my $web_menu = $st->{_web}->get_menu;
                    my @timeouts = $web_menu->get_children;
                    my $timeout  = undef;
                    foreach my $to (@timeouts) {
                        $timeout = $to->get_name;
                        $timeout =~ /([0-9]+)/;
                        $timeout = $1;
                        if ( $settings_xml->{'general'}->{'web_timeout'} == $timeout ) {
                            $to->set_active(TRUE);
                        }
                    }

                    #action settings
                    my $model = $progname->get_model;
                    utf8::decode $settings_xml->{'general'}->{'prog'};
                    $model->foreach( \&fct_iter_programs, $settings_xml->{'general'}->{'prog'} );
                    $progname_active->set_active( $settings_xml->{'general'}->{'prog_active'} );

                    $im_colors_active->set_active( $settings_xml->{'general'}->{'im_colors_active'} );
                    $combobox_im_colors->set_active( $settings_xml->{'general'}->{'im_colors'} );

                    $thumbnail->set_value( $settings_xml->{'general'}->{'thumbnail'} );
                    $thumbnail_active->set_active( $settings_xml->{'general'}->{'thumbnail_active'} );

                    $bordereffect->set_value( $settings_xml->{'general'}->{'bordereffect'} );
                    $bordereffect_active->set_active( $settings_xml->{'general'}->{'bordereffect_active'} );
                    if ( defined $settings_xml->{'general'}->{'bordereffect_col'} ) {
                        $bordereffect_cbtn->set_color( Gtk2::Gdk::Color->parse( $settings_xml->{'general'}->{'bordereffect_col'} ) );
                    }

                    #advanced settings
                    $zoom_active->set_active( $settings_xml->{'general'}->{'zoom_active'} );

                    $as_help_active->set_active( $settings_xml->{'general'}->{'as_help_active'} );

                    $asel_size3->set_value( $settings_xml->{'general'}->{'asel_x'} );
                    $asel_size4->set_value( $settings_xml->{'general'}->{'asel_y'} );
                    $asel_size1->set_value( $settings_xml->{'general'}->{'asel_w'} );
                    $asel_size2->set_value( $settings_xml->{'general'}->{'asel_h'} );

                    $border_active->set_active( $settings_xml->{'general'}->{'border'} );

                    $winresize_active->set_active( $settings_xml->{'general'}->{'winresize_active'} );
                    $winresize_w->set_value( $settings_xml->{'general'}->{'winresize_w'} );
                    $winresize_h->set_value( $settings_xml->{'general'}->{'winresize_h'} );

                    $autoshape_active->set_active( $settings_xml->{'general'}->{'autoshape_active'} );
                    $visible_windows_active->set_active( $settings_xml->{'general'}->{'visible_windows'} );
                    $menu_waround_active->set_active( $settings_xml->{'general'}->{'menu_waround'} );
                    $menu_delay->set_value( $settings_xml->{'general'}->{'menu_delay'} );
                    $combobox_web_width->set_active( $settings_xml->{'general'}->{'web_width'} );

                    #imageview
                    $trans_check->set_active( $settings_xml->{'general'}->{'trans_check'} );
                    $trans_custom->set_active( $settings_xml->{'general'}->{'trans_custom'} );
                    if ( defined $settings_xml->{'general'}->{'trans_custom_col'} ) {
                        $trans_custom_btn->set_color( Gtk2::Gdk::Color->parse( $settings_xml->{'general'}->{'trans_custom_col'} ) );
                    }
                    $trans_backg->set_active( $settings_xml->{'general'}->{'trans_backg'} );

                    $session_asc->set_active( $settings_xml->{'general'}->{'session_asc'} );
                    $session_asc_combo->set_active( $settings_xml->{'general'}->{'session_asc_combo'} );
                    $session_desc->set_active( $settings_xml->{'general'}->{'session_desc'} );
                    $session_desc_combo->set_active( $settings_xml->{'general'}->{'session_desc_combo'} );

                    #behavior
                    $fs_active->set_active( $settings_xml->{'general'}->{'autofs'} );
                    $fs_min_active->set_active( $settings_xml->{'general'}->{'autofs_min'} );
                    $fs_nonot_active->set_active( $settings_xml->{'general'}->{'autofs_not'} );
                    $hide_active->set_active( $settings_xml->{'general'}->{'autohide'} );
                    $hide_time->set_value( $settings_xml->{'general'}->{'autohide_time'} );
                    $present_after_active->set_active( $settings_xml->{'general'}->{'present_after'} );
                    $close_at_close_active->set_active( $settings_xml->{'general'}->{'close_at_close'} );
                    $notify_after_active->set_active( $settings_xml->{'general'}->{'notify_after'} );
                    $notify_timeout_active->set_active( $settings_xml->{'general'}->{'notify_timeout'} );
                    $notify_ptimeout_active->set_active( $settings_xml->{'general'}->{'notify_ptimeout'} );
                    $combobox_ns->set_active( $settings_xml->{'general'}->{'notify_agent'} );
                    $ask_on_delete_active->set_active( $settings_xml->{'general'}->{'ask_on_delete'} );
                    $delete_on_close_active->set_active( $settings_xml->{'general'}->{'delete_on_close'} );
                    $ask_on_fs_delete_active->set_active( $settings_xml->{'general'}->{'ask_on_fs_delete'} );

                    #ftp_upload
                    utf8::decode $settings_xml->{'general'}->{'ftp_uri'};
                    utf8::decode $settings_xml->{'general'}->{'ftp_mode'};
                    utf8::decode $settings_xml->{'general'}->{'ftp_username'};
                    utf8::decode $settings_xml->{'general'}->{'ftp_password'};
                    utf8::decode $settings_xml->{'general'}->{'ftp_wurl'};

                    $ftp_remote_entry->set_text( $settings_xml->{'general'}->{'ftp_uri'} );
                    $ftp_mode_combo->set_active( $settings_xml->{'general'}->{'ftp_mode'} );
                    $ftp_username_entry->set_text( $settings_xml->{'general'}->{'ftp_username'} );
                    $ftp_password_entry->set_text( $settings_xml->{'general'}->{'ftp_password'} );
                    $ftp_wurl_entry->set_text( $settings_xml->{'general'}->{'ftp_wurl'} );

                    #we store the version info, so we know if there was a new version installed
                    #when starting new version we clear the cache on first startup
                    if ( defined $settings_xml->{'general'}->{'app_version'} ) {
                        if ( $sc->get_version . $sc->get_rev ne $settings_xml->{'general'}->{'app_version'} ) {
                            $sc->set_clear_cache(TRUE);
                        }
                    }
                    else {
                        $sc->set_clear_cache(TRUE);
                    }

                    #load account data from profile unless param is set to ignore it
                    &fct_load_accounts($profilename);
                    if ( defined $accounts_tree ) {
                        &fct_load_accounts_tree;
                        $accounts_tree->set_model($accounts_model);
                        &fct_set_model_accounts($accounts_tree);
                    }

                    #endif profile load
                }
                else {

                    #recently used
                    $sc->set_ruu_tab( $settings_xml->{'recent'}->{'ruu_tab'} );
                    $sc->set_ruu_hosting( $settings_xml->{'recent'}->{'ruu_hosting'} );
                    $sc->set_ruu_places( $settings_xml->{'recent'}->{'ruu_places'} );

                    #we store the version info, so we know if there was a new version installed
                    #when starting new version we clear the cache on first startup
                    if ( defined $settings_xml->{'general'}->{'app_version'} ) {
                        if ( $sc->get_version . $sc->get_rev ne $settings_xml->{'general'}->{'app_version'} ) {
                            $sc->set_clear_cache(TRUE);
                        }
                    }
                    else {
                        $sc->set_clear_cache(TRUE);
                    }

                    #get plugins from cache unless param is set to ignore it
                    if ( !$sc->get_clear_cache ) {

                        foreach my $plugin_key ( sort keys %{ $settings_xml->{'plugins'} } ) {
                            utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'binary'};

                            #check if plugin still exists in filesystem
                            if ( $shf->file_exists( $settings_xml->{'plugins'}->{$plugin_key}->{'binary'} ) ) {

                                #restore newlines <![CDATA[<br>]]> tags => \n
                                $settings_xml->{'plugins'}->{$plugin_key}->{'tooltip'} =~ s/\<\!\[CDATA\[\<br\>\]\]\>/\n/g;

                                utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'name_plugin'};
                                utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'category'};
                                utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'tooltip'};
                                utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'lang'};
                                $plugins{$plugin_key}->{'binary'}   = $settings_xml->{'plugins'}->{$plugin_key}->{'binary'};
                                $plugins{$plugin_key}->{'name'}     = $settings_xml->{'plugins'}->{$plugin_key}->{'name_plugin'};
                                $plugins{$plugin_key}->{'category'} = $settings_xml->{'plugins'}->{$plugin_key}->{'category'};
                                $plugins{$plugin_key}->{'tooltip'}  = $settings_xml->{'plugins'}->{$plugin_key}->{'tooltip'};
                                $plugins{$plugin_key}->{'lang'}     = $settings_xml->{'plugins'}->{$plugin_key}->{'lang'} || "shell";
                                $plugins{$plugin_key}->{'recent'}   = $settings_xml->{'plugins'}->{$plugin_key}->{'recent'};
                            }

                        }    #endforeach

                    }    #endif plugins from cache

                }

            };
            if ($@) {
                $sd->dlg_error_message( $@, $d->get("Settings could not be restored!") );
                unlink $settingsfile;
            }
            else {
                &fct_show_status_message( 1, $d->get("Settings loaded successfully") );
            }

            #endif file exists
        }
        else {
            warn "ERROR: settingsfile " . $settingsfile . " does not exist\n\n";
        }

        return $settings_xml;
    }

    sub fct_get_program_model {
        my $model = Gtk2::ListStore->new( 'Gtk2::Gdk::Pixbuf', 'Glib::String', 'Glib::Scalar' );

        #add Shutter's built-in editor to the list
        if ($goocanvas) {
            my $icon_pixbuf = undef;
            my $icon        = 'shutter';
            if ( $sc->get_theme->has_icon($icon) ) {
                my ( $iw, $ih ) = Gtk2::IconSize->lookup('menu');
                eval { $icon_pixbuf = $sc->get_theme->load_icon( $icon, $ih, 'generic-fallback' ); };
                if ($@) {
                    print "\nWARNING: Could not load icon $icon: $@\n";
                    $icon_pixbuf = undef;
                }
            }
            $model->set( $model->append, 0, $icon_pixbuf, 1, $d->get("Built-in Editor"), 2, 'shutter-built-in' );
        }

        #get applications
        my $mime_type = Gnome2::VFS::Mime::Type->new('image/png');
        my @apps      = $mime_type->get_all_applications();

        #no apps determined!
        unless ( scalar @apps ) {
            return $model;
        }

        #create menu items
        foreach my $app (@apps) {

            #ignore Shutter's desktop entry
            next if $app->{'id'} eq 'shutter.desktop';

            $app->{'name'} = $shf->utf8_decode( $app->{'name'} );

            #get icon
            my $icon_pixbuf = undef;
            my $icon        = $app->get_icon;
            if ($icon) {

                #cut image formats
                $icon =~ s/(.png|.svg|.gif|.jpeg|.jpg|.xpm)//g;
                if ( $sc->get_theme->has_icon($icon) ) {
                    my ( $iw, $ih ) = Gtk2::IconSize->lookup('menu');
                    eval { $icon_pixbuf = $sc->get_theme->load_icon( $icon, $ih, 'generic-fallback' ); };
                    if ($@) {
                        print "\nWARNING: Could not load icon $icon: $@\n";
                        $icon_pixbuf = undef;
                    }
                }
            }
            $model->set( $model->append, 0, $icon_pixbuf, 1, $app->{'name'}, 2, $app );
        }

        return $model;
    }

    sub fct_load_accounts {
        my ($profilename) = @_;

        #accounts file
        my $accountsfile = "$ENV{ HOME }/.shutter/accounts.xml";
        $accountsfile = "$ENV{ HOME }/.shutter/profiles/$profilename\_accounts.xml"
          if ( defined $profilename );

        if ( $shf->file_exists($accountsfile) ) {
            my $accounts_xml = undef;
            eval { $accounts_xml = XMLin( IO::File->new($accountsfile) ) };
            if ($@) {
                $sd->dlg_error_message( $@, $d->get("Account-settings could not be restored!") );
                unlink $accountsfile;
            }
            else {
                foreach ( keys %{$accounts_xml} ) {

                    #check if plugin still exists
                    if ( $shf->file_exists( $accounts_xml->{$_}->{path} ) ) {

                        #clear cache
                        if ( !$sc->get_clear_cache ) {
                            $accounts{$_}->{path}                       = $accounts_xml->{$_}->{path};
                            $accounts{$_}->{module}                     = $accounts_xml->{$_}->{module};
                            $accounts{$_}->{host}                       = $accounts_xml->{$_}->{host};
                            $accounts{$_}->{folder}                     = $accounts_xml->{$_}->{folder};
                            $accounts{$_}->{description}                = $accounts_xml->{$_}->{description};
                            $accounts{$_}->{register_color}             = "blue";
                            $accounts{$_}->{register_text}              = $accounts_xml->{$_}->{register_text};
                            $accounts{$_}->{supports_anonymous_upload}  = $accounts_xml->{$_}->{supports_anonymous_upload};
                            $accounts{$_}->{supports_authorized_upload} = $accounts_xml->{$_}->{supports_authorized_upload};
                            $accounts{$_}->{supports_oauth_upload}      = $accounts_xml->{$_}->{supports_oauth_upload};

                            utf8::decode $accounts{$_}->{'host'};
                        }
                        $accounts{$_}->{username} = $accounts_xml->{$_}->{username};
                        $accounts{$_}->{password} = $accounts_xml->{$_}->{password};

                        utf8::decode $accounts{$_}->{'username'};
                        utf8::decode $accounts{$_}->{'password'};
                    }
                }
            }
        }

        return TRUE;
    }

    sub fct_drop_handler {
        my ( $widget, $context, $x, $y, $selection, $info, $time ) = @_;
        my $type = $selection->target->name;
        my $data = $selection->data;
        return unless $type eq 'text/uri-list';

        my @files = grep defined($_), split /[\r\n]+/, $data;

        my @valid_files;
        foreach my $file (@files) {
            my $mime_type = Gnome2::VFS->get_mime_type_for_name($file);
            $mime_type =~ s/image\/x\-apple\-ios\-png/image\/png/; #FIXME
            if ( $mime_type && &fct_check_valid_mime_type($mime_type) ) {
                push @valid_files, $file;
            }
        }

        #open all valid files
        if (@valid_files) {
            &fct_open_files(@valid_files);
        }
        else {
            $context->finish( 0, 0, $time );
            return FALSE;
        }

        $context->finish( 1, 0, $time );
        return TRUE;
    }

    sub fct_check_valid_mime_type {
        my $mime_type = shift;

        foreach my $format ( Gtk2::Gdk::Pixbuf->get_formats ) {
            foreach my $mtype ( @{ $format->{mime_types} } ) {
                return TRUE if $mtype eq $mime_type;
                last;
            }
        }

        return FALSE;
    }

    sub fct_open_files {
        my (@new_files) = @_;

        return FALSE if scalar(@new_files) < 1;

        my ( $throbber, $sep ) = &fct_toggle_status_throbber($status);

        foreach my $file (@new_files) {

            my $new_uri = Gnome2::VFS::URI->new( $shf->utf8_decode( Gnome2::VFS->unescape_string($file) ) );

            next if &fct_is_uri_in_session( $new_uri, TRUE );

            #refresh gui
            &fct_update_gui;

            #do the real work
            if ( &fct_integrate_screenshot_in_notebook($new_uri) ) {
                &fct_show_status_message( 1, $new_uri->get_path . " " . $d->get("opened") );
            }
            else {
                &fct_show_status_message( 1, sprintf( $d->get("Error while opening image %s."), "'" . $new_uri->extract_short_name . "'" ) );
            }
        }

        &fct_toggle_status_throbber( $status, $throbber, $sep );

        return TRUE;
    }

    sub fct_is_uri_in_session {
        my $uri  = shift;
        my $jump = shift;

        return FALSE unless $uri;

        foreach my $key ( keys %session_screens ) {
            if ( exists $session_screens{$key}->{'uri'} ) {
                if ( $uri->equal( $session_screens{$key}->{'uri'} ) ) {
                    if ( exists $session_screens{$key}->{'tab_child'} ) {
                        if ($jump) {
                            $notebook->set_current_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );
                        }
                        return TRUE;
                    }
                }
            }
        }

        return FALSE;
    }

    sub fct_toggle_status_throbber {
        my $status   = shift;
        my $throbber = shift;
        my $sep      = shift;
        return FALSE unless $status;

        if ( defined $throbber && defined $sep ) {
            $throbber->destroy;
            $throbber = undef;
            $sep->destroy;
            $sep = undef;
        }
        else {

            #don't show more than one
            foreach my $child ( $status->get_children ) {
                if ( $child->get_name eq 'throbber' ) {
                    return FALSE;
                }
            }
            $throbber = Gtk2::Image->new_from_file("$shutter_root/share/shutter/resources/icons/throbber_16x16.gif");
            $throbber->set_name('throbber');
            $sep = Gtk2::HSeparator->new;
            $status->pack_start( $sep, FALSE, FALSE, 3 );
            $status->pack_end( $throbber, FALSE, FALSE, 0 );
        }

        $status->show_all;

        return ( $throbber, $sep );
    }

    sub fct_load_session {

        #session file
        my $sessionfile = "$ENV{ HOME }/.shutter/session.xml";

        eval {
            my $session_xml = XMLin( IO::File->new($sessionfile) )
              if $shf->file_exists($sessionfile);

            return FALSE if scalar( keys %{$session_xml} ) < 1;

            #activate throbber
            my ( $throbber, $sep ) = &fct_toggle_status_throbber($status);

            #how many files have to be loaded
            #store this value in the session hash
            $session_start_screen{'first_page'}->{'num_session_files'} = scalar( keys %{$session_xml} );

            #local counter
            #is passed to several subroutines to indicate the correct index
            my $count = 0;
            foreach my $key ( sort keys %{$session_xml} ) {

                #increment counter
                $count++;

                #refresh gui
                &fct_update_gui;

                #do the real work
                my $new_uri = Gnome2::VFS::URI->new( ${$session_xml}{$key}{'filename'} );
                if ( &fct_integrate_screenshot_in_notebook( $new_uri, undef, undef, $count ) ) {
                    &fct_show_status_message( 1, $new_uri->get_path . " " . $d->get("opened") );
                }
                else {
                    &fct_show_status_message( 1, sprintf( $d->get("Error while opening image %s."), "'" . $new_uri->extract_short_name . "'" ) );
                }

            }

            #clear the value after loading the files
            $session_start_screen{'first_page'}->{'num_session_files'} = undef;

            #de-activate the throbber
            &fct_toggle_status_throbber( $status, $throbber, $sep );

        };
        if ($@) {
            $sd->dlg_error_message( $@, $d->get("Session could not be restored!") );
            unlink $sessionfile;
        }

        return TRUE;
    }

    sub fct_screenshot_exists {
        my ($key) = @_;

        #check if file still exists
        unless ( $session_screens{$key}->{'uri'}->exists ) {
            &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("not found") );
            return FALSE;
        }
        return TRUE;
    }

    sub fct_trash {
        my $key = shift;

        #cancel handle
        if ( exists $session_screens{$key}->{'handle'} ) {
            $session_screens{$key}->{'handle'}->cancel;
        }

        #find trash directory
        my $trash_uri = Gnome2::VFS->find_directory( Gnome2::VFS::URI->new( $ENV{'HOME'} ), 'trash', TRUE, TRUE, 755 );

        #create a trashinfo file to enable restoring (a tempfile first)
        my $trashinfo_path = $strash->create_trashinfo_file( Gnome2::VFS->escape_path_string( $session_screens{$key}->{'long'} ) );

        #get filename for trash folder
        my ( $short, $folder, $ext ) = fileparse( $session_screens{$key}->{'long'}, qr/\.[^.]*/ );
        my $new_trash_uri = &fct_get_next_filename( $short, $shf->utf8_decode( Gnome2::VFS->unescape_string( $trash_uri->get_path ) ), $ext );
        my $trash_filename = $shf->utf8_decode( Gnome2::VFS->unescape_string( $new_trash_uri->get_path ) );

        if ($trashinfo_path) {

            #get filename for trashinfo file
            my ( $ishort, $ifolder, $iext ) = fileparse( $trash_filename, qr/\.[^.]*/ );
            my $trashinfo_uri      = $new_trash_uri->get_parent->get_parent->append_path("info")->append_file_name( $ishort . $iext . ".trashinfo" );
            my $trashinfo_filename = $shf->utf8_decode( Gnome2::VFS->unescape_string( $trashinfo_uri->get_path ) );

            if ( $sc->get_debug ) {
                print "trashing file...\n";
                print $trash_filename,     "\n";
                print $trashinfo_filename, "\n";
            }

            #move trashinfo file
            my $result = Gnome2::VFS::Xfer->uri( Gnome2::VFS::URI->new($trashinfo_path), $trashinfo_uri, 'default', 'abort', 'replace', sub { return TRUE } );
            unless ( $result eq 'ok' ) {
                print "WARNING: ", sprintf( $d->get("Error while creating the trashinfo file %s."), "'" . $trashinfo_filename . "'" ), "\n";

                #~ $sd->dlg_error_message( Gnome2::VFS->result_to_string($result), sprintf ($d->get("Error while creating the trashinfo file %s."), "'" .$trashinfo_filename. "'" ) );
            }

            #delete temp trashinfo file
            unlink $trashinfo_path;
        }

        #move to trash (Xfer because the Trash might be on a different filesystem)
        my $result = Gnome2::VFS::Xfer->uri( $session_screens{$key}->{'uri'}, $new_trash_uri, 'default', 'abort', 'replace', sub { return TRUE } );
        unless ( $result eq 'ok' ) {
            $sd->dlg_error_message( Gnome2::VFS->result_to_string($result), sprintf( $d->get("Error while moving the file %s to trash."), "'" . $trash_filename . "'" ) );
        }

        #and finally delete the file
        $result = $session_screens{$key}->{'uri'}->unlink;
        unless ( $result eq 'ok' ) {
            $sd->dlg_error_message( Gnome2::VFS->result_to_string($result), sprintf( $d->get("Error while removing the file %s from disk."), "'" . $session_screens{$key}->{'long'} . "'" ) );
        }

    }

    sub fct_delete {
        my $key    = shift;
        my $action = shift;

        #close current tab (unless $key is provided or close_all)
        unless ( defined $action && $action eq 'menu_close_all' ) {
            $key = &fct_get_current_file unless $key;
        }

        #single file
        if ($key) {

            if ( $ask_on_delete_active->get_active ) {
                my $response = $sd->dlg_question_message( "", sprintf( $d->get("Are you sure you want to move %s to the trash?"), "'" . $session_screens{$key}->{'long'} . "'" ), 'gtk-cancel', $d->get("Move to _Trash"), );
                return FALSE unless $response == 20;
            }

            if ( $session_screens{$key}->{'uri'}->exists ) {
                &fct_trash($key);
                eval {

                    #remove from recentmanager
                    Gtk2::RecentManager->get_default->remove_item( $session_screens{$key}->{'uri'}->to_string );
                };
            }

            $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
            &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("deleted") )
              if defined( $session_screens{$key}->{'long'} );

            if ( defined $session_screens{$key}->{'iter'}
                && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
            {
                $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
            }

            #unlink undo and redo files
            &fct_unlink_tempfiles($key);

            delete $session_screens{$key};

            $window->show_all unless $is_hidden;

            #session tab
        }
        else {

            if ( $ask_on_delete_active->get_active ) {

                #any files selected?
                my $selected = FALSE;
                $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                    sub {
                        my ( $view, $path ) = @_;
                        my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                        if ( defined $iter ) {
                            $selected = TRUE;
                        }
                    }
                );

                if ($selected) {
                    my $response = $sd->dlg_question_message( "", $d->get("Are you sure you want to move the selected files to the trash?"), 'gtk-cancel', $d->get("Move to _Trash"), );
                    return FALSE unless $response == 20;
                }
                else {
                    &fct_show_status_message( 1, $d->get("No screenshots selected") );
                    return FALSE;
                }
            }

            my @to_delete;
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );

                        if ( $session_screens{$key}->{'uri'}->exists ) {
                            &fct_trash($key);
                            eval {

                                #remove from recentmanager
                                Gtk2::RecentManager->get_default->remove_item( $session_screens{$key}->{'uri'}->to_string );
                            };
                        }

                        #copy to array
                        #we delete the files from hash and model
                        #when exiting the sub
                        push @to_delete, $key;

                    }
                },
                undef
            );

            if ( scalar @to_delete == 0 ) {
                &fct_show_status_message( 1, $d->get("No screenshots selected") );
                return FALSE;
            }

            #delete from hash and model
            foreach my $key (@to_delete) {
                if ( defined $session_screens{$key}->{'iter'}
                    && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                {
                    $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
                }

                #unlink undo and redo files
                &fct_unlink_tempfiles($key);

                delete $session_screens{$key};
            }

            &fct_show_status_message( 1, $d->get("Selected screenshots deleted") );

            $window->show_all unless $is_hidden;

        }

        &fct_update_info_and_tray();

        return TRUE;
    }

    sub fct_remove {
        my $key    = shift;
        my $action = shift;

        #close current tab (unless $key is provided or close_all)
        unless ( defined $action && $action eq 'menu_close_all' ) {
            $key = &fct_get_current_file unless $key;
        }

        #single file
        if ($key) {

            #delete instead of remove
            if ( $delete_on_close_active->get_active ) {
                &fct_delete($key);
                return FALSE;
            }

            if ( exists $session_screens{$key}->{'handle'} ) {

                #cancel handle
                $session_screens{$key}->{'handle'}->cancel;
            }

            $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
            &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
              if defined( $session_screens{$key}->{'long'} );

            if ( defined $session_screens{$key}->{'iter'}
                && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
            {
                $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
            }

            #unlink undo and redo files
            &fct_unlink_tempfiles($key);

            delete $session_screens{$key};

            $window->show_all unless $is_hidden;

        }
        else {

            #delete instead of remove
            if ( $delete_on_close_active->get_active ) {
                &fct_delete( undef, 'menu_close_all' );
                return FALSE;
            }

            my @to_remove;
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );

                        if ( exists $session_screens{$key}->{'handle'} ) {

                            #cancel handle
                            $session_screens{$key}->{'handle'}->cancel;
                        }

                        #copy to array
                        #we remove the files from hash and model
                        #when exiting the sub
                        push @to_remove, $key;

                    }
                },
                undef
            );

            if ( scalar @to_remove == 0 ) {
                &fct_show_status_message( 1, $d->get("No screenshots selected") );
                return FALSE;
            }

            #delete from hash and model
            foreach my $key (@to_remove) {
                if ( defined $session_screens{$key}->{'iter'}
                    && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                {
                    $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
                }

                #unlink undo and redo files
                &fct_unlink_tempfiles($key);

                delete $session_screens{$key};
            }

            &fct_show_status_message( 1, $d->get("Selected screenshots removed") );

            $window->show_all unless $is_hidden;

        }

        &fct_update_info_and_tray();

        return TRUE;
    }

    sub fct_update_gui {

        while ( Gtk2->events_pending ) {
            Gtk2->main_iteration;
        }
        Gtk2::Gdk->flush;

        return TRUE;
    }

    sub fct_clipboard_import {

        my $image = $clipboard->wait_for_image;
        if ( defined $image ) {

            #determine current file type (name - description)
            $combobox_type->get_active_text =~ /(.*) -/;
            my $filetype_value = $1;
            unless ($filetype_value) {
                $sd->dlg_error_message( $d->get("No valid filetype specified"), $d->get("Failed") );
                &fct_control_main_window('show');
                return FALSE;
            }

            #create tempfile
            my ( $tmpfh, $tmpfilename ) = tempfile( UNLINK => 1 );
            $tmpfilename .= "." . $filetype_value;

            #save pixbuf to tempfile and integrate it
            if ( $sp->save_pixbuf_to_file( $image, $tmpfilename, $filetype_value ) ) {
                my $new_key = &fct_integrate_screenshot_in_notebook( Gnome2::VFS::URI->new($tmpfilename), $image );
            }

        }
        else {
            &fct_show_status_message( 1, $d->get("There is no image data in the clipboard to paste") );
        }

        return TRUE;
    }

    sub fct_clipboard {
        my ( $widget, $mode ) = @_;

        my $key = &fct_get_current_file;

        #create shutter region object
        my $sr = Shutter::Geometry::Region->new();

        my @clipboard_array;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);
            push( @clipboard_array, $key );

        }
        else {

            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @clipboard_array, $key );
                    }
                },
                undef
            );

        }

        my $clipboard_string = undef;
        my $clipboard_region = Gtk2::Gdk::Region->new;
        my @pixbuf_array;
        my @rects_array;
        foreach my $key (@clipboard_array) {

            if ( $mode eq 'image' ) {
                my $pixbuf = $lp->load( $session_screens{$key}->{'long'} );
                my $rect = Gtk2::Gdk::Rectangle->new( $sr->get_clipbox($clipboard_region)->width, 0, $pixbuf->get_width, $pixbuf->get_height );
                $clipboard_region->union_with_rect($rect);
                push @pixbuf_array, $pixbuf;
                push @rects_array,  $rect;
            }
            else {
                $clipboard_string .= $session_screens{$key}->{'long'} . "\n";
            }

        }

        if ($clipboard_string) {
            chomp $clipboard_string;
            $clipboard->set_text($clipboard_string);
            &fct_show_status_message( 1, $d->get("Selected filenames copied to clipboard") );
        }

        if ( $clipboard_region->get_rectangles ) {
            my $clipboard_image = Gtk2::Gdk::Pixbuf->new( 'rgb', TRUE, 8, $sr->get_clipbox($clipboard_region)->width, $sr->get_clipbox($clipboard_region)->height );
            $clipboard_image->fill(0x00000000);

            #copy images to the blank pixbuf
            my $rect_counter = 0;
            foreach my $pixbuf (@pixbuf_array) {
                $pixbuf->copy_area( 0, 0, $pixbuf->get_width, $pixbuf->get_height, $clipboard_image, $rects_array[$rect_counter]->x, 0 );
                $rect_counter++;
            }

            $clipboard->set_image($clipboard_image);
            &fct_show_status_message( 1, $d->get("Selected images copied to clipboard") );
        }

        return TRUE;
    }

    sub fct_unlink_tempfiles {
        my $key = shift;

        foreach my $tmpf ( @{ $session_screens{$key}->{'undo'} } ) {
            unlink $tmpf;
        }

        foreach my $tmpf ( @{ $session_screens{$key}->{'redo'} } ) {
            unlink $tmpf;
        }

        return TRUE;
    }

    sub fct_undo {

        my $key = &fct_get_current_file;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);

            #push current version to redo
            #(current version is always the last element in the array)
            my $current_version = pop @{ $session_screens{$key}->{'undo'} };
            push @{ $session_screens{$key}->{'redo'} }, $current_version;

            #and revert last version
            my $last_version = pop @{ $session_screens{$key}->{'undo'} };
            if ($last_version) {

                #cancel handle
                if ( exists $session_screens{$key}->{'handle'} ) {
                    $session_screens{$key}->{'handle'}->cancel;
                }

                if ( cp( $last_version, $session_screens{$key}->{'long'} ) ) {

                    &fct_update_tab( $key, undef, $session_screens{$key}->{'uri'}, TRUE, 'gui' );

                    &fct_show_status_message( 1, $d->get("Last action undone") );

                    #delete last_version from filesystem
                    unlink $last_version;

                }
                else {

                    my $response = $sd->dlg_error_message( sprintf( $d->get("Error while copying last version (%s)."), "'" . $last_version . "'" ), sprintf( $d->get("There was an error performing undo on %s."), "'" . $session_screens{$key}->{'long'} . "'" ), undef, undef, undef, undef, undef, undef, $@ );

                    &fct_update_tab( $key, undef, $session_screens{$key}->{'uri'}, TRUE, 'clear' );

                }

                #setup a new filemonitor, so we get noticed if the file changed
                &fct_add_file_monitor($key);

            }

        }
        return TRUE;
    }

    sub fct_redo {

        my $key = &fct_get_current_file;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);

            #and revert last version
            my $last_version = pop @{ $session_screens{$key}->{'redo'} };

            #~ push @{$session_screens{$key}->{'undo'}}, $last_version;

            if ($last_version) {

                #cancel handle
                if ( exists $session_screens{$key}->{'handle'} ) {
                    $session_screens{$key}->{'handle'}->cancel;
                }

                if ( cp( $last_version, $session_screens{$key}->{'long'} ) ) {

                    &fct_update_tab( $key, undef, $session_screens{$key}->{'uri'}, TRUE, 'gui' );

                    &fct_show_status_message( 1, $d->get("Last action redone") );

                    #delete last_version from filesystem
                    unlink $last_version;

                }
                else {

                    my $response = $sd->dlg_error_message( sprintf( $d->get("Error while copying last version (%s)."), "'" . $last_version . "'" ), sprintf( $d->get("There was an error performing redo on %s."), "'" . $session_screens{$key}->{'long'} . "'" ), undef, undef, undef, undef, undef, undef, $@ );

                    &fct_update_tab( $key, undef, $session_screens{$key}->{'uri'}, TRUE, 'clear' );

                }

                #setup a new filemonitor, so we get noticed if the file changed
                &fct_add_file_monitor($key);

            }

        }
        return TRUE;
    }

    sub fct_select_all {

        $session_start_screen{'first_page'}->{'view'}->select_all;

        return TRUE;
    }

    sub fct_plugin {

        my $key = &fct_get_current_file;

        my @plugin_array;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);

            unless ( keys %plugins > 0 ) {
                $sd->dlg_error_message( $d->get("No plugin installed"), $d->get("Failed") );
            }
            else {
                push( @plugin_array, $key );
                &dlg_plugin(@plugin_array);
            }

            #session tab
        }
        else {

            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @plugin_array, $key );
                    }

                },
                undef
            );
            &dlg_plugin(@plugin_array);
        }
        return TRUE;
    }

    sub fct_show_in_folder {
        my $key = &fct_get_current_file;

        my @show_in_folder_array;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);

            print "Showing in filebrowser started  - file: " . $session_screens{$key}->{'long'} . "\n"
              if $sc->get_debug;
            push( @show_in_folder_array, $key );

        }
        else {

            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @show_in_folder_array, $key );
                    }
                },
                undef
            );

        }

        #open folders in filebrowser
        foreach my $ckey (@show_in_folder_array) {
            $shf->xdg_open( undef, $session_screens{$ckey}->{'folder'} );
        }

        return TRUE;
    }

    sub fct_rename {

        my $key = &fct_get_current_file;

        my @rename_array;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);

            print "Renaming of file " . $session_screens{$key}->{'long'} . " started\n"
              if $sc->get_debug;
            push( @rename_array, $key );

        }
        else {
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @rename_array, $key );
                    }
                },
                undef
            );
        }

        &dlg_rename(@rename_array);

        return TRUE;
    }

    sub fct_draw {

        my $key = &fct_get_current_file;

        my @draw_array;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);
            push( @draw_array, $key );

        }
        else {
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @draw_array, $key );
                    }
                },
                undef
            );
        }

        #open drawing tool
        foreach my $key (@draw_array) {
            my $drawing_tool = Shutter::Draw::DrawingTool->new($sc);
            $drawing_tool->show( $session_screens{$key}->{'long'}, $session_screens{$key}->{'filetype'}, $session_screens{$key}->{'mime_type'}, $session_screens{$key}->{'name'}, $session_screens{$key}->{'is_unsaved'}, \%session_screens );
        }

        #~ &fct_control_main_window ('show');

        return TRUE;
    }

    sub fct_take_screenshot {
        my ( $widget, $data, $folder_from_config, $extra ) = @_;

        print "\n$data was emitted by widget $widget\n"
          if $sc->get_debug;

        #quality
        my $quality_value = $scale->get_value();

        #delay
        my $delay_value = undef;

        #include_cursor
        my $include_cursor = undef;

        #filename
        my $filename_value = $filename->get_text();

        #filetype
        my $filetype_value = undef;

        #folder to save
        my $folder = $saveDir_button->get_filename || $folder_from_config;
        if ( $save_no_active->get_active ) {
            $folder = $sdir->get_cache_dir;
        }

        #screenshot(pixbuf) and screenshot name
        my $screenshot       = undef;
        my $screenshooter    = undef;
        my $screenshot_name  = undef;
        my $thumbnail_ending = "thumb";

        #determine current file type (name - description)
        $combobox_type->get_active_text =~ /(.*) -/;
        $filetype_value = $1;
        unless ($filetype_value) {
            $sd->dlg_error_message( $d->get("No valid filetype specified"), $d->get("Failed") );
            &fct_control_main_window('show');
            return FALSE;
        }

        #delay
        #when capturing a menu or tooltip => disable delay (there is a dedicated delay property for this)
        unless ( $data eq "menu"
            || $data eq "tray_menu"
            || $data eq "tooltip"
            || $data eq "tray_tooltip" )
        {
            if ( defined $sc->get_delay ) {
                $delay_value = int $sc->get_delay;
            }
            else {
                if ( $delay->get_value ) {
                    $delay_value = int $delay->get_value;
                }
                else {
                    $delay_value = 0;
                }
            }
        }
        else {
            $delay_value = 0;
        }

        #cursor
        if ( $sc->get_include_cursor ) {
            $include_cursor = $sc->get_include_cursor;
        }
        elsif ( $sc->get_remove_cursor ) {
            $include_cursor = FALSE;
        }
        else {
            if ( $cursor_active->get_active ) {
                $include_cursor = $cursor_active->get_active;
            }
            else {
                $include_cursor = FALSE;
            }
        }

        #get next filename (auto increment using a wild card or manually)
        my $uri = undef;
        if ( $sc->get_export_filename ) {
            my ( $short, $folder, $ext ) = fileparse( $shf->switch_home_in_file( $shf->utf8_decode( $sc->get_export_filename ) ), qr/\.[^.]*/ );

            #set filetype
            $filetype_value = $ext;
            $filetype_value =~ s/\.//;

            #prepare filename, parse wild-cards
            $short = strftime $short, localtime;

            #..remove / and #
            $short =~ s/(\/|\#)/-/g;

            #relative to abs
            my $tmp_filename = $folder . $short . $ext;
            unless ( File::Spec->file_name_is_absolute($tmp_filename) ) {
                $tmp_filename = File::Spec->rel2abs($tmp_filename);
            }

            #...and create an uri
            $uri = Gnome2::VFS::URI->new($tmp_filename);
        }
        else {

            #prepare filename, parse wild-cards
            $filename_value = $shf->utf8_decode( strftime $filename_value , localtime );

            #..remove / and #
            $filename_value =~ s/(\/|\#)/-/g;

            #...and get next filename
            $uri = &fct_get_next_filename( $filename_value, $folder, $filetype_value );
        }

        #no valid filename was determined, exit here
        unless ($uri) {
            my $response = $sd->dlg_error_message( $d->get("There was an error determining the filename."), $d->get("Failed") );
            &fct_control_main_window('show');
            return FALSE;
        }

        #fullscreen screenshot
        if ( $data eq "full" || $data eq "tray_full" ) {

            $screenshooter = Shutter::Screenshot::Workspace->new( $sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, $wnck_screen->get_active_workspace, undef, undef, $current_monitor_active->get_active );

            $screenshot = $screenshooter->workspace();

            #window
        }
        elsif ($data eq "window"
            || $data eq "tray_window"
            || $data eq "awindow"
            || $data eq "tray_awindow"
            || $data eq "section"
            || $data eq "tray_section"
            || $data eq "menu"
            || $data eq "tray_menu"
            || $data eq "tooltip"
            || $data eq "tray_tooltip" )
        {

            #control some wm related settings
            my $curr_value = &fct_control_wm_settings('start');

            if ( defined $extra && $extra ) {

                $screenshooter = Shutter::Screenshot::WindowName->new( $sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, $border_active->get_active, $winresize_active->get_active, $winresize_w->get_value, $winresize_h->get_value, $hide_time->get_value, $data, $autoshape_active->get_active );

                $screenshot = $screenshooter->window_find_by_name($extra);

            }
            else {

                $screenshooter = Shutter::Screenshot::Window->new( $sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, $border_active->get_active, $winresize_active->get_active, $winresize_w->get_value, $winresize_h->get_value, $hide_time->get_value, $data, $autoshape_active->get_active, $is_hidden, $visible_windows_active->get_active, $menu_waround_active->get_active );

                $screenshot = $screenshooter->window();

            }

            #control some wm related settings
            if ( defined $curr_value && $curr_value != -1 ) {
                &fct_control_wm_settings( 'stop', $curr_value );
            }

            #selection
        }
        elsif ( $data eq "select" || $data eq "tray_select" ) {

            if ( defined $extra && $extra ) {

                my @coords = split( ',', $extra );

                $screenshooter = Shutter::Screenshot::SelectorAuto->new( $sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, );

                $screenshot = $screenshooter->select_auto( $coords[0], $coords[1], $coords[2], $coords[3] );

            }
            else {

                $screenshooter = Shutter::Screenshot::SelectorAdvanced->new( $sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, $zoom_active->get_active, $hide_time->get_value, $as_help_active->get_active, $asel_size3->get_value, $asel_size4->get_value, $asel_size1->get_value, $asel_size2->get_value, );

                $screenshot = $screenshooter->select_advanced();

            }

            #web
        }
        elsif ( $data eq "web" || $data eq "tray_web" ) {

            my $website_width = 1024;
            if ( $combobox_web_width->get_active_text =~ /(\d+)/ ) {
                $website_width = $1;
            }

            print "\nvirtual website width: $website_width\n"
              if $sc->get_debug;

            #determine timeout
            my $web_menu = $st->{_web}->get_menu;
            my @timeouts = $web_menu->get_children;
            my $timeout  = undef;
            foreach my $to (@timeouts) {
                if ( $to->get_active ) {
                    $timeout = $to->get_name;
                    $timeout =~ /([0-9]+)/;
                    $timeout = $1;
                    print $timeout. "\n" if $sc->get_debug;
                }
            }

            $screenshooter = Shutter::Screenshot::Web->new( $sc, $timeout, $website_width );
            $screenshot = $screenshooter->dlg_website($extra);

            #window by xid
        }
        elsif ( $data =~ /^shutter_window_direct(.*)/ ) {

            my $xid = $1;
            print "Selected xid: $xid\n" if $sc->get_debug;

            #control some wm related settings
            my $curr_value = &fct_control_wm_settings('start');

            #change mode (imitating selecting a window by mouse)
            $data = "window";

            $screenshooter = Shutter::Screenshot::WindowXid->new( $sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, $border_active->get_active, $winresize_active->get_active, $winresize_w->get_value, $winresize_h->get_value, $hide_time->get_value, $data, $autoshape_active->get_active );

            $screenshot = $screenshooter->window_by_xid($xid);

            #control some wm related settings
            if ( defined $curr_value && $curr_value != -1 ) {
                &fct_control_wm_settings( 'stop', $curr_value );
            }

        }
        elsif ( $data =~ /^shutter_wrksp_direct/ ) {

            #we need to handle different wm, e.g. metacity, compiz here
            my $selected_workspace = undef;
            my $vpx                = undef;
            my $vpy                = undef;

            #compiz
            if ( $data =~ /compiz(\d*)x(\d*)/ ) {
                $vpx = $1;
                $vpy = $2;
                print "Sel. Viewport: $vpx, $vpy\n" if $sc->get_debug;

                #metacity etc.
            }
            elsif ( $data =~ /shutter_wrksp_direct(.*)/ ) {
                $selected_workspace = $1;
                print "Sel. Workspace: $selected_workspace\n"
                  if $sc->get_debug;

                #all workspaces
            }
            elsif ( $data =~ /shutter_wrksp_all/ ) {
                print "Capturing all workspaces\n"
                  if $sc->get_debug;
                $selected_workspace = 'all';
            }

            $screenshooter = Shutter::Screenshot::Workspace->new( $sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, $selected_workspace, $vpx, $vpy, $current_monitor_active->get_active );

            if ( $selected_workspace eq 'all' ) {
                $screenshot = $screenshooter->workspaces();
            }
            else {
                $screenshot = $screenshooter->workspace();
            }

        }
        elsif ( $data eq "redoshot" ) {

            #~ my $key = &fct_get_last_capture;
            #~ if(defined $key && exists $session_screens{$key}->{'history'} && defined $session_screens{$key}->{'history'}){
            #~ $screenshooter = $session_screens{$key}->{'history'};
            #~ $screenshot = $screenshooter->redo_capture;
            #~ }else{
            #~ $screenshot = 3;
            #~ }

            if ( $screenshooter = &fct_get_last_capture ) {

                #we need to handle menu and tooltip in a special way
                if ( $screenshooter->can('get_mode') ) {
                    if ( my $mode = $screenshooter->get_mode ) {

                        #control some wm related settings
                        my $curr_value = undef;
                        if ( ( $mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section" ) ) {
                            $curr_value = &fct_control_wm_settings('start');
                        }

                        if ( $mode eq "menu" || $mode eq "tray_menu" ) {
                            $st->{_menu}->signal_emit('clicked');
                            return FALSE;
                        }
                        elsif ( $mode eq "tooltip" || $mode eq "tray_tooltip" ) {
                            $st->{_tooltip}->signal_emit('clicked');
                            return FALSE;
                        }
                        else {
                            $screenshot = $screenshooter->redo_capture;
                        }

                        #control some wm related settings
                        if ( ( $mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section" ) ) {
                            if ( defined $curr_value && $curr_value != -1 ) {
                                &fct_control_wm_settings( 'stop', $curr_value );
                            }
                        }

                        #window by xid
                    }
                    else {

                        #control some wm related settings
                        my $curr_value = &fct_control_wm_settings('start');
                        $screenshot = $screenshooter->redo_capture;

                        #control some wm related settings
                        if ( defined $curr_value && $curr_value != -1 ) {
                            &fct_control_wm_settings( 'stop', $curr_value );
                        }
                    }
                }
                else {
                    $screenshot = $screenshooter->redo_capture;
                }
            }
            else {
                $screenshot = 3;
            }

        }
        elsif ( $data eq "redoshot_this" ) {

            #get current screenshot (current notebook page)
            my $key = &fct_get_current_file;

            #or get the selected screenshot in the view
            unless ( defined $key ) {
                $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                    sub {
                        my ( $view, $path ) = @_;
                        my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                        if ( defined $iter ) {
                            $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        }
                    },
                    undef
                );
            }

            if (   defined $key
                && exists $session_screens{$key}->{'history'}
                && defined $session_screens{$key}->{'history'} )
            {
                $screenshooter = $session_screens{$key}->{'history'};

                #we need to handle menu and tooltip in a special way
                if ( $screenshooter->can('get_mode') ) {
                    if ( my $mode = $screenshooter->get_mode ) {

                        #control some wm related settings
                        my $curr_value = undef;
                        if ( ( $mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section" ) ) {
                            $curr_value = &fct_control_wm_settings('start');
                        }

                        if ( $mode eq "menu" || $mode eq "tray_menu" ) {
                            $st->{_menu}->signal_emit('clicked');
                            return FALSE;
                        }
                        elsif ( $mode eq "tooltip" || $mode eq "tray_tooltip" ) {
                            $st->{_tooltip}->signal_emit('clicked');
                            return FALSE;
                        }
                        else {
                            $screenshot = $screenshooter->redo_capture;
                        }

                        #control some wm related settings
                        if ( ( $mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section" ) ) {
                            if ( defined $curr_value && $curr_value != -1 ) {
                                &fct_control_wm_settings( 'stop', $curr_value );
                            }
                        }

                        #window by xid
                    }
                    else {

                        #control some wm related settings
                        my $curr_value = &fct_control_wm_settings('start');
                        $screenshot = $screenshooter->redo_capture;

                        #control some wm related settings
                        if ( defined $curr_value && $curr_value != -1 ) {
                            &fct_control_wm_settings( 'stop', $curr_value );
                        }
                    }
                }
                else {
                    $screenshot = $screenshooter->redo_capture;
                }
            }
            else {
                $screenshot = 3;
            }

        }
        else {

            #show error dialog
            my $response = $sd->dlg_error_message( $d->get("Triggered invalid screenshot action."), $d->get("Error while taking the screenshot.") );

            &fct_show_status_message( 1, $d->get("Error while taking the screenshot.") );
            &fct_control_main_window('show');
            return FALSE;
        }

        #screenshot was taken at this stage...
        #start postprocessing here

        #...successfully???
        my $error = Shutter::Screenshot::Error->new( $sc, $screenshot, $data, $extra );
        if ( $error->is_error ) {
            my $detailed_error_text = '';
            if ( defined $screenshooter && $screenshooter ) {
                $detailed_error_text = $screenshooter->get_error_text;
            }
            my ( $response, $status_text ) = $error->show_dialog($detailed_error_text);
            &fct_show_status_message( 1, $status_text );
            if ( $error->is_aborted_by_user ) {
                &fct_control_main_window( 'show', $present_after_active->get_active );
            }
            else {
                &fct_control_main_window('show');
            }
            return FALSE;

        }
        else {

            #we have to use the path (e.g. /home/username/file1.png)
            #so we can save the screenshot_properly
            $screenshot_name = $shf->utf8_decode( Gnome2::VFS->unescape_string( $uri->get_path ) );

            #maybe / is set as uri (get_path returns undef)
            #in this case nothing is returned when using get_path
            #we use the directory name and the short name in this case
            #(anyway - most users won't have permissions to write to /)
            $screenshot_name = "/" . $uri->extract_short_name
              unless $screenshot_name;

            print "Parsing wildcards for $screenshot_name\n"
              if $sc->get_debug;

            #parse width and height
            my $swidth  = $screenshot->get_width;
            my $sheight = $screenshot->get_height;

            $screenshot_name =~ s/\$w/$swidth/g;
            $screenshot_name =~ s/\$h/$sheight/g;

            print "Parsed \$width and \$height: $screenshot_name\n"
              if $sc->get_debug;

            #parse profile name
            my $current_pname = $combobox_settings_profiles->get_active_text;
            $screenshot_name =~ s/\$profile/$current_pname/g;

            print "Parsed \$profile: $screenshot_name\n"
              if $sc->get_debug;

            #set name
            #e.g. window or workspace name
            if ( my $action_name = $screenshooter->get_action_name ) {
                utf8::decode $action_name;
                $action_name     =~ s/(\/|\#|\>|\<|\%|\*)/-/g;
                $screenshot_name =~ s/\$name/$action_name/g;

                #no blanks (special wildcard)
                $action_name     =~ s/\ //g;
                $screenshot_name =~ s/\$nb_name/$action_name/g;
            }
            else {
                $screenshot_name =~ s/(\$name|\$nb_name)/unknown/g;
            }

            print "Parsed \$name: $screenshot_name\n"
              if $sc->get_debug;

            #update uri after parsing as well, so we can check if file exists for example
            $uri = Gnome2::VFS::URI->new($screenshot_name);

            #maybe the uri already exists, so we have to append some digits (e.g. testfile01(0002).png)
            #don't check if filename is set via cmd parameter
            unless ( $sc->get_export_filename ) {
                if ( $uri->exists ) {
                    my $count = 1;
                    my $new_filename = fileparse( $shf->utf8_decode( Gnome2::VFS->unescape_string( $uri->get_path ) ), qr/\.[^.]*/ );

                    print "Checking if filename already exists: " . $new_filename . "\n"
                      if $sc->get_debug;

                    my $existing_filename = $new_filename;
                    while ( $uri->exists ) {
                        $new_filename = $existing_filename . "(" . sprintf( "%03d", $count++ ) . ")";
                        $uri          = Gnome2::VFS::URI->new($folder);
                        $uri          = $uri->append_string("$new_filename.$filetype_value");
                        print "Checking new uri after parsing: " . $uri->to_string . "\n"
                          if $sc->get_debug;
                    }
                }
            }

            #we have to update the path again
            $screenshot_name = $shf->utf8_decode( Gnome2::VFS->unescape_string( $uri->get_path ) );

            #no valid filename was determined, exit here
            unless ($screenshot_name) {
                my $response = $sd->dlg_error_message( $d->get("There was an error determining the filename."), $d->get("Failed") );
                &fct_control_main_window('show');
                return FALSE;
            }

            print "New uri after exists check: " . $uri->to_string . "\n"
              if $sc->get_debug;

            #manipulate before saving
            #bordereffect
            if ( $bordereffect_active->get_active ) {

                print "Adding border effect to $screenshot_name\n"
                  if $sc->get_debug;

                my $pbuf_border = Shutter::Pixbuf::Border->new($sc);
                $screenshot = $pbuf_border->create_border( $screenshot, $bordereffect->get_value, $bordereffect_cbtn->get_color );
            }

            #ask for filename and folder
            if ( $save_ask_active->get_active ) {

                print "Asking for filename\n"
                  if $sc->get_debug;

                if ( $screenshot_name = &dlg_save_as( undef, undef, $screenshot_name, $screenshot, $quality_value ) ) {
                    if ( $screenshot_name eq 'user_cancel' ) {
                        &fct_show_status_message( 1, $d->get("Capture aborted by user") );
                        &fct_control_main_window( 'show', $present_after_active->get_active );
                        return FALSE;
                    }
                    else {

                        #update uri after saving, so we can check if file exists for example
                        $uri = Gnome2::VFS::URI->new($screenshot_name);
                    }
                }
                else {
                    &fct_control_main_window('show');
                    return FALSE;
                }

            }
            else {

                print "Trying to save file to $screenshot_name\n"
                  if $sc->get_debug;

                #finally save pixbuf
                unless ( $sp->save_pixbuf_to_file( $screenshot, $screenshot_name, $filetype_value, $quality_value ) ) {
                    &fct_control_main_window('show');
                    return FALSE;
                }

            }

        }    #end screenshot successfull

        if ( $uri->exists ) {

            #quantize
            if ( $im_colors_active->get_active ) {
                my $colors;
                if ( $combobox_im_colors->get_active == 0 ) {
                    $colors = 16;
                }
                elsif ( $combobox_im_colors->get_active == 1 ) {
                    $colors = 64;
                }
                elsif ( $combobox_im_colors->get_active == 2 ) {
                    $colors = 256;
                }
                $screenshot = &fct_imagemagick_perform( 'reduce_colors', $screenshot_name, $colors );
            }

            #generate the thumbnail
            my $screenshot_thumbnail      = undef;
            my $screenshot_thumbnail_name = undef;
            if ( $thumbnail_active->get_active ) {

                #calculate size
                my $twidth  = int( $screenshot->get_width *  ( $thumbnail->get_value / 100 ) );
                my $theight = int( $screenshot->get_height * ( $thumbnail->get_value / 100 ) );

                #create thumbail
                $screenshot_thumbnail = $lp->load( $screenshot_name, $twidth, $theight, TRUE );

                #save path of thumbnail
                my ( $name, $folder, $ext ) = fileparse( $screenshot_name, qr/\.[^.]*/ );
                $screenshot_thumbnail_name = $folder . "/$name-$thumbnail_ending.$filetype_value";

                #parse wild cards
                $screenshot_thumbnail_name =~ s/\$w/$twidth/g;
                $screenshot_thumbnail_name =~ s/\$h/$theight/g;

                print "Trying to save file to $screenshot_thumbnail_name\n"
                  if $sc->get_debug;

                #finally save pixbuf
                unless ( $sp->save_pixbuf_to_file( $screenshot_thumbnail, $screenshot_thumbnail_name, $filetype_value, $quality_value ) ) {
                    &fct_control_main_window('show');
                    return FALSE;
                }

            }

            my $new_key_screenshot           = undef;
            my $new_key_screenshot_thumbnail = undef;

            #Dont add it to session if no_session-parameter is set
            unless ( $sc->get_no_session ) {

                #Dont add it to session if it already exists
                unless ( &fct_is_uri_in_session( $uri, TRUE ) ) {

                    #integrate it into the notebook
                    $new_key_screenshot = &fct_integrate_screenshot_in_notebook( $uri, $screenshot, $screenshooter );

                    #thumbnail as well if present
                    $new_key_screenshot_thumbnail = &fct_integrate_screenshot_in_notebook( Gnome2::VFS::URI->new($screenshot_thumbnail_name), $screenshot_thumbnail )
                      if $thumbnail_active->get_active;

                }
            }

            #in some cases it is not possible to add it to the session
            #e.g. when saving to pdf
            if ($new_key_screenshot) {

                #copy to clipboard
                if ( !$no_autocopy_active->get_active() ) {

                    #image_autocopy to clipboard if configured
                    if ( $image_autocopy_active->get_active() ) {
                        $clipboard->set_image($screenshot);
                    }

                    #filename autocopy to clipboard if configured
                    if ( $fname_autocopy_active->get_active() ) {
                        $clipboard->set_text($screenshot_name);
                    }

                }

                #open screenshot with configured program
                if ( $progname_active->get_active ) {
                    my $model         = $progname->get_model();
                    my $progname_iter = $progname->get_active_iter();
                    if ($progname_iter) {
                        my $progname_value = $model->get_value( $progname_iter, 2 );
                        my $appname_value  = $model->get_value( $progname_iter, 1 );
                        &fct_open_with_program( $progname_value, $appname_value );
                    }
                }
                print "screenshot successfully saved to $screenshot_name!\n"
                  if $sc->get_debug;

                &fct_show_status_message( 1, sprintf( $d->get("%s saved"), $session_screens{$new_key_screenshot}->{'short'} ) );

                #show pop-up notification
                if ( $notify_after_active->get_active ) {
                    my $notify = $sc->get_notification_object;
                    if ( defined $session_screens{$new_key_screenshot}->{'is_unsaved'}
                        && $session_screens{$new_key_screenshot}->{'is_unsaved'} )
                    {
                        $notify->show( $d->get("Screenshot saved"), "*" . $session_screens{$new_key_screenshot}->{'name'} );
                    }
                    else {
                        $notify->show( $d->get("Screenshot saved"), $session_screens{$new_key_screenshot}->{'long'} );
                    }
                }

            }
            else {    #endif - adding to session worked

                print "screenshot successfully saved to $screenshot_name, but unable to add the file to session!\n"
                  if $sc->get_debug;

                &fct_show_status_message( 1, sprintf( $d->get("%s saved"), $screenshot_name ) );

                #show pop-up notification
                if ( $notify_after_active->get_active ) {
                    my $notify = $sc->get_notification_object;
                    $notify->show( $d->get("Screenshot saved"), $screenshot_name );
                }

            }

        }
        else {

            #show error dialog
            my $response = $sd->dlg_error_message( sprintf( $d->get("The filename %s could not be verified. Maybe it contains unsupported characters."), "'" . $screenshot_name . "'" ), $d->get("Error while taking the screenshot.") );
            &fct_show_status_message( 1, $d->get("Error while taking the screenshot.") );
            &fct_control_main_window('show');
            return FALSE;

        }

        &fct_control_main_window( 'show', $present_after_active->get_active );

        #Exit Shutter after the first capture has been made.
        #This is useful when using Shutter in scripts.
        if ( $sc->get_exit_after_capture ) {
            &evt_delete_window( '', 'quit' );
        }

        return TRUE;
    }

    sub fct_update_tray_menu {
        my $screen = shift;
        if ( $sc->get_debug ) {
            print "\nfct_update_tray_menu was called by $screen\n";
        }

        #update window list
        foreach my $child ( $tray_menu->get_children ) {
            if ( $child->get_name eq 'windowlist' ) {
                $child->set_submenu(&fct_ret_window_menu);
                last;
            }
        }
    }

    sub fct_upload {

        my $key = &fct_get_current_file;

        my @upload_array;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);
            push( @upload_array, $key );
            &dlg_upload(@upload_array);

            #session tab
        }
        else {

            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        return FALSE unless &fct_screenshot_exists($key);
                        push( @upload_array, $key );
                    }

                },
                undef
            );
            &dlg_upload(@upload_array);

        }

        #update actions
        #new public links might be available
        foreach my $key (@upload_array) {
            &fct_update_actions( 1, $key );
        }

        return TRUE;
    }

    sub fct_send {

        my $key = &fct_get_current_file;

        my @files_to_send;
        unless ($key) {
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @files_to_send, $session_screens{$key}->{'long'} );
                    }

                }
            );
        }
        else {
            push( @files_to_send, $session_screens{$key}->{'long'} );
        }

        my $sendto_string = undef;
        foreach my $sendto_filename (@files_to_send) {
            $sendto_string .= "'$sendto_filename' ";
        }

        $shf->nautilus_sendto($sendto_string);

        return TRUE;
    }

    sub fct_email {

        my $key = &fct_get_current_file;

        my @files_to_email;
        unless ($key) {
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @files_to_email, $session_screens{$key}->{'long'} );
                    }

                }
            );
        }
        else {
            push( @files_to_email, $session_screens{$key}->{'uri'}->to_string );
        }

        my $mail_string = undef;
        foreach my $email_filename (@files_to_email) {
            $mail_string .= "--attach '$email_filename' ";
        }

        $shf->xdg_open_mail( undef, undef, $mail_string );

        return TRUE;
    }

    sub fct_print {

        my $key = &fct_get_current_file;

        my @pages;
        unless ($key) {
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        push( @pages, $session_screens{$key}->{'long'} );
                    }

                }
            );
        }
        else {
            push( @pages, $session_screens{$key}->{'long'} );
        }

        my $op = Gtk2::PrintOperation->new;
        $op->set_job_name( SHUTTER_NAME . " - " . SHUTTER_VERSION . " - " . localtime );
        $op->set_n_pages( scalar @pages );
        $op->set_unit('pixel');
        $op->set_show_progress(TRUE);
        $op->set_default_page_setup($pagesetup);

        #restore settings if prossible
        if ( $shf->file_exists("$ENV{ HOME }/.shutter/printing.xml") ) {
            eval {
                my $ssettings = Gtk2::PrintSettings->new_from_file("$ENV{ HOME }/.shutter/printing.xml");
                $op->set_print_settings($ssettings);
            };
        }

        $op->signal_connect(
            'status-changed' => sub {
                my $op = shift;
                &fct_show_status_message( 1, $op->get_status_string );
            }
        );

        $op->signal_connect(
            'draw-page' => sub {
                my $op  = shift;
                my $pc  = shift;
                my $int = shift;

                #cairo context
                my $cr = $pc->get_cairo_context;

                #load pixbuf from file
                if ( my $pixbuf = $lp->load( $pages[$int] ) ) {

                    #scale if image doesn't fit on page
                    my $scale_x = $pc->get_width / $pixbuf->get_width;
                    my $scale_y = $pc->get_height / $pixbuf->get_height;
                    if ( min( $scale_x, $scale_y ) < 1 ) {
                        $cr->scale( min( $scale_x, $scale_y ), min( $scale_x, $scale_y ) );
                    }

                    Gtk2::Gdk::Cairo::Context::set_source_pixbuf( $cr, $pixbuf, 0, 0 );

                }

                $cr->paint;

            }
        );

        $op->run( 'print-dialog', $window );

        #save settings
        my $settings = $op->get_print_settings;
        eval { $settings->to_file("$ENV{ HOME }/.shutter/printing.xml"); };

        return TRUE;
    }

    sub fct_open_with_program {
        my $app = shift;

        #no program set - exit
        return FALSE unless $app;

        my $key = &fct_get_current_file;

        #single file
        if ($key) {

            return FALSE unless &fct_screenshot_exists($key);

            #built-in-editor
            if ( $app =~ /shutter/ ) {
                &fct_draw();
                &fct_show_status_message( 1, sprintf( $d->get("%s opened with %s"), $session_screens{$key}->{'short'}, $d->get("Built-in Editor") ) );
            }
            else {

                #everything is fine -> open it
                if ( $app->supports_uris ) {
                    $app->launch( $session_screens{$key}->{'uri'}->to_string );
                }
                else {
                    $app->launch( $session_screens{$key}->{'long'} );
                }
                &fct_show_status_message( 1, sprintf( $d->get("%s opened with %s"), $session_screens{$key}->{'short'}, $app->{'name'} ) );
            }

            #session tab
        }
        else {

            my @open_files;
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                        if ( $app->supports_uris ) {
                            push @open_files, $session_screens{$key}->{'uri'}->to_string;
                        }
                        else {
                            push @open_files, $session_screens{$key}->{'long'};
                        }
                    }
                },
                undef
            );
            if ( @open_files > 0 ) {
                $app->launch(@open_files);
                &fct_show_status_message( 1, $d->get("Opened all files with") . " " . $app->{'name'} );
            }
        }

        return TRUE;
    }

    sub fct_execute_plugin {
        my $arrayref = $_[1];
        my ( $plugin_value, $plugin_name, $plugin_lang, $key, $plugin_dialog, $plugin_progress ) = @$arrayref;

        unless ( $shf->file_exists( $session_screens{$key}->{'long'} ) ) {
            return FALSE;
        }

        #if it is a native perl plugin, use a plug to integrate it properly
        if ( $plugin_lang eq "perl" ) {

            #hide plugin dialog
            $plugin_dialog->hide if defined $plugin_dialog;

            #dialog to show the plugin
            my $sdialog = Gtk2::Dialog->new( $plugin_name, $window, [qw/modal destroy-with-parent/] );
            $sdialog->set_resizable(FALSE);
            $sdialog->set_has_separator(FALSE);

            # Ensure that the dialog box is destroyed when the user responds.
            $sdialog->signal_connect( response => sub { $_[0]->destroy } );

            #initiate the socket to draw the contents of the plugin to our dialog
            my $socket = Gtk2::Socket->new;
            $sdialog->vbox->add($socket);
            $socket->signal_connect(
                'plug-removed' => sub {
                    $sdialog->destroy();
                    return TRUE;
                }
            );

            printf( "\n", $socket->get_id );

            my $pid = fork;
            if ( $pid < 0 ) {
                $sd->dlg_error_message( sprintf( $d->get("Could not apply plugin %s"), "'" . $plugin_name . "'" ), $d->get("Failed") );
            }
            elsif ( $pid == 0 ) {

                #see Bug #661424
                my $qfilename = quotemeta $session_screens{$key}->{'long'};
                exec( sprintf( "$^X $plugin_value %d $qfilename $session_screens{$key}->{'width'} $session_screens{$key}->{'height'} $session_screens{$key}->{'filetype'}\n", $socket->get_id ) );
            }

            $sdialog->show_all;
            $sdialog->run;

            waitpid( $pid, 0 );

            #check exit code
            if ( $? == 0 ) {
                &fct_show_status_message( 1, sprintf( $d->get("Successfully applied plugin %s"), "'" . $plugin_name . "'" ) );
            }
            elsif ( $? / 256 == 1 ) {
                &fct_show_status_message( 1, sprintf( $d->get("Could not apply plugin %s"), "'" . $plugin_name . "'" ) );
            }

            #...if not => simple execute the plugin via system (e.g. shell plugins)
        }
        else {

            print "$plugin_value $session_screens{$key}->{'long'} $session_screens{$key}->{'width'} $session_screens{$key}->{'height'} $session_screens{$key}->{'filetype'} submitted to plugin\n"
              if $sc->get_debug;

            #cancel handle, because file gets manipulated
            #multiple times
            if ( exists $session_screens{$key}->{'handle'} ) {
                $session_screens{$key}->{'handle'}->cancel;
            }

            #create a new process, so we are able to cancel the current operation
            my $plugin_process = Proc::Simple->new;

            #see Bug #661424
            my $qfilename = quotemeta $session_screens{$key}->{'long'};

            $plugin_process->start(
                sub {
                    system("'$plugin_value' $qfilename '$session_screens{$key}->{'width'}' '$session_screens{$key}->{'height'}' '$session_screens{$key}->{'filetype'}' ");
                    POSIX::_exit(0);
                }
            );

            #ignore delete-event during execute
            $plugin_dialog->signal_connect(
                'delete-event' => sub {
                    return TRUE;
                }
            );

            #we are also able to show a little progress bar to give some feedback
            #to the user. there is no real progress because we are just executing a shell script
            while ( $plugin_process->poll ) {
                $plugin_progress->set_text( $plugin_name . " - " . $session_screens{$key}->{'short'} );
                $plugin_progress->pulse;
                &fct_update_gui;
                usleep 100000;
            }

            &fct_update_gui;

            #finally show some status messages
            if ( $plugin_process->exit_status() == 0 ) {
                &fct_show_status_message( 1, sprintf( $d->get("Successfully applied plugin %s"), "'" . $plugin_name . "'" ) );
            }
            else {
                $sd->dlg_error_message( sprintf( $d->get("Error while executing plugin %s."), "'" . $plugin_name . "'" ), $d->get("There was an error executing the plugin."), );
            }

            #update session tab manually
            &fct_update_tab( $key, undef, $session_screens{$key}->{'uri'} );

            #setup a new filemonitor, so we get noticed if the file changed
            &fct_add_file_monitor($key);

        }

        return TRUE;
    }

    sub fct_show_status_message {
        my $index       = shift;
        my $status_text = shift;

        $status->pop($index);
        if (defined $session_start_screen{'first_page'}->{'statusbar_timer'}){
			if ($session_start_screen{'first_page'}->{'statusbar_timer'}){
				Glib::Source->remove( $session_start_screen{'first_page'}->{'statusbar_timer'} )
			}
		}  
        $status->push( $index, $status_text );

        #...and remove it
        $session_start_screen{'first_page'}->{'statusbar_timer'} = Glib::Timeout->add(
            3000,
            sub {
                $status->pop($index);

                #show file or session info again
                &fct_update_info_and_tray();
                return FALSE;
            }
        );

        return TRUE;
    }

    sub fct_update_info_and_tray {
        my $force_key = shift;

        my $key = undef;
        if ($force_key) {
            if ( $force_key eq "session" ) {
                $key = undef;
            }
            else {
                $key = $force_key;
            }
        }
        else {
            $key = &fct_get_current_file;
        }

        #STATUSBAR AND WINDOW TITLE
        #--------------------------------------
        #update statusbar when this image is current tab
        if (   $key
            && defined $session_screens{$key}->{'long'}
            && defined $session_screens{$key}->{'width'} )
        {

            #change window title
            if ( defined $session_screens{$key}->{'is_unsaved'}
                && $session_screens{$key}->{'is_unsaved'} )
            {
                $window->set_title( "*" . $session_screens{$key}->{'name'} . " - " . SHUTTER_NAME );
            }
            else {
                $window->set_title( $session_screens{$key}->{'long'} . " - " . SHUTTER_NAME );
            }

            $status->push( 1, $session_screens{$key}->{'width'} . " x " . $session_screens{$key}->{'height'} . " " . $d->get("pixels") . "  " . $shf->utf8_decode( Gnome2::VFS->format_file_size_for_display( $session_screens{$key}->{'size'} ) ) );

            #session tab
        }
        else {

            #change window title
            $window->set_title( $d->get("Session") . " - " . SHUTTER_NAME );

            $status->push( 1, sprintf( $d->nget( "%s screenshot", "%s screenshots", scalar( keys(%session_screens) ) ), scalar( keys(%session_screens) ) ) . "  " . $shf->utf8_decode( Gnome2::VFS->format_file_size_for_display(&fct_get_total_size_of_session) ) );

        }

        #TRAY TOOLTIP
        #--------------------------------------
        if ($combobox_settings_profiles) {
            if ( $tray && $tray->isa('Gtk2::StatusIcon') ) {
                if ( $combobox_settings_profiles->get_active_text ) {
                    $tray->set_tooltip( $d->get("Current profile") . ": " . $combobox_settings_profiles->get_active_text );
                }
                else {
                    $tray->set_tooltip( SHUTTER_NAME . " " . SHUTTER_VERSION );
                }
            }
            elsif ( $tray && $tray->isa('Gtk2::TrayIcon') ) {
                $tooltips->set_tip( $tray, SHUTTER_NAME . " " . SHUTTER_VERSION );
            }
        }

        return TRUE;
    }

    sub fct_get_key_by_filename {
        my $filename = shift;

        return unless $filename;

        my $key = undef;

        #and loop through hash to find the corresponding key
        foreach my $ckey ( keys %session_screens ) {
            next unless exists $session_screens{$ckey}->{'long'};

            #~ print "compare ".$session_screens{$ckey}->{'long'}." - $filename\n";
            if ( $session_screens{$ckey}->{'long'} eq $filename ) {
                $key = $ckey;
                last;
            }
        }

        return $key;
    }

    sub fct_get_key_by_pubfile {
        my $filename = shift;

        return unless $filename;

        my $key = undef;

        #and loop through hash to find the corresponding key
        foreach my $ckey ( keys %session_screens ) {
            next unless exists $session_screens{$ckey}->{'links'};
            next
              unless exists $session_screens{$ckey}->{'links'}->{'ubuntu-one'};
            next
              unless exists $session_screens{$ckey}->{'links'}->{'ubuntu-one'}->{'pubfile'};

            #~ print "compare ".$session_screens{$ckey}->{'links'}->{'ubuntu-one'}->{'pubfile'}." - $filename\n";
            if ( $session_screens{$ckey}->{'links'}->{'ubuntu-one'}->{'pubfile'} eq $filename ) {
                $key = $ckey;
                last;
            }
        }

        return $key;
    }

    sub fct_get_file_by_index {
        my $index = shift;

        return unless $index;

        #get current page
        my $curr_page = $notebook->get_nth_page($index);

        my $key = undef;

        #and loop through hash to find the corresponding key
        if ($curr_page) {
            foreach my $ckey ( keys %session_screens ) {
                next unless exists $session_screens{$ckey}->{'tab_child'};
                if ( $session_screens{$ckey}->{'tab_child'} == $curr_page ) {
                    $key = $ckey;
                    last;
                }
            }
        }

        return $key;
    }

    sub fct_get_total_size_of_session {
        my $total_size = 0;
        foreach my $ckey ( keys %session_screens ) {
            next unless $session_screens{$ckey}->{'size'};
            $total_size += $session_screens{$ckey}->{'size'};
        }
        return $total_size;
    }

    sub fct_get_current_file {

        #get current page
        my $curr_page = $notebook->get_nth_page( $notebook->get_current_page );

        my $key = undef;

        #and loop through hash to find the corresponding key
        if ($curr_page) {
            foreach my $ckey ( keys %session_screens ) {
                next unless ( exists $session_screens{$ckey}->{'tab_child'} );
                if ( $session_screens{$ckey}->{'tab_child'} == $curr_page ) {
                    $key = $ckey;
                    last;
                }
            }
        }

        return $key;
    }

    sub fct_update_profile_selectors {
        my ( $combobox_settings_profiles, $current_profiles_ref, $recur_widget ) = @_;

        #populate quick selector as well
        if ( scalar @{$current_profiles_ref} > 0 ) {

            #tray menu
            foreach my $child ( $tray_menu->get_children ) {
                if ( $child->get_name eq 'quicks' ) {
                    $child->set_submenu( fct_ret_profile_menu( $combobox_settings_profiles, $current_profiles_ref ) );
                    $child->set_sensitive(TRUE);
                    last;
                }
            }

            #main menu
            $sm->{_menuitem_quicks}->set_submenu( fct_ret_profile_menu( $combobox_settings_profiles, $current_profiles_ref, $sm->{_menuitem_quicks}->get_submenu ) );
            $sm->{_menuitem_quicks}->set_sensitive(TRUE);

            #and statusbar
            #FIXME - some explanation is missing here
            unless ( $recur_widget
                && $recur_widget eq $combobox_status_profiles )
            {
                if (   defined $combobox_status_profiles
                    && defined $combobox_status_profiles_label )
                {
                    $combobox_status_profiles_label->destroy;
                    $combobox_status_profiles->destroy;
                }

                $combobox_status_profiles_label = Gtk2::Label->new( $d->get("Profile") . ":" );
                $combobox_status_profiles       = Gtk2::ComboBox->new_text;
                $status->pack_start( $combobox_status_profiles_label, FALSE, FALSE, 0 );
                $status->pack_start( $combobox_status_profiles,       FALSE, FALSE, 0 );

                foreach my $profile ( @{$current_profiles_ref} ) {
                    $combobox_status_profiles->append_text($profile);
                }

                $combobox_status_profiles->set_active( $combobox_settings_profiles->get_active );

                $combobox_status_profiles->signal_connect(
                    'changed' => sub {
                        my $widget = shift;

                        $combobox_settings_profiles->set_active( $widget->get_active );
                        &evt_apply_profile( $widget, $combobox_settings_profiles, $current_profiles_ref );

                    }
                );

                $status->show_all;
            }

        }
        else {

            #tray menu
            foreach my $child ( $tray_menu->get_children ) {
                if ( $child->get_name eq 'quicks' ) {
                    $child->remove_submenu;
                    $child->set_sensitive(FALSE);
                    last;
                }
            }

            #main menu
            $sm->{_menuitem_quicks}->remove_submenu;
            $sm->{_menuitem_quicks}->set_sensitive(FALSE);

            #and statusbar
            if (   defined $combobox_status_profiles
                && defined $combobox_status_profiles_label )
            {
                $combobox_status_profiles_label->destroy;
                $combobox_status_profiles->destroy;
            }
        }
        return TRUE;
    }

    sub fct_update_tab {

        #mandatory
        my $key = shift;
        return FALSE unless $key;

        #optional, e.g.used by fct_integrate...
        my $pixbuf      = shift;
        my $uri         = shift;
        my $force_thumb = shift;
        my $xdo         = shift;

        $session_screens{$key}->{'uri'} = $uri if $uri;
        $session_screens{$key}->{'mtime'} = -1
          unless $session_screens{$key}->{'mtime'};

        #something wrong here
        unless ( defined $session_screens{$key}->{'uri'} ) {
            return FALSE;
        }

        #sometimes there are some read errors
        #because the CHANGED signal gets emitted by the file monitor
        #but the file is still in use (e.g. plugin, external app)
        #we try to read the fileinfos and the file itsels several times
        #until throwing an error
        my $error_counter = 0;
        while ( $error_counter <= MAX_ERROR ) {

            my $fileinfo = $session_screens{$key}->{'uri'}->get_file_info('default');

            #does the file exist?
            if ( $session_screens{$key}->{'uri'}->exists ) {

                #maybe we need no update
                if ( $fileinfo->{'mtime'} == $session_screens{$key}->{'mtime'}
                    && !$uri )
                {
                    print "Updating fileinfos REJECTED for key: $key (not modified)\n"
                      if $sc->get_debug;
                    return TRUE;
                }

                print "Updating fileinfos for key: $key\n" if $sc->get_debug;

                #FILEINFO
                #--------------------------------------
                $session_screens{$key}->{'mtime'} = $fileinfo->{'mtime'};
                $session_screens{$key}->{'size'}  = $fileinfo->{'size'};

                $session_screens{$key}->{'short'}    = $shf->utf8_decode( Gnome2::VFS->unescape_string( $session_screens{$key}->{'uri'}->extract_short_name ) );
                $session_screens{$key}->{'long'}     = $shf->utf8_decode( Gnome2::VFS->unescape_string( $session_screens{$key}->{'uri'}->get_path ) );
                $session_screens{$key}->{'folder'}   = $shf->utf8_decode( Gnome2::VFS->unescape_string( $session_screens{$key}->{'uri'}->extract_dirname ) );
                $session_screens{$key}->{'filetype'} = $session_screens{$key}->{'short'};
                $session_screens{$key}->{'filetype'} =~ s/.*\.//ig;

                #just the name
                $session_screens{$key}->{'name'} = $session_screens{$key}->{'short'};
                $session_screens{$key}->{'name'} =~ s/\.$session_screens{$key}->{'filetype'}//g;

                #mime type
                my $mime_type = Gnome2::VFS->get_mime_type_for_name( $session_screens{$key}->{'uri'}->to_string );
				$mime_type =~ s/image\/x\-apple\-ios\-png/image\/png/; #FIXME
				$session_screens{$key}->{'mime_type'} = $mime_type;

				#THUMBNAIL
                #--------------------------------------
                #maybe we have a pixbuf already (e.g. after taking a screenshot)
                unless ($pixbuf) {
                    $pixbuf = $lp_ne->load( $session_screens{$key}->{'long'}, undef, undef, undef, TRUE );
                    unless ($pixbuf) {

                        #increment error counter
                        #and go to next try
                        $error_counter++;
                        sleep 1;

                        #we need to reset the modification time
                        #because the change would not be
                        #recognized otherwise
                        $session_screens{$key}->{'mtime'} = -1;
                        next;
                    }
                }

                #setting pixbuf
                $session_screens{$key}->{'image'}->set_pixbuf($pixbuf);

                #UPDATE INFOS
                #--------------------------------------

                #get dimensions - using the pixbuf
                $session_screens{$key}->{'width'}  = $pixbuf->get_width;
                $session_screens{$key}->{'height'} = $pixbuf->get_height;

                #generate thumbnail if file is not too large
                #set flag
                if (   $session_screens{$key}->{'width'} <= 10000
                    && $session_screens{$key}->{'height'} <= 10000 )
                {
                    $session_screens{$key}->{'no_thumbnail'} = FALSE;
                }
                else {
                    $session_screens{$key}->{'no_thumbnail'} = TRUE;
                }

                #update is_unsaved flag
                if ( $session_screens{$key}->{'folder'} eq $sdir->get_cache_dir ) {
                    $session_screens{$key}->{'is_unsaved'} = TRUE;
                }
                else {
                    $session_screens{$key}->{'is_unsaved'} = FALSE;
                }

                #update tab label
                #and tooltip
                if ( defined $session_screens{$key}->{'is_unsaved'}
                    && $session_screens{$key}->{'is_unsaved'} )
                {
                    $tooltips->set_tip( $session_screens{$key}->{'hbox_tab_label'}, "*" . $session_screens{$key}->{'name'} );
                    $session_screens{$key}->{'tab_label'}->set_text( "[" . $session_screens{$key}->{'tab_indx'} . "] - " . "*" . $session_screens{$key}->{'name'} );
                }
                else {
                    $tooltips->set_tip( $session_screens{$key}->{'hbox_tab_label'}, $session_screens{$key}->{'long'} );
                    $session_screens{$key}->{'tab_label'}->set_text( "[" . $session_screens{$key}->{'tab_indx'} . "] - " . $session_screens{$key}->{'short'} );
                }

                #create tempfile
                #maybe we have to restore the file later
                my ( $tmpfh, $tmpfilename ) = tempfile( UNLINK => 1 );

                #UNDO / REDO
                #--------------------------------------

                #blocked (e.g. renaming)
                if ( defined $xdo && $xdo eq 'block' ) {

                    unlink $tmpfilename;

                    #clear (e.g. save_as)
                }
                elsif ( defined $xdo && $xdo eq 'clear' ) {

                    while ( defined $session_screens{$key}->{'undo'}
                        && scalar @{ $session_screens{$key}->{'undo'} } > 0 )
                    {
                        unlink shift @{ $session_screens{$key}->{'undo'} };
                    }
                    while ( defined $session_screens{$key}->{'redo'}
                        && scalar @{ $session_screens{$key}->{'redo'} } > 0 )
                    {
                        unlink shift @{ $session_screens{$key}->{'redo'} };
                    }

                    push @{ $session_screens{$key}->{'undo'} }, $tmpfilename;
                    cp( $session_screens{$key}->{'long'}, $tmpfilename );

                    #push to undo
                }
                else {

                    #clear redo unless triggered from gui (undo/redo buttons)
                    if ( !defined $xdo ) {
                        while ( defined $session_screens{$key}->{'redo'}
                            && scalar @{ $session_screens{$key}->{'redo'} } > 0 )
                        {
                            unlink shift @{ $session_screens{$key}->{'redo'} };
                        }
                    }

                    push @{ $session_screens{$key}->{'undo'} }, $tmpfilename;
                    cp( $session_screens{$key}->{'long'}, $tmpfilename );

                }

                #thumbnail in tab
                my $thumb;
                unless ( $session_screens{$key}->{'no_thumbnail'} ) {

                    #update tab icon
                    $thumb = $sthumb->get_thumbnail( $session_screens{$key}->{'uri'}->to_string, $session_screens{$key}->{'mime_type'}, $session_screens{$key}->{'mtime'}, 0.2, $force_thumb );
                    $session_screens{$key}->{'tab_icon'}->set_from_pixbuf($thumb);
                }

                #UPDATE FIRST TAB - VIEW
                #--------------------------------------

                my $thumb_view;
                unless ( $session_screens{$key}->{'no_thumbnail'} ) {

                    #update view icon
                    $thumb_view = $sthumb->get_thumbnail( $session_screens{$key}->{'uri'}->to_string, $session_screens{$key}->{'mime_type'}, $session_screens{$key}->{'mtime'}, 1.0 );

                    #update dnd pixbuf
                    $session_screens{$key}->{'image'}->drag_source_set_icon_pixbuf($thumb_view);
                }
                else {
                    $thumb_view = Gtk2::Gdk::Pixbuf->new( 'rgb', TRUE, 8, 5, 5 );
                    $thumb_view->fill(0x00000000);
                }

                #create new iter if needed...
                unless ( defined $session_screens{$key}->{'iter'}
                    && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                {
                    $session_screens{$key}->{'iter'} = $session_start_screen{'first_page'}->{'model'}->append;
                }

                #...update it
                if ( defined $session_screens{$key}->{'is_unsaved'}
                    && $session_screens{$key}->{'is_unsaved'} )
                {
                    $session_start_screen{'first_page'}->{'model'}->set( $session_screens{$key}->{'iter'}, 0, $thumb_view, 1, "*" . $session_screens{$key}->{'name'}, 2, $key );
                }
                else {
                    $session_start_screen{'first_page'}->{'model'}->set( $session_screens{$key}->{'iter'}, 0, $thumb_view, 1, $session_screens{$key}->{'short'}, 2, $key );
                }

                #update first tab
                &fct_update_info_and_tray();

                #update menu actions
                my $current_key = &fct_get_current_file;
                if ( defined $current_key && $current_key eq $key ) {
                    &fct_update_actions( 1, $key );
                }

                return TRUE;

                #file does not exist
            }
            else {

                #show dialog
                if ( $ask_on_fs_delete_active->get_active ) {

                    #mark file as deleted
                    $session_screens{$key}->{'deleted'} = TRUE;

                    #we only handle one case here:
                    #file was deleted in filesystem and we got informed about that...
                    my $response = $sd->dlg_question_message( $d->get("Try to resave the file?"), sprintf( $d->get("Image %s was not found on disk"), "'" . $session_screens{$key}->{'long'} . "'" ), 'gtk-discard', 'gtk-save' );

                    #handle different responses
                    if ( $response == 10 || $response == -1 ) {

                        $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
                        &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
                          if defined( $session_screens{$key}->{'long'} );

                        if ( defined $session_screens{$key}->{'iter'}
                            && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                        {
                            $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
                        }

                        delete( $session_screens{$key} );

                    }
                    elsif ( $response == 20 ) {

                        #try to resave the file
                        #(current version is always the last element in the array)
                        my $current_version = pop @{ $session_screens{$key}->{'undo'} };

                        my $pixbuf = $lp_ne->load($current_version);

                        #restoring the last version failed => delete the screenshot
                        unless ($pixbuf) {

                            $sd->dlg_error_message( sprintf( $d->get("Error while saving the image %s."), "'" . $session_screens{$key}->{'short'} . "'" ), sprintf( $d->get("There was an error saving the image to %s."), "'" . $session_screens{$key}->{'folder'} . "'" ), undef, undef, undef, undef, undef, undef, $@ );

                            $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
                            &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
                              if defined( $session_screens{$key}->{'long'} );

                            if ( defined $session_screens{$key}->{'iter'}
                                && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                            {
                                $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
                            }

                            delete( $session_screens{$key} );

                            &fct_update_info_and_tray();
                            return FALSE;

                        }

                        if ( $sp->save_pixbuf_to_file( $pixbuf, $session_screens{$key}->{'long'}, $session_screens{$key}->{'filetype'} ) ) {

                            &fct_update_tab($key);

                            #setup a new filemonitor, so we get noticed if the file changed
                            &fct_add_file_monitor($key);

                            &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("saved") );

                            &fct_update_info_and_tray();
                            return TRUE;

                            #resave failed => delete the screenshot
                        }
                        else {

                            $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
                            &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
                              if defined( $session_screens{$key}->{'long'} );

                            if ( defined $session_screens{$key}->{'iter'}
                                && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                            {
                                $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
                            }

                            delete( $session_screens{$key} );

                        }
                    }

                    #no dialog
                }
                else {

                    #mark file as deleted
                    $session_screens{$key}->{'deleted'} = TRUE;

                    #try to resave the file
                    #(current version is always the last element in the array)
                    my $current_version = pop @{ $session_screens{$key}->{'undo'} };

                    my $pixbuf = $lp_ne->load($current_version);

                    #restoring the last version failed => delete the screenshot
                    unless ($pixbuf) {

                        $sd->dlg_error_message( sprintf( $d->get("Error while saving the image %s."), "'" . $session_screens{$key}->{'short'} . "'" ), sprintf( $d->get("There was an error saving the image to %s."), "'" . $sdir->get_cache_dir . "'" ), undef, undef, undef, undef, undef, undef, $@ );

                        $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
                        &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
                          if defined( $session_screens{$key}->{'long'} );

                        if ( defined $session_screens{$key}->{'iter'}
                            && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                        {
                            $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
                        }

                        delete( $session_screens{$key} );

                        &fct_update_info_and_tray();
                        return FALSE;

                    }

                    #prepare new filename
                    my ( $short, $folder, $ext ) = fileparse( $session_screens{$key}->{'long'}, qr/\.[^.]*/ );
                    my $new_uri = &fct_get_next_filename( $short, $sdir->get_cache_dir, $ext );
                    my $new_filename = $shf->utf8_decode( Gnome2::VFS->unescape_string( $new_uri->get_path ) );

                    if ( $sp->save_pixbuf_to_file( $pixbuf, $new_filename, $session_screens{$key}->{'filetype'} ) ) {

                        if ( &fct_update_tab( $key, undef, Gnome2::VFS::URI->new($new_filename), FALSE, 'clear' ) ) {

                            #setup a new filemonitor, so we get noticed if the file changed
                            &fct_add_file_monitor($key);
                        }

                        &fct_show_status_message( 1, sprintf( $d->get("Image %s was deleted from filesystem"), $new_filename ) );

                        &fct_update_info_and_tray();
                        return TRUE;

                        #resave failed => delete the screenshot
                    }
                    else {

                        $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
                        &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
                          if defined( $session_screens{$key}->{'long'} );

                        if ( defined $session_screens{$key}->{'iter'}
                            && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
                        {
                            $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
                        }

                        delete( $session_screens{$key} );

                    }

                }

                &fct_update_info_and_tray();
                return FALSE;

            }    #end if exists

        }    #end while($error_counter <= MAX_ERROR){

        #could not load the file => show an error message
        my $response = $sd->dlg_error_message( sprintf( $d->get("Error while opening image %s."), "'" . $session_screens{$key}->{'long'} . "'" ), $d->get("There was an error opening the image."), undef, undef, undef, undef, undef, undef, $@ );

        $notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );    #delete tab
        &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
          if defined( $session_screens{$key}->{'long'} );

        if ( defined $session_screens{$key}->{'iter'}
            && $session_start_screen{'first_page'}->{'model'}->iter_is_valid( $session_screens{$key}->{'iter'} ) )
        {
            $session_start_screen{'first_page'}->{'model'}->remove( $session_screens{$key}->{'iter'} );
        }

        delete( $session_screens{$key} );

        &fct_update_info_and_tray();
        return FALSE;

    }

    sub fct_get_latest_tab_key {
        my $max_key = 0;
        foreach my $key ( keys %session_screens ) {
            $key =~ /\[(\d+)\]/;
            $max_key = $1 if ( $1 > $max_key );
        }
        return $max_key + 1;
    }

    sub fct_imagemagick_perform {
        my ( $function, $file, $data ) = @_;

        my $pixbuf = undef;
        my $result = undef;
        $file = $shf->switch_home_in_file($file);

        if ( $function eq "reduce_colors" ) {
            $result = `convert '$file' -colors $data '$file'`;
            $pixbuf = $lp->load($file);
        }

        return $pixbuf;
    }

    sub fct_check_installed_programs {

        #update list of available programs in settings dialog as well
        if ($progname) {

            my $model         = $progname->get_model();
            my $progname_iter = $progname->get_active_iter();

            #get last prog
            my $progname_value;
            if ( defined $progname_iter ) {
                $progname_value = $model->get_value( $progname_iter, 1 );
            }

            #rebuild model with new hash of installed programs...
            $model = &fct_get_program_model;
            $progname->set_model($model);

            #...and try to set last	value
            if ($progname_value) {
                $model->foreach( \&fct_iter_programs, $progname_value );
            }
            else {
                $progname->set_active(0);
            }

            #nothing has been set
            if ( $progname->get_active == -1 ) {
                $progname->set_active(0);
            }
        }

        return TRUE;
    }

    sub fct_get_next_filename {
        my ( $filename_value, $folder, $filetype_value ) = @_;

        #remove possible dots
        $filetype_value =~ s/\.//;

        $filename_value =~ s/\\//g;

        #random number - should be earlier than %N reading, as $R is actually a part of date
        if ( $filename_value =~ /\$R{1,}/ ) {

            #how many Rs are used? (important for formatting)
            my $pos_proc  = index( $filename_value, "\$R", 0 );
            my $r_counter = 0;
            my $last_pos  = $pos_proc;
            $pos_proc++;

            while ( $pos_proc <= length($filename_value) ) {
                $last_pos = index( $filename_value, "R", $pos_proc );
                if ( $last_pos != -1 && ( $last_pos - $pos_proc <= 1 ) ) {
                    $r_counter++;
                    $pos_proc++;
                }
                else {
                    last;
                }
            }

            #prepare filename
            print "---$r_counter Rs used in wild-card\n" if $sc->get_debug;
            my $marks = "";
            my $i     = 0;

            # Md5 will contain a salt (shutter) and a seconds since 1970
            my $md5_data = "shutter" . time;
            my $md5_hash = md5_hex($md5_data);

            # TODO: set random offset? I guess, current implementation is sufficient
            $marks = substr( $md5_hash, 0, $r_counter );

            #switch $Rs to a part of the hash
            $filename_value =~ s/\$R{1,}/$marks/g;
        }

        #auto increment
        if ( $filename_value =~ /\%N{1,}/ ) {

            #how many Ns are used? (important for formatting)
            my $pos_proc  = index( $filename_value, "%", 0 );
            my $n_counter = 0;
            my $last_pos  = $pos_proc;
            $pos_proc++;

            while ( $pos_proc <= length($filename_value) ) {
                $last_pos = index( $filename_value, "N", $pos_proc );
                if ( $last_pos != -1 && ( $last_pos - $pos_proc <= 1 ) ) {
                    $n_counter++;
                    $pos_proc++;
                }
                else {
                    last;
                }
            }

            #prepare filename
            print "$n_counter Ns used in wild-card\n" if $sc->get_debug;
            my $marks = "";
            my $i     = 0;

            while ( $i < $n_counter ) {
                $marks .= '\d';
                $i++;
            }

            #switch %Ns to \d
            $filename_value =~ s/\%N{1,}/$marks/g;

            #construct regex
            my $first = index( "$filename_value", '\d', 0 );
            my $search_file_start = quotemeta substr( $filename_value, 0, $first );
            my $search_file_end = quotemeta substr( $filename_value, $first + $n_counter * 2, length($filename_value) - $first + $n_counter * 2 );

            #store regex to string
            my $search_pattern = qr/$search_file_start($marks)$search_file_end\.$filetype_value/;

            print "Searching for files with pattern: $search_pattern\n"
              if $sc->get_debug;

            #shutter's custom wildcards are switched to reg.expressions in this search
            #($w, $h, $name)
            $search_pattern =~ s/\\\$w/\\d{1,}/g;
            $search_pattern =~ s/\\\$h/\\d{1,}/g;
            $search_pattern =~ s/\\\$profile/.{1,}/g;
            $search_pattern =~ s/\\\$name/.{1,}/g;
            $search_pattern =~ s/\\\$nb_name/.{1,}/g;

            print "Searching for files with pattern: $search_pattern\n"
              if $sc->get_debug;

            #get_all files from directory
            #we handle the listing with GnomeVFS to read remote dirs as well
            my ( $result, $uri_list ) = Gnome2::VFS::Directory->open( $folder, 'default' );

            #could not open directory, show error message and return
            unless ( $result eq 'ok' ) {

                my $response = $sd->dlg_error_message( sprintf( $d->get("Error while opening directory %s."), "'" . $folder . "'" ), $d->get("There was an error determining the filename."), undef, undef, undef, undef, undef, undef, Gnome2::VFS->result_to_string($result) );

                return FALSE;

            }

            #reading all files in current directory
            my $next_count = 0;
            while ( my ( $result, $file ) = $uri_list->read_next ) {
                if ( $result eq 'ok' ) {
                    my $fileinfo = Gnome2::VFS::FileInfo->new($file);
                    my $fname    = $shf->utf8_decode( $fileinfo->{'name'} );

                    #not a regular file? -> skip
                    next unless $fileinfo->{'type'} eq 'regular';

                    #does the current file match the pattern?
                    print "Comparing $fname\n" if $sc->get_debug;
                    if ( $fname =~ $search_pattern ) {
                        my $curr_value = $1;
                        if ( $curr_value && $curr_value > $next_count ) {
                            $next_count = $curr_value;
                            print "$next_count is currently greatest value...\n"
                              if $sc->get_debug;
                        }
                    }
                }
                elsif ( $result eq 'error-eof' ) {
                    $uri_list->close();
                    last;
                }
                else {
                    next;
                }
            }

            $next_count = 0 unless $next_count =~ /^(\d+\.?\d*|\.\d+)$/;
            unless ( length( $next_count + 1 ) > $n_counter ) {
                $next_count = sprintf( "%0" . $n_counter . "d", $next_count + 1 );
            }
            else {
                $next_count = sprintf( "%0" . $n_counter . "d", $next_count );
            }
            $marks = quotemeta $marks;

            #switch placeholder to $next_count
            $filename_value =~ s/$marks/$next_count/g;

        }

        #create new uri
        my $new_uri = Gnome2::VFS::URI->new("$folder/$filename_value.$filetype_value");
        if ( $new_uri->exists ) {
            my $count             = 1;
            my $existing_filename = $filename_value;
            while ( $new_uri->exists ) {
                $filename_value = $existing_filename . "(" . sprintf( "%03d", $count++ ) . ")";
                $new_uri        = Gnome2::VFS::URI->new($folder);
                $new_uri        = $new_uri->append_string("$filename_value.$filetype_value");
                print "Checking new uri: " . $new_uri->to_string . "\n"
                  if $sc->get_debug;
            }
        }

        return $new_uri;
    }

    sub fct_check_installed_plugins {

        my $plugin_dialog = Gtk2::MessageDialog->new( $window, [qw/modal destroy-with-parent/], 'info', 'close', $d->get("Updating plugin information") );
        $plugin_dialog->{destroyed} = FALSE;

        $plugin_dialog->set_title("Shutter");

        $plugin_dialog->set( 'secondary-text' => $d->get("Please wait while Shutter updates the plugin information") . "." );

        $plugin_dialog->signal_connect( response => sub { $plugin_dialog->{destroyed} = TRUE; $_[0]->destroy; } );

        $plugin_dialog->set_resizable(TRUE);

        my $plugin_progress = Gtk2::ProgressBar->new;
        $plugin_progress->set_no_show_all(TRUE);
        $plugin_progress->set_ellipsize('middle');
        $plugin_progress->set_orientation('left-to-right');
        $plugin_progress->set_fraction(0);

        $plugin_dialog->vbox->add($plugin_progress);

        my @plugin_paths = ( "$shutter_root/share/shutter/resources/system/plugins/*/*", "$ENV{'HOME'}/.shutter/plugins/*/*" );

        #fallback icon
        # maybe the plugin
        # does not provide a custom icon
        my $fb_pixbuf_path = "$shutter_root/share/shutter/resources/icons/executable.svg";
        my $fb_pixbuf = $lp->load( $fb_pixbuf_path, Gtk2::IconSize->lookup('menu') );

        foreach my $plugin_path (@plugin_paths) {
            my @plugins = glob($plugin_path);
            foreach my $pkey (@plugins) {
                if ( -d $pkey ) {
                    my $dir_name = $pkey;

                    #parse filename
                    my ( $name, $folder, $type ) = fileparse( $dir_name, qr/\.[^.]*/ );

                    #file exists
                    if ( $shf->file_exists("$dir_name/$name") ) {

                        #file is executable
                        if ( $shf->file_executable("$dir_name/$name") ) {

                            #new plugin information?
                            unless ( $plugins{$pkey}->{'binary'}
                                && $plugins{$pkey}->{'name'}
                                && $plugins{$pkey}->{'category'}
                                && $plugins{$pkey}->{'tooltip'}
                                && $plugins{$pkey}->{'lang'} )
                            {

                                #show dialog and progress bar
                                if (   !$plugin_dialog->window
                                    && !$plugin_dialog->{destroyed} )
                                {
                                    $plugin_progress->show;
                                    $plugin_dialog->show_all;
                                }

                                print "\nINFO: new plugin information detected - $dir_name/$name\n";

                                #path to executable
                                $plugins{$pkey}->{'binary'} = "$dir_name/$name";

                                #name
                                $plugins{$pkey}->{'name'} = &fct_plugin_get_info( $plugins{$pkey}->{'binary'}, 'name' );

                                #category
                                $plugins{$pkey}->{'category'} = &fct_plugin_get_info( $plugins{$pkey}->{'binary'}, 'sort' );

                                #tooltip
                                $plugins{$pkey}->{'tooltip'} = &fct_plugin_get_info( $plugins{$pkey}->{'binary'}, 'tip' );

                                #language (shell, perl etc.)
                                #=> directory name
                                my $folder_name = dirname($dir_name);
                                $folder_name =~ /.*\/(.*)/;
                                $plugins{$pkey}->{'lang'} = $1;

                                #refresh the progressbar
                                $plugin_progress->pulse;
                                $plugin_progress->set_text( $plugins{$pkey}->{'binary'} );

                                #refresh gui
                                &fct_update_gui;

                            }

                            $plugins{$pkey}->{'lang'} = "shell"
                              if $plugins{$pkey}->{'lang'} eq "";

                            chomp( $plugins{$pkey}->{'name'} );
                            chomp( $plugins{$pkey}->{'category'} );
                            chomp( $plugins{$pkey}->{'tooltip'} );
                            chomp( $plugins{$pkey}->{'lang'} );

                            #pixbuf
                            $plugins{$pkey}->{'pixbuf'} = $plugins{$pkey}->{'binary'} . ".png"
                              if ( $shf->file_exists( $plugins{$pkey}->{'binary'} . ".png" ) );
                            $plugins{$pkey}->{'pixbuf'} = $plugins{$pkey}->{'binary'} . ".svg"
                              if ( $shf->file_exists( $plugins{$pkey}->{'binary'} . ".svg" ) );

                            if ( $shf->file_exists( $plugins{$pkey}->{'pixbuf'} ) ) {
                                $plugins{$pkey}->{'pixbuf_object'} = $lp->load( $plugins{$pkey}->{'pixbuf'}, Gtk2::IconSize->lookup('menu') );
                            }
                            else {
                                $plugins{$pkey}->{'pixbuf'}        = $fb_pixbuf_path;
                                $plugins{$pkey}->{'pixbuf_object'} = $fb_pixbuf;
                            }
                            if ( $sc->get_debug ) {
                                print "$plugins{$pkey}->{'name'} - $plugins{$pkey}->{'binary'}\n";
                            }

                        }
                        else {
                            my $changed = chmod( 0755, "$dir_name/$name" );
                            unless ($changed) {
                                print "\nERROR: plugin exists but is not executable - $dir_name/$name\n";
                                delete $plugins{$pkey};
                            }
                        }    #endif plugin is executable

                    }
                    else {
                        delete $plugins{$pkey};
                    }    #endif plugin exists

                }
            }
        }

        #destroys the plugin dialog
        $plugin_dialog->response('ok');

        return TRUE;
    }

    sub fct_plugin_get_info {
        my ( $plugin, $info ) = @_;

        my $plugin_info = `$plugin $info`;
        utf8::decode $plugin_info;

        return $plugin_info;
    }

    sub fct_check_installed_upload_plugins {

        my $upload_plugin_dialog = Gtk2::MessageDialog->new( $window, [qw/modal destroy-with-parent/], 'info', 'close', $d->get("Updating upload plugin information") );
        $upload_plugin_dialog->{destroyed} = FALSE;

        $upload_plugin_dialog->set_title("Shutter");

        $upload_plugin_dialog->set( 'secondary-text' => $d->get("Please wait while Shutter updates the upload plugin information") . "." );

        $upload_plugin_dialog->signal_connect( response => sub { $upload_plugin_dialog->{destroyed} = TRUE; $_[0]->destroy; } );

        $upload_plugin_dialog->set_resizable(TRUE);

        my $upload_plugin_progress = Gtk2::ProgressBar->new;
        $upload_plugin_progress->set_no_show_all(TRUE);
        $upload_plugin_progress->set_ellipsize('middle');
        $upload_plugin_progress->set_orientation('left-to-right');
        $upload_plugin_progress->set_fraction(0);

        $upload_plugin_dialog->vbox->add($upload_plugin_progress);

        #plugins in user-home not supported yet FIXME
        my @upload_plugin_paths = ("$shutter_root/share/shutter/resources/system/upload_plugins/upload/*");

        foreach my $upload_plugin_path (@upload_plugin_paths) {
            my @upload_plugins = glob($upload_plugin_path);
            foreach my $ukey (@upload_plugins) {

                #Checking if file exists
                if ( $shf->file_exists("$ukey") ) {

                    #file is executable
                    if ( $shf->file_executable("$ukey") ) {

                        #parse filename
                        my ( $name, $folder, $type ) = fileparse( $ukey, qr/\.[^.]*/ );

                        #~ print $name, $folder, $type, "\n";

                        if (   !exists $accounts{$name}
                            || !exists $accounts{$name}->{module} )
                        {

                            #show dialog and progress bar
                            if (   !$upload_plugin_dialog->window
                                && !$upload_plugin_dialog->{destroyed} )
                            {
                                $upload_plugin_progress->show;
                                $upload_plugin_dialog->show_all;
                            }

                            print "\nINFO: new upload-plugin information detected - $folder$name\n";

                            if ( &fct_upload_plugin_get_info( $ukey, 'module' ) ) {

                                # Path
                                $accounts{$name}->{path} = $ukey;

                                # Module Name
                                $accounts{$name}->{module} = &fct_upload_plugin_get_info( $ukey, 'module' );

                                # URL
                                $accounts{$name}->{host} = &fct_upload_plugin_get_info( $ukey, 'url' );

                                # Folder
                                $accounts{$name}->{folder} = $folder;

                                # Description
                                $accounts{$name}->{description} = &fct_plugin_get_info( $ukey, 'description' );

                                # Username
                                $accounts{$name}->{username} = ""
                                  unless defined $accounts{$name}->{username};

                                # Password
                                $accounts{$name}->{password} = ""
                                  unless defined $accounts{$name}->{password};

                                # Register Color
                                $accounts{$name}->{register_color} = "blue";

                                # Register Text
                                $accounts{$name}->{register_text} = &fct_upload_plugin_get_info( $ukey, 'registration' );

                                # Upload Features
                                $accounts{$name}->{supports_anonymous_upload}  = &fct_upload_plugin_get_info( $ukey, 'supports_anonymous_upload' );
                                $accounts{$name}->{supports_authorized_upload} = &fct_upload_plugin_get_info( $ukey, 'supports_authorized_upload' );
                                $accounts{$name}->{supports_oauth_upload}      = &fct_upload_plugin_get_info( $ukey, 'supports_oauth_upload' );

                                #refresh the progressbar
                                $upload_plugin_progress->pulse;
                                $upload_plugin_progress->set_text( $accounts{$name}->{path} );

                            }
                            else {
                                print "\nERROR: upload-plugin exists but does not work properly - $folder$name\n";
                                delete $accounts{$name};
                            }

                            #refresh gui
                            &fct_update_gui;

                        }

                    }
                    else {
                        my $changed = chmod( 0755, "$ukey" );
                        unless ($changed) {

                            #parse filename
                            my ( $name, $folder, $type ) = fileparse( $ukey, qr/\.[^.]*/ );
                            print "\nERROR: upload-plugin exists but is not executable - $ukey\n";
                            delete $accounts{$name};
                        }    #endif plugin is executable
                    }
                }
            }

        }

        #destroys the upload_plugin dialog
        $upload_plugin_dialog->response('ok');

        return TRUE;
    }

    sub fct_upload_plugin_get_info {
        my ( $upload_plugin, $info ) = @_;

        my $upload_plugin_info = `$upload_plugin $info`;
        utf8::decode $upload_plugin_info;

        return $upload_plugin_info;
    }

    sub fct_iter_programs {
        my ( $model, $path, $iter, $search_for ) = @_;
        my $progname_value = $model->get_value( $iter, 1 );
        return FALSE if $search_for ne $progname_value;
        $progname->set_active_iter($iter);
        return TRUE;
    }

    sub fct_ret_workspace_menu {
        my $init = shift;

        my $menu_wrksp = Gtk2::Menu->new;

        my $wnck_screen = Gnome2::Wnck::Screen->get_default;
        $wnck_screen->force_update();

        #we determine the wm name but on older
        #version of libwnck (or the bindings)
        #the needed method is not available
        #in this case we use gdk to do it
        #
        #this leads to a known problem when switching
        #the wm => wm_name will still remain the old one
        my $wm_name = Gtk2::Gdk::Screen->get_default->get_window_manager_name;
        if ( $wnck_screen->can('get_window_manager_name') ) {
            $wm_name = $wnck_screen->get_window_manager_name;
        }

        my $active_workspace = $wnck_screen->get_active_workspace;

        #we need to handle different window managers here because there are some different models related
        #to workspaces and viewports
        #	compiz uses "multiple workspaces" - "multiple viewports" model for example
        #	default gnome wm metacity simply uses multiple workspaces
        #we will try to handle them by name
        my @workspaces = ();
        for ( my $wcount = 0 ; $wcount < $wnck_screen->get_workspace_count ; $wcount++ ) {
            push( @workspaces, $wnck_screen->get_workspace($wcount) );
        }

        foreach my $space (@workspaces) {
            next unless defined $space;

            #compiz
            print "Current window manager: ", $wm_name, "\n" if $sc->get_debug;
            if ( $wm_name =~ /compiz/i ) {

                #calculate viewports with size of workspace
                my $vpx = $space->get_viewport_x;
                my $vpy = $space->get_viewport_y;

                my $n_viewports_column = int( $space->get_width / $wnck_screen->get_width );
                my $n_viewports_rows   = int( $space->get_height / $wnck_screen->get_height );

                #rows
                for ( my $j = 0 ; $j < $n_viewports_rows ; $j++ ) {

                    #columns
                    for ( my $i = 0 ; $i < $n_viewports_column ; $i++ ) {
                        my @vp = ( $i * $wnck_screen->get_width, $j * $wnck_screen->get_height );
                        my $vp_name = "$wm_name x: $i y: $j";

                        print "shutter_wrksp_direct_compiz" . $vp[0] . "x" . $vp[1] . "\n"
                          if $sc->get_debug;

                        my $vp_item = Gtk2::MenuItem->new_with_label( ucfirst $vp_name );
                        $vp_item->signal_connect(
                            'activate' => \&evt_take_screenshot,
                            "shutter_wrksp_direct_compiz" . $vp[0] . "x" . $vp[1]
                        );
                        $menu_wrksp->append($vp_item);

                        #do not offer current viewport
                        if ( $vp[0] == $vpx && $vp[1] == $vpy ) {
                            $vp_item->set_sensitive(FALSE);
                        }
                    }    #columns
                }    #rows

                #all other wm manager like metacity etc.
                #we could add more of them here if needed
            }
            else {

                my $wrkspace_item = Gtk2::MenuItem->new_with_label( $space->get_name );
                $wrkspace_item->signal_connect(
                    'activate' => \&evt_take_screenshot,
                    "shutter_wrksp_direct" . $space->get_number
                );
                $menu_wrksp->append($wrkspace_item);

                if (   $active_workspace
                    && $active_workspace->get_number == $space->get_number )
                {
                    $wrkspace_item->set_sensitive(FALSE);
                }

            }
        }

        #entry for capturing all workspaces
        $menu_wrksp->append( Gtk2::SeparatorMenuItem->new );

        my $allwspaces_item = Gtk2::MenuItem->new_with_label( $d->get("Capture All Workspaces") );
        $allwspaces_item->signal_connect(
            'activate' => \&evt_take_screenshot,
            "shutter_wrksp_direct" . 'all'
        );
        $menu_wrksp->append($allwspaces_item);

        #monitor flag
        my $n_mons = Gtk2::Gdk::Screen->get_default->get_n_monitors;

        #use only current monitor
        $menu_wrksp->append( Gtk2::SeparatorMenuItem->new );
        if ($init) {
            $current_monitor_active = Gtk2::CheckMenuItem->new_with_label( $d->get("Limit to current monitor") );
            if ( defined $settings_xml->{'general'}->{'current_monitor_active'} ) {
                $current_monitor_active->set_active( $settings_xml->{'general'}->{'current_monitor_active'} );
            }
            else {
                $current_monitor_active->set_active(FALSE);
            }
            $menu_wrksp->append($current_monitor_active);
        }
        else {
            $current_monitor_active->reparent($menu_wrksp);
        }

        $tooltips->set_tip( $current_monitor_active, sprintf( $d->nget( "This option is only useful when you are running a multi-monitor system (%d monitor detected).\nEnable it to capture only the current monitor.", "This option is only useful when you are running a multi-monitor system (%d monitors detected).\nEnable it to capture only the current monitor.", $n_mons ), $n_mons ) );
        if ( $n_mons > 1 ) {
            $current_monitor_active->set_sensitive(TRUE);
        }
        else {
            $current_monitor_active->set_active(FALSE);
            $current_monitor_active->set_sensitive(FALSE);
        }

        $menu_wrksp->show_all();
        return $menu_wrksp;
    }

    sub fct_ret_window_menu {

        my $menu_windows = Gtk2::Menu->new;

        my $active_workspace = $wnck_screen->get_active_workspace;
        my $icontheme        = $sc->get_theme;

        #add item for active window
        my $active_window_item_image;
        if ( $icontheme->has_icon('preferences-system-windows') ) {
            $active_window_item_image = Gtk2::Image->new_from_icon_name( 'preferences-system-windows', 'menu' );
        }
        else {
            $active_window_item_image = Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window_active.svg", Gtk2::IconSize->lookup('menu') ) );
        }

        my $active_window_item = Gtk2::ImageMenuItem->new_with_label( $d->get("Active Window") );
        $active_window_item->set_image($active_window_item_image);
        $active_window_item->set( 'always_show_image' => TRUE )
          if Gtk2->CHECK_VERSION( 2, 16, 0 );

        $tooltips->set_tip( $active_window_item, $d->get("Capture the last active window") );

        $active_window_item->signal_connect(
            'activate' => \&evt_take_screenshot,
            'awindow'
        );

        $menu_windows->append($active_window_item);
        $menu_windows->append( Gtk2::SeparatorMenuItem->new );

        #add all windows to menu to capture it directly
        foreach my $win ( $wnck_screen->get_windows_stacked ) {
            if ( $active_workspace && $win->is_on_workspace($active_workspace) ) {
                my $window_item = Gtk2::ImageMenuItem->new_with_label( $win->get_name );
                foreach my $child ( $window_item->get_children ) {
                    if ( $child =~ /Gtk2::AccelLabel/ ) {
                        $child->set_width_chars(50);
                        $child->set_ellipsize('middle');
                        last;
                    }
                }
                $window_item->set_image( Gtk2::Image->new_from_pixbuf( $win->get_mini_icon ) );
                $window_item->set( 'always_show_image' => TRUE )
                  if Gtk2->CHECK_VERSION( 2, 16, 0 );
                $window_item->signal_connect(
                    'activate' => \&evt_take_screenshot,
                    "shutter_window_direct" . $win->get_xid
                );
                $menu_windows->append($window_item);
            }
        }

        $menu_windows->show_all;
        return $menu_windows;
    }

    sub fct_ret_tray_menu {

        my $traytheme = $sc->get_theme;

        my $menu_tray = Gtk2::Menu->new();

        #selection
        my $menuitem_select = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('_Selection') );
        eval {
            my $ccursor_pb = Gtk2::Gdk::Cursor->new('left_ptr')->get_image->scale_simple( Gtk2::IconSize->lookup('menu'), 'bilinear' );
            $menuitem_select->set_image( Gtk2::Image->new_from_pixbuf($ccursor_pb) );
        };
        if ($@) {
            if ( $traytheme->has_icon('applications-accessories') ) {
                $menuitem_select->set_image( Gtk2::Image->new_from_icon_name( 'applications-accessories', 'menu' ) );
            }
            else {
                $menuitem_select->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/selection.svg", Gtk2::IconSize->lookup('menu') ) ) );
            }
        }
        $menuitem_select->signal_connect(
            activate => \&evt_take_screenshot,
            'tray_select'
        );

        #full screen
        my $menuitem_full = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('_Desktop') );
        if ( $traytheme->has_icon('user-desktop') ) {
            $menuitem_full->set_image( Gtk2::Image->new_from_icon_name( 'user-desktop', 'menu' ) );
        }
        elsif ( $traytheme->has_icon('desktop') ) {
            $menuitem_full->set_image( Gtk2::Image->new_from_icon_name( 'desktop', 'menu' ) );
        }
        else {
            $menuitem_full->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/desktop.svg", Gtk2::IconSize->lookup('menu') ) ) );
        }
        $menuitem_full->signal_connect(
            activate => \&evt_take_screenshot,
            'tray_full'
        );

        #~ #awindow
        #~ my $menuitem_awindow = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('_Active Window') );
        #~ if($traytheme->has_icon('preferences-system-windows')){
        #~ $menuitem_awindow->set_image( Gtk2::Image->new_from_icon_name( 'preferences-system-windows', 'menu' ) );
        #~ }else{
        #~ $menuitem_awindow->set_image(
        #~ Gtk2::Image->new_from_pixbuf(
        #~ $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window_active.svg", Gtk2::IconSize->lookup('menu') )
        #~ )
        #~ );
        #~ }
        #~ $menuitem_awindow->signal_connect(
        #~ activate => \&evt_take_screenshot,
        #~ 'tray_awindow'
        #~ );

        #window
        my $menuitem_window = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('Window _under Cursor') );
        if ( $traytheme->has_icon('preferences-system-windows') ) {
            $menuitem_window->set_image( Gtk2::Image->new_from_icon_name( 'preferences-system-windows', 'menu' ) );
        }
        else {
            $menuitem_window->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window.svg", Gtk2::IconSize->lookup('menu') ) ) );
        }
        $menuitem_window->signal_connect(
            activate => \&evt_take_screenshot,
            'tray_window'
        );

        #window list
        my $menuitem_window_list = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('Select W_indow') );
        if ( $traytheme->has_icon('preferences-system-windows') ) {
            $menuitem_window_list->set_image( Gtk2::Image->new_from_icon_name( 'preferences-system-windows', 'menu' ) );
        }
        else {
            $menuitem_window_list->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window.svg", Gtk2::IconSize->lookup('menu') ) ) );
        }
        $menuitem_window_list->set_name('windowlist');
        $menuitem_window_list->set_submenu(&fct_ret_window_menu);

        #section
        my $menuitem_window_sect = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('Se_ction') );
        if ( $traytheme->has_icon('gdm-xnest') ) {
            $menuitem_window_sect->set_image( Gtk2::Image->new_from_icon_name( 'gdm-xnest', 'menu' ) );
        }
        else {
            $menuitem_window_sect->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window_section.svg", Gtk2::IconSize->lookup('menu') ) ) );
        }
        $menuitem_window_sect->signal_connect(
            activate => \&evt_take_screenshot,
            'tray_section'
        );

        #menu
        my $menuitem_window_menu = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('_Menu') );
        if ( $traytheme->has_icon('alacarte') ) {
            $menuitem_window_menu->set_image( Gtk2::Image->new_from_icon_name( 'alacarte', 'menu' ) );
        }
        else {
            $menuitem_window_menu->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window_menu.svg", Gtk2::IconSize->lookup('menu') ) ) );
        }
        $menuitem_window_menu->signal_connect(
            activate => \&evt_take_screenshot,
            'tray_menu'
        );

        #tooltip
        my $menuitem_window_tooltip = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('_Tooltip') );
        if ( $traytheme->has_icon('help-faq') ) {
            $menuitem_window_tooltip->set_image( Gtk2::Image->new_from_icon_name( 'help-faq', 'menu' ) );
        }
        else {
            $menuitem_window_tooltip->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window_tooltip.svg", Gtk2::IconSize->lookup('menu') ) ) );
        }
        $menuitem_window_tooltip->signal_connect(
            activate => \&evt_take_screenshot,
            'tray_tooltip'
        );

        #web
        my $menuitem_web = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('_Web') );
        $menuitem_web->set_sensitive($gnome_web_photo);
        if ( $traytheme->has_icon('web-browser') ) {
            $menuitem_web->set_image( Gtk2::Image->new_from_icon_name( 'web-browser', 'menu' ) );
        }
        else {
            $menuitem_web->set_image( Gtk2::Image->new_from_pixbuf( $lp->load( "$shutter_root/share/shutter/resources/icons/web_image.svg", Gtk2::IconSize->lookup('menu') ) ) );
        }
        $menuitem_web->signal_connect(
            activate => \&evt_take_screenshot,
            'tray_web'
        );

        #show main window
        my $menuitem_show_window = Gtk2::MenuItem->new_with_mnemonic( $d->get('S_how main window') );
        $menuitem_show_window->signal_connect( 'activate', sub { $is_hidden = TRUE; &fct_control_main_window('show'); } );
        $menuitem_show_window->set_name('show_window');
        $menuitem_show_window->set_sensitive(TRUE);

        #redo last screenshot
        my $menuitem_redoshot = Gtk2::ImageMenuItem->new_with_mnemonic( $d->get('_Redo last screenshot') );
        $menuitem_redoshot->set_image( Gtk2::Image->new_from_stock( 'gtk-refresh', 'menu' ) );
        $menuitem_redoshot->signal_connect( 'activate', \&evt_take_screenshot, 'redoshot' );
        $menuitem_redoshot->set_name('redoshot');
        $menuitem_redoshot->set_sensitive(FALSE);

        #preferences
        my $menuitem_settings = Gtk2::ImageMenuItem->new_from_stock('gtk-preferences');
        $menuitem_settings->signal_connect( "activate", \&evt_show_settings );

        #quick profile selector
        my $menuitem_quicks = Gtk2::MenuItem->new_with_mnemonic( $d->get('_Quick profile select') );

        #set name to identify the item later - we use this in really rare cases
        $menuitem_quicks->set_name('quicks');
        $menuitem_quicks->set_sensitive(FALSE);

        #info
        my $menuitem_info = Gtk2::ImageMenuItem->new_from_stock('gtk-about');
        $menuitem_info->signal_connect( "activate", \&evt_about );

        #quit
        my $menuitem_quit = Gtk2::ImageMenuItem->new_from_stock('gtk-quit');
        $menuitem_quit->signal_connect( "activate", \&evt_delete_window, 'quit' );

        $menu_tray->append($menuitem_show_window);
        $menu_tray->append( Gtk2::SeparatorMenuItem->new );
        $menu_tray->append($menuitem_redoshot);
        $menu_tray->append( Gtk2::SeparatorMenuItem->new );
        $menu_tray->append($menuitem_select);

        #~ $menu_tray->append( Gtk2::SeparatorMenuItem->new );
        $menu_tray->append($menuitem_full);

        #~ $menu_tray->append( Gtk2::SeparatorMenuItem->new );
        #~ $menu_tray->append($menuitem_awindow);
        $menu_tray->append($menuitem_window);
        $menu_tray->append($menuitem_window_list);
        $menu_tray->append($menuitem_window_sect);
        $menu_tray->append($menuitem_window_menu);
        $menu_tray->append($menuitem_window_tooltip);

        #~ $menu_tray->append( Gtk2::SeparatorMenuItem->new );
        $menu_tray->append($menuitem_web);
        $menu_tray->append( Gtk2::SeparatorMenuItem->new );
        $menu_tray->append($menuitem_settings);
        $menu_tray->append($menuitem_quicks);
        $menu_tray->append( Gtk2::SeparatorMenuItem->new );
        $menu_tray->append($menuitem_info);
        $menu_tray->append($menuitem_quit);
        $menu_tray->show_all;

        return $menu_tray;
    }

    sub fct_ret_program_menu {
        my $menu_programs = shift;

        $menu_programs = Gtk2::Menu->new unless defined $menu_programs;
        foreach my $child ( $menu_programs->get_children ) {
            $child->destroy;
        }

        #take $key (mime) directly
        my $key = &fct_get_current_file;

        #FIXME - different mime types
        #have different apps registered
        #we should restrict the offeres apps
        #by comparing the selected
        #
        #currently we just take the last selected file into account
        #
        #search selected files for mime...
        unless ($key) {
            $session_start_screen{'first_page'}->{'view'}->selected_foreach(
                sub {
                    my ( $view, $path ) = @_;
                    my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
                    if ( defined $iter ) {
                        $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );
                    }
                }
            );
        }

        #still no key? => leave sub
        unless ($key) {
            $sm->{_menuitem_reopen}->set_sensitive(FALSE);
            $sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
            return $menu_programs;
        }

        #no valid hash entry?
        unless ( exists $session_screens{$key}->{'mime_type'} ) {
            $sm->{_menuitem_reopen}->set_sensitive(FALSE);
            $sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
            return $menu_programs;
        }

        #get applications
        my $mime_type = Gnome2::VFS::Mime::Type->new( $session_screens{$key}->{'mime_type'} );
        my @apps      = $mime_type->get_all_applications();

        #no apps determined!
        unless ( scalar @apps ) {
            $sm->{_menuitem_reopen}->set_sensitive(FALSE);
            $sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
            return $menu_programs;
        }

        #create menu items
        foreach my $app (@apps) {

            #ignore Shutter's desktop entry
            next if $app->{'id'} eq 'shutter.desktop';

            $app->{'name'} = $shf->utf8_decode( $app->{'name'} );

            #FIXME
            #we simply cut the kde* / kde4* substring here
            #is it possible to get the wrong app if there
            #is the kde3 and the kde4 version of an app installed?
            #
            #I think so ;-)
            $app->{'id'} =~ s/^(kde4|kde)-//g;

            my $program_item = Gtk2::ImageMenuItem->new_with_label( $app->{'name'} );
            $program_item->set( 'always_show_image' => TRUE )
              if Gtk2->CHECK_VERSION( 2, 16, 0 );
            $menu_programs->append($program_item);

            my $icon = $app->get_icon;
            if ($icon) {

                #cut image formats
                $icon =~ s/(.png|.svg|.gif|.jpeg|.jpg|.xpm)//g;
                if ( $sc->get_theme->has_icon($icon) ) {
                    my ( $iw, $ih ) = Gtk2::IconSize->lookup('menu');

                    my $icon_pixbuf = undef;
                    eval { $icon_pixbuf = $sc->get_theme->load_icon( $icon, $ih, 'generic-fallback' ); };
                    if ($@) {
                        print "\nWARNING: Could not load icon $icon: $@\n";
                        $icon_pixbuf = undef;
                    }

                    if ($program_item) {
                        $program_item->set_image( Gtk2::Image->new_from_pixbuf($icon_pixbuf) );
                    }
                }
            }

            #connect to signal
            if ($program_item) {
                $program_item->signal_connect(
                    'activate' => sub {
                        &fct_open_with_program( $app, $app->{'name'} );
                    }
                );
            }
        }

        #menu does not contain any item
        unless ( $menu_programs->get_children ) {
            $sm->{_menuitem_reopen}->set_sensitive(FALSE);
            $sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
        }

        $menu_programs->show_all;
        return $menu_programs;
    }

    sub fct_ret_web_menu {

        my $menu_web = Gtk2::Menu->new;

        my $timeout0 = Gtk2::RadioMenuItem->new( undef, $d->get("Wait indefinitely") );
        my $timeout1 = Gtk2::RadioMenuItem->new( $timeout0, sprintf( $d->nget( "Wait max %d second", "Wait max %d seconds", 10 ), 10 ) );
        my $timeout2 = Gtk2::RadioMenuItem->new( $timeout0, sprintf( $d->nget( "Wait max %d second", "Wait max %d seconds", 10 ), 30 ) );
        my $timeout3 = Gtk2::RadioMenuItem->new( $timeout0, sprintf( $d->nget( "Wait max %d minute", "Wait max %d minutes", 1 ),  1 ) );
        my $timeout4 = Gtk2::RadioMenuItem->new( $timeout0, sprintf( $d->nget( "Wait max %d minute", "Wait max %d minutes", 2 ),  2 ) );

        $timeout0->set_name("timeout0");
        $timeout1->set_name("timeout10");
        $timeout2->set_name("timeout30");
        $timeout3->set_name("timeout60");
        $timeout4->set_name("timeout120");

        $tooltips->set_tip( $timeout0, $d->get("Shutter will wait indefinitely for the screenshot to capture") );
        $tooltips->set_tip( $timeout1, sprintf( $d->nget( "Shutter will wait up to %d second for the screenshot to capture before aborting the process if it's taking too long", "Shutter will wait up to %d seconds for the screenshot to capture before aborting the process if it's taking too long", 10 ), 10 ) );
        $tooltips->set_tip( $timeout2, sprintf( $d->nget( "Shutter will wait up to %d second for the screenshot to capture before aborting the process if it's taking too long", "Shutter will wait up to %d seconds for the screenshot to capture before aborting the process if it's taking too long", 30 ), 30 ) );
        $tooltips->set_tip( $timeout3, sprintf( $d->nget( "Shutter will wait up to %d minute for the screenshot to capture before aborting the process if it's taking too long", "Shutter will wait up to %d minutes for the screenshot to capture before aborting the process if it's taking too long", 1 ), 1 ) );
        $tooltips->set_tip( $timeout4, sprintf( $d->nget( "Shutter will wait up to %d minute for the screenshot to capture before aborting the process if it's taking too long", "Shutter will wait up to %d minutes for the screenshot to capture before aborting the process if it's taking too long", 2 ), 2 ) );

        $timeout2->set_active(TRUE);
        $menu_web->append($timeout0);
        $menu_web->append($timeout1);
        $menu_web->append($timeout2);
        $menu_web->append($timeout3);
        $menu_web->append($timeout4);

        if ( defined $settings_xml->{'general'}->{'web_timeout'} ) {

            #determining timeout
            my @timeouts = $menu_web->get_children;
            my $timeout  = undef;
            foreach my $to (@timeouts) {
                $timeout = $to->get_name;
                $timeout =~ /([0-9]+)/;
                $timeout = $1;
                if ( $settings_xml->{'general'}->{'web_timeout'} == $timeout ) {
                    $to->set_active(TRUE);
                }
            }
        }
        $menu_web->show_all;
        return $menu_web;
    }

    sub fct_ret_profile_menu {
        my $combobox_settings_profiles = shift;
        my $current_profiles_ref       = shift;
        my $menu_profile               = shift;

        $menu_profile = Gtk2::Menu->new unless defined $menu_profile;
        foreach my $child ( $menu_profile->get_children ) {
            $child->destroy;
        }

        my $group   = undef;
        my $counter = 0;
        foreach my $profile ( @{$current_profiles_ref} ) {
            my $profile_item = Gtk2::RadioMenuItem->new( $group, $profile );
            $profile_item->set_active(TRUE)
              if $profile eq $combobox_settings_profiles->get_active_text;
            $profile_item->signal_connect(
                'toggled' => sub {
                    my $widget = shift;
                    return TRUE unless $widget->get_active;

                    for ( my $i = 0 ; $i < scalar @{$current_profiles_ref} ; $i++ ) {
                        $combobox_settings_profiles->set_active($i);
                        $current_profile_indx = $i;
                        if ( $profile eq $combobox_settings_profiles->get_active_text ) {
                            &evt_apply_profile( $widget, $combobox_settings_profiles, $current_profiles_ref );
                            last;
                        }
                    }
                }
            );
            $group = $profile_item unless $group;
            $menu_profile->append($profile_item);
            $counter++;
        }

        $menu_profile->show_all;
        return $menu_profile;
    }

    sub fct_load_accounts_tree {

        $accounts_model = Gtk2::ListStore->new( 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::Boolean', 'Glib::Boolean', 'Glib::Boolean' );

        foreach ( keys %accounts ) {
            my $hidden_text = "";
            for ( my $i = 1 ; $i <= length( $accounts{$_}->{'password'} ) ; $i++ ) {
                $hidden_text .= '*';
            }
            $accounts_model->set( $accounts_model->append, 0, $accounts{$_}->{'host'}, 1, $accounts{$_}->{'username'}, 2, $hidden_text, 3, $accounts{$_}->{'not_used_yet'}, 4, $accounts{$_}->{'register_color'}, 5, $accounts{$_}->{'register_text'}, 6, $accounts{$_}->{'module'}, 7, $accounts{$_}->{'path'}, 8, $accounts{$_}->{'folder'}, 9, $accounts{$_}->{'description'}, 10, $accounts{$_}->{'supports_anonymous_upload'}, 11, $accounts{$_}->{'supports_authorized_upload'}, 12, $accounts{$_}->{'supports_oauth_upload'}, );
        }

        return TRUE;
    }

    sub fct_load_plugin_tree {

        my $effects_model = Gtk2::ListStore->new( 'Gtk2::Gdk::Pixbuf', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', );
        foreach my $pkey ( sort keys %plugins ) {
            if ( $plugins{$pkey}->{'binary'} ) {

                #we need to update the pixbuf of the plugins again in some cases
                #
                #pixbufs are not cached and therefore not checked at startup if
                #the cached plugin is not in the plugin path
                #(maybe changed the installation dir)
                unless ( $plugins{$pkey}->{'pixbuf'}
                    || $plugins{$pkey}->{'pixbuf_object'} )
                {
                    $plugins{$pkey}->{'pixbuf'} = $plugins{$pkey}->{'binary'} . ".png"
                      if ( $shf->file_exists( $plugins{$pkey}->{'binary'} . ".png" ) );
                    $plugins{$pkey}->{'pixbuf'} = $plugins{$pkey}->{'binary'} . ".svg"
                      if ( $shf->file_exists( $plugins{$pkey}->{'binary'} . ".svg" ) );

                    if ( $shf->file_exists( $plugins{$pkey}->{'pixbuf'} ) ) {
                        $plugins{$pkey}->{'pixbuf_object'} = $lp->load( $plugins{$pkey}->{'pixbuf'}, Gtk2::IconSize->lookup('menu') );
                    }
                    else {
                        $plugins{$pkey}->{'pixbuf'} = "$shutter_root/share/shutter/resources/icons/executable.svg";
                        $plugins{$pkey}->{'pixbuf_object'} = $lp->load( $plugins{$pkey}->{'pixbuf'}, Gtk2::IconSize->lookup('menu') );
                    }
                }

                $effects_model->set( $effects_model->append, 0, $plugins{$pkey}->{'pixbuf_object'}, 1, $plugins{$pkey}->{'name'}, 2, $plugins{$pkey}->{'category'}, 3, $plugins{$pkey}->{'tooltip'}, 4, $plugins{$pkey}->{'lang'}, 5, $plugins{$pkey}->{'binary'}, 6, $pkey, );
            }
            else {
                print "\nWARNING: Plugin $pkey is not configured properly, ignoring\n";
                delete $plugins{$pkey};
            }
        }

        return $effects_model;
    }

    sub fct_set_model_accounts {
        my $accounts_tree = $_[0];

        my @columns = $accounts_tree->get_columns;
        foreach my $col (@columns) {
            $accounts_tree->remove_column($col);
        }

        $accounts_tree->set_tooltip_column(9)
          if Gtk2->CHECK_VERSION( 2, 11, 0 );

        #name
        my $tv_clmn_name_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_name_text->set_title( $d->get("Host") );
        my $renderer_name_accounts = Gtk2::CellRendererText->new;
        $tv_clmn_name_text->pack_start( $renderer_name_accounts, FALSE );
        $tv_clmn_name_text->set_attributes( $renderer_name_accounts, text => 6 );
        $accounts_tree->append_column($tv_clmn_name_text);

        #username
        my $tv_clmn_username_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_username_text->set_max_width(100);
        $tv_clmn_username_text->set_title( $d->get("Username") );
        my $renderer_username_accounts = Gtk2::CellRendererText->new;
        $tv_clmn_username_text->pack_start( $renderer_username_accounts, FALSE );
        $tv_clmn_username_text->set_attributes(
            $renderer_username_accounts,
            text      => 1,
            editable  => 11,
            sensitive => 11
        );
        $renderer_username_accounts->signal_connect(
            'edited' => sub {
                my ( $cell, $text_path, $new_text, $model ) = @_;
                my $path = Gtk2::TreePath->new_from_string($text_path);
                my $iter = $model->get_iter($path);

                #save entered username to the hash
                $accounts{ $model->get_value( $iter, 6 ) }->{'username'} = $new_text;

                $model->set( $iter, 1, $new_text );
            },
            $accounts_model
        );

        $accounts_tree->append_column($tv_clmn_username_text);

        #password
        my $tv_clmn_password_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_password_text->set_max_width(100);
        $tv_clmn_password_text->set_title( $d->get("Password") );
        my $renderer_password_accounts = Gtk2::CellRendererText->new;
        $tv_clmn_password_text->pack_start( $renderer_password_accounts, FALSE );
        $tv_clmn_password_text->set_attributes(
            $renderer_password_accounts,
            text      => 2,
            editable  => 11,
            sensitive => 11
        );
        $renderer_password_accounts->signal_connect(
            'edited' => sub {
                my ( $cell, $text_path, $new_text, $model ) = @_;
                my $path        = Gtk2::TreePath->new_from_string($text_path);
                my $iter        = $model->get_iter($path);
                my $hidden_text = "";

                for ( my $i = 1 ; $i <= length($new_text) ; $i++ ) {
                    $hidden_text .= '*';
                }

                $accounts{ $model->get_value( $iter, 6 ) }->{'password'} = $new_text;    #save entered password to the hash
                $model->set( $iter, 2, $hidden_text );
            },
            $accounts_model
        );

        $accounts_tree->append_column($tv_clmn_password_text);

        #upload features
        my $tv_clmn_f1_toggle = Gtk2::TreeViewColumn->new;
        $tv_clmn_f1_toggle->set_title( $d->get("Anonymous Upload") );
        my $f1_toggle = Gtk2::CellRendererToggle->new();
        $tv_clmn_f1_toggle->pack_start( $f1_toggle, FALSE );
        $tv_clmn_f1_toggle->set_attributes( $f1_toggle, active => 10 );
        $accounts_tree->append_column($tv_clmn_f1_toggle);

        my $tv_clmn_f2_toggle = Gtk2::TreeViewColumn->new;
        $tv_clmn_f2_toggle->set_title( $d->get("Authorized Upload") );
        my $f2_toggle = Gtk2::CellRendererToggle->new();
        $tv_clmn_f2_toggle->pack_start( $f2_toggle, FALSE );
        $tv_clmn_f2_toggle->set_attributes( $f2_toggle, active => 11 );
        $accounts_tree->append_column($tv_clmn_f2_toggle);

        my $tv_clmn_f3_toggle = Gtk2::TreeViewColumn->new;
        $tv_clmn_f3_toggle->set_title( $d->get("OAuth Upload") );
        my $f3_toggle = Gtk2::CellRendererToggle->new();
        $tv_clmn_f3_toggle->pack_start( $f3_toggle, FALSE );
        $tv_clmn_f3_toggle->set_attributes( $f3_toggle, active => 12 );
        $accounts_tree->append_column($tv_clmn_f3_toggle);

        #description
        #tooltip column (show as columns when needed)
        unless ( Gtk2->CHECK_VERSION( 2, 12, 0 ) ) {
            my $tv_clmn_descr_text = Gtk2::TreeViewColumn->new;
            $tv_clmn_descr_text->set_resizable(TRUE);
            $tv_clmn_descr_text->set_title( $d->get("Description") );
            my $renderer_descr_effects = Gtk2::CellRendererText->new;
            $tv_clmn_descr_text->pack_start( $renderer_descr_effects, FALSE );
            $tv_clmn_descr_text->set_attributes( $renderer_descr_effects, text => 9 );
            $accounts_tree->append_column($tv_clmn_descr_text);
        }

        #register
        my $tv_clmn_pix_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_pix_text->set_title( $d->get("Register") );
        my $ren_text = Gtk2::CellRendererText->new();
        $tv_clmn_pix_text->pack_start( $ren_text, FALSE );
        $tv_clmn_pix_text->set_attributes( $ren_text, 'text', 5, 'foreground', 4 );
        $accounts_tree->append_column($tv_clmn_pix_text);

        return TRUE;
    }

    sub fct_set_model_plugins {
        my $effects_tree = $_[0];

        #~ my @columns = $effects_tree->get_columns;
        #~ foreach (@columns) {
        #~ $effects_tree->remove_column($_);
        #~ }

        #tooltip
        $effects_tree->set_tooltip_column(3)
          if Gtk2->CHECK_VERSION( 2, 11, 0 );

        my $tv_clmn_pix_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_pix_text->set_resizable(TRUE);
        $tv_clmn_pix_text->set_title( $d->get("Icon") );
        my $renderer_pix_effects = Gtk2::CellRendererPixbuf->new;
        $tv_clmn_pix_text->pack_start( $renderer_pix_effects, FALSE );
        $tv_clmn_pix_text->set_attributes( $renderer_pix_effects, pixbuf => 0 );
        $effects_tree->append_column($tv_clmn_pix_text);

        #name
        my $tv_clmn_text_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_text_text->set_resizable(TRUE);
        $tv_clmn_text_text->set_title( $d->get("Name") );
        my $renderer_text_effects = Gtk2::CellRendererText->new;
        $tv_clmn_text_text->pack_start( $renderer_text_effects, FALSE );
        $tv_clmn_text_text->set_attributes( $renderer_text_effects, text => 1 );

        $effects_tree->append_column($tv_clmn_text_text);

        #category
        my $tv_clmn_category_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_category_text->set_resizable(TRUE);
        $tv_clmn_category_text->set_title( $d->get("Category") );
        my $renderer_category_effects = Gtk2::CellRendererText->new;
        $tv_clmn_category_text->pack_start( $renderer_category_effects, FALSE );
        $tv_clmn_category_text->set_attributes( $renderer_category_effects, text => 2 );
        $effects_tree->append_column($tv_clmn_category_text);

        #tooltip column
        unless ( Gtk2->CHECK_VERSION( 2, 12, 0 ) ) {
            my $tv_clmn_descr_text = Gtk2::TreeViewColumn->new;
            $tv_clmn_descr_text->set_resizable(TRUE);
            $tv_clmn_descr_text->set_title( $d->get("Description") );
            my $renderer_descr_effects = Gtk2::CellRendererText->new;
            $tv_clmn_descr_text->pack_start( $renderer_descr_effects, FALSE );
            $tv_clmn_descr_text->set_attributes( $renderer_descr_effects, text => 3 );
            $effects_tree->append_column($tv_clmn_descr_text);
        }

        #language
        my $tv_clmn_lang_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_lang_text->set_resizable(TRUE);
        $tv_clmn_lang_text->set_title( $d->get("Language") );
        my $renderer_lang_effects = Gtk2::CellRendererText->new;
        $tv_clmn_lang_text->pack_start( $renderer_lang_effects, FALSE );
        $tv_clmn_lang_text->set_attributes( $renderer_lang_effects, text => 4 );
        $effects_tree->append_column($tv_clmn_lang_text);

        #path
        my $tv_clmn_path_text = Gtk2::TreeViewColumn->new;
        $tv_clmn_path_text->set_resizable(TRUE);
        $tv_clmn_path_text->set_title( $d->get("Path") );
        my $renderer_path_effects = Gtk2::CellRendererText->new;
        $tv_clmn_path_text->pack_start( $renderer_path_effects, FALSE );
        $tv_clmn_path_text->set_attributes( $renderer_path_effects, text => 5 );
        $effects_tree->append_column($tv_clmn_path_text);

        return TRUE;
    }

    sub fct_init_depend {

        #imagemagick/perlmagick
        unless ( File::Which::which('convert') ) {
            die "ERROR: imagemagick is missing --> aborting!\n\n";
        }

        #gnome-web-photo
        unless ( File::Which::which('gnome-web-photo') ) {
            warn "WARNING: gnome-web-photo is missing --> screenshots of websites will be disabled!\n\n";
            $gnome_web_photo = FALSE;
        }

        #nautilus-sendto
        unless ( File::Which::which('nautilus-sendto') ) {
            $nautilus_sendto = FALSE;
        }

        #goocanvas
        eval { require Goo::Canvas };
        if ($@) {
            warn "WARNING: Goo::Canvas/libgoo-canvas-perl is missing --> drawing tool will be disabled!\n\n";
            $goocanvas = FALSE;
        }

        #libimage-exiftool-perl
        eval { require Image::ExifTool };
        if ($@) {
            warn "WARNING: Image::ExifTool is missing --> writing Exif information will be disabled!\n\n";
            $exiftool = FALSE;
        }

        #libgtk2-appindicator-perl
        eval { require Gtk2::AppIndicator };
        if ($@) {
            warn "WARNING: Gtk2::AppIndicator is missing --> there will be no icon showing up in the status bar when running Unity!\n\n";
            $appindicator = FALSE;
        }

        return TRUE;
    }

    sub fct_control_wm_settings {
        my $mode          = shift;
        my $restore_value = shift;

        #compiz via dbus
        my $bus    = undef;
        my $compiz = undef;
        my $fpl    = undef;

        #disable focus_prevention
        my $curr_value = -1;

        #disable focus prevention when using compiz
        eval {
            $bus = Net::DBus->find;

            #Get a handle to the compiz service
            $compiz = $bus->get_service("org.freedesktop.compiz");

            #Get the relevant object
            $fpl = $compiz->get_object( "/org/freedesktop/compiz/core/screen0/focus_prevention_level", "org.freedesktop.compiz" );
        };
        if ($@) {
            warn "INFO: DBus connection to org.freedesktop.compiz failed --> skipping compiz related tasks\n\n";
            warn $@ . "\n\n";
            return $curr_value;
        }

        if ( defined $fpl && $fpl ) {
            eval {
                if ( $mode eq 'start' )
                {

                    #save and return current value
                    if ( defined $fpl && $fpl ) {
                        $curr_value = $fpl->get;
                    }
                    if ( defined $fpl && $fpl && $fpl->get != 0 ) {
                        $fpl->set(0);
                    }

                    #re-enable focus prevention -> restore value
                }
                elsif ( $mode eq 'stop' ) {
                    if ( defined $fpl && $fpl && defined $restore_value ) {
                        $fpl->set($restore_value);
                    }
                    elsif ( defined $fpl && $fpl ) {
                        $fpl->set(1);
                    }
                }
            };
            if ($@) {
                warn "ERROR: Unable to set/get focus_level_prevention --> skipping compiz related tasks\n\n";
                warn $@ . "\n\n";
            }
        }

        return $curr_value;
    }

    sub fct_init_environment {

        #is there already a .shutter folder?
        mkdir("$ENV{ 'HOME' }/.shutter")
          unless ( -d "$ENV{ 'HOME' }/.shutter" );

        #...and a profiles folder?
        mkdir "$ENV{'HOME'}/.shutter/profiles"
          unless ( -d "$ENV{'HOME'}/.shutter/profiles" );

        return TRUE;
    }

    sub fct_init_unsaved_files {

        #delete all files in this folder
        #except the ones that are in the current session
        my @unsaved_files = glob( $sdir->get_cache_dir . "/*" );
        foreach my $unsaved_file (@unsaved_files) {
            utf8::decode $unsaved_file;
            print $unsaved_file, " checking \n" if $sc->get_debug;
            unless ( &fct_get_key_by_filename($unsaved_file) ) {
                print $unsaved_file, " deleted \n" if $sc->get_debug;
                unlink $unsaved_file;
            }
        }
    }

    sub fct_init_debug_output {

        print "\nINFO: gathering system information...";
        print "\n";
        print "\n";

        #kernel info
        if ( File::Which::which('uname') ) {
            print `uname -a`, "\n";
        }

        #issue
        if ( -f '/etc/issue' ) {
            if ( File::Which::which('cat') ) {
                print `cat /etc/issue`, "\n";
            }
        }

        printf "Glib %s \n", $Glib::VERSION;
        printf "Gtk2 %s \n", $Gtk2::VERSION;
        print "\n";

        # The version info stuff appeared in 1.040.
        print "Glib built for " . join( ".", Glib->GET_VERSION_INFO ) . ", running with " . join( ".", &Glib::major_version, &Glib::minor_version, &Glib::micro_version ) . "\n"
          if $Glib::VERSION >= 1.040;
        print "Gtk2 built for " . join( ".", Gtk2->GET_VERSION_INFO ) . ", running with " . join( ".", &Gtk2::major_version, &Gtk2::minor_version, &Gtk2::micro_version ) . "\n"
          if $Gtk2::VERSION >= 1.040;
        print "\n";

        return TRUE;
    }

    #--------------------------------------

    #dialogs
    #--------------------------------------

    sub dlg_rename {
        my (@file_to_rename_keys) = @_;

        foreach my $key (@file_to_rename_keys) {

            my $input_dialog = Gtk2::MessageDialog->new( $window, [qw/modal destroy-with-parent/], 'other', 'none', undef );

            $input_dialog->set_title( $d->get("Rename") );

            $input_dialog->set( 'image' => Gtk2::Image->new_from_stock( 'gtk-save-as', 'dialog' ) );

            $input_dialog->set( 'text' => sprintf( $d->get("Rename image %s"), "'$session_screens{$key}->{'short'}'" ) );

            $input_dialog->set( 'secondary-text' => $d->get("New filename") . ": " );

            #rename button
            my $rename_btn = Gtk2::Button->new_with_mnemonic( $d->get("_Rename") );
            $rename_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-save-as', 'button' ) );
            $rename_btn->can_default(TRUE);

            $input_dialog->add_button( 'gtk-cancel', 'reject' );
            $input_dialog->add_action_widget( $rename_btn, 'accept' );

            $input_dialog->set_default_response('accept');

            my $new_filename_vbox = Gtk2::VBox->new();
            my $new_filename_hint = Gtk2::Label->new();
            my $new_filename      = Gtk2::Entry->new();
            $new_filename->set_activates_default(TRUE);

            #here are all invalid char codes
            my @invalid_codes = ( 47, 92, 63, 37, 42, 58, 124, 34, 60, 62, 44, 59, 35, 38 );
            $new_filename->signal_connect(
                'key-press-event' => sub {
                    my $new_filename = shift;
                    my $event        = shift;

                    my $input = Gtk2::Gdk->keyval_to_unicode( $event->keyval );

                    #invalid input
                    #~ print $input."\n";
                    if ( grep( $input == $_, @invalid_codes ) ) {
                        my $char = chr($input);
                        $char = '&amp;' if $char eq '&';
                        $new_filename_hint->set_markup( "<span size='small'>" . sprintf( $d->get("Reserved character %s is not allowed to be in a filename."), "'" . $char . "'" ) . "</span>" );
                        return TRUE;
                    }
                    else {

                        #clear possible message when valid char is entered
                        $new_filename_hint->set_markup("<span size='small'></span>");
                        return FALSE;
                    }
                }
            );

            #parse filename
            my ( $short, $folder, $ext ) = fileparse( $session_screens{$key}->{'long'}, qr/\.[^.]*/ );

            #enable/disable rename button
            #e.g. if no text is in entry
            $new_filename->signal_connect(
                'changed' => sub {
                    my $temp_filename = $new_filename->get_text;
                    if ( length($temp_filename) ) {
                        $rename_btn->set_sensitive(TRUE);

                        #Bug #1087367
                        if ( $temp_filename =~ /.*$ext$/ ) {
                            my ( $short, $folder, $ext ) = fileparse( $temp_filename, qr/\.[^.]*/ );
                            $new_filename->set_text($short);
                        }
                    }
                    else {
                        $rename_btn->set_sensitive(FALSE);
                    }
                    return TRUE;
                }
            );

            #show just the name of the image
            $new_filename->set_text( $session_screens{$key}->{'name'} );
            if ( length( $new_filename->get_text ) ) {
                $rename_btn->set_sensitive(TRUE);
            }
            else {
                $rename_btn->set_sensitive(FALSE);
            }

            $new_filename_vbox->pack_start_defaults($new_filename);
            $new_filename_vbox->pack_start_defaults($new_filename_hint);
            $input_dialog->vbox->add($new_filename_vbox);
            $input_dialog->show_all;

            #run dialog
            my $input_response = $input_dialog->run;

            #handle user responses here
            if ( $input_response eq 'accept' ) {

                my $new_name = $new_filename->get_text;
                $new_name = $session_screens{$key}->{'folder'} . "/" . $new_name . "." . $session_screens{$key}->{'filetype'};

                #create uris for following action (e.g. update tab, move etc.)
                my $new_uri = Gnome2::VFS::URI->new($new_name);
                my $old_uri = $session_screens{$key}->{'uri'};

                if ($new_uri) {

                    #filenames eq? -> nothing to do here
                    unless ( $session_screens{$key}->{'long'} eq $new_name ) {

                        #does the "renamed" file already exists?
                        unless ( $shf->file_exists($new_name) ) {

                            #ok => rename it

                            #cancel handle
                            if ( exists $session_screens{$key}->{'handle'} ) {

                                $session_screens{$key}->{'handle'}->cancel;
                            }

                            my $result = $old_uri->move( $new_uri, TRUE );
                            if ( $result eq 'ok' ) {

                                &fct_update_tab( $key, undef, $new_uri, FALSE, 'block' );

                                #setup a new filemonitor, so we get noticed if the file changed
                                &fct_add_file_monitor($key);

                                &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("renamed") );

                                #change window title
                                #~ $window->set_title($session_screens{$key}->{'long'}." - ".SHUTTER_NAME);

                            }
                            else {

                                my $response = $sd->dlg_error_message( sprintf( $d->get("Error while renaming the image %s."), "'" . $old_uri->extract_short_name . "'" ), sprintf( $d->get("There was an error renaming the image to %s."), "'" . $new_uri->extract_short_name . "'" ), undef, undef, undef, undef, undef, undef, Gnome2::VFS->result_to_string($result) );

                            }

                        }
                        else {

                            #ask the user to replace the image
                            #replace button
                            my $replace_btn = Gtk2::Button->new_with_mnemonic( $d->get("_Replace") );
                            $replace_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-save-as', 'button' ) );

                            my $sd = Shutter::App::SimpleDialogs->new;

                            my $response = $sd->dlg_warning_message( sprintf( $d->get("The image already exists in %s. Replacing it will overwrite its contents."), "'" . $new_uri->extract_dirname . "'" ), sprintf( $d->get("An image named %s already exists. Do you want to replace it?"), "'" . $new_uri->extract_short_name . "'" ), undef, undef, undef, $replace_btn, undef, undef );

                            #rename == replace_btn was hit
                            if ( $response == 40 ) {

                                #ok => rename it

                                #cancel handle
                                if ( exists $session_screens{$key}->{'handle'} ) {

                                    $session_screens{$key}->{'handle'}->cancel;
                                }

                                my $result = $old_uri->move( $new_uri, TRUE );
                                if ( $result eq 'ok' ) {

                                    &fct_update_tab( $key, undef, $new_uri, FALSE, 'block' );

                                    #setup a new filemonitor, so we get noticed if the file changed
                                    &fct_add_file_monitor($key);

                                    &fct_show_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("renamed") );

                                    #change window title
                                    #~ $window->set_title($session_screens{$key}->{'long'}." - ".SHUTTER_NAME);

                                }
                                else {

                                    my $response = $sd->dlg_error_message( sprintf( $d->get("Error while renaming the image %s."), "'" . $old_uri->extract_short_name . "'" ), sprintf( $d->get("There was an error renaming the image to %s."), "'" . $new_uri->extract_short_name . "'" ), undef, undef, undef, undef, undef, undef, Gnome2::VFS->result_to_string($result) );

                                }

                                #maybe file is in session as well, need to set the handler again ;-)
                                foreach my $searchkey ( keys %session_screens ) {
                                    next if $key eq $searchkey;
                                    if ( $session_screens{$searchkey}->{'long'} eq $new_name ) {

                                        #cancel handle
                                        if ( exists $session_screens{$searchkey}->{'handle'} ) {

                                            $session_screens{$searchkey}->{'handle'}->cancel;
                                        }

                                        &fct_update_tab( $searchkey, undef, $new_uri, FALSE, 'block' );

                                        #setup a new filemonitor, so we get noticed if the file changed
                                        &fct_add_file_monitor($searchkey);

                                    }
                                }
                                $input_dialog->destroy();
                                next;
                            }
                            $input_dialog->destroy();
                            next;
                        }

                    }

                }
                else {

                    #uri object could not be created
                    #=> uri illegal
                    my $response = $sd->dlg_error_message( sprintf( $d->get("Error while renaming the image %s."), "'" . $old_uri->extract_short_name . "'" ), sprintf( $d->get("There was an error renaming the image to %s."), "'" . $new_name . "'" ), undef, undef, undef, undef, undef, undef, $d->get("Invalid Filename") );

                }

            }

            $input_dialog->destroy();
            next;

        }

    }

    sub dlg_open {
        my ( $widget, $data ) = @_;
        print "\n$data was emitted by widget $widget\n"
          if $sc->get_debug;

        #do we need to open a filechooserdialog?
        #maybe we open a recently opened file that is
        #selected via menu
        my @new_files;
        unless ( $widget =~ /Gtk2::RecentChooserMenu/ ) {
            my $fs = Gtk2::FileChooserDialog->new(
                $d->get("Choose file to open"), $window,
                'open',
                'gtk-cancel' => 'reject',
                'gtk-open'   => 'accept'
            );
            $fs->set_select_multiple(TRUE);

            #preview widget
            my $iprev = Gtk2::Image->new;
            $fs->set_preview_widget($iprev);

            $fs->signal_connect(
                'selection-changed' => sub {
                    if ( my $pfilename = $fs->get_preview_filename ) {

                        #without error dialog
                        my $pixbuf = $lp_ne->load( $pfilename, 200, 200, TRUE, TRUE );
                        unless ( defined $pixbuf ) {
                            $fs->set_preview_widget_active(FALSE);
                        }
                        else {
                            $fs->get_preview_widget->set_from_pixbuf($pixbuf);
                            $fs->set_preview_widget_active(TRUE);
                        }
                    }
                    else {
                        $fs->set_preview_widget_active(FALSE);
                    }
                }
            );

            my $filter_all = Gtk2::FileFilter->new;
            $filter_all->set_name( $d->get("All compatible image formats") );
            $fs->add_filter($filter_all);

            foreach my $format ( Gtk2::Gdk::Pixbuf->get_formats ) {
                my $filter = Gtk2::FileFilter->new;

                #add all known formats to the dialog
                $filter->set_name( $format->{name} . " - " . $format->{description} );

                foreach my $ext ( @{ $format->{extensions} } ) {
                    $filter->add_pattern( "*." . uc $ext );
                    $filter_all->add_pattern( "*." . uc $ext );
                    $filter->add_pattern( "*." . $ext );
                    $filter_all->add_pattern( "*." . $ext );
                }
                $fs->add_filter($filter);
            }

            #set default filter
            $fs->set_filter($filter_all);

            #get current file
            my $key = &fct_get_current_file;

            #go to recently used folder
            if ( defined $sc->get_ruof && $shf->folder_exists( $sc->get_ruof ) ) {
                $fs->set_current_folder( $sc->get_ruof );
            }
            else {
                if ($key) {
                    $fs->set_filename( $session_screens{$key}->{'long'} );
                }
                elsif ( $saveDir_button->get_filename ) {
                    $fs->set_current_folder( $saveDir_button->get_filename );
                }
                else {
                    $fs->set_current_folder( $ENV{'HOME'} );
                }
            }

            my $fs_resp = $fs->run;

            if ( $fs_resp eq "accept" ) {
                @new_files = $fs->get_filenames;

                #keep folder in mind
                if ( $new_files[0] ) {
                    my ( $oshort, $ofolder, $oext ) = fileparse( $new_files[0], qr/\.[^.]*/ );
                    $sc->set_ruof($ofolder) if defined $ofolder;
                }

                $fs->destroy();
            }
            else {
                $fs->destroy();
            }

        }
        else {
            print "Trying to open file via RecentChooserMenu ", $sm->{_menu_recent}->get_current_item->get_uri, "\n"
              if $sc->get_debug;
            push @new_files, $sm->{_menu_recent}->get_current_item->get_uri;
        }

        #call function to open files - with progress bar etc.
        &fct_open_files(@new_files);

        return TRUE;
    }

    sub dlg_save_as {

        #mandatory
        my $key = shift;

        #optional
        my $rfiletype = shift;
        my $rfilename = shift;
        my $rpixbuf   = shift;
        my $rquality  = shift;

        $rfilename = $session_screens{$key}->{'long'} if $key;

        my $fs = Gtk2::FileChooserDialog->new(
            $d->get("Choose a location to save to"),
            $window, 'save',
            'gtk-cancel' => 'reject',
            'gtk-save'   => 'accept'
        );

        #parse filename
        my ( $short, $folder, $ext ) = fileparse( $rfilename, qr/\.[^.]*/ );

        #go to recently used folder
        if ( defined $sc->get_rusf && $shf->folder_exists( $sc->get_rusf ) ) {
            $fs->set_current_folder( $sc->get_rusf );
            $fs->set_current_name( $short . $ext );
        }
        elsif (defined $key
            && defined $session_screens{$key}->{'is_unsaved'}
            && $session_screens{$key}->{'is_unsaved'} )
        {
            $fs->set_current_folder( $saveDir_button->get_current_folder );
            $fs->set_current_name( $short . $ext );
        }
        else {
            $fs->set_current_folder($folder);
            $fs->set_current_name( $short . $ext );
        }

        #preview widget
        my $iprev = Gtk2::Image->new;
        $fs->set_preview_widget($iprev);

        $fs->signal_connect(
            'selection-changed' => sub {
                if ( my $pfilename = $fs->get_preview_filename ) {

                    #without error dialog
                    my $pixbuf = $lp_ne->load( $pfilename, 200, 200, TRUE, TRUE );
                    unless ( defined $pixbuf ) {
                        $fs->set_preview_widget_active(FALSE);
                    }
                    else {
                        $fs->get_preview_widget->set_from_pixbuf($pixbuf);
                        $fs->set_preview_widget_active(TRUE);
                    }
                }
                else {
                    $fs->set_preview_widget_active(FALSE);
                }
            }
        );

        #change extension related to the requested filetype
        if ( defined $rfiletype && defined $rfilename ) {
            my ( $short, $folder, $ext ) = fileparse( $rfilename, qr/\.[^.]*/ );
            $fs->set_current_name( $short . "." . $rfiletype );
        }

        my $extra_hbox = Gtk2::HBox->new;

        my $label_save_as_type = Gtk2::Label->new( $d->get("Image format") . ":" );

        my $combobox_save_as_type = Gtk2::ComboBox->new_text;

        #add supported formats to combobox
        my $counter     = 0;
        my $png_counter = undef;

        #add pdf support
        if ( defined $rfiletype && $rfiletype eq 'pdf' ) {

            $combobox_save_as_type->insert_text( $counter, "pdf - Portable Document Format" );
            $combobox_save_as_type->set_active(0);

        }
        elsif ( defined $rfiletype && $rfiletype eq 'ps' ) {

            $combobox_save_as_type->insert_text( $counter, "ps - PostScript" );
            $combobox_save_as_type->set_active(0);

            #images
        }
        else {

            foreach my $format ( Gtk2::Gdk::Pixbuf->get_formats ) {

                #we don't want svg here - this is a dedicated action in the DrawingTool
                next if !defined $rfiletype && $format->{name} =~ /svg/;

                #we have a requested filetype - nothing else will be offered
                next if defined $rfiletype && $format->{name} ne $rfiletype;

                #we want jpg not jpeg
                if ( $format->{name} eq "jpeg" || $format->{name} eq "jpg" ) {
                    $combobox_save_as_type->insert_text( $counter, "jpg" . " - " . $format->{description} );
                }
                else {
                    $combobox_save_as_type->insert_text( $counter, $format->{name} . " - " . $format->{description} );
                }

                #set active when mime_type is matching
                #loop because multiple mime types are registered for fome file formats
                foreach my $mime ( @{ $format->{mime_types} } ) {

                    if ( defined $key ) {
                        if ( $mime eq $session_screens{$key}->{'mime_type'}
                            || defined $rfiletype )
                        {
                            $combobox_save_as_type->set_active($counter);
                        }
                    }
                    else {

                        #Fix Bug #966159
                        if ( defined $rfilename ) {
                            my ( $short, $folder, $ext ) = fileparse( $rfilename, qr/\.[^.]*/ );
                            if ( $mime eq "image/jpeg" && $ext eq ".jpg" ) {
                                $combobox_save_as_type->set_active($counter);
                            }
                            elsif ( $mime eq "image/png" && $ext eq ".png" ) {
                                $combobox_save_as_type->set_active($counter);
                            }
                            elsif ( $mime eq "image/bmp" && $ext eq ".bmp" ) {
                                $combobox_save_as_type->set_active($counter);
                            }
                        }
                    }

                    #save png_counter as well as fallback
                    $png_counter = $counter if $mime eq 'image/png';
                }

                $counter++;

            }

        }

        #something went wrong here
        #filetype was not detected automatically
        #set to png as default
        unless ( $combobox_save_as_type->get_active_text ) {
            if ( defined $png_counter ) {
                $combobox_save_as_type->set_active($png_counter);
            }
        }

        $combobox_save_as_type->signal_connect(
            'changed' => sub {
                my $filename = $fs->get_filename;

                my $choosen_format = $combobox_save_as_type->get_active_text;
                $choosen_format =~ s/ \-.*//;    #get png or jpeg (jpg) for example
                                                 #~ print $choosen_format . "\n";

                #parse filename
                my ( $short, $folder, $ext ) = fileparse( $filename, qr/\.[^.]*/ );

                $fs->set_current_name( $short . "." . $choosen_format );
            }
        );

        #emit the signal once in order to invoke the sub above
        #~ $combobox_save_as_type->signal_emit('changed');

        $extra_hbox->pack_start( $label_save_as_type,    FALSE, FALSE, 5 );
        $extra_hbox->pack_start( $combobox_save_as_type, FALSE, FALSE, 5 );

        my $align_save_as_type = Gtk2::Alignment->new( 1, 0, 0, 0 );

        $align_save_as_type->add($extra_hbox);
        $align_save_as_type->show_all;

        $fs->set_extra_widget($align_save_as_type);

        my $fs_resp = $fs->run;

        if ( $fs_resp eq "accept" ) {
            my $filename = $fs->get_filename;

            #parse filename
            my ( $short, $folder, $ext ) = fileparse( $filename, qr/\.[^.]*/ );

            #keep selected folder in mind
            $sc->set_rusf($folder);

            #handle file format
            my $choosen_format = $combobox_save_as_type->get_active_text;
            $choosen_format =~ s/ \-.*//;    #get png or jpeg (jpg) for example

            $filename = $folder . $short . "." . $choosen_format;

            unless ( $shf->file_exists($filename) ) {

                #get pixbuf from param
                my $pixbuf = $rpixbuf;
                unless ($pixbuf) {

                    #or load pixbuf from existing file
                    $pixbuf = $lp_ne->load($rfilename);
                }

                #save as (pixbuf, new_filename, filetype, quality - auto here, old_filename)
                if ( $sp->save_pixbuf_to_file( $pixbuf, $filename, $choosen_format, $rquality ) ) {

                    if ($key) {

                        #do not try to update when exporting to pdf or ps
                        unless ( defined $rfiletype
                            && ( $rfiletype eq 'pdf' || $rfiletype eq 'ps' ) )
                        {

                            #cancel handle
                            if ( exists $session_screens{$key}->{'handle'} ) {

                                $session_screens{$key}->{'handle'}->cancel;
                            }
                            if ( &fct_update_tab( $key, undef, Gnome2::VFS::URI->new($filename), FALSE, 'clear' ) ) {

                                #setup a new filemonitor, so we get noticed if the file changed
                                &fct_add_file_monitor($key);

                                &fct_show_status_message( 1, "$session_screens{ $key }->{ 'long' } " . $d->get("saved") );
                            }

                        }
                        else {
                            if ( $shf->file_exists($filename) ) {
                                &fct_show_status_message( 1, "$filename " . $d->get("saved") );
                            }
                        }

                    }

                    #successfully saved
                    $fs->destroy();
                    return $filename;

                }
                else {

                    #error while saving
                    $fs->destroy();
                    return FALSE;

                }

            }
            else {

                #ask the user to replace the image
                #replace button
                my $replace_btn = Gtk2::Button->new_with_mnemonic( $d->get("_Replace") );
                $replace_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-save-as', 'button' ) );

                my $response = $sd->dlg_warning_message( sprintf( $d->get("The image already exists in %s. Replacing it will overwrite its contents."), "'" . $folder . "'" ), sprintf( $d->get("An image named %s already exists. Do you want to replace it?"), "'" . $short . "." . $choosen_format . "'" ), undef, undef, undef, $replace_btn, undef, undef );

                if ( $response == 40 ) {

                    #get pixbuf from param
                    my $pixbuf = $rpixbuf;
                    unless ($pixbuf) {

                        #or load pixbuf from existing file
                        $pixbuf = $lp_ne->load($rfilename);
                    }

                    if ( $sp->save_pixbuf_to_file( $pixbuf, $filename, $choosen_format, $rquality ) ) {

                        if ($key) {

                            #do not try to update when exporting to pdf
                            unless ( defined $rfiletype
                                && ( $rfiletype eq 'pdf' || $rfiletype eq 'ps' ) )
                            {

                                #cancel handle
                                if ( exists $session_screens{$key}->{'handle'} ) {

                                    $session_screens{$key}->{'handle'}->cancel;
                                }

                                if ( &fct_update_tab( $key, undef, Gnome2::VFS::URI->new($filename), FALSE, 'clear' ) ) {

                                    #setup a new filemonitor, so we get noticed if the file changed
                                    &fct_add_file_monitor($key);

                                    #maybe file is in session as well, need to set the handler again ;-)
                                    foreach my $searchkey ( keys %session_screens ) {
                                        next if $key eq $searchkey;
                                        if ( $session_screens{$searchkey}->{'long'} eq $filename ) {
                                            $session_screens{$searchkey}->{'changed'} = TRUE;
                                            &fct_update_tab( $searchkey, undef, undef, FALSE, 'clear' );
                                        }
                                    }

                                    &fct_show_status_message( 1, "$session_screens{ $key }->{ 'long' } " . $d->get("saved") );

                                }

                            }
                            else {
                                if ( $shf->file_exists($filename) ) {
                                    &fct_show_status_message( 1, "$filename " . $d->get("saved") );
                                }
                            }

                        }    #end if $key

                        #successfully saved
                        $fs->destroy();
                        return $filename;

                    }
                    else {

                        #error while saving
                        $fs->destroy();
                        return FALSE;

                    }

                }
                else {

                    #user cancelled overwrite
                    $fs->destroy();
                    return 'user_cancel';

                }

            }

        }
        else {

            #user cancelled
            $fs->destroy();
            return 'user_cancel';
        }

        $fs->destroy();

    }

    sub dlg_plugin {
        my (@file_to_plugin_keys) = @_;

        my $plugin_dialog = Gtk2::Dialog->new( $d->get("Choose a plugin"), $window, [qw/modal destroy-with-parent/] );
        $plugin_dialog->set_size_request( 350, -1 );
        $plugin_dialog->set_resizable(FALSE);

        #rename button
        my $run_btn = Gtk2::Button->new_with_mnemonic( $d->get("_Run") );
        $run_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-execute', 'button' ) );
        $run_btn->can_default(TRUE);

        $plugin_dialog->add_button( 'gtk-cancel', 'reject' );
        $plugin_dialog->add_action_widget( $run_btn, 'accept' );

        $plugin_dialog->set_default_response('accept');

        my $model = Gtk2::ListStore->new( 'Gtk2::Gdk::Pixbuf', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String' );

        #temp variables to restore the
        #recent plugin
        my $recent_time        = 0;
        my $iter_lastex_plugin = undef;
        foreach my $pkey ( sort keys %plugins ) {

            #check if plugin allows current filetype
            #~ my $nfiles_ok += scalar grep($plugins{$pkey}->{'ext'} =~ /$session_screens{$_}->{'mime_type'}/, @file_to_plugin_keys);
            #~ next if scalar @file_to_plugin_keys > $nfiles_ok;

            if ( $plugins{$pkey}->{'binary'} ne "" ) {

                my $new_iter = $model->append;
                $model->set( $new_iter, 0, $plugins{$pkey}->{'pixbuf_object'}, 1, $plugins{$pkey}->{'name'}, 2, $plugins{$pkey}->{'binary'}, 3, $plugins{$pkey}->{'lang'}, 4, $plugins{$pkey}->{'tooltip'}, 5, $pkey );

                #initialize $iter_lastex_plugin
                #with first new iter
                $iter_lastex_plugin = $new_iter
                  unless defined $iter_lastex_plugin;

                #restore the recent plugin
                #($plugins{$plugin_key}->{'recent'} is a timestamp)
                #
                #we keep the new_iter in mind
                if ( defined $plugins{$pkey}->{'recent'}
                    && $plugins{$pkey}->{'recent'} > $recent_time )
                {
                    $iter_lastex_plugin = $new_iter;
                    $recent_time        = $plugins{$pkey}->{'recent'};
                }

            }
            else {
                print "WARNING: Program $pkey is not configured properly, ignoring\n";
            }

        }

        my $plugin_label = Gtk2::Label->new( $d->get("Plugin") . ":" );
        my $plugin       = Gtk2::ComboBox->new($model);

        #plugin description
        my $plugin_descr      = Gtk2::TextBuffer->new;
        my $plugin_descr_view = Gtk2::TextView->new_with_buffer($plugin_descr);
        $plugin_descr_view->set_sensitive(FALSE);
        $plugin_descr_view->set_wrap_mode('word');
        my $textview_hbox = Gtk2::HBox->new( FALSE, 5 );
        $textview_hbox->set_border_width(8);
        $textview_hbox->pack_start_defaults($plugin_descr_view);

        my $plugin_descr_label = Gtk2::Label->new();
        $plugin_descr_label->set_markup( "<b>" . $d->get("Description") . "</b>" );
        my $plugin_descr_frame = Gtk2::Frame->new();
        $plugin_descr_frame->set_label_widget($plugin_descr_label);
        $plugin_descr_frame->set_shadow_type('none');
        $plugin_descr_frame->add($textview_hbox);

        #plugin image
        my $plugin_image = Gtk2::Image->new;

        #packing
        my $plugin_vbox1 = Gtk2::VBox->new( FALSE, 5 );
        my $plugin_hbox1 = Gtk2::HBox->new( FALSE, 5 );
        my $plugin_hbox2 = Gtk2::HBox->new( FALSE, 5 );
        $plugin_hbox2->set_border_width(10);

        #what plugin is selected?
        my $plugin_pixbuf = undef;
        my $plugin_name   = undef;
        my $plugin_value  = undef;
        my $plugin_lang   = undef;
        my $plugin_tip    = undef;
        my $plugin_key    = undef;
        $plugin->signal_connect(
            'changed' => sub {
                my $model       = $plugin->get_model();
                my $plugin_iter = $plugin->get_active_iter();

                if ($plugin_iter) {
                    $plugin_pixbuf = $model->get_value( $plugin_iter, 0 );
                    $plugin_name   = $model->get_value( $plugin_iter, 1 );
                    $plugin_value  = $model->get_value( $plugin_iter, 2 );
                    $plugin_lang   = $model->get_value( $plugin_iter, 3 );
                    $plugin_tip    = $model->get_value( $plugin_iter, 4 );
                    $plugin_key    = $model->get_value( $plugin_iter, 5 );

                    $plugin_descr->set_text($plugin_tip);
                    if ( $shf->file_exists( $plugins{$plugin_key}->{'pixbuf'} ) ) {
                        $plugin_image->set_from_pixbuf( $lp->load( $plugins{$plugin_key}->{'pixbuf'}, 100, 100 ) );
                    }
                }
            }
        );

        my $renderer_pix = Gtk2::CellRendererPixbuf->new;
        $plugin->pack_start( $renderer_pix, FALSE );
        $plugin->add_attribute( $renderer_pix, pixbuf => 0 );
        my $renderer_text = Gtk2::CellRendererText->new;
        $plugin->pack_start( $renderer_text, FALSE );
        $plugin->add_attribute( $renderer_text, text => 1 );

        #we try to activate the last executed plugin if that's possible
        $plugin->set_active_iter($iter_lastex_plugin);

        $plugin_hbox1->pack_start_defaults($plugin);

        $plugin_hbox2->pack_start_defaults($plugin_image);
        $plugin_hbox2->pack_start_defaults($plugin_descr_frame);

        $plugin_vbox1->pack_start( $plugin_hbox1, FALSE, TRUE, 1 );
        $plugin_vbox1->pack_start( $plugin_hbox2, TRUE,  TRUE, 1 );

        $plugin_dialog->vbox->add($plugin_vbox1);

        my $plugin_progress = Gtk2::ProgressBar->new;
        $plugin_progress->set_no_show_all(TRUE);
        $plugin_progress->set_ellipsize('middle');
        $plugin_progress->set_orientation('left-to-right');
        $plugin_dialog->vbox->add($plugin_progress);

        $plugin_dialog->show_all;

        my $plugin_response = $plugin_dialog->run;

        if ( $plugin_response eq 'accept' ) {

            #anything wrong with the selected plugin?
            unless ( $plugin_value =~ /[a-zA-Z0-9]+/ ) {
                $sd->dlg_error_message( $d->get("No plugin specified"), $d->get("Failed") );
                return FALSE;
            }

            #we save the last execution time
            #and try to preselect it when the plugin dialog is executed again
            $plugins{$plugin_key}->{'recent'} = time;

            #disable buttons and combobox
            $plugin->set_sensitive(FALSE);
            foreach my $dialog_child ( $plugin_dialog->vbox->get_children ) {
                $dialog_child->set_sensitive(FALSE)
                  if $dialog_child =~ /Button/;
            }

            #show the progress bar
            $plugin_progress->show;
            $plugin_progress->set_fraction(0);
            &fct_update_gui;
            my $counter = 1;

            #call execute_plugin for each file to be processed
            foreach my $key (@file_to_plugin_keys) {

                #update the progress bar and update gui to show changes
                #~ $plugin_progress->set_text($session_screens{$key}->{'long'});
                #~ $plugin_progress->set_fraction($counter / scalar @file_to_plugin_keys);
                #~ &fct_update_gui;

                #store data
                my $data = [ $plugin_value, $plugin_name, $plugin_lang, $key, $plugin_dialog, $plugin_progress ];
                &fct_execute_plugin( undef, $data );

                #increase counter and update gui to show updated progress bar
                $counter++;
            }

            $plugin_dialog->destroy();
            return TRUE;
        }
        else {
            $plugin_dialog->destroy();
            return FALSE;
        }
    }

    sub dlg_upload {
        my (@files_to_upload) = @_;

        return FALSE if @files_to_upload < 1;

        my $dlg_header = $d->get("Upload / Export");
        my $hosting_dialog = Gtk2::Dialog->new( $dlg_header, $window, [qw/modal destroy-with-parent/] );

        my $close_button  = $hosting_dialog->add_button( 'gtk-close',        'close' );
        my $upload_button = $hosting_dialog->add_button( $d->get("_Upload"), 'accept' );
        $upload_button->set_image( Gtk2::Image->new_from_stock( 'gtk-go-up', 'button' ) );
        $hosting_dialog->set_default_response('accept');

        my $model = Gtk2::ListStore->new( 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String' );

        foreach ( keys %accounts ) {

            #cut username so the dialog will not explode ;-)
            my $short_username = $accounts{$_}->{'username'};
            if ( defined $accounts{$_}->{'username'}
                && length $accounts{$_}->{'username'} > 10 )
            {
                $short_username = substr( $accounts{$_}->{'username'}, 0, 10 ) . "...";
            }

            #Create Username/Password entry (if supported and supplied)
            if ( $accounts{$_}->{'supports_authorized_upload'} ) {
                if (   $accounts{$_}->{'username'} ne ""
                    && $accounts{$_}->{'password'} ne "" )
                {
                    $model->set( $model->append, 0, $accounts{$_}->{'module'}, 1, $accounts{$_}->{'username'}, 2, $accounts{$_}->{'password'}, 3, $short_username, 4, $accounts{$_}->{'module'}, 5, $accounts{$_}->{'folder'} );
                }
            }

            #Create Anonymous entry (if supported)
            if ( $accounts{$_}->{'supports_anonymous_upload'} ) {
                $model->set( $model->append, 0, $accounts{$_}->{'module'}, 1, $d->get("Guest"), 2, "", 3, $d->get("Guest"), 4, $accounts{$_}->{'module'}, 5, $accounts{$_}->{'folder'} );
            }

            #Create OAuth entry (if supported)
            if ( $accounts{$_}->{'supports_oauth_upload'} ) {
                $model->set( $model->append, 0, $accounts{$_}->{'module'}, 1, $d->get("OAuth"), 2, "", 3, $d->get("OAuth"), 4, $accounts{$_}->{'module'}, 5, $accounts{$_}->{'folder'} );
            }
        }

        my $hosting_image = Gtk2::Image->new;

        #set up account combobox
        my $hosting       = Gtk2::ComboBox->new($model);
        my $renderer_host = Gtk2::CellRendererText->new;
        $hosting->pack_start( $renderer_host, FALSE );
        $hosting->add_attribute( $renderer_host, text => 0 );

        my $renderer_username = Gtk2::CellRendererText->new;
        $hosting->pack_start( $renderer_username, FALSE );
        $hosting->add_attribute( $renderer_username, text => 3 );
        $hosting->set_active(0);

        #public hosting settings
        my $pub_hbox1      = Gtk2::HBox->new( FALSE, 0 );
        my $pub_hbox2      = Gtk2::HBox->new( FALSE, 0 );
        my $pub_hbox_hint  = Gtk2::HBox->new( FALSE, 0 );
        my $pub_hbox_hint2 = Gtk2::HBox->new( FALSE, 0 );
        my $pub_vbox1      = Gtk2::VBox->new( FALSE, 0 );

        my $pub_hint  = Gtk2::Label->new();
        my $pub_hint2 = Gtk2::Label->new();
        $pub_hint->set_line_wrap(TRUE);
        $pub_hint2->set_line_wrap(TRUE);
        if ( Gtk2->CHECK_VERSION( 2, 9, 0 ) ) {
            $pub_hint->set_line_wrap_mode('word-char');
            $pub_hint2->set_line_wrap_mode('word-char');
        }

        $pub_hint->set_markup( "<span size='small'>" . $d->get("Please choose one of the accounts above and click <i>Upload</i>. The upload links will still be available in the screenshot's <i>right-click menu</i> after closing this dialog.") . "</span>" );
        $pub_hint2->set_markup( "<span size='small'>" . $d->get("<b>Please note:</b> If a plugin allows only authorized uploading you need to enter your credentials in preferences first to make it appear in the list above.") . "</span>" );

        $pub_hbox1->pack_start( Gtk2::Label->new( $d->get("Choose account") . ":" ), FALSE, FALSE, 6 );
        $pub_hbox1->pack_start_defaults($hosting);
        $pub_hbox_hint->pack_start( $pub_hint, TRUE, TRUE, 6 );
        $pub_hbox_hint2->pack_start( $pub_hint2, TRUE, TRUE, 6 );

        $pub_hint->set_alignment( 0, 0.5 );
        $pub_hint2->set_alignment( 0, 0.5 );

        $pub_vbox1->pack_start( $pub_hbox1,      FALSE, FALSE, 3 );
        $pub_vbox1->pack_start( $pub_hbox_hint,  FALSE, FALSE, 3 );
        $pub_vbox1->pack_start( $pub_hbox_hint2, FALSE, FALSE, 3 );

        #places settings
        my $pl_hbox1 = Gtk2::HBox->new( FALSE, 0 );
        my $pl_vbox1 = Gtk2::VBox->new( FALSE, 0 );
        my $places_fc = Gtk2::FileChooserButton->new_with_backend( "Shutter - " . $d->get("Choose folder"), 'select-folder', 'gnome-vfs' );
        $places_fc->set( 'local-only' => FALSE );
        $pl_hbox1->pack_start( Gtk2::Label->new( $d->get("Choose folder") . ":" ), FALSE, FALSE, 6 );
        $pl_hbox1->pack_start_defaults($places_fc);
        $pl_vbox1->pack_start( $pl_hbox1, FALSE, FALSE, 3 );

        #ftp settings
        #we are using the same widgets as in the settings and populate
        #them with saved values when possible
        my $ftp_hbox1_dlg = Gtk2::HBox->new( FALSE, 0 );
        my $ftp_hbox2_dlg = Gtk2::HBox->new( FALSE, 0 );
        my $ftp_hbox3_dlg = Gtk2::HBox->new( FALSE, 0 );
        my $ftp_hbox4_dlg = Gtk2::HBox->new( FALSE, 0 );
        my $ftp_hbox5_dlg = Gtk2::HBox->new( FALSE, 0 );

        #uri
        my $ftp_entry_label_dlg = Gtk2::Label->new( $d->get("URI") . ":" );
        $ftp_hbox1_dlg->pack_start( $ftp_entry_label_dlg, FALSE, TRUE, 10 );
        my $ftp_remote_entry_dlg = Gtk2::Entry->new;
        $ftp_remote_entry_dlg->set_text( $ftp_remote_entry->get_text );

        $tooltips->set_tip( $ftp_entry_label_dlg, $d->get("URI\nExample: ftp://host:port/path") );

        $tooltips->set_tip( $ftp_remote_entry_dlg, $d->get("URI\nExample: ftp://host:port/path") );

        $ftp_hbox1_dlg->pack_start( $ftp_remote_entry_dlg, TRUE, TRUE, 10 );

        #connection mode
        my $ftp_mode_label_dlg = Gtk2::Label->new( $d->get("Connection mode") . ":" );
        $ftp_hbox2_dlg->pack_start( $ftp_mode_label_dlg, FALSE, TRUE, 10 );
        my $ftp_mode_combo_dlg = Gtk2::ComboBox->new_text;
        $ftp_mode_combo_dlg->insert_text( 0, $d->get("Active mode") );
        $ftp_mode_combo_dlg->insert_text( 1, $d->get("Passive mode") );
        $ftp_mode_combo_dlg->set_active( $ftp_mode_combo->get_active );

        $tooltips->set_tip( $ftp_mode_label_dlg, $d->get("Connection mode") );

        $tooltips->set_tip( $ftp_mode_combo_dlg, $d->get("Connection mode") );

        $ftp_hbox2_dlg->pack_start( $ftp_mode_combo_dlg, TRUE, TRUE, 10 );

        #username
        my $ftp_username_label_dlg = Gtk2::Label->new( $d->get("Username") . ":" );
        $ftp_hbox3_dlg->pack_start( $ftp_username_label_dlg, FALSE, TRUE, 10 );
        my $ftp_username_entry_dlg = Gtk2::Entry->new;
        $ftp_username_entry_dlg->set_text( $ftp_username_entry->get_text );

        $tooltips->set_tip( $ftp_username_label_dlg, $d->get("Username") );

        $tooltips->set_tip( $ftp_username_entry_dlg, $d->get("Username") );

        $ftp_hbox3_dlg->pack_start( $ftp_username_entry_dlg, TRUE, TRUE, 10 );

        #password
        my $ftp_password_label_dlg = Gtk2::Label->new( $d->get("Password") . ":" );
        $ftp_hbox4_dlg->pack_start( $ftp_password_label_dlg, FALSE, TRUE, 10 );
        my $ftp_password_entry_dlg = Gtk2::Entry->new;
        $ftp_password_entry_dlg->set_invisible_char("*");
        $ftp_password_entry_dlg->set_visibility(FALSE);
        $ftp_password_entry_dlg->set_text( $ftp_password_entry->get_text );

        $tooltips->set_tip( $ftp_password_label_dlg, $d->get("Password") );

        $tooltips->set_tip( $ftp_password_entry_dlg, $d->get("Password") );

        $ftp_hbox4_dlg->pack_start( $ftp_password_entry_dlg, TRUE, TRUE, 10 );

        #website url
        my $ftp_wurl_label_dlg = Gtk2::Label->new( $d->get("Website URL") . ":" );
        $ftp_hbox5_dlg->pack_start( $ftp_wurl_label_dlg, FALSE, TRUE, 10 );
        my $ftp_wurl_entry_dlg = Gtk2::Entry->new;
        $ftp_wurl_entry_dlg->set_text( $ftp_wurl_entry->get_text );

        $tooltips->set_tip( $ftp_wurl_label_dlg, $d->get("Website URL") );

        $tooltips->set_tip( $ftp_wurl_entry_dlg, $d->get("Website URL") );

        $ftp_hbox5_dlg->pack_start( $ftp_wurl_entry_dlg, TRUE, TRUE, 10 );

        my $ftp_vbox_dlg = Gtk2::VBox->new( FALSE, 0 );
        $ftp_vbox_dlg->pack_start( $ftp_hbox1_dlg, FALSE, TRUE, 3 );
        $ftp_vbox_dlg->pack_start( $ftp_hbox2_dlg, FALSE, TRUE, 3 );
        $ftp_vbox_dlg->pack_start( $ftp_hbox3_dlg, FALSE, TRUE, 3 );
        $ftp_vbox_dlg->pack_start( $ftp_hbox4_dlg, FALSE, TRUE, 3 );
        $ftp_vbox_dlg->pack_start( $ftp_hbox5_dlg, FALSE, TRUE, 3 );

        #all labels = one size
        $ftp_entry_label_dlg->set_alignment( 0, 0.5 );
        $ftp_mode_label_dlg->set_alignment( 0, 0.5 );
        $ftp_username_label_dlg->set_alignment( 0, 0.5 );
        $ftp_password_label_dlg->set_alignment( 0, 0.5 );
        $ftp_wurl_label_dlg->set_alignment( 0, 0.5 );

        my $sg_ftp_dlg = Gtk2::SizeGroup->new('horizontal');
        $sg_ftp_dlg->add_widget($ftp_entry_label_dlg);
        $sg_ftp_dlg->add_widget($ftp_mode_label_dlg);
        $sg_ftp_dlg->add_widget($ftp_username_label_dlg);
        $sg_ftp_dlg->add_widget($ftp_password_label_dlg);
        $sg_ftp_dlg->add_widget($ftp_wurl_label_dlg);

        #setup notebook
        my $unotebook = Gtk2::Notebook->new;
        $unotebook->append_page( $pub_vbox1,    $d->get("Public hosting") );
        $unotebook->append_page( $ftp_vbox_dlg, "FTP" );
        $unotebook->append_page( $pl_vbox1,     $d->get("Places") );
        $hosting_dialog->vbox->add($unotebook);

        my $hosting_progress = Gtk2::ProgressBar->new;
        $hosting_progress->set_no_show_all(TRUE);
        $hosting_progress->set_ellipsize('middle');
        $hosting_progress->set_orientation('left-to-right');
        $hosting_dialog->vbox->add($hosting_progress);

        $hosting_dialog->show_all;

        #restore recently used upload tab
        if ( defined $sc->get_ruu_tab && $sc->get_ruu_tab ) {
            $unotebook->set_current_page( $sc->get_ruu_tab );
        }

        #and the relevant detail (folder, uploader etc.)
        if ( defined $sc->get_ruu_hosting && $sc->get_ruu_hosting ) {
            $hosting->set_active( $sc->get_ruu_hosting );
        }
        else {
            $hosting->set_active(0);
        }
        if ( defined $sc->get_ruu_places
            && $shf->folder_exists( $sc->get_ruu_places ) )
        {
            $places_fc->set_current_folder( $sc->get_ruu_places );
        }

        #DIALOG RUN
        while ( my $hosting_response = $hosting_dialog->run ) {

            #start upload
            if ( $hosting_response eq "accept" ) {

                #running state of dialog
                $upload_button->set_sensitive(FALSE);
                $close_button->set_sensitive(FALSE);
                $hosting_progress->show;

                #public hosting
                #All modules must provide the following methods:
                # 1: init
                # 2: upload
                # 3: show
                # 4: show_all

                if ( $unotebook->get_current_page == 0 ) {

                    my $model            = $hosting->get_model();
                    my $hosting_iter     = $hosting->get_active_iter();
                    my $hosting_host     = $model->get_value( $hosting_iter, 0 );
                    my $hosting_username = $model->get_value( $hosting_iter, 1 );
                    my $hosting_password = $model->get_value( $hosting_iter, 2 );
                    my $hosting_module   = $model->get_value( $hosting_iter, 4 );
                    my $hosting_folder   = $model->get_value( $hosting_iter, 5 );

                    $hosting_progress->set_text( sprintf( $d->get("Loading module %s"), $hosting_module ) );
                    &fct_update_gui;

                    #import module
                    eval {
                        import lib $hosting_folder;
                        require "$hosting_module.pm";
                    };
                    if ($@) {

                        #dialogs (main window != parent window)
                        my $sd = Shutter::App::SimpleDialogs->new;

                        $sd->dlg_error_message( sprintf( $d->get("Error while executing upload plugin %s."), "'" . $hosting_module . "'" ), $d->get("There was an error executing the upload plugin."), undef, undef, undef, undef, undef, undef, $@ );
                        $hosting_dialog->destroy();
                        return FALSE;
                    }

                    my $uploader = $hosting_module->new( $hosting_host, $sc->get_debug, $shutter_root, $d, $window, SHUTTER_VERSION );

                    #init module
                    if ( $uploader->init ) {

                        my $counter = 1;
                        $hosting_progress->set_fraction(0);
                        foreach my $key ( sort @files_to_upload ) {

                            my $file = $session_screens{$key}->{'long'};

                            #set text for progressbar
                            $hosting_progress->set_text("Uploading $file");
                            &fct_update_gui;

                            #upload file
                            my %upload_response = $uploader->upload( $shf->switch_home_in_file($file), $hosting_username, $hosting_password );

                            if ( is_success( $upload_response{'status'} ) ) {

                                #add to public-links menu
                                foreach ( keys %upload_response ) {
                                    next if $_ eq 'status';
                                    $session_screens{$key}->{'links'}->{$hosting_module}->{$_} = $upload_response{$_};
                                    $session_screens{$key}->{'links'}->{$hosting_module}->{'menuentry'} = $hosting_module;
                                }

                                $uploader->show;
                                &fct_show_status_message( 1, $file . " " . $d->get("uploaded") );
                            }
                            else {
                                my $response = &dlg_upload_error_message( $upload_response{'status'}, $upload_response{'max_filesize'} );

                                #10 == skip all, 20 == skip, else == cancel
                                last if $response == 10;
                                next if $response == 20;
                                redo if $response == 30;
                                next;
                            }
                            $hosting_progress->set_fraction( $counter / @files_to_upload );

                            #update gui
                            &fct_update_gui;
                            $counter++;
                        }

                        $uploader->show_all;

                    }

                    #ftp
                }
                elsif ( $unotebook->get_current_page == 1 ) {

                    #create upload object
                    my $uploader = Shutter::Upload::FTP->new( $sc->get_debug, $shutter_root, $d, $window, $ftp_mode_combo_dlg->get_active );

                    my $counter = 1;
                    my $login   = FALSE;
                    $hosting_progress->set_fraction(0);

                    #start upload
                    foreach my $key ( sort @files_to_upload ) {

                        my $file = $session_screens{$key}->{'long'};

                        #need to login?
                        my @upload_response;
                        unless ($login) {

                            eval { $uploader->quit; };

                            @upload_response = $uploader->login( $ftp_remote_entry_dlg->get_text, $ftp_username_entry_dlg->get_text, $ftp_password_entry_dlg->get_text );

                            if ( $upload_response[0] ) {

                                #dialogs (main window != parent window)
                                my $sd = Shutter::App::SimpleDialogs->new;

                                #we already get translated error messaged back
                                my $response = $sd->dlg_error_message( $upload_response[1], $upload_response[0], undef, undef, undef, undef, undef, undef, $upload_response[2] );
                                next;
                            }
                            else {
                                $login = TRUE;
                            }

                        }

                        $hosting_progress->set_text($file);

                        #update gui
                        &fct_update_gui;
                        @upload_response = $uploader->upload( $shf->switch_home_in_file($file) );

                        #upload returns FALSE if there is no error
                        unless ( $upload_response[0] ) {

                            #everything is fine here
                            &fct_show_status_message( 1, $file . " " . $d->get("uploaded") );

                            #show as notification
                            my $notify = $sc->get_notification_object;
                            $notify->show( $d->get("Successfully uploaded"), sprintf( $d->get("The file %s was successfully uploaded."), $file ) );

                            #copy website url to clipboard
                            if ( $ftp_wurl_entry_dlg->get_text ) {
                                my $wuri = Gnome2::VFS::URI->new( $ftp_wurl_entry_dlg->get_text );

                                my ( $short, $folder, $ext ) = fileparse( $file, qr/\.[^.]*/ );
                                $wuri = $wuri->append_file_name( $short . $ext );
                                $clipboard->set_text( $wuri->to_string );
                                print "copied URI ", $wuri->to_string, " to clipboard\n"
                                  if $sc->get_debug;
                            }

                        }
                        else {

                            #dialogs (main window != parent window)
                            my $sd = Shutter::App::SimpleDialogs->new;

                            #we already get translated error messaged back
                            my $response = $sd->dlg_error_message( $upload_response[1], $upload_response[0], $d->get("Skip all"), $d->get("Skip"), $d->get("Retry"), undef, undef, undef, $upload_response[2] );

                            #10 == skip all, 20 == skip, 30 == redo, else == cancel
                            if ( $response == 10 ) {
                                last;
                            }
                            elsif ( $response == 20 ) {
                                $login = FALSE;
                                next;
                            }
                            elsif ( $response == 30 ) {
                                $login = FALSE;
                                redo;
                            }
                            else {
                                next;
                            }

                        }
                        $hosting_progress->set_fraction( $counter / @files_to_upload );

                        #update gui
                        &fct_update_gui;
                        $counter++;
                    }    #end foreach

                    eval { $uploader->quit; };

                    #xfer using Gnome-VFS
                }
                elsif ($unotebook->get_current_page == 2)
                {

                    my $counter = 1;
                    $hosting_progress->set_fraction(0);

                    #start upload
                    foreach my $key ( sort @files_to_upload ) {

                        my $file = $session_screens{$key}->{'long'};

                        $hosting_progress->set_text($file);

                        #update gui
                        &fct_update_gui;

                        my $source_uri = Gnome2::VFS::URI->new($file);

                        my $target_uri = Gnome2::VFS::URI->new( $places_fc->get_uri );
                        $target_uri = $target_uri->append_file_name( $source_uri->extract_short_name );

                        #~ print sprintf("%s und %s \n", $target_uri->to_string, $source_uri->to_string);

                        my $result;
                        unless ( Gnome2::VFS->unescape_string( $target_uri->to_string ) eq Gnome2::VFS->unescape_string( $source_uri->to_string ) ) {
                            unless ( $target_uri->exists ) {
                                $result = Gnome2::VFS::Xfer->uri( $source_uri, $target_uri, 'default', 'abort', 'replace', sub { return TRUE } );
                            }
                            else {
                                $result = 'error-file-exists';
                            }
                        }
                        else {
                            $result = 'ok';
                        }

                        #everything is fine here
                        if ( $result eq 'ok' ) {

							if ( $target_uri->is_local ) {
								&fct_show_status_message( 1, $file . " " . $d->get("exported") );

								#show as notification
								my $notify = $sc->get_notification_object;
								$notify->show( $d->get("Successfully exported"), sprintf( $d->get("The file %s was successfully exported."), $file ) );
							}
							else {
								&fct_show_status_message( 1, $file . " " . $d->get("uploaded") );

								#show as notification
								my $notify = $sc->get_notification_object;
								$notify->show( $d->get("Successfully uploaded"), sprintf( $d->get("The file %s was successfully uploaded."), $file ) );
							}

                        }
                        elsif ( $result eq 'error-file-exists' ) {

                            #ask the user to replace the image
                            #replace button
                            my $replace_btn = Gtk2::Button->new_with_mnemonic( $d->get("_Replace") );
                            $replace_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-save-as', 'button' ) );

                            my $target_path = undef;
                            if ( $target_uri->is_local ) {
                                $target_path = $shf->utf8_decode( Gnome2::VFS->unescape_string( $target_uri->extract_dirname ) );
                            }
                            else {
                                $target_path = $shf->utf8_decode( Gnome2::VFS->unescape_string( $target_uri->get_scheme . "://" . $target_uri->get_host_name . $target_uri->extract_dirname ) );
                            }

                            #dialogs (main window != parent window)
                            my $sd = Shutter::App::SimpleDialogs->new;

                            my $response = $sd->dlg_warning_message( sprintf( $d->get("The image already exists in %s. Replacing it will overwrite its contents."), "'" . $target_path . "'" ), sprintf( $d->get("An image named %s already exists. Do you want to replace it?"), "'" . $target_uri->extract_short_name . "'" ), $d->get("Skip all"), $d->get("Skip"), undef, $replace_btn, undef, undef );

                            #10 == skip all, 20 == skip, 40 == replace, else == cancel
                            if ( $response == 10 ) {
                                last;
                            }
                            elsif ( $response == 20 ) {
                                next;
                            }
                            elsif ( $response == 40 ) {
                                $result = Gnome2::VFS::Xfer->uri( $source_uri, $target_uri, 'default', 'abort', 'replace', sub { return TRUE } );

                                #check result again
                                if ( $result eq 'ok' ) {

									if ( $target_uri->is_local ) {
										&fct_show_status_message( 1, $file . " " . $d->get("exported") );

										#show as notification
										my $notify = $sc->get_notification_object;
										$notify->show( $d->get("Successfully exported"), sprintf( $d->get("The file %s was successfully exported."), $file ) );
									}
									else {
										&fct_show_status_message( 1, $file . " " . $d->get("uploaded") );

										#show as notification
										my $notify = $sc->get_notification_object;
										$notify->show( $d->get("Successfully uploaded"), sprintf( $d->get("The file %s was successfully uploaded."), $file ) );
									}

                                }
                                else {

                                    my $response = &dlg_upload_error_message_gnome_vfs( $target_uri, $result );

                                    #10 == skip all, 20 == skip, 40 == retry, else == cancel
                                    if ( $response == 10 ) {
                                        last;
                                    }
                                    elsif ( $response == 20 ) {
                                        next;
                                    }
                                    elsif ( $response == 40 ) {
                                        redo;
                                    }
                                    else {
                                        next;
                                    }

                                }
                            }

                        }
                        else {

                            my $response = &dlg_upload_error_message_gnome_vfs( $target_uri, $result );

                            #10 == skip all, 20 == skip, 40 == retry, else == cancel
                            if ( $response == 10 ) {
                                last;
                            }
                            elsif ( $response == 20 ) {
                                next;
                            }
                            elsif ( $response == 40 ) {
                                redo;
                            }
                            else {
                                next;
                            }

                        }

                        $hosting_progress->set_fraction( $counter / @files_to_upload );

                        #update gui
                        &fct_update_gui;
                        $counter++;

                    }

                }

                #save recently used upload tab
                $sc->set_ruu_tab( $unotebook->get_current_page );

                #and the relevant detail (folder, uploader etc.)
                #hosting service
                $sc->set_ruu_hosting( $hosting->get_active );
                $sc->set_ruu_places( $places_fc->get_filename );

                #set initial state of dialog
                $upload_button->set_sensitive(TRUE);
                $close_button->set_sensitive(TRUE);
                $hosting_progress->hide;

                #response != accept
            }
            else {
                $hosting_dialog->destroy();
                return FALSE;
            }

        }    #dialog loop
    }

    sub dlg_upload_error_message_gnome_vfs {
        my $target_uri = shift;
        my $result     = shift;

        #dialogs (main window != parent window)
        my $sd = Shutter::App::SimpleDialogs->new;

        my $target_path = undef;
        if ( $target_uri->is_local ) {
            $target_path = $shf->utf8_decode( Gnome2::VFS->unescape_string( $target_uri->extract_dirname ) );
        }
        else {
            $target_path = $shf->utf8_decode( Gnome2::VFS->unescape_string( $target_uri->get_scheme . "://" . $target_uri->get_host_name . $target_uri->extract_dirname ) );
        }

        #retry button
        my $retry_btn = Gtk2::Button->new_with_mnemonic( $d->get("_Retry") );
        $retry_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-redo', 'button' ) );

        my $response = $sd->dlg_error_message( sprintf( $d->get("Error while copying the image %s."), "'" . $target_uri->extract_short_name . "'" ), sprintf( $d->get("There was an error copying the image into %s."), "'" . $target_path . "'" ), $d->get("Skip all"), $d->get("Skip"), undef, $retry_btn, undef, undef, Gnome2::VFS->result_to_string($result) );

        return $response;
    }

    sub dlg_upload_error_message {
        my ( $status, $max_filesize ) = @_;

        #dialogs (main window != parent window)
        my $sd = Shutter::App::SimpleDialogs->new;

        my $response;
        if ( $status == 999 ) {
            $response = $sd->dlg_error_message( $d->get("Please check your credentials and try again."), $d->get("Error while login") );
        }
        elsif ( $status == 998 ) {
            $response = $sd->dlg_error_message( $d->get("Maximum filesize reached"), $d->get("Error while uploading"), $d->get("Skip all"), $d->get("Skip"), undef, undef, undef, undef, sprintf( $d->get("Maximum filesize: %s"), $max_filesize ) );
        }
        else {
            $response = $sd->dlg_error_message( $status, $d->get("Error while connecting"), $d->get("Skip all"), $d->get("Skip"), $d->get("Retry"), );
        }
        return $response;
    }

    sub dlg_profile_name {
        my ( $curr_profile_name, $combobox_settings_profiles ) = @_;

        my $profile_dialog = Gtk2::MessageDialog->new( $window, [qw/modal destroy-with-parent/], 'other', 'none', undef );

        $profile_dialog->set_title("Shutter");

        $profile_dialog->set( 'image' => Gtk2::Image->new_from_stock( 'gtk-dialog-question', 'dialog' ) );

        $profile_dialog->set( 'text' => $d->get("Save current preferences as new profile") );

        $profile_dialog->set( 'secondary-text' => $d->get("New profile name") . ": " );

        $profile_dialog->add_button( 'gtk-cancel', 'reject' );
        $profile_dialog->add_button( 'gtk-save',   'accept' );

        $profile_dialog->set_default_response('accept');

        my $new_profile_name_vbox = Gtk2::VBox->new();
        my $new_profile_name_hint = Gtk2::Label->new();
        my $new_profile_name      = Gtk2::Entry->new();
        $new_profile_name->set_activates_default(TRUE);

        #here are all invalid char codes
        my @invalid_codes = ( 47, 92, 63, 37, 42, 58, 124, 34, 60, 62, 44, 59, 35, 38 );
        $new_profile_name->signal_connect(
            'key-press-event' => sub {
                my $new_profile_name = shift;
                my $event            = shift;

                my $input = Gtk2::Gdk->keyval_to_unicode( $event->keyval );

                #invalid input
                #~ print $input."\n";
                if ( grep( $input == $_, @invalid_codes ) ) {
                    my $char = chr($input);
                    $char = '&amp;' if $char eq '&';
                    $new_profile_name_hint->set_markup( "<span size='small'>" . sprintf( $d->get("Reserved character %s is not allowed to be in a filename."), "'" . $char . "'" ) . "</span>" );
                    return TRUE;
                }
                else {

                    #clear possible message when valid char is entered
                    $new_profile_name_hint->set_markup("<span size='small'></span>");
                    return FALSE;
                }
            }
        );

        #show name of current profile
        $new_profile_name->set_text($curr_profile_name)
          if defined $curr_profile_name;

        $new_profile_name_vbox->pack_start_defaults($new_profile_name);
        $new_profile_name_vbox->pack_start_defaults($new_profile_name_hint);
        $profile_dialog->vbox->add($new_profile_name_vbox);
        $profile_dialog->show_all;

        #run dialog
        my $profile_response = $profile_dialog->run;

        #handle user responses here
        if ( $profile_response eq 'accept' ) {
            my $entered_name = $new_profile_name->get_text;

            if ( $shf->file_exists("$ENV{'HOME'}/.shutter/profiles/$entered_name.xml") ) {

                #ask the user to replace the profile
                #replace button
                my $replace_btn = Gtk2::Button->new_with_mnemonic( $d->get("_Replace") );
                $replace_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-save-as', 'button' ) );

                my $response = $sd->dlg_warning_message( $d->get("Replacing it will overwrite its contents."), sprintf( $d->get("A profile named %s already exists. Do you want to replace it?"), "'" . $entered_name . "'" ), undef, undef, undef, $replace_btn, undef, undef );

                #40 == replace_btn was hit
                if ( $response != 40 ) {
                    $profile_dialog->destroy();
                    return FALSE;
                }
            }

            $profile_dialog->destroy();
            return $entered_name;
        }
        else {
            $profile_dialog->destroy();
            return FALSE;
        }
    }

    sub fct_zoom_in {
        my $key = &fct_get_current_file;
        if ($key) {
            $session_screens{$key}->{'image'}->zoom_in;
        }
    }

    sub fct_zoom_out {
        my $key = &fct_get_current_file;
        if ($key) {
            $session_screens{$key}->{'image'}->zoom_out;
        }
    }

    sub fct_zoom_100 {
        my $key = &fct_get_current_file;
        if ($key) {
            $session_screens{$key}->{'image'}->set_zoom(1);
        }
    }

    sub fct_zoom_best {
        my $key = &fct_get_current_file;
        if ($key) {
            $session_screens{$key}->{'image'}->set_fitting(TRUE);
        }
    }

    sub fct_fullscreen {
        my ($widget) = @_;

        if ( $widget->get_active ) {
            $window->fullscreen;
        }
        else {
            $window->unfullscreen;
        }
    }

    sub fct_navigation_toolbar {
        my ($widget) = @_;

        if ( $widget->get_active ) {
            $nav_toolbar->show;
            foreach my $child ( $nav_toolbar->get_children ) {
                $child->show_all;
            }
        }
        else {
            $nav_toolbar->hide;
            foreach my $child ( $nav_toolbar->get_children ) {
                $child->hide_all;
            }
        }
    }

    #--------------------------------------
}

__END__

=head1 NAME

Shutter - Feature-rich Screenshot Tool

=head1 SYNOPSIS

shutter [options]

=head1 COPYRIGHT

Shutter is Copyright (C) by Mario Kemper and Shutter Team

=head1 DESCRIPTION

B<Shutter> is a feature-rich screenshot program. You can take a screenshot of a specific area, window, your whole screen, or even of a website - apply different effects to it, draw on it to highlight points, and then upload to an image hosting site, all within one window.

=head1 OPTIONS

=over 8

=item Example 1

shutter -a -p=myprofile --min_at_startup

=item Example 2

shutter -s=100,100,300,300 -e

=item Example 3

shutter --window=.*firefox.*

=item Example 4

shutter --web=http://shutter-project.org/ -e

=back

=head2 CAPTURE MODE OPTIONS

=over 8

=item B<-s, --select=[X,Y,WIDTH,HEIGHT]>

Capture an area of the screen. Providing X,Y,WIDTH,HEIGHT is optional.

=item B<-f, --full>

Capture the entire screen.

=item B<-w, --window=[NAME_PATTERN]>

Select a window to capture. Providing a NAME_PATTERN (Perl-style regex) ist optional.

=item B<-a, --active>

Capture the current active window.

=item B<--section>

Capture a section. You will be able to select any child window by moving the mouse over it.

=item B<-m, --menu>

Capture a menu.

=item B<-t, --tooltip>

Capture a tooltip.

=item B<--web=[URL]>

Capture a webpage. Providing an URL ist optional.

=item B<-r, --redo>

Redo last screenshot.

=back

=head2 SETTINGS OPTIONS

=over 8

=item B<-p, --profile=NAME>

Load a specific profile on startup.

=item B<-o, --output=FILENAME>

Specify a filename to save the screenshot to (overwrites any profile-related setting).

B<Supported image formats:> You can save to any popular image format (e.g. jpeg, png, gif, bmp). Additionally it is possible to save to pdf, ps or svg.

B<Please note:> There are several wildcards available, like

 %Y = year
 %m = month
 %d = day
 %T = time
 $w = width
 $h = height
 $name = multi-purpose (e.g. window title)
 $nb_name = like $name but without blanks in resulting strings
 $profile = name of current profile
 $R = random char (e.g. $RRRR = ag4r)
 %NN = counter

The string is interpretted by strftime. See C<man strftime> for more examples.

B<As an example:> shutter -f -e -o './%y-%m-%d_$w_$h.png' would create a file named '11-10-28_1280_800.png' in the current directory. 

=item B<-d, --delay=SECONDS>

Wait n seconds before taking a screenshot.

=item B<-c, --include_cursor>

Include cursor when taking a screenshot.

=item B<-C, --remove_cursor>

Remove cursor when taking a screenshot.

=back

=head2 APPLICATION OPTIONS

=over 8

=item B<-h, --help>

Prints a brief help message and exits.

=item B<-v, --version>

Prints version information.

=item B<--debug>

Prints a lot of debugging information to STDOUT.

=item B<--clear_cache>

Clears cache, e.g. installed plugins, at startup.

=item B<--min_at_startup>

Starts Shutter minimized to tray.

=item B<--disable_systray>

Disables systray icon.

=item B<-e, --exit_after_capture>

Exit after the first capture has been made. This is useful when using Shutter in scripts.

=item B<-n, --no_session>

Do not add the screenshot to the session. This is useful when using Shutter in scripts.

=back

=head1 BUG REPORTS

If you find a bug in Shutter, you should report it.  But first, you should make sure that it really is a bug, and that it appears in the latest version of Shutter.

The latest version is always available from:
B<https://launchpad.net/shutter>

Once you have determined that a bug actually exists, please report it at launchpad:
B<https://bugs.launchpad.net/shutter/+filebug>

=cut
