#! /usr/bin/perl

###################################################
#
#  Copyright (C) Mario Kemper <mario.kemper@googlemail.com> and Shutter Team
#
#  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
###################################################

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

#Gnome2 libraries
use Gnome2;

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

#GConf - used for metacity keybindings
use Gnome2::GConf;

#GnomeVFS
use Gnome2::VFS '-init';

#Image operations
use Image::Magick();

#File operations
use File::Copy;
use File::Path qw/ rmtree /;
use File::Basename;
use File::Temp qw/ tempfile tempdir /;
use IO::File;

#Gtk2
use Gtk2 '-init';
use Gtk2::Gdk::Keysyms;
use Gtk2::Pango;

#X11
use X11::Protocol;

#Gettext and filename parsing
use POSIX qw/setlocale strftime/;
use Locale::gettext;

#handle upload responses properly
use HTTP::Status;

#load and save settings
use XML::Simple;

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

#internal use
use FindBin '$Bin';
use Data::Dumper;

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

#define constants
#--------------------------------------
use constant TRUE                	=> 1;
use constant FALSE               	=> 0;
use constant MAX_ERROR 				=> 5;
use constant REV                	=> "Rev.397";
use constant PPA_VERSION         	=> "ppa2";
use constant SHUTTER_NAME         	=> "Shutter";
use constant SHUTTER_VERSION      	=> "v0.70.1";
use constant SHUTTER_VERSION_FULL 	=> REV . " - " . PPA_VERSION;

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

#configure path settings
#--------------------------------------
$Bin =~ m/(.*)\//;
my $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 $gtkimageview    = TRUE;
my $goocanvas       = TRUE;
&fct_init_optional;

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

#load modules at custom path at runtime
#--------------------------------------
require lib;
import lib "$shutter_root/share/shutter/resources/modules";

#proc (Thanks to Michael Schilli)
require Proc::Simple;

#Perl extension for recursively copying files and directories (Thanks to Daniel Muey)
require File::Copy::Recursive;

#Find programs to open a file by mimetype
require File::MimeInfo::Applications;

#shutter app classes
require Shutter::App::Common;
require Shutter::App::SimpleDialogs;
require Shutter::App::HelperFunctions;
require Shutter::App::Menu;
require Shutter::App::Toolbar;

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

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

#screenshot classes
require Shutter::Screenshot::SelectorAdvanced;
require Shutter::Screenshot::SelectorSimple;
require Shutter::Screenshot::Workspace;
require Shutter::Screenshot::Web;
require Shutter::Screenshot::Window;

#upload classes
require Shutter::Upload::ImageBanana;
require Shutter::Upload::UbuntuPics;
require Shutter::Upload::ImageShack;
require Shutter::Upload::FTP;

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

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

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

#create app objects
#--------------------------------------
my $shutter_common 	= Shutter::App::Common->new($shutter_root);
$shutter_common->set_mainwindow($window);
my $shutter_hfunct 	= Shutter::App::HelperFunctions->new($shutter_common);
my $shutter_menu   	= Shutter::App::Menu->new($shutter_common);
my $shutter_tool   	= Shutter::App::Toolbar->new($shutter_common);
my $shutter_dialog 	= Shutter::App::SimpleDialogs->new($window);
my $shutter_pix 	= Shutter::Pixbuf::Save->new($shutter_common);
my $shutter_thumb 	= Shutter::Pixbuf::Thumbnail->new($shutter_common);

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

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

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

#Page Setup
my $pagesetup = undef;

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

#X11 protocol and XSHAPE ext
my $x11 = X11::Protocol->new( $ENV{ 'DISPLAY' } );
$x11->{ext_shape} = $x11->init_extension('SHAPE');

#Gtk2::ImageView and Selector for advanced selection tool
my $view;
my $selector;
if($gtkimageview){
	$view     = Gtk2::ImageView->new;
	$selector = Gtk2::ImageView::Tool::Selector->new($view);
	$view->set_tool($selector);
}

#data structures
#--------------------------------------
my %gm_programs;    #hash to store program infos
my %plugins;        #hash to store plugin infos
my %accounts;       #hash to store account infos
my %settings;       #hash to store settings
&fct_init;
&fct_init_framework_versions;
&fct_check_installed_programs;
&fct_load_accounts;

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

#signal-handler
$SIG{RTMIN} = sub { &evt_take_screenshot( 'global_keybinding', 'select' ) };
$SIG{USR1}  = sub { &evt_take_screenshot( 'global_keybinding', 'raw' ) };
$SIG{USR2}  = sub { &evt_take_screenshot( 'global_keybinding', 'window' ) };
$SIG{RTMAX} = sub { &evt_take_screenshot( 'global_keybinding', 'section' ) };

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

#main window gui
#--------------------------------------
$window->set_title(SHUTTER_NAME);
$window->set_default_icon( Gtk2::Gdk::Pixbuf->new_from_file_at_scale( "$shutter_root/share/pixmaps/shutter.svg", 100, 100, TRUE ) );
$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_position('center');
$window->set_default_size( 650, 500 );
$window->set_size_request( -1, 450 );

#TRAY ICON
my $icon                 = undef;
my $current_profile_indx = 0;
my $is_in_tray           = TRUE;

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

#STATUSBAR
my $status1 = Gtk2::Statusbar->new;
$status1->set_size_request( 200, -1 );
my $status2 = Gtk2::Statusbar->new;

#arrange settings in notebook
my $notebook_settings = Gtk2::Notebook->new;
my $settings_dialog   = Gtk2::Dialog->new(
	SHUTTER_NAME . " - " . $shutter_common->get_gettext->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( $shutter_menu->create_menu, FALSE, TRUE, 0 );

$shutter_menu->{_menuitem_open}->signal_connect( 'activate', \&evt_open, 'menu_open' );
$shutter_menu->{_menuitem_selection}->signal_connect( 'activate', \&evt_take_screenshot, 'select' );
$shutter_menu->{_menuitem_full}->signal_connect( 'activate', \&evt_take_screenshot, 'raw' );
$shutter_menu->{_menuitem_window}->signal_connect( 'activate', \&evt_take_screenshot, 'window' );
$shutter_menu->{_menuitem_section}->signal_connect( 'activate', \&evt_take_screenshot, 'section' );

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

$shutter_menu->{_menuitem_save_as}->signal_connect( 'activate', \&evt_save_as, 'menu_save_as' );
$shutter_menu->{_menuitem_print}->signal_connect( 'activate', \&fct_print, 'menu_print' );
$shutter_menu->{_menuitem_pagesetup}->signal_connect( 'activate', \&evt_page_setup, 'menu_pagesetup' );
$shutter_menu->{_menuitem_close}->signal_connect( 'activate', sub { &fct_remove(undef); }, 'menu_close' );
$shutter_menu->{_menuitem_close_all}->signal_connect( 'activate', sub { &fct_remove_all(); }, 'menu_close_all' );
$shutter_menu->{_menuitem_quit}->signal_connect( 'activate', \&evt_delete_window, 'menu_quit' );

$shutter_menu->{_menuitem_copy}->signal_connect( 'activate', \&fct_clipboard );
$shutter_menu->{_menuitem_trash}->signal_connect( 'activate', \&fct_delete );
$shutter_menu->{_menuitem_select_all}->signal_connect( 'activate', \&fct_select_all );
$shutter_menu->{_menuitem_settings}->signal_connect( 'activate', \&evt_show_settings, 'exp_settings_menu' );

$shutter_menu->{_menuitem_reopen}->set_submenu(&fct_ret_program_menu);
$shutter_menu->{_menuitem_rename}->signal_connect( 'activate', \&fct_rename );
$shutter_menu->{_menuitem_upload}->signal_connect( 'activate', \&fct_upload );
$shutter_menu->{_menuitem_draw}->signal_connect( 'activate', \&fct_draw );
$shutter_menu->{_menuitem_plugin}->signal_connect( 'activate', \&fct_plugin );

$shutter_menu->{_menuitem_back}->signal_connect( 'activate', \&evt_navigate, 'previous' );
$shutter_menu->{_menuitem_forward}->signal_connect( 'activate', \&evt_navigate, 'forward' );
$shutter_menu->{_menuitem_first}->signal_connect( 'activate', \&evt_navigate, 'first' );
$shutter_menu->{_menuitem_last}->signal_connect( 'activate', \&evt_navigate, 'last' );
$shutter_menu->{_menuitem_question}->signal_connect( 'activate', \&evt_question, $window );
$shutter_menu->{_menuitem_translate}->signal_connect( 'activate', \&evt_translate, $window );
$shutter_menu->{_menuitem_bug}->signal_connect( 'activate', \&evt_bug, $window );
$shutter_menu->{_menuitem_about}->signal_connect( 'activate', \&evt_about, $window );

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

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

	if ( Gtk2->CHECK_VERSION( 2, 10, 0 ) ) {
		$icon = Gtk2::StatusIcon->new();
		$icon->set_from_file("$shutter_root/share/pixmaps/shutter.svg");
		$icon->set_visible(1);
		$icon->signal_connect(
			'popup-menu' => sub { &evt_show_systray_statusicon; },
			$icon
		);
		$icon->signal_connect(
			'activate' => sub {
				&evt_activate_systray_statusicon;
				$icon;
			},
			$icon
		);
		$icon->set_tooltip( SHUTTER_NAME . " " . SHUTTER_VERSION );
	} else {
		require Gtk2::TrayIcon;
		$icon = Gtk2::Image->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$shutter_root/share/pixmaps/shutter.svg", 24, 24 ) );
		my $eventbox = Gtk2::EventBox->new;
		$eventbox->add($icon);
		my $tray = Gtk2::TrayIcon->new('shutter TrayIcon');
		$tray->add($eventbox);
		$tooltips->set_tip( $tray, SHUTTER_NAME . " " . SHUTTER_VERSION );
		$eventbox->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_extras         = Gtk2::VBox->new( FALSE, 12 );
my $vbox_behavior       = Gtk2::VBox->new( FALSE, 12 );
my $vbox_plugins        = Gtk2::VBox->new( FALSE, 12 );
my $vbox_accounts       = Gtk2::VBox->new( FALSE, 12 );
my $file_vbox           = Gtk2::VBox->new( FALSE, 0 );
my $save_vbox           = Gtk2::VBox->new( FALSE, 0 );
my $behavior_vbox       = Gtk2::VBox->new( FALSE, 0 );
my $behavior_hbox1      = Gtk2::HBox->new( FALSE, 0 );
my $behavior_hbox2      = Gtk2::HBox->new( FALSE, 0 );
my $behavior_hbox3      = Gtk2::HBox->new( FALSE, 0 );
my $behavior_hbox4      = Gtk2::HBox->new( FALSE, 0 );
my $keybinding_vbox     = Gtk2::VBox->new( FALSE, 0 );
my $keybinding_mode_box = Gtk2::HBox->new( TRUE,  0 );
my $actions_vbox        = Gtk2::VBox->new( FALSE, 0 );
my $capture_vbox        = Gtk2::VBox->new( FALSE, 0 );
my $effects_vbox        = Gtk2::VBox->new( FALSE, 0 );
my $accounts_hbox       = Gtk2::HBox->new( FALSE, 0 );
my $accounts_vbox       = Gtk2::VBox->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_vbox            = Gtk2::VBox->new( FALSE, 0 );
my $profiles_box        = Gtk2::HBox->new( FALSE, 0 );
my $scale_box           = Gtk2::HBox->new( FALSE, 0 );
my $delay_box           = Gtk2::HBox->new( FALSE, 0 );
my $delay_box2          = Gtk2::HBox->new( FALSE, 0 );
my $thumbnail_box       = Gtk2::HBox->new( FALSE, 0 );
my $thumbnail_box2      = Gtk2::HBox->new( FALSE, 0 );
my $filename_box        = Gtk2::HBox->new( FALSE, 0 );
my $progname_box        = Gtk2::HBox->new( FALSE, 0 );
my $progname_box2       = Gtk2::HBox->new( FALSE, 0 );
my $im_colors_box       = Gtk2::HBox->new( FALSE, 0 );
my $im_colors_box2      = Gtk2::HBox->new( FALSE, 0 );
my $filetype_box        = Gtk2::HBox->new( FALSE, 0 );
my $saveDir_box         = Gtk2::HBox->new( FALSE, 0 );
my $key_box             = Gtk2::HBox->new( FALSE, 0 );
my $key_box2            = Gtk2::HBox->new( FALSE, 0 );
my $key_sel_box         = Gtk2::HBox->new( FALSE, 0 );
my $key_sel_box2        = Gtk2::HBox->new( FALSE, 0 );
my $border_box          = Gtk2::HBox->new( FALSE, 0 );
my $cursor_box          = Gtk2::HBox->new( FALSE, 0 );

my $profiles_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Profile") . ":" );

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

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

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

#attach signal handlers to subroutines and pack toolbar
#--------------------------------------
my $handlebox = Gtk2::HandleBox->new;
$handlebox->add( $shutter_tool->create_toolbar );
$vbox->pack_start( $handlebox, FALSE, TRUE, 0 );

my ( $tool_advanced, $tool_simple ) = undef;
my $zoom_active = undef;
my ( $zoom_size1, $zoom_size2, $zoom_size3 ) = undef;
$shutter_tool->{_select}->set_menu(&fct_ret_sel_menu);
$shutter_tool->{_select}->signal_connect( 'clicked' => \&evt_take_screenshot, 'select' );

my $current_monitor_active = undef;
$shutter_tool->{_full}->signal_connect( 'clicked' => \&evt_take_screenshot, 'raw' );
$shutter_tool->{_full}->set_menu( &fct_ret_workspace_menu(TRUE) );
$shutter_tool->{_full}->signal_connect( 'show-menu' => sub { &fct_ret_workspace_menu(FALSE) } );

$shutter_tool->{_window}->signal_connect( 'clicked' => \&evt_take_screenshot, 'window' );
$shutter_tool->{_window}->set_menu(&fct_ret_window_menu);
$shutter_tool->{_window}->signal_connect( 'show-menu' => \&fct_ret_window_menu );

$shutter_tool->{_section}->signal_connect( 'clicked' => \&evt_take_screenshot, 'section' );

#gnome web photo is optional, don't enable it when gnome-web-photo is not in PATH
if ( $gnome_web_photo ) {
	$tooltips->set_tip( $shutter_tool->{_web}, $d->get("Take a screenshot of a website") );
	$shutter_tool->{_web}->set_arrow_tooltip( Gtk2::Tooltips->new, $d->get("Set up a connection timeout (seconds)"), 'arrow' );
	$shutter_tool->{_web}->set_sensitive(TRUE);
	$shutter_tool->{_web}->signal_connect( 'clicked' => \&evt_take_screenshot, 'web' );
	$shutter_tool->{_web}->set_menu(&fct_ret_web_menu);
	$shutter_tool->{_web}->signal_connect( 'show-menu' => \&fct_ret_web_menu );
} else {
	$tooltips->set_tip( $shutter_tool->{_web}, $d->get("gnome-web-photo needs to be installed for this feature") );
	$shutter_tool->{_web}->set_arrow_tooltip( $tooltips, $d->get("gnome-web-photo needs to be installed for this feature"), 'arrow' );
	$shutter_tool->{_web}->set_sensitive(FALSE);
}

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

#handle profiles
#--------------------------------------
my $combobox_settings_profiles = Gtk2::ComboBox->new_text;
my @saved_profiles             = glob("$ENV{'HOME'}/.shutter/profiles/*.xml");
my @current_profiles;
my $current_index = 0;
foreach ( sort @saved_profiles ) {
	utf8::decode $_;
	next
		if $_ =~ /\_accounts.xml/;    #accounts file - we are looking for "real" profiles
	$_ =~ /.*\/(.*)\.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, $shutter_common->get_gettext->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;
}

#populate quick selector as well
$shutter_menu->{_menuitem_quicks}->set_submenu( fct_ret_profile_menu( $combobox_settings_profiles, \@current_profiles ) );

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, $shutter_common->get_gettext->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, $shutter_common->get_gettext->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, $shutter_common->get_gettext->get("Set profile for current configuration") );

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


#frames and label for settings dialog
#--------------------------------------
my $file_frame_label = Gtk2::Label->new;
$file_frame_label->set_markup( "<b>" . $shutter_common->get_gettext->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>" . $shutter_common->get_gettext->get("Save") . "</b>" );

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

my $behavior_frame_label = Gtk2::Label->new;
$behavior_frame_label->set_markup( "<b>" . $shutter_common->get_gettext->get("Behavior") . "</b>" );

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

my $keybinding_frame_label = Gtk2::Label->new;
$keybinding_frame_label->set_markup( "<b>" . $shutter_common->get_gettext->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>" . $shutter_common->get_gettext->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>" . $shutter_common->get_gettext->get("Capture") . "</b>" );

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

my $accounts_frame_label = Gtk2::Label->new;
$accounts_frame_label->set_markup( "<b>" . $shutter_common->get_gettext->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>" . $shutter_common->get_gettext->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');

#delay
#--------------------------------------
my $delay_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Delay") . ":" );
my $delay = Gtk2::HScale->new_with_range( 1, 10, 1 );
$delay->signal_connect(
	'value-changed' => \&evt_value_changed,
	'delay_changed'
);
$delay->set_value_pos('right');

if ( defined $settings_xml->{'general'}->{'delay'} ) {
	$delay->set_value( $settings_xml->{'general'}->{'delay'} );
} else {
	$delay->set_value(0);
}
my $delay_active = Gtk2::CheckButton->new;
$delay_active->signal_connect(
	'toggled' => \&evt_value_changed,
	'delay_toggled'
);
$delay_active->set_active(TRUE);

if ( defined $settings_xml->{'general'}->{'delay_active'} ) {
	$delay_active->set_active( $settings_xml->{'general'}->{'delay_active'} );
} else {
	$delay_active->set_active(FALSE);
}
$tooltips->set_tip( $delay,        $shutter_common->get_gettext->get("Wait n seconds before taking a screenshot") );
$tooltips->set_tip( $delay_active, $shutter_common->get_gettext->get("Wait n seconds before taking a screenshot") );
$tooltips->set_tip( $delay_label,  $shutter_common->get_gettext->get("Wait n seconds before taking a screenshot") );
$delay_box->pack_start( $delay_label, FALSE, TRUE, 12 );
$delay_box2->pack_start( $delay_active, FALSE, FALSE, 0 );
$delay_box2->pack_start( $delay,        TRUE,  TRUE,  0 );
$delay_box->pack_start( $delay_box2, TRUE, TRUE, 0 );

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

#thumbnail
#--------------------------------------
my $thumbnail_label = Gtk2::Label->new( $shutter_common->get_gettext->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->signal_connect(
	'toggled' => \&evt_value_changed,
	'thumbnail_toggled'
);
$thumbnail_active->set_active(TRUE);

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,
	$shutter_common->get_gettext->get("Generate thumbnail too.\nselect the percentage of the original size for the thumbnail to be") );
$tooltips->set_tip( $thumbnail_active,
	$shutter_common->get_gettext->get("Generate thumbnail too.\nselect the percentage of the original size for the thumbnail to be") );
$tooltips->set_tip( $thumbnail_label,
	$shutter_common->get_gettext->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_box2->pack_start( $thumbnail_active, FALSE, FALSE, 0 );
$thumbnail_box2->pack_start( $thumbnail,        TRUE,  TRUE,  0 );
$thumbnail_box->pack_start( $thumbnail_box2, TRUE, TRUE, 0 );

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

#filename
#--------------------------------------
my $filename = Gtk2::Entry->new;
if ( defined $settings_xml->{'general'}->{'filename'} ) {
	$filename->set_text( $settings_xml->{'general'}->{'filename'} );
} else {
	$filename->set_text("screenshot_\%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->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>");	
		return TRUE;
	}else{
		#clear possible message when valid char is entered
		$filename_hint->set_markup("<span size='small'></span>");						
		return FALSE;
	}
});

my $filename_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Filename") . ":" );
$tooltips->set_tip(
	$filename,
	$shutter_common->get_gettext->get(
		"There are several wild-cards available, like\n%Y = year\n%m = month\n%d = day\n%T = time\n\$w = width\n\$h = height\n%NN = counter"
	)
);
$tooltips->set_tip(
	$filename_label,
	$shutter_common->get_gettext->get(
		"There are several wild-cards available, like\n%Y = year\n%m = month\n%d = day\n%T = time\n\$w = width\n\$h = height\n%NN = counter"
	)
);
$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( $shutter_common->get_gettext->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,
	$shutter_common->get_gettext->get("Quality/Compression:\nHigh value means high size / high compression\n(depending on file format chosen)") );
$tooltips->set_tip( $scale_label,
	$shutter_common->get_gettext->get("Quality/Compression:\nHigh value means high size / high compression\n(depending on file format chosen)") );
$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 ) = ( 0, 0, 0 );
my $format_counter = 0;

foreach ( Gtk2::Gdk::Pixbuf->get_formats ) {
	if (   $_->{name} eq "jpeg"
		|| $_->{name} eq "png"
		|| $_->{name} eq "bmp" )
	{
		$combobox_type->append_text( $_->{name} . " - " . $_->{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 ( $_->{name} eq "jpeg" ) {
			$int_jpeg = $format_counter;
		} elsif ( $_->{name} eq "png" ) {
			$int_png = $format_counter;
		} elsif ( $_->{name} eq "bmp" ) {
			$int_bmp = $format_counter;
		}

		$format_counter++;

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

if ( defined $settings_xml->{'general'}->{'filetype'} ) {
	
	#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'});	
	}
	
	#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 ( @{ [ $int_png, $int_jpeg, $int_bmp ] } ) {
		if ( $_ > 0 ) {
			$combobox_type->set_active( $_ );
			last;
		}
	}

}

my $filetype_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Image format") . ":" );
$tooltips->set_tip( $combobox_type,  $shutter_common->get_gettext->get("Select a file format") );
$tooltips->set_tip( $filetype_label, $shutter_common->get_gettext->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( $shutter_common->get_gettext->get("Directory") . ":" );
my $saveDir_button = Gtk2::FileChooserButton->new( "Shutter - " . $shutter_common->get_gettext->get("Choose folder"), 'select-folder' );
if ( defined $settings_xml->{'general'}->{'folder'} ) {
	$saveDir_button->set_filename( $settings_xml->{'general'}->{'folder'} );
} else {
	$saveDir_button->set_filename( $ENV{'HOME'} );
}

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

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

#behavior
#--------------------------------------
my $capture_key = Gtk2::Entry->new;
if ( defined $settings_xml->{'general'}->{'capture_key'} ) {
	$capture_key->set_text( $settings_xml->{'general'}->{'capture_key'} );
} else {
	$capture_key->set_text("Print");
}
my $capture_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Capture") . ":" );
$tooltips->set_tip(
	$capture_key,
	$shutter_common->get_gettext->get(
		"Configure global keybinding for capture\nThe format looks like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this action. "
	)
);
$tooltips->set_tip(
	$capture_label,
	$shutter_common->get_gettext->get(
		"Configure global keybinding for capture\nThe format looks like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this action. "
	)
);
my $capture_sel_key = Gtk2::Entry->new;

if ( defined $settings_xml->{'general'}->{'capture_sel_key'} ) {
	$capture_sel_key->set_text( $settings_xml->{'general'}->{'capture_sel_key'} );
} else {
	$capture_sel_key->set_text("<Alt>Print");
}

my $capture_sel_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Capture with selection") . ":" );
$tooltips->set_tip(
	$capture_sel_key,
	$shutter_common->get_gettext->get(
		"Configure global keybinding for capture with selection\nThe format looks like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this action. "
	)
);
$tooltips->set_tip(
	$capture_sel_label,
	$shutter_common->get_gettext->get(
		"Configure global keybinding for capture with selection\nThe format looks like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this action. "
	)
);

#keybinding_mode
my $combobox_keybinding_mode = Gtk2::ComboBox->new_text;
$combobox_keybinding_mode->insert_text( 0, $shutter_common->get_gettext->get("Selection") );
$combobox_keybinding_mode->insert_text( 1, $shutter_common->get_gettext->get("Window") );
$combobox_keybinding_mode->insert_text( 2, $shutter_common->get_gettext->get("Section") );

if ( defined $settings_xml->{'general'}->{'keybinding_mode'} ) {
	$combobox_keybinding_mode->set_active( $settings_xml->{'general'}->{'keybinding_mode'} );
} else {
	$combobox_keybinding_mode->set_active(1);
}
$tooltips->set_tip(
	$combobox_keybinding_mode,
	$shutter_common->get_gettext->get(
		"Configure global keybinding for capture with selection\nThe format looks like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this action. "
	)
);
$combobox_keybinding_mode->signal_connect(
	'changed' => \&evt_behavior_handle,
	'keybinding_sel_toggled'
);

$keybinding_mode_box->pack_start( Gtk2::Label->new,          FALSE, FALSE, 0 );
$keybinding_mode_box->pack_start( $combobox_keybinding_mode, TRUE,  TRUE,  0 );

#keybindings
my $keybinding_active = Gtk2::CheckButton->new;
$keybinding_active->signal_connect(
	'toggled' => \&evt_behavior_handle,
	'keybinding_toggled'
);
my $keybinding_sel_active = Gtk2::CheckButton->new;
$keybinding_sel_active->signal_connect(
	'toggled' => \&evt_behavior_handle,
	'keybinding_sel_toggled'
);
$key_box->pack_start( $capture_label, FALSE, TRUE, 12 );
$key_box2->pack_start( $keybinding_active, FALSE, FALSE, 0 );
$key_box2->pack_start( $capture_key,       TRUE,  TRUE,  0 );
$key_box->pack_start( $key_box2, TRUE, TRUE, 0 );
$key_sel_box->pack_start( $capture_sel_label, FALSE, TRUE, 12 );
$key_sel_box2->pack_start( $keybinding_sel_active, FALSE, FALSE, 0 );
$key_sel_box2->pack_start( $capture_sel_key,       TRUE,  TRUE,  0 );
$key_sel_box->pack_start( $key_sel_box2, TRUE, TRUE, 0 );
$keybinding_active->set_active(TRUE);

if ( defined $settings_xml->{'general'}->{'keybinding'} ) {
	$keybinding_active->set_active( $settings_xml->{'general'}->{'keybinding'} );
} else {
	$keybinding_active->set_active(FALSE);
}
$keybinding_sel_active->set_active(TRUE);
if ( defined $settings_xml->{'general'}->{'keybinding_sel'} ) {
	$keybinding_sel_active->set_active( $settings_xml->{'general'}->{'keybinding_sel'} );
} else {
	$keybinding_sel_active->set_active(FALSE);
}
my $hide_active           = Gtk2::CheckButton->new_with_label( $shutter_common->get_gettext->get("Autohide Shutter Window when taking a screenshot") );
my $autocopy_active       = Gtk2::CheckButton->new_with_label( $shutter_common->get_gettext->get("Automatically copy screenshot to clipboard") );
my $close_at_close_active = Gtk2::CheckButton->new_with_label( $shutter_common->get_gettext->get("Minimize to tray when closing main window") );
my $save_at_close_active  = Gtk2::CheckButton->new_with_label( $shutter_common->get_gettext->get("Save settings when exiting") );
$behavior_hbox1->pack_start( $hide_active,           FALSE, TRUE, 12 );
$behavior_hbox2->pack_start( $autocopy_active,       FALSE, TRUE, 12 );
$behavior_hbox3->pack_start( $close_at_close_active, FALSE, TRUE, 12 );
$behavior_hbox4->pack_start( $save_at_close_active,  FALSE, TRUE, 12 );

$hide_active->signal_connect(
	'toggled' => \&evt_behavior_handle,
	'hide_toggled'
);

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, $shutter_common->get_gettext->get("Autohide Shutter Window when taking a screenshot") );
$autocopy_active->signal_connect(
	'toggled' => \&evt_behavior_handle,
	'autocopy_toggled'
);

if ( defined $settings_xml->{'general'}->{'autocopy'} ) {
	$autocopy_active->set_active( $settings_xml->{'general'}->{'autocopy'} );
} else {
	$autocopy_active->set_active(TRUE);
}
$tooltips->set_tip( $autocopy_active, $shutter_common->get_gettext->get("Automatically copy screenshot to clipboard") );
$close_at_close_active->signal_connect(
	'toggled' => \&evt_behavior_handle,
	'close_at_close_toggled'
);

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, $shutter_common->get_gettext->get("Minimize to tray when closing main window") );
$save_at_close_active->signal_connect(
	'toggled' => \&evt_behavior_handle,
	'save_at_close_toggled'
);

if ( defined $settings_xml->{'general'}->{'save_at_close'} ) {
	$save_at_close_active->set_active( $settings_xml->{'general'}->{'save_at_close'} );
} else {
	$save_at_close_active->set_active(TRUE);
}
$tooltips->set_tip( $save_at_close_active, $shutter_common->get_gettext->get("Save settings automatically when exiting Shutter") );

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

#program
#--------------------------------------
my $model        = &fct_get_program_model;
my $progname     = Gtk2::ComboBox->new($model);
my $renderer_pix = Gtk2::CellRendererPixbuf->new;
$progname->pack_start( $renderer_pix, FALSE );
$progname->add_attribute( $renderer_pix, pixbuf => 0 );
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->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( $shutter_common->get_gettext->get("Open with") . ":" );
$tooltips->set_tip( $progname,        $shutter_common->get_gettext->get("Open your screenshot\nwith this program after capturing") );
$tooltips->set_tip( $progname_active, $shutter_common->get_gettext->get("Open your screenshot\nwith this program after capturing") );
$tooltips->set_tip( $progname_label,  $shutter_common->get_gettext->get("Open your screenshot\nwith this program after capturing") );
$progname_box->pack_start( $progname_label, FALSE, TRUE, 12 );
$progname_box2->pack_start( $progname_active, FALSE, TRUE, 0 );
$progname_box2->pack_start( $progname,        TRUE,  TRUE, 0 );
$progname_box->pack_start( $progname_box2, TRUE, TRUE, 0 );

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

#im_colors
#--------------------------------------
my $combobox_im_colors = Gtk2::ComboBox->new_text;
$combobox_im_colors->insert_text( 0, $shutter_common->get_gettext->get("16 colors   - (4bit) ") );
$combobox_im_colors->insert_text( 1, $shutter_common->get_gettext->get("64 colors   - (6bit) ") );
$combobox_im_colors->insert_text( 2, $shutter_common->get_gettext->get("256 colors  - (8bit) ") );
$combobox_im_colors->signal_connect(
	'changed' => \&evt_value_changed,
	'border_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->signal_connect(
	'toggled' => \&evt_value_changed,
	'im_colors_toggled'
);
$im_colors_active->set_active(TRUE);

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( $shutter_common->get_gettext->get("Reduce colors") . ":" );
$tooltips->set_tip( $combobox_im_colors, $shutter_common->get_gettext->get("Automatically reduce colors \nafter taking a screenshot") );
$tooltips->set_tip( $im_colors_active,   $shutter_common->get_gettext->get("Automatically reduce colors \nafter taking a screenshot") );
$tooltips->set_tip( $im_colors_label,    $shutter_common->get_gettext->get("Automatically reduce colors \nafter taking a screenshot") );
$im_colors_box->pack_start( $im_colors_label, FALSE, TRUE, 12 );
$im_colors_box2->pack_start( $im_colors_active,   FALSE, TRUE, 0 );
$im_colors_box2->pack_start( $combobox_im_colors, TRUE,  TRUE, 0 );
$im_colors_box->pack_start( $im_colors_box2, TRUE, TRUE, 0 );

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

#border
#--------------------------------------
my $combobox_border = Gtk2::ComboBox->new_text;
$combobox_border->insert_text( 1, $shutter_common->get_gettext->get("activate") );
$combobox_border->insert_text( 0, $shutter_common->get_gettext->get("deactivate") );
$combobox_border->signal_connect(
	'changed' => \&evt_value_changed,
	'border_changed'
);

if ( defined $settings_xml->{'general'}->{'border'} ) {
	$combobox_border->set_active( $settings_xml->{'general'}->{'border'} );
} else {
	$combobox_border->set_active(TRUE);
}
my $border_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Window border") . ":" );
$tooltips->set_tip( $combobox_border, $shutter_common->get_gettext->get("Include wm border when selecting a window") );
$tooltips->set_tip( $border_label,    $shutter_common->get_gettext->get("Include wm border when selecting a window") );
$border_box->pack_start( $border_label,    FALSE, TRUE, 12 );
$border_box->pack_start( $combobox_border, TRUE,  TRUE, 0 );

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

#cursor
#--------------------------------------
my $combobox_cursor = Gtk2::ComboBox->new_text;
$combobox_cursor->insert_text( 1, $shutter_common->get_gettext->get("activate") );
$combobox_cursor->insert_text( 0, $shutter_common->get_gettext->get("deactivate") );
$combobox_cursor->signal_connect(
	'changed' => \&evt_value_changed,
	'cursor_changed'
);

if ( defined $settings_xml->{'general'}->{'cursor'} ) {
	$combobox_cursor->set_active( $settings_xml->{'general'}->{'cursor'} );
} else {
	$combobox_cursor->set_active(0);
}
my $cursor_label = Gtk2::Label->new( $shutter_common->get_gettext->get("Include cursor") . ":" );
$tooltips->set_tip( $combobox_cursor, $shutter_common->get_gettext->get("Include cursor when taking a screenshot") );
$tooltips->set_tip( $cursor_label,    $shutter_common->get_gettext->get("Include cursor when taking a screenshot") );
$cursor_box->pack_start( $cursor_label,    FALSE, TRUE, 12 );
$cursor_box->pack_start( $combobox_cursor, TRUE,  TRUE, 0 );

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

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

my $accounts_tree = Gtk2::TreeView->new_with_model($accounts_model);
$tooltips->set_tip(
	$accounts_tree,
	$shutter_common->get_gettext->get(
		"Entering your Accounts for specific hosting-sites is optional. If entered it will give you the same benefits as the upload on the website. If you leave these fields empty you will be able to upload to the specific hosting-partner as a guest."
	)
);

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

&fct_set_model_accounts($accounts_tree);

#ftp uri
my $ftp_entry_label = Gtk2::Label->new( $shutter_common->get_gettext->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, $shutter_common->get_gettext->get("URI\nExample: ftp://host:port/path") );

$tooltips->set_tip( $ftp_remote_entry, $shutter_common->get_gettext->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( $shutter_common->get_gettext->get("Connection mode") . ":" );

my $ftp_mode_combo = Gtk2::ComboBox->new_text;
$ftp_mode_combo->insert_text( 0, $shutter_common->get_gettext->get("Active mode") );
$ftp_mode_combo->insert_text( 1, $shutter_common->get_gettext->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, $shutter_common->get_gettext->get("Connection mode") );

$tooltips->set_tip( $ftp_mode_combo, $shutter_common->get_gettext->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( $shutter_common->get_gettext->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, $shutter_common->get_gettext->get("Username") );

$tooltips->set_tip( $ftp_username_entry, $shutter_common->get_gettext->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( $shutter_common->get_gettext->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, $shutter_common->get_gettext->get("Password") );

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

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

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

#plugins
#--------------------------------------
my $effects_model = undef;
&fct_load_plugin_tree;

my $effects_tree = Gtk2::TreeView->new_with_model($effects_model);
$effects_tree->signal_connect(
	'row-activated' => \&evt_plugins,
	'row_activated'
);

&fct_set_model_plugins($effects_tree);

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

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

#settings main tab
my $label_basic = Gtk2::Label->new;
$label_basic->set_markup( $shutter_common->get_gettext->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( $filename_box, TRUE,  TRUE, 3 );
$save_vbox->pack_start( $saveDir_box,  FALSE, TRUE, 3 );
$save_vbox->pack_start( $filename_hint, TRUE,  TRUE, 3 );
$save_frame->add($save_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->set_border_width(5);

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

$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_frame->add($actions_vbox);

$capture_vbox->pack_start( $delay_box,  FALSE, TRUE, 3 );
$capture_vbox->pack_start( $border_box, FALSE, TRUE, 3 );
$capture_vbox->pack_start( $cursor_box, FALSE, TRUE, 3 );
$capture_frame->add($capture_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 );
$delay_label->set_alignment( 0, 0.5 );
$border_label->set_alignment( 0, 0.5 );
$cursor_label->set_alignment( 0, 0.5 );

my $sg_adv = Gtk2::SizeGroup->new('horizontal');
$sg_adv->add_widget($progname_label);
$sg_adv->add_widget($im_colors_label);
$sg_adv->add_widget($thumbnail_label);
$sg_adv->add_widget($delay_label);
$sg_adv->add_widget($border_label);
$sg_adv->add_widget($cursor_label);

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

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

$behavior_vbox->pack_start( $behavior_hbox1, TRUE, TRUE, 3 );
$behavior_vbox->pack_start( $behavior_hbox2, TRUE, TRUE, 3 );
$behavior_vbox->pack_start( $behavior_hbox3, TRUE, TRUE, 3 );
$behavior_vbox->pack_start( $behavior_hbox4, TRUE, TRUE, 3 );
$behavior_frame->add($behavior_vbox);

$keybinding_vbox->pack_start( $key_box,             FALSE, TRUE, 3 );
$keybinding_vbox->pack_start( $key_sel_box,         FALSE, TRUE, 3 );
$keybinding_vbox->pack_start( $keybinding_mode_box, FALSE, TRUE, 3 );
$keybinding_frame->add($keybinding_vbox);

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

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

$vbox_behavior->pack_start( $behavior_frame,   FALSE, TRUE, 3 );
$vbox_behavior->pack_start( $keybinding_frame, FALSE, TRUE, 3 );
$vbox_behavior->set_border_width(5);

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

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_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_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 );

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);

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

#append pages to notebook
my $notebook_settings_first  = $notebook_settings->append_page( $vbox_basic,    $label_basic );
my $notebook_settings_second = $notebook_settings->append_page( $vbox_extras,   $label_extras );
my $notebook_settings_third  = $notebook_settings->append_page( $vbox_behavior, $label_behavior );
my $notebook_settings_fourth = $notebook_settings->append_page( $vbox_accounts, $label_accounts );

#plugins
if ( keys(%plugins) > 0 ) {
	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( $shutter_common->get_gettext->get("Plugins") );
	my $label_treeview = Gtk2::Label->new( $shutter_common->get_gettext->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 );
	$vbox_plugins->pack_start( $effects_vbox,            TRUE,  TRUE, 1 );
	$vbox_plugins->set_border_width(5);
	my $notebook_settings_fifth = $notebook_settings->append_page( $vbox_plugins, $label_plugins );
}

#profiles
$profiles_box->pack_start( $profiles_label,             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, FALSE, TRUE, 6 );
$settings_dialog->vbox->add($hbox_settings);
$settings_dialog->set_default_response('apply');

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

#pack statusbar
$status1->set_has_resize_grip (FALSE);
$status2->set_has_resize_grip (TRUE);
my $status_hbox = Gtk2::HBox->new( FALSE, 0 );
$status_hbox->pack_start( $status1, TRUE, TRUE, 0 );
$status_hbox->pack_start( $status2, TRUE, TRUE, 0 );
$vbox->pack_start( $status_hbox, FALSE, FALSE, 0 );

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

#restore session
#--------------------------------------
&fct_load_session;

#start minimized?
#--------------------------------------
unless ( $shutter_common->get_min ) {
	&fct_update_first_tab();
	$window->show_all;
	$is_in_tray = FALSE;
} else {
	&fct_update_first_tab();
	$window->hide;
	$is_in_tray = TRUE;
}

#load saved settings
#--------------------------------------
my $folder_to_save = $settings_xml->{'general'}->{'folder'}
	|| $ENV{'HOME'};
if ( $shutter_common->get_start_with && $folder_to_save ) {
	if ( $shutter_common->get_start_with eq "raw" ) {
		&evt_take_screenshot( 'global_keybinding', "raw", $folder_to_save );
	} elsif ( $shutter_common->get_start_with eq "select" ) {
		&evt_take_screenshot( 'global_keybinding', "select", $folder_to_save );
	} elsif ( $shutter_common->get_start_with eq "window" ) {
		&evt_take_screenshot( 'global_keybinding', "window", $folder_to_save );
	} elsif ( $shutter_common->get_start_with eq "section" ) {
		&evt_take_screenshot( 'global_keybinding', "section", $folder_to_save );
	}
}

Gtk2->main;

0;

#events
#--------------------------------------
sub evt_navigate {
	my ( $widget, $data ) = @_;
	print "\n$data was emitted by widget $widget\n"
		if $shutter_common->get_debug;
	if ( $data eq "first" ) {
		$notebook->set_current_page(0);
	} elsif ( $data eq "last" ) {
		$notebook->set_current_page( $notebook->get_n_pages - 1 );
	} elsif ( $data eq "previous" ) {
		$notebook->prev_page;
	} elsif ( $data eq "forward" ) {
		$notebook->next_page;
	}
	return 1;
}

sub evt_value_changed {
	my ( $widget, $data ) = @_;
	print "\n$data was emitted by widget $widget\n"
		if $shutter_common->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);
		}
	}

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

	#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);
		}
	}

	#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( $shutter_common->get_gettext->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( $shutter_common->get_gettext->get("Compression") . ":" );
		} else {
			$scale->set_sensitive(FALSE);
			$scale_label->set_sensitive(FALSE);
		}
	}

	return TRUE;
}

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

	#disable signal-handler
	$SIG{USR1}  = 'IGNORE';
	$SIG{USR2}  = 'IGNORE';
	$SIG{RTMIN} = 'IGNORE';
	$SIG{RTMAX} = 'IGNORE';

	my $quality_value             = $scale->get_value();
	my $delay_value               = undef;
	my $thumbnail_value           = $thumbnail->get_value;
	my $progname_value            = undef;
	my $filename_value            = undef;
	my $filetype_value            = undef;
	my $folder                    = undef;
	my $screenshot                = undef;
	my $screenshot_name           = undef;
	my $screenshot_thumbnail      = undef;
	my $screenshot_thumbnail_name = undef;
	my $thumbnail_ending          = "thumb";
	print "\n$data was emitted by widget $widget\n"
		if $shutter_common->get_debug;
	
	#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;
	}

	#determine current file type (name - description)
	$combobox_type->get_active_text =~ /(.*) -/;
	$filetype_value = $1;
	unless ($filetype_value) {
		$shutter_dialog->dlg_error_message( $shutter_common->get_gettext->get("No valid filetype specified"), $d->get("Failed") );
		&fct_control_main_window( TRUE, 'show' );
		return FALSE;
	}

	#determine folder to save
	$folder = $saveDir_button->get_filename || $folder_from_config;
	utf8::decode $folder;

	if ( $delay_active->get_active ) {
		$delay_value = $delay->get_value;
	} else {
		$delay_value = 0;
	}

	#prepare filename, parse wild-cards
	$filename_value = $filename->get_text();
	utf8::decode $filename_value;
	$filename_value = strftime $filename_value , localtime;

	#get next filename (auto increment using a wild card or manually)
	my $uri = &fct_get_next_filename( $filename_value, $folder, $filetype_value );

	#no valid filename was determined, exit here
	unless($uri){
		my $response = $shutter_dialog->dlg_error_message( 
			$d->get( "There was an error determining the filename." ),
			$d->get("Failed") 
		);		
		&fct_control_main_window( TRUE, 'show' );
		return FALSE;
	}

	#save current position of main window
	my ( $old_x, $old_y ) = $window->get_position;

	#hide mainwindow
	if (   $hide_active->get_active
		&& ( $data ne "web" && $data ne "tray_web" )
		&& !$is_in_tray
		&& !$selfcapture )
	{
		&fct_control_main_window(FALSE, 'hide');
	}

	#fullscreen screenshot
	if ( $data eq "raw" || $data eq "tray_raw" ) {
		my $wnck_screen = Gnome2::Wnck::Screen->get_default;
		unless ( $filename_value =~ /[a-zA-Z0-9]+/
			&& defined($folder)
			&& defined($filetype_value) )
		{
			$shutter_dialog->dlg_error_message( 
				$shutter_common->get_gettext->get("No valid filename specified"), 
				$d->get("Failed") 
			);
			&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
			return FALSE;
		}

		my $screenshooter = Shutter::Screenshot::Workspace->new(
			$shutter_common, $combobox_cursor->get_active,
			$delay_value, $wnck_screen->get_active_workspace,
			undef, undef, $current_monitor_active->get_active
		);
		$screenshot = $screenshooter->workspace();
		undef $screenshooter;

		#window
	} elsif ( $data eq "window"
		|| $data eq "tray_window"
		|| $data eq "section"
		|| $data eq "tray_section" )
	{
		unless ( $filename_value =~ /[a-zA-Z0-9]+/ ) {
			$shutter_dialog->dlg_error_message( $shutter_common->get_gettext->get("No valid filename specified"), $d->get("Failed") );
			&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
			return FALSE;
		}

		my $screenshooter = Shutter::Screenshot::Window->new(
			$shutter_common, $combobox_cursor->get_active,
			$delay_value, $x11, $combobox_border->get_active,
			undef, $data, $is_in_tray
		);
		$screenshot = $screenshooter->window_select();
		undef $screenshooter;

		#selection
	} elsif ( $data eq "select" || $data eq "tray_select" ) {
		unless ( $filename_value =~ /[a-zA-Z0-9]+/ ) {
			$shutter_dialog->dlg_error_message( $shutter_common->get_gettext->get("No valid filename specified"), $d->get("Failed") );
			&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
			return FALSE;
		}
		if ( $tool_advanced->get_active ) {
					
			my $screenshooter = Shutter::Screenshot::SelectorAdvanced->new( $shutter_common, $combobox_cursor->get_active, $delay_value, \$view, \$selector );
			$screenshot = $screenshooter->select_advanced();
			undef $screenshooter;

		} else {
			my $zoom_size_factor = 1;
			$zoom_size_factor = 2 if ( $zoom_size2->get_active );
			$zoom_size_factor = 3 if ( $zoom_size3->get_active );
			my $screenshooter = Shutter::Screenshot::SelectorSimple->new( $shutter_common, $combobox_cursor->get_active,
				$delay_value, $zoom_size_factor, $zoom_active->get_active );
			$screenshot = $screenshooter->select_simple();
			undef $screenshooter;
		}

		#web
	} elsif ( $data eq "web" || $data eq "tray_web" ) {

		$screenshot = &dlg_website( $uri->get_path(), $filetype_value, $quality_value );
		if ( $screenshot != 5 ) {
			eval { $screenshot->isa('Image::Magick'); };
			if ($@) {
				$shutter_dialog->dlg_error_message( $shutter_common->get_gettext->get("Unable to capture website"), $d->get("Failed") );
				&dlg_status_message( 1, $shutter_common->get_gettext->get("Unable to capture website"), $d->get("Failed") );
				&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
				return FALSE;
			}
		}
	} elsif ( $data =~ /^shutter_window_direct(.*)/ ) {
		my $xid = $1;
		print "Selected xid: $xid\n" if $shutter_common->get_debug;
		unless ( $filename_value =~ /[a-zA-Z0-9]+/ ) {
			$shutter_dialog->dlg_error_message( $shutter_common->get_gettext->get("No valid filename specified"), $d->get("Failed") );
			&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
			return FALSE;
		}
		my $screenshooter
			= Shutter::Screenshot::Window->new( $shutter_common, $combobox_cursor->get_active, $delay_value, $x11, $combobox_border->get_active, $xid );
		$screenshot = $screenshooter->window_by_xid();
		undef $screenshooter;

	} 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 $shutter_common->get_debug;

			#metacity etc.
		} elsif ( $data =~ /shutter_wrksp_direct(.*)/ ) {
			$selected_workspace = $1;
			print "Sel. Workspace: $selected_workspace\n"
				if $shutter_common->get_debug;
		}

		unless ( $filename_value =~ /[a-zA-Z0-9]+/ ) {
			$shutter_dialog->dlg_error_message( $shutter_common->get_gettext->get("No valid filename specified"), $d->get("Failed") );
			&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
			return FALSE;
		}
		my $screenshooter = Shutter::Screenshot::Workspace->new( $shutter_common, $combobox_cursor->get_active,
			$delay_value, $selected_workspace, $vpx, $vpy, $current_monitor_active->get_active );
		$screenshot = $screenshooter->workspace();

	}

	#screenshot was taken at this stage...
	#start postprocessing here

	#...successfully???
	unless ($screenshot) {
			
		#show error dialog
		my $response = $shutter_dialog->dlg_error_message( 
			$d->get( "Maybe mouse pointer could not be grabbed or the selected area is invalid." ),
			$d->get( "Error while taking the screenshot" )
		);
			
		&dlg_status_message( 1, $shutter_common->get_gettext->get("Screenshot failed!") );
		&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
		return FALSE;
	} else {

		#user aborted screenshot
		if ( $screenshot == 5 ) {
			&dlg_status_message( 1, $shutter_common->get_gettext->get("Capture aborted by user") );
			&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
			return FALSE;
		}

		#we have to use the path (e.g. /home/username/file1.png)
		#so we can save the screenshot_properly
		$screenshot_name = $uri->get_path();

		#parse wild cards
		my $swidth  = $screenshot->get_width;
		my $sheight = $screenshot->get_height;

		$screenshot_name =~ s/\%24w/$swidth/g;
		$screenshot_name =~ s/\%24h/$sheight/g;

		#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)
		#we don't do this when taking a web screenshot,
		#because gnome-web-photo creates the file immediately
		#we would save two files in this case 
		#because the new file would always "exist"
		if($data ne "web" && $data ne "tray_web"){
			if ( $uri->exists ) {
				my $count             = 1;
				my $filename_value = fileparse( $uri->get_path, '\..*' );
				my $existing_filename = $filename_value;
				while ( $uri->exists ) {
					$filename_value = $existing_filename . "(" . sprintf( "%03d", $count++ ) . ")";
					$uri 	= Gnome2::VFS::URI->new($folder);
					$uri    = $uri->append_string("$filename_value.$filetype_value");
					print "Checking new uri after parsing: " . $uri->to_string . "\n" if $shutter_common->get_debug;
				}
			}
		}
		
		#we have to update the path again
		$screenshot_name = $uri->get_path();

		print "Trying to save file to $screenshot_name\n"
			if $shutter_common->get_debug;

		#finally save pixbuf
		unless ($shutter_pix->save_pixbuf_to_file($screenshot, $screenshot_name, $screenshot_name, $filetype_value, $quality_value)){
			&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
			return FALSE;			
		}

	}    #end screenshot successfull
	if ( $uri->exists ) {

		#quantize
		if ( $im_colors_active->get_active ) {
			my $im_colors_value = $combobox_im_colors->get_active_text();
			$im_colors_value =~ /.*\(([0-9]*).*\)/;
			&fct_imagemagick_perform( 'reduce_colors', $screenshot_name, $im_colors_value );
		}

		#generate the thumbnail
		if ( $thumbnail_active->get_active ) {

			#calculate size
			my $twidth  = int( $screenshot->get_width *  ( $thumbnail_value / 100 ) );
			my $theight = int( $screenshot->get_height * ( $thumbnail_value / 100 ) );

			#create thumbail
			$screenshot_thumbnail = Gtk2::Gdk::Pixbuf->new_from_file_at_scale( $screenshot_name, $twidth, $theight, TRUE );

			#save path of thumbnail
			my ($name, $folder, $ext) = fileparse( $uri->get_path, '\..*' );
			$screenshot_thumbnail_name = $folder . "/$name-$thumbnail_ending.$filetype_value";

			#parse wild cards
			$screenshot_thumbnail_name =~ s/\%24w/$twidth/g;
			$screenshot_thumbnail_name =~ s/\%24h/$theight/g;

			print "Trying to save file to $screenshot_thumbnail_name\n"
				if $shutter_common->get_debug;

			#finally save pixbuf
			unless($shutter_pix->save_pixbuf_to_file($screenshot_thumbnail, $screenshot_thumbnail_name, $screenshot_thumbnail_name, $filetype_value, $quality_value)){
				&fct_control_main_window( TRUE, 'show', $old_x, $old_y );
				return FALSE;			
			}

		}

		#integrate it into the notebook
		my $new_key_screenshot = &fct_integrate_screenshot_in_notebook( $uri, $screenshot );

		#thumbnail as well if present
		my $new_key_screenshot_thumbnail = &fct_integrate_screenshot_in_notebook( Gnome2::VFS::URI->new($screenshot_thumbnail_name), $screenshot_thumbnail )
			if $thumbnail_active->get_active;

		#autocopy to clipboard if configured
		if ( $autocopy_active->get_active() ) {
			$clipboard->set_image($screenshot);
		}

		#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) {
				$progname_value = $model->get_value( $progname_iter, 2 );
			}
			&fct_open_with_program($progname_value);
		}
		print "screenshot successfully saved to $screenshot_name!\n"
			if $shutter_common->get_debug;
		&dlg_status_message( 1, "$session_screens{$new_key_screenshot}->{'short'} " . $shutter_common->get_gettext->get("saved") );
	} else {
		#show error dialog
		my $response = $shutter_dialog->dlg_error_message( 
			$d->get( "Maybe mouse pointer could not be grabbed or the selected area is invalid." ),
			$d->get( "Error while taking the screenshot" )
		);
		&dlg_status_message( 1, $shutter_common->get_gettext->get("Screenshot failed!") );
	}

	&fct_control_main_window( TRUE, 'show', $old_x, $old_y );

	return TRUE;
}

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

	#checkbox for "keybinding" -> entry active/inactive
	if ( $data eq "keybinding_toggled" ) {
		if ( $keybinding_active->get_active ) {
			$capture_key->set_sensitive(TRUE);
		} else {
			$capture_key->set_sensitive(FALSE);
		}
	}

	#checkbox for "keybinding_sel" -> entry active/inactive
	if ( $data eq "keybinding_sel_toggled" ) {
		if ( $keybinding_sel_active->get_active ) {
			$capture_sel_key->set_sensitive(TRUE);
			$combobox_keybinding_mode->set_sensitive(TRUE);
		} else {
			$capture_sel_key->set_sensitive(FALSE);
			$combobox_keybinding_mode->set_sensitive(FALSE);
		}
	}

	&fct_save_bindings();

	return TRUE;
}

sub evt_notebook_switch {
	my ( $widget, $pointer, $int ) = @_;
	if ( $shutter_menu->{_menubar} ) {

		#enable/disable menu entry when we are in the session tab and selection changes
		&fct_update_menu($int);

	}

	#	foreach my $key ( keys %session_screens ) {
	#		eval {
	#
	#			#		$session_screens{$key}->{'handle'}->cancel;
	#			$session_screens{$key}->{'image'}->clear;
	#		};
	#	}

	#	my $calc_num = 0;
	#	my ($wwidth, $wheight) = $window->get_size;
	#	foreach my $key ( keys %session_screens ) {
	#		if($session_screens{$key}->{'tab_label'}->window){
	#			my $alloc = $session_screens{$key}->{'tab_label'}->allocation;
	#			print "$wwidth / $alloc->width \n";
	#			$calc_num = int($wwidth / $alloc->width);
	#			last;
	#		}
	#	}
	#
	#	print $calc_num."\n";

	#	$notebook->reorder_child ($session_start_screen{'first_page'}->{'tab_child'}, $int-1);
	return TRUE;
}

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

	if ( $data ne "menu_quit" && $close_at_close_active->get_active ) {
		$window->hide;
		$is_in_tray = TRUE;
		return TRUE;
	}

	if ( $save_at_close_active->get_active ) {
		$window->hide;
		&fct_save_settings(undef);
		&fct_save_settings( $combobox_settings_profiles->get_active_text )
			if $combobox_settings_profiles->get_active != -1;
	}

	Gtk2->main_quit;
	return FALSE;
}

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

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

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

sub evt_about {
	my ( $widget, $data ) = @_;
	if ( $shutter_common->get_debug ) {
		print "\n$data was emitted by widget $widget\n";
	}
	
	#everything is stored in external files, so it is easier to maintain
	my $all_hint = "";
	open( GPL_HINT, "$shutter_root/share/shutter/resources/license/gplv3_hint" )
		or die $!;
	while(my $hint = <GPL_HINT>){
		utf8::decode $hint;
		$all_hint .= $hint;	
	}
	close(GPL_HINT);
	
	my $all_gpl = "";
	open( GPL, "$shutter_root/share/shutter/resources/license/gplv3" )
		or die $!;
	while(my $gpl = <GPL>){
		utf8::decode $gpl;
		$all_gpl .= $gpl;	
	}	
	close(GPL);
	
	#~ my $all_trans = "";	
	#~ open( TRANSCREDITS, "$shutter_root/share/shutter/resources/credits/trans" )
		#~ or die $!;
	#~ while(my $trans = <TRANSCREDITS>){
		#~ utf8::decode $trans;
		#~ $all_trans .= $trans;	
	#~ }
	#~ close(TRANSCREDITS);

	my $all_dev = "";
	open( DEVCREDITS, "$shutter_root/share/shutter/resources/credits/dev" )
		or die $!;
	while(my $dev = <DEVCREDITS>){
		utf8::decode $dev;
		$all_dev .= $dev;	
	}
	close(DEVCREDITS);

	my $all_art = "";
	open( ARTCREDITS, "$shutter_root/share/shutter/resources/credits/art" )
		or die $!;
	while(my $art = <ARTCREDITS>){
		utf8::decode $art;
		$all_art .= $art;	
	}
	close(ARTCREDITS);
	
	my $website = "http://shutter-project.org";
	my $about   = Gtk2::AboutDialog->new;
	my $logo    = Gtk2::Gdk::Pixbuf->new_from_file_at_scale( "$shutter_root/share/pixmaps/shutter.svg", 100, 100, TRUE );
	$about->set_logo($logo);
	if (Gtk2->CHECK_VERSION( 2, 12, 0 )){
		$about->set_program_name(SHUTTER_NAME);
	}else{
		$about->set_name(SHUTTER_NAME);
	}
	$about->set_version(SHUTTER_VERSION);
	$about->set_url_hook( sub { $shutter_hfunct->gnome_open(@_) } );
	$about->set_website_label("Shutter-Website");
	$about->set_website($website);
	$about->set_email_hook( sub { $shutter_hfunct->gnome_open_mail(@_) } );
	$about->set_authors( $all_dev );
	$about->set_artists( $all_art );
	#~ $about->set_translator_credits($all_trans);
	$about->set_translator_credits($d->get("translator-credits"));
	$about->set_copyright($all_hint);
	$about->set_license($all_gpl);
	$about->set_comments(SHUTTER_VERSION_FULL);
	$about->show_all;
	$about->signal_connect( 'response' => sub { $about->destroy } );
}

sub evt_show_systray {
	my ( $widget, $data ) = @_;
	if ( $shutter_common->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 (TRUE, 'hide');
		} else {
			&fct_control_main_window (TRUE, 'show');
		}
	}

	#right button (mouse)
	elsif ( $_[1]->button == 3 ) {

		my $tray_menu = &fct_ret_tray_menu;

		$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, $icon ) = @_;
	if ( $shutter_common->get_debug ) {
		print "\n$button, $time was emitted by widget $widget\n";
	}

	my $tray_menu = &fct_ret_tray_menu;

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

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

	if ( $window->visible ) {
		&fct_control_main_window (TRUE, 'hide');
	} else {
		&fct_control_main_window (TRUE, 'show');
	}

	return TRUE;
}

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

	#nothing to do here right now...
	return TRUE;
}

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

	#open browser if register url is clicked
	if ( $column->get_title eq $shutter_common->get_gettext->get("Register") ) {
		my $model         = $tree->get_model();
		my $account_iter  = $model->get_iter($path);
		my $account_value = $model->get_value( $account_iter, 3 );
		$shutter_hfunct->gnome_open( undef, $account_value, undef );
	}
	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);
		my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
		my $key = $session_start_screen{'first_page'}->{'model'}->get_value( $iter, 2 );		

		my $item_menu = $shutter_menu->fct_ret_actions_menu(undef, $d, $shutter_root);

		foreach my $menuitem ($item_menu->get_children){
			$menuitem->set_sensitive(TRUE);
			if($menuitem->get_name eq 'item-reopen'){
				$menuitem->set_submenu(&fct_ret_program_menu);
			}elsif($menuitem->get_name eq 'item-rename'){
				$menuitem->signal_connect( 'activate', \&fct_rename);				
			}elsif($menuitem->get_name eq 'item-upload'){
				$menuitem->signal_connect( 'activate', \&fct_upload);			
			}elsif($menuitem->get_name eq 'item-draw'){
				$menuitem->signal_connect( 'activate', \&fct_draw);	
				#maybe lib is not installed
				unless ($goocanvas) {
					$menuitem->set_sensitive(FALSE);
				}		
			}elsif($menuitem->get_name eq 'item-plugin'){
				$menuitem->signal_connect( 'activate', \&fct_plugin);				
			}	
		}

		$item_menu->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 ( $iconview, $data ) = @_;

	my @sel_items = $iconview->get_selected_items;

	#enable/disable menu entry when we are in the session tab and selection changes
	&fct_update_menu( scalar @sel_items );

	return TRUE;
}

sub fct_update_menu {
	my $n_items = shift;

	$shutter_menu->{_menuitem_reopen}->set_sensitive($n_items);
	if($n_items){
		$shutter_menu->{_menuitem_reopen}->set_submenu(&fct_ret_program_menu);		
	}
	$shutter_menu->{_menuitem_rename}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_upload}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_draw}->set_sensitive($n_items);
	#maybe lib is not installed
	unless ($goocanvas) {
		$shutter_menu->{_menuitem_draw}->set_sensitive(FALSE);
	}		

	$shutter_menu->{_menuitem_plugin}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_save_as}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_pagesetup}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_print}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_close}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_trash}->set_sensitive($n_items);
	$shutter_menu->{_menuitem_copy}->set_sensitive($n_items);
	
	#count items in iconview ($n_items := selected items)
	my $n_all_items=0;
	$session_start_screen{'first_page'}->{'model'}->foreach ( sub{
		$n_all_items++;
	});
	
	$shutter_menu->{_menuitem_select_all}->set_sensitive($n_all_items);
	$shutter_menu->{_menuitem_close_all}->set_sensitive($n_all_items);
	
	return TRUE;
}

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

	my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
	my $key = $session_start_screen{'first_page'}->{'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;
	if ( $settings_dialog_response eq "close" ) {

		&fct_post_settings($settings_dialog);

		return TRUE;
	} else {

		&fct_post_settings($settings_dialog);

		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);
	}

	$settings_dialog->hide();
	
	#we need to update the first tab here
	#because the profile might have changed
	&fct_update_first_tab();

	return TRUE;
}

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

	my $fs = Gtk2::FileChooserDialog->new(
		$shutter_common->get_gettext->get("Choose file to open"), $window,
		'open',
		'gtk-cancel' => 'reject',
		'gtk-open'   => 'accept'
	);
	$fs->set_select_multiple(TRUE);

	my $filter_all = Gtk2::FileFilter->new;
	$filter_all->set_name( $shutter_common->get_gettext->get("All compatible image formats") );
	$fs->add_filter($filter_all);

	foreach ( Gtk2::Gdk::Pixbuf->get_formats ) {
		my $filter = Gtk2::FileFilter->new;
		
		#add all known formats to the dialog
		#but filter out some special ones like svg
		#FIXME write in SVG via cairo?
		next if ($_->{name} =~ /svg/);
			
		$filter->set_name( $_->{name} . " - " . $_->{description} );
		
		foreach ( @{ $_->{extensions} } ) {
			$filter->add_pattern( "*." . uc $_ );
			$filter_all->add_pattern( "*." . uc $_ );
			$filter->add_pattern( "*." . $_ );
			$filter_all->add_pattern( "*." . $_ );
		}
		$fs->add_filter($filter);
	}

	my $key = &fct_get_current_file(undef);
	if ($key) {
		$fs->set_filename( $session_screens{$key}->{'folder'} );
	} elsif ( $ENV{'HOME'} ) {
		$fs->set_filename( $saveDir_button->get_filename() );
	}
	my $fs_resp = $fs->run;

	my @new_files;
	if ( $fs_resp eq "accept" ) {
		@new_files = $fs->get_filenames;
		$fs->destroy();
	} else {
		$fs->destroy();
	}

	#call function to open files - with progress bar etc.
	&fct_open_files(@new_files);

	return TRUE;
}

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

	#restore settings if prossible
	my $ssettings = Gtk2::PrintSettings->new;
	if ( $shutter_hfunct->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 $shutter_common->get_debug;


	my $key = &fct_get_current_file(undef);

	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
		);

	}

	&fct_save_as(@save_as_files);

	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 );

			#populate quick selector as well
			$shutter_menu->{_menuitem_quicks}->set_submenu( fct_ret_profile_menu( $combobox_settings_profiles, $current_profiles_ref ) );
		}
		&fct_save_settings($new_profile_name);
	}
	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 ( $shutter_hfunct->file_exists( "$ENV{'HOME'}/.shutter/profiles/" . $active_text . ".xml" )
			|| $shutter_hfunct->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 );

			#populate quick selector as well
			$shutter_menu->{_menuitem_quicks}->set_submenu( fct_ret_profile_menu( $combobox_settings_profiles, $current_profiles_ref ) );

			&dlg_status_message( 1, $d->get("Profile deleted") );
		} else {
			$shutter_dialog->dlg_error_message( $d->get("Profile could not be deleted"), $d->get("Failed") );
			&dlg_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( undef, 'profile_load', $combobox_settings_profiles->get_active_text );
		$current_profile_indx = $combobox_settings_profiles->get_active;

		#populate quick selector as well
		$shutter_menu->{_menuitem_quicks}->set_submenu( fct_ret_profile_menu( $combobox_settings_profiles, $current_profiles_ref ) );
		
	}
	
	&fct_update_first_tab();
	
	return TRUE;
}

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

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

sub fct_create_session_notebook {

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

	$notebook->set_size_request( 430, 320 );
	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, TRUE, 1 );
	$hbox_first_label->pack_start( $tab_first_label,  TRUE,  TRUE, 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    = shift;
	my $pixbuf = shift;

	#check parameters
	return FALSE unless $uri;
	return FALSE unless $uri->exists;

	#append a page to notebook using with label == filename
	my ( $second, $minute, $hour ) = localtime();
	my $theTime = sprintf("%02d:%02d:%02d", $hour, $minute, $second);
	my $key     = "[" . &fct_get_latest_tab_key . "] - $theTime";

	#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_from_pixbuf( $session_screens{$key}->{'thumb'} );

	#setup tab label
	my $tab_close_button = Gtk2::Button->new;
	$tab_close_button->set_relief('none');
	$tab_close_button->set_image($close_icon);
	my $tab_label = Gtk2::Label->new($key);
	$hbox_tab_label->pack_start( $session_screens{$key}->{'tab_icon'}, FALSE, TRUE, 1 );
	$hbox_tab_label->pack_start( $tab_label,                           TRUE,  TRUE, 1 );
	$hbox_tab_label->pack_start( $tab_close_button,                    FALSE, TRUE, 1 );
	$hbox_tab_label->show_all;

	#and append page with label == key
	my $new_index = $notebook->append_page( &fct_create_tab( $key, FALSE ), $hbox_tab_label );
	$session_screens{$key}->{'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); } );

	$notebook->set_current_page($new_index);

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

		#set image
		$session_screens{$key}->{'image'}->set_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file( $session_screens{$key}->{'long'} ) );
		$session_screens{$key}->{'image'}->{'current_width'}  = $session_screens{$key}->{'image'}->get_pixbuf->get_width;
		$session_screens{$key}->{'image'}->{'current_height'} = $session_screens{$key}->{'image'}->get_pixbuf->get_height;
		$session_screens{$key}->{'image'}->{'aspect_ratio'}
			= $session_screens{$key}->{'image'}->{'current_width'} / $session_screens{$key}->{'image'}->{'current_height'};

		#and finally set the signal handler to handle expose-events
		#dynamically resize the preview image for each tab 
		$session_screens{$key}->{'image_handler'} = $session_screens{$key}->{'image'}->signal_connect( 'expose-event', \&fct_resize_thumb, $key );

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

	#is this really needed here??
	#~ &fct_update_first_tab;

	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;

	#reset mtime
	$session_screens{$key}->{'mtime'} = -1;

	my $result;
	( $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 $shutter_common->get_debug;

			if ( $event eq 'deleted' ) {
				$handle->cancel;
				$session_screens{$key}->{'deleted'} = TRUE;
				$session_screens{$key}->{'changed'} = TRUE;
				&fct_update_tab($key);
				&fct_update_first_tab;

			} elsif ( $event eq 'changed' ) {

				#some files receive an CREATED event followed by CHANGED event (not used anymore)
				#we don't do anything in this case to avoid unneeded work (not used anymore)
				#~ unless ( $session_screens{$key}->{'created'} ) {
					print $session_screens{$key}->{'uri'}->to_string . " - " . $event . "\n" if $shutter_common->get_debug;
					$session_screens{$key}->{'changed'} = TRUE;
					&fct_update_tab($key);
					&fct_update_first_tab;
				#~ } else {
					#~ $session_screens{$key}->{'created'} = FALSE;
				#~ }

				#mark file when CREATED - see above
			#~ } elsif ( $event eq 'created' ) {
				#~ $session_screens{$key}->{'created'} = TRUE;
			}

			return TRUE;
		},
		$key
	);
	
	#show error dialog when installing the file
	#monitor failed
	unless ($result eq 'ok'){
		$shutter_dialog->dlg_error_message( Gnome2::VFS->result_to_string($result), $d->get("Failed") );		
		return FALSE;
	}

	return TRUE;
}

sub fct_control_main_window {
	my $set = shift;
	my $mode = shift;
	my $old_x = shift;
	my $old_y = shift;

	#set all buttons insensitive/sensitive
	$shutter_tool->{_select}->set_sensitive($set);
	$shutter_tool->{_full}->set_sensitive($set);
	$shutter_tool->{_window}->set_sensitive($set);
	$shutter_tool->{_section}->set_sensitive($set);
	$shutter_tool->{_web}->set_sensitive($set) if ($gnome_web_photo);

	my $screen = Gnome2::Wnck::Screen->get_default;
	$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($screen->can('get_window_manager_name')){
		$wm_name = $screen->get_window_manager_name;
	}
	
	#hide or show window
	if($mode eq 'show'){

		#focus window after taking a screenshot
		$window->deiconify;
		$window->show_all;

		#move window to saved position
		$window->move( $old_x, $old_y ) if (defined $old_x && defined $old_y);

		$window->present;
		$is_in_tray = FALSE;

		#attach signal-handler again
		$SIG{USR1}  = sub { &evt_take_screenshot( 'global_keybinding', 'raw' ) };
		$SIG{USR2}  = sub { &evt_take_screenshot( 'global_keybinding', 'window' ) };
		$SIG{RTMIN} = sub { &evt_take_screenshot( 'global_keybinding', 'select' ) };
		$SIG{RTMAX} = sub { &evt_take_screenshot( 'global_keybinding', 'section' ) };
			
	}elsif($mode eq 'hide'){

		$window->iconify;
		$window->hide;
		#wait longer when running compiz
		if($wm_name =~ /compiz/){
			usleep 200000;
		}else{
			usleep 100000;	
		}
		while ( Gtk2->events_pending ) {
			Gtk2->main_iteration;
		}		
		Gtk2::Gdk->flush;
		$is_in_tray = 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 $hbox_tab        = Gtk2::HBox->new( FALSE, 0 );
	my $vbox_all        = Gtk2::VBox->new( FALSE, 0 );
	my $hbox_all        = Gtk2::HBox->new( FALSE, 0 );
	my $vbox_all2       = Gtk2::VBox->new( FALSE, 0 );
	my $vbox_fileinfos  = Gtk2::VBox->new( FALSE, 0 );
	my $vbox_fileinfos2 = Gtk2::VBox->new( FALSE, 0 );
	my $hbox_tab_file   = Gtk2::HBox->new( FALSE, 0 );

	#keep number (1 = single tab, 2 = session tab) for translation
	my $number = 1;
	$number = 2 if $is_all;

	unless ($is_all) {
		my $filename_label = Gtk2::Label->new;
		$filename_label->set_markup( "<b>" . $d->get("Filename") . "</b>" );
		$session_screens{$key}->{'filename_label'} = Gtk2::Label->new();
		$session_screens{$key}->{'filename_label'}->set_line_wrap(TRUE);
		$session_screens{$key}->{'filename_label'}->set_single_line_mode(FALSE);

		my $folder_label = Gtk2::Label->new;
		$folder_label->set_markup( "<b>" . $d->get("Directory") . "</b>" );
		$session_screens{$key}->{'folder_label'} = Gtk2::Label->new();
		$session_screens{$key}->{'folder_label'}->set_line_wrap(TRUE);
		$session_screens{$key}->{'folder_label'}->set_single_line_mode(FALSE);

		my $mime_type_label = Gtk2::Label->new;
		$mime_type_label->set_markup( "<b>" . $d->get("Mime-Type") . "</b>" );
		$session_screens{$key}->{'mime_type_label'} = Gtk2::Label->new();

		my $size_label = Gtk2::Label->new;
		$size_label->set_markup( "<b>" . $d->get("Filesize") . "</b>" );
		$session_screens{$key}->{'size_label'} = Gtk2::Label->new();

		my $geometry_label = Gtk2::Label->new;
		$geometry_label->set_markup( "<b>" . $d->get("Geometry") . "</b>" );
		$session_screens{$key}->{'geometry_label'} = Gtk2::Label->new();

		#		$session_screens{$key}->{'image'} = Gtk2::Image->new_from_pixbuf( $session_screens{$key}->{'orig'} );
		#
		#		$session_screens{$key}->{'image'}->{'current_width'}  = $session_screens{$key}->{'image'}->get_pixbuf->get_width;
		#		$session_screens{$key}->{'image'}->{'current_height'} = $session_screens{$key}->{'image'}->get_pixbuf->get_height;
		#		$session_screens{$key}->{'image'}->{'aspect_ratio'}
		#			= $session_screens{$key}->{'image'}->{'current_width'} / $session_screens{$key}->{'image'}->{'current_height'};
		#		$session_screens{$key}->{'image_handler'} = $session_screens{$key}->{'image'}->signal_connect( 'expose-event', \&fct_resize_thumb, $key );

		$session_screens{$key}->{'image'} = Gtk2::Image->new();
		#~ $session_screens{$key}->{'image_handler'} = $session_screens{$key}->{'image'}->signal_connect( 'expose-event', \&fct_resize_thumb, $key );

		#packing
		my $tab_infos_sizegroup = Gtk2::SizeGroup->new('vertical');
		$tab_infos_sizegroup->add_widget( $session_screens{$key}->{'filename_label'} );
		$tab_infos_sizegroup->add_widget( $session_screens{$key}->{'folder_label'} );
		$tab_infos_sizegroup->add_widget( $session_screens{$key}->{'size_label'} );
		$tab_infos_sizegroup->add_widget( $session_screens{$key}->{'mime_type_label'} );
		$tab_infos_sizegroup->add_widget( $session_screens{$key}->{'geometry_label'} );

		$vbox_fileinfos->pack_start( $filename_label,                             FALSE, TRUE, 5 );
		$vbox_fileinfos->pack_start( $session_screens{$key}->{'filename_label'},  FALSE, TRUE, 2 );
		$vbox_fileinfos->pack_start( $folder_label,                               FALSE, TRUE, 5 );
		$vbox_fileinfos->pack_start( $session_screens{$key}->{'folder_label'},    FALSE, TRUE, 2 );
		$vbox_fileinfos->pack_start( $size_label,                                 FALSE, TRUE, 10 );
		$vbox_fileinfos->pack_start( $session_screens{$key}->{'size_label'},      FALSE, TRUE, 2 );
		$vbox_fileinfos->pack_start( $mime_type_label,                            FALSE, TRUE, 10 );
		$vbox_fileinfos->pack_start( $session_screens{$key}->{'mime_type_label'}, FALSE, TRUE, 2 );
		$vbox_fileinfos->pack_start( $geometry_label,                             FALSE, TRUE, 10 );
		$vbox_fileinfos->pack_start( $session_screens{$key}->{'geometry_label'},  FALSE, TRUE, 2 );

		$hbox_tab_file->pack_start( $session_screens{$key}->{'image'}, TRUE,  TRUE, 10 );
		$hbox_tab_file->pack_start( $vbox_fileinfos,                   FALSE, TRUE, 1 );
		$hbox_tab_file->pack_start( $vbox_fileinfos2,                  FALSE, TRUE, 1 );

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

	} else {
		my $stats_label = Gtk2::Label->new;
		$stats_label->set_markup( "<b>" . $d->get("Statistic") . "</b>" );

		$session_start_screen{'first_page'}->{'statistics_counter'} = Gtk2::Label->new(
			$notebook->get_n_pages . " " . $d->nget( "screenshot during this session", "screenshots during this session", $notebook->get_n_pages ) );

		$session_start_screen{'first_page'}->{'size_counter'}
			= Gtk2::Label->new( $d->get("Total size") . ": " . Gnome2::VFS->format_file_size_for_display(0) );

		$vbox_all->pack_start( $stats_label,                                                FALSE, TRUE, 1 );
		$vbox_all->pack_start( $session_start_screen{'first_page'}->{'statistics_counter'}, FALSE, TRUE, 1 );
		$vbox_all->pack_start( $session_start_screen{'first_page'}->{'size_counter'},       FALSE, TRUE, 1 );

		$session_start_screen{'first_page'}->{'settings_label'} = Gtk2::Label->new;
		$session_start_screen{'first_page'}->{'settings_label'}->set_markup( "<b>" . $d->get("Current Preferences") . "</b>" );

		$vbox_all2->pack_start_defaults( $session_start_screen{'first_page'}->{'settings_label'} );

		$session_start_screen{'first_page'}->{'filename_label'} = Gtk2::Label->new( $d->get("Filename") . ": " );
		$session_start_screen{'first_page'}->{'folder_label'}   = Gtk2::Label->new( $d->get("Directory") . ": " );

		my $tab_all_sizegroup = Gtk2::SizeGroup->new('vertical');
		$tab_all_sizegroup->add_widget( $session_start_screen{'first_page'}->{'filename_label'} );
		$tab_all_sizegroup->add_widget( $session_start_screen{'first_page'}->{'folder_label'} );

		$vbox_all2->pack_start_defaults( $session_start_screen{'first_page'}->{'filename_label'} );
		$vbox_all2->pack_start_defaults( $session_start_screen{'first_page'}->{'folder_label'} );

		#create iconview for session
		my $viewmodel = Gtk2::ListStore->new( 'Gtk2::Gdk::Pixbuf', 'Glib::String', 'Glib::String' );
		foreach ( keys %session_screens ) {
			$viewmodel->set( $viewmodel->append, 0, $session_screens{$_}->{'thumb'}, 1, $session_screens{$_}->{'short'}, 2, $_ );
		}
		my $view = Gtk2::IconView->new_with_model($viewmodel);
		$view->set_orientation('horizontal');
		$view->set_pixbuf_column(0);
		$view->set_text_column(1);
		$view->set_selection_mode('multiple');
		$view->set_columns(0);
		$view->signal_connect( 'selection-changed', \&evt_iconview_sel_changed,    'sel_changed' );
		$view->signal_connect( 'item-activated',    \&evt_iconview_item_activated, 'item_activated' );

		$session_start_screen{'first_page'}->{'view'}  = $view;
		$session_start_screen{'first_page'}->{'model'} = $viewmodel;

		$hbox_all->pack_start_defaults($vbox_all);
		$hbox_all->pack_start_defaults($vbox_all2);
		$vbox_tab->pack_start( $hbox_all, FALSE, TRUE, 0 );

		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($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, $view );

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

	}

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

	return $vbox;
}

sub fct_resize_thumb {
	my ( $widget, $event, $key ) = @_;

	print "\n$event was emitted by widget $widget and some $key\n" if $shutter_common->get_debug;

	if ( defined $widget ) {
		my $image = $session_screens{$key}->{'image'};
		my $orig  = $session_screens{$key}->{'orig'};
		
		if(defined $image){
			my $pixbuf = $image->get_pixbuf;

			my $old_width  = $image->{'current_width'};
			my $old_height = $image->{'current_height'};
			$image->{'current_height'} = $widget->allocation->height - 60;
			$image->{'current_width'}  = $image->{'current_height'} * $image->{'aspect_ratio'};

			my $decr = 10;
			while ($image->{'current_width'} >= $widget->allocation->width - 50
				|| $image->{'current_height'} >= $widget->allocation->height - 50 )
			{
				$image->{'current_height'} -= $decr;
				$image->{'current_width'} = $image->{'current_height'} * $image->{'aspect_ratio'};
			}

			return FALSE if $image->{'current_width'} < 10 || $image->{'current_height'} < 10;

			if (   $old_width != $image->{'current_width'}
				|| $session_screens{$key}->{'changed'} == TRUE
				|| $session_screens{$key}->{'deleted'} == TRUE )
			{

				my $scaled = $orig->scale_simple( $image->{'current_width'}, $image->{'current_height'}, 'tiles' );
				$image->set_from_pixbuf($scaled);
				$session_screens{$key}->{'changed'} = FALSE;

			}
		}
	}
	return FALSE;
}

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 "" );
	}

	open my $fh_setting, '>', $settingsfile
		or $shutter_dialog->dlg_error_message( $!, $d->get("Settings could not be saved!") );

	#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'} = SHUTTER_VERSION . PPA_VERSION . REV;

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

	utf8::encode $settings{'general'}->{'last_profile_name'};

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

	utf8::encode $settings{'general'}->{'filename'};

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

	utf8::encode $settings{'general'}->{'folder'};

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

	$settings{'general'}->{'selection_tool'} = 1
		if $tool_advanced->get_active;
	$settings{'general'}->{'selection_tool'} = 2
		if $tool_simple->get_active;

	$settings{'general'}->{'zoom_active'} = $zoom_active->get_active();
	$settings{'general'}->{'zoom_size'}   = 1
		if ( $zoom_size1->get_active );
	$settings{'general'}->{'zoom_size'} = 2
		if ( $zoom_size2->get_active );
	$settings{'general'}->{'zoom_size'} = 3
		if ( $zoom_size3->get_active );

	#determining timeout
	if($gnome_web_photo){
		my $web_menu = $shutter_tool->{_web}->get_menu;
		my @timeouts = $web_menu->get_children;
		my $timeout  = undef;
		foreach (@timeouts) {

			if ( $_->get_active ) {
				$timeout = $_->get_children->get_text;
				$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;
		utf8::encode $settings{'general'}->{'prog'};
	}

	$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'}->{'delay'}            = $delay->get_value();
	$settings{'general'}->{'delay_active'}     = $delay_active->get_active();
	$settings{'general'}->{'thumbnail'}        = $thumbnail->get_value();
	$settings{'general'}->{'thumbnail_active'} = $thumbnail_active->get_active();
	$settings{'general'}->{'border'}           = $combobox_border->get_active();
	$settings{'general'}->{'cursor'}           = $combobox_cursor->get_active();
	$settings{'general'}->{'autohide'}         = $hide_active->get_active();
	$settings{'general'}->{'autocopy'}         = $autocopy_active->get_active();
	$settings{'general'}->{'close_at_close'}   = $close_at_close_active->get_active();
	$settings{'general'}->{'save_at_close'}    = $save_at_close_active->get_active();
	$settings{'general'}->{'keybinding'}       = $keybinding_active->get_active();
	$settings{'general'}->{'keybinding_sel'}   = $keybinding_sel_active->get_active();
	$settings{'general'}->{'keybinding_mode'}  = $combobox_keybinding_mode->get_active();
	$settings{'general'}->{'capture_key'}      = $capture_key->get_text();
	$settings{'general'}->{'capture_sel_key'}  = $capture_sel_key->get_text();

	#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();

	#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'};
		$settings{'plugins'}->{$plugin_key}->{'tooltip'}     = $plugins{$plugin_key}->{'tooltip'};
		$settings{'plugins'}->{$plugin_key}->{'lang'}        = $plugins{$plugin_key}->{'lang'};
		utf8::encode $settings{'plugins'}->{$plugin_key}->{'name'};
		utf8::encode $settings{'plugins'}->{$plugin_key}->{'binary'};
		utf8::encode $settings{'plugins'}->{$plugin_key}->{'name_plugin'};
		utf8::encode $settings{'plugins'}->{$plugin_key}->{'category'};
		utf8::encode $settings{'plugins'}->{$plugin_key}->{'tooltip'};
		utf8::encode $settings{'plugins'}->{$plugin_key}->{'lang'};
	}

	#settings
	eval {
		XMLout( \%settings, OutputFile => $fh_setting );
		$fh_setting->close();
		&dlg_status_message( 1, $d->get("Settings saved successfully!") );
	};
	if ($@) {
		$shutter_dialog->dlg_error_message( $@, $d->get("Settings could not be saved!") );
	}

	#session
	open my $fh_session, '>', $sessionfile
		or $shutter_dialog->dlg_error_message( $!, $d->get("Session could not be saved!") );

	#we need to clean the hashkeys, so they become parseable
	my %clean_files;
	my $counter = 0;
	foreach ( sort keys %session_screens ) {

		next unless exists $session_screens{$_}->{'long'};

		#encode filename
		my $utf8_filename = $session_screens{$_}->{'long'};
		utf8::encode $utf8_filename;

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

	eval {
		XMLout( \%clean_files, OutputFile => $fh_session );
		$fh_session->close();
	};
	if ($@) {
		$shutter_dialog->dlg_error_message( $@, $d->get("Session could not be saved!") );
	}

	#accounts
	open my $fh_accounts, '>', $accountsfile
		or $shutter_dialog->dlg_error_message( $!, $d->get("Account-settings could not be saved!") );

	foreach ( keys %accounts ) {
		utf8::encode $accounts{$_}->{'password'};
		utf8::encode $accounts{$_}->{'username'};
		utf8::encode $accounts{$_}->{'register_text'};
	}

	eval {
		XMLout( \%accounts, OutputFile => $fh_accounts );
		$fh_accounts->close();
	};
	if ($@) {
		$shutter_dialog->dlg_error_message( $@, $d->get("Account-settings could not be saved!") );
	}

	return TRUE;
}

sub fct_save_bindings {

	my $client        = Gnome2::GConf::Client->get_default;
	my $shortcut_full = "/apps/metacity/global_keybindings/run_command_screenshot";
	my $shortcut_sel  = "/apps/metacity/global_keybindings/run_command_window_screenshot";
	my $command_full  = "/apps/metacity/keybinding_commands/command_screenshot";
	my $command_sel   = "/apps/metacity/keybinding_commands/command_window_screenshot";

	#set gconf values
	if ( $keybinding_active->get_active() ) {
		$client->set( $command_full, { type => 'string', value => "$shutter_path --full", } );
		$client->set(
			$shortcut_full,
			{   type  => 'string',
				value => $capture_key->get_text(),
			}
		);
	} else {
		$client->set( $command_full,  { type => 'string', value => 'gnome-screenshot', } );
		$client->set( $shortcut_full, { type => 'string', value => 'Print', } );
	}
	if ( $keybinding_sel_active->get_active() ) {
		my $mode = undef;
		if ( $combobox_keybinding_mode->get_active() == 0 ) {
			$mode = "--selection";
		} elsif ( $combobox_keybinding_mode->get_active() == 1 ) {
			$mode = "--window";
		} elsif ( $combobox_keybinding_mode->get_active() == 2 ) {
			$mode = "--section";
		} else {
			$mode = "--window";
		}
		$client->set(
			$command_sel,
			{   type  => 'string',
				value => "$shutter_path $mode",
			}
		);
		$client->set(
			$shortcut_sel,
			{   type  => 'string',
				value => $capture_sel_key->get_text(),
			}
		);
	} else {
		$client->set(
			$command_sel,
			{   type  => 'string',
				value => 'gnome-screenshot --window',
			}
		);
		$client->set( $shortcut_sel, { type => 'string', value => '<Alt>Print', } );
	}

	return TRUE;
}

sub fct_load_settings {
	my ( $widget, $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 ( $shutter_hfunct->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'});	
				}

				$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_filename( $settings_xml->{'general'}->{'folder'} );

				#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'} );

				#selection tool -> submenu
				$tool_advanced->set_active(TRUE)
					if $settings_xml->{'general'}->{'selection_tool'} == 1;
				$tool_simple->set_active(TRUE)
					if $settings_xml->{'general'}->{'selection_tool'} == 2;
				$zoom_active->set_active( $settings_xml->{'general'}->{'zoom_active'} );
				$zoom_size1->set_active(TRUE)
					if $settings_xml->{'general'}->{'zoom_size'} == 1;
				$zoom_size2->set_active(TRUE)
					if $settings_xml->{'general'}->{'zoom_size'} == 2;
				$zoom_size3->set_active(TRUE)
					if $settings_xml->{'general'}->{'zoom_size'} == 3;

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

				#advanced 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'} );
				$delay->set_value( $settings_xml->{'general'}->{'delay'} );
				$delay_active->set_active( $settings_xml->{'general'}->{'delay_active'} );
				$thumbnail->set_value( $settings_xml->{'general'}->{'thumbnail'} );
				$thumbnail_active->set_active( $settings_xml->{'general'}->{'thumbnail_active'} );
				$combobox_border->set_active( $settings_xml->{'general'}->{'border'} );
				$combobox_cursor->set_active( $settings_xml->{'general'}->{'cursor'} );

				#behavior
				$hide_active->set_active( $settings_xml->{'general'}->{'autohide'} );
				$autocopy_active->set_active( $settings_xml->{'general'}->{'autocopy'} );
				$close_at_close_active->set_active( $settings_xml->{'general'}->{'close_at_close'} );
				$save_at_close_active->set_active( $settings_xml->{'general'}->{'save_at_close'} );

				#keybindings
				$keybinding_active->set_active( $settings_xml->{'general'}->{'keybinding'} );
				$keybinding_sel_active->set_active( $settings_xml->{'general'}->{'keybinding_sel'} );
				$capture_key->set_text( $settings_xml->{'general'}->{'capture_key'} );
				$capture_sel_key->set_text( $settings_xml->{'general'}->{'capture_sel_key'} );
				$combobox_keybinding_mode->set_active( $settings_xml->{'general'}->{'keybinding_mode'} );

				#ftp_upload
				$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'} );
			}

			#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(SHUTTER_VERSION . PPA_VERSION . REV ne $settings_xml->{'general'}->{'app_version'}){
					$shutter_common->set_clear_cache(TRUE);
				}	
			}else{
				$shutter_common->set_clear_cache(TRUE);
			}

			#load account data
			&fct_load_accounts($profilename);
			if ( defined $accounts_tree ) {
				&fct_load_accounts_tree;
				$accounts_tree->set_model($accounts_model);
				&fct_set_model_accounts($accounts_tree);
			}

			&dlg_status_message( 1, $d->get("Settings loaded successfully") );
			}

	};
	if ($@) {
		$shutter_dialog->dlg_error_message( $@, $d->get("Settings could not be restored!") );
		unlink $settingsfile;
	}

	#get plugins from cache unless param is set to ignore it
	if ( !$shutter_common->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 ( $shutter_hfunct->file_exists( $settings_xml->{'plugins'}->{$plugin_key}->{'binary'} ) ) {
				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'};
			} else {
				next;
			}
		}
	}

	#maybe there are new plugins...
	&fct_check_installed_plugins;

	if ( defined $effects_tree ) {
		&fct_load_plugin_tree;
		$effects_tree->set_model($effects_model);
		&fct_set_model_plugins($effects_tree);
	}

	return $settings_xml;
}

sub fct_get_program_model {
	my $model = Gtk2::ListStore->new( 'Gtk2::Gdk::Pixbuf', 'Glib::String', 'Glib::Scalar' );

	my $icontheme = Gtk2::IconTheme->get_for_screen( Gtk2::Gdk::Screen->get_default );

	#FIXME - use png as default mime type (is this clever enough?)
	my ( $default, @apps ) = File::MimeInfo::Applications::mime_applications('image/png');

	foreach (@apps) {
		my $program_item = Gtk2::ImageMenuItem->new_with_label();
		my $icon_pixbuf;
		if ( $icontheme->has_icon( $_->Icon ) ) {
			my ( $iw, $ih ) = Gtk2::IconSize->lookup('menu');
			$icon_pixbuf = $icontheme->load_icon( $_->Icon, $ih, 'generic-fallback' );
			$program_item->set_image( Gtk2::Image->new_from_pixbuf($icon_pixbuf) );
		}
		$model->set( $model->append, 0, $icon_pixbuf, 1, $_->Name, 2, $_ );
	}

	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 );

	my $accounts_xml;
	eval { $accounts_xml = XMLin( IO::File->new($accountsfile) ) if $shutter_hfunct->file_exists($accountsfile); };

	if ($@) {
		$shutter_dialog->dlg_error_message( $@, $d->get("Account-settings could not be restored!") );
		unlink $accountsfile;
	}

	#account data, load defaults if nothing is set
	unless ( exists( $accounts_xml->{'ubuntu-pics.de'} ) ) {
		$accounts{'ubuntu-pics.de'}->{host}     = "ubuntu-pics.de";
		$accounts{'ubuntu-pics.de'}->{username} = "";
		$accounts{'ubuntu-pics.de'}->{password} = "";
	} else {
		$accounts{'ubuntu-pics.de'}->{host}     = $accounts_xml->{'ubuntu-pics.de'}->{host};
		$accounts{'ubuntu-pics.de'}->{username} = $accounts_xml->{'ubuntu-pics.de'}->{username};
		$accounts{'ubuntu-pics.de'}->{password} = $accounts_xml->{'ubuntu-pics.de'}->{password};
	}

	$accounts{'ubuntu-pics.de'}->{register} = "http://www.ubuntu-pics.de/registrieren.html";

	#account data, load defaults if nothing is set
	unless ( exists( $accounts_xml->{'imageshack.us'} ) ) {
		$accounts{'imageshack.us'}->{host}     = "imageshack.us";
		$accounts{'imageshack.us'}->{username} = "";
		$accounts{'imageshack.us'}->{password} = "";
	} else {
		$accounts{'imageshack.us'}->{host}     = $accounts_xml->{'imageshack.us'}->{host};
		$accounts{'imageshack.us'}->{username} = $accounts_xml->{'imageshack.us'}->{username};
		$accounts{'imageshack.us'}->{password} = $accounts_xml->{'imageshack.us'}->{password};
	}

	$accounts{'imageshack.us'}->{register} = "http://my.imageshack.us/registration/";

	unless ( exists( $accounts_xml->{'imagebanana.com'} ) ) {
		$accounts{'imagebanana.com'}->{host}     = "imagebanana.com";
		$accounts{'imagebanana.com'}->{username} = "";
		$accounts{'imagebanana.com'}->{password} = "";
	} else {
		$accounts{'imagebanana.com'}->{host}     = $accounts_xml->{'imagebanana.com'}->{host};
		$accounts{'imagebanana.com'}->{username} = $accounts_xml->{'imagebanana.com'}->{username};
		$accounts{'imagebanana.com'}->{password} = $accounts_xml->{'imagebanana.com'}->{password};
	}

	$accounts{'imagebanana.com'}->{register} = "http://www.imagebanana.com/myib/registrieren/";

	foreach ( keys %accounts ) {
		utf8::decode $accounts{$_}->{'username'};
		utf8::decode $accounts{$_}->{'password'};
		$accounts{$_}->{'register_color'} = "blue";
		$accounts{$_}->{'register_text'}  = $d->get("click me");
	}

	return TRUE;
}

sub fct_open_files {
	my (@new_files) = @_;

	return FALSE if scalar(@new_files) < 1;

	my $open_dialog = Gtk2::MessageDialog->new( $window, [qw/modal destroy-with-parent/], 'info', 'close', $d->get("Loading files") );

	$open_dialog->set( 'secondary-text' => $d->get("Please wait while your selected files\nare being integrated into Shutter") . "." );

	$open_dialog->signal_connect( response => sub { $_[0]->destroy } );

	my $open_progress = Gtk2::ProgressBar->new;
	$open_progress->set_no_show_all(TRUE);
	$open_progress->set_ellipsize('middle');
	$open_progress->set_orientation('left-to-right');
	$open_progress->set_fraction(0);

	$open_dialog->vbox->add($open_progress);

	#do not show when min at startup
	unless ( $shutter_common->get_min ) {
		$open_progress->show;
		$open_dialog->show_all;
	}

	my $num_files = scalar(@new_files);
	my $count     = 0;
	foreach my $new_file (@new_files) {

		#refresh the progressbar
		$count++;
		$open_progress->set_fraction( $count / $num_files );
		$open_progress->set_text($new_file);

		#refresh tray icon
		if ( $icon && $icon->isa('Gtk2::StatusIcon') ) {
			$icon->set_blinking(TRUE);
		}

		#refresh gui
		&fct_update_gui;

		#do the real work
		if(&fct_integrate_screenshot_in_notebook( Gnome2::VFS::URI->new ($new_file), undef )){
			&dlg_status_message( 1, $new_file . " " . $d->get("opened") );	
		}
	}
	$open_dialog->response('ok');

	#refresh tray icon
	if ( $icon && $icon->isa('Gtk2::StatusIcon') ) {
		$icon->set_blinking(FALSE);
	}

	return TRUE;
}

sub fct_load_session {

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

	eval {
		my $session_xml = XMLin( IO::File->new($sessionfile) )
			if $shutter_hfunct->file_exists($sessionfile);

		return FALSE if scalar( keys %{$session_xml} ) < 1;

		my $restore_dialog = Gtk2::MessageDialog->new( $window, [qw/modal destroy-with-parent/], 'info', 'close', undef );

		$restore_dialog->set( 'text' => $d->get("Restoring session") );

		$restore_dialog->set( 'secondary-text' => $d->get("Please wait while your saved session\nis being restored") . "." );

		$restore_dialog->signal_connect( response => sub { $_[0]->destroy } );

		my $restore_progress = Gtk2::ProgressBar->new;
		$restore_progress->set_no_show_all(TRUE);
		$restore_progress->set_ellipsize('middle');
		$restore_progress->set_orientation('left-to-right');
		$restore_progress->set_fraction(0);

		$restore_dialog->vbox->add($restore_progress);

		#do not show when min at startup
		unless ( $shutter_common->get_min ) {
			$restore_progress->show;
			$restore_dialog->show_all;
			$restore_progress->grab_focus;
		}

		my $num_files = scalar( keys %{$session_xml} );
		my $count     = 0;
		foreach ( sort keys %{$session_xml} ) {

			#refresh the progressbar
			$count++;
			$restore_progress->set_fraction( $count / $num_files );
			$restore_progress->set_text( ${$session_xml}{$_}{'filename'} );

			#refresh tray icon
			if ( $icon && $icon->isa('Gtk2::StatusIcon') ) {
				$icon->set_blinking(TRUE);
			}

			#refresh gui
			&fct_update_gui;

			#do the real work
			&fct_integrate_screenshot_in_notebook( Gnome2::VFS::URI->new( ${$session_xml}{$_}{'filename'} ), undef );
		}
		$restore_dialog->response('ok');

		#refresh tray icon
		if ( $icon && $icon->isa('Gtk2::StatusIcon') ) {
			$icon->set_blinking(FALSE);
		}

	};
	if ($@) {
		$shutter_dialog->dlg_error_message( $@, $d->get("Session could not be restored!") );

		unlink $sessionfile;

		#refresh tray icon
		if ( $icon && $icon->isa('Gtk2::StatusIcon') ) {
			$icon->set_blinking(FALSE);
		}

	}

	return TRUE;
}

sub fct_screenshot_exists {
	my ($key) = @_;

	#check if file still exists
	unless ( $session_screens{$key}->{'uri'}->exists ) {
		&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("not found") );

		return FALSE;
	}
	return TRUE;
}

sub fct_delete {

	my $key = &fct_get_current_file(undef);

	#single file
	if ($key) {

		if ( $session_screens{$key}->{'uri'}->exists ) {

			#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 );

			#move to trash
			$trash_uri = $trash_uri->append_file_name( $session_screens{$key}->{'short'} );
			$session_screens{$key}->{'uri'}->move( $trash_uri, TRUE ) if $session_screens{$key}->{'uri'}->exists;

		}

		$notebook->remove_page( $notebook->get_current_page );    #delete tab
		&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("deleted") )
			if defined( $session_screens{$key}->{'long'} );

		delete $session_screens{$key};                             # delete from hash

		$window->show_all unless $is_in_tray;

		#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 );
					$notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );
					
					#~ $session_screens{$key}->{'tab_child'}->destroy;

					if ( $session_screens{$key}->{'uri'}->exists ) {

						#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 );

						#move to trash
						$trash_uri = $trash_uri->append_file_name( $session_screens{$key}->{'short'} );
						$session_screens{$key}->{'uri'}->move( $trash_uri, TRUE );

					}

					delete $session_screens{$key};

					&dlg_status_message( 1, $d->get("Selected screenshots deleted") );

				}
			},
			undef
		);

		$window->show_all unless $is_in_tray;

	}

	&fct_update_first_tab;

	return TRUE;
}

sub fct_remove_all {

	foreach my $key ( keys %session_screens ) {
		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( $session_screens{$key} );
	}

	&dlg_status_message( 1, $d->get("All screenshots removed") );
	$window->show_all unless $is_in_tray;

	&fct_update_first_tab;

	return TRUE;
}

sub fct_remove {
	my $key = shift;

	$key = &fct_get_current_file(undef) unless $key;

	#single file
	if ($key) {

		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
		&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session") )
			if defined( $session_screens{$key}->{'long'} );
		delete( $session_screens{$key} );                                                          # delete from hash

		$window->show_all unless $is_in_tray;

	} 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 );

					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( $session_screens{$key} );
				}
			},
			undef
		);

		&dlg_status_message( 1, $d->get("All screenshots removed") );
		$window->show_all unless $is_in_tray;

	}

	&fct_update_first_tab;

	return TRUE;
}

sub fct_update_gui {

	while ( Gtk2->events_pending ) {
		Gtk2->main_iteration;
	}
	Gtk2::Gdk->flush;

	return TRUE;
}

sub fct_clipboard {

	my $key = &fct_get_current_file(undef);

	#single file
	if ($key) {

		return FALSE unless &fct_screenshot_exists($key);

		$clipboard->set_image( $session_screens{$key}->{'orig'} );
		&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("copied to clipboard") );

	}
	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(undef);

	my @plugin_array;

	#single file
	if ($key) {

		return FALSE unless &fct_screenshot_exists($key);

		unless ( keys %plugins > 0 ) {
			$shutter_dialog->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_rename {

	my $key = &fct_get_current_file(undef);

	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 $shutter_common->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);

	&fct_update_first_tab;	

	return TRUE;
}

sub fct_draw {

	my $key = &fct_get_current_file(undef);

	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($shutter_common);
		$drawing_tool->show( $session_screens{$key}->{'long'}, $session_screens{$key}->{'filetype'}, \%session_screens );		
	}

	&fct_control_main_window (TRUE, 'show');

	return TRUE;
}

sub fct_upload {

	my $key = &fct_get_current_file(undef);

	my @upload_array;

	#single file
	if ($key) {

		return FALSE unless &fct_screenshot_exists($key);
		push( @upload_array, $session_screens{$key}->{'long'} );
		&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, $session_screens{$key}->{'long'} );
				}

			},
			undef
		);
		&dlg_upload(@upload_array);
	}
	return TRUE;
}

sub fct_print {

	my $key = &fct_get_current_file(undef);

	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 ( $shutter_hfunct->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;
			&dlg_status_message( 1, $op->get_status_string );
		}
	);

	$op->signal_connect(
		'draw-page' => sub {
			my $op  = shift;
			my $pc  = shift;
			my $int = shift;

			#manip cairo context
			my $cr = $pc->get_cairo_context;

			#see if pixbuf fits on the printing area
			my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file( $pages[$int] );
			if ( $pc->get_width < $pixbuf->get_width || $pc->get_height < $pixbuf->get_height ) {
				$pixbuf = Gtk2::Gdk::Pixbuf->new_from_file_at_scale( $pages[$int], $pc->get_width, $pc->get_height, TRUE );
			}

			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 $dentry = shift;

	my $key = &fct_get_current_file(undef);

	#no program set - take default from settings
	unless ($dentry) {
		my $model         = $progname->get_model();
		my $progname_iter = $progname->get_active_iter();

		if ($progname_iter) {
			$dentry = $model->get_value( $progname_iter, 2 );
		}
	}

	my $exec_call;

	#single file
	if ($key) {

		return FALSE unless &fct_screenshot_exists($key);

		#everything is fine -> open it
		if ( $dentry->wants_uris ) {
			$exec_call = $dentry->parse_Exec( $session_screens{$key}->{'uri'}->to_string );
		} else {
			$exec_call = $dentry->parse_Exec( $session_screens{$key}->{'long'} );
		}

		&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("opened with") . " " . $dentry->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 ( $dentry->wants_uris ) {
						push @open_files, $session_screens{$key}->{'uri'}->to_string;
					} else {
						push @open_files, $session_screens{$key}->{'long'};
					}
				}
			},
			undef
		);
		if ( @open_files > 0 ) {
			if ( $dentry->wants_list ) {
				$exec_call = $dentry->parse_Exec(@open_files);
				&dlg_status_message( 1, $d->get("Opened all files with") . " " . $dentry->Name );
			} else {
				foreach my $file (@open_files) {
					$exec_call .= $dentry->parse_Exec($file) . ";";
				}
			}

		}
	}

	if ($exec_call) {
		foreach ( split /;/, $exec_call ) {
			print Dumper $_ . " &" if $shutter_common->get_debug;
			system( $_ . " &" );
		}

	}
	return TRUE;
}

sub fct_execute_plugin {

	my $arrayref = $_[1];
	my ( $plugin_value, $plugin_name, $plugin_lang, $key, $plugin_dialog, $plugin_progress ) = @$arrayref;

	unless ( $shutter_hfunct->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" ) {
		$plugin_dialog->hide if defined $plugin_dialog;

		#initiate the socket to draw the contents of the plugin to our dialog
		my $plugin_socket = Gtk2::Dialog->new( $plugin_name, $window, [qw/modal destroy-with-parent/] );
		$plugin_socket->set_has_separator(FALSE); 
		my $socket = Gtk2::Socket->new;
		$plugin_socket->vbox->add($socket);
		$socket->signal_connect(
			'plug-removed' => sub {
				print STDERR "GtkPlug Disconnected\n"
					if $shutter_common->get_debug;
				$plugin_socket->destroy();
				return TRUE;
				1;
			}
		);
		printf( "\n", $socket->get_id );
		my $pid = fork;
		if ( $pid < 0 ) {
			$shutter_dialog->dlg_error_message( $d->get("Could not execute plugin") . ": " . $plugin_name, $d->get("Failed") );
		}
		if ( $pid == 0 ) {
			exec(
				sprintf(
					"$^X $plugin_value %d '$session_screens{$key}->{'long'}' $session_screens{$key}->{'width'} $session_screens{$key}->{'height'} $session_screens{$key}->{'filetype'}\n",
					$socket->get_id )
			);
		}
		$plugin_socket->show_all;
		$plugin_socket->run;

		&dlg_status_message( 1, $d->get("Successfully executed plugin") . ": " . $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 $shutter_common->get_debug;
		
		#create a new process, so we are able to cancel the current operation
		my $plugin_process = Proc::Simple->new;

		$plugin_process->start(
			sub {
				system("'$plugin_value' '$session_screens{$key}->{'long'}' '$session_screens{$key}->{'width'}' '$session_screens{$key}->{'height'}' '$session_screens{$key}->{'filetype'}' ");				
				POSIX::_exit(0);
			}
		);

		#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 ) {
			&dlg_status_message( 1, $d->get("Successfully executed plugin") . ": " . $plugin_name );
		}else{
			$shutter_dialog->dlg_error_message( $d->get("Could not execute plugin") . ": " . $plugin_name, $d->get("Failed") );
		}

	}

	return TRUE;
}

sub fct_update_first_tab {

	$session_start_screen{'first_page'}->{'view'}->unselect_all;
	$session_start_screen{'first_page'}->{'model'}->clear;

	print "Updating first tab\n" if $shutter_common->get_debug;

	#create thumbails for iconview
	foreach my $key ( sort keys %session_screens ) {

		print "Updating $key in session\n" if $shutter_common->get_debug;

		unless(defined $session_screens{$key}->{'uri'}){
				&fct_update_tab($key);
				last;				
		}else{
			unless($session_screens{$key}->{'uri'}->exists){
				next;
			}			
		}
		
		#try to generate a new thumbnail
		my $pixbuf = $shutter_thumb->get_thumbnail(
			$session_screens{$key}->{'uri'}->to_string,
			$session_screens{$key}->{'mime_type'},
			$session_screens{$key}->{'mtime'},
			0.5
		);
		
		print "Thumb retrieved\n" if $shutter_common->get_debug;
			
		$session_start_screen{'first_page'}->{'model'}
			->set( $session_start_screen{'first_page'}->{'model'}->append, 0, $pixbuf, 1, $session_screens{$key}->{'short'}, 2, $key );
	
		print "Added to session $key\n" if $shutter_common->get_debug;

	}

	$session_start_screen{'first_page'}->{'view'}->set_model( $session_start_screen{'first_page'}->{'model'} );
	$session_start_screen{'first_page'}->{'statistics_counter'}->set_text(
		scalar( keys(%session_screens) ) . " "
			. $d->nget( "screenshot during this session", "screenshots during this session", scalar( keys(%session_screens) ) ) );

	#handle total size in session
	my $total_size = 0;
	foreach ( keys %session_screens ) {
		next unless $session_screens{$_}->{'size'};
		$total_size += $session_screens{$_}->{'size'};
	}
	$session_start_screen{'first_page'}->{'size_counter'}
		->set_text( $d->get("Total size") . ": " . Gnome2::VFS->format_file_size_for_display($total_size) );

	#if size == 0 => no screenshot in session( handle menu entries properly )
	if ( $shutter_menu->{_menuitem_close_all} ) {

		#enable/disable menu entry when we are in the session tab and selection changes
		&fct_update_menu($total_size);
	}

	#handle session information
	if ( $filename && $saveDir_button && $combobox_settings_profiles ) {

		if ( $combobox_settings_profiles->get_active_text ) {
			#display text on label...
			$session_start_screen{'first_page'}->{'settings_label'}
				->set_markup( "<b>" . $d->get("Current Preferences") . "</b>" . " (" . $combobox_settings_profiles->get_active_text . ")" );
			#...and statusbar
			$status2->push(1, $d->get("Current Profile") . ": " . $combobox_settings_profiles->get_active_text);
		} else {
			$session_start_screen{'first_page'}->{'settings_label'}->set_markup( "<b>" . $d->get("Current Preferences") . "</b>" );
			$status2->push(1, "");
		}

		my $current_folder = $saveDir_button->get_filename;

		if ( $settings_xml->{'general'}->{'folder_force'} || !$current_folder ) {
			if ( exists $settings_xml->{'general'}->{'folder'} ) {
				$current_folder = $settings_xml->{'general'}->{'folder'};
			} else {
				$current_folder = $ENV{'HOME'};
			}
			$settings_xml->{'general'}->{'folder_force'} = FALSE;
		}

		if ( $filename->get_text ne "" ) {
			$session_start_screen{'first_page'}->{'filename_label'}->set_text( $d->get("Filename") . ": " . $filename->get_text );
		} else {
			$session_start_screen{'first_page'}->{'filename_label'}->set_text( $d->get("Filename") . ": -" );
		}

		$session_start_screen{'first_page'}->{'folder_label'}->set_text( $d->get("Directory") . ": " . $current_folder );
	}

	return TRUE;
}

sub fct_save_as {
	my (@keys) = @_;
	
	foreach my $key (@keys){
		
		my $fs = Gtk2::FileChooserDialog->new(
			$d->get("Choose a location to save to"),
			$window, 'save',
			'gtk-cancel' => 'reject',
			'gtk-save'   => 'accept'
		);

		$fs->set_current_folder( $session_screens{$key}->{'folder'} );
		$fs->set_current_name( $session_screens{$key}->{'short'} );

		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
		#the user can decide to save in jpeg, png or bmp format
		my $counter = 0;
		foreach ( Gtk2::Gdk::Pixbuf->get_formats ) {
			
			#add all known formats to the dialog
			#but filter out some special ones like svg
			#FIXME write in SVG via cairo?
			$combobox_save_as_type->insert_text( $counter, $_->{name} . " - " . $_->{description} )
			unless ($_->{name} =~ /svg/);
			
			#set active when mime_type is matching
			#loop because multiple mime types are registered for fome file formats
			foreach my $mime (@{$_->{mime_types}}){
				$combobox_save_as_type->set_active($counter)
					if $mime eq $session_screens{$key}->{'mime_type'};		
			}
			$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 for example
				#~ print $choosen_format . "\n";

				unless ( $filename =~ /.*\.$choosen_format$/ ) {
					$filename =~ s/\..*$/\.$choosen_format/;
				}

				#parse filename
				my ( $short, $folder, $ext ) = fileparse( $filename, '\..*' );

				$fs->set_current_name( $short . $ext );
			}
		);

		$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, '\..*' );

			#handle file format
			my $choosen_format = $combobox_save_as_type->get_active_text;
			$choosen_format =~ s/ \-.*//;    #get png or jpeg for example

			unless ( $filename =~ /.*\.$choosen_format$/ ) {
				$filename .= "." . $choosen_format;
			}

			unless ( $shutter_hfunct->file_exists($filename) ) {
				#save as (pixbuf, new_filename, filetype, quality - auto here, old_filename)
				if($shutter_pix->save_pixbuf_to_file($session_screens{$key}->{'orig'}, $filename, $session_screens{$key}->{'long'}, $choosen_format)){

					#cancel handle
					if ( exists $session_screens{$key}->{'handle'} ) {
						
						$session_screens{$key}->{'handle'}->cancel;
					}
					if(&fct_update_tab( $key, undef, Gnome2::VFS::URI->new($filename) )){
						#setup a new filemonitor, so we get noticed if the file changed
						&fct_add_file_monitor($key);

						&dlg_status_message( 1, "$session_screens{ $key }->{ 'long' } " . $d->get("saved") );
					}
					
				}
				
			} 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 = $shutter_dialog->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.$ext . "'" ),
					undef, undef, undef,
					$replace_btn, undef, undef
				);

				if ( $response == 40 ) {
					if($shutter_pix->save_pixbuf_to_file($session_screens{$key}->{'orig'}, $filename, $session_screens{$key}->{'long'}, $choosen_format)){

						#cancel handle
						if ( exists $session_screens{$key}->{'handle'} ) {
							
							$session_screens{$key}->{'handle'}->cancel;
						}

						if(&fct_update_tab( $key, undef, Gnome2::VFS::URI->new($filename) )){

							#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);
								}
							}	

							&dlg_status_message( 1, "$session_screens{ $key }->{ 'long' } " . $d->get("saved") );					

						}

					}	

				}

			}

		} 	
	
		$fs->destroy();
		
	}
		
}

sub fct_get_current_file {
	my $index = shift;

	my $curr_page;
	if ($index) {
		$curr_page = $notebook->get_nth_page($index);
	} else {
		$curr_page = $notebook->get_nth_page( $notebook->get_current_page );
	}
	my $key = undef;
	foreach ( keys %session_screens ) {
		next unless ( exists $session_screens{$_}->{'tab_child'} );
		next unless ($curr_page);
		if ( $session_screens{$_}->{'tab_child'} == $curr_page ) {
			$key = $_;
		}
	}
	
	
	
	return $key;
}

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;

	#update fileinfos
	if ( &fct_create_thumbnail_and_fileinfos( $key, $pixbuf, $uri ) ) {

		#update tab icon - maybe pic changed due to use of plugin or drawing tool
		$session_screens{$key}->{'tab_icon'}->set_from_pixbuf( $session_screens{$key}->{'thumb'} );

		$session_screens{$key}->{'filename_label'}->set_text( $session_screens{$key}->{'uri'}->extract_short_name );
		$tooltips->set_tip( $session_screens{$key}->{'filename_label'}, $session_screens{$key}->{'uri'}->to_string );

		$session_screens{$key}->{'folder_label'}->set_text( $session_screens{$key}->{'uri'}->extract_dirname );
		$tooltips->set_tip( $session_screens{$key}->{'folder_label'}, $session_screens{$key}->{'uri'}->extract_dirname );

		$session_screens{$key}->{'mime_type_label'}->set_text( $session_screens{$key}->{'mime_type'} );

		$session_screens{$key}->{'size_label'}->set_text( Gnome2::VFS->format_file_size_for_display( $session_screens{$key}->{'size'} ) );

		$session_screens{$key}->{'geometry_label'}->set_text( $session_screens{$key}->{'width'} . "x" . $session_screens{$key}->{'height'} );

		eval {
			if ( $session_screens{$key}->{'image'}->get_pixbuf )
			{
				$session_screens{$key}->{'image'}->{'current_width'}  = $session_screens{$key}->{'orig'}->get_width;
				$session_screens{$key}->{'image'}->{'current_height'} = $session_screens{$key}->{'orig'}->get_height;
				$session_screens{$key}->{'image'}->{'aspect_ratio'}
					= $session_screens{$key}->{'image'}->{'current_width'} / $session_screens{$key}->{'image'}->{'current_height'};

				print "Manually signal_emit for $key \n" if $shutter_common->get_debug;

				$session_screens{$key}->{'image'}->signal_emit( 'expose-event', Gtk2::Gdk::Event->new('expose') );
			}
		};
		if ($@) {

			#we handle no case here ;-)
			$shutter_dialog->dlg_error_message( $@, $d->get("Failed") );

			#FIXME, not very cool to do the update manually all the time
			&fct_update_first_tab;

			return FALSE;
		}

	} else {

		#delete page and hash entry
		if($session_screens{$key}->{'tab_child'}){
			$notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );
		}
		
		delete $session_screens{$key};	

		#FIXME, not very cool to do the update manually all the time
		&fct_update_first_tab;

		return FALSE;

	}

	#FIXME, not very cool to do the update manually all the time
	&fct_update_first_tab;

	return TRUE;
}

sub fct_get_latest_tab_key {
	my $max_key = 0;
	foreach my $key ( keys %session_screens ) {
		$key =~ /\[(.*)\]/;
		$max_key = $1 if ( $1 > $max_key );
	}
	return $max_key + 1;
}

sub fct_imagemagick_perform {
	my ( $function, $file, $data ) = @_;
	my $image 	= Image::Magick->new;
	my $result 	= undef;
	$file = $shutter_hfunct->switch_home_in_file($file);
	
	$result = $image->ReadImage($file);
	# print the error message
	if($result){
		#destroy object
		undef $image;
		warn "$result";      
  		return $result;
	}

	if ( $function eq "reduce_colors" ) {
		$image->Quantize( colors => 2**$1 );
		$result = $image->WriteImage( filename => $file );
		# print the error message
		if($result){
			#destroy object
			undef $image;
			warn "$result";      
			return $result;
		}
	} 
	
	#destroy object
	undef $image;

	return FALSE;
}

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 );
			utf8::encode $progname_value;
		}

		#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 ) = @_;

	$filename_value =~ s/\\//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;
		$pos_proc++;

		while ( $pos_proc <= length($filename_value) ) {
			if ( index( $filename_value, "N", $pos_proc ) != -1 ) {
				$n_counter++;
				$pos_proc++;
			} else {
				last;
			}
		}
		print "$n_counter Ns used in wild-card\n" if $shutter_common->get_debug;
		my $marks = "";
		my $i     = 0;

		while ( $i < $n_counter ) {
			$marks .= '\d';
			$i++;
		}

		$filename_value =~ s/\%N{1,}/$marks/g;
		print "Searching for files with pattern: $filename_value.$filetype_value\n"
			if $shutter_common->get_debug;

		#get_all files from directory
		#we handle the listing with GnomeVFS to read remote dirs as well
		my @files;
		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 = $shutter_dialog->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
		while ( my ( $result, $file ) = $uri_list->read_next ) {
			if ( $result eq 'ok' ) {
				my $fileinfo = Gnome2::VFS::FileInfo->new($file);
				my $search_pattern = $filename_value."\.".$filetype_value;
				push @files, $fileinfo->{'name'} if $fileinfo->{'name'} =~ /$search_pattern/;
			} elsif ( $result eq 'error-eof' ) {
				$uri_list->close();
				last;
			} else {
				next;
			}
		}

		@files = sort { $b cmp $a } @files;

		if ( $shutter_common->get_debug ) {
			print "All files in directory for this pattern:\n";
			foreach (@files) {
				print $_. " \n";
			}
		}

		#check pos of %NN
		#~ $filename_value =~ s/\\d/d/g;
		my $pos = index( "$filename_value", '\d', 0 );
		my $next_count = 0;
		unless ( $pos == -1 ) {
			foreach (@files) {
				$next_count = substr( $_, $pos, $n_counter );
				next unless $next_count =~ /^(\d+\.?\d*|\.\d+)$/;
				print "Counter at position $pos - $next_count is currently greatest value...\n"
					if $shutter_common->get_debug;
				last;
			}
		}
		$next_count = 0 unless $next_count =~ /^(\d+\.?\d*|\.\d+)$/;
		$next_count = sprintf( "%0" . $n_counter . "d", $next_count + 1 );
		$marks = quotemeta $marks;
		$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 $shutter_common->get_debug;
		}
	}

	return $new_uri;
}

sub fct_check_installed_plugins {

	my @plugin_paths = ( "$shutter_root/share/shutter/resources/system/plugins/*/*", "$ENV{'HOME'}/.shutter/plugins/*/*" );

	foreach my $plugin_path (@plugin_paths) {
		my @plugins = glob($plugin_path);
		foreach (@plugins) {
			if ( -d $_ ) {
				my $dir_name = $_;

				#parse filename
				my ( $name, $folder, $type ) = fileparse( $dir_name, '\..*' );

				if ( $shutter_hfunct->file_exists("$dir_name/$name") ) {

					unless ( $plugins{$_}->{'binary'}
						&& $plugins{$_}->{'name'}
						&& $plugins{$_}->{'category'}
						&& $plugins{$_}->{'tooltip'}
						&& $plugins{$_}->{'lang'} )
					{

						print "\nINFO: new plugin information detected - $dir_name/$name\n";

						#path to executable
						$plugins{$_}->{'binary'} = "$dir_name/$name";

						#name
						$plugins{$_}->{'name'} = &fct_plugin_get_info( $plugins{$_}->{'binary'}, 'name' );

						#category
						$plugins{$_}->{'category'} = &fct_plugin_get_info( $plugins{$_}->{'binary'}, 'sort' );

						#tooltip
						$plugins{$_}->{'tooltip'} = &fct_plugin_get_info( $plugins{$_}->{'binary'}, 'tip' );

						#language (shell, perl etc.)
						$plugins{$_}->{'lang'} = &fct_plugin_get_info( $plugins{$_}->{'binary'}, 'lang' );

					}

					$plugins{$_}->{'lang'} = "shell"
						if $plugins{$_}->{'lang'} eq "";

					chomp( $plugins{$_}->{'name'} );
					chomp( $plugins{$_}->{'category'} );
					chomp( $plugins{$_}->{'tooltip'} );
					chomp( $plugins{$_}->{'lang'} );

					#pixbuf
					$plugins{$_}->{'pixbuf'} = $plugins{$_}->{'binary'} . ".png"
						if ( $shutter_hfunct->file_exists( $plugins{$_}->{'binary'} . ".png" ) );
					$plugins{$_}->{'pixbuf'} = $plugins{$_}->{'binary'} . ".svg"
						if ( $shutter_hfunct->file_exists( $plugins{$_}->{'binary'} . ".svg" ) );

					if ( $shutter_hfunct->file_exists( $plugins{$_}->{'pixbuf'} ) ) {
						$plugins{$_}->{'pixbuf_object'}
							= Gtk2::Gdk::Pixbuf->new_from_file_at_size( $plugins{$_}->{'pixbuf'}, Gtk2::IconSize->lookup('menu') );
					} else {
						$plugins{$_}->{'pixbuf'} = "$shutter_root/share/shutter/resources/icons/executable.svg";
						$plugins{$_}->{'pixbuf_object'}
							= Gtk2::Gdk::Pixbuf->new_from_file_at_size( $plugins{$_}->{'pixbuf'}, Gtk2::IconSize->lookup('menu') );
					}
					if ( $shutter_common->get_debug ) {
						print "$plugins{$_}->{'name'} - $plugins{$_}->{'binary'}\n";
					}
				} else {
					delete $plugins{$_};
				}    #endif binary exists
			}
		}
	}

	return TRUE;
}

sub fct_plugin_get_info {
	my ( $plugin, $info ) = @_;

	my $plugin_info = `$plugin $info`;
	utf8::decode $plugin_info;

	return $plugin_info;
}

sub fct_create_thumbnail_and_fileinfos {

	#mandatory
	my $key = shift;
	return FALSE unless $key;

	#optional, e.g.used by fct_integrate...
	my $pixbuf = shift;
	my $uri    = shift;

	$session_screens{$key}->{'uri'}      = $uri if $uri;
	$session_screens{$key}->{'mtime'} 	 = -1 unless $session_screens{$key}->{'mtime'};

	#anything wrong?	
	return FALSE unless $session_screens{$key}->{'uri'};

	#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){

		$session_screens{$key}->{'fileinfo'}  = $session_screens{$key}->{'uri'}->get_file_info('default');

		#does the file exist?
		if($session_screens{$key}->{'uri'}->exists){
			
			#maybe we need no update
			#~ return TRUE if $session_screens{$key}->{'fileinfo'}->{'mtime'} == $session_screens{$key}->{'mtime'};

			print "Updating fileinfos for key: $key\n" if $shutter_common->get_debug;

			$session_screens{$key}->{'mtime'}      = $session_screens{$key}->{'fileinfo'}->{'mtime'};
			$session_screens{$key}->{'size'}      = $session_screens{$key}->{'fileinfo'}->{'size'};

			$session_screens{$key}->{'short'}    = $session_screens{$key}->{'uri'}->extract_short_name;
			$session_screens{$key}->{'long'}     = $session_screens{$key}->{'uri'}->get_path;
			$session_screens{$key}->{'folder'}   = $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'} = fileparse( $session_screens{$key}->{'long'}, '\..*' );
			$session_screens{$key}->{'name'} = $session_screens{$key}->{'short'};
			$session_screens{$key}->{'name'} =~ s/\.$session_screens{$key}->{'filetype'}//g;

			#mime type
			$session_screens{$key}->{'mime_type'} = Gnome2::VFS->get_mime_type_for_name( $session_screens{$key}->{'uri'}->to_string );

			eval {
				
				#maybe we have a pixbuf already (e.g. after taking a screenshot)
				unless ($pixbuf) {
					$session_screens{$key}->{'orig'} = Gtk2::Gdk::Pixbuf->new_from_file( $session_screens{$key}->{'long'} );		
				} else {
					$session_screens{$key}->{'orig'} = $pixbuf;
				}

				#get dimensions - using the pixbuf
				$session_screens{$key}->{'width'}  = $session_screens{$key}->{'orig'}->get_width;
				$session_screens{$key}->{'height'} = $session_screens{$key}->{'orig'}->get_height;

				#get thumbnail (tab header)
				$session_screens{$key}->{'thumb'} = $shutter_thumb->get_thumbnail(
					$session_screens{$key}->{'uri'}->to_string,
					$session_screens{$key}->{'mime_type'},
					$session_screens{$key}->{'mtime'},
					0.2
				);

			};

		}else{
			#mark file as deleted
			$session_screens{$key}->{'deleted'} = TRUE;	
		}

		if ($@ || $session_screens{$key}->{'deleted'}) {

			#we only handle one case here:
			#file was deleted in filesystem and we got informed about that...
			if ( defined $session_screens{$key}->{'deleted'} && $session_screens{$key}->{'deleted'} == TRUE ) {
				
				my $response = $shutter_dialog->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){
							
					#delete page and hash entry
					$notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );
					
					&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("deleted") )
					if defined( $session_screens{$key}->{'long'} );

					delete $session_screens{$key};	
					
				}elsif($response == 20){
					
					#try to resave the file
					if($shutter_pix->save_pixbuf_to_file($session_screens{$key}->{'orig'}, $session_screens{$key}->{'long'}, $session_screens{$key}->{'long'}, $session_screens{$key}->{'filetype'})){

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

						&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $shutter_common->get_gettext->get("saved"));
					
					#resave failed, so we delete the screenshot	
					}else{

						#cancel handle
						if ( exists $session_screens{$key}->{'handle'} ) {
							
							$session_screens{$key}->{'handle'}->cancel;
						}

						#delete page and hash entry
						if($session_screens{$key}->{'tab_child'}){
							$notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );
						}
						
						delete $session_screens{$key};						

					}	
				
				}

				#all other cases are unknown => show "real" error
			} else {

				#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;
			
			}

			return FALSE;
				
		#no error occured 	
		}else{
			return TRUE;	
		}
	}

	#could not load the file => show an error message
	my $response = $shutter_dialog->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,
		$@
	);	

	#delete page and hash entry
	if($session_screens{$key}->{'tab_child'}){
		$notebook->remove_page( $notebook->page_num( $session_screens{$key}->{'tab_child'} ) );
	}
	
	delete $session_screens{$key};	
	
	return FALSE;
	
}

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 $screen = Gnome2::Wnck::Screen->get_default;
	$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($screen->can('get_window_manager_name')){
		$wm_name = $screen->get_window_manager_name;
	}

	my $active_workspace = $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 "one workspace" - "multiple viewports" model for example
	#	default gnome wm metacity simply uses multiple workspaces
	#we will try to handle them by name

	#compiz
	if ( $wm_name =~ /compiz/ ) {

		#calculate viewports with size of workspace
		my $vpx = $active_workspace->get_viewport_x;
		my $vpy = $active_workspace->get_viewport_y;

		my $n_viewports_column = int( $active_workspace->get_width / $screen->get_width );
		my $n_viewports_rows   = int( $active_workspace->get_height / $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 * $screen->get_width, $j * $screen->get_height );
				my $vp_name = "$wm_name x: $i y: $j";

				print "shutter_wrksp_direct_compiz" . $vp[0] . "x" . $vp[1] . "\n"
					if $shutter_common->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 @workspaces = ();
		for ( my $wcount = 0; $wcount < $screen->get_workspace_count; $wcount++ ) {
			push( @workspaces, $screen->get_workspace($wcount) );
		}

		foreach my $space (@workspaces) {
			next unless defined $space;

			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->get_number == $space->get_number ) {
				$wrkspace_item->set_sensitive(FALSE);
			}
		}
	}

	my $n_mons = Gtk2::Gdk::Screen->get_default->get_n_monitors;

	#use only current monitore
	$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);
	}

	$shutter_tool->{_full}->set_menu($menu_wrksp);
	$menu_wrksp->show_all();
	return $menu_wrksp;
}

sub fct_ret_window_menu {
	my $screen = Gnome2::Wnck::Screen->get_default;
	$screen->force_update();

	my $menu_windows = Gtk2::Menu->new;
	foreach my $win ( $screen->get_windows ) {
		if ( $win->is_visible_on_workspace( $screen->get_active_workspace ) ) {
			my $window_item = Gtk2::ImageMenuItem->new_with_label( $win->get_name );
			$window_item->set_image( Gtk2::Image->new_from_pixbuf( $win->get_mini_icon ) );
			$window_item->signal_connect(
				'activate' => \&evt_take_screenshot,
				"shutter_window_direct" . $win->get_xid
			);
			$menu_windows->append($window_item);
		}
	}
	$shutter_tool->{_window}->set_menu($menu_windows);
	$menu_windows->show_all;
	return $menu_windows;
}

sub fct_ret_tray_menu {

	my $tray_menu       = Gtk2::Menu->new();
	my $menuitem_select = Gtk2::ImageMenuItem->new( $d->get("Selection") );
	$menuitem_select->set_image(
		Gtk2::Image->new_from_pixbuf(
			Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$shutter_root/share/shutter/resources/icons/selection.svg", Gtk2::IconSize->lookup('menu') )
		)
	);
	$menuitem_select->signal_connect(
		activate => \&evt_take_screenshot,
		'tray_select'
	);
	my $menuitem_raw = Gtk2::ImageMenuItem->new( $d->get("Full Screen") );
	$menuitem_raw->set_image(
		Gtk2::Image->new_from_pixbuf(
			Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$shutter_root/share/shutter/resources/icons/fullscreen.svg", Gtk2::IconSize->lookup('menu') )
		)
	);
	$menuitem_raw->signal_connect(
		activate => \&evt_take_screenshot,
		'tray_raw'
	);
	my $menuitem_window = Gtk2::ImageMenuItem->new( $d->get("Window") );
	$menuitem_window->set_image(
		Gtk2::Image->new_from_pixbuf(
			Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$shutter_root/share/shutter/resources/icons/sel_window.svg", Gtk2::IconSize->lookup('menu') )
		)
	);
	$menuitem_window->signal_connect(
		activate => \&evt_take_screenshot,
		'tray_window'
	);
	my $menuitem_window_sect = Gtk2::ImageMenuItem->new( $d->get("Section") );
	$menuitem_window_sect->set_image(
		Gtk2::Image->new_from_pixbuf(
			Gtk2::Gdk::Pixbuf->new_from_file_at_size(
				"$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'
	);
	my $menuitem_web = Gtk2::ImageMenuItem->new( $d->get("Web") );
	$menuitem_web->set_sensitive($gnome_web_photo);
	$menuitem_web->set_image(
		Gtk2::Image->new_from_pixbuf(
			Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$shutter_root/share/shutter/resources/icons/web_image.svg", Gtk2::IconSize->lookup('menu') )
		)
	);
	$menuitem_web->signal_connect(
		activate => \&evt_take_screenshot,
		'tray_web'
	);
	my $menuitem_info = Gtk2::ImageMenuItem->new( $d->get("Info") );
	$menuitem_info->set_image( Gtk2::Image->new_from_icon_name( 'gtk-about', 'menu' ) );
	$menuitem_info->signal_connect( "activate", \&evt_about, $window );
	my $menuitem_quit = Gtk2::ImageMenuItem->new( $d->get("Quit") );
	$menuitem_quit->set_image( Gtk2::Image->new_from_icon_name( 'gtk-quit', 'menu' ) );
	$menuitem_quit->signal_connect( "activate", \&evt_delete_window, 'menu_quit' );
	$tray_menu->append($menuitem_select);
	$tray_menu->append( Gtk2::SeparatorMenuItem->new );
	$tray_menu->append($menuitem_raw);
	$tray_menu->append( Gtk2::SeparatorMenuItem->new );
	$tray_menu->append($menuitem_window);
	$tray_menu->append($menuitem_window_sect);
	$tray_menu->append( Gtk2::SeparatorMenuItem->new );
	$tray_menu->append($menuitem_web);
	$tray_menu->append( Gtk2::SeparatorMenuItem->new );
	$tray_menu->append($menuitem_info);
	$tray_menu->append($menuitem_quit);
	$tray_menu->show_all;

	return $tray_menu;
}

sub fct_ret_sel_menu {

	#PREF MENU
	my $menu_settings = Gtk2::Menu->new;
	$zoom_active = Gtk2::CheckMenuItem->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);
	}

	my $menu_size  = Gtk2::MenuItem->new_with_label( $d->get("Size of zoom window") );
	my $menu_size2 = Gtk2::Menu->new;
	$zoom_size1 = Gtk2::RadioMenuItem->new( undef,       $d->get("Small") );
	$zoom_size2 = Gtk2::RadioMenuItem->new( $zoom_size1, $d->get("Medium") );
	$zoom_size3 = Gtk2::RadioMenuItem->new( $zoom_size1, $d->get("Large") );

	if ( defined $settings_xml->{'general'}->{'zoom_size'} ) {
		$zoom_size1->set_active(TRUE)
			if $settings_xml->{'general'}->{'zoom_size'} == 1;
		$zoom_size2->set_active(TRUE)
			if $settings_xml->{'general'}->{'zoom_size'} == 2;
		$zoom_size3->set_active(TRUE)
			if $settings_xml->{'general'}->{'zoom_size'} == 3;
	} else {
		$zoom_size1->set_active(TRUE);
	}

	#TOP MENU
	my $menu_sel = Gtk2::Menu->new;

	#advanced tool
	$tool_advanced = Gtk2::RadioMenuItem->new( undef, $d->get("Advanced selection tool") );

	#simple tool
	$tool_simple = Gtk2::RadioMenuItem->new( $tool_advanced, $d->get("Simple selection tool") );

	#and some more preferences
	my $advanced_settings = Gtk2::MenuItem->new_with_label( $d->get("Preferences") );

	$menu_sel->append($tool_advanced);
	$menu_sel->append($tool_simple);
	$menu_sel->append($advanced_settings);

	$menu_size->set_submenu($menu_size2);
	$menu_size2->append($zoom_size1);
	$menu_size2->append($zoom_size2);
	$menu_size2->append($zoom_size3);

	$menu_settings->append($zoom_active);
	$menu_settings->append($menu_size);
	$advanced_settings->set_submenu($menu_settings);

	$tool_simple->signal_connect(
		'activate' => sub {
			my $widget = shift;
			if ( $widget->get_active ) {
				$advanced_settings->set_sensitive(TRUE);
			} else {
				$advanced_settings->set_sensitive(FALSE);
			}
		}
	);

	#set saved/default settings
	if ( defined $settings_xml->{'general'}->{'selection_tool'} ) {
		if ( $settings_xml->{'general'}->{'selection_tool'} == 1 ) {
			$tool_advanced->set_active(TRUE);
			$advanced_settings->set_sensitive(FALSE);
		} elsif ( $settings_xml->{'general'}->{'selection_tool'} == 2 ) {
			$tool_simple->set_active(TRUE);
			$advanced_settings->set_sensitive(TRUE);
		}
	} else {
		$tool_advanced->set_active(TRUE);
		$advanced_settings->set_sensitive(FALSE);
	}

	#check if Gtk2::ImageView is supported
	if ($gtkimageview) {
		$tooltips->set_tip( $tool_advanced,
			$d->get("The advanced selection tool allows you to enlarge/shrink or move your selected area\nuntil you finally take the screenshot.") );
	} else {
		$tool_advanced->set_sensitive(FALSE);
		$tooltips->set_tip( $tool_advanced, $d->get("Gtk2::ImageView needs to be installed for this feature") );

		#needs to be enabled by default now
		$tool_simple->set_active(TRUE);
		$advanced_settings->set_sensitive(TRUE);
	}

	$tooltips->set_tip( $tool_simple,
		$d->get("The simple selection tool is the fastest way of taking a screenshot.\nIt provides an optional zoom window for precise shots.") );

	$menu_sel->show_all;

	return $menu_sel;
}

sub fct_ret_program_menu {
	my $icontheme     = Gtk2::IconTheme->get_for_screen( Gtk2::Gdk::Screen->get_default );
	my $menu_programs = Gtk2::Menu->new;

	#take $key (mime) directly
	my $key = &fct_get_current_file(undef);

	#search selected files for mime...
	unless ($key) {

		#no iconview ??
		return $menu_programs unless $session_start_screen{'first_page'}->{'view'};
		$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
	return $menu_programs unless $key;

	#	my $mime_type = Gnome2::VFS::Mime::Type->new ($session_screens{$key}->{'mime_type'});
	#	my @apps = $mime_type->get_all_applications_for_uri( $session_screens{$key}->{'uri'} );

	#FIXME
	#cannot get icon with GnomeVFS
	#libgnomevfs-WARNING **:
	#Cannot call gnome_vfs_mime_application_get_icon
	#with a GNOMEVFSMimeApplication structure
	#constructed by the deprecated application registry
	return $menu_programs unless exists $session_screens{$key}->{'mime_type'};

	my ( $default, @apps ) = File::MimeInfo::Applications::mime_applications( $session_screens{$key}->{'mime_type'} );
	foreach my $app (@apps) {

		my $program_item = Gtk2::ImageMenuItem->new_with_label( $app->Name );
		if ( $icontheme->has_icon( $app->Icon ) ) {
			my ( $iw, $ih ) = Gtk2::IconSize->lookup('menu');
			my $icon_pixbuf = $icontheme->load_icon( $app->Icon, $ih, 'generic-fallback' );
			$program_item->set_image( Gtk2::Image->new_from_pixbuf($icon_pixbuf) );
		}
		$program_item->signal_connect(
			'activate' => sub {
				&fct_open_with_program($app);
			}
		);

		$menu_programs->append($program_item);
	}

	$menu_programs->show_all;
	return $menu_programs;
}

sub fct_ret_web_menu {
	my $menu_web = Gtk2::Menu->new;
	my $timeout1 = Gtk2::RadioMenuItem->new( undef, $d->get("Timeout") . ": 5" );
	my $timeout2 = Gtk2::RadioMenuItem->new( $timeout1, $d->get("Timeout") . ": 10" );
	my $timeout3 = Gtk2::RadioMenuItem->new( $timeout1, $d->get("Timeout") . ": 15" );
	$timeout2->set_active(TRUE);
	$menu_web->append($timeout1);
	$menu_web->append($timeout2);
	$menu_web->append($timeout3);

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

		#determining timeout
		my @timeouts = $menu_web->get_children;
		my $timeout  = undef;
		foreach (@timeouts) {
			$timeout = $_->get_children->get_text;
			$timeout =~ /([0-9]+)/;
			$timeout = $1;
			if ( $settings_xml->{'general'}->{'web_timeout'} == $timeout ) {
				$_->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 = Gtk2::Menu->new;

	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' );

	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{$_}->{'register'}, 4, $accounts{$_}->{'register_color'}, 5,
			$accounts{$_}->{'register_text'}
		);
	}

	return TRUE;
}

sub fct_load_plugin_tree {

	$effects_model = Gtk2::ListStore->new(
		'Gtk2::Gdk::Pixbuf', 'Glib::String', 'Glib::String', 
		'Glib::String', 'Glib::String', 'Glib::String', 
		'Glib::String',
	);
	foreach ( sort keys %plugins ) {
		if ( $plugins{$_}->{'binary'} ) {

			#pixbuf
			$plugins{$_}->{'pixbuf'} = $plugins{$_}->{'binary'} . ".png"
				if ( $shutter_hfunct->file_exists( $plugins{$_}->{'binary'} . ".png" ) );
			$plugins{$_}->{'pixbuf'} = $plugins{$_}->{'binary'} . ".svg"
				if ( $shutter_hfunct->file_exists( $plugins{$_}->{'binary'} . ".svg" ) );

			if ( $shutter_hfunct->file_exists( $plugins{$_}->{'pixbuf'} ) ) {
				$plugins{$_}->{'pixbuf_object'}
					= Gtk2::Gdk::Pixbuf->new_from_file_at_size( $plugins{$_}->{'pixbuf'}, Gtk2::IconSize->lookup('menu') );
			} else {
				$plugins{$_}->{'pixbuf'} = "$shutter_root/share/shutter/resources/icons/executable.svg";
				$plugins{$_}->{'pixbuf_object'}
					= Gtk2::Gdk::Pixbuf->new_from_file_at_size( $plugins{$_}->{'pixbuf'}, Gtk2::IconSize->lookup('menu') );
			}

			$effects_model->set(
				$effects_model->append,     
				0, $plugins{$_}->{'pixbuf_object'}, 1, $plugins{$_}->{'name'},
				2, $plugins{$_}->{'category'}, 3, $plugins{$_}->{'tooltip'},  
				4, $plugins{$_}->{'lang'}, 5, $plugins{$_}->{'binary'}, 6, $_,
			);
		} else {
			print "\nWARNING: Plugin $_ is not configured properly, ignoring\n";
			delete $plugins{$_};
		}
	}

	return TRUE;
}

sub fct_set_model_accounts {
	my $accounts_tree = $_[0];

	my @columns = $accounts_tree->get_columns;
	foreach (@columns) {
		$accounts_tree->remove_column($_);
	}

	#host
	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 => 0 );
	$accounts_tree->append_column($tv_clmn_name_text);

	my $renderer_username_accounts = Gtk2::CellRendererText->new;
	$renderer_username_accounts->set( editable => TRUE );
	$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, 0 ) }->{'username'} = $new_text;

			$model->set( $iter, 1, $new_text );
		},
		$accounts_model
	);
	
	my $tv_clmn_username_text = Gtk2::TreeViewColumn->new_with_attributes( $d->get("Username"), $renderer_username_accounts, text => 1 );
	$tv_clmn_username_text->set_max_width(100);
	$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;
	$renderer_password_accounts->set( editable => TRUE );

	$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, 0 ) }->{'password'} = $new_text;    #save entered password to the hash
			$model->set( $iter, 2, $hidden_text );
		},
		$accounts_model
	);

	$tv_clmn_password_text->pack_start( $renderer_password_accounts, FALSE );
	$tv_clmn_password_text->set_attributes( $renderer_password_accounts, text => 2 );
	$accounts_tree->append_column($tv_clmn_password_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', ( $d->get(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($_);
	}

	#icon
	$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_optional {

	print "INFO: searching for optional components...\n\n";
	if ( system("which gnome-web-photo") == 0 ) {
		print "SUCCESS: gnome-web-photo is installed on your system!\n\n";
	} else {
		warn "WARNING: gnome-web-photo is missing --> screenshots of websites will be disabled!\n\n";
		$gnome_web_photo = FALSE;
	}
	eval { require Gtk2::ImageView };
	if ($@) {
		warn "WARNING: Gtk2::ImageView is missing --> advanced seletion tool will be disabled!\n\n";
		$gtkimageview = FALSE;
	}
	eval { require Goo::Canvas };
	if ($@) {
		warn "WARNING: Goo::Canvas is missing --> drawing tool will be disabled!\n\n";
		$goocanvas = FALSE;
	}

	return TRUE;
}

sub fct_init {

	#are there any command line params?
	if ( @ARGV > 0 ) {
		foreach my $arg (@ARGV) {
			$arg =~ s/.{2}//;
			if ( $arg eq "debug" ) {
				$shutter_common->set_debug(TRUE);
			} elsif ( $arg eq "help" ) {
				$shutter_hfunct->usage;
				exit;
			} elsif ( $arg eq "clear_cache" ) {
				$shutter_common->set_clear_cache(TRUE);
			} elsif ( $arg eq "min_at_startup" ) {
				$shutter_common->set_min(TRUE);
			} elsif ( $arg eq "disable_systray" ) {
				$shutter_common->set_disable_systray(TRUE);
			} elsif ( $arg eq "section" ) {

				#is there already a process of shutter running?
				my @shutter_pids = `pidof -o $$ -x $shutter_path`;
				foreach (@shutter_pids) {
					kill RTMAX => $_;
					die;
				}
				$shutter_common->set_start_with("section");
				$shutter_common->set_min(TRUE);
			} elsif ( $arg eq "selection" ) {

				#is there already a process of shutter running?
				my @shutter_pids = `pidof -o $$ -x $shutter_path`;
				foreach (@shutter_pids) {
					kill RTMIN => $_;
					die;
				}
				$shutter_common->set_start_with("select");
				$shutter_common->set_min(TRUE);
			} elsif ( $arg eq "window" ) {

				#is there already a process of shutter running?
				my @shutter_pids = `pidof -o $$ -x $shutter_path`;
				foreach (@shutter_pids) {
					kill USR2 => $_;
					die;
				}
				$shutter_common->set_start_with("window");
				$shutter_common->set_min(TRUE);
			} elsif ( $arg eq "full" ) {

				#is there already a process of shutter running?
				my @shutter_pids = `pidof -o $$ -x $shutter_path`;
				foreach (@shutter_pids) {
					kill USR1 => $_;
					die;
				}
				$shutter_common->set_start_with("raw");
				$shutter_common->set_min(TRUE);
			} else {
				warn "ERROR: illegal command " . $arg . " \n\n";
				$shutter_hfunct->usage;
				exit;
			}
			print "INFO: command " . $arg . " recognized!\n\n";
		}
	} else {
		print "INFO: no command line parameters set...\n\n";
	}

	#an old .shutter file existing?
	unlink("$ENV{ 'HOME' }/.shutter")
		if ( $shutter_hfunct->file_exists("$ENV{ 'HOME' }/.shutter") );

	#an old .shutter/settings.conf file existing?
	unlink("$ENV{ 'HOME' }/.shutter/settings.conf")
		if ( $shutter_hfunct->file_exists("$ENV{ 'HOME' }/.shutter/settings.conf") );


	#migrate from gscrot to shutter
	#if an .gscrot folder exists in the home dir
	#we copy the contents to a newly created .shutter
	#folder
	if(-d "$ENV{ 'HOME' }/.gscrot"){
		if(File::Copy::Recursive::dircopy("$ENV{ 'HOME' }/.gscrot", "$ENV{ 'HOME' }/.shutter")){
			print "INFO: successfully copied all files from .gscrot to .shutter...\n\n";
			rmtree("$ENV{ 'HOME' }/.gscrot");
		}else{
			die $!;	
		}
	}

	#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_framework_versions {
	if ( $shutter_common->get_debug ) {
		print "\nINFO: gathering system information...";
		print "\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_status_message {
	my $index = shift;
	my $status_text = shift;
	
	$status1->pop(1);
	Glib::Source->remove ($session_start_screen{'first_page'}->{'statusbar_timer'}) if defined $session_start_screen{'first_page'}->{'statusbar_timer'};
	$status1->push( $index, $status_text );

	#...and remove it after 4 seconds
	$session_start_screen{'first_page'}->{'statusbar_timer'} = Glib::Timeout->add(
		5000,
		sub {
			$status1->pop(1);
			return FALSE;
		}
	);
	
	return TRUE;
}

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( 'image' => Gtk2::Image->new_from_stock( 'gtk-dialog-question', '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', 10 );
		$input_dialog->add_action_widget( $rename_btn, 20 );

		$input_dialog->set_default_response(20);

		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;
			}
		});

		#enable/disable rename button
		#e.g. if no text is in entry
		$new_filename->signal_connect('changed' => sub {
			if(length($new_filename->get_text)){
				$rename_btn->set_sensitive(TRUE);	
			}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 == 20 ) {

			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 ( $shutter_hfunct->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 );

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

							&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("renamed") );

						}else{

							my $response = $shutter_dialog->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 $response = $shutter_dialog->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 );

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

								&dlg_status_message( 1, $session_screens{$key}->{'long'} . " " . $d->get("renamed") );

							}else{

								my $response = $shutter_dialog->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);

									#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 = $shutter_dialog->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_plugin {
	my (@file_to_plugin_keys) = @_;

	my $dlg_header    = $d->get("Choose a plugin");
	my $plugin_dialog = Gtk2::Dialog->new(
		$dlg_header,
		$window,
		[qw/modal destroy-with-parent/],
		'gtk-cancel'  => 'reject',
		'gtk-execute' => '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' );

	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 "" ) {

			$model->set(
				$model->append,           0, $plugins{$pkey}->{'pixbuf_object'}, 1, $plugins{$pkey}->{'name'},    2,
				$plugins{$pkey}->{'binary'}, 3, $plugins{$pkey}->{'lang'},          4, $plugins{$pkey}->{'tooltip'}, 5,
				$pkey
			);
		} else {
			print "WARNING: Program $pkey is not configured properly, ignoring\n";
		}
	
	}
	
	my $plugin_label       = Gtk2::Label->new( $d->get("Plugin") . ":" );
	my $plugin_label_blank = Gtk2::Label->new();
	my $plugin             = Gtk2::ComboBox->new($model);
	my $plugin_descr       = Gtk2::Label->new;
	$plugin_descr->set_line_wrap(TRUE);
	$plugin_descr->set_width_chars(30);
	$plugin_descr->set_padding( 10, 10 );
	my $plugin_image       = Gtk2::Image->new;
	my $plugin_descr_frame = Gtk2::Frame->new( $d->get("Description") );
	$plugin_descr_frame->add($plugin_descr);
	my $plugin_hbox1 = Gtk2::HBox->new( FALSE, 5 );
	my $plugin_hbox2 = Gtk2::HBox->new( FALSE, 5 );
	$plugin_hbox2->set_border_width(10);

	$plugin->signal_connect(
		'changed' => sub {

			my $model       = $plugin->get_model();
			my $plugin_iter = $plugin->get_active_iter();

			if ($plugin_iter) {
				my $plugin_pixbuf = $model->get_value( $plugin_iter, 0 );
				my $plugin_name   = $model->get_value( $plugin_iter, 1 );
				my $plugin_value  = $model->get_value( $plugin_iter, 2 );
				my $plugin_lang   = $model->get_value( $plugin_iter, 3 );
				my $plugin_tip    = $model->get_value( $plugin_iter, 4 );
				my $plugin_key    = $model->get_value( $plugin_iter, 5 );

				$plugin_descr->set_text($plugin_tip);
				if ( $shutter_hfunct->file_exists( $plugins{$plugin_key}->{'pixbuf'} ) ) {
					$plugin_image->set_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file_at_size( $plugins{$plugin_key}->{'pixbuf'}, 100, 100 ) );
				}
			}
		},
		'changed'
	);
	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 );
	$plugin->set_active(0);

	$plugin_hbox1->pack_start_defaults($plugin);

	$plugin_hbox2->pack_start_defaults($plugin_image);
	$plugin_hbox2->pack_start_defaults($plugin_descr_frame);

	$plugin_dialog->vbox->add($plugin_hbox1);
	$plugin_dialog->vbox->add($plugin_hbox2);

	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" ) {
		
		#what plugin was selected?
		my $model        = $plugin->get_model();
		my $plugin_iter  = $plugin->get_active_iter();
		my $plugin_value = $model->get_value( $plugin_iter, 2 );
		my $plugin_name  = $model->get_value( $plugin_iter, 1 );
		my $plugin_lang  = $model->get_value( $plugin_iter, 3 );
		unless ( $plugin_value =~ /[a-zA-Z0-9]+/ ) {
			$shutter_dialog->dlg_error_message( $d->get("No plugin specified"), $d->get("Failed") );
			return FALSE;
		}

		#disable all widgets
		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");
	my $hosting_dialog = Gtk2::Dialog->new( $dlg_header, $window, [qw/modal destroy-with-parent/] );

	my $cancel_button = $hosting_dialog->add_button( 'gtk-cancel',       'reject' );
	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' );

	foreach ( keys %accounts ) {

		#cut username so the dialog will not explode ;-)
		my $short_username = $accounts{$_}->{'username'};
		if ( length $accounts{$_}->{'username'} > 10 ) {
			$short_username = substr( $accounts{$_}->{'username'}, 0, 10 ) . "...";
		}

		$model->set( $model->append, 0, $accounts{$_}->{'host'}, 1, $accounts{$_}->{'username'}, 2, $accounts{$_}->{'password'}, 3, $short_username )
			if ($accounts{$_}->{'username'} ne "" && $accounts{$_}->{'password'} ne "" );			
		
		$model->set( $model->append, 0, $accounts{$_}->{'host'}, 1, $d->get("Guest"), 2, "", 3, $d->get("Guest") );
	}

	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->signal_connect(
		#~ 'changed' => sub {
#~ 
			#~ my $model        = $hosting->get_model();
			#~ my $hosting_iter = $hosting->get_active_iter();
#~ 
			#~ if ($hosting_iter) {
				#~ my $hosting_host     = $model->get_value( $hosting_iter, 0 );
				#~ my $hosting_username = $model->get_value( $hosting_iter, 1 );
				#~ if ( $hosting_host =~ /imageshack/i ) {
					#~ $hosting_image->set_from_pixbuf(
						#~ Gtk2::Gdk::Pixbuf->new_from_file_at_scale( "$shutter_root/share/shutter/resources/icons/logo-imageshack.png", 200, 200, TRUE )
					#~ );
				#~ } elsif ( $hosting_host =~ /imagebanana/i ) {
					#~ $hosting_image->set_from_pixbuf(
						#~ Gtk2::Gdk::Pixbuf->new_from_file_at_scale( "$shutter_root/share/shutter/resources/icons/logo-imagebanana.png", 200, 200, TRUE )
					#~ );
				#~ } elsif ( $hosting_host =~ /ubuntu-pics/i ) {
					#~ $hosting_image->set_from_pixbuf(
						#~ Gtk2::Gdk::Pixbuf->new_from_file_at_scale( "$shutter_root/share/shutter/resources/icons/logo-ubuntu-pics.png", 200, 200, TRUE )
					#~ );
				#~ }
#~ 
			#~ }
		#~ },
		#~ 'changed'
	#~ );

	$hosting->set_active(0);

	#public hosting settings
	my $pub_hbox1 = Gtk2::HBox->new( FALSE, 12 );
	my $pub_hbox2 = Gtk2::HBox->new( FALSE, 12 );
	my $pub_vbox1 = Gtk2::VBox->new( FALSE, 12 );
	$pub_hbox2->set_border_width(12);
	$pub_hbox1->set_border_width(12);
	$pub_hbox2->set_border_width(12);
	$pub_vbox1->set_border_width(12);
	$pub_hbox1->pack_start( Gtk2::Label->new( $d->get("Choose account"). ":" ), FALSE, FALSE, 6 );
	$pub_hbox1->pack_start_defaults($hosting);
	$pub_vbox1->pack_start($pub_hbox1, FALSE, FALSE, 6);

	#places settings
	my $pl_hbox1 = Gtk2::HBox->new( FALSE, 12 );
	my $pl_vbox1 = Gtk2::VBox->new( FALSE, 12 );
 	$pl_hbox1->set_border_width(12);
 	$pl_vbox1->set_border_width(12);
	my $places_fc = Gtk2::FileChooserButton->new_with_backend ("Shutter - " . $shutter_common->get_gettext->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, 6);

	#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 );

	#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 );

	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 );

	#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 );

	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);

	#setup notebook
	my $unotebook = Gtk2::Notebook->new;
	$unotebook->set( homogeneous  => TRUE );
	$unotebook->set( 'scrollable' => TRUE );

	$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;
UPDIALOG: while ($hosting_dialog) {

		#initial state of dialog
		$upload_button->set_sensitive(TRUE);
		$cancel_button->set_sensitive(TRUE);
		$hosting_progress->hide;

		#DIALOG RUN
		my $hosting_response = $hosting_dialog->run;

		#running state of dialog
		$upload_button->set_sensitive(FALSE);
		$cancel_button->set_sensitive(FALSE);
		$hosting_progress->show;

		#start upload
		if ( $hosting_response eq "accept" ) {

			#public hosting
			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 );
				if ( $hosting_host eq "ubuntu-pics.de" ) {
					my $uploader
						= Shutter::Upload::UbuntuPics->new( $hosting_host, $shutter_common->get_debug, $shutter_root, $d, $window, SHUTTER_VERSION );
					my $counter = 1;
					$hosting_progress->set_fraction(0);
					foreach my $file ( sort @files_to_upload ) {
						$hosting_progress->set_text($file);
						
						#update gui
						&fct_update_gui;
						
						my %upload_response = $uploader->upload( $shutter_hfunct->switch_home_in_file($file), $hosting_username, $hosting_password );

						if ( is_success( $upload_response{'status'} ) ) {
							$uploader->show;
							&dlg_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 UPDIALOG;
						}
						$hosting_progress->set_fraction( $counter / @files_to_upload );

						#update gui
						&fct_update_gui;
						$counter++;
					}
					$uploader->show_all;
				} elsif ( $hosting_host eq "imagebanana.com" ) {
					my $uploader
						= Shutter::Upload::ImageBanana->new( $hosting_host, $shutter_common->get_debug, $shutter_root, $d, $window, SHUTTER_VERSION );
					my $counter = 1;
					$hosting_progress->set_fraction(0);
					foreach my $file (@files_to_upload) {
						$hosting_progress->set_text($file);

						#update gui
						&fct_update_gui;
						my %upload_response = $uploader->upload( $shutter_hfunct->switch_home_in_file($file), $hosting_username, $hosting_password );

						if ( is_success( $upload_response{'status'} ) ) {
							$uploader->show;
							&dlg_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 UPDIALOG;
						}
						$hosting_progress->set_fraction( $counter / @files_to_upload );

						#update gui
						&fct_update_gui;
						$counter++;
					}
					$uploader->show_all;
				} elsif ( $hosting_host eq "imageshack.us" ) {
					my $ishack = Shutter::Upload::ImageShack->new();
					
					#clear possible cookie (is this really needed here?)
					$ishack->logout;
										
					#upload
					my $counter = 1;
					$hosting_progress->set_fraction(0);
					foreach my $file (@files_to_upload) {

						#login
						eval { $ishack->login($hosting_username, $hosting_password); };
						if ($@) {
							my $response = $shutter_dialog->dlg_error_message( $d->get("Please check your credentials and try again."),
								$d->get("Login failed!") );

							next UPDIALOG;
						}

						$hosting_progress->set_text($file);

						#update gui
						&fct_update_gui;
						my $url = undef;
						eval { $url = $ishack->host( $file, undef ); };
						if ($@) {
							my $response = $shutter_dialog->dlg_error_message(
								$d->get("Please check your connectivity and try again."),
								$d->get("Connection error!"),
								$d->get("Skip all"), 
								$d->get("Skip"), 
								'gtk-redo'
							);

							#10 == skip all, 20 == skip, else == cancel
							last if $response == 10;
							next if $response == 20;
							redo if $response == 30;
							next UPDIALOG;
						}

						#get thumbnail url
						my $thumb_url = undef;
						eval { $thumb_url = $ishack->hosted_thumb; };

						if ($url) {
							$ishack->show( $hosting_host, $hosting_username, $file, $url, $thumb_url, RC_OK, $d, $window, $shutter_root );
							&dlg_status_message( 1, $file . " " . $d->get("uploaded") );
						} else {
							my $response = $shutter_dialog->dlg_error_message(
								$d->get("Please check your connectivity and try again."),
								$d->get("Connection error!"),
								$d->get("Skip all"), 
								$d->get("Skip"), 
								'gtk-redo'
							);

							#10 == skip all, 20 == skip, else == cancel
							last if $response == 10;
							next if $response == 20;
							redo if $response == 30;
							next UPDIALOG;
						}
						$hosting_progress->set_fraction( $counter / @files_to_upload );

						#update gui
						&fct_update_gui;
						$counter++;
					}
					$ishack->show_all;
				}

				#ftp
			} elsif ( $unotebook->get_current_page == 1 ) {

				#create upload object
				my $uploader = Shutter::Upload::FTP->new( $shutter_common->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 $file (sort @files_to_upload) {

					#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]) {

							#we already get translated error messaged back
							my $response = $shutter_dialog->dlg_error_message( 
								$upload_response[1], 
								$upload_response[0],
								undef, undef, undef,
								undef, undef, undef,
								$upload_response[2]
							);
							next UPDIALOG;
						} else {
							$login = TRUE;
						}

					}

					$hosting_progress->set_text($file);

					#update gui
					&fct_update_gui;
					@upload_response = $uploader->upload( $shutter_hfunct->switch_home_in_file($file) );
				
					#upload returns FALSE if there is no error
					unless ($upload_response[0]) {
						#everything is fine here
						&dlg_status_message( 1, $file . " " . $d->get("uploaded") );
					} else {

						#we already get translated error messaged back
						my $response = $shutter_dialog->dlg_error_message( 
							$upload_response[1], 
							$upload_response[0],
							$d->get("Skip all"), 
							$d->get("Skip"),
							'gtk-redo',
							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 UPDIALOG;
						}

					}
					$hosting_progress->set_fraction( $counter / @files_to_upload );

					#update gui
					&fct_update_gui;
					$counter++;
				}    #end foreach
				$uploader->quit;
			
			
			#places using Gnone-VFS
			} elsif ( $unotebook->get_current_page == 2 ) {
		
				my $counter = 1;
				$hosting_progress->set_fraction(0);

				#start upload
				foreach my $file (sort @files_to_upload) {
					
					$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 $source_uri->to_string . " - " . $target_uri->to_string."\n" if $shutter_common->get_debug;
					my $result;
					unless($target_uri->exists){
						$result = Gnome2::VFS::Xfer->uri ($source_uri, $target_uri, 'default', 'abort', 'replace', sub{ return TRUE });
					}else{
						$result = 'error-file-exists';	
					}

					if($result eq 'ok'){
					
						#everything is fine here
						if($target_uri->is_local){
							&dlg_status_message( 1, $file . " " . $d->get("exported") );
						}else{
							&dlg_status_message( 1, $file . " " . $d->get("uploaded") );
						}
					
					}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 = Gnome2::VFS->unescape_string_for_display ($target_uri->extract_dirname);
						}else{								
							$target_path = Gnome2::VFS->unescape_string_for_display ($target_uri->get_scheme."://".$target_uri->get_host_name.$target_uri->extract_dirname);
						}

						my $response = $shutter_dialog->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'){	
								#everything is fine here
								if($target_uri->is_local){
									&dlg_status_message( 1, $file . " " . $d->get("exported") );
								}else{
									&dlg_status_message( 1, $file . " " . $d->get("uploaded") );
								}			
							} else{

								my $response = &dlg_upload_error_message_gnome_vfs($target_uri, $result);

								#10 == skip all, 20 == skip, 30 == redo, else == cancel
								if ( $response == 10 ) {
									last;
								} elsif ( $response == 20 ) {
									next;
								} elsif ( $response == 30 ) {
									redo;
								} else {
									next UPDIALOG;
								}										
								
							}
						}	
						
					}else{

						my $response = &dlg_upload_error_message_gnome_vfs($target_uri, $result);

						#10 == skip all, 20 == skip, 30 == redo, else == cancel
						if ( $response == 10 ) {
							last;
						} elsif ( $response == 20 ) {
							next;
						} elsif ( $response == 30 ) {
							redo;
						} else {
							next UPDIALOG;
						}					
		
					}

					$hosting_progress->set_fraction( $counter / @files_to_upload );

					#update gui
					&fct_update_gui;
					$counter++;
													
				}
				
			}

			$hosting_dialog->destroy();
			return TRUE;
		} else {
			$hosting_dialog->destroy();
			return FALSE;
		}    #if response == accept

	}    #dialog loop
}

sub dlg_upload_error_message_gnome_vfs {
	my $target_uri = shift;
	my $result = shift;

	my $target_path=undef;
	if($target_uri->is_local){
		$target_path = Gnome2::VFS->unescape_string_for_display ($target_uri->extract_dirname);
	}else{								
		$target_path = Gnome2::VFS->unescape_string_for_display ($target_uri->get_scheme."://".$target_uri->get_host_name.$target_uri->extract_dirname);
	}

	my $response = $shutter_dialog->dlg_warning_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"),
		'gtk-redo',
		undef,
		undef,
		undef,
		Gnome2::VFS->result_to_string ($result)
	);
	
	return $response;
	
}

sub dlg_upload_error_message {
	my ( $status, $max_filesize ) = @_;

	my $response;
	if ( $status == 999 ) {
		$response = $shutter_dialog->dlg_error_message( $d->get("Please check your credentials and try again."), $d->get("Login failed!") );
	} elsif ( $status == 998 ) {
		$response = $shutter_dialog->dlg_error_message( $d->get("Maximum filesize reached!") . " ( $max_filesize )",
			$d->get("Failed"), $d->get("Skip all"), $d->get("Skip") );
	} else {
		$response = $shutter_dialog->dlg_error_message(
			$d->get("Please check your connectivity and try again."),
			$d->get("Connection error!") . " (" . $status . ")",
			$d->get("Skip all"), $d->get("Skip"), 'gtk-redo'
		);
	}
	return $response;
}

sub dlg_website {
	my ( $filename, $filetype_value, $quality_value ) = @_;

	my $screenshot  = 5;
	my $web_process = Proc::Simple->new;

	my $website_dialog = Gtk2::MessageDialog->new( $window, [qw/modal destroy-with-parent/], 'other', 'none', undef );

	$website_dialog->set( 'text' => $d->get("Take a screenshot of a website") );

	$website_dialog->set( 'secondary-text' => $d->get("URL to capture") . ": " );

	$website_dialog->set(
		'image' => Gtk2::Image->new_from_pixbuf(
			Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$shutter_root/share/shutter/resources/icons/web_image.svg", Gtk2::IconSize->lookup('dialog') )
		)
	);

	#cancel button
	my $cancel_btn = Gtk2::Button->new_from_stock('gtk-cancel');

	#save button
	my $execute_btn = Gtk2::Button->new_from_stock('gtk-execute');
	$execute_btn->can_default(TRUE);

	$website_dialog->add_action_widget( $cancel_btn,  'cancel' );
	$website_dialog->add_action_widget( $execute_btn, 'accept' );

	$website_dialog->set_default_response('accept');

	my $website_hbox  = Gtk2::HBox->new();
	my $website_hbox2 = Gtk2::HBox->new();

	my $website = Gtk2::Entry->new;
	$website->set_text("http://");
	$website->set_activates_default(TRUE);
	my $clipboard_string = $clipboard->wait_for_text;
	print "Content of clipboard is: $clipboard_string\n"
		if $shutter_common->get_debug;

	if ( defined $clipboard_string ) {
		if (   $clipboard_string =~ /^http/
			|| $clipboard_string =~ /^file/
			|| $clipboard_string =~ /^www\./ )
		{
			$website->set_text($clipboard_string);
		}
	}

	$website_hbox->pack_start( $website, TRUE, TRUE, 12 );
	$website_dialog->vbox->add($website_hbox);

	my $website_progress = Gtk2::ProgressBar->new;
	$website_progress->set_no_show_all(TRUE);
	$website_progress->set_ellipsize('middle');
	$website_progress->set_orientation('left-to-right');
	$website_progress->set_fraction(0);
	$website_hbox2->pack_start( $website_progress, TRUE, TRUE, 12 );
	$website_dialog->vbox->add($website_hbox2);

	$website_dialog->show_all;
	my $website_response = $website_dialog->run;

	if ( $website_response eq "accept" ) {

		$execute_btn->set_sensitive(FALSE);

		#show progress bar while executing gnome-web-photo
		$website_progress->show;
		&fct_update_gui;

		my $url      = $website->get_text;
		my $hostname = $url;
		$hostname =~ s/http:\/\///;

		if ( $hostname eq "" ) {
			$shutter_dialog->dlg_error_message( $d->get("No valid url entered"), $d->get("Failed") );
			$website_dialog->destroy();
			return $screenshot;
		}

		#determining timeout
		my $web_menu = $shutter_tool->{_web}->get_menu;
		my @timeouts = $web_menu->get_children;
		my $timeout  = undef;
		foreach (@timeouts) {
			if ( $_->get_active ) {
				$timeout = $_->get_children->get_text;
				$timeout =~ /([0-9]+)/;
				$timeout = $1;
				print $timeout. "\n" if $shutter_common->get_debug;
			}
		}

		my $screenshooter = Shutter::Screenshot::Web->new( $timeout, $filetype_value, $quality_value, $url, $filename );

		Proc::Simple::debug(1) if $shutter_common->get_debug;

		$web_process->start(
			sub {
				$screenshooter->web();
				POSIX::_exit(0);
			}
		);

		$cancel_btn->signal_connect(
			'clicked' => sub {
				if ( $web_process->kill() ) {

					#delete file if process was cancelled
					unlink("$filename");
					$website_dialog->destroy();
				}
			}
		);

		while ( $web_process->poll ) {
			$website_progress->pulse;
			&fct_update_gui;
			usleep 100000;
		}

		#we cannot kill the process anymore
		#closing the dialog will confuse the user
		#because the image will appear in the session later on
		$cancel_btn->set_sensitive(FALSE);
		&fct_update_gui;

		if ( $web_process->exit_status() == 0 ) {

			$website_progress->set_fraction( 2 / 3 );
			&fct_update_gui;

			eval { $screenshot = Gtk2::Gdk::Pixbuf->new_from_file($filename) };
			if ($@) {

				#error when loading file
				$screenshot = 0;
				unlink($filename);
				$website_dialog->destroy();
			}

			$website_progress->set_fraction( 3 / 3 );
			&fct_update_gui;

		}

		$website_dialog->destroy();

		return $screenshot;
	} else {
		$website_dialog->destroy();

		return $screenshot;
	}
}

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( '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', 10 );
	$profile_dialog->add_button( 'gtk-save', 20 );

	$profile_dialog->set_default_response(20);

	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 == 20 ) {
		my $entered_name = $new_profile_name->get_text;

		if ( $shutter_hfunct->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 = $shutter_dialog->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
			);

			#rename == replace_btn was hit
			if ( $response == 40 ) {
				$profile_dialog->destroy();
				return $new_profile_name->get_text;
			} else {
				$profile_dialog->destroy();
				return FALSE;
			}
		}

		$profile_dialog->destroy();
		return $new_profile_name->get_text;
	} else {
		$profile_dialog->destroy();
		return FALSE;
	}
}

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

