#! /usr/bin/perl

###################################################
#
#  Copyright (C) 2008-2013 Mario Kemper <mario.kemper@gmail.com>
#  Copyright (C) 2020-2021 Google LLC, contributed by Alexey Sokolov <sokolov@google.com>
#
#  This file is part of Shutter.
#
#  Shutter is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  Shutter is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with Shutter; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
#
###################################################

# See "Migrating from GnomeVFS to GIO":
# https://developer.gnome.org/gio/stable/ch33.html

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

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

use Carp::Always;

BEGIN {
	use Glib::Object::Introspection;
	Glib::Object::Introspection->setup(
		basename => 'Gio',
		version  => '2.0',
		package  => 'Glib::IO',
	);
	Glib::Object::Introspection->setup(
		basename => 'Wnck',
		version  => '3.0',
		package  => 'Wnck',
	);
	Glib::Object::Introspection->setup(
		basename => 'GdkX11',
		version  => '3.0',
		package  => 'Gtk3::GdkX11',
	);
}

package Shutter::App;

#Deal with encoding problem
binmode(STDOUT, "encoding(UTF-8)");
use Encode;

use File::stat;
use Number::Bytes::Human;

#Glib
use Pango;
use Glib qw/TRUE FALSE/;
use Gtk3 '-init';
use Glib::Object::Subclass qw/Gtk3::Application/;
use Gtk3::ImageView 9;

#filename parsing
use POSIX qw/ strftime /;

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

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

#load and save settings
use XML::Simple;

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

#HTTP Status code processing
use HTTP::Status;

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

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

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

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

#proc
use Proc::Simple;

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

sub escape_string {
	return $_[0];

	# used to be  Gnome2::VFS->escape_string.
	my $ret = Gnome2::VFS->escape_string($_[0]);
	say "VFS escape_string $_[0] -> $ret";
	return $ret;
}

sub unescape_string {
	return $_[0];

	# used to be  Gnome2::VFS->unescape_string.
	# at least, transform utf-8 to internal perl format for utf8
	my $ret = Gnome2::VFS->unescape_string($_[0]);
	say "VFS unescape_string $_[0] -> $ret";
	return $ret;
}

sub unescape_string_for_display {
	return $_[0];

	# used to be  Gnome2::VFS->unescape_string_for_display.
	my $ret = Gnome2::VFS->unescape_string_for_display($_[0]);
	say "VFS unescape_string_for_display $_[0] -> $ret";
	return $ret;
}

sub escape_path_string {
	return $_[0];

	# used to be  Gnome2::VFS->escape_path_string.
	my $ret = Gnome2::VFS->escape_path_string($_[0]);
	say "VFS escape_path_string $_[0] -> $ret";
	return $ret;
}

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

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

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

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

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

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

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

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

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

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

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

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

#region
require Shutter::Geometry::Region;

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

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

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

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

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

my $sc   = Shutter::App::Common->new($shutter_root, undef, SHUTTER_NAME, SHUTTER_VERSION, SHUTTER_REV, $$);
my $shf  = Shutter::App::HelperFunctions->new($sc);
my $so   = Shutter::App::Options->new($sc, $shf);
my $sdir = Shutter::App::Directories->new();

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

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

#load command line arguments
#as well as file to open when starting
my $init_files = $so->get_options;
# accept either path or uri as arguments, but store only uri
my @init_files = map { Glib::IO::File::new_for_commandline_arg($_)->get_uri } @$init_files;

sub STARTUP {
	# This is called by $app->run below if another Shutter instance is not running.

	my ($app) = @_;
	$app->SUPER::STARTUP();

	#main window
	#--------------------------------------
	my $window = Gtk3::ApplicationWindow->new($app);
	#--------------------------------------

	#create app objects
	#--------------------------------------
	$sc->set_mainwindow($window);
	my $sas  = Shutter::App::Autostart->new();
	my $sm   = Shutter::App::Menu->new($sc);
	my $st   = Shutter::App::Toolbar->new($sc);
	my $sd   = Shutter::App::SimpleDialogs->new($window);

	my $sp    = Shutter::Pixbuf::Save->new($sc);
	my $lp    = Shutter::Pixbuf::Load->new($sc);
	my $lp_ne = Shutter::Pixbuf::Load->new($sc, undef, TRUE);
	my $hu    = Number::Bytes::Human->new(si => 1);
	#--------------------------------------

	#Clipboard
	my $clipboard = Gtk3::Clipboard::get($Gtk3::Gdk::SELECTION_CLIPBOARD);

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

	#Page Setup
	my $pagesetup = undef;

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

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

	# Watch the main window and register a handler that will be called each time
	# that there's a new message.
	my @signal_connections;
	my $action;

	$action = Glib::IO::SimpleAction->new('exitac', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		$sc->set_exit_after_capture(TRUE);
	});

	$action = Glib::IO::SimpleAction->new('exfilename', 's');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		my $arg = $_[1]->get_string;
		$sc->set_export_filename($arg);
	});

	$action = Glib::IO::SimpleAction->new('delay', 's');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		my $arg = $_[1]->get_string;
		$sc->set_delay($arg);
	});

	$action = Glib::IO::SimpleAction->new('include_cursor', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		$sc->set_include_cursor(TRUE);
		$sc->set_remove_cursor(FALSE);
	});

	$action = Glib::IO::SimpleAction->new('remove_cursor', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		$sc->set_remove_cursor(TRUE);
		$sc->set_include_cursor(FALSE);
	});

	$action = Glib::IO::SimpleAction->new('nosession', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		$sc->set_no_session(TRUE);
	});

	$action = Glib::IO::SimpleAction->new('fopen', 'as');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		my $args = $_[1]->get('as');
		if (scalar @$args > 0) {
			fct_open_files(@$args);
		}
		fct_control_main_window('show');
	});

	$action = Glib::IO::SimpleAction->new('profile', 's');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		my $arg = $_[1]->get_string;
		print "FIXME: switching profiles via IPC is not implemented yet\n";
	});

	$action = Glib::IO::SimpleAction->new('select', 's');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		my $arg = $_[1]->get_string;
		evt_take_screenshot('global_keybinding', 'select', undef, $arg);
	});

	$action = Glib::IO::SimpleAction->new('full', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		evt_take_screenshot('global_keybinding', 'full');
	});

	$action = Glib::IO::SimpleAction->new('window', 's');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		my $arg = $_[1]->get_string;
		evt_take_screenshot('global_keybinding', 'window', undef, $arg);
	});

	$action = Glib::IO::SimpleAction->new('awindow', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		evt_take_screenshot('global_keybinding', 'awindow');
	});

	# No sections for now: https://github.com/shutter-project/shutter/issues/25
	#$action = Glib::IO::SimpleAction->new('section', '');
	#$app->add_action($action);
	#push @signal_connections, $action->signal_connect('activate'=>sub {
	#	evt_take_screenshot('global_keybinding', 'section');
	#});

	$action = Glib::IO::SimpleAction->new('menu', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		evt_take_screenshot('global_keybinding', 'menu');
	});

	$action = Glib::IO::SimpleAction->new('tooltip', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		evt_take_screenshot('global_keybinding', 'tooltip');
	});

	$action = Glib::IO::SimpleAction->new('web', 's');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		my $arg = $_[1]->get_string;
		evt_take_screenshot('global_keybinding', 'web', undef, $arg);
	});

	$action = Glib::IO::SimpleAction->new('redoshot', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		evt_take_screenshot('global_keybinding', 'redoshot');
	});

	$action = Glib::IO::SimpleAction->new('showmainwindow', '');
	$app->add_action($action);
	push @signal_connections, $action->signal_connect('activate'=>sub {
		fct_control_main_window('show');
	});

	#create needed directories etc.
	fct_init_environment();

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

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

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

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

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

	#TRAY ICON AND MENU
	my $tray      = undef;
	my $tray_menu = fct_ret_tray_menu();

	#SESSION NOTEBOOK
	my $notebook = Gtk3::Notebook->new;
	$notebook = fct_create_session_notebook();

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

	my $combobox_status_profiles_label = Gtk3::Label->new($d->get("Profile") . ":");
	my $combobox_status_profiles       = Gtk3::ComboBoxText->new;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		$tray = Gtk3::StatusIcon->new();
		$tray->set_from_icon_name("shutter-panel");
		$tray->set_visible(1);

		fct_update_gui();

		if ($tray->is_embedded) {
			$tray->{'hid'} = $tray->signal_connect(
				'popup-menu' => sub { evt_show_systray_statusicon(@_); },
				$tray
			);
			$tray->{'hid2'} = $tray->signal_connect(
				'activate' => sub {
					evt_activate_systray_statusicon(@_);
					$tray;
				},
				$tray
			);
		} else {
			$tray = undef;
		}

		if ($appindicator && !defined $tray) {
			# Fallback to AppIndicator. This one doesn't allow left-click signal, but it seems to be the only option for Gnome on Ubuntu 21.04...
			$tray = AppIndicator::Indicator->new("Shutter", "shutter-panel", 'application-status');
			$tray->set_menu($tray_menu);
			$tray->set_status('active');
		}
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	#load accounts for hosting services
	fct_load_accounts();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	unless ($wnck_screen) {
		my $tooltip = $d->get("Can't take screenshots without X11 server");
		for my $name ('_select', '_full', '_window', '_menu', '_tooltip') {
			$st->{$name}->set_sensitive(FALSE);
			$st->{$name}->set_tooltip_text($tooltip);
		}
		for my $name ('_full', '_window') {
			$st->{$name}->set_arrow_tooltip_text($tooltip);
		}
	}

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

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

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

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

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

	my $button_profile_save = Gtk3::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(Gtk3::Image->new_from_stock('gtk-save', 'button'));
	$button_profile_save->set_tooltip_text($d->get("Save configuration as profile"));

	my $button_profile_delete = Gtk3::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(Gtk3::Image->new_from_stock('gtk-delete', 'button'));
	$button_profile_delete->set_tooltip_text($d->get("Delete profile"));
	my $button_profile_apply = Gtk3::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(Gtk3::Image->new_from_stock('gtk-apply', 'button'));
	$button_profile_apply->set_tooltip_text($d->get("Load the selected profile's configuration"));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	$filename->set_tooltip_text($filename_tooltip_string);
	$filename_label->set_tooltip_text($filename_tooltip_string);

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

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

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

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

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

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

	#add compatile, writeable file types
	my $combobox_type = Gtk3::ComboBoxText->new;
	my ($int_png, $int_jpeg, $int_bmp) = (-1, -1, -1);
	my $format_counter = 0;

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

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

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

			$format_counter++;

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

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

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

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

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

	} else {

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

	}

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

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

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

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

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

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

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

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

	$save_no_active->set_tooltip_text($d->get("Do not save file automatically"));

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

	$save_auto_active->set_tooltip_text($d->get("Automatically save file"));

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

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

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

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

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

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

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

	$image_autocopy_active->set_tooltip_text($d->get("Automatically copy screenshot to clipboard"));

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

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

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

	$fname_autocopy_active->set_tooltip_text($d->get("Automatically copy filename to clipboard"));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	#program
	#--------------------------------------
	my $model    = fct_get_program_model();
	my $progname = Gtk3::ComboBox->new_with_model($model);

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

	#add text renderer for app name
	my $renderer_text = Gtk3::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 = Gtk3::CheckButton->new;
	$progname_active->set_active(TRUE);
	$progname_active->signal_connect(
		'toggled' => \&evt_value_changed,
		'progname_toggled'
	);
	if (defined $settings_xml->{'general'}->{'prog_active'}) {
		$progname_active->set_active($settings_xml->{'general'}->{'prog_active'});
	} else {
		$progname_active->set_active(FALSE);
	}
	my $progname_label = Gtk3::Label->new($d->get("Open with") . ":");
	$progname->set_tooltip_text($d->get("Open your screenshot with this program after capturing"));
	$progname_active->set_tooltip_text($d->get("Open your screenshot with this program after capturing"));
	$progname_label->set_tooltip_text($d->get("Open your screenshot with this program after capturing"));
	$progname_box->pack_start($progname_label,  FALSE, TRUE, 12);
	$progname_box->pack_start($progname_active, FALSE, TRUE, 0);
	$progname_box->pack_start($progname,        TRUE,  TRUE, 0);

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

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

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

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

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

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

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

	#thumbnail
	#--------------------------------------
	my $thumbnail_label = Gtk3::Label->new($d->get("Thumbnail") . ":");
	my $thumbnail       = Gtk3::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 = Gtk3::CheckButton->new;
	$thumbnail_active->set_active(TRUE);
	$thumbnail_active->signal_connect(
		'toggled' => \&evt_value_changed,
		'thumbnail_toggled'
	);

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

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

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

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

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

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

	$bordereffect_clabel->set_tooltip_text($d->get("Choose border color"));
	$bordereffect_cbtn->set_tooltip_text($d->get("Choose border color"));

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

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

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

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

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

	if (defined $settings_xml->{'general'}->{'bordereffect_col'}) {
		$bordereffect_cbtn->set_rgba(Gtk3::Gdk::RGBA::parse($settings_xml->{'general'}->{'bordereffect_col'}));
	} else {
		$bordereffect_cbtn->set_rgba(Gtk3::Gdk::RGBA::parse('black'));
	}

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

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

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

	$zoom_active->set_tooltip_text($d->get("Enable zoom window"));

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

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

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

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

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

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

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

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

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

	$as_help_active->set_tooltip_text($d->get("Enables the help text"));

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

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

	#border
	#--------------------------------------
	my $border_active = Gtk3::CheckButton->new_with_label($d->get("Include window decoration when capturing a window"));
	$border_active->set_tooltip_text($d->get("Include window decoration when capturing a window"));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	#visible windows only
	#--------------------------------------
	my $visible_windows_active = Gtk3::CheckButton->new_with_label($d->get("Select only visible windows"));
	$visible_windows_active->set_tooltip_text($d->get("Select only visible windows"));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	#imageview
	#--------------------------------------
	my $css_provider_alpha = Gtk3::CssProvider->new;

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

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

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

	if (defined $settings_xml->{'general'}->{'trans_custom_col'}) {
		$trans_custom_btn->set_rgba(Gtk3::Gdk::RGBA::parse($settings_xml->{'general'}->{'trans_custom_col'}));
	} else {
		$trans_custom_btn->set_rgba(Gtk3::Gdk::RGBA::parse('black'));
	}

	if (   defined $settings_xml->{'general'}->{'trans_check'}
		&& defined $settings_xml->{'general'}->{'trans_custom'}
		&& defined $settings_xml->{'general'}->{'trans_backg'})
	{
		$trans_check->set_active($settings_xml->{'general'}->{'trans_check'});
		$trans_custom->set_active($settings_xml->{'general'}->{'trans_custom'});
		$trans_backg->set_active($settings_xml->{'general'}->{'trans_backg'});
	} else {
		$trans_check->set_active(TRUE);
	}
	# initialize css
	evt_value_changed(undef, 'transp_toggled');

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	$fs_active->set_tooltip_text($d->get("Start Shutter at login"));

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

	$fs_min_active->set_tooltip_text($d->get("Hide window on first launch"));

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

	$fs_nonot_active->set_tooltip_text($d->get("Hide notification icon"));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	#accounts
	#--------------------------------------
	my $accounts_model = undef;
	fct_load_accounts_tree();

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

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

	fct_set_model_accounts($accounts_tree);

	#some notes related to uploading
	my $pub_hint_pref = Gtk3::Label->new();
	$pub_hint_pref->set_line_wrap(TRUE);
	$pub_hint_pref->set_line_wrap_mode('word-char');

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

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

	my $ftp_remote_entry = Gtk3::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");
	}

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

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

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

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

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

	$ftp_mode_label->set_tooltip_text($d->get("Connection mode"));

	$ftp_mode_combo->set_tooltip_text($d->get("Connection mode"));

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

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

	my $ftp_username_entry = Gtk3::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("");
	}

	$ftp_username_label->set_tooltip_text($d->get("Username"));

	$ftp_username_entry->set_tooltip_text($d->get("Username"));

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

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

	my $ftp_password_entry = Gtk3::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("");
	}

	$ftp_password_label->set_tooltip_text($d->get("Password"));

	$ftp_password_entry->set_tooltip_text($d->get("Password"));

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

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

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

	$ftp_wurl_label->set_tooltip_text($d->get("Website URL"));

	$ftp_wurl_entry->set_tooltip_text($d->get("Website URL"));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		my $scrolled_plugins_window = Gtk3::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 = Gtk3::Label->new;
		$label_plugins->set_markup($d->get("Plugins"));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	#unblock controls
	fct_control_signals('unblock');

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

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

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

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

	#update the first tab on startup
	fct_update_info_and_tray();

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

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

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

		return FALSE unless $data;

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

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

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

			#Sets how the view should draw transparent parts of images with an alpha channel
			if ($trans_check->get_active) {
				$css_provider_alpha->load_from_data("
					.imageview.transparent {
						background-image: url('$shutter_root/share/shutter/resources/gui/checkers.svg');
					}
				");
			} elsif ($trans_custom->get_active) {
				my $color_string = $trans_custom_btn->get_rgba->to_string;
				$css_provider_alpha->load_from_data("
					.imageview.transparent {
						background-color: $color_string;
					}
				");
			} elsif ($trans_backg->get_active) {
				$css_provider_alpha->load_from_data(" ");
			}
			$window->queue_draw;
		}

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

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

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

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

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

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

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

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

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

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

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

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

		return TRUE;
	}

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

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

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

			fct_control_main_window('hide');

		} else {

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

		}

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

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

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

			#unblock signal handler
			fct_control_signals('unblock');
			return TRUE;
		} elsif (!defined $wnck_screen) {
			my $sd = Shutter::App::SimpleDialogs->new;
			$sd->dlg_error_message($d->get("Can't take screenshots without X11 server"), $d->get("Failed"));
			fct_control_signals('unblock');
			fct_control_main_window('show');
			return TRUE;
		}

		if ($data eq "menu"
			|| $data eq "tray_menu"
			|| $data eq "tooltip"
			|| $data eq "tray_tooltip")
		{

			my $scd_text;
			if ($data eq "menu" || $data eq "tray_menu") {
				$scd_text = $d->get("Please activate the menu you want to capture");
				if ($ENV{GDK_SCALE} > 1) {
					my $sd = Shutter::App::SimpleDialogs->new;
					$sd->dlg_info_message("Capturing a cascading menu is known to be broken with HiDPI.\nPlease unset GDK_SCALE variable and restart Shutter.\nPlease follow https://github.com/shutter-project/shutter/issues/326 and send us the patch\nWill attempt capturing it anyway...", undef, 'gtk-ok');
				}
			} elsif ($data eq "tooltip" || $data eq "tray_tooltip") {
				$scd_text = $d->get("Please activate the tooltip you want to capture");
			}

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

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

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

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

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

								return FALSE;

							} else {

								return TRUE;

							}
						});
				} else {

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

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

					#unblock signal handler
					fct_control_signals('unblock');
					return FALSE;
				});
		} else {
			if (($data eq "section" || $data eq "tray_section") && $ENV{GDK_SCALE} > 1) {
				my $sd = Shutter::App::SimpleDialogs->new;
				$sd->dlg_info_message("Capturing a window section is known to be broken with HiDPI.\nPlease unset GDK_SCALE variable and restart Shutter.\nPlease follow https://github.com/shutter-project/shutter/issues/326 and send us the patch\nWill attempt capturing it anyway...", undef, 'gtk-ok');
			}

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

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

		return TRUE;
	}

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

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

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

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

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

								#update window title
								fct_update_info_and_tray($key);

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

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

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

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

		return TRUE;
	}

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

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

		Glib::Idle->add(
			sub {

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

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

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

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

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

				$app->quit;

				return FALSE;
			});

		return TRUE;
	}

	sub evt_bug {
		$shf->xdg_open(undef, "https://github.com/shutter-project/shutter/issues/new?labels=bug&template=bug_report.md", undef);
	}

	sub evt_question {
		$shf->xdg_open(undef, "https://github.com/shutter-project/shutter/issues/new?labels=question&template=question.md", undef);
	}

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

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

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

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

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

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

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

		return TRUE;
	}

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

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

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

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

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

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

		return TRUE;
	}

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

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

		if ($path) {

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

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

		}

		return TRUE;
	}

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

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

			return FALSE;
		}

		my $items = $view->get_selected_items;
		my @sel_items;
		@sel_items = @$items if $items;

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

		return TRUE;
	}

	sub fct_get_last_capture {

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

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

		my $traytheme = $sc->get_theme;

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

		my $nmenu_entries = 0;

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

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

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

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

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

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

					$menu_urls->append($menuitem_url);
				}

				$menuitem_hoster->set_submenu($menu_urls);

				$menu_links->append($menuitem_hoster);

				$nmenu_entries++;

			}
		}

		$menu_links->show_all;

		return ($nmenu_entries, $menu_links);
	}

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

		Glib::Idle->add(
			sub {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

				return FALSE;
			});

		return TRUE;
	}

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

		my $model = $view->get_model;

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

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

		return TRUE;
	}

	sub evt_show_settings {
		fct_check_installed_programs();

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

		fct_post_settings($settings_dialog);

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

	sub fct_post_settings {
		my $settings_dialog = shift;

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

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

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

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

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

		return TRUE;
	}

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

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

		($pagesetup) = Glib::Object::Introspection->invoke('Gtk', undef, 'print_run_page_setup_dialog', $window, $pagesetup, $ssettings);

		return TRUE;
	}

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

		my $key = fct_get_current_file();

		my @save_as_files;

		#single file
		if ($key) {

			push @save_as_files, $key;

			#session tab
		} else {

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

		}

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

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

		return TRUE;

	}

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

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

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

				fct_update_profile_selectors($combobox_settings_profiles, $current_profiles_ref);

			}

			#save settings
			fct_save_settings($new_profile_name);

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

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

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

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

				fct_update_profile_selectors($combobox_settings_profiles, $current_profiles_ref);

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

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

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

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

			fct_update_info_and_tray();

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

		return TRUE;
	}

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

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

	sub fct_create_session_notebook {

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

		#enable dnd for it
		$notebook->drag_dest_set('all', [Gtk3::TargetEntry->new('text/uri-list', [], 0)], 'link');
		$notebook->signal_connect(drag_data_received => \&fct_drop_handler);
		$notebook->signal_connect(drag_motion => sub {
			my ($view, $ctx, $x, $y, $time) = @_;
			for my $target (@{$ctx->list_targets}) {
				if ($target->name eq 'text/uri-list') {
					Gtk3::Gdk::drag_status($ctx, 'link', $time);
					return TRUE;
				}
			}
			return FALSE;
		});

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

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

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

		return $notebook;
	}

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

		#check parameters
		return FALSE unless $giofile;

		unless ($giofile->query_exists) {
			fct_show_status_message(1, $giofile->get_path . " " . $d->get("not found"));
			return FALSE;
		}

		#check mime type
		my ($mime_type) = Glib::Object::Introspection->invoke('Gio', undef, 'content_type_guess', $giofile->get_path);
		$mime_type =~ s/image\/x\-apple\-ios\-png/image\/png/;    #FIXME
		if ($mime_type =~ m/(pdf|ps|svg)/ig) {

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

		#add to recentmanager
		Gtk3::RecentManager::get_default->add_item($giofile->get_path);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		if (fct_update_tab($key, $pixbuf, $giofile, undef, undef, TRUE)) {

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

		return $key;
	}

	sub fct_add_file_monitor {
		my $key = shift;

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

		eval {
			if (defined $session_screens{$key}->{'giofile'}) {
				my $monitor = $session_screens{$key}->{'giofile'}->monitor_file([]);
				$session_screens{$key}->{'monitor'} = $monitor;
				$monitor->signal_connect(
					'changed',
					sub {
						my $handle = shift;
						my $file1  = shift;
						my $file2  = shift;
						my $event  = shift;
						my $key    = shift;

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

						if ($event eq 'deleted') {

							$handle->cancel;

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

						} elsif ($event eq 'changed') {

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

						}

					},
					$key
				);
			}
		};
		if ($@) {

			#show error dialog when installing the file
			#monitor failed
			$sd->dlg_error_message("$@", $d->get("Error while adding the file monitor."));
			return FALSE;
		}

		return TRUE;
	}

	sub fct_control_signals {
		my $action = shift;

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

			$sensitive = FALSE;

			#block signals
			foreach my $connection (@signal_connections) {
				if ($app->signal_handler_is_connected($connection)) {
					$app->signal_handler_block($connection);
				}
			}

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

		} elsif ($action eq 'unblock') {

			$sensitive = TRUE;

			#attach signal-handler again
			foreach my $connection (@signal_connections) {
				if ($app->signal_handler_is_connected($connection)) {
					$app->signal_handler_unblock($connection);
				}
			}

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

		}

		#enable/disable controls
		if ($st->{_select} && $sm->{_menuitem_selection}) {
			# if $wnck_screen is undefined, we are on Wayland, and all these buttons are already disabled and should stay disabled

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

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

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

		}

		return TRUE;
	}

	sub fct_control_main_window {
		my $mode = shift;

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

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

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

			#if it's shown already, but behind other windows, without hiding it doesn't show
			$window->hide;

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

			#set flag
			$is_hidden = FALSE;

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

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

		} elsif ($mode eq 'hide') {

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

			$window->hide;

			$is_hidden = TRUE;

		}

		return TRUE;
	}

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

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

		unless ($is_all) {

			#Gtk2::ImageView - empty at first
			$session_screens{$key}->{'image'} = Gtk3::ImageView->new();
			#$session_screens{$key}->{'image'}->set_show_frame(FALSE);
			$session_screens{$key}->{'image'}->set_fitting(TRUE);
			$session_screens{$key}->{'image'}->get_style_context->add_provider($css_provider_alpha, 0);
			$session_screens{$key}->{'image'}->set('zoom-step', 1.2);

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

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

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

			$session_screens{$key}->{'image'}->signal_connect(
				'dnd-start',
				sub {
					my ($view, $x, $y, $button) = @_;
					my $list = Gtk3::TargetList->new;
					$list->add_table([Gtk3::TargetEntry->new('text/uri-list', [], 0)]);
					$view->drag_begin_with_coordinates(
						$list,
						['copy'],
						$button,
						undef,
						$x, $y,
					);
					return TRUE;
				}
			);
			$session_screens{$key}->{'image'}->signal_connect(
				'drag-data-get',
				sub {
					my ($widget, $context, $data, $info, $time) = @_;
					$data->set_uris([$session_screens{$key}->{'giofile'}->get_uri]);
				}
			);
			$session_screens{$key}->{'image'}->signal_connect(
				'zoom-changed',
				sub {
					my ($view, $zoom) = @_;
					if ($zoom >= 1) {
						$view->set_interpolation('nearest');
					} else {
						$view->set_interpolation('bilinear');
					}
				}
			);

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

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

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

			return $vbox_tab_event;

		} else {

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

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

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

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

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

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

					my @target_list;
					$session_start_screen{'first_page'}->{'view'}->selected_foreach(
						sub {
							my ($view, $path) = @_;
							my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
							if (defined $iter) {
								my $key = $session_start_screen{'first_page'}->{'model'}->get_value($iter, 2);
								if (exists $session_screens{$key}->{'giofile'}
									&& defined $session_screens{$key}->{'giofile'})
								{
									push @target_list, $session_screens{$key}->{'giofile'}->get_uri;
								}
							}
						});

					$data->set_uris(\@target_list);

				});

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

			$vbox->pack_start($vbox_tab, TRUE, TRUE, 0);
			$vbox->show_all;

			return $vbox;

		}

	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		return TRUE;
	}

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

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

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

				if ($data eq 'profile_load') {

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

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

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

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

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

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

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

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

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

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

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

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

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

					$bordereffect->set_value($settings_xml->{'general'}->{'bordereffect'});
					$bordereffect_active->set_active($settings_xml->{'general'}->{'bordereffect_active'});
					if (defined $settings_xml->{'general'}->{'bordereffect_col'}) {
						$bordereffect_cbtn->set_rgba(Gtk3::Gdk::RGBA::parse($settings_xml->{'general'}->{'bordereffect_col'}));
					}

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

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

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

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

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

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

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

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

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

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

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

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

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

					#endif profile load
				} else {

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

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

					#get plugins from cache unless param is set to ignore it
					if (!$sc->get_clear_cache) {

						foreach my $plugin_key (sort keys %{$settings_xml->{'plugins'}}) {
							utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'binary'};

							#check if plugin still exists in filesystem
							if ($shf->file_exists($settings_xml->{'plugins'}->{$plugin_key}->{'binary'})) {

								#restore newlines <![CDATA[<br>]]> tags => \n
								$settings_xml->{'plugins'}->{$plugin_key}->{'tooltip'} =~ s/\<\!\[CDATA\[\<br\>\]\]\>/\n/g;

								utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'name_plugin'};
								utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'category'};
								utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'tooltip'};
								utf8::decode $settings_xml->{'plugins'}->{$plugin_key}->{'lang'};
								$plugins{$plugin_key}->{'binary'}   = $settings_xml->{'plugins'}->{$plugin_key}->{'binary'};
								$plugins{$plugin_key}->{'name'}     = $settings_xml->{'plugins'}->{$plugin_key}->{'name_plugin'};
								$plugins{$plugin_key}->{'category'} = $settings_xml->{'plugins'}->{$plugin_key}->{'category'};
								$plugins{$plugin_key}->{'tooltip'}  = $settings_xml->{'plugins'}->{$plugin_key}->{'tooltip'};
								$plugins{$plugin_key}->{'lang'}     = $settings_xml->{'plugins'}->{$plugin_key}->{'lang'} || "shell";
								$plugins{$plugin_key}->{'recent'}   = $settings_xml->{'plugins'}->{$plugin_key}->{'recent'};
							}

						}    #endforeach

					}    #endif plugins from cache

				}

			};
			if ($@) {
				$sd->dlg_error_message($@, $d->get("Settings could not be restored!"));
				unlink $settingsfile;
			} else {
				fct_show_status_message(1, $d->get("Settings loaded successfully"));
			}

			#endif file exists
		} else {
			warn "ERROR: settingsfile " . $settingsfile . " does not exist\n\n";
		}

		return $settings_xml;
	}

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

		#add Shutter's built-in editor to the list
		if ($goocanvas) {
			my $icon_pixbuf = undef;
			my $icon        = 'shutter';
			if ($sc->get_theme->has_icon($icon)) {
				my ($iw, $ih) = $shf->icon_size('menu');
				eval { $icon_pixbuf = $sc->get_theme->load_icon($icon, $ih, 'generic-fallback'); };
				if ($@) {
					print "\nWARNING: Could not load icon $icon: $@\n";
					$icon_pixbuf = undef;
				}
			}
			$model->set($model->append, 0, $icon_pixbuf, 1, $d->get("Built-in Editor"), 2, 'shutter-built-in');
		}

		#get applications
		my $apps = Glib::IO::AppInfo::get_recommended_for_type('image/png');

		#no apps determined!
		unless (scalar @$apps) {
			return $model;
		}

		#create menu items
		foreach my $app (@$apps) {

			#ignore Shutter's desktop entry
			next if $app->get_id eq 'shutter.desktop';

			$app->{'name'} = $shf->utf8_decode($app->get_display_name);

			#get icon
			my $icon_pixbuf = undef;
			my $icon        = $app->get_icon;
			if ($icon) {
				my ($iw, $ih) = $shf->icon_size('menu');
				eval {
					my $icon_info = $sc->get_theme->choose_icon($icon->get_names, $ih, []);
					$icon_pixbuf = $icon_info->load_icon if $icon_info;
				};
				if ($@) {
					print "\nWARNING: Could not load icon for ", $app->{'name'}, ": $@\n";
					$icon_pixbuf = undef;
				}
			}
			$model->set($model->append, 0, $icon_pixbuf, 1, $app->{'name'}, 2, $app);
		}

		return $model;
	}

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

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

		if ($shf->file_exists($accountsfile)) {
			my $accounts_xml = undef;
			eval { $accounts_xml = XMLin(IO::File->new($accountsfile)) };
			if ($@) {
				$sd->dlg_error_message($@, $d->get("Account-settings could not be restored!"));
				unlink $accountsfile;
			} else {
				foreach (keys %{$accounts_xml}) {

					#check if plugin still exists
					if ($shf->file_exists($accounts_xml->{$_}->{path})) {

						#clear cache
						if (!$sc->get_clear_cache) {
							$accounts{$_}->{path}                       = $accounts_xml->{$_}->{path};
							$accounts{$_}->{module}                     = $accounts_xml->{$_}->{module};
							$accounts{$_}->{host}                       = $accounts_xml->{$_}->{host};
							$accounts{$_}->{folder}                     = $accounts_xml->{$_}->{folder};
							$accounts{$_}->{description}                = $accounts_xml->{$_}->{description};
							$accounts{$_}->{register_color}             = "blue";
							$accounts{$_}->{register_text}              = $accounts_xml->{$_}->{register_text};
							$accounts{$_}->{supports_anonymous_upload}  = $accounts_xml->{$_}->{supports_anonymous_upload};
							$accounts{$_}->{supports_authorized_upload} = $accounts_xml->{$_}->{supports_authorized_upload};
							$accounts{$_}->{supports_oauth_upload}      = $accounts_xml->{$_}->{supports_oauth_upload};

							utf8::decode $accounts{$_}->{'host'};
						}
						$accounts{$_}->{username} = $accounts_xml->{$_}->{username};
						$accounts{$_}->{password} = $accounts_xml->{$_}->{password};

						utf8::decode $accounts{$_}->{'username'};
						utf8::decode $accounts{$_}->{'password'};
					}
				}
			}
		}

		return TRUE;
	}

	sub fct_drop_handler {
		my ($widget, $context, $x, $y, $selection, $info, $time) = @_;
		my $type = $selection->get_target->name;
		return unless $type eq 'text/uri-list';
		my $data = $selection->get_data;
		$data = join('', map { chr } @$data);

		my @files = grep defined($_), split /[\r\n]+/, $data;

		my @valid_files;
		foreach my $file (@files) {
			my $giofile = Glib::IO::File::new_for_uri($file);
			my ($mime_type) = Glib::Object::Introspection->invoke('Gio', undef, 'content_type_guess', $giofile->get_path);
			$mime_type =~ s/image\/x\-apple\-ios\-png/image\/png/;    #FIXME
			if ($mime_type && fct_check_valid_mime_type($mime_type)) {
				push @valid_files, $file;
			}
		}

		#open all valid files
		if (@valid_files) {
			fct_open_files(@valid_files);
			Gtk3::drag_finish($context, 1, 0, $time);
			return TRUE;
		} else {
			Gtk3::drag_finish($context, 0, 0, $time);
			return FALSE;
		}
	}

	sub fct_check_valid_mime_type {
		my $mime_type = shift;

		foreach my $format (Gtk3::Gdk::Pixbuf::get_formats()) {
			foreach my $mtype (@{$format->get_mime_types}) {
				return TRUE if $mtype eq $mime_type;
				last;
			}
		}

		return FALSE;
	}

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

		return FALSE if scalar(@new_files) < 1;

		my ($throbber, $sep) = fct_toggle_status_throbber($status);

		foreach my $file (@new_files) {

			my $new_giofile = Glib::IO::File::new_for_uri($shf->utf8_decode(unescape_string($file)));
			next if fct_is_uri_in_session($new_giofile, TRUE);

			#refresh gui
			fct_update_gui();

			#do the real work
			if (fct_integrate_screenshot_in_notebook($new_giofile)) {
				fct_show_status_message(1, $shf->utf8_decode($new_giofile->get_path) . " " . $d->get("opened"));
			} else {
				fct_show_status_message(1, sprintf($d->get("Error while opening image %s."), "'" . $shf->utf8_decode($new_giofile->get_basename) . "'"));
			}
		}

		fct_toggle_status_throbber($status, $throbber, $sep);

		return TRUE;
	}

	sub fct_is_uri_in_session {
		my $giofile = shift;
		my $jump    = shift;

		return FALSE unless $giofile;

		foreach my $key (keys %session_screens) {
			if (exists $session_screens{$key}->{'giofile'}) {
				if ($giofile->equal($session_screens{$key}->{'giofile'})) {
					if (exists $session_screens{$key}->{'tab_child'}) {
						if ($jump) {
							$notebook->set_current_page($notebook->page_num($session_screens{$key}->{'tab_child'}));
						}
						return TRUE;
					}
				}
			}
		}

		return FALSE;
	}

	sub fct_toggle_status_throbber {
		my $status   = shift;
		my $throbber = shift;
		my $sep      = shift;
		return FALSE unless $status;

		if (defined $throbber && defined $sep) {
			$throbber->destroy;
			$throbber = undef;
			$sep->destroy;
			$sep = undef;
		} else {

			#don't show more than one
			foreach my $child ($status->get_children) {
				if ($child->get_name eq 'throbber') {
					return FALSE;
				}
			}
			$throbber = Gtk3::Image->new_from_file("$shutter_root/share/shutter/resources/icons/throbber_16x16.gif");
			$throbber->set_name('throbber');
			$sep = Gtk3::HSeparator->new;
			$status->pack_start($sep, FALSE, FALSE, 3);
			$status->pack_end($throbber, FALSE, FALSE, 0);
		}

		$status->show_all;

		return ($throbber, $sep);
	}

	sub fct_load_session {

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

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

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

			#activate throbber
			my ($throbber, $sep) = fct_toggle_status_throbber($status);

			#how many files have to be loaded
			#store this value in the session hash
			$session_start_screen{'first_page'}->{'num_session_files'} = scalar(keys %{$session_xml});

			#local counter
			#is passed to several subroutines to indicate the correct index
			my $count = 0;
			foreach my $key (sort keys %{$session_xml}) {

				#increment counter
				$count++;

				#refresh gui
				fct_update_gui();

				#do the real work
				my $new_giofile = Glib::IO::File::new_for_path(${$session_xml}{$key}{'filename'});
				if (fct_integrate_screenshot_in_notebook($new_giofile, undef, undef, $count)) {
					fct_show_status_message(1, $shf->utf8_decode($new_giofile->get_path) . " " . $d->get("opened"));
				} else {
					fct_show_status_message(1, sprintf($d->get("Error while opening image %s."), "'" . $new_giofile->get_basename . "'"));
				}

			}

			#clear the value after loading the files
			$session_start_screen{'first_page'}->{'num_session_files'} = undef;

			#de-activate the throbber
			fct_toggle_status_throbber($status, $throbber, $sep);

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

		return TRUE;
	}

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

		#check if file still exists
		unless ($session_screens{$key}->{'giofile'}->query_exists) {
			fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("not found"));
			return FALSE;
		}
		return TRUE;
	}

	sub fct_trash {
		my $key = shift;

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

		$session_screens{$key}->{'giofile'}->trash;
	}

	sub fct_delete {
		my $key    = shift;
		my $action = shift;

		#close current tab (unless $key is provided or close_all)
		unless (defined $action && $action eq 'menu_close_all') {
			$key = fct_get_current_file() unless $key;
		}

		#single file
		if ($key) {

			if ($ask_on_delete_active->get_active) {
				my $response = $sd->dlg_question_message(
					"", sprintf($d->get("Are you sure you want to move %s to the trash?"), "'" . $session_screens{$key}->{'long'} . "'"),
					'gtk-cancel', $d->get("Move to _Trash"),
				);
				return FALSE unless $response == 20;
			}

			if ($session_screens{$key}->{'giofile'}->query_exists) {
				fct_trash($key);
				eval {

					#remove from recentmanager
					Gtk3::RecentManager::get_default->remove_item($session_screens{$key}->{'giofile'}->get_path);
				};
			}

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

			if (defined $session_screens{$key}->{'iter'}
				&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
			{
				$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
			}

			#unlink undo and redo files
			fct_unlink_tempfiles($key);

			delete $session_screens{$key};

			$window->show_all unless $is_hidden;

			#session tab
		} else {

			if ($ask_on_delete_active->get_active) {

				#any files selected?
				my $selected = FALSE;
				$session_start_screen{'first_page'}->{'view'}->selected_foreach(
					sub {
						my ($view, $path) = @_;
						my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
						if (defined $iter) {
							$selected = TRUE;
						}
					});

				if ($selected) {
					my $response = $sd->dlg_question_message("", $d->get("Are you sure you want to move the selected files to the trash?"), 'gtk-cancel', $d->get("Move to _Trash"),);
					return FALSE unless $response == 20;
				} else {
					fct_show_status_message(1, $d->get("No screenshots selected"));
					return FALSE;
				}
			}

			my @to_delete;
			$session_start_screen{'first_page'}->{'view'}->selected_foreach(
				sub {
					my ($view, $path) = @_;
					my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
					if (defined $iter) {
						my $key = $session_start_screen{'first_page'}->{'model'}->get_value($iter, 2);
						$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));

						if ($session_screens{$key}->{'giofile'}->query_exists) {
							fct_trash($key);
							eval {

								#remove from recentmanager
								Gtk3::RecentManager::get_default->remove_item($session_screens{$key}->{'giofile'}->get_path);
							};
						}

						#copy to array
						#we delete the files from hash and model
						#when exiting the sub
						push @to_delete, $key;

					}
				},
				undef
			);

			if (scalar @to_delete == 0) {
				fct_show_status_message(1, $d->get("No screenshots selected"));
				return FALSE;
			}

			#delete from hash and model
			foreach my $key (@to_delete) {
				if (defined $session_screens{$key}->{'iter'}
					&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
				{
					$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
				}

				#unlink undo and redo files
				fct_unlink_tempfiles($key);

				delete $session_screens{$key};
			}

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

			$window->show_all unless $is_hidden;

		}

		fct_update_info_and_tray();

		return TRUE;
	}

	sub fct_remove {
		my $key    = shift;
		my $action = shift;

		#close current tab (unless $key is provided or close_all)
		unless (defined $action && $action eq 'menu_close_all') {
			$key = fct_get_current_file() unless $key;
		}

		#single file
		if ($key) {

			#delete instead of remove
			if ($delete_on_close_active->get_active) {
				fct_delete($key);
				return FALSE;
			}

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

				#cancel handle
				$session_screens{$key}->{'handle'}->cancel;
			}

			$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));    #delete tab
			fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session"))
				if defined($session_screens{$key}->{'long'});

			if (defined $session_screens{$key}->{'iter'}
				&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
			{
				$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
			}

			#unlink undo and redo files
			fct_unlink_tempfiles($key);

			delete $session_screens{$key};

			$window->show_all unless $is_hidden;

		} else {

			#delete instead of remove
			if ($delete_on_close_active->get_active) {
				fct_delete(undef, 'menu_close_all');
				return FALSE;
			}

			my @to_remove;
			$session_start_screen{'first_page'}->{'view'}->selected_foreach(
				sub {
					my ($view, $path) = @_;
					my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
					if (defined $iter) {
						my $key = $session_start_screen{'first_page'}->{'model'}->get_value($iter, 2);
						$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));

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

							#cancel handle
							$session_screens{$key}->{'handle'}->cancel;
						}

						#copy to array
						#we remove the files from hash and model
						#when exiting the sub
						push @to_remove, $key;

					}
				},
				undef
			);

			if (scalar @to_remove == 0) {
				fct_show_status_message(1, $d->get("No screenshots selected"));
				return FALSE;
			}

			#delete from hash and model
			foreach my $key (@to_remove) {
				if (defined $session_screens{$key}->{'iter'}
					&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
				{
					$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
				}

				#unlink undo and redo files
				fct_unlink_tempfiles($key);

				delete $session_screens{$key};
			}

			fct_show_status_message(1, $d->get("Selected screenshots removed"));

			$window->show_all unless $is_hidden;

		}

		fct_update_info_and_tray();

		return TRUE;
	}

	sub fct_update_gui {

		while (Gtk3::events_pending()) {
			Gtk3::main_iteration();
		}
		Gtk3::Gdk::flush();

		return TRUE;
	}

	sub fct_clipboard_import {

		my $image = $clipboard->wait_for_image;
		if (defined $image) {

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

			#create tempfile
			my ($tmpfh, $tmpfilename) = tempfile(UNLINK => 1);
			$tmpfilename .= "." . $filetype_value;

			#save pixbuf to tempfile and integrate it
			if ($sp->save_pixbuf_to_file($image, $tmpfilename, $filetype_value)) {
				my $new_key = fct_integrate_screenshot_in_notebook(Glib::IO::File::new_for_path($tmpfilename), $image);
			}

		} else {
			fct_show_status_message(1, $d->get("There is no image data in the clipboard to paste"));
		}

		return TRUE;
	}

	sub fct_clipboard {
		my ($widget, $mode) = @_;

		my $key = fct_get_current_file();

		#create shutter region object
		my $sr = Shutter::Geometry::Region->new();

		my @clipboard_array;

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);
			push(@clipboard_array, $key);

		} else {

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

		}

		my $clipboard_string = undef;
		my $clipboard_region = Cairo::Region->create;
		my @pixbuf_array;
		my @rects_array;
		foreach my $key (@clipboard_array) {

			if ($mode eq 'image') {
				my $pixbuf = $lp->load($session_screens{$key}->{'long'});
				my $rect   = {x=>$sr->get_clipbox($clipboard_region)->{width}, y=>0, width=>$pixbuf->get_width, height=>$pixbuf->get_height};
				$clipboard_region->union_rectangle($rect);
				push @pixbuf_array, $pixbuf;
				push @rects_array,  $rect;
			} else {
				$clipboard_string .= $session_screens{$key}->{'long'} . "\n";
			}

		}

		if ($clipboard_string) {
			chomp $clipboard_string;
			$clipboard->set_text($clipboard_string);
			fct_show_status_message(1, $d->get("Selected filenames copied to clipboard"));
		}

		if ($clipboard_region->num_rectangles) {
			my $clipboard_image = Gtk3::Gdk::Pixbuf->new('rgb', TRUE, 8, $sr->get_clipbox($clipboard_region)->{width}, $sr->get_clipbox($clipboard_region)->{height});
			$clipboard_image->fill(0x00000000);

			#copy images to the blank pixbuf
			my $rect_counter = 0;
			foreach my $pixbuf (@pixbuf_array) {
				$pixbuf->copy_area(0, 0, $pixbuf->get_width, $pixbuf->get_height, $clipboard_image, $rects_array[$rect_counter]->{x}, 0);
				$rect_counter++;
			}

			$clipboard->set_image($clipboard_image);
			fct_show_status_message(1, $d->get("Selected images copied to clipboard"));
		}

		return TRUE;
	}

	sub fct_unlink_tempfiles {
		my $key = shift;

		foreach my $tmpf (@{$session_screens{$key}->{'undo'}}) {
			unlink $tmpf;
		}

		foreach my $tmpf (@{$session_screens{$key}->{'redo'}}) {
			unlink $tmpf;
		}

		return TRUE;
	}

	sub fct_undo {

		my $key = fct_get_current_file();

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);

			#push current version to redo
			#(current version is always the last element in the array)
			my $current_version = pop @{$session_screens{$key}->{'undo'}};
			push @{$session_screens{$key}->{'redo'}}, $current_version;

			#and revert last version
			my $last_version = pop @{$session_screens{$key}->{'undo'}};
			if ($last_version) {

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

				if (cp($last_version, $session_screens{$key}->{'long'})) {

					fct_update_tab($key, undef, $session_screens{$key}->{'giofile'}, TRUE, 'gui');

					fct_show_status_message(1, $d->get("Last action undone"));

					#delete last_version from filesystem
					unlink $last_version;

				} else {

					my $response = $sd->dlg_error_message(
						sprintf($d->get("Error while copying last version (%s)."),    "'" . $last_version . "'"),
						sprintf($d->get("There was an error performing undo on %s."), "'" . $session_screens{$key}->{'long'} . "'"),
						undef, undef, undef, undef, undef, undef, $@
					);

					fct_update_tab($key, undef, $session_screens{$key}->{'giofile'}, TRUE, 'clear');

				}

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

			}

		}
		return TRUE;
	}

	sub fct_redo {

		my $key = fct_get_current_file();

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);

			#and revert last version
			my $last_version = pop @{$session_screens{$key}->{'redo'}};

			#~ push @{$session_screens{$key}->{'undo'}}, $last_version;

			if ($last_version) {

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

				if (cp($last_version, $session_screens{$key}->{'long'})) {

					fct_update_tab($key, undef, $session_screens{$key}->{'giofile'}, TRUE, 'gui');

					fct_show_status_message(1, $d->get("Last action redone"));

					#delete last_version from filesystem
					unlink $last_version;

				} else {

					my $response = $sd->dlg_error_message(
						sprintf($d->get("Error while copying last version (%s)."),    "'" . $last_version . "'"),
						sprintf($d->get("There was an error performing redo on %s."), "'" . $session_screens{$key}->{'long'} . "'"),
						undef, undef, undef, undef, undef, undef, $@
					);

					fct_update_tab($key, undef, $session_screens{$key}->{'giofile'}, TRUE, 'clear');

				}

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

			}

		}
		return TRUE;
	}

	sub fct_select_all {

		$session_start_screen{'first_page'}->{'view'}->select_all;

		return TRUE;
	}

	sub fct_plugin {

		my $key = fct_get_current_file();

		my @plugin_array;

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);

			unless (keys %plugins > 0) {
				$sd->dlg_error_message($d->get("No plugin installed"), $d->get("Failed"));
			} else {
				push(@plugin_array, $key);
				dlg_plugin(@plugin_array);
			}

			#session tab
		} else {

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

				},
				undef
			);
			dlg_plugin(@plugin_array);
		}
		return TRUE;
	}

	sub fct_show_in_folder {
		my $key = fct_get_current_file();

		my @show_in_folder_array;

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);

			print "Showing in filebrowser started  - file: " . $session_screens{$key}->{'long'} . "\n"
				if $sc->get_debug;
			push(@show_in_folder_array, $key);

		} else {

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

		}

		#open folders in filebrowser
		foreach my $ckey (@show_in_folder_array) {
			utf8::encode(my $folder_name_utf8 = $session_screens{$ckey}->{'folder'});
			$shf->xdg_open(undef, $folder_name_utf8);
		}

		return TRUE;
	}

	sub fct_rename {

		my $key = fct_get_current_file();

		my @rename_array;

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);

			print "Renaming of file " . $session_screens{$key}->{'long'} . " started\n"
				if $sc->get_debug;
			push(@rename_array, $key);

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

		dlg_rename(@rename_array);

		return TRUE;
	}

	sub fct_draw {

		my $key = fct_get_current_file();

		my @draw_array;

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);
			push(@draw_array, $key);

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

		#open drawing tool
		foreach my $key (@draw_array) {
			my $drawing_tool = Shutter::Draw::DrawingTool->new($sc);
			$drawing_tool->show(
				$session_screens{$key}->{'long'}, $session_screens{$key}->{'filetype'},   $session_screens{$key}->{'mime_type'},
				$session_screens{$key}->{'name'}, $session_screens{$key}->{'is_unsaved'}, \%session_screens
			);
		}

		#~ &fct_control_main_window ('show');

		return TRUE;
	}

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

		print "\n$data was emitted by widget $widget\n"
			if $sc->get_debug;

		#quality
		my $quality_value = $scale->get_value();

		#delay
		my $delay_value = undef;

		#include_cursor
		my $include_cursor = undef;

		#filename
		my $filename_value = $filename->get_text();

		#filetype
		my $filetype_value = undef;

		#folder to save
		my $folder = Glib::filename_to_unicode($saveDir_button->get_filename) || $folder_from_config;
		if ($save_no_active->get_active) {
			$folder = $sdir->get_cache_dir;
		}

		#screenshot(pixbuf) and screenshot name
		my $screenshot       = undef;
		my $screenshooter    = undef;
		my $screenshot_name  = undef;
		my $thumbnail_ending = "thumb";

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

		#delay
		#when capturing a menu or tooltip => disable delay (there is a dedicated delay property for this)
		unless ($data eq "menu"
			|| $data eq "tray_menu"
			|| $data eq "tooltip"
			|| $data eq "tray_tooltip")
		{
			if (defined $sc->get_delay) {
				$delay_value = int $sc->get_delay;
			} else {
				if ($delay->get_value) {
					$delay_value = int $delay->get_value;
				} else {
					$delay_value = 0;
				}
			}
		} else {
			$delay_value = 0;
		}

		#cursor
		if ($sc->get_include_cursor) {
			$include_cursor = $sc->get_include_cursor;
		} elsif ($sc->get_remove_cursor) {
			$include_cursor = FALSE;
		} else {
			if ($cursor_active->get_active) {
				$include_cursor = $cursor_active->get_active;
			} else {
				$include_cursor = FALSE;
			}
		}

		#fullscreen screenshot
		if ($data eq "full" || $data eq "tray_full") {

			$screenshooter = Shutter::Screenshot::Workspace->new(
				$sc, $include_cursor, $delay_value,
				$notify_timeout_active->get_active,
				$wnck_screen->get_active_workspace,
				undef, undef, $current_monitor_active->get_active
			);

			$screenshot = $screenshooter->workspace();

			#window
		} elsif ($data eq "window"
			|| $data eq "tray_window"
			|| $data eq "awindow"
			|| $data eq "tray_awindow"
			|| $data eq "section"
			|| $data eq "tray_section"
			|| $data eq "menu"
			|| $data eq "tray_menu"
			|| $data eq "tooltip"
			|| $data eq "tray_tooltip")
		{

			#control some wm related settings
			my $curr_value = fct_control_wm_settings('start');

			if (defined $extra && $extra) {

				$screenshooter = Shutter::Screenshot::WindowName->new(
					$sc,                        $include_cursor,               $delay_value,            $notify_timeout_active->get_active,
					$border_active->get_active, $winresize_active->get_active, $winresize_w->get_value, $winresize_h->get_value,
					$hide_time->get_value,      $data,                         $autoshape_active->get_active
				);

				$screenshot = $screenshooter->window_find_by_name($extra);

			} else {

				$screenshooter = Shutter::Screenshot::Window->new(
					$sc,                                 $include_cursor,               $delay_value,                  $notify_timeout_active->get_active,
					$border_active->get_active,          $winresize_active->get_active, $winresize_w->get_value,       $winresize_h->get_value,
					$hide_time->get_value,               $data,                         $autoshape_active->get_active, $is_hidden,
					$visible_windows_active->get_active, $menu_waround_active->get_active
				);

				$screenshot = $screenshooter->window();

			}

			#control some wm related settings
			if (defined $curr_value && $curr_value != -1) {
				fct_control_wm_settings('stop', $curr_value);
			}

			#selection
		} elsif ($data eq "select" || $data eq "tray_select") {

			if (defined $extra && $extra) {

				my @coords = split(',', $extra);

				$screenshooter = Shutter::Screenshot::SelectorAuto->new($sc, $include_cursor, $delay_value, $notify_timeout_active->get_active,);

				$screenshot = $screenshooter->select_auto($coords[0], $coords[1], $coords[2], $coords[3]);

			} else {

				$screenshooter = Shutter::Screenshot::SelectorAdvanced->new(
					$sc,                      $include_cursor,        $delay_value,                $notify_timeout_active->get_active,
					$zoom_active->get_active, $hide_time->get_value,  $as_help_active->get_active, $asel_size3->get_value,
					$asel_size4->get_value,   $asel_size1->get_value, $asel_size2->get_value,
				);

				$screenshot = $screenshooter->select_advanced();

			}

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

			my $website_width = 1024;
			if ($combobox_web_width->get_active_text =~ /(\d+)/) {
				$website_width = $1;
			}

			print "\nvirtual website width: $website_width\n"
				if $sc->get_debug;

			#determine timeout
			my $web_menu = $st->{_web}->get_menu;
			my @timeouts = $web_menu->get_children;
			my $timeout  = undef;
			foreach my $to (@timeouts) {
				if ($to->get_active) {
					$timeout = $to->get_name;
					$timeout =~ /([0-9]+)/;
					$timeout = $1;
					print $timeout. "\n" if $sc->get_debug;
				}
			}

			$screenshooter = Shutter::Screenshot::Web->new($sc, $timeout, $website_width);
			$screenshot    = $screenshooter->dlg_website($extra);

			#window by xid
		} elsif ($data =~ /^shutter_window_direct(.*)/) {

			my $xid = $1;
			print "Selected xid: $xid\n" if $sc->get_debug;

			#control some wm related settings
			my $curr_value = fct_control_wm_settings('start');

			#change mode (imitating selecting a window by mouse)
			$data = "window";

			$screenshooter = Shutter::Screenshot::WindowXid->new(
				$sc,                        $include_cursor,               $delay_value,            $notify_timeout_active->get_active,
				$border_active->get_active, $winresize_active->get_active, $winresize_w->get_value, $winresize_h->get_value,
				$hide_time->get_value,      $data,                         $autoshape_active->get_active
			);

			$screenshot = $screenshooter->window_by_xid($xid);

			#control some wm related settings
			if (defined $curr_value && $curr_value != -1) {
				fct_control_wm_settings('stop', $curr_value);
			}

		} elsif ($data =~ /^shutter_wrksp_direct/) {

			#we need to handle different wm, e.g. metacity, compiz here
			my $selected_workspace = undef;
			my $vpx                = undef;
			my $vpy                = undef;

			#compiz
			if ($data =~ /compiz(\d*)x(\d*)/) {
				$vpx = $1;
				$vpy = $2;
				print "Sel. Viewport: $vpx, $vpy\n" if $sc->get_debug;

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

				#all workspaces
			} elsif ($data =~ /shutter_wrksp_all/) {
				print "Capturing all workspaces\n"
					if $sc->get_debug;
				$selected_workspace = 'all';
			}

			$screenshooter =
				Shutter::Screenshot::Workspace->new($sc, $include_cursor, $delay_value, $notify_timeout_active->get_active, $selected_workspace, $vpx, $vpy, $current_monitor_active->get_active);

			if ($selected_workspace eq 'all') {
				$screenshot = $screenshooter->workspaces();
			} else {
				$screenshot = $screenshooter->workspace();
			}

		} elsif ($data eq "redoshot") {

			#~ my $key = fct_get_last_capture();
			#~ if(defined $key && exists $session_screens{$key}->{'history'} && defined $session_screens{$key}->{'history'}){
			#~ $screenshooter = $session_screens{$key}->{'history'};
			#~ $screenshot = $screenshooter->redo_capture;
			#~ }else{
			#~ $screenshot = 3;
			#~ }

			if ($screenshooter = fct_get_last_capture()) {

				#we need to handle menu and tooltip in a special way
				if ($screenshooter->can('get_mode')) {
					if (my $mode = $screenshooter->get_mode) {

						#control some wm related settings
						my $curr_value = undef;
						if (($mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section")) {
							$curr_value = fct_control_wm_settings('start');
						}

						if ($mode eq "menu" || $mode eq "tray_menu") {
							$st->{_menu}->signal_emit('clicked');
							return FALSE;
						} elsif ($mode eq "tooltip" || $mode eq "tray_tooltip") {
							$st->{_tooltip}->signal_emit('clicked');
							return FALSE;
						} else {
							$screenshot = $screenshooter->redo_capture;
						}

						#control some wm related settings
						if (($mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section")) {
							if (defined $curr_value && $curr_value != -1) {
								fct_control_wm_settings('stop', $curr_value);
							}
						}

						#window by xid
					} else {

						#control some wm related settings
						my $curr_value = fct_control_wm_settings('start');
						$screenshot = $screenshooter->redo_capture;

						#control some wm related settings
						if (defined $curr_value && $curr_value != -1) {
							fct_control_wm_settings('stop', $curr_value);
						}
					}
				} else {
					$screenshot = $screenshooter->redo_capture;
				}
			} else {
				$screenshot = 3;
			}

		} elsif ($data eq "redoshot_this") {

			#get current screenshot (current notebook page)
			my $key = fct_get_current_file();

			#or get the selected screenshot in the view
			unless (defined $key) {
				$session_start_screen{'first_page'}->{'view'}->selected_foreach(
					sub {
						my ($view, $path) = @_;
						my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
						if (defined $iter) {
							$key = $session_start_screen{'first_page'}->{'model'}->get_value($iter, 2);
						}
					},
					undef
				);
			}

			if (   defined $key
				&& exists $session_screens{$key}->{'history'}
				&& defined $session_screens{$key}->{'history'})
			{
				$screenshooter = $session_screens{$key}->{'history'};

				#we need to handle menu and tooltip in a special way
				if ($screenshooter->can('get_mode')) {
					if (my $mode = $screenshooter->get_mode) {

						#control some wm related settings
						my $curr_value = undef;
						if (($mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section")) {
							$curr_value = fct_control_wm_settings('start');
						}

						if ($mode eq "menu" || $mode eq "tray_menu") {
							$st->{_menu}->signal_emit('clicked');
							return FALSE;
						} elsif ($mode eq "tooltip" || $mode eq "tray_tooltip") {
							$st->{_tooltip}->signal_emit('clicked');
							return FALSE;
						} else {
							$screenshot = $screenshooter->redo_capture;
						}

						#control some wm related settings
						if (($mode eq "window" || $mode eq "tray_window" || $mode eq "awindow" || $mode eq "tray_awindow" || $mode eq "section" || $mode eq "tray_section")) {
							if (defined $curr_value && $curr_value != -1) {
								fct_control_wm_settings('stop', $curr_value);
							}
						}

						#window by xid
					} else {

						#control some wm related settings
						my $curr_value = fct_control_wm_settings('start');
						$screenshot = $screenshooter->redo_capture;

						#control some wm related settings
						if (defined $curr_value && $curr_value != -1) {
							fct_control_wm_settings('stop', $curr_value);
						}
					}
				} else {
					$screenshot = $screenshooter->redo_capture;
				}
			} else {
				$screenshot = 3;
			}

		} else {

			#show error dialog
			my $response = $sd->dlg_error_message($d->get("Triggered invalid screenshot action."), $d->get("Error while taking the screenshot."));

			fct_show_status_message(1, $d->get("Error while taking the screenshot."));
			fct_control_main_window('show');
			return FALSE;
		}

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

		#...successfully???
		my $giofile = undef;
		my $error = Shutter::Screenshot::Error->new($sc, $screenshot, $data, $extra);
		if ($error->is_error) {
			my $detailed_error_text = '';
			if (defined $screenshooter && $screenshooter) {
				$detailed_error_text = $screenshooter->get_error_text;
			}
			my ($response, $status_text) = $error->show_dialog($detailed_error_text);
			fct_show_status_message(1, $status_text);
			if ($error->is_aborted_by_user) {
				fct_control_main_window('show', $present_after_active->get_active);
			} else {
				fct_control_main_window('show');
			}
			return FALSE;

		} else {
			#get next filename (auto increment using a wild card or manually)
			if ($sc->get_export_filename) {
				my ($short, $folder, $ext) = fileparse($shf->switch_home_in_file($shf->utf8_decode($sc->get_export_filename)), qr/\.[^.]*/);

				#set filetype
				$filetype_value = $ext;
				$filetype_value =~ s/\.//;

				#prepare filename, parse wild-cards
				$short = strftime $short, localtime;

				#..remove / and #
				$short =~ s/(\/|\#)/-/g;

				#relative to abs
				my $tmp_filename = $folder . $short . $ext;
				unless (File::Spec->file_name_is_absolute($tmp_filename)) {
					$tmp_filename = File::Spec->rel2abs($tmp_filename);
				}

				#..replace wildcards by values
				$tmp_filename = &fct_parse_filename_wildcards($tmp_filename, $screenshooter, $screenshot);

				#...and create an uri
				$giofile = Glib::IO::File::new_for_path($tmp_filename);
			} else {

				#prepare filename, parse wild-cards
				$filename_value = $shf->utf8_decode(strftime $filename_value , localtime);

				#..remove / and #
				$filename_value =~ s/(\/|\#)/-/g;

				#..replace wildcards by values
				$filename_value = &fct_parse_filename_wildcards($filename_value, $screenshooter, $screenshot);

				#...and get next filename
				$giofile = fct_get_next_filename($filename_value, $folder, $filetype_value);
			}

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


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

			#maybe / is set as uri (get_path returns undef)
			#in this case nothing is returned when using get_path
			#we use the directory name and the short name in this case
			#(anyway - most users won't have permissions to write to /)
			$screenshot_name = "/" . $giofile->get_basename
				unless $screenshot_name;

			#update uri after parsing as well, so we can check if file exists for example
			$giofile = Glib::IO::File::new_for_path($screenshot_name);

			#maybe the uri already exists, so we have to append some digits (e.g. testfile01(0002).png)
			#don't check if filename is set via cmd parameter
			unless ($sc->get_export_filename) {
				if ($giofile->query_exists) {
					my $count        = 1;
					my $new_filename = fileparse($shf->utf8_decode(unescape_string($giofile->get_path)), qr/\.[^.]*/);

					print "Checking if filename already exists: " . $new_filename . "\n"
						if $sc->get_debug;

					my $existing_filename = $new_filename;
					while ($giofile->query_exists) {
						$new_filename = $existing_filename . "(" . sprintf("%03d", $count++) . ")";
						$giofile      = Glib::IO::File::new_for_path($folder);
						$giofile      = $giofile->append_string("$new_filename.$filetype_value");
						print "Checking new uri after parsing: " . $giofile->get_path . "\n"
							if $sc->get_debug;
					}
				}
			}

			#we have to update the path again
			$screenshot_name = $shf->utf8_decode(unescape_string($giofile->get_path));

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

			print "New uri after exists check: " . $shf->utf8_decode($giofile->get_path) . "\n"
				if $sc->get_debug;

			#manipulate before saving
			#bordereffect
			if ($bordereffect_active->get_active) {

				print "Adding border effect to $screenshot_name\n"
					if $sc->get_debug;

				my $pbuf_border = Shutter::Pixbuf::Border->new($sc);
				$screenshot = $pbuf_border->create_border($screenshot, $bordereffect->get_value, $bordereffect_cbtn->get_color);
			}

			#ask for filename and folder
			if ($save_ask_active->get_active) {

				print "Asking for filename\n"
					if $sc->get_debug;

				if ($screenshot_name = dlg_save_as(undef, undef, $screenshot_name, $screenshot, $quality_value)) {
					if ($screenshot_name eq 'user_cancel') {
						fct_show_status_message(1, $d->get("Capture aborted by user"));
						fct_control_main_window('show', $present_after_active->get_active);
						return FALSE;
					} else {

						#update uri after saving, so we can check if file exists for example
						$giofile = Glib::IO::File::new_for_path($screenshot_name);
					}
				} else {
					fct_control_main_window('show');
					return FALSE;
				}

			} else {

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

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

			}

		}    #end screenshot successfull

		if ($giofile->query_exists) {

			#quantize
			if ($im_colors_active->get_active) {
				my $colors;
				if ($combobox_im_colors->get_active == 0) {
					$colors = 16;
				} elsif ($combobox_im_colors->get_active == 1) {
					$colors = 64;
				} elsif ($combobox_im_colors->get_active == 2) {
					$colors = 256;
				}
				$screenshot = fct_imagemagick_perform('reduce_colors', $screenshot_name, $colors);
			}

			#generate the thumbnail
			my $screenshot_thumbnail      = undef;
			my $screenshot_thumbnail_name = undef;
			if ($thumbnail_active->get_active) {

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

				#create thumbail
				$screenshot_thumbnail = $lp->load($screenshot_name, $twidth, $theight, TRUE);

				#save path of thumbnail
				my ($name, $folder, $ext) = fileparse($screenshot_name, qr/\.[^.]*/);
				$screenshot_thumbnail_name = $folder . "/$name-$thumbnail_ending.$filetype_value";

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

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

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

			}

			my $new_key_screenshot           = undef;
			my $new_key_screenshot_thumbnail = undef;

			#Dont add it to session if no_session-parameter is set
			unless ($sc->get_no_session) {

				#Dont add it to session if it already exists
				unless (fct_is_uri_in_session($giofile, TRUE)) {

					#integrate it into the notebook
					$new_key_screenshot = fct_integrate_screenshot_in_notebook($giofile, $screenshot, $screenshooter);

					#thumbnail as well if present
					$new_key_screenshot_thumbnail = fct_integrate_screenshot_in_notebook(Glib::IO::File::new_for_path($screenshot_thumbnail_name), $screenshot_thumbnail)
						if $thumbnail_active->get_active;

					$session_screens{$new_key_screenshot}->{'image'}->set_fitting(TRUE);
				}
			}

			#in some cases it is not possible to add it to the session
			#e.g. when saving to pdf
			if ($new_key_screenshot) {

				#copy to clipboard
				if (!$no_autocopy_active->get_active()) {

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

					#filename autocopy to clipboard if configured
					if ($fname_autocopy_active->get_active()) {
						$clipboard->set_text($screenshot_name);
					}

				}

				#open screenshot with configured program
				if ($progname_active->get_active) {
					my $model         = $progname->get_model();
					my $progname_iter = $progname->get_active_iter();
					if ($progname_iter) {
						my $progname_value = $model->get_value($progname_iter, 2);
						my $appname_value  = $model->get_value($progname_iter, 1);
						fct_open_with_program($progname_value, $appname_value);
					}
				}
				print "screenshot successfully saved to $screenshot_name!\n"
					if $sc->get_debug;

				fct_show_status_message(1, sprintf($d->get("%s saved"), $session_screens{$new_key_screenshot}->{'short'}));

				#show pop-up notification
				if ($notify_after_active->get_active) {
					my $notify = $sc->get_notification_object;
					if (defined $session_screens{$new_key_screenshot}->{'is_unsaved'}
						&& $session_screens{$new_key_screenshot}->{'is_unsaved'})
					{
						$notify->show($d->get("Screenshot saved"), "*" . $session_screens{$new_key_screenshot}->{'name'});
					} else {
						$notify->show($d->get("Screenshot saved"), $session_screens{$new_key_screenshot}->{'long'});
					}
				}

			} else {    #endif - adding to session worked

				print "screenshot successfully saved to $screenshot_name, but unable to add the file to session!\n"
					if $sc->get_debug;

				fct_show_status_message(1, sprintf($d->get("%s saved"), $screenshot_name));

				#show pop-up notification
				if ($notify_after_active->get_active) {
					my $notify = $sc->get_notification_object;
					$notify->show($d->get("Screenshot saved"), $screenshot_name);
				}

			}

		} else {

			#show error dialog
			my $response = $sd->dlg_error_message(sprintf($d->get("The filename %s could not be verified. Maybe it contains unsupported characters."), "'" . $screenshot_name . "'"),
				$d->get("Error while taking the screenshot."));
			fct_show_status_message(1, $d->get("Error while taking the screenshot."));
			fct_control_main_window('show');
			return FALSE;

		}

		fct_control_main_window('show', $present_after_active->get_active);

		#Exit Shutter after the first capture has been made.
		#This is useful when using Shutter in scripts.
		if ($sc->get_exit_after_capture) {
			evt_delete_window('', 'quit');
		}

		return TRUE;
	}

	sub fct_update_tray_menu {
		my $screen = shift;
		if ($sc->get_debug) {
			print "\nfct_update_tray_menu was called by $screen\n";
		}

		#update window list
		foreach my $child ($tray_menu->get_children) {
			if ($child->get_name eq 'windowlist') {
				$child->set_submenu(fct_ret_window_menu());
				last;
			}
		}
	}

	sub fct_upload {

		my $key = fct_get_current_file();

		my @upload_array;

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);
			push(@upload_array, $key);
			dlg_upload(@upload_array);

			#session tab
		} else {

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

				},
				undef
			);
			dlg_upload(@upload_array);

		}

		#update actions
		#new public links might be available
		foreach my $key (@upload_array) {
			fct_update_actions(1, $key);
		}

		return TRUE;
	}

	sub fct_send {

		my $key = fct_get_current_file();

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

				});
		} else {
			push(@files_to_send, $session_screens{$key}->{'long'});
		}

		my $sendto_string = undef;
		foreach my $sendto_filename (@files_to_send) {
			$sendto_string .= "'$sendto_filename' ";
		}

		$shf->nautilus_sendto($sendto_string);

		return TRUE;
	}

	sub fct_email {

		my $key = fct_get_current_file();

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

				});
		} else {
			push(@files_to_email, $session_screens{$key}->{'long'});
		}

		my @mail_args = map { ('--attach' => $_) } @files_to_email;

		$shf->xdg_open_mail(undef, undef, @mail_args);

		return TRUE;
	}

	sub fct_print {

		my $key = fct_get_current_file();

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

				});
		} else {
			push(@pages, $session_screens{$key}->{'long'});
		}

		my $op = Gtk3::PrintOperation->new;
		$op->set_job_name(SHUTTER_NAME . " - " . SHUTTER_VERSION . " - " . localtime);
		$op->set_n_pages(scalar @pages);
		$op->set_unit('none'); # aka pixel
		$op->set_show_progress(TRUE);
		$op->set_default_page_setup($pagesetup);

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

		$op->signal_connect(
			'status-changed' => sub {
				my $op = shift;
				fct_show_status_message(1, $op->get_status_string);
			});

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

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

				#load pixbuf from file
				if (my $pixbuf = $lp->load($pages[$int])) {

					#scale if image doesn't fit on page
					my $scale_x = $pc->get_width / $pixbuf->get_width;
					my $scale_y = $pc->get_height / $pixbuf->get_height;
					if (min($scale_x, $scale_y) < 1) {
						$cr->scale(min($scale_x, $scale_y), min($scale_x, $scale_y));
					}

					Gtk3::Gdk::cairo_set_source_pixbuf($cr, $pixbuf, 0, 0);

				}

				$cr->paint;

			});

		$op->run('print-dialog', $window);

		#save settings
		my $settings = $op->get_print_settings;
		eval { $settings->to_file("$ENV{ HOME }/.shutter/printing.xml"); };

		return TRUE;
	}

	sub fct_open_with_program {
		my $app = shift;

		#no program set - exit
		return FALSE unless $app;

		my $key = fct_get_current_file();

		#single file
		if ($key) {

			return FALSE unless fct_screenshot_exists($key);

			#built-in-editor
			if ($app =~ /shutter/i) {
				fct_draw();
				fct_show_status_message(1, sprintf($d->get("%s opened with %s"), $session_screens{$key}->{'short'}, $d->get("Built-in Editor")));
			} else {

				#everything is fine -> open it
				if ($app->supports_uris) {
					$app->launch_uris([$session_screens{$key}->{'giofile'}->get_uri]);
				} else {
					$app->launch([$session_screens{$key}->{'giofile'}]);
				}
				fct_show_status_message(1, sprintf($d->get("%s opened with %s"), $session_screens{$key}->{'short'}, $app->{'name'}));
			}

			#session tab
		} else {

			my @open_files;
			$session_start_screen{'first_page'}->{'view'}->selected_foreach(
				sub {
					my ($view, $path) = @_;
					my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
					if (defined $iter) {
						my $key = $session_start_screen{'first_page'}->{'model'}->get_value($iter, 2);
						if ($app->supports_uris) {
							push @open_files, $session_screens{$key}->{'giofile'}->get_uri;
						} else {
							push @open_files, $session_screens{$key}->{'giofile'};
						}
					}
				},
				undef
			);
			if (@open_files > 0) {
				if ($app->supports_uris) {
					$app->launch_uris(\@open_files);
				} else {
					$app->launch(\@open_files);
				}
				fct_show_status_message(1, $d->get("Opened all files with") . " " . $app->{'name'});
			}
		}

		return TRUE;
	}

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

		unless ($shf->file_exists($session_screens{$key}->{'long'})) {
			return FALSE;
		}

		#if it is a native perl plugin, use a plug to integrate it properly
		if ($plugin_lang eq "perl") {

			#hide plugin dialog
			$plugin_dialog->hide if defined $plugin_dialog;

			#dialog to show the plugin
			my $sdialog = Gtk3::Dialog->new($plugin_name, $window, [qw/modal destroy-with-parent/]);
			$sdialog->set_resizable(FALSE);

			# Ensure that the dialog box is destroyed when the user responds.
			$sdialog->signal_connect(response => sub { $_[0]->destroy });

			#initiate the socket to draw the contents of the plugin to our dialog
			my $socket = Gtk3::Socket->new;
			$sdialog->get_child->add($socket);
			$socket->signal_connect(
				'plug-removed' => sub {
					$sdialog->destroy();
					return TRUE;
				});

			printf("\n", $socket->get_id);

			my $pid = fork;
			if ($pid < 0) {
				$sd->dlg_error_message(sprintf($d->get("Could not apply plugin %s"), "'" . $plugin_name . "'"), $d->get("Failed"));
			} elsif ($pid == 0) {

				#see Bug #661424
				#my $qfilename = quotemeta $session_screens{$key}->{'long'};
				exec($^X, $plugin_value, $socket->get_id, $session_screens{$key}->{'long'}, $session_screens{$key}->{'width'}, $session_screens{$key}->{'height'},
					$session_screens{$key}->{'filetype'});
			}

			$sdialog->show_all;
			$sdialog->run;

			waitpid($pid, 0);

			#check exit code
			if ($? == 0) {
				fct_show_status_message(1, sprintf($d->get("Successfully applied plugin %s"), "'" . $plugin_name . "'"));
			} elsif ($? / 256 == 1) {
				fct_show_status_message(1, sprintf($d->get("Could not apply plugin %s"), "'" . $plugin_name . "'"));
			}

			#...if not => simple execute the plugin via system (e.g. shell plugins)
		} else {

			print "$plugin_value $session_screens{$key}->{'long'} $session_screens{$key}->{'width'} $session_screens{$key}->{'height'} $session_screens{$key}->{'filetype'} submitted to plugin\n"
				if $sc->get_debug;

			#cancel handle, because file gets manipulated
			#multiple times
			if (exists $session_screens{$key}->{'handle'}) {
				$session_screens{$key}->{'handle'}->cancel;
			}

			#create a new process, so we are able to cancel the current operation
			my $plugin_process = Proc::Simple->new;

			#see Bug #661424
			#my $qfilename = quotemeta $session_screens{$key}->{'long'};

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

			#ignore delete-event during execute
			$plugin_dialog->signal_connect(
				'delete-event' => sub {
					return TRUE;
				});

			#we are also able to show a little progress bar to give some feedback
			#to the user. there is no real progress because we are just executing a shell script
			while ($plugin_process->poll) {
				$plugin_progress->set_text($plugin_name . " - " . $session_screens{$key}->{'short'});
				$plugin_progress->pulse;
				fct_update_gui();
				usleep 100000;
			}

			fct_update_gui();

			#finally show some status messages
			if ($plugin_process->exit_status() == 0) {
				fct_show_status_message(1, sprintf($d->get("Successfully applied plugin %s"), "'" . $plugin_name . "'"));
			} else {
				$sd->dlg_error_message(sprintf($d->get("Error while executing plugin %s."), "'" . $plugin_name . "'"), $d->get("There was an error executing the plugin."),);
			}

			#update session tab manually
			fct_update_tab($key, undef, $session_screens{$key}->{'giofile'});

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

		}

		return TRUE;
	}

	sub fct_show_status_message {
		my $index       = shift;
		my $status_text = shift;

		$status->pop($index);
		if (defined $session_start_screen{'first_page'}->{'statusbar_timer'}) {
			if ($session_start_screen{'first_page'}->{'statusbar_timer'}) {
				Glib::Source->remove($session_start_screen{'first_page'}->{'statusbar_timer'});
			}
		}
		$status->push($index, $status_text);

		#...and remove it
		$session_start_screen{'first_page'}->{'statusbar_timer'} = Glib::Timeout->add(
			3000,
			sub {
				$status->pop($index);

				#show file or session info again
				fct_update_info_and_tray();
				return FALSE;
			});

		return TRUE;
	}

	sub fct_update_info_and_tray {
		my $force_key = shift;

		my $key = undef;
		if ($force_key) {
			if ($force_key eq "session") {
				$key = undef;
			} else {
				$key = $force_key;
			}
		} else {
			$key = fct_get_current_file();
		}

		#STATUSBAR AND WINDOW TITLE
		#--------------------------------------
		#update statusbar when this image is current tab
		if (   $key
			&& defined $session_screens{$key}->{'long'}
			&& defined $session_screens{$key}->{'width'})
		{

			#change window title
			if (defined $session_screens{$key}->{'is_unsaved'}
				&& $session_screens{$key}->{'is_unsaved'})
			{
				$window->set_title("*" . $session_screens{$key}->{'name'} . " - " . SHUTTER_NAME);
			} else {
				$window->set_title($session_screens{$key}->{'long'} . " - " . SHUTTER_NAME);
			}

			$status->push(1,
				$session_screens{$key}->{'width'} . " x " . $session_screens{$key}->{'height'} . " " . $d->get("pixels") . "  " . $shf->utf8_decode($hu->format($session_screens{$key}->{'size'})));

			#session tab
		} else {

			#change window title
			$window->set_title($d->get("Session") . " - " . SHUTTER_NAME);

			$status->push(1,
				sprintf($d->nget("%s screenshot", "%s screenshots", scalar(keys(%session_screens))), scalar(keys(%session_screens))) . "  "
					. $shf->utf8_decode($hu->format(fct_get_total_size_of_session())));

		}

		#TRAY TOOLTIP
		#--------------------------------------
		if ($combobox_settings_profiles) {
			if ($tray && $tray->isa('Gtk3::StatusIcon')) {
				if ($combobox_settings_profiles->get_active_text) {
					$tray->set_tooltip_text($d->get("Current profile") . ": " . $combobox_settings_profiles->get_active_text);
				} else {
					$tray->set_tooltip_text(SHUTTER_NAME . " " . SHUTTER_VERSION);
				}
			}
		}

		return TRUE;
	}

	sub fct_get_key_by_filename {
		my $filename = shift;

		return unless $filename;

		my $key = undef;

		#and loop through hash to find the corresponding key
		foreach my $ckey (keys %session_screens) {
			next unless exists $session_screens{$ckey}->{'long'};

			#~ print "compare ".$session_screens{$ckey}->{'long'}." - $filename\n";
			if ($session_screens{$ckey}->{'long'} eq $filename) {
				$key = $ckey;
				last;
			}
		}

		return $key;
	}

	sub fct_get_key_by_pubfile {
		my $filename = shift;

		return unless $filename;

		my $key = undef;

		#and loop through hash to find the corresponding key
		foreach my $ckey (keys %session_screens) {
			next unless exists $session_screens{$ckey}->{'links'};
			next
				unless exists $session_screens{$ckey}->{'links'}->{'ubuntu-one'};
			next
				unless exists $session_screens{$ckey}->{'links'}->{'ubuntu-one'}->{'pubfile'};

			#~ print "compare ".$session_screens{$ckey}->{'links'}->{'ubuntu-one'}->{'pubfile'}." - $filename\n";
			if ($session_screens{$ckey}->{'links'}->{'ubuntu-one'}->{'pubfile'} eq $filename) {
				$key = $ckey;
				last;
			}
		}

		return $key;
	}

	sub fct_get_file_by_index {
		my $index = shift;

		return unless $index;

		#get current page
		my $curr_page = $notebook->get_nth_page($index);

		my $key = undef;

		#and loop through hash to find the corresponding key
		if ($curr_page) {
			foreach my $ckey (keys %session_screens) {
				next unless exists $session_screens{$ckey}->{'tab_child'};
				if ($session_screens{$ckey}->{'tab_child'} == $curr_page) {
					$key = $ckey;
					last;
				}
			}
		}

		return $key;
	}

	sub fct_get_total_size_of_session {
		my $total_size = 0;
		foreach my $ckey (keys %session_screens) {
			next unless $session_screens{$ckey}->{'size'};
			$total_size += $session_screens{$ckey}->{'size'};
		}
		return $total_size;
	}

	sub fct_get_current_file {

		#get current page
		my $curr_page = $notebook->get_nth_page($notebook->get_current_page);

		my $key = undef;

		#and loop through hash to find the corresponding key
		if ($curr_page) {
			foreach my $ckey (keys %session_screens) {
				next unless (exists $session_screens{$ckey}->{'tab_child'});
				if ($session_screens{$ckey}->{'tab_child'} == $curr_page) {
					$key = $ckey;
					last;
				}
			}
		}

		return $key;
	}

	sub fct_update_profile_selectors {
		my ($combobox_settings_profiles, $current_profiles_ref, $recur_widget) = @_;

		#populate quick selector as well
		if (scalar @{$current_profiles_ref} > 0) {

			#tray menu
			foreach my $child ($tray_menu->get_children) {
				if ($child->get_name eq 'quicks') {
					$child->set_submenu(fct_ret_profile_menu($combobox_settings_profiles, $current_profiles_ref));
					$child->set_sensitive(TRUE);
					last;
				}
			}

			#main menu
			$sm->{_menuitem_quicks}->set_submenu(fct_ret_profile_menu($combobox_settings_profiles, $current_profiles_ref, $sm->{_menuitem_quicks}->get_submenu));
			$sm->{_menuitem_quicks}->set_sensitive(TRUE);

			#and statusbar
			#FIXME - some explanation is missing here
			unless ($recur_widget
				&& $recur_widget eq $combobox_status_profiles)
			{
				if (   defined $combobox_status_profiles
					&& defined $combobox_status_profiles_label)
				{
					$combobox_status_profiles_label->destroy;
					$combobox_status_profiles->destroy;
				}

				$combobox_status_profiles_label = Gtk3::Label->new($d->get("Profile") . ":");
				$combobox_status_profiles       = Gtk3::ComboBoxText->new;
				$status->pack_start($combobox_status_profiles_label, FALSE, FALSE, 0);
				$status->pack_start($combobox_status_profiles,       FALSE, FALSE, 0);

				foreach my $profile (@{$current_profiles_ref}) {
					$combobox_status_profiles->append_text($profile);
				}

				$combobox_status_profiles->set_active($combobox_settings_profiles->get_active);

				$combobox_status_profiles->signal_connect(
					'changed' => sub {
						my $widget = shift;

						$combobox_settings_profiles->set_active($widget->get_active);
						evt_apply_profile($widget, $combobox_settings_profiles, $current_profiles_ref);

					});

				$status->show_all;
			}

		} else {

			#tray menu
			foreach my $child ($tray_menu->get_children) {
				if ($child->get_name eq 'quicks') {
					$child->remove_submenu;
					$child->set_sensitive(FALSE);
					last;
				}
			}

			#main menu
			$sm->{_menuitem_quicks}->remove_submenu;
			$sm->{_menuitem_quicks}->set_sensitive(FALSE);

			#and statusbar
			if (   defined $combobox_status_profiles
				&& defined $combobox_status_profiles_label)
			{
				$combobox_status_profiles_label->destroy;
				$combobox_status_profiles->destroy;
			}
		}
		return TRUE;
	}

	sub fct_update_tab {

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

		#optional, e.g.used by fct_integrate...
		my $pixbuf        = shift;
		my $giofile       = shift;
		my $force_thumb   = shift;
		my $xdo           = shift;
		my $no_image_load = shift;

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

		#something wrong here
		unless (defined $session_screens{$key}->{'giofile'}) {
			return FALSE;
		}

		#sometimes there are some read errors
		#because the CHANGED signal gets emitted by the file monitor
		#but the file is still in use (e.g. plugin, external app)
		#we try to read the fileinfos and the file itsels several times
		#until throwing an error
		my $error_counter = 0;
		while ($error_counter <= MAX_ERROR) {

			my $filestat = stat($session_screens{$key}->{'giofile'}->get_path);

			#does the file exist?
			if ($session_screens{$key}->{'giofile'}->query_exists) {

				#maybe we need no update
				if ($filestat->mtime == $session_screens{$key}->{'mtime'}
					&& !$giofile)
				{
					print "Updating fileinfos REJECTED for key: $key (not modified)\n"
						if $sc->get_debug;
					return TRUE;
				}

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

				#FILEINFO
				#--------------------------------------
				$session_screens{$key}->{'mtime'} = $filestat->mtime;
				$session_screens{$key}->{'size'}  = $filestat->size;

				$session_screens{$key}->{'short'}    = $shf->utf8_decode(unescape_string($session_screens{$key}->{'giofile'}->get_basename));
				$session_screens{$key}->{'long'}     = $shf->utf8_decode(unescape_string($session_screens{$key}->{'giofile'}->get_path));
				$session_screens{$key}->{'folder'}   = $shf->utf8_decode(unescape_string($session_screens{$key}->{'giofile'}->get_parent->get_path));
				$session_screens{$key}->{'filetype'} = $session_screens{$key}->{'short'};
				$session_screens{$key}->{'filetype'} =~ s/.*\.//ig;

				#just the name
				$session_screens{$key}->{'name'} = $session_screens{$key}->{'short'};
				$session_screens{$key}->{'name'} =~ s/\.$session_screens{$key}->{'filetype'}//g;

				#mime type
				my ($mime_type) = Glib::Object::Introspection->invoke('Gio', undef, 'content_type_guess', $session_screens{$key}->{'giofile'}->get_path);
				$mime_type =~ s/image\/x\-apple\-ios\-png/image\/png/;    #FIXME
				$session_screens{$key}->{'mime_type'} = $mime_type;

				#TAB PREVIEW IMAGE
				#--------------------------------------
				#maybe we have a pixbuf already (e.g. after taking a screenshot)

				unless ($pixbuf) {
					unless ($no_image_load) {
						$pixbuf = $lp_ne->load($session_screens{$key}->{'long'}, undef, undef, undef, TRUE);

						unless ($pixbuf) {

							#increment error counter
							#and go to next try
							$error_counter++;
							sleep 1;

							#we need to reset the modification time
							#because the change would not be
							#recognized otherwise
							$session_screens{$key}->{'mtime'} = -1;
							next;
						}
					}
				}

				my $im_format = undef;
				my $im_width = undef;
				my $im_height = undef;

				if (defined $pixbuf) {
					#setting pixbuf
					$session_screens{$key}->{'image'}->set_pixbuf($pixbuf);

					$im_width = $pixbuf->get_width;
					$im_height = $pixbuf->get_height;

				} else {
					#If image pixbuf was not loaded, get image info without loading it into the memory
					($im_format, $im_width, $im_height) = Gtk3::Gdk::Pixbuf::get_file_info($session_screens{$key}->{'long'});

					unless ($im_format) {
						#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;
					}
				}

				#UPDATE INFOS
				#--------------------------------------

				#get dimensions - using the pixbuf
				$session_screens{$key}->{'width'}  = $im_width;
				$session_screens{$key}->{'height'} = $im_height;


				#generate thumbnail if file is not too large
				#set flag
				if (   $session_screens{$key}->{'width'} <= 10000
					&& $session_screens{$key}->{'height'} <= 10000)
				{
					$session_screens{$key}->{'no_thumbnail'} = FALSE;
				} else {
					$session_screens{$key}->{'no_thumbnail'} = TRUE;
				}

				#update is_unsaved flag
				if ($session_screens{$key}->{'folder'} eq $sdir->get_cache_dir) {
					$session_screens{$key}->{'is_unsaved'} = TRUE;
				} else {
					$session_screens{$key}->{'is_unsaved'} = FALSE;
				}

				#update tab label
				#and tooltip
				if (defined $session_screens{$key}->{'is_unsaved'}
					&& $session_screens{$key}->{'is_unsaved'})
				{
					$session_screens{$key}->{'hbox_tab_label'}->set_tooltip_text("*" . $session_screens{$key}->{'name'});
					$session_screens{$key}->{'tab_label'}->set_text("[" . $session_screens{$key}->{'tab_indx'} . "] - " . "*" . $session_screens{$key}->{'name'});
				} else {
					$session_screens{$key}->{'hbox_tab_label'}->set_tooltip_text($session_screens{$key}->{'long'});
					$session_screens{$key}->{'tab_label'}->set_text("[" . $session_screens{$key}->{'tab_indx'} . "] - " . $session_screens{$key}->{'short'});
				}

				#create tempfile
				#maybe we have to restore the file later
				my ($tmpfh, $tmpfilename) = tempfile(UNLINK => 1);

				#UNDO / REDO
				#--------------------------------------

				#blocked (e.g. renaming)
				if (defined $xdo && $xdo eq 'block') {

					unlink $tmpfilename;

					#clear (e.g. save_as)
				} elsif (defined $xdo && $xdo eq 'clear') {

					while (defined $session_screens{$key}->{'undo'}
						&& scalar @{$session_screens{$key}->{'undo'}} > 0)
					{
						unlink shift @{$session_screens{$key}->{'undo'}};
					}
					while (defined $session_screens{$key}->{'redo'}
						&& scalar @{$session_screens{$key}->{'redo'}} > 0)
					{
						unlink shift @{$session_screens{$key}->{'redo'}};
					}

					push @{$session_screens{$key}->{'undo'}}, $tmpfilename;
					cp($session_screens{$key}->{'long'}, $tmpfilename);

					#push to undo
				} else {

					#clear redo unless triggered from gui (undo/redo buttons)
					if (!defined $xdo) {
						while (defined $session_screens{$key}->{'redo'}
							&& scalar @{$session_screens{$key}->{'redo'}} > 0)
						{
							unlink shift @{$session_screens{$key}->{'redo'}};
						}
					}

					push @{$session_screens{$key}->{'undo'}}, $tmpfilename;
					cp($session_screens{$key}->{'long'}, $tmpfilename);

				}

				#thumbnail in tab
				my $thumb;
				unless ($session_screens{$key}->{'no_thumbnail'}) {

					#update tab icon
					$thumb = $lp_ne->load($shf->utf8_decode($session_screens{$key}->{'giofile'}->get_path), $shf->icon_size('small-toolbar'));
					$session_screens{$key}->{'tab_icon'}->set_from_pixbuf($thumb);
				}

				#UPDATE FIRST TAB - VIEW
				#--------------------------------------

				my $thumb_view = undef;
				unless ($session_screens{$key}->{'no_thumbnail'}) {
					my $max_size = 100;

					#update first page tab list view thumb icon
					if ($im_width <= $max_size && $im_height <= $max_size) {
						if (defined $pixbuf) {
							$thumb_view = $pixbuf;
						} else {
							#If the full image is smaller than max_size in all
							#the dimensions, no need to resize it.
							$thumb_view = $lp_ne->load($shf->utf8_decode($session_screens{$key}->{'giofile'}->get_path));
						}
					} else {
						$thumb_view = $lp_ne->load($shf->utf8_decode($session_screens{$key}->{'giofile'}->get_path), $max_size, $max_size);
					}

					#update dnd pixbuf
					$session_screens{$key}->{'image'}->drag_source_set_icon_pixbuf($thumb_view);
				} else {
					$thumb_view = Gtk3::Gdk::Pixbuf->new('rgb', TRUE, 8, 5, 5);
					$thumb_view->fill(0x00000000);
				}

				#create new iter if needed...
				unless (defined $session_screens{$key}->{'iter'}
					&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
				{
					$session_screens{$key}->{'iter'} = $session_start_screen{'first_page'}->{'model'}->append;
				}

				#...update it
				if (defined $session_screens{$key}->{'is_unsaved'}
					&& $session_screens{$key}->{'is_unsaved'})
				{
					$session_start_screen{'first_page'}->{'model'}->set($session_screens{$key}->{'iter'}, 0, $thumb_view, 1, "*" . $session_screens{$key}->{'name'}, 2, $key);
				} else {
					$session_start_screen{'first_page'}->{'model'}->set($session_screens{$key}->{'iter'}, 0, $thumb_view, 1, $session_screens{$key}->{'short'}, 2, $key);
				}

				#update first tab
				fct_update_info_and_tray();

				#update menu actions
				my $current_key = fct_get_current_file();
				if (defined $current_key && $current_key eq $key) {
					fct_update_actions(1, $key);
				}

				return TRUE;

				#file does not exist
			} else {

				#show dialog
				if ($ask_on_fs_delete_active->get_active) {

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

					#we only handle one case here:
					#file was deleted in filesystem and we got informed about that...
					my $response = $sd->dlg_question_message(
						$d->get("Try to resave the file?"),
						sprintf($d->get("Image %s was not found on disk"), "'" . $session_screens{$key}->{'long'} . "'"),
						'gtk-discard', 'gtk-save'
					);

					#handle different responses
					if ($response == 10 || $response == -1) {

						$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));    #delete tab
						fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session"))
							if defined($session_screens{$key}->{'long'});

						if (defined $session_screens{$key}->{'iter'}
							&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
						{
							$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
						}

						delete($session_screens{$key});

					} elsif ($response == 20) {

						#try to resave the file
						#(current version is always the last element in the array)
						my $current_version = pop @{$session_screens{$key}->{'undo'}};

						my $pixbuf = $lp_ne->load($current_version);

						#restoring the last version failed => delete the screenshot
						unless ($pixbuf) {

							$sd->dlg_error_message(
								sprintf($d->get("Error while saving the image %s."),           "'" . $session_screens{$key}->{'short'} . "'"),
								sprintf($d->get("There was an error saving the image to %s."), "'" . $session_screens{$key}->{'folder'} . "'"),
								undef, undef, undef, undef, undef, undef, $@
							);

							$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));    #delete tab
							fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session"))
								if defined($session_screens{$key}->{'long'});

							if (defined $session_screens{$key}->{'iter'}
								&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
							{
								$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
							}

							delete($session_screens{$key});

							fct_update_info_and_tray();
							return FALSE;

						}

						if ($sp->save_pixbuf_to_file($pixbuf, $session_screens{$key}->{'long'}, $session_screens{$key}->{'filetype'})) {

							fct_update_tab($key);

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

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

							fct_update_info_and_tray();
							return TRUE;

							#resave failed => delete the screenshot
						} else {

							$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));    #delete tab
							fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session"))
								if defined($session_screens{$key}->{'long'});

							if (defined $session_screens{$key}->{'iter'}
								&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
							{
								$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
							}

							delete($session_screens{$key});

						}
					}

					#no dialog
				} else {

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

					#try to resave the file
					#(current version is always the last element in the array)
					my $current_version = pop @{$session_screens{$key}->{'undo'}};

					my $pixbuf = $lp_ne->load($current_version);

					#restoring the last version failed => delete the screenshot
					unless ($pixbuf) {

						$sd->dlg_error_message(
							sprintf($d->get("Error while saving the image %s."),           "'" . $session_screens{$key}->{'short'} . "'"),
							sprintf($d->get("There was an error saving the image to %s."), "'" . $sdir->get_cache_dir . "'"),
							undef, undef, undef, undef, undef, undef, $@
						);

						$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));    #delete tab
						fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session"))
							if defined($session_screens{$key}->{'long'});

						if (defined $session_screens{$key}->{'iter'}
							&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
						{
							$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
						}

						delete($session_screens{$key});

						fct_update_info_and_tray();
						return FALSE;

					}

					#prepare new filename
					my ($short, $folder, $ext) = fileparse($session_screens{$key}->{'long'}, qr/\.[^.]*/);
					my $new_giofile  = fct_get_next_filename($short, $sdir->get_cache_dir, $ext);
					my $new_filename = $shf->utf8_decode(unescape_string($new_giofile->get_path));

					if ($sp->save_pixbuf_to_file($pixbuf, $new_filename, $session_screens{$key}->{'filetype'})) {

						if (fct_update_tab($key, undef, Glib::IO::File::new_for_path($new_filename), FALSE, 'clear')) {

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

						fct_show_status_message(1, sprintf($d->get("Image %s was deleted from filesystem"), $new_filename));

						fct_update_info_and_tray();
						return TRUE;

						#resave failed => delete the screenshot
					} else {

						$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));    #delete tab
						fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session"))
							if defined($session_screens{$key}->{'long'});

						if (defined $session_screens{$key}->{'iter'}
							&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
						{
							$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
						}

						delete($session_screens{$key});

					}

				}

				fct_update_info_and_tray();
				return FALSE;

			}    #end if exists

		}    #end while($error_counter <= MAX_ERROR){

		#could not load the file => show an error message
		my $response = $sd->dlg_error_message(
			sprintf($d->get("Error while opening image %s."), "'" . $session_screens{$key}->{'long'} . "'"),
			$d->get("There was an error opening the image."),
			undef, undef, undef, undef, undef, undef, $@
		);

		$notebook->remove_page($notebook->page_num($session_screens{$key}->{'tab_child'}));    #delete tab
		fct_show_status_message(1, $session_screens{$key}->{'long'} . " " . $d->get("removed from session"))
			if defined($session_screens{$key}->{'long'});

		if (defined $session_screens{$key}->{'iter'}
			&& $session_start_screen{'first_page'}->{'model'}->iter_is_valid($session_screens{$key}->{'iter'}))
		{
			$session_start_screen{'first_page'}->{'model'}->remove($session_screens{$key}->{'iter'});
		}

		delete($session_screens{$key});

		fct_update_info_and_tray();
		return FALSE;

	}

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

	sub fct_imagemagick_perform {
		my ($function, $file, $data) = @_;

		my $pixbuf = undef;
		my $result = undef;
		$file = $shf->switch_home_in_file($file);

		if ($function eq "reduce_colors") {
			$result = `convert '$file' -colors $data '$file'`;
			$pixbuf = $lp->load($file);
		}

		return $pixbuf;
	}

	sub fct_check_installed_programs {

		#update list of available programs in settings dialog as well
		if ($progname) {

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

			#get last prog
			my $progname_value;
			if (defined $progname_iter) {
				$progname_value = $model->get_value($progname_iter, 1);
			}

			#rebuild model with new hash of installed programs...
			$model = fct_get_program_model();
			$progname->set_model($model);

			#...and try to set last	value
			if ($progname_value) {
				$model->foreach(\&fct_iter_programs, $progname_value);
			} else {
				$progname->set_active(0);
			}

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

		return TRUE;
	}

	sub fct_parse_filename_wildcards {
		my ($filename_value, $screenshooter, $screenshot) = @_;

		my $screenshot_name = $filename_value;

		print "Parsing wildcards for $screenshot_name\n"
			if $sc->get_debug;

		#parse width and height
		my $swidth  = $screenshot->get_width;
		my $sheight = $screenshot->get_height;

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

		print "Parsed \$width and \$height: $screenshot_name\n"
			if $sc->get_debug;

		#parse profile name
		my $current_pname = $combobox_settings_profiles->get_active_text;
		$screenshot_name =~ s/\$profile/$current_pname/g;

		print "Parsed \$profile: $screenshot_name\n"
			if $sc->get_debug;

		#set name
		#e.g. window or workspace name
		if (my $action_name = $screenshooter->get_action_name) {
			utf8::decode $action_name;
			$action_name     =~ s/(\/|\#|\>|\<|\%|\*)/-/g;
			$screenshot_name =~ s/\$name/$action_name/g;

			#no blanks (special wildcard)
			$action_name     =~ s/\ //g;
			$screenshot_name =~ s/\$nb_name/$action_name/g;
		} else {
			$screenshot_name =~ s/(\$name|\$nb_name)/unknown/g;
		}

		print "Parsed \$name: $screenshot_name\n"
			if $sc->get_debug;

		return $screenshot_name;
	}


	sub fct_get_next_filename {
		my ($filename_value, $folder, $filetype_value) = @_;

		#remove possible dots
		$filetype_value =~ s/\.//;

		$filename_value =~ s/\\//g;

		#random number - should be earlier than %N reading, as $R is actually a part of date
		if ($filename_value =~ /\$R{1,}/) {

			#how many Rs are used? (important for formatting)
			my $pos_proc  = index($filename_value, "\$R", 0);
			my $r_counter = 0;
			my $last_pos  = $pos_proc;
			$pos_proc++;

			while ($pos_proc <= length($filename_value)) {
				$last_pos = index($filename_value, "R", $pos_proc);
				if ($last_pos != -1 && ($last_pos - $pos_proc <= 1)) {
					$r_counter++;
					$pos_proc++;
				} else {
					last;
				}
			}

			#prepare filename
			print "---$r_counter Rs used in wild-card\n" if $sc->get_debug;
			my $marks = "";
			my $i     = 0;

			# Md5 will contain a salt (shutter) and a seconds since 1970
			my $md5_data = "shutter" . time;
			my $md5_hash = md5_hex($md5_data);

			# TODO: set random offset? I guess, current implementation is sufficient
			$marks = substr($md5_hash, 0, $r_counter);

			#switch $Rs to a part of the hash
			$filename_value =~ s/\$R{1,}/$marks/g;
		}

		#auto increment  (%NNN is the pattern for the increment placeholder)
		if ($filename_value =~ /\%(N{1,})/) {
			#how many Ns are used? (important for formatting)
			my $n_counter = length($1);

			#prepare filename
			print "$n_counter Ns used in wild-card\n" if $sc->get_debug;

			my $filename_template = quotemeta $filename_value;

			#replace %NNN by a \d+ regex to search for digits
			#also take into account conflicted filenames Ex.: "_014(002)"
			$filename_template =~ s/\\\%N+/(\\d+)(?:\\(\\d+\\))?/g;
			#store regex to string
			my $search_pattern = qr/$filename_template\.$filetype_value/;

			print "Searching for files with pattern: $search_pattern\n"
				if $sc->get_debug;

			#get_all files from directory
			#we handle the listing with GnomeVFS to read remote dirs as well
			my $dir        = Glib::IO::File::new_for_path($folder);
			my $next_count = 0;
			eval {
				my $enumerator = $dir->enumerate_children('standard::*', []);
				while (my $fileinfo = $enumerator->next_file) {
					my $fname = $shf->utf8_decode($fileinfo->get_name);

					#not a regular file? -> skip
					next unless $fileinfo->get_file_type eq 'regular';

					#does the current file match the pattern?
					# print "Comparing $fname\n" if $sc->get_debug;
					if ($fname =~ $search_pattern) {
						my $curr_value = $1;
						if ($curr_value && $curr_value > $next_count) {
							$next_count = $curr_value;
							print "$next_count is currently greatest value...\n"
								if $sc->get_debug;
						}
					}
				}
				$enumerator->close;
			};
			if ($@) {
				my $response = $sd->dlg_error_message(
					sprintf($d->get("Error while opening directory %s."), "'" . $folder . "'"),
					$d->get("There was an error determining the filename."),
					undef, undef, undef, undef, undef, undef, $@
				);
				return FALSE;
			}

			$next_count = 0 unless $next_count =~ /^(\d+\.?\d*|\.\d+)$/;

			$next_count = sprintf("%0" . $n_counter . "d", $next_count + 1);

			#switch placeholder to $next_count
			$filename_value =~ s/\%N+/$next_count/g;

		}

		#create new uri
		my $new_giofile = Glib::IO::File::new_for_path("$folder/$filename_value.$filetype_value");
		if ($new_giofile->query_exists) {
			my $count             = 1;
			my $existing_filename = $filename_value;
			while ($new_giofile->query_exists) {
				$filename_value = $existing_filename . "(" . sprintf("%03d", $count++) . ")";
				$new_giofile    = Glib::IO::File::new_for_path($folder);
				$new_giofile    = $new_giofile->append_string("$filename_value.$filetype_value");
				print "Checking new uri: " . $new_giofile->to_string . "\n"
					if $sc->get_debug;
			}
		}

		return $new_giofile;
	}

	sub fct_check_installed_plugins {

		my $plugin_dialog = Gtk3::MessageDialog->new($window, [qw/modal destroy-with-parent/], 'info', 'close', $d->get("Updating plugin information"));
		$plugin_dialog->{destroyed} = FALSE;

		$plugin_dialog->set_title("Shutter");

		$plugin_dialog->set('secondary-text' => $d->get("Please wait while Shutter updates the plugin information") . ".");

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

		$plugin_dialog->set_resizable(TRUE);

		my $plugin_progress = Gtk3::ProgressBar->new;
		$plugin_progress->set_no_show_all(TRUE);
		$plugin_progress->set_ellipsize('middle');
		$plugin_progress->set_orientation('horizontal');
		$plugin_progress->set_fraction(0);

		$plugin_dialog->get_child->add($plugin_progress);
		my $current_plugin = Gtk3::Label->new("");
		$current_plugin->set_line_wrap(TRUE);
		$plugin_dialog->get_child->add($current_plugin);

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

		#fallback icon
		# maybe the plugin
		# does not provide a custom icon
		my $fb_pixbuf_path = "$shutter_root/share/shutter/resources/icons/executable.svg";
		my $fb_pixbuf      = $lp->load($fb_pixbuf_path, $shf->icon_size('menu'));

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

					#parse filename
					my ($name, $folder, $type) = fileparse($dir_name, qr/\.[^.]*/);

					#file exists
					if ($shf->file_exists("$dir_name/$name")) {

						#file is executable
						if ($shf->file_executable("$dir_name/$name")) {

							#new plugin information?
							unless ($plugins{$pkey}->{'binary'}
								&& $plugins{$pkey}->{'name'}
								&& $plugins{$pkey}->{'category'}
								&& $plugins{$pkey}->{'tooltip'}
								&& $plugins{$pkey}->{'lang'})
							{

								#show dialog and progress bar
								if (   !$plugin_dialog->get_window
									&& !$plugin_dialog->{destroyed})
								{
									$plugin_progress->show;
									$plugin_dialog->show_all;
								}

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

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

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

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

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

								#language (shell, perl etc.)
								#=> directory name
								my $folder_name = dirname($dir_name);
								$folder_name =~ /.*\/(.*)/;
								$plugins{$pkey}->{'lang'} = $1;

								#refresh the progressbar
								$plugin_progress->pulse;
								$current_plugin->set_text($plugins{$pkey}->{'binary'});

								#refresh gui
								fct_update_gui();

							}

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

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

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

							if ($shf->file_exists($plugins{$pkey}->{'pixbuf'})) {
								$plugins{$pkey}->{'pixbuf_object'} = $lp->load($plugins{$pkey}->{'pixbuf'}, $shf->icon_size('menu'));
							} else {
								$plugins{$pkey}->{'pixbuf'}        = $fb_pixbuf_path;
								$plugins{$pkey}->{'pixbuf_object'} = $fb_pixbuf;
							}
							if ($sc->get_debug) {
								print "$plugins{$pkey}->{'name'} - $plugins{$pkey}->{'binary'}\n";
							}

						} else {
							my $changed = chmod(0755, "$dir_name/$name");
							unless ($changed) {
								print "\nERROR: plugin exists but is not executable - $dir_name/$name\n";
								delete $plugins{$pkey};
							}
						}    #endif plugin is executable

					} else {
						delete $plugins{$pkey};
					}    #endif plugin exists

				}
			}
		}

		#destroys the plugin dialog
		$plugin_dialog->response('ok');

		return TRUE;
	}

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

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

		return $plugin_info;
	}

	sub fct_check_installed_upload_plugins {

		my $upload_plugin_dialog = Gtk3::MessageDialog->new($window, [qw/modal destroy-with-parent/], 'info', 'close', $d->get("Updating upload plugin information"));
		$upload_plugin_dialog->{destroyed} = FALSE;

		$upload_plugin_dialog->set_title("Shutter");

		$upload_plugin_dialog->set('secondary-text' => $d->get("Please wait while Shutter updates the upload plugin information") . ".");

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

		$upload_plugin_dialog->set_resizable(TRUE);

		my $upload_plugin_progress = Gtk3::ProgressBar->new;
		$upload_plugin_progress->set_no_show_all(TRUE);
		$upload_plugin_progress->set_ellipsize('middle');
		$upload_plugin_progress->set_orientation('horizontal');
		$upload_plugin_progress->set_fraction(0);

		$upload_plugin_dialog->get_child->add($upload_plugin_progress);
		my $current_plugin = Gtk3::Label->new("");
		$current_plugin->set_line_wrap(TRUE);
		$upload_plugin_dialog->get_child->add($current_plugin);

		#plugins in user-home not supported yet FIXME
		my @upload_plugin_paths = ("$shutter_root/share/shutter/resources/system/upload_plugins/upload/*");

		foreach my $upload_plugin_path (@upload_plugin_paths) {
			my @upload_plugins = bsd_glob($upload_plugin_path);
			foreach my $ukey (@upload_plugins) {

				#Checking if file exists
				if ($shf->file_exists("$ukey")) {

					#file is executable
					if ($shf->file_executable("$ukey")) {

						#parse filename
						my ($name, $folder, $type) = fileparse($ukey, qr/\.[^.]*/);

						#~ print $name, $folder, $type, "\n";

						if (   !exists $accounts{$name}
							|| !exists $accounts{$name}->{module}
							|| $accounts{$name}->{supports_anonymous_upload} ne fct_upload_plugin_get_info($ukey, 'supports_anonymous_upload')
							|| $accounts{$name}->{supports_authorized_upload} ne fct_upload_plugin_get_info($ukey, 'supports_authorized_upload')
							|| $accounts{$name}->{supports_oauth_upload} ne fct_upload_plugin_get_info($ukey, 'supports_oauth_upload'))
						{

							#show dialog and progress bar
							if (   !$upload_plugin_dialog->get_window
								&& !$upload_plugin_dialog->{destroyed})
							{
								$upload_plugin_progress->show;
								$upload_plugin_dialog->show_all;
							}

							print "\nINFO: new upload-plugin information detected - $folder$name\n";

							if (fct_upload_plugin_get_info($ukey, 'module')) {

								# Path
								$accounts{$name}->{path} = $ukey;

								# Module Name
								$accounts{$name}->{module} = fct_upload_plugin_get_info($ukey, 'module');

								# URL
								$accounts{$name}->{host} = fct_upload_plugin_get_info($ukey, 'url');

								# Folder
								$accounts{$name}->{folder} = $folder;

								# Description
								$accounts{$name}->{description} = fct_plugin_get_info($ukey, 'description');

								# Username
								$accounts{$name}->{username} = ""
									unless defined $accounts{$name}->{username};

								# Password
								$accounts{$name}->{password} = ""
									unless defined $accounts{$name}->{password};

								# Register Color
								$accounts{$name}->{register_color} = "blue";

								# Register Text
								$accounts{$name}->{register_text} = fct_upload_plugin_get_info($ukey, 'registration');

								# Upload Features
								$accounts{$name}->{supports_anonymous_upload}  = fct_upload_plugin_get_info($ukey, 'supports_anonymous_upload');
								$accounts{$name}->{supports_authorized_upload} = fct_upload_plugin_get_info($ukey, 'supports_authorized_upload');
								$accounts{$name}->{supports_oauth_upload}      = fct_upload_plugin_get_info($ukey, 'supports_oauth_upload');

								#refresh the progressbar
								$upload_plugin_progress->pulse;
								$current_plugin->set_text($accounts{$name}->{path});

							} else {
								print "\nERROR: upload-plugin exists but does not work properly - $folder$name\n";
								delete $accounts{$name};
							}

							#refresh gui
							fct_update_gui();

						}

					} else {
						my $changed = chmod(0755, "$ukey");
						unless ($changed) {

							#parse filename
							my ($name, $folder, $type) = fileparse($ukey, qr/\.[^.]*/);
							print "\nERROR: upload-plugin exists but is not executable - $ukey\n";
							delete $accounts{$name};
						}    #endif plugin is executable
					}
				}
			}

		}

		#destroys the upload_plugin dialog
		$upload_plugin_dialog->response('ok');

		return TRUE;
	}

	sub fct_upload_plugin_get_info {
		my ($upload_plugin, $info) = @_;

		my $upload_plugin_info = `$upload_plugin $info`;
		utf8::decode $upload_plugin_info;

		return $upload_plugin_info;
	}

	sub fct_iter_programs {
		my ($model, $path, $iter, $search_for) = @_;
		my $progname_value = $model->get_value($iter, 1);
		return FALSE if $search_for ne $progname_value;
		$progname->set_active_iter($iter);
		return TRUE;
	}

	sub fct_ret_workspace_menu {
		my $init = shift;

		my $menu_wrksp = Gtk3::Menu->new;

		my $wnck_screen = Wnck::Screen::get_default();
		unless ($wnck_screen) {
			$current_monitor_active = Gtk3::CheckMenuItem->new_with_label($d->get("Limit to current monitor"));
			return $menu_wrksp;
		}
		$wnck_screen->force_update();

		#we determine the wm name but on older
		#version of libwnck (or the bindings)
		#the needed method is not available
		#in this case we use gdk to do it
		#
		#this leads to a known problem when switching
		#the wm => wm_name will still remain the old one
		#but it doesn't work on gtk3
		my $wm_name;
		if ($wnck_screen->can('get_window_manager_name')) {
			$wm_name = $wnck_screen->get_window_manager_name;
		}

		my $active_workspace = $wnck_screen->get_active_workspace;

		#we need to handle different window managers here because there are some different models related
		#to workspaces and viewports
		#	compiz uses "multiple workspaces" - "multiple viewports" model for example
		#	default gnome wm metacity simply uses multiple workspaces
		#we will try to handle them by name
		my @workspaces = ();
		for (my $wcount = 0 ; $wcount < $wnck_screen->get_workspace_count ; $wcount++) {
			push(@workspaces, $wnck_screen->get_workspace($wcount));
		}

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

			#compiz
			print "Current window manager: ", $wm_name, "\n" if $sc->get_debug;
			if ($wm_name =~ /compiz/i) {

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

				my $n_viewports_column = int($space->get_width / $wnck_screen->get_width);
				my $n_viewports_rows   = int($space->get_height / $wnck_screen->get_height);

				#rows
				for (my $j = 0 ; $j < $n_viewports_rows ; $j++) {

					#columns
					for (my $i = 0 ; $i < $n_viewports_column ; $i++) {
						my @vp      = ($i * $wnck_screen->get_width, $j * $wnck_screen->get_height);
						my $vp_name = "$wm_name x: $i y: $j";

						print "shutter_wrksp_direct_compiz" . $vp[0] . "x" . $vp[1] . "\n"
							if $sc->get_debug;

						my $vp_item = Gtk3::MenuItem->new_with_label(ucfirst $vp_name);
						$vp_item->signal_connect(
							'activate' => \&evt_take_screenshot,
							"shutter_wrksp_direct_compiz" . $vp[0] . "x" . $vp[1]);
						$menu_wrksp->append($vp_item);

						#do not offer current viewport
						if ($vp[0] == $vpx && $vp[1] == $vpy) {
							$vp_item->set_sensitive(FALSE);
						}
					}    #columns
				}    #rows

				#all other wm manager like metacity etc.
				#we could add more of them here if needed
			} else {

				my $wrkspace_item = Gtk3::MenuItem->new_with_label($space->get_name);
				$wrkspace_item->signal_connect(
					'activate' => \&evt_take_screenshot,
					"shutter_wrksp_direct" . $space->get_number
				);
				$menu_wrksp->append($wrkspace_item);

				if (   $active_workspace
					&& $active_workspace->get_number == $space->get_number)
				{
					$wrkspace_item->set_sensitive(FALSE);
				}

			}
		}

		#entry for capturing all workspaces
		$menu_wrksp->append(Gtk3::SeparatorMenuItem->new);

		my $allwspaces_item = Gtk3::MenuItem->new_with_label($d->get("Capture All Workspaces"));
		$allwspaces_item->signal_connect(
			'activate' => \&evt_take_screenshot,
			"shutter_wrksp_direct" . 'all'
		);
		$menu_wrksp->append($allwspaces_item);

		#monitor flag
		my $n_mons = Gtk3::Gdk::Screen::get_default->get_n_monitors;

		#use only current monitor
		$menu_wrksp->append(Gtk3::SeparatorMenuItem->new);
		if ($init) {
			$current_monitor_active = Gtk3::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);
		}

		$current_monitor_active->set_tooltip_text(
			sprintf(
				$d->nget(
					"This option is only useful when you are running a multi-monitor system (%d monitor detected).\nEnable it to capture only the current monitor.",
					"This option is only useful when you are running a multi-monitor system (%d monitors detected).\nEnable it to capture only the current monitor.",
					$n_mons
				),
				$n_mons
			));
		if ($n_mons > 1) {
			$current_monitor_active->set_sensitive(TRUE);
		} else {
			$current_monitor_active->set_active(FALSE);
			$current_monitor_active->set_sensitive(FALSE);
		}

		$menu_wrksp->show_all();
		return $menu_wrksp;
	}

	sub fct_ret_window_menu {

		my $menu_windows = Gtk3::Menu->new;
		return $menu_windows unless $wnck_screen;

		my $active_workspace = $wnck_screen->get_active_workspace;
		my $icontheme        = $sc->get_theme;

		#add item for active window
		my $active_window_item_image;
		if ($icontheme->has_icon('preferences-system-windows')) {
			$active_window_item_image = Gtk3::Image->new_from_icon_name('preferences-system-windows', 'menu');
		} else {
			$active_window_item_image = Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/sel_window_active.svg", $shf->icon_size('menu')));
		}

		my $active_window_item = Gtk3::ImageMenuItem->new_with_label($d->get("Active Window"));
		$active_window_item->set_image($active_window_item_image);
		$active_window_item->set('always_show_image' => TRUE);

		$active_window_item->set_tooltip_text($d->get("Capture the last active window"));

		$active_window_item->signal_connect(
			'activate' => \&evt_take_screenshot,
			'awindow'
		);

		$menu_windows->append($active_window_item);
		$menu_windows->append(Gtk3::SeparatorMenuItem->new);

		#add all windows to menu to capture it directly
		foreach my $win (@{$wnck_screen->get_windows_stacked}) {
			if ($active_workspace && $win->is_on_workspace($active_workspace)) {
				my $win_name = $win->get_name;
				Encode::_utf8_on($win_name);
				my $window_item = Gtk3::ImageMenuItem->new_with_label($win_name);
				foreach my $child ($window_item->get_children) {
					if ($child =~ /Gtk3::AccelLabel/) {
						$child->set_width_chars(50);
						$child->set_ellipsize('middle');
						last;
					}
				}
				$window_item->set_image(Gtk3::Image->new_from_pixbuf($win->get_mini_icon));
				$window_item->set('always_show_image' => TRUE);
				$window_item->signal_connect(
					'activate' => \&evt_take_screenshot,
					"shutter_window_direct" . $win->get_xid
				);
				$menu_windows->append($window_item);
			}
		}

		$menu_windows->show_all;
		return $menu_windows;
	}

	sub fct_ret_tray_menu {

		my $traytheme = $sc->get_theme;

		my $menu_tray = Gtk3::Menu->new();

		#selection
		my $menuitem_select = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('_Selection'));
		$menuitem_select->set_sensitive($wnck_screen);
		eval {
			my $ccursor_pb = Gtk3::Gdk::Cursor::new('left_ptr')->get_image->scale_simple($shf->icon_size('menu'), 'bilinear');
			$menuitem_select->set_image(Gtk3::Image->new_from_pixbuf($ccursor_pb));
		};
		if ($@) {
			if ($traytheme->has_icon('applications-accessories')) {
				$menuitem_select->set_image(Gtk3::Image->new_from_icon_name('applications-accessories', 'menu'));
			} else {
				$menuitem_select->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/selection.svg", $shf->icon_size('menu'))));
			}
		}
		$menuitem_select->signal_connect(
			activate => \&evt_take_screenshot,
			'tray_select'
		);

		#full screen
		my $menuitem_full = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('_Desktop'));
		$menuitem_full->set_sensitive($wnck_screen);
		if ($traytheme->has_icon('user-desktop')) {
			$menuitem_full->set_image(Gtk3::Image->new_from_icon_name('user-desktop', 'menu'));
		} elsif ($traytheme->has_icon('desktop')) {
			$menuitem_full->set_image(Gtk3::Image->new_from_icon_name('desktop', 'menu'));
		} else {
			$menuitem_full->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/desktop.svg", $shf->icon_size('menu'))));
		}
		$menuitem_full->signal_connect(
			activate => \&evt_take_screenshot,
			'tray_full'
		);

		#~ #awindow
		#~ my $menuitem_awindow = Gtk3::ImageMenuItem->new_with_mnemonic( $d->get('_Active Window') );
		#~ if($traytheme->has_icon('preferences-system-windows')){
		#~ $menuitem_awindow->set_image( Gtk3::Image->new_from_icon_name( 'preferences-system-windows', 'menu' ) );
		#~ }else{
		#~ $menuitem_awindow->set_image(
		#~ Gtk3::Image->new_from_pixbuf(
		#~ $lp->load( "$shutter_root/share/shutter/resources/icons/sel_window_active.svg", $shf->icon_size('menu') )
		#~ )
		#~ );
		#~ }
		#~ $menuitem_awindow->signal_connect(
		#~ activate => \&evt_take_screenshot,
		#~ 'tray_awindow'
		#~ );

		#window
		my $menuitem_window = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('Window _under Cursor'));
		$menuitem_window->set_sensitive($wnck_screen);
		if ($traytheme->has_icon('preferences-system-windows')) {
			$menuitem_window->set_image(Gtk3::Image->new_from_icon_name('preferences-system-windows', 'menu'));
		} else {
			$menuitem_window->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/sel_window.svg", $shf->icon_size('menu'))));
		}
		$menuitem_window->signal_connect(
			activate => \&evt_take_screenshot,
			'tray_window'
		);

		#window list
		my $menuitem_window_list = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('Select W_indow'));
		$menuitem_window_list->set_sensitive($wnck_screen);
		if ($traytheme->has_icon('preferences-system-windows')) {
			$menuitem_window_list->set_image(Gtk3::Image->new_from_icon_name('preferences-system-windows', 'menu'));
		} else {
			$menuitem_window_list->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/sel_window.svg", $shf->icon_size('menu'))));
		}
		$menuitem_window_list->set_name('windowlist');
		$menuitem_window_list->set_submenu(fct_ret_window_menu());

		#section
		# No sections for now: https://github.com/shutter-project/shutter/issues/25
		#my $menuitem_window_sect = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('Se_ction'));
		#if ($traytheme->has_icon('gdm-xnest')) {
		#	$menuitem_window_sect->set_image(Gtk3::Image->new_from_icon_name('gdm-xnest', 'menu'));
		#} else {
		#	$menuitem_window_sect->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/sel_window_section.svg", $shf->icon_size('menu'))));
		#}
		#$menuitem_window_sect->signal_connect(
		#	activate => \&evt_take_screenshot,
		#	'tray_section'
		#);

		#menu
		my $menuitem_window_menu = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('_Menu'));
		$menuitem_window_menu->set_sensitive($wnck_screen);
		if ($traytheme->has_icon('alacarte')) {
			$menuitem_window_menu->set_image(Gtk3::Image->new_from_icon_name('alacarte', 'menu'));
		} else {
			$menuitem_window_menu->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/sel_window_menu.svg", $shf->icon_size('menu'))));
		}
		$menuitem_window_menu->signal_connect(
			activate => \&evt_take_screenshot,
			'tray_menu'
		);

		#tooltip
		my $menuitem_window_tooltip = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('_Tooltip'));
		$menuitem_window_tooltip->set_sensitive($wnck_screen);
		if ($traytheme->has_icon('help-faq')) {
			$menuitem_window_tooltip->set_image(Gtk3::Image->new_from_icon_name('help-faq', 'menu'));
		} else {
			$menuitem_window_tooltip->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/sel_window_tooltip.svg", $shf->icon_size('menu'))));
		}
		$menuitem_window_tooltip->signal_connect(
			activate => \&evt_take_screenshot,
			'tray_tooltip'
		);

		#web
		my $menuitem_web = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('_Web'));
		$menuitem_web->set_sensitive($gnome_web_photo);
		if ($traytheme->has_icon('web-browser')) {
			$menuitem_web->set_image(Gtk3::Image->new_from_icon_name('web-browser', 'menu'));
		} else {
			$menuitem_web->set_image(Gtk3::Image->new_from_pixbuf($lp->load("$shutter_root/share/shutter/resources/icons/web_image.svg", $shf->icon_size('menu'))));
		}
		$menuitem_web->signal_connect(
			activate => \&evt_take_screenshot,
			'tray_web'
		);

		#show main window
		my $menuitem_show_window = Gtk3::MenuItem->new_with_mnemonic($d->get('S_how main window'));
		$menuitem_show_window->signal_connect('activate', sub { $is_hidden = TRUE; fct_control_main_window('show'); });
		$menuitem_show_window->set_name('show_window');
		$menuitem_show_window->set_sensitive(TRUE);

		#redo last screenshot
		my $menuitem_redoshot = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('_Redo last screenshot'));
		$menuitem_redoshot->set_image(Gtk3::Image->new_from_stock('gtk-refresh', 'menu'));
		$menuitem_redoshot->signal_connect('activate', \&evt_take_screenshot, 'redoshot');
		$menuitem_redoshot->set_name('redoshot');
		$menuitem_redoshot->set_sensitive(FALSE);

		#preferences
		my $menuitem_settings = Gtk3::ImageMenuItem->new_from_stock('gtk-preferences');
		$menuitem_settings->signal_connect("activate", \&evt_show_settings);

		#quick profile selector
		my $menuitem_quicks = Gtk3::MenuItem->new_with_mnemonic($d->get('_Quick profile select'));

		#set name to identify the item later - we use this in really rare cases
		$menuitem_quicks->set_name('quicks');
		$menuitem_quicks->set_sensitive(FALSE);

		#info
		my $menuitem_info = Gtk3::ImageMenuItem->new_from_stock('gtk-about');
		$menuitem_info->signal_connect("activate", \&evt_about);

		#quit
		my $menuitem_quit = Gtk3::ImageMenuItem->new_from_stock('gtk-quit');
		$menuitem_quit->signal_connect("activate", \&evt_delete_window, 'quit');

		$menu_tray->append($menuitem_show_window);
		$menu_tray->append(Gtk3::SeparatorMenuItem->new);
		$menu_tray->append($menuitem_redoshot);
		$menu_tray->append(Gtk3::SeparatorMenuItem->new);
		$menu_tray->append($menuitem_select);

		#~ $menu_tray->append( Gtk3::SeparatorMenuItem->new );
		$menu_tray->append($menuitem_full);

		#~ $menu_tray->append( Gtk3::SeparatorMenuItem->new );
		#~ $menu_tray->append($menuitem_awindow);
		$menu_tray->append($menuitem_window);
		$menu_tray->append($menuitem_window_list);
		# No sections for now: https://github.com/shutter-project/shutter/issues/25
		#$menu_tray->append($menuitem_window_sect);
		$menu_tray->append($menuitem_window_menu);
		$menu_tray->append($menuitem_window_tooltip);

		#~ $menu_tray->append( Gtk3::SeparatorMenuItem->new );
		$menu_tray->append($menuitem_web);
		$menu_tray->append(Gtk3::SeparatorMenuItem->new);
		$menu_tray->append($menuitem_settings);
		$menu_tray->append($menuitem_quicks);
		$menu_tray->append(Gtk3::SeparatorMenuItem->new);
		$menu_tray->append($menuitem_info);
		$menu_tray->append($menuitem_quit);
		$menu_tray->show_all;

		return $menu_tray;
	}

	sub fct_ret_program_menu {
		my $menu_programs = shift;

		$menu_programs = Gtk3::Menu->new unless defined $menu_programs;
		foreach my $child ($menu_programs->get_children) {
			$child->destroy;
		}

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

		#FIXME - different mime types
		#have different apps registered
		#we should restrict the offeres apps
		#by comparing the selected
		#
		#currently we just take the last selected file into account
		#
		#search selected files for mime...
		unless ($key) {
			$session_start_screen{'first_page'}->{'view'}->selected_foreach(
				sub {
					my ($view, $path) = @_;
					my $iter = $session_start_screen{'first_page'}->{'model'}->get_iter($path);
					if (defined $iter) {
						$key = $session_start_screen{'first_page'}->{'model'}->get_value($iter, 2);
					}
				});
		}

		#still no key? => leave sub
		unless ($key) {
			$sm->{_menuitem_reopen}->set_sensitive(FALSE);
			$sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
			return $menu_programs;
		}

		#no valid hash entry?
		unless (exists $session_screens{$key}->{'mime_type'}) {
			$sm->{_menuitem_reopen}->set_sensitive(FALSE);
			$sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
			return $menu_programs;
		}

		#get applications
		my $mime_type = $session_screens{$key}->{'mime_type'};

		# apps is a list of GAppInfo
		# https://developer.gnome.org/gio/stable/GAppInfo.html
		my $apps = Glib::IO::AppInfo::get_recommended_for_type($mime_type);

		#no apps determined!
		unless (scalar @$apps) {
			$sm->{_menuitem_reopen}->set_sensitive(FALSE);
			$sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
			return $menu_programs;
		}

		#create menu items
		foreach my $app (@$apps) {

			#ignore Shutter's desktop entry
			next if $app->get_display_name =~ /shutter/i;

			# $app->{'name'} = $shf->utf8_decode( $app->{'name'} );

			#FIXME
			#we simply cut the kde* / kde4* substring here
			#is it possible to get the wrong app if there
			#is the kde3 and the kde4 version of an app installed?
			#
			#I think so ;-)
			# $app->{'id'} =~ s/^(kde4|kde)-//g;

			my $program_item = Gtk3::ImageMenuItem->new_with_label($app->get_display_name);
			$program_item->set('always_show_image' => TRUE);
			$menu_programs->append($program_item);

			my $icon = $app->get_icon;
			if ($icon && $program_item) {
				my $icon_pixbuf = undef;
				my ($iw, $ih) = $shf->icon_size('menu');
				eval {
					my $icon_info = $sc->get_theme->choose_icon($icon->get_names, $ih, []);
					$icon_pixbuf = $icon_info->load_icon if $icon_info;
				};
				if ($@) {
					print "\nWARNING: Could not load icon for ", $app->get_display_name, ": $@\n";
					$icon_pixbuf = undef;
				}
				if ($icon_pixbuf) {
					$program_item->set_image(Gtk3::Image->new_from_pixbuf($icon_pixbuf));
				}
			}

			#connect to signal
			if ($program_item) {
				$program_item->signal_connect(
					'activate' => sub {
						fct_open_with_program($app, $app->get_display_name);
					});
			}
		}

		#menu does not contain any item
		unless ($menu_programs->get_children) {
			$sm->{_menuitem_reopen}->set_sensitive(FALSE);
			$sm->{_menuitem_large_reopen}->set_sensitive(FALSE);
		}

		$menu_programs->show_all;
		return $menu_programs;
	}

	sub fct_ret_web_menu {

		my $menu_web = Gtk3::Menu->new;

		my $timeout0 = Gtk3::RadioMenuItem->new(undef, $d->get("Wait indefinitely"));
		my $timeout1 = Gtk3::RadioMenuItem->new($timeout0, sprintf($d->nget("Wait max %d second", "Wait max %d seconds", 10), 10));
		my $timeout2 = Gtk3::RadioMenuItem->new($timeout0, sprintf($d->nget("Wait max %d second", "Wait max %d seconds", 10), 30));
		my $timeout3 = Gtk3::RadioMenuItem->new($timeout0, sprintf($d->nget("Wait max %d minute", "Wait max %d minutes", 1), 1));
		my $timeout4 = Gtk3::RadioMenuItem->new($timeout0, sprintf($d->nget("Wait max %d minute", "Wait max %d minutes", 2), 2));

		$timeout0->set_name("timeout0");
		$timeout1->set_name("timeout10");
		$timeout2->set_name("timeout30");
		$timeout3->set_name("timeout60");
		$timeout4->set_name("timeout120");

		$timeout0->set_tooltip_text($d->get("Shutter will wait indefinitely for the screenshot to capture"));
		$timeout1->set_tooltip_text(
			sprintf(
				$d->nget(
					"Shutter will wait up to %d second for the screenshot to capture before aborting the process if it's taking too long",
					"Shutter will wait up to %d seconds for the screenshot to capture before aborting the process if it's taking too long",
					10
				),
				10
			));
		$timeout2->set_tooltip_text(
			sprintf(
				$d->nget(
					"Shutter will wait up to %d second for the screenshot to capture before aborting the process if it's taking too long",
					"Shutter will wait up to %d seconds for the screenshot to capture before aborting the process if it's taking too long",
					30
				),
				30
			));
		$timeout3->set_tooltip_text(
			sprintf(
				$d->nget(
					"Shutter will wait up to %d minute for the screenshot to capture before aborting the process if it's taking too long",
					"Shutter will wait up to %d minutes for the screenshot to capture before aborting the process if it's taking too long",
					1
				),
				1
			));
		$timeout4->set_tooltip_text(
			sprintf(
				$d->nget(
					"Shutter will wait up to %d minute for the screenshot to capture before aborting the process if it's taking too long",
					"Shutter will wait up to %d minutes for the screenshot to capture before aborting the process if it's taking too long",
					2
				),
				2
			));

		$timeout2->set_active(TRUE);
		$menu_web->append($timeout0);
		$menu_web->append($timeout1);
		$menu_web->append($timeout2);
		$menu_web->append($timeout3);
		$menu_web->append($timeout4);

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

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

	sub fct_ret_profile_menu {
		my $combobox_settings_profiles = shift;
		my $current_profiles_ref       = shift;
		my $menu_profile               = shift;

		$menu_profile = Gtk3::Menu->new unless defined $menu_profile;
		foreach my $child ($menu_profile->get_children) {
			$child->destroy;
		}

		my $group   = undef;
		my $counter = 0;
		foreach my $profile (@{$current_profiles_ref}) {
			my $profile_item = Gtk3::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 = Gtk3::ListStore->new(
			'Glib::String', 'Glib::String', 'Glib::String',  'Glib::String',  'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String',
			'Glib::String', 'Glib::String', 'Glib::Boolean', 'Glib::Boolean', 'Glib::Boolean'
		);

		foreach (keys %accounts) {
			my $hidden_text = "";
			for (my $i = 1 ; $i <= length($accounts{$_}->{'password'}) ; $i++) {
				$hidden_text .= '*';
			}
			$accounts_model->set(
				$accounts_model->append,                       0,  $accounts{$_}->{'host'},         1,  $accounts{$_}->{'username'},                  2,
				$hidden_text,                                  3,  $accounts{$_}->{'not_used_yet'}, 4,  $accounts{$_}->{'register_color'},            5,
				$accounts{$_}->{'register_text'},              6,  $accounts{$_}->{'module'},       7,  $accounts{$_}->{'path'},                      8,
				$accounts{$_}->{'folder'},                     9,  $accounts{$_}->{'description'},  10, $accounts{$_}->{'supports_anonymous_upload'}, 11,
				$accounts{$_}->{'supports_authorized_upload'}, 12, $accounts{$_}->{'supports_oauth_upload'},
			);
		}

		return TRUE;
	}

	sub fct_load_plugin_tree {

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

				#we need to update the pixbuf of the plugins again in some cases
				#
				#pixbufs are not cached and therefore not checked at startup if
				#the cached plugin is not in the plugin path
				#(maybe changed the installation dir)
				unless ($plugins{$pkey}->{'pixbuf'}
					|| $plugins{$pkey}->{'pixbuf_object'})
				{
					$plugins{$pkey}->{'pixbuf'} = $plugins{$pkey}->{'binary'} . ".png"
						if ($shf->file_exists($plugins{$pkey}->{'binary'} . ".png"));
					$plugins{$pkey}->{'pixbuf'} = $plugins{$pkey}->{'binary'} . ".svg"
						if ($shf->file_exists($plugins{$pkey}->{'binary'} . ".svg"));

					if ($shf->file_exists($plugins{$pkey}->{'pixbuf'})) {
						$plugins{$pkey}->{'pixbuf_object'} = $lp->load($plugins{$pkey}->{'pixbuf'}, $shf->icon_size('menu'));
					} else {
						$plugins{$pkey}->{'pixbuf'}        = "$shutter_root/share/shutter/resources/icons/executable.svg";
						$plugins{$pkey}->{'pixbuf_object'} = $lp->load($plugins{$pkey}->{'pixbuf'}, $shf->icon_size('menu'));
					}
				}

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

		return $effects_model;
	}

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

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

		$accounts_tree->set_tooltip_column(9);

		#name
		my $tv_clmn_name_text = Gtk3::TreeViewColumn->new;
		$tv_clmn_name_text->set_title($d->get("Host"));
		my $renderer_name_accounts = Gtk3::CellRendererText->new;
		$tv_clmn_name_text->pack_start($renderer_name_accounts, FALSE);
		$tv_clmn_name_text->set_attributes($renderer_name_accounts, text => 6);
		$accounts_tree->append_column($tv_clmn_name_text);

		#username
		my $tv_clmn_username_text = Gtk3::TreeViewColumn->new;
		$tv_clmn_username_text->set_max_width(100);
		$tv_clmn_username_text->set_title($d->get("Username"));
		my $renderer_username_accounts = Gtk3::CellRendererText->new;
		$tv_clmn_username_text->pack_start($renderer_username_accounts, FALSE);
		$tv_clmn_username_text->set_attributes(
			$renderer_username_accounts,
			text      => 1,
			editable  => 11,
			sensitive => 11
		);
		$renderer_username_accounts->signal_connect(
			'edited' => sub {
				my ($cell, $text_path, $new_text, $model) = @_;
				my $path = Gtk3::TreePath->new_from_string($text_path);
				my $iter = $model->get_iter($path);

				#save entered username to the hash
				$accounts{$model->get_value($iter, 6)}->{'username'} = $new_text;

				$model->set($iter, 1, $new_text);
			},
			$accounts_model
		);

		$accounts_tree->append_column($tv_clmn_username_text);

		#password
		my $tv_clmn_password_text = Gtk3::TreeViewColumn->new;
		$tv_clmn_password_text->set_max_width(100);
		$tv_clmn_password_text->set_title($d->get("Password"));
		my $renderer_password_accounts = Gtk3::CellRendererText->new;
		$tv_clmn_password_text->pack_start($renderer_password_accounts, FALSE);
		$tv_clmn_password_text->set_attributes(
			$renderer_password_accounts,
			text      => 2,
			editable  => 11,
			sensitive => 11
		);
		$renderer_password_accounts->signal_connect(
			'edited' => sub {
				my ($cell, $text_path, $new_text, $model) = @_;
				my $path        = Gtk3::TreePath->new_from_string($text_path);
				my $iter        = $model->get_iter($path);
				my $hidden_text = "";

				for (my $i = 1 ; $i <= length($new_text) ; $i++) {
					$hidden_text .= '*';
				}

				$accounts{$model->get_value($iter, 6)}->{'password'} = $new_text;    #save entered password to the hash
				$model->set($iter, 2, $hidden_text);
			},
			$accounts_model
		);

		$accounts_tree->append_column($tv_clmn_password_text);

		#upload features
		my $tv_clmn_f1_toggle = Gtk3::TreeViewColumn->new;
		$tv_clmn_f1_toggle->set_title($d->get("Anonymous Upload"));
		my $f1_toggle = Gtk3::CellRendererToggle->new();
		$tv_clmn_f1_toggle->pack_start($f1_toggle, FALSE);
		$tv_clmn_f1_toggle->set_attributes($f1_toggle, active => 10);
		$accounts_tree->append_column($tv_clmn_f1_toggle);

		my $tv_clmn_f2_toggle = Gtk3::TreeViewColumn->new;
		$tv_clmn_f2_toggle->set_title($d->get("Authorized Upload"));
		my $f2_toggle = Gtk3::CellRendererToggle->new();
		$tv_clmn_f2_toggle->pack_start($f2_toggle, FALSE);
		$tv_clmn_f2_toggle->set_attributes($f2_toggle, active => 11);
		$accounts_tree->append_column($tv_clmn_f2_toggle);

		my $tv_clmn_f3_toggle = Gtk3::TreeViewColumn->new;
		$tv_clmn_f3_toggle->set_title($d->get("OAuth Upload"));
		my $f3_toggle = Gtk3::CellRendererToggle->new();
		$tv_clmn_f3_toggle->pack_start($f3_toggle, FALSE);
		$tv_clmn_f3_toggle->set_attributes($f3_toggle, active => 12);
		$accounts_tree->append_column($tv_clmn_f3_toggle);

		#description
		#tooltip column (show as columns when needed)
		my $tv_clmn_descr_text = Gtk3::TreeViewColumn->new;
		$tv_clmn_descr_text->set_resizable(TRUE);
		$tv_clmn_descr_text->set_title($d->get("Description"));
		my $renderer_descr_effects = Gtk3::CellRendererText->new;
		$tv_clmn_descr_text->pack_start($renderer_descr_effects, FALSE);
		$tv_clmn_descr_text->set_attributes($renderer_descr_effects, text => 9);
		$accounts_tree->append_column($tv_clmn_descr_text);

		#register
		my $tv_clmn_pix_text = Gtk3::TreeViewColumn->new;
		$tv_clmn_pix_text->set_title($d->get("Register"));
		my $ren_text = Gtk3::CellRendererText->new();
		$tv_clmn_pix_text->pack_start($ren_text, FALSE);
		$tv_clmn_pix_text->set_attributes($ren_text, 'text', 5, 'foreground', 4);
		$accounts_tree->append_column($tv_clmn_pix_text);

		return TRUE;
	}

	sub fct_set_model_plugins {
		my $effects_tree = $_[0];

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

		#tooltip
		$effects_tree->set_tooltip_column(3);

		my $tv_clmn_pix_text = Gtk3::TreeViewColumn->new;
		$tv_clmn_pix_text->set_resizable(TRUE);
		$tv_clmn_pix_text->set_title($d->get("Icon"));
		my $renderer_pix_effects = Gtk3::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 = Gtk3::TreeViewColumn->new;
		$tv_clmn_text_text->set_resizable(TRUE);
		$tv_clmn_text_text->set_title($d->get("Name"));
		my $renderer_text_effects = Gtk3::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 = Gtk3::TreeViewColumn->new;
		$tv_clmn_category_text->set_resizable(TRUE);
		$tv_clmn_category_text->set_title($d->get("Category"));
		my $renderer_category_effects = Gtk3::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);

		my $tv_clmn_descr_text = Gtk3::TreeViewColumn->new;
		$tv_clmn_descr_text->set_resizable(TRUE);
		$tv_clmn_descr_text->set_title($d->get("Description"));
		my $renderer_descr_effects = Gtk3::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 = Gtk3::TreeViewColumn->new;
		$tv_clmn_lang_text->set_resizable(TRUE);
		$tv_clmn_lang_text->set_title($d->get("Language"));
		my $renderer_lang_effects = Gtk3::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 = Gtk3::TreeViewColumn->new;
		$tv_clmn_path_text->set_resizable(TRUE);
		$tv_clmn_path_text->set_title($d->get("Path"));
		my $renderer_path_effects = Gtk3::CellRendererText->new;
		$tv_clmn_path_text->pack_start($renderer_path_effects, FALSE);
		$tv_clmn_path_text->set_attributes($renderer_path_effects, text => 5);
		$effects_tree->append_column($tv_clmn_path_text);

		return TRUE;
	}

	sub fct_init_depend {

		#imagemagick/perlmagick
		unless (File::Which::which('convert')) {
			die "ERROR: imagemagick is missing --> aborting!\n\n";
		}

		#gnome-web-photo
		unless (File::Which::which('gnome-web-photo')) {
			warn "WARNING: gnome-web-photo is missing --> screenshots of websites will be disabled!\n\n";
			$gnome_web_photo = FALSE;
		}

		#nautilus-sendto
		unless (File::Which::which('nautilus-sendto')) {
			$nautilus_sendto = FALSE;
		}

		#goocanvas
		eval { require GooCanvas2; require GooCanvas2::CairoTypes; };
		if ($@) {
			warn "WARNING: Goo::Canvas/libgoo-canvas-perl is missing --> drawing tool will be disabled!\n\n";
			$goocanvas = FALSE;
		}

		#libimage-exiftool-perl
		eval { require Image::ExifTool };
		if ($@) {
			warn "WARNING: Image::ExifTool is missing --> writing Exif information will be disabled!\n\n";
			$exiftool = FALSE;
		}

		#dev-libs/libappindicator[introspection]
		eval {
			Glib::Object::Introspection->setup(
				basename => 'AppIndicator3',
				version  => '0.1',
				package  => 'AppIndicator',
			);
		};
		if ($@) {
			warn "WARNING: AppIndicator is missing --> there will be no icon showing up in the status bar when running Unity!\n\n";
			$appindicator = FALSE;
		}

		return TRUE;
	}

	sub fct_control_wm_settings {
		my $mode          = shift;
		my $restore_value = shift;

		#compiz via dbus
		my $bus    = undef;
		my $compiz = undef;
		my $fpl    = undef;

		#disable focus_prevention
		my $curr_value = -1;

		#disable focus prevention when using compiz
		eval {
			$bus = Net::DBus->find;

			#Get a handle to the compiz service
			$compiz = $bus->get_service("org.freedesktop.compiz");

			#Get the relevant object
			$fpl = $compiz->get_object("/org/freedesktop/compiz/core/screen0/focus_prevention_level", "org.freedesktop.compiz");
		};
		if ($@) {
			warn "INFO: DBus connection to org.freedesktop.compiz failed --> skipping compiz related tasks\n\n";
			warn $@ . "\n\n";
			return $curr_value;
		}

		if (defined $fpl && $fpl) {
			eval {
				if ($mode eq 'start') {

					#save and return current value
					if (defined $fpl && $fpl) {
						$curr_value = $fpl->get;
					}
					if (defined $fpl && $fpl && $fpl->get != 0) {
						$fpl->set(0);
					}

					#re-enable focus prevention -> restore value
				} elsif ($mode eq 'stop') {
					if (defined $fpl && $fpl && defined $restore_value) {
						$fpl->set($restore_value);
					} elsif (defined $fpl && $fpl) {
						$fpl->set(1);
					}
				}
			};
			if ($@) {
				warn "ERROR: Unable to set/get focus_level_prevention --> skipping compiz related tasks\n\n";
				warn $@ . "\n\n";
			}
		}

		return $curr_value;
	}

	sub fct_init_environment {

		#is there already a .shutter folder?
		mkdir("$ENV{ 'HOME' }/.shutter")
			unless (-d "$ENV{ 'HOME' }/.shutter");

		#...and a profiles folder?
		mkdir "$ENV{'HOME'}/.shutter/profiles"
			unless (-d "$ENV{'HOME'}/.shutter/profiles");

		return TRUE;
	}

	sub fct_init_unsaved_files {

		#delete all files in this folder
		#except the ones that are in the current session
		my @unsaved_files = bsd_glob($sdir->get_cache_dir . "/*");
		foreach my $unsaved_file (@unsaved_files) {
			utf8::decode $unsaved_file;
			print $unsaved_file, " checking \n" if $sc->get_debug;
			unless (fct_get_key_by_filename($unsaved_file)) {
				print $unsaved_file, " deleted \n" if $sc->get_debug;
				unlink $unsaved_file;
			}
		}
	}

	sub fct_init_debug_output {

		print "\nINFO: gathering system information...";
		print "\n";
		print "\n";

		#kernel info
		if (File::Which::which('uname')) {
			print `uname -a`, "\n";
		}

		#issue
		if (-f '/etc/issue') {
			if (File::Which::which('cat')) {
				print `cat /etc/issue`, "\n";
			}
		}

		printf "Glib %s \n", $Glib::VERSION;
		printf "Gtk3 %s \n", $Gtk3::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 "Gtk3 built for " . join(".", Gtk3->GET_VERSION_INFO) . ", running with " . join(".", Gtk3::major_version(), Gtk3::minor_version(), Gtk3::micro_version()) . "\n"
			if $Gtk3::VERSION >= 1.040;
		print "\n";

		return TRUE;
	}

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

	#dialogs
	#--------------------------------------

	sub dlg_rename {
		my (@file_to_rename_keys) = @_;

		foreach my $key (@file_to_rename_keys) {

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

			$input_dialog->set_title($d->get("Rename"));

			$input_dialog->set('image' => Gtk3::Image->new_from_stock('gtk-save-as', 'dialog'));

			$input_dialog->set('text' => sprintf($d->get("Rename image %s"), "'$session_screens{$key}->{'short'}'"));

			$input_dialog->set('secondary-text' => $d->get("New filename") . ": ");

			#rename button
			my $rename_btn = Gtk3::Button->new_with_mnemonic($d->get("_Rename"));
			$rename_btn->set_image(Gtk3::Image->new_from_stock('gtk-save-as', 'button'));
			$rename_btn->set_can_default(TRUE);

			$input_dialog->add_button('gtk-cancel', 'reject');
			$input_dialog->add_action_widget($rename_btn, 'accept');

			$input_dialog->set_default_response('accept');

			my $new_filename_vbox = Gtk3::VBox->new();
			my $new_filename_hint = Gtk3::Label->new();
			my $new_filename      = Gtk3::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 = Gtk3::Gdk::keyval_to_unicode($event->keyval);

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

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

			#parse filename
			my ($short, $folder, $ext) = fileparse($session_screens{$key}->{'long'}, qr/\.[^.]*/);

			#enable/disable rename button
			#e.g. if no text is in entry
			$new_filename->signal_connect(
				'changed' => sub {
					my $temp_filename = $new_filename->get_text;
					if (length($temp_filename)) {
						$rename_btn->set_sensitive(TRUE);

						#Bug #1087367
						if ($temp_filename =~ /.*$ext$/) {
							my ($short, $folder, $ext) = fileparse($temp_filename, qr/\.[^.]*/);
							$new_filename->set_text($short);
						}
					} else {
						$rename_btn->set_sensitive(FALSE);
					}
					return TRUE;
				});

			#show just the name of the image
			$new_filename->set_text($session_screens{$key}->{'name'});
			if (length($new_filename->get_text)) {
				$rename_btn->set_sensitive(TRUE);
			} else {
				$rename_btn->set_sensitive(FALSE);
			}

			$new_filename_vbox->pack_start($new_filename, TRUE, TRUE, 0);
			$new_filename_vbox->pack_start($new_filename_hint, TRUE, TRUE, 0);
			$input_dialog->get_child->add($new_filename_vbox);
			$input_dialog->show_all;

			#run dialog
			my $input_response = $input_dialog->run;

			#handle user responses here
			if ($input_response eq 'accept') {

				my $new_name = $new_filename->get_text;
				$new_name = $session_screens{$key}->{'folder'} . "/" . $new_name . "." . $session_screens{$key}->{'filetype'};

				#create uris for following action (e.g. update tab, move etc.)
				my $new_giofile = Glib::IO::File::new_for_path($new_name);
				my $old_giofile = $session_screens{$key}->{'giofile'};

				if ($new_giofile) {

					#filenames eq? -> nothing to do here
					unless ($session_screens{$key}->{'long'} eq $new_name) {

						#does the "renamed" file already exists?
						unless ($shf->file_exists($new_name)) {

							#ok => rename it

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

								$session_screens{$key}->{'handle'}->cancel;
							}

							eval { $old_giofile->move($new_giofile, []); };
							if ($@) {
								my $response = $sd->dlg_error_message(
									sprintf($d->get("Error while renaming the image %s."),           "'" . $old_giofile->get_basename . "'"),
									sprintf($d->get("There was an error renaming the image to %s."), "'" . $new_giofile->get_basename . "'"),
									undef, undef, undef, undef, undef, undef, $@
								);

							}
							fct_update_tab($key, undef, $new_giofile, FALSE, 'block');

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

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

							#change window title
							#~ $window->set_title($session_screens{$key}->{'long'}." - ".SHUTTER_NAME);

						} else {

							#ask the user to replace the image
							#replace button
							my $replace_btn = Gtk3::Button->new_with_mnemonic($d->get("_Replace"));
							$replace_btn->set_image(Gtk3::Image->new_from_stock('gtk-save-as', 'button'));

							my $sd = Shutter::App::SimpleDialogs->new;

							my $response = $sd->dlg_warning_message(
								sprintf($d->get("The image already exists in %s. Replacing it will overwrite its contents."), "'" . $new_giofile->extract_dirname . "'"),
								sprintf($d->get("An image named %s already exists. Do you want to replace it?"),              "'" . $new_giofile->get_basename . "'"),
								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;
								}

								eval { $old_giofile->move($new_giofile, ['overwrite']); };
								if ($@) {
									my $response = $sd->dlg_error_message(
										sprintf($d->get("Error while renaming the image %s."),           "'" . $old_giofile->get_basename . "'"),
										sprintf($d->get("There was an error renaming the image to %s."), "'" . $new_giofile->get_basename . "'"),
										undef, undef, undef, undef, undef, undef, $@
									);
								}
								fct_update_tab($key, undef, $new_giofile, FALSE, 'block');

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

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

								#change window title
								#~ $window->set_title($session_screens{$key}->{'long'}." - ".SHUTTER_NAME);

								#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_giofile, FALSE, 'block');

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

									}
								}
								$input_dialog->destroy();
								next;
							}
							$input_dialog->destroy();
							next;
						}

					}

				} else {

					#uri object could not be created
					#=> uri illegal
					my $response = $sd->dlg_error_message(
						sprintf($d->get("Error while renaming the image %s."),           "'" . $old_giofile->get_basename . "'"),
						sprintf($d->get("There was an error renaming the image to %s."), "'" . $new_name . "'"),
						undef, undef, undef, undef, undef, undef, $d->get("Invalid Filename"));

				}

			}

			$input_dialog->destroy();
			next;

		}

	}

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

		#do we need to open a filechooserdialog?
		#maybe we open a recently opened file that is
		#selected via menu
		my @new_files;
		unless ($widget =~ /Gtk3::RecentChooserMenu/) {
			my $fs = Gtk3::FileChooserDialog->new(
				$d->get("Choose file to open"), $window,
				'open',
				'gtk-cancel' => 'reject',
				'gtk-open'   => 'accept'
			);
			$fs->set_select_multiple(TRUE);

			#preview widget
			my $iprev = Gtk3::Image->new;
			$fs->set_preview_widget($iprev);

			$fs->signal_connect(
				'selection-changed' => sub {
					if (my $pfilename = $fs->get_preview_filename) {

						#without error dialog
						my $pixbuf = $lp_ne->load($pfilename, 200, 200, TRUE, TRUE);
						unless (defined $pixbuf) {
							$fs->set_preview_widget_active(FALSE);
						} else {
							$fs->get_preview_widget->set_from_pixbuf($pixbuf);
							$fs->set_preview_widget_active(TRUE);
						}
					} else {
						$fs->set_preview_widget_active(FALSE);
					}
				});

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

			foreach my $format (Gtk3::Gdk::Pixbuf::get_formats()) {
				my $filter = Gtk3::FileFilter->new;

				#add all known formats to the dialog
				$filter->set_name($format->get_name . " - " . $format->get_description);

				foreach my $ext (@{$format->get_extensions}) {
					$filter->add_pattern("*." . uc $ext);
					$filter_all->add_pattern("*." . uc $ext);
					$filter->add_pattern("*." . $ext);
					$filter_all->add_pattern("*." . $ext);
				}
				$fs->add_filter($filter);
			}

			#set default filter
			$fs->set_filter($filter_all);

			#get current file
			my $key = fct_get_current_file();

			#go to recently used folder
			if (defined $sc->get_ruof && $shf->folder_exists($sc->get_ruof)) {
				$fs->set_current_folder_uri($sc->get_ruof);
			} else {
				if ($key) {
					$fs->set_filename($session_screens{$key}->{'long'});
				} elsif ($saveDir_button->get_filename) {
					$fs->set_current_folder($saveDir_button->get_filename);
				} else {
					$fs->set_current_folder($ENV{'HOME'});
				}
			}

			my $fs_resp = $fs->run;

			if ($fs_resp eq "accept") {
				@new_files = $fs->get_uris;

				#keep folder in mind
				if ($new_files[0]) {
					my ($oshort, $ofolder, $oext) = fileparse($new_files[0], qr/\.[^.]*/);
					$sc->set_ruof($ofolder) if defined $ofolder;
				}

				$fs->destroy();
			} else {
				$fs->destroy();
			}

		} else {
			print "Trying to open file via RecentChooserMenu ", $sm->{_menu_recent}->get_current_item->get_uri, "\n"
				if $sc->get_debug;
			push @new_files, $sm->{_menu_recent}->get_current_item->get_uri;
		}

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

		return TRUE;
	}

	sub dlg_save_as {

		#mandatory
		my $key = shift;

		#optional
		my $rfiletype = shift;
		my $rfilename = shift;
		my $rpixbuf   = shift;
		my $rquality  = shift;

		$rfilename = $session_screens{$key}->{'long'} if $key;

		my $fs = Gtk3::FileChooserDialog->new(
			$d->get("Choose a location to save to"),
			$window, 'save',
			'gtk-cancel' => 'reject',
			'gtk-save'   => 'accept'
		);

		#parse filename
		my ($short, $folder, $ext) = fileparse($rfilename, qr/\.[^.]*/);

		#go to recently used folder
		if (defined $sc->get_rusf && $shf->folder_exists($sc->get_rusf)) {
			$fs->set_current_folder($sc->get_rusf);
			$fs->set_current_name($short . $ext);
		} elsif (defined $key
			&& defined $session_screens{$key}->{'is_unsaved'}
			&& $session_screens{$key}->{'is_unsaved'})
		{
			$fs->set_current_folder($saveDir_button->get_current_folder);
			$fs->set_current_name($short . $ext);
		} else {
			$fs->set_current_folder($folder);
			$fs->set_current_name($short . $ext);
		}

		#preview widget
		my $iprev = Gtk3::Image->new;
		$fs->set_preview_widget($iprev);

		$fs->signal_connect(
			'selection-changed' => sub {
				if (my $pfilename = $fs->get_preview_filename) {

					#without error dialog
					my $pixbuf = $lp_ne->load($pfilename, 200, 200, TRUE, TRUE);
					unless (defined $pixbuf) {
						$fs->set_preview_widget_active(FALSE);
					} else {
						$fs->get_preview_widget->set_from_pixbuf($pixbuf);
						$fs->set_preview_widget_active(TRUE);
					}
				} else {
					$fs->set_preview_widget_active(FALSE);
				}
			});

		#change extension related to the requested filetype
		if (defined $rfiletype && defined $rfilename) {
			my ($short, $folder, $ext) = fileparse($rfilename, qr/\.[^.]*/);
			$fs->set_current_name($short . "." . $rfiletype);
		}

		my $extra_hbox = Gtk3::HBox->new;

		my $label_save_as_type = Gtk3::Label->new($d->get("Image format") . ":");

		my $combobox_save_as_type = Gtk3::ComboBoxText->new;

		#add supported formats to combobox
		my $counter     = 0;
		my $png_counter = undef;

		#add pdf support
		if (defined $rfiletype && $rfiletype eq 'pdf') {

			$combobox_save_as_type->insert_text($counter, "pdf - Portable Document Format");
			$combobox_save_as_type->set_active(0);

		} elsif (defined $rfiletype && $rfiletype eq 'ps') {

			$combobox_save_as_type->insert_text($counter, "ps - PostScript");
			$combobox_save_as_type->set_active(0);

			#images
		} else {

			foreach my $format (Gtk3::Gdk::Pixbuf::get_formats()) {

				#we don't want svg here - this is a dedicated action in the DrawingTool
				next if !defined $rfiletype && $format->get_name =~ /svg/;

				#we have a requested filetype - nothing else will be offered
				next if defined $rfiletype && $format->get_name ne $rfiletype;

				#we want jpg not jpeg
				if ($format->get_name eq "jpeg" || $format->get_name eq "jpg") {
					$combobox_save_as_type->insert_text($counter, "jpg" . " - " . $format->get_description);
				} else {
					$combobox_save_as_type->insert_text($counter, $format->get_name . " - " . $format->get_description);
				}

				#set active when mime_type is matching
				#loop because multiple mime types are registered for fome file formats
				foreach my $mime (@{$format->get_mime_types}) {

					if (defined $key) {
						if ($mime eq $session_screens{$key}->{'mime_type'}
							|| defined $rfiletype)
						{
							$combobox_save_as_type->set_active($counter);
						}
					} else {

						#Fix Bug #966159
						if (defined $rfilename) {
							my ($short, $folder, $ext) = fileparse($rfilename, qr/\.[^.]*/);
							if ($mime eq "image/jpeg" && $ext eq ".jpg") {
								$combobox_save_as_type->set_active($counter);
							} elsif ($mime eq "image/png" && $ext eq ".png") {
								$combobox_save_as_type->set_active($counter);
							} elsif ($mime eq "image/bmp" && $ext eq ".bmp") {
								$combobox_save_as_type->set_active($counter);
							}
						}
					}

					#save png_counter as well as fallback
					$png_counter = $counter if $mime eq 'image/png';
				}

				$counter++;

			}

		}

		#something went wrong here
		#filetype was not detected automatically
		#set to png as default
		unless ($combobox_save_as_type->get_active_text) {
			if (defined $png_counter) {
				$combobox_save_as_type->set_active($png_counter);
			}
		}

		$combobox_save_as_type->signal_connect(
			'changed' => sub {
				my $filename = $shf->utf8_decode($fs->get_filename);

				my $choosen_format = $combobox_save_as_type->get_active_text;
				$choosen_format =~ s/ \-.*//;    #get png or jpeg (jpg) for example
												#~ print $choosen_format . "\n";

				#parse filename
				my ($short, $folder, $ext) = fileparse($filename, qr/\.[^.]*/);

				$fs->set_current_name($short . "." . $choosen_format);
			});

		#emit the signal once in order to invoke the sub above
		#~ $combobox_save_as_type->signal_emit('changed');

		$extra_hbox->pack_start($label_save_as_type,    FALSE, FALSE, 5);
		$extra_hbox->pack_start($combobox_save_as_type, FALSE, FALSE, 5);

		my $align_save_as_type = Gtk3::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 = $shf->utf8_decode($fs->get_filename);

			#parse filename
			my ($short, $folder, $ext) = fileparse($filename, qr/\.[^.]*/);

			#keep selected folder in mind
			$sc->set_rusf($folder);

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

			$filename = $folder . $short . "." . $choosen_format;

			unless ($shf->file_exists($filename)) {

				#get pixbuf from param
				my $pixbuf = $rpixbuf;
				unless ($pixbuf) {

					#or load pixbuf from existing file
					$pixbuf = $lp_ne->load($rfilename);
				}

				#save as (pixbuf, new_filename, filetype, quality - auto here, old_filename)
				if ($sp->save_pixbuf_to_file($pixbuf, $filename, $choosen_format, $rquality)) {

					if ($key) {

						#do not try to update when exporting to pdf or ps
						unless (defined $rfiletype
							&& ($rfiletype eq 'pdf' || $rfiletype eq 'ps'))
						{

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

								$session_screens{$key}->{'handle'}->cancel;
							}
							if (fct_update_tab($key, undef, Glib::IO::File::new_for_path($filename), FALSE, 'clear')) {

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

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

						} else {
							if ($shf->file_exists($filename)) {
								fct_show_status_message(1, "$filename " . $d->get("saved"));
							}
						}

					}

					#successfully saved
					$fs->destroy();
					return $filename;

				} else {

					#error while saving
					$fs->destroy();
					return FALSE;

				}

			} else {

				#ask the user to replace the image
				#replace button
				my $replace_btn = Gtk3::Button->new_with_mnemonic($d->get("_Replace"));
				$replace_btn->set_image(Gtk3::Image->new_from_stock('gtk-save-as', 'button'));

				my $response = $sd->dlg_warning_message(
					sprintf($d->get("The image already exists in %s. Replacing it will overwrite its contents."), "'" . $folder . "'"),
					sprintf($d->get("An image named %s already exists. Do you want to replace it?"),              "'" . $short . "." . $choosen_format . "'"),
					undef, undef, undef, $replace_btn, undef, undef
				);

				if ($response == 40) {

					#get pixbuf from param
					my $pixbuf = $rpixbuf;
					unless ($pixbuf) {

						#or load pixbuf from existing file
						$pixbuf = $lp_ne->load($rfilename);
					}

					if ($sp->save_pixbuf_to_file($pixbuf, $filename, $choosen_format, $rquality)) {

						if ($key) {

							#do not try to update when exporting to pdf
							unless (defined $rfiletype
								&& ($rfiletype eq 'pdf' || $rfiletype eq 'ps'))
							{

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

									$session_screens{$key}->{'handle'}->cancel;
								}

								if (fct_update_tab($key, undef, Glib::IO::File::new_for_path($filename), FALSE, 'clear')) {

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

									#maybe file is in session as well, need to set the handler again ;-)
									foreach my $searchkey (keys %session_screens) {
										next if $key eq $searchkey;
										if ($session_screens{$searchkey}->{'long'} eq $filename) {
											$session_screens{$searchkey}->{'changed'} = TRUE;
											fct_update_tab($searchkey, undef, undef, FALSE, 'clear');
										}
									}

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

								}

							} else {
								if ($shf->file_exists($filename)) {
									fct_show_status_message(1, "$filename " . $d->get("saved"));
								}
							}

						}    #end if $key

						#successfully saved
						$fs->destroy();
						return $filename;

					} else {

						#error while saving
						$fs->destroy();
						return FALSE;

					}

				} else {

					#user cancelled overwrite
					$fs->destroy();
					return 'user_cancel';

				}

			}

		} else {

			#user cancelled
			$fs->destroy();
			return 'user_cancel';
		}

		$fs->destroy();

	}

	sub dlg_plugin {
		my (@file_to_plugin_keys) = @_;

		my $plugin_dialog = Gtk3::Dialog->new($d->get("Choose a plugin"), $window, [qw/modal destroy-with-parent/]);
		$plugin_dialog->set_size_request(350, -1);
		$plugin_dialog->set_resizable(FALSE);

		#rename button
		my $run_btn = Gtk3::Button->new_with_mnemonic($d->get("_Run"));
		$run_btn->set_image(Gtk3::Image->new_from_stock('gtk-execute', 'button'));
		$run_btn->set_can_default(TRUE);

		$plugin_dialog->add_button('gtk-cancel', 'reject');
		$plugin_dialog->add_action_widget($run_btn, 'accept');

		$plugin_dialog->set_default_response('accept');

		my $model = Gtk3::ListStore->new('Gtk3::Gdk::Pixbuf', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String');

		#temp variables to restore the
		#recent plugin
		my $recent_time        = 0;
		my $iter_lastex_plugin = undef;
		foreach my $pkey (sort keys %plugins) {

			#check if plugin allows current filetype
			#~ my $nfiles_ok += scalar grep($plugins{$pkey}->{'ext'} =~ /$session_screens{$_}->{'mime_type'}/, @file_to_plugin_keys);
			#~ next if scalar @file_to_plugin_keys > $nfiles_ok;

			if ($plugins{$pkey}->{'binary'} ne "") {

				my $new_iter = $model->append;
				$model->set(
					$new_iter,                 0, $plugins{$pkey}->{'pixbuf_object'}, 1, $plugins{$pkey}->{'name'}, 2, $plugins{$pkey}->{'binary'}, 3,
					$plugins{$pkey}->{'lang'}, 4, $plugins{$pkey}->{'tooltip'},       5, $pkey
				);

				#initialize $iter_lastex_plugin
				#with first new iter
				$iter_lastex_plugin = $new_iter
					unless defined $iter_lastex_plugin;

				#restore the recent plugin
				#($plugins{$plugin_key}->{'recent'} is a timestamp)
				#
				#we keep the new_iter in mind
				if (defined $plugins{$pkey}->{'recent'}
					&& $plugins{$pkey}->{'recent'} > $recent_time)
				{
					$iter_lastex_plugin = $new_iter;
					$recent_time        = $plugins{$pkey}->{'recent'};
				}

			} else {
				print "WARNING: Program $pkey is not configured properly, ignoring\n";
			}

		}

		my $plugin_label = Gtk3::Label->new($d->get("Plugin") . ":");
		my $plugin       = Gtk3::ComboBox->new_with_model($model);

		#plugin description
		my $plugin_descr      = Gtk3::TextBuffer->new;
		my $plugin_descr_view = Gtk3::TextView->new_with_buffer($plugin_descr);
		$plugin_descr_view->set_sensitive(FALSE);
		$plugin_descr_view->set_wrap_mode('word');
		my $textview_hbox = Gtk3::HBox->new(FALSE, 5);
		$textview_hbox->set_border_width(8);
		$textview_hbox->pack_start($plugin_descr_view, TRUE, TRUE, 0);

		my $plugin_descr_label = Gtk3::Label->new();
		$plugin_descr_label->set_markup("<b>" . $d->get("Description") . "</b>");
		my $plugin_descr_frame = Gtk3::Frame->new();
		$plugin_descr_frame->set_label_widget($plugin_descr_label);
		$plugin_descr_frame->set_shadow_type('none');
		$plugin_descr_frame->add($textview_hbox);

		#plugin image
		my $plugin_image = Gtk3::Image->new;

		#packing
		my $plugin_vbox1 = Gtk3::VBox->new(FALSE, 5);
		my $plugin_hbox1 = Gtk3::HBox->new(FALSE, 5);
		my $plugin_hbox2 = Gtk3::HBox->new(FALSE, 5);
		$plugin_hbox2->set_border_width(10);

		#what plugin is selected?
		my $plugin_pixbuf = undef;
		my $plugin_name   = undef;
		my $plugin_value  = undef;
		my $plugin_lang   = undef;
		my $plugin_tip    = undef;
		my $plugin_key    = undef;
		$plugin->signal_connect(
			'changed' => sub {
				my $model       = $plugin->get_model();
				my $plugin_iter = $plugin->get_active_iter();

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

					$plugin_descr->set_text($plugin_tip);
					if ($shf->file_exists($plugins{$plugin_key}->{'pixbuf'})) {
						$plugin_image->set_from_pixbuf($lp->load($plugins{$plugin_key}->{'pixbuf'}, 100, 100));
					}
				}
			});

		my $renderer_pix = Gtk3::CellRendererPixbuf->new;
		$plugin->pack_start($renderer_pix, FALSE);
		$plugin->add_attribute($renderer_pix, pixbuf => 0);
		my $renderer_text = Gtk3::CellRendererText->new;
		$plugin->pack_start($renderer_text, FALSE);
		$plugin->add_attribute($renderer_text, text => 1);

		#we try to activate the last executed plugin if that's possible
		$plugin->set_active_iter($iter_lastex_plugin);

		$plugin_hbox1->pack_start($plugin, TRUE, TRUE, 0);

		$plugin_hbox2->pack_start($plugin_image, TRUE, TRUE, 0);
		$plugin_hbox2->pack_start($plugin_descr_frame, TRUE, TRUE, 0);

		$plugin_vbox1->pack_start($plugin_hbox1, FALSE, TRUE, 1);
		$plugin_vbox1->pack_start($plugin_hbox2, TRUE,  TRUE, 1);

		$plugin_dialog->get_child->add($plugin_vbox1);

		my $plugin_progress = Gtk3::ProgressBar->new;
		$plugin_progress->set_no_show_all(TRUE);
		$plugin_progress->set_ellipsize('middle');
		$plugin_progress->set_orientation('horizontal');
		$plugin_dialog->get_child->add($plugin_progress);

		$plugin_dialog->show_all;

		my $plugin_response = $plugin_dialog->run;

		if ($plugin_response eq 'accept') {

			#anything wrong with the selected plugin?
			unless ($plugin_value =~ /[a-zA-Z0-9]+/) {
				$sd->dlg_error_message($d->get("No plugin specified"), $d->get("Failed"));
				return FALSE;
			}

			#we save the last execution time
			#and try to preselect it when the plugin dialog is executed again
			$plugins{$plugin_key}->{'recent'} = time;

			#disable buttons and combobox
			$plugin->set_sensitive(FALSE);
			foreach my $dialog_child ($plugin_dialog->get_child->get_children) {
				$dialog_child->set_sensitive(FALSE)
					if $dialog_child =~ /Button/;
			}

			#show the progress bar
			$plugin_progress->show;
			$plugin_progress->set_fraction(0);
			fct_update_gui();
			my $counter = 1;

			#call execute_plugin for each file to be processed
			foreach my $key (@file_to_plugin_keys) {

				#update the progress bar and update gui to show changes
				#~ $plugin_progress->set_text($session_screens{$key}->{'long'});
				#~ $plugin_progress->set_fraction($counter / scalar @file_to_plugin_keys);
				#~ fct_update_gui();

				#store data
				my $data = [$plugin_value, $plugin_name, $plugin_lang, $key, $plugin_dialog, $plugin_progress];
				fct_execute_plugin(undef, $data);

				#increase counter and update gui to show updated progress bar
				$counter++;
			}

			$plugin_dialog->destroy();
			return TRUE;
		} else {
			$plugin_dialog->destroy();
			return FALSE;
		}
	}

	sub dlg_upload {
		my (@files_to_upload) = @_;

		return FALSE if @files_to_upload < 1;

		my $dlg_header     = $d->get("Upload / Export");
		my $hosting_dialog = Gtk3::Dialog->new($dlg_header, $window, [qw/modal destroy-with-parent/]);
		$hosting_dialog->set_default_size(400, 300);

		my $close_button  = $hosting_dialog->add_button('gtk-close',        'close');
		my $upload_button = $hosting_dialog->add_button($d->get("_Upload"), 'accept');
		$upload_button->set_image(Gtk3::Image->new_from_stock('gtk-go-up', 'button'));
		$hosting_dialog->set_default_response('accept');

		my $model = Gtk3::ListStore->new('Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String', 'Glib::String');

		foreach (keys %accounts) {

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

			#Create Username/Password entry (if supported and supplied)
			if ($accounts{$_}->{'supports_authorized_upload'}) {
				if (   $accounts{$_}->{'username'} ne ""
					&& $accounts{$_}->{'password'} ne "")
				{
					$model->set(
						$model->append,  0, $accounts{$_}->{'module'}, 1, $accounts{$_}->{'username'}, 2, $accounts{$_}->{'password'}, 3,
						$short_username, 4, $accounts{$_}->{'module'}, 5, $accounts{$_}->{'folder'});
				}
			}

			#Create Anonymous entry (if supported)
			if ($accounts{$_}->{'supports_anonymous_upload'}) {
				$model->set($model->append, 0, $accounts{$_}->{'module'}, 1, $d->get("Guest"), 2, "", 3, $d->get("Guest"), 4, $accounts{$_}->{'module'}, 5, $accounts{$_}->{'folder'});
			}

			#Create OAuth entry (if supported)
			if ($accounts{$_}->{'supports_oauth_upload'}) {
				$model->set($model->append, 0, $accounts{$_}->{'module'}, 1, $d->get("OAuth"), 2, "", 3, $d->get("OAuth"), 4, $accounts{$_}->{'module'}, 5, $accounts{$_}->{'folder'});
			}
		}

		#set up account combobox
		my $hosting       = Gtk3::ComboBox->new_with_model($model);
		my $renderer_host = Gtk3::CellRendererText->new;
		$hosting->pack_start($renderer_host, FALSE);
		$hosting->add_attribute($renderer_host, text => 0);

		my $renderer_username = Gtk3::CellRendererText->new;
		$hosting->pack_start($renderer_username, FALSE);
		$hosting->add_attribute($renderer_username, text => 3);
		$hosting->set_active(0);

		#public hosting settings
		my $pub_hbox1      = Gtk3::HBox->new(FALSE, 0);
		my $pub_hbox2      = Gtk3::HBox->new(FALSE, 0);
		my $pub_hbox_hint  = Gtk3::HBox->new(FALSE, 0);
		my $pub_hbox_hint2 = Gtk3::HBox->new(FALSE, 0);
		my $pub_vbox1      = Gtk3::VBox->new(FALSE, 0);

		my $pub_hint  = Gtk3::Label->new();
		my $pub_hint2 = Gtk3::Label->new();
		$pub_hint->set_line_wrap(TRUE);
		$pub_hint2->set_line_wrap(TRUE);
		$pub_hint->set_line_wrap_mode('word-char');
		$pub_hint2->set_line_wrap_mode('word-char');

		$pub_hint->set_markup(
			"<span size='small'>"
				. $d->get(
				"Please choose one of the accounts above and click <i>Upload</i>. The upload links will still be available in the screenshot's <i>right-click menu</i> after closing this dialog.")
				. "</span>"
		);
		$pub_hint2->set_markup("<span size='small'>"
				. $d->get("<b>Please note:</b> If a plugin allows only authorized uploading you need to enter your credentials in preferences first to make it appear in the list above.")
				. "</span>");

		$pub_hbox1->pack_start(Gtk3::Label->new($d->get("Choose account") . ":"), FALSE, FALSE, 6);
		$pub_hbox1->pack_start($hosting, TRUE, TRUE, 0);
		$pub_hbox_hint->pack_start($pub_hint, TRUE, TRUE, 6);
		$pub_hbox_hint2->pack_start($pub_hint2, TRUE, TRUE, 6);

		$pub_hint->set_alignment(0, 0.5);
		$pub_hint2->set_alignment(0, 0.5);

		$pub_vbox1->pack_start($pub_hbox1,      FALSE, FALSE, 3);
		$pub_vbox1->pack_start($pub_hbox_hint,  FALSE, FALSE, 3);
		$pub_vbox1->pack_start($pub_hbox_hint2, FALSE, FALSE, 3);

		#places settings
		my $pl_hbox1 = Gtk3::HBox->new(FALSE, 0);
		my $pl_vbox1 = Gtk3::VBox->new(FALSE, 0);
		my $places_fc = Gtk3::FileChooserButton->new("Shutter - " . $d->get("Choose folder"), 'select-folder');
		$places_fc->set('local-only' => FALSE);
		$pl_hbox1->pack_start(Gtk3::Label->new($d->get("Choose folder") . ":"), FALSE, FALSE, 6);
		$pl_hbox1->pack_start($places_fc, TRUE, TRUE, 0);
		$pl_vbox1->pack_start($pl_hbox1, FALSE, FALSE, 3);

		#ftp settings
		#we are using the same widgets as in the settings and populate
		#them with saved values when possible
		my $ftp_hbox1_dlg = Gtk3::HBox->new(FALSE, 0);
		my $ftp_hbox2_dlg = Gtk3::HBox->new(FALSE, 0);
		my $ftp_hbox3_dlg = Gtk3::HBox->new(FALSE, 0);
		my $ftp_hbox4_dlg = Gtk3::HBox->new(FALSE, 0);
		my $ftp_hbox5_dlg = Gtk3::HBox->new(FALSE, 0);

		#uri
		my $ftp_entry_label_dlg = Gtk3::Label->new($d->get("URI") . ":");
		$ftp_hbox1_dlg->pack_start($ftp_entry_label_dlg, FALSE, TRUE, 10);
		my $ftp_remote_entry_dlg = Gtk3::Entry->new;
		$ftp_remote_entry_dlg->set_text($ftp_remote_entry->get_text);

		$ftp_entry_label_dlg->set_tooltip_text($d->get("URI\nExample: ftp://host:port/path"));

		$ftp_remote_entry_dlg->set_tooltip_text($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 = Gtk3::Label->new($d->get("Connection mode") . ":");
		$ftp_hbox2_dlg->pack_start($ftp_mode_label_dlg, FALSE, TRUE, 10);
		my $ftp_mode_combo_dlg = Gtk3::ComboBoxText->new;
		$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);

		$ftp_mode_label_dlg->set_tooltip_text($d->get("Connection mode"));

		$ftp_mode_combo_dlg->set_tooltip_text($d->get("Connection mode"));

		$ftp_hbox2_dlg->pack_start($ftp_mode_combo_dlg, TRUE, TRUE, 10);

		#username
		my $ftp_username_label_dlg = Gtk3::Label->new($d->get("Username") . ":");
		$ftp_hbox3_dlg->pack_start($ftp_username_label_dlg, FALSE, TRUE, 10);
		my $ftp_username_entry_dlg = Gtk3::Entry->new;
		$ftp_username_entry_dlg->set_text($ftp_username_entry->get_text);

		$ftp_username_label_dlg->set_tooltip_text($d->get("Username"));

		$ftp_username_entry_dlg->set_tooltip_text($d->get("Username"));

		$ftp_hbox3_dlg->pack_start($ftp_username_entry_dlg, TRUE, TRUE, 10);

		#password
		my $ftp_password_label_dlg = Gtk3::Label->new($d->get("Password") . ":");
		$ftp_hbox4_dlg->pack_start($ftp_password_label_dlg, FALSE, TRUE, 10);
		my $ftp_password_entry_dlg = Gtk3::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);

		$ftp_password_label_dlg->set_tooltip_text($d->get("Password"));

		$ftp_password_entry_dlg->set_tooltip_text($d->get("Password"));

		$ftp_hbox4_dlg->pack_start($ftp_password_entry_dlg, TRUE, TRUE, 10);

		#website url
		my $ftp_wurl_label_dlg = Gtk3::Label->new($d->get("Website URL") . ":");
		$ftp_hbox5_dlg->pack_start($ftp_wurl_label_dlg, FALSE, TRUE, 10);
		my $ftp_wurl_entry_dlg = Gtk3::Entry->new;
		$ftp_wurl_entry_dlg->set_text($ftp_wurl_entry->get_text);

		$ftp_wurl_label_dlg->set_tooltip_text($d->get("Website URL"));

		$ftp_wurl_entry_dlg->set_tooltip_text($d->get("Website URL"));

		$ftp_hbox5_dlg->pack_start($ftp_wurl_entry_dlg, TRUE, TRUE, 10);

		my $ftp_vbox_dlg = Gtk3::VBox->new(FALSE, 0);
		$ftp_vbox_dlg->pack_start($ftp_hbox1_dlg, FALSE, TRUE, 3);
		$ftp_vbox_dlg->pack_start($ftp_hbox2_dlg, FALSE, TRUE, 3);
		$ftp_vbox_dlg->pack_start($ftp_hbox3_dlg, FALSE, TRUE, 3);
		$ftp_vbox_dlg->pack_start($ftp_hbox4_dlg, FALSE, TRUE, 3);
		$ftp_vbox_dlg->pack_start($ftp_hbox5_dlg, FALSE, TRUE, 3);

		#all labels = one size
		$ftp_entry_label_dlg->set_alignment(0, 0.5);
		$ftp_mode_label_dlg->set_alignment(0, 0.5);
		$ftp_username_label_dlg->set_alignment(0, 0.5);
		$ftp_password_label_dlg->set_alignment(0, 0.5);
		$ftp_wurl_label_dlg->set_alignment(0, 0.5);

		my $sg_ftp_dlg = Gtk3::SizeGroup->new('horizontal');
		$sg_ftp_dlg->add_widget($ftp_entry_label_dlg);
		$sg_ftp_dlg->add_widget($ftp_mode_label_dlg);
		$sg_ftp_dlg->add_widget($ftp_username_label_dlg);
		$sg_ftp_dlg->add_widget($ftp_password_label_dlg);
		$sg_ftp_dlg->add_widget($ftp_wurl_label_dlg);

		#setup notebook
		my $unotebook = Gtk3::Notebook->new;
		my $hosting_label = Gtk3::Label->new;
		$hosting_label->set_text($d->get("Public hosting"));
		$unotebook->append_page($pub_vbox1,    $hosting_label);
		my $ftp_label = Gtk3::Label->new;
		$ftp_label->set_text("FTP");
		$unotebook->append_page($ftp_vbox_dlg, $ftp_label);
		my $places_label = Gtk3::Label->new;
		$places_label->set_text($d->get("Places"));
		$unotebook->append_page($pl_vbox1,     $places_label);
		$hosting_dialog->get_child->add($unotebook);

		my $hosting_progress = Gtk3::ProgressBar->new;
		$hosting_progress->set_no_show_all(TRUE);
		$hosting_progress->set_ellipsize('middle');
		$hosting_progress->set_orientation('horizontal');
		$hosting_dialog->get_child->add($hosting_progress);

		$hosting_dialog->show_all;

		#restore recently used upload tab
		if (defined $sc->get_ruu_tab && $sc->get_ruu_tab) {
			$unotebook->set_current_page($sc->get_ruu_tab);
		}

		#and the relevant detail (folder, uploader etc.)
		if (defined $sc->get_ruu_hosting && $sc->get_ruu_hosting) {
			$hosting->set_active($sc->get_ruu_hosting);
		} else {
			$hosting->set_active(0);
		}
		if (defined $sc->get_ruu_places
			&& $shf->folder_exists($sc->get_ruu_places))
		{
			$places_fc->set_current_folder($sc->get_ruu_places);
		}

		#DIALOG RUN
		while (my $hosting_response = $hosting_dialog->run) {

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

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

				#public hosting
				#All modules must provide the following methods:
				# 1: init
				# 2: upload
				# 3: show
				# 4: show_all

				if ($unotebook->get_current_page == 0) {

					my $model            = $hosting->get_model();
					my $hosting_iter     = $hosting->get_active_iter();
					my $hosting_host     = $model->get_value($hosting_iter, 0);
					my $hosting_username = $model->get_value($hosting_iter, 1);
					my $hosting_password = $model->get_value($hosting_iter, 2);
					my $hosting_module   = $model->get_value($hosting_iter, 4);
					my $hosting_folder   = $model->get_value($hosting_iter, 5);

					$hosting_progress->set_text(sprintf($d->get("Loading module %s"), $hosting_module));
					fct_update_gui();

					#import module
					eval {
						import lib $hosting_folder;
						require "$hosting_module.pm";
					};
					if ($@) {

						#dialogs (main window != parent window)
						my $sd = Shutter::App::SimpleDialogs->new;

						$sd->dlg_error_message(
							sprintf($d->get("Error while executing upload plugin %s."), "'" . $hosting_module . "'"),
							$d->get("There was an error executing the upload plugin."),
							undef, undef, undef, undef, undef, undef, $@
						);
						$hosting_dialog->destroy();
						return FALSE;
					}

					my $uploader = $hosting_module->new($hosting_host, $sc->get_debug, $shutter_root, $d, $window, SHUTTER_VERSION);

					#init module
					if ($uploader->init($hosting_username)) {

						my $counter = 1;
						$hosting_progress->set_fraction(0);
						foreach my $key (sort @files_to_upload) {

							my $file = $session_screens{$key}->{'long'};

							#set text for progressbar
							$hosting_progress->set_text("Uploading $file");
							fct_update_gui();

							#upload file
							my %upload_response = $uploader->upload($shf->switch_home_in_file($file), $hosting_username, $hosting_password);

							if (is_success($upload_response{'status'})) {

								#add to public-links menu
								foreach (keys %upload_response) {
									next if $_ eq 'status';
									$session_screens{$key}->{'links'}->{$hosting_module}->{$_} = $upload_response{$_};
									$session_screens{$key}->{'links'}->{$hosting_module}->{'menuentry'} = $hosting_module;
								}

								$uploader->show;
								fct_show_status_message(1, $file . " " . $d->get("uploaded"));
							} else {
								my $response = dlg_upload_error_message($upload_response{'status'}, $upload_response{'max_filesize'});

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

							#update gui
							fct_update_gui();
							$counter++;
						}

						$uploader->show_all;

					}

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

					#create upload object
					my $uploader = Shutter::Upload::FTP->new($sc->get_debug, $shutter_root, $d, $window, $ftp_mode_combo_dlg->get_active);

					my $counter = 1;
					my $login   = FALSE;
					$hosting_progress->set_fraction(0);

					#start upload
					foreach my $key (sort @files_to_upload) {

						my $file = $session_screens{$key}->{'long'};

						#need to login?
						my @upload_response;
						unless ($login) {

							eval { $uploader->quit; };

							@upload_response = $uploader->login($ftp_remote_entry_dlg->get_text, $ftp_username_entry_dlg->get_text, $ftp_password_entry_dlg->get_text);

							if ($upload_response[0]) {

								#dialogs (main window != parent window)
								my $sd = Shutter::App::SimpleDialogs->new;

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

						}

						$hosting_progress->set_text($file);

						#update gui
						fct_update_gui();
						@upload_response = $uploader->upload($shf->switch_home_in_file($file));

						#upload returns FALSE if there is no error
						unless ($upload_response[0]) {

							#everything is fine here
							fct_show_status_message(1, $file . " " . $d->get("uploaded"));

							#show as notification
							my $notify = $sc->get_notification_object;
							$notify->show($d->get("Successfully uploaded"), sprintf($d->get("The file %s was successfully uploaded."), $file));

							#copy website url to clipboard
							my $uri = $ftp_wurl_entry_dlg->get_text;
							if ($uri) {
								my ($short, $folder, $ext) = fileparse($file, qr/\.[^.]*/);
								if ($uri !~ m|/$|) {
									$uri .= '/';
								}
								$uri .= $short . $ext;
								$clipboard->set_text($uri);
								print "copied URI ", $uri, " to clipboard\n"
									if $sc->get_debug;
							}

						} else {

							#dialogs (main window != parent window)
							my $sd = Shutter::App::SimpleDialogs->new;

							#we already get translated error messaged back
							my $response =
								$sd->dlg_error_message($upload_response[1], $upload_response[0], $d->get("Skip all"), $d->get("Skip"), $d->get("Retry"), undef, undef, undef, $upload_response[2]);

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

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

						#update gui
						fct_update_gui();
						$counter++;
					}    #end foreach

					eval { $uploader->quit; };

					#xfer using Gnome-VFS
				} elsif ($unotebook->get_current_page == 2) {

					my $counter = 1;
					$hosting_progress->set_fraction(0);

					#start upload
					foreach my $key (sort @files_to_upload) {

						my $file = $session_screens{$key}->{'long'};

						$hosting_progress->set_text($file);

						#update gui
						fct_update_gui();

						my $source_giofile = Glib::IO::File::new_for_path($file);

						my $target_giofile = Glib::IO::File::new_for_uri($places_fc->get_uri);
						$target_giofile = $target_giofile->get_child($source_giofile->get_basename);

						#~ print sprintf("%s und %s \n", $target_giofile->to_string, $source_giofile->to_string);

						my $result;
						unless (unescape_string($target_giofile->get_path) eq unescape_string($source_giofile->get_path)) {
							unless ($target_giofile->query_exists) {
								eval {
									$source_giofile->copy($target_giofile, []);
									$result = 'ok';
								};
								if ($@) {
									$result = $@;
								}
							} else {
								$result = 'error-file-exists';
							}
						} else {
							$result = 'ok';
						}

						#everything is fine here
						if ($result eq 'ok') {
							fct_show_status_message(1, $file . " " . $d->get("exported"));

							#show as notification
							my $notify = $sc->get_notification_object;
						} elsif ($result eq 'error-file-exists') {

							#ask the user to replace the image
							#replace button
							my $replace_btn = Gtk3::Button->new_with_mnemonic($d->get("_Replace"));
							$replace_btn->set_image(Gtk3::Image->new_from_stock('gtk-save-as', 'button'));

							my $target_path = $shf->utf8_decode(unescape_string($target_giofile->get_path // $target_giofile->get_uri));

							#dialogs (main window != parent window)
							my $sd = Shutter::App::SimpleDialogs->new;

							my $response = $sd->dlg_warning_message(
								sprintf($d->get("The image already exists in %s. Replacing it will overwrite its contents."), "'" . $target_path . "'"),
								sprintf($d->get("An image named %s already exists. Do you want to replace it?"),              "'" . $shf->utf8_decode($target_giofile->get_basename) . "'"),
								$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) {
								eval {
									$source_giofile->copy($target_giofile, ['overwrite']);
									$result = 'ok';
								};
								if ($@) {
									$result = $@;
								}

								#check result again
								if ($result eq 'ok') {

									fct_show_status_message(1, $file . " " . $d->get("exported"));

									#show as notification
									my $notify = $sc->get_notification_object;
									$notify->show($d->get("Successfully exported"), sprintf($d->get("The file %s was successfully exported."), $file));

								} else {

									my $response = dlg_upload_error_message_gnome_vfs($target_giofile, $result);

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

								}
							}

						} else {

							my $response = dlg_upload_error_message_gnome_vfs($target_giofile, $result);

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

						}

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

						#update gui
						fct_update_gui();
						$counter++;

					}

				}

				#save recently used upload tab
				$sc->set_ruu_tab($unotebook->get_current_page);

				#and the relevant detail (folder, uploader etc.)
				#hosting service
				$sc->set_ruu_hosting($hosting->get_active);
				$sc->set_ruu_places($places_fc->get_filename);

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

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

		}    #dialog loop
	}

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

		#dialogs (main window != parent window)
		my $sd = Shutter::App::SimpleDialogs->new;

		my $target_path = $shf->utf8_decode(unescape_string($target_giofile->get_path // $target_giofile->get_uri));

		#retry button
		my $retry_btn = Gtk3::Button->new_with_mnemonic($d->get("_Retry"));
		$retry_btn->set_image(Gtk3::Image->new_from_stock('gtk-redo', 'button'));

		my $response = $sd->dlg_error_message(
			sprintf($d->get("Error while copying the image %s."),             "'" . $target_giofile->get_basename . "'"),
			sprintf($d->get("There was an error copying the image into %s."), "'" . $target_path . "'"),
			$d->get("Skip all"), $d->get("Skip"), undef, $retry_btn, undef, undef, $result
		);

		return $response;
	}

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

		#dialogs (main window != parent window)
		my $sd = Shutter::App::SimpleDialogs->new;

		my $response;
		if ($status == 999) {
			$response = $sd->dlg_error_message($d->get("Please check your credentials and try again."), $d->get("Error while login"));
		} elsif ($status == 998) {
			$response = $sd->dlg_error_message(
				$d->get("Maximum filesize reached"),
				$d->get("Error while uploading"),
				$d->get("Skip all"), $d->get("Skip"), undef, undef, undef, undef, sprintf($d->get("Maximum filesize: %s"), $max_filesize));
		} else {
			$response = $sd->dlg_error_message($status, $d->get("Error while connecting"), $d->get("Skip all"), $d->get("Skip"), $d->get("Retry"),);
		}
		return $response;
	}

	sub dlg_profile_name {
		my ($curr_profile_name, $combobox_settings_profiles) = @_;

		my $profile_dialog = Gtk3::MessageDialog->new($window, [qw/modal destroy-with-parent/], 'other', 'none', undef);

		$profile_dialog->set_title("Shutter");

		$profile_dialog->set('image' => Gtk3::Image->new_from_stock('gtk-dialog-question', 'dialog'));

		$profile_dialog->set('text' => $d->get("Save current preferences as new profile"));

		$profile_dialog->set('secondary-text' => $d->get("New profile name") . ": ");

		$profile_dialog->add_button('gtk-cancel', 'reject');
		$profile_dialog->add_button('gtk-save',   'accept');

		$profile_dialog->set_default_response('accept');

		my $new_profile_name_vbox = Gtk3::VBox->new();
		my $new_profile_name_hint = Gtk3::Label->new();
		my $new_profile_name      = Gtk3::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 = Gtk3::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($new_profile_name, TRUE, TRUE, 0);
		$new_profile_name_vbox->pack_start($new_profile_name_hint, TRUE, TRUE, 0);
		$profile_dialog->get_child->add($new_profile_name_vbox);
		$profile_dialog->show_all;

		#run dialog
		my $profile_response = $profile_dialog->run;

		#handle user responses here
		if ($profile_response eq 'accept') {
			my $entered_name = $new_profile_name->get_text;

			if ($shf->file_exists("$ENV{'HOME'}/.shutter/profiles/$entered_name.xml")) {

				#ask the user to replace the profile
				#replace button
				my $replace_btn = Gtk3::Button->new_with_mnemonic($d->get("_Replace"));
				$replace_btn->set_image(Gtk3::Image->new_from_stock('gtk-save-as', 'button'));

				my $response = $sd->dlg_warning_message(
					$d->get("Replacing it will overwrite its contents."),
					sprintf($d->get("A profile named %s already exists. Do you want to replace it?"), "'" . $entered_name . "'"),
					undef, undef, undef, $replace_btn, undef, undef
				);

				#40 == replace_btn was hit
				if ($response != 40) {
					$profile_dialog->destroy();
					return FALSE;
				}
			}

			$profile_dialog->destroy();
			return $entered_name;
		} else {
			$profile_dialog->destroy();
			return FALSE;
		}
	}

	sub fct_zoom_in {
		my $key = fct_get_current_file();
		if ($key) {
			$session_screens{$key}->{'image'}->zoom_in;
		}
	}

	sub fct_zoom_out {
		my $key = fct_get_current_file();
		if ($key) {
			$session_screens{$key}->{'image'}->zoom_out;
		}
	}

	sub fct_zoom_100 {
		my $key = fct_get_current_file();
		if ($key) {
			$session_screens{$key}->{'image'}->set_zoom(1);
		}
	}

	sub fct_zoom_best {
		my $key = fct_get_current_file();
		if ($key) {
			$session_screens{$key}->{'image'}->set_fitting(TRUE);
		}
	}

	sub fct_fullscreen {
		my ($widget) = @_;

		if ($widget->get_active) {
			$window->fullscreen;
		} else {
			$window->unfullscreen;
		}
	}

	sub fct_navigation_toolbar {
		my ($widget) = @_;

		if ($widget->get_active) {
			$nav_toolbar->show;
			foreach my $child ($nav_toolbar->get_children) {
				$child->show_all;
			}
		} else {
			$nav_toolbar->hide;
			foreach my $child ($nav_toolbar->get_children) {
				$child->hide_all;
			}
		}
	}

	#--------------------------------------
}

package main;

my $app = Shutter::App->new(
	application_id=>'org.shutter-project.Shutter',
	flags=>['flags-none']);

$app->run;
if ($app->get_is_remote) {
	#The application is already running, send it a message

	my ($cmdname, $extra) = $sc->get_start_with;
	my $profile        = $sc->get_profile_to_start_with;
	my $exitac         = $sc->get_exit_after_capture;
	my $exfilename     = $sc->get_export_filename;
	my $delay          = $sc->get_delay;
	my $include_cursor = $sc->get_include_cursor;
	my $remove_cursor  = $sc->get_remove_cursor;
	my $nosession      = $sc->get_no_session;

	#change profile in running application
	if (defined $profile && $profile) {
		$app->activate_action('profile', Glib::Variant->new_string($profile));
	}

	#set exit flag in running application
	if (defined $exitac && $exitac) {
		$app->activate_action('exitac', Glib::Variant->new(''));
	}

	#set export_filename (parameter -o) in running application
	if (defined $exfilename && $exfilename) {
		$app->activate_action('exfilename', Glib::Variant->new_string($shf->utf8_decode($exfilename)));
	}

	#change delay in running application
	if (defined $delay && $delay) {
		$app->activate_action('delay', Glib::Variant->new_string($delay));
	}

	#change include_cursor in running application
	if (defined $include_cursor && $include_cursor) {
		$app->activate_action('include_cursor', Glib::Variant->new(''));
	}

	#change remove_cursor in running application
	if (defined $remove_cursor && $remove_cursor) {
		$app->activate_action('remove_cursor', Glib::Variant->new(''));
	}

	#set nosession flag in running application
	if (defined $nosession && $nosession) {
		$app->activate_action('nosession', Glib::Variant->new(''));
	}

	my %screenshot_cmds = (
		select => 1,
		full => 1,
		window => 1,
		awindow => 1,
		# No sections for now: https://github.com/shutter-project/shutter/issues/25
		#section => 1,
		menu => 1,
		tooltip => 1,
		web => 1,
		redoshot => 1,
	);
	if (defined $cmdname && $screenshot_cmds{$cmdname} && defined $extra) {
		$app->activate_action($cmdname, Glib::Variant->new_string($extra));
	} elsif (defined $cmdname && $screenshot_cmds{$cmdname}) {
		$app->activate_action($cmdname, Glib::Variant->new(''));
	} elsif (@init_files) {

		my @variants;
		foreach my $uri (@init_files) {
			push @variants, Glib::Variant->new_string($uri);
		}
		$app->activate_action('fopen', Glib::Variant->new_array(undef, \@variants));
	} else {
		$app->activate_action('showmainwindow', Glib::Variant->new(''));
	}

	print "\nINFO: There is already another instance of Shutter running!\n";
}

__END__

=head1 NAME

Shutter - Feature-rich Screenshot Tool

=head1 SYNOPSIS

shutter [options]

=head1 COPYRIGHT

Shutter is Copyright (C) by Mario Kemper and Shutter Team

=head1 DESCRIPTION

B<Shutter> is a feature-rich screenshot program. You can take a screenshot of a specific area, window, your whole screen, or even of a website - apply different effects to it, draw on it to highlight points, and then upload to an image hosting site, all within one window.

=head1 OPTIONS

=over 8

=item Example 1

shutter -a -p=myprofile --min_at_startup

=item Example 2

shutter -s=100,100,300,300 -e

=item Example 3

shutter --window=.*firefox.*

=item Example 4

shutter --web=http://shutter-project.org/ -e

=back

=head2 CAPTURE MODE OPTIONS

=over 8

=item B<-s, --select=[X,Y,WIDTH,HEIGHT]>

Capture an area of the screen. Providing X,Y,WIDTH,HEIGHT is optional.

=item B<-f, --full>

Capture the entire screen.

=item B<-w, --window=[NAME_PATTERN]>

Select a window to capture. Providing a NAME_PATTERN (Perl-style regex) ist optional.

=item B<-a, --active>

Capture the current active window.

=item B<-m, --menu>

Capture a menu.

=item B<-t, --tooltip>

Capture a tooltip.

=item B<--web=[URL]>

Capture a webpage. Providing an URL ist optional.

=item B<-r, --redo>

Redo last screenshot.

=back

=head2 SETTINGS OPTIONS

=over 8

=item B<-p, --profile=NAME>

Load a specific profile on startup.

=item B<-o, --output=FILENAME>

Specify a filename to save the screenshot to (overwrites any profile-related setting).

B<Supported image formats:> You can save to any popular image format (e.g. jpeg, png, gif, bmp). Additionally it is possible to save to pdf, ps or svg.

B<Please note:> There are several wildcards available, like

 %Y = year
 %m = month
 %d = day
 %T = time
 $w = width
 $h = height
 $name = multi-purpose (e.g. window title)
 $nb_name = like $name but without blanks in resulting strings
 $profile = name of current profile
 $R = random char (e.g. $RRRR = ag4r)
 %NN = counter

The string is interpretted by strftime. See C<man strftime> for more examples.

B<As an example:> shutter -f -e -o './%y-%m-%d_$w_$h.png' would create a file named '11-10-28_1280_800.png' in the current directory.

=item B<-d, --delay=SECONDS>

Wait n seconds before taking a screenshot.

=item B<-c, --include_cursor>

Include cursor when taking a screenshot.

=item B<-C, --remove_cursor>

Remove cursor when taking a screenshot.

=back

=head2 APPLICATION OPTIONS

=over 8

=item B<-h, --help>

Prints a brief help message and exits.

=item B<-v, --version>

Prints version information.

=item B<--debug>

Prints a lot of debugging information to STDOUT.

=item B<--clear_cache>

Clears cache, e.g. installed plugins, at startup.

=item B<--min_at_startup>

Starts Shutter minimized to tray.

=item B<--disable_systray>

Disables systray icon.

=item B<-e, --exit_after_capture>

Exit after the first capture has been made. This is useful when using Shutter in scripts.

=item B<-n, --no_session>

Do not add the screenshot to the session. This is useful when using Shutter in scripts.

=back

=head1 BUG REPORTS

If you find a bug in Shutter, you should report it.  But first, you should make sure that it really is a bug, and that it appears in the latest version of Shutter.

The latest version is always available from:
B<https://github.com/shutter-project/shutter/releases>

Once you have determined that a bug actually exists, please report it at github:
B<https://github.com/shutter-project/shutter/issues/new>

=cut
