~ubuntu-branches/ubuntu/trusty/shutter/trusty

« back to all changes in this revision

Viewing changes to share/shutter/resources/system/plugins/perl/sppolaroid/sppolaroid

  • Committer: Bazaar Package Importer
  • Author(s): Ryan Niebur
  • Date: 2009-08-06 16:29:32 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806162932-g00c3k4obbdddb4u
Tags: 0.80.1-1
* New Upstream Version
  - update copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /usr/bin/perl
 
1
#! /usr/bin/env perl
2
2
 
3
3
###################################################
4
4
#
5
 
#  Copyright (C) Mario Kemper <mario.kemper@googlemail.com> and Shutter Team
 
5
#  Copyright (C) 2008, 2009 Mario Kemper <mario.kemper@googlemail.com> and Shutter Team
6
6
#
7
7
#  This file is part of Shutter.
8
8
#
27
27
use warnings;
28
28
use Gtk2 '-init';
29
29
use Image::Magick;
30
 
use POSIX qw/setlocale/;
 
30
use POSIX qw/setlocale strftime/;
31
31
use Locale::gettext;
32
32
use Glib qw/TRUE FALSE/;
33
33
use FindBin '$Bin';    #path where plugin is located
34
34
use File::Temp qw/ tempfile tempdir /;
 
35
use Time::HiRes qw/usleep/;
 
36
 
 
37
#load modules at custom path at runtime
 
38
#--------------------------------------
 
39
require lib;
 
40
import lib $ENV{'SHUTTER_ROOT'}."/share/shutter/resources/modules";
 
41
 
 
42
#proc (Thanks to Michael Schilli)
 
43
require Proc::Simple;
 
44
 
 
45
#load shutter's modules
 
46
#--------------------------------------
 
47
require Shutter::App::SimpleDialogs;
35
48
 
36
49
#configure gettext using ENV Variable (setup during shutter start)
37
50
setlocale( LC_MESSAGES, "" );
38
51
my $d = Locale::gettext->domain("shutter-plugins");
39
52
$d->dir( $ENV{'SHUTTER_INTL'} );
40
53
 
 
54
#shutter will ask for some infos
 
55
my %plugin_info =       (       'name'  => $d->get( "polaroid" ),
 
56
                                                'sort'  => $d->get( "effect" ),
 
57
                                                'tip'   => $d->get("make your screenshot look like a polaroid photo, add a caption, and even rotate it a little"),
 
58
                                        );
 
59
 
41
60
binmode( STDOUT, ":utf8" );
42
 
#gscrot will ask for some infos - no need of changing anything
43
 
if ( $ARGV[ 0 ] eq "name" ) {
44
 
        print $d->get( "polaroid" );
45
 
        exit;
46
 
} elsif ( $ARGV[ 0 ] eq "sort" ) {
47
 
        print $d->get( "effect" );
48
 
        exit;
49
 
} elsif ( $ARGV[ 0 ] eq "tip" ) {
50
 
        print $d->get(
51
 
                "make your screenshot look like a polaroid photo, add a caption, and even rotate it a little"
52
 
        );
53
 
        exit;
54
 
} elsif ( $ARGV[ 0 ] eq "ext" ) {
55
 
        print "image/png";
56
 
        exit;
57
 
} elsif ( $ARGV[ 0 ] eq "lang" ) {
58
 
        print "perl";
 
61
if ( exists $plugin_info{$ARGV[ 0 ]} ) {
 
62
        print $plugin_info{$ARGV[ 0 ]};
59
63
        exit;
60
64
}
61
65
 
66
70
my $height    = $ARGV[ 3 ];
67
71
my $filetype  = $ARGV[ 4 ];
68
72
 
 
73
#decode filename
 
74
utf8::decode $filename;
 
75
 
69
76
#check convert command
70
77
my $use_caption = FALSE;
71
78
if ( `convert --help | grep caption` =~ /caption/ ) {
73
80
}
74
81
 
75
82
my $plug = Gtk2::Plug->new( $socket_id );
 
83
eval{
 
84
        $plug->set_default_icon_from_file( $ENV{'SHUTTER_ICON'} );
 
85
};
76
86
$plug->set_border_width( 10 );
77
87
 
78
88
$plug->signal_connect( destroy => sub { Gtk2->main_quit } );
79
89
 
80
 
#variables used in this plugin
81
 
my $width_preview  = 0;
82
 
my $height_preview = 0;
 
90
#tooltips
 
91
my $tooltips = Gtk2::Tooltips->new;
83
92
 
84
93
#configure buttons and other needed controls
85
 
my $caption_frame = Gtk2::Frame->new( $d->get( "Caption:" ) );
86
 
 
87
94
my $caption_label = Gtk2::Label->new( $d->get( "Text:" ) );
88
95
my $caption_entry = Gtk2::Entry->new();
89
 
$caption_entry->set_text( "$ENV{ 'USER' }" );
 
96
$caption_entry->set_text( "%c - $filename" );
 
97
 
 
98
$tooltips->set_tip(
 
99
        $caption_label,
 
100
        $d->get(
 
101
                "There are several wild-cards available, like\n%Y = year\n%m = month\n%d = day\n%T = time"
 
102
        )
 
103
);
 
104
$tooltips->set_tip(
 
105
        $caption_entry,
 
106
        $d->get(
 
107
                "There are several wild-cards available, like\n%Y = year\n%m = month\n%d = day\n%T = time"
 
108
        )
 
109
);
90
110
 
91
111
my $pointsize_label = Gtk2::Label->new( $d->get( "Font size:" ) );
92
112
my $pointsize_sbutton = Gtk2::SpinButton->new_with_range( 1, 200, 1 );
93
 
$pointsize_sbutton->set_value( 40 );
 
113
$pointsize_sbutton->set_value( 20 );
94
114
 
95
115
my $gravity_label = Gtk2::Label->new( $d->get( "Gravity:" ) );
96
116
my $gravity_combo = Gtk2::ComboBox->new_text;
109
129
my $angle_sbutton = Gtk2::SpinButton->new_with_range( -90, 90, 1 );
110
130
$angle_sbutton->set_value( -5 );
111
131
 
 
132
my $stroke_color_label = Gtk2::Label->new( $d->get("Stroke color"). ":" );
 
133
my $stroke_color = Gtk2::ColorButton->new();
 
134
$stroke_color->set_color( Gtk2::Gdk::Color->parse('black') );
 
135
$stroke_color->set_alpha( int( 1.0 * 65535 ) );
 
136
$stroke_color->set_use_alpha(TRUE);
 
137
$stroke_color->set_title( $d->get("Choose stroke color") );
 
138
 
 
139
#we define two Gtk2::Image widgets
 
140
#to store the screenshot
 
141
#and a throbber that is shown while the changes are processed
 
142
my $preview =
 
143
        Gtk2::Image->new_from_pixbuf(
 
144
           Gtk2::Gdk::Pixbuf->new_from_file_at_scale( $filename, 300, 300, TRUE ) );
 
145
 
 
146
my $preview_throb =
 
147
        Gtk2::Image->new_from_file( $ENV{'SHUTTER_ROOT'}."/share/shutter/resources/icons/throbber.gif" );
 
148
 
 
149
my $sg = Gtk2::SizeGroup->new ('both');
 
150
$sg->set ('ignore-hidden' => FALSE);
 
151
$sg->add_widget($preview);
 
152
$sg->add_widget($preview_throb);
 
153
 
 
154
 
 
155
#we define three Gtk2::Button widgets
 
156
#to refresh, save and cancel the plugin's work
112
157
my $refresh_btn = Gtk2::Button->new_from_stock( 'gtk-refresh' );
113
158
$refresh_btn->signal_connect( 'clicked', \&fct_imagemagick_polaroid,
114
159
                                                          'refresh' );
115
160
 
116
 
my $preview =
117
 
        Gtk2::Image->new_from_pixbuf(
118
 
           Gtk2::Gdk::Pixbuf->new_from_file_at_scale( $filename, 300, 300, TRUE ) );
119
 
 
120
 
 
121
161
my $save_btn = Gtk2::Button->new_from_stock( 'gtk-save' );
122
162
$save_btn->signal_connect( 'clicked', \&fct_imagemagick_polaroid, 'save' );
123
163
 
124
164
my $cancel_btn = Gtk2::Button->new_from_stock( 'gtk-cancel' );
125
 
$cancel_btn->signal_connect( 'clicked' => sub { Gtk2->main_quit }, 'cancel' );
 
165
$cancel_btn->signal_connect( 'clicked' => sub { Gtk2->main_quit; exit 2; }, 'cancel' );
126
166
 
127
167
#define the gui layout
128
168
my $vbox_param = Gtk2::VBox->new( TRUE,  10 );
130
170
my $hbox2      = Gtk2::HBox->new( FALSE, 10 );
131
171
my $hbox3      = Gtk2::HBox->new( FALSE, 10 );
132
172
my $hbox4      = Gtk2::HBox->new( FALSE, 10 );
 
173
my $hbox5      = Gtk2::HBox->new( FALSE, 10 );
133
174
 
134
175
my $hbox_row1 = Gtk2::HBox->new( TRUE, 10 );
135
176
my $hbox_row2 = Gtk2::HBox->new( TRUE, 10 );
152
193
        $hbox4->pack_start( $angle_label,   FALSE, TRUE, 5 );
153
194
        $hbox4->pack_start( $angle_sbutton, TRUE,  TRUE, 5 );
154
195
 
 
196
        $hbox5->pack_start( $stroke_color_label, FALSE, TRUE, 5 );
 
197
        $hbox5->pack_start( $stroke_color, FALSE, TRUE, 5 );
 
198
 
155
199
        $hbox_row1->pack_start_defaults( $hbox1 );
156
200
        $hbox_row1->pack_start_defaults( $hbox2 );
157
201
 
158
202
        $hbox_row2->pack_start_defaults( $hbox3 );
159
203
        $hbox_row2->pack_start_defaults( $hbox4 );
 
204
        $hbox_row2->pack_start_defaults( $hbox5 );
160
205
 
161
206
        $vbox_param->pack_start( $hbox_row1, TRUE, TRUE, 5 );
162
207
 
172
217
 
173
218
$vbox_main->pack_start( $vbox_param, FALSE, TRUE, 5 );
174
219
 
175
 
$vbox_main->pack_start( $preview,     TRUE, TRUE, 5 );
 
220
$vbox_main->pack_start( $preview, TRUE, TRUE, 5 );
 
221
$vbox_main->pack_start( $preview_throb, TRUE, TRUE, 5 );
176
222
$vbox_main->pack_start( $refresh_btn, TRUE, TRUE, 5 );
177
223
 
178
224
$hbox_btn->pack_start( $cancel_btn, TRUE, TRUE, 5 );
183
229
 
184
230
$plug->show_all;
185
231
 
186
 
#generate first preview
187
 
&fct_imagemagick_polaroid( undef, 'refresh' );
 
232
#hide the preview widget at startup 
 
233
$preview->hide_all;
 
234
 
 
235
#create tempfile
 
236
my ( $tmpfh, $tmpfilename ) = tempfile();
 
237
#png format
 
238
$tmpfilename .= ".png";
 
239
 
 
240
#we fork a child process to do the work
 
241
my $process = Proc::Simple->new;
 
242
#create tempfiles for subprocess outputs
 
243
my ( $tmpfh_stdout, $tmpfilename_stdout ) = tempfile(UNLINK => 1);
 
244
my ( $tmpfh_stderr, $tmpfilename_sterr ) = tempfile(UNLINK => 1);
 
245
$process->redirect_output ($tmpfilename_stdout, $tmpfilename_sterr);
 
246
 
 
247
#generate first preview at startup
 
248
Glib::Idle->add (
 
249
        sub{
 
250
                &fct_imagemagick_polaroid( undef, 'refresh' );
 
251
                return FALSE;   
 
252
        }, 
 
253
undef);
188
254
 
189
255
#lets'start
190
256
Gtk2->main;
195
261
sub fct_imagemagick_polaroid {
196
262
        my ( $widget, $data ) = @_;
197
263
 
198
 
        my $image = Image::Magick->new;
 
264
        $save_btn->set_sensitive(FALSE);
199
265
 
200
266
        if ( $data eq 'save' ) {
201
267
 
202
 
                my ( $tmpfh, $tmpfilename ) = tempfile();
203
 
                my $convert_output = undef;
204
 
                if ( $use_caption ) {
205
 
                        $convert_output =
206
 
                                system(   "convert -caption '"
207
 
                                                . $caption_entry->get_text
208
 
                                                . "' '$filename' -pointsize "
209
 
                                                . $pointsize_sbutton->get_value
210
 
                                                . " -gravity "
211
 
                                                . $gravity_combo->get_active_text
212
 
                                                . "  -bordercolor snow "
213
 
                                                . " -background black "
214
 
                                                . " -polaroid "
215
 
                                                . $angle_sbutton->get_value
216
 
                                                . " $tmpfilename" );
217
 
                } else {
218
 
                        $convert_output = system( "
219
 
                                  convert '$filename' -bordercolor white -border 6 -bordercolor grey60 -border 1 -background none -rotate "
220
 
                                        . $angle_sbutton->get_value
221
 
                                        . " -background  black  \\( +clone -shadow 60x4+4+4 \\) +swap -background none -flatten $tmpfilename"
222
 
                        );
223
 
                }
 
268
                my $image = Image::Magick->new;
224
269
                $image->ReadImage( $tmpfilename );
225
270
                $image->WriteImage( filename => $filename );
226
271
 
 
272
                #delete temp files
 
273
                unlink $tmpfilename;
 
274
 
227
275
                Gtk2->main_quit;
228
276
                return TRUE;
229
277
        } else {
230
278
 
231
 
                my ( $tmpfh, $tmpfilename ) = tempfile();
232
 
                my $convert_output = undef;
233
 
                if ( $use_caption ) {
234
 
                        $convert_output =
235
 
                                system(   "convert -caption '"
236
 
                                                . $caption_entry->get_text
237
 
                                                . "' '$filename' -pointsize "
238
 
                                                . $pointsize_sbutton->get_value
239
 
                                                . " -gravity "
240
 
                                                . $gravity_combo->get_active_text
241
 
                                                . "  -bordercolor snow "
242
 
                                                . " -background black "
243
 
                                                . " -polaroid "
244
 
                                                . $angle_sbutton->get_value
245
 
                                                . " $tmpfilename" );
246
 
                } else {
247
 
                        $convert_output = system( "
248
 
                                  convert '$filename' -bordercolor white -border 6 -bordercolor grey60 -border 1 -background none -rotate "
249
 
                                        . $angle_sbutton->get_value
250
 
                                        . " -background  black  \\( +clone -shadow 60x4+4+4 \\) +swap -background none -flatten $tmpfilename"
 
279
                $preview->hide_all;
 
280
                $preview_throb->show_all;
 
281
 
 
282
                $process->start(
 
283
                        sub {
 
284
                                &apply_effect();
 
285
                                POSIX::_exit(0);
 
286
                        }
 
287
                );
 
288
 
 
289
                #so we can update the gui
 
290
                while ( $process->poll ) {
 
291
                        &fct_update_gui;
 
292
                        usleep 100000;
 
293
                }
 
294
        
 
295
                eval{
 
296
                        $preview->set_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file_at_scale(
 
297
                                                                                $tmpfilename, 300, 300, TRUE)
 
298
                                                                         );
 
299
                };
 
300
                #error -> read output from tempfiles
 
301
                if($@){         
 
302
                        #store error here
 
303
                        my $error_string = "Plugin error:\n";
 
304
                        
 
305
                        #reading stdout from file
 
306
                        while (<$tmpfh_stdout>){
 
307
                                $error_string .= $_;    
 
308
                        }
 
309
                        #reading stderr from file
 
310
                        while (<$tmpfh_stderr>){
 
311
                                $error_string .= $_;    
 
312
                        }
 
313
                        
 
314
                        #get the parent window of the plug
 
315
                        require X11::Protocol;
 
316
                        my $x11 = X11::Protocol->new( $ENV{ 'DISPLAY' } );
 
317
                        
 
318
                        my $plugp = Gtk2::Gdk::Window->foreign_new( &find_wm_window( $x11, $plug->get_id ));
 
319
                        
 
320
                        #show error message
 
321
                        my $shutter_dialog = Shutter::App::SimpleDialogs->new($plug, $plugp);
 
322
                        $shutter_dialog->dlg_error_message( 
 
323
                                sprintf ( $d->get(  "Error while executing plugin %s." ), "'" . $plugin_info{'name'} . "'" ) ,
 
324
                                $d->get( "There was an error executing the plugin." ),
 
325
                                undef, undef, undef,
 
326
                                undef, undef, undef,
 
327
                                $error_string
251
328
                        );
 
329
                        
 
330
                        #delete temp files
 
331
                        unlink $tmpfilename;
 
332
 
 
333
                        Gtk2->main_quit;
 
334
                        exit 1; 
252
335
                }
253
 
                $preview->set_from_pixbuf(
254
 
                                                                   Gtk2::Gdk::Pixbuf->new_from_file_at_scale(
255
 
                                                                                                        $tmpfilename, 300, 300, TRUE
256
 
                                                                                                                                                        )
257
 
                                                                 );
 
336
 
 
337
                $save_btn->set_sensitive(TRUE);
 
338
                $preview->show_all;
 
339
                $preview_throb->hide_all;
258
340
 
259
341
                return TRUE;
260
342
        }
261
343
}
262
 
####define your functions here
 
344
 
 
345
sub apply_effect {
 
346
 
 
347
        my $convert_output = undef;
 
348
        if ( $use_caption ) {
 
349
 
 
350
                my $text = $caption_entry->get_text;
 
351
                utf8::decode $text;
 
352
                $text = strftime $text, localtime;
 
353
                $text = quotemeta $text;
 
354
 
 
355
                my $color = $stroke_color->get_color;
 
356
                        
 
357
                system(   "convert -caption "
 
358
                                . $text
 
359
                                . " -fill '"
 
360
                                . sprintf( "#%04x%04x%04x%04x", $color->red, $color->green, $color->blue, $stroke_color->get_alpha )
 
361
                                . "' '$filename' -pointsize "
 
362
                                . $pointsize_sbutton->get_value
 
363
                                . " -gravity "
 
364
                                . $gravity_combo->get_active_text
 
365
                                . "  -bordercolor snow "
 
366
                                . " -background black "
 
367
                                . " -polaroid "
 
368
                                . $angle_sbutton->get_value
 
369
                                . " $tmpfilename" );
 
370
                                
 
371
        } else {
 
372
                
 
373
                system( "
 
374
                          convert '$filename' -bordercolor white -border 6 -bordercolor grey60 -border 1 -background none -rotate "
 
375
                                . $angle_sbutton->get_value
 
376
                                . " -background  black  \\( +clone -shadow 60x4+4+4 \\) +swap -background none -flatten $tmpfilename"
 
377
                );
 
378
        
 
379
        }
 
380
 
 
381
}
 
382
 
 
383
sub fct_update_gui {
 
384
 
 
385
        while ( Gtk2->events_pending ) {
 
386
                Gtk2->main_iteration;
 
387
        }
 
388
        Gtk2::Gdk->flush;
 
389
 
 
390
        return TRUE;
 
391
}
 
392
 
 
393
sub find_wm_window {
 
394
        my $x11  = shift;
 
395
        my $xid  = shift;
 
396
 
 
397
        do {
 
398
                my ( $qroot, $qparent, @qkids ) = $x11->QueryTree($xid);
 
399
                return undef unless ( $qroot || $qparent );
 
400
                return $xid if ( $qroot == $qparent );
 
401
                $xid = $qparent;
 
402
        } while (TRUE);
 
403
}
263
404
 
264
405
1;
265
406