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

« back to all changes in this revision

Viewing changes to share/shutter/resources/modules/Shutter/Draw/DrawingTool.pm

  • 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
1
###################################################
2
2
#
3
 
#  Copyright (C) Mario Kemper <mario.kemper@googlemail.com> and Shutter Team
 
3
#  Copyright (C) 2008, 2009 Mario Kemper <mario.kemper@googlemail.com> and Shutter Team
4
4
#
5
5
#  This file is part of Shutter.
6
6
#
24
24
 
25
25
#modules
26
26
#--------------------------------------
 
27
use SelfLoader;
 
28
 
27
29
use utf8;
28
30
use strict;
 
31
use warnings;
 
32
 
 
33
use Gtk2;
 
34
 
29
35
use Exporter;
30
36
use Goo::Canvas;
31
 
use File::Basename;
 
37
use File::Basename qw / fileparse dirname /;
 
38
use File::Glob qw/ glob /;
32
39
use Data::Dumper;
33
40
 
 
41
#Sort::Naturally - sort lexically, but sort numeral parts numerically
 
42
use Sort::Naturally;
 
43
 
34
44
#load and save settings
35
45
use XML::Simple;
36
46
 
48
58
 
49
59
        my $self = { _shutter_common => shift };
50
60
 
 
61
        #FIXME
 
62
        #get them as params 
 
63
        #because there is a leak when 
 
64
        #we declare them each time      
 
65
        $self->{_view}                  = shift;
 
66
        $self->{_selector}              = shift;
 
67
        $self->{_dragger}               = shift;
 
68
 
 
69
        #WORKAROUND
 
70
        #upstream bug
 
71
        #http://trac.bjourne.webfactional.com/ticket/21                                         
 
72
        #left  => zoom in
 
73
        #right => zoom out
 
74
        $self->{_view}->signal_connect('scroll-event', sub{
 
75
                my ($view, $ev) = @_;           
 
76
                if($ev->direction eq 'left'){
 
77
                        $ev->direction('up');
 
78
                }elsif($ev->direction eq 'right'){
 
79
                        $ev->direction('down');
 
80
                }
 
81
                return FALSE;
 
82
        });
 
83
 
51
84
        #file
52
 
        $self->{_filename}    = undef;
53
 
        $self->{_filetype}    = undef;
54
 
        $self->{_import_hash} = undef;
 
85
        $self->{_filename}      = undef;
 
86
        $self->{_filetype}      = undef;
 
87
        $self->{_import_hash}   = undef;
 
88
        
 
89
        #custom cursors
 
90
        $self->{_cursors}               = undef;
55
91
 
56
92
        #ui
57
 
        $self->{_uimanager} = undef;
58
 
        $self->{_factory}   = undef;
 
93
        $self->{_uimanager}     = undef;
 
94
        $self->{_factory}               = undef;
59
95
 
60
96
        #canvas
61
 
        $self->{_canvas}     = undef;
 
97
        $self->{_canvas}        = undef;
62
98
        
63
99
        #all items are stored here
64
 
        $self->{_items} = undef;
 
100
        $self->{_uid}           = time;
 
101
        $self->{_items}                 = undef;
65
102
        $self->{_items_history} = undef;
66
103
        
67
104
        #undo and redo stacks
68
 
        $self->{_undo}      = undef;
69
 
        $self->{_redo}      = undef;
 
105
        $self->{_undo}          = undef;
 
106
        $self->{_redo}          = undef;
70
107
        
71
108
        #autoscroll option, disabled by default
72
109
        $self->{_autoscroll} = FALSE;
73
110
 
74
 
        #drawing colors
 
111
        #drawing colors and line width
 
112
        #general - shown in the bottom hbox
75
113
        $self->{_fill_color}         = Gtk2::Gdk::Color->parse('#0000ff');
76
114
        $self->{_fill_color_alpha}   = 0.25;
77
115
        $self->{_stroke_color}       = Gtk2::Gdk::Color->parse('#000000');
78
116
        $self->{_stroke_color_alpha} = 1;
79
 
 
80
 
        #line_width
81
 
        $self->{_line_width} = 3;
82
 
 
83
 
        #font
84
 
        $self->{_font} = 'Sans Italic 16';
85
 
 
86
 
        #some globals
87
 
        $self->{_last_item}               = undef;
 
117
        $self->{_line_width}             = 3;
 
118
        $self->{_font}                           = 'Sans Italic 16';
 
119
 
 
120
        #obtain current colors and font_desc from the main window
 
121
    $self->{_style}              = $self->{_shutter_common}->get_mainwindow->get_style;
 
122
        $self->{_style_bg}               = $self->{_style}->bg('selected');
 
123
        $self->{_style_tx}           = $self->{_style}->text('selected');
 
124
 
 
125
        #remember drawing colors, line width and font settings
 
126
        #maybe we have to restore them
 
127
        $self->{_last_fill_color}         = Gtk2::Gdk::Color->parse('#0000ff');
 
128
        $self->{_last_fill_color_alpha}   = 0.25;
 
129
        $self->{_last_stroke_color}       = Gtk2::Gdk::Color->parse('#000000');
 
130
        $self->{_last_stroke_color_alpha} = 1;
 
131
        $self->{_last_line_width}                 = 3;
 
132
        $self->{_last_font}                       = 'Sans Italic 16';
 
133
 
 
134
        #some status variables
 
135
        $self->{_busy}                    = undef;
 
136
        $self->{_last_item}               = undef;
88
137
        $self->{_current_item}            = undef;
89
138
        $self->{_current_new_item}        = undef;
90
139
        $self->{_current_copy_item}       = undef;
 
140
        $self->{_last_mode}               = undef;
91
141
        $self->{_current_mode}            = 10;
92
142
        $self->{_current_mode_descr}      = "select";
 
143
        $self->{_last_mode_descr}         = undef;
93
144
        $self->{_current_pixbuf}          = undef;
94
145
        $self->{_current_pixbuf_filename} = undef;
95
146
        $self->{_cut}                                     = FALSE;
96
 
 
 
147
        
97
148
        $self->{_start_time} = undef;
98
149
 
99
150
        bless $self, $class;
101
152
        return $self;
102
153
}
103
154
 
 
155
#~ sub DESTROY {
 
156
    #~ my $self = shift;
 
157
    #~ print "$self dying at\n";
 
158
#~ } 
 
159
 
 
160
1;
 
161
 
 
162
__DATA__
 
163
 
104
164
sub show {
105
 
        my $self        = shift;
106
 
        my $filename    = shift;
107
 
        my $filetype    = shift;
108
 
        my $import_hash = shift;
109
 
 
110
 
        $self->{_filename}    = $filename;
111
 
        $self->{_filetype}    = $filetype;
112
 
        $self->{_import_hash} = $import_hash;
113
 
 
114
 
        my $d = $self->{_shutter_common}->get_gettext;
115
 
 
116
 
        #root window
 
165
        my $self                  = shift;
 
166
 
 
167
        $self->{_filename}    = shift;
 
168
        $self->{_filetype}    = shift;
 
169
        $self->{_import_hash} = shift;
 
170
 
 
171
        #gettext
 
172
        $self->{_d} = $self->{_shutter_common}->get_gettext;
 
173
        
 
174
        #define own icons
 
175
        $self->{_dicons} = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool";
 
176
        $self->{_icons} = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons";
 
177
 
 
178
        #MAIN WINDOW
 
179
        #-------------------------------------------------
117
180
        $self->{_root} = Gtk2::Gdk->get_default_root_window;
118
181
        ( $self->{_root}->{x}, $self->{_root}->{y}, $self->{_root}->{w}, $self->{_root}->{h} ) = $self->{_root}->get_geometry;
119
182
        ( $self->{_root}->{x}, $self->{_root}->{y} ) = $self->{_root}->get_origin;
120
183
 
121
184
        $self->{_drawing_window} = Gtk2::Window->new('toplevel');
122
 
        $self->{_drawing_window}->set_title( "shutter DrawingTool - " . $self->{_filename} );
 
185
        $self->{_drawing_window}->set_title( "Shutter DrawingTool - " . $self->{_filename} );
123
186
        $self->{_drawing_window}->set_position('center');
124
 
        $self->{_drawing_window}->set_modal(0);
 
187
        $self->{_drawing_window}->set_modal(1);
125
188
        $self->{_drawing_window}->signal_connect( 'delete_event', sub { return $self->quit(TRUE) } );
126
189
 
127
190
        #adjust toplevel window size
135
198
        $self->{_dialogs} = Shutter::App::SimpleDialogs->new( $self->{_drawing_window} );
136
199
        $self->{_thumbs}  = Shutter::Pixbuf::Thumbnail->new( $self->{_shutter_common} );
137
200
 
 
201
        #setup cursor-hash
 
202
        #
 
203
        #cursors borrowed from inkscape
 
204
        #http://www.inkscape.org
 
205
        my @cursors = glob($self->{_dicons}."/cursor/*");
 
206
        foreach my $cursor_path (@cursors){
 
207
                my ( $cname, $folder, $type ) = fileparse( $cursor_path, '\..*' );
 
208
                $self->{_cursors}{$cname} = Gtk2::Gdk::Pixbuf->new_from_file($cursor_path);
 
209
                #see 'man xcursor' for a detailed description
 
210
                #of these values
 
211
                $self->{_cursors}{$cname}{'x_hot'} = $self->{_cursors}{$cname}->get_option('x_hot');
 
212
                $self->{_cursors}{$cname}{'y_hot'} = $self->{_cursors}{$cname}->get_option('y_hot');
 
213
        }
 
214
        
 
215
        #setu ui
138
216
        $self->{_uimanager} = $self->setup_uimanager();
139
217
 
140
218
        #load settings
146
224
        };
147
225
        if($@){
148
226
                my $response = $self->{_dialogs}->dlg_error_message( 
149
 
                        sprintf( $d->get("Error while opening image %s."), "'" . $filename . "'"),
150
 
                        $d->get( "There was an error opening the image." ),
 
227
                        sprintf( $self->{_d}->get("Error while opening image %s."), "'" . $self->{_filename} . "'"),
 
228
                        $self->{_d}->get( "There was an error opening the image." ),
151
229
                        undef, undef, undef,
152
230
                        undef, undef, undef,
153
231
                        $@
154
232
                );
155
233
                
156
234
                $self->{_drawing_window}->destroy if $self->{_drawing_window};
157
 
                Gtk2->main_quit();
158
235
                return FALSE;           
159
236
        
160
237
        }
161
238
        
162
 
        #create canvas
 
239
        #CANVAS
 
240
        #-------------------------------------------------
163
241
        $self->{_canvas} = Goo::Canvas->new();
164
 
        my $gray = Gtk2::Gdk::Color->parse('gray');
165
 
        $self->{_canvas}->set( 'background-color' => sprintf( "#%04x%04x%04x", $gray->red, $gray->green, $gray->blue ) );
166
 
 
167
 
        $self->{_canvas}->set_bounds( 0, 0, $self->{_drawing_pixbuf}->get_width, $self->{_drawing_pixbuf}->get_height );
168
 
        my $root = $self->{_canvas}->get_root_item;
169
 
 
170
 
        $self->{_canvas_bg} = Goo::Canvas::Image->new( $root, $self->{_drawing_pixbuf}, 0, 0 );
 
242
        
 
243
        #'redraw-when-scrolled' to reduce the flicker of static items
 
244
        #
 
245
        #this property is not available in older versions
 
246
        #it was added to goocanvas on Mon Nov 17 10:28:07 2008 UTC
 
247
        #http://svn.gnome.org/viewvc/goocanvas?view=revision&revision=28        
 
248
        if($self->{_canvas}->find_property ('redraw-when-scrolled')){
 
249
                $self->{_canvas}->set( 
 
250
                        'redraw-when-scrolled'  => TRUE
 
251
                );              
 
252
        }
 
253
 
 
254
        my $gray = Gtk2::Gdk::Color->parse('gray');     
 
255
        $self->{_canvas}->set( 
 
256
                'automatic-bounds'              => FALSE,
 
257
                'bounds-from-origin'    => FALSE,
 
258
                'background-color'              => sprintf( "#%04x%04x%04x", $gray->red, $gray->green, $gray->blue ), 
 
259
        );
 
260
        
 
261
        #and attach scroll event
 
262
        #to imitate scroll behavior of
 
263
        #Gtk2::ImageView widget Ctrl+Mouse Wheel
 
264
        $self->{_canvas}->signal_connect(
 
265
                'scroll-event' =>
 
266
                sub {
 
267
                        my ( $canvas, $ev ) = @_;
 
268
 
 
269
                        my $alloc = $self->{_canvas}->allocation;                       
 
270
                        my $scale = $canvas->get_scale;
 
271
                                                
 
272
                        if ($ev->state >= 'control-mask' && ($ev->direction eq 'up' || $ev->direction eq 'left') ) {
 
273
                                $self->zoom_in_cb;
 
274
                                $canvas->scroll_to(int($ev->x - $alloc->width / 2 ) / $scale, int($ev->y - $alloc->height / 2 ) / $scale);
 
275
                                return TRUE;
 
276
                        }elsif ( $ev->state >= 'control-mask' && ($ev->direction eq 'down' || $ev->direction eq 'right') ) {
 
277
                                $self->zoom_out_cb;
 
278
                                return TRUE;
 
279
                        }
 
280
                        return FALSE;           
 
281
                }
 
282
        );
 
283
 
 
284
        #create rectangle to resize the background
 
285
        $self->{_canvas_bg_rect} = Goo::Canvas::Rect->new(
 
286
                $self->{_canvas}->get_root_item, 0, 0, $self->{_drawing_pixbuf}->get_width, $self->{_drawing_pixbuf}->get_height,
 
287
                'fill-pattern' => $self->create_color('gray', 1.0),
 
288
                'line-dash'    => Goo::Canvas::LineDash->new( [ 5, 5 ] ),
 
289
                'line-width'   => 1,
 
290
                'stroke-color' => 'black',
 
291
        );      
 
292
        $self->setup_item_signals( $self->{_canvas_bg_rect} );
 
293
 
 
294
        $self->handle_bg_rects( 'create' );
 
295
        $self->handle_bg_rects( 'update' );
 
296
 
 
297
        #create canvas background (:= screenshot)
 
298
        $self->{_canvas_bg} = Goo::Canvas::Image->new( 
 
299
                $self->{_canvas}->get_root_item, 
 
300
                $self->{_drawing_pixbuf}, 
 
301
                0, 0,
 
302
        );
171
303
        $self->setup_item_signals( $self->{_canvas_bg} );
172
304
 
173
 
        #packing
174
 
        $self->{_scrolled_window} = Gtk2::ScrolledWindow->new;
175
 
        $self->{_scrolled_window}->set_policy( 'automatic', 'automatic' );
176
 
        $self->{_scrolled_window}->add( $self->{_canvas} );
 
305
        $self->handle_bg_rects( 'raise' );
177
306
 
178
 
        my $drawing_vbox       = Gtk2::VBox->new( FALSE, 0 );
179
 
        my $drawing_inner_vbox = Gtk2::VBox->new( FALSE, 0 );
180
 
        my $drawing_hbox       = Gtk2::HBox->new( FALSE, 0 );
 
307
        #PACKING
 
308
        #-------------------------------------------------
 
309
        $self->{_drawing_vbox}         = Gtk2::VBox->new( FALSE, 0 );
 
310
        $self->{_drawing_inner_vbox}   = Gtk2::VBox->new( FALSE, 0 );
 
311
        $self->{_drawing_inner_vbox_c} = Gtk2::VBox->new( FALSE, 0 );
 
312
        $self->{_drawing_hbox}         = Gtk2::HBox->new( FALSE, 0 );
 
313
        $self->{_drawing_hbox_c}         = Gtk2::HBox->new( FALSE, 0 );
181
314
 
182
315
        #disable undo/redo actions at startup
183
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Undo")->set_sensitive(FALSE);
184
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Redo")->set_sensitive(FALSE);
185
 
 
186
 
        #do show these actions because the user would be confused
187
 
        #to see multiple shortcuts to handle zooming
188
 
        #controlequal is used for english keyboard layouts for example
189
 
        $self->{_uimanager}->get_action("/MenuBar/View/ControlEqual")->set_visible(FALSE);
190
 
        $self->{_uimanager}->get_action("/MenuBar/View/ControlKpAdd")->set_visible(FALSE);
191
 
        $self->{_uimanager}->get_action("/MenuBar/View/ControlKpSub")->set_visible(FALSE);
192
 
 
193
 
        #create a table for placing the ruler and scrolle window
194
 
        my $table = new Gtk2::Table( 3, 2, FALSE );
195
 
 
196
 
        $self->{_drawing_window}->add($drawing_vbox);
 
316
        $self->{_uimanager}->get_widget("/MenuBar/Edit/Undo")->set_sensitive(FALSE);
 
317
        $self->{_uimanager}->get_widget("/MenuBar/Edit/Redo")->set_sensitive(FALSE);
 
318
 
 
319
        $self->{_uimanager}->get_widget("/ToolBar/Undo")->set_sensitive(FALSE);
 
320
        $self->{_uimanager}->get_widget("/ToolBar/Redo")->set_sensitive(FALSE);
 
321
 
 
322
        $self->{_drawing_window}->add($self->{_drawing_vbox});
197
323
 
198
324
        my $menubar = $self->{_uimanager}->get_widget("/MenuBar");
199
 
        $drawing_vbox->pack_start( $menubar, FALSE, FALSE, 0 );
 
325
        $self->{_drawing_vbox}->pack_start( $menubar, FALSE, FALSE, 0 );
200
326
 
201
327
        my $toolbar_drawing = $self->{_uimanager}->get_widget("/ToolBarDrawing");
202
328
        $toolbar_drawing->set_orientation('vertical');
203
329
        $toolbar_drawing->set_style('icons');
204
330
        $toolbar_drawing->set_icon_size('menu');
205
331
        $toolbar_drawing->set_show_arrow(FALSE);
206
 
        $drawing_hbox->pack_start( $toolbar_drawing, FALSE, FALSE, 0 );
 
332
        $self->{_drawing_hbox}->pack_start( $toolbar_drawing, FALSE, FALSE, 0 );
207
333
 
 
334
        #DRAWING TOOL CONTAINER
 
335
        #-------------------------------------------------
 
336
        #scrolled window for the canvas
 
337
        $self->{_scrolled_window} = Gtk2::ScrolledWindow->new;
 
338
        $self->{_scrolled_window}->set_policy( 'automatic', 'automatic' );
 
339
        $self->{_scrolled_window}->add( $self->{_canvas} );
 
340
        $self->{_hscroll_hid} = $self->{_scrolled_window}->get_hscrollbar->signal_connect('value-changed' => sub { $self->adjust_rulers} );
 
341
        $self->{_vscroll_hid} = $self->{_scrolled_window}->get_vscrollbar->signal_connect('value-changed' => sub { $self->adjust_rulers} );
 
342
        
208
343
        #vruler
209
344
        $self->{_vruler} = Gtk2::VRuler->new;
210
345
        $self->{_vruler}->set_metric('pixels');
215
350
        $self->{_hruler}->set_metric('pixels');
216
351
        $self->{_hruler}->set_range( 0, $self->{_drawing_pixbuf}->get_width, 0, $self->{_drawing_pixbuf}->get_width );
217
352
 
 
353
        #create a table for placing the ruler and scrolle window
 
354
        $self->{_table} = new Gtk2::Table( 3, 2, FALSE );
 
355
        
218
356
        #attach scrolled window and rulers to the table
219
 
        $table->attach( $self->{_scrolled_window}, 1, 2, 1, 2, [ 'expand', 'fill' ], [ 'expand', 'fill' ], 0, 0 );
220
 
 
221
 
        $table->attach( $self->{_hruler}, 1, 2, 0, 1, [ 'expand', 'shrink', 'fill' ], [], 0, 0 );
222
 
        $table->attach( $self->{_vruler}, 0, 1, 1, 2, [], [ 'fill', 'expand', 'shrink' ], 0, 0 );
223
 
 
224
 
        $drawing_inner_vbox->pack_start( $table,                   TRUE,  TRUE, 0 );
225
 
        $drawing_inner_vbox->pack_start( $self->setup_bottom_hbox, FALSE, TRUE, 0 );
226
 
        $drawing_hbox->pack_start( $drawing_inner_vbox, TRUE, TRUE, 0 );
227
 
 
228
 
        my $toolbar = $self->{_uimanager}->get_widget("/ToolBar");
229
 
        $drawing_vbox->pack_start( $self->{_uimanager}->get_widget("/ToolBar"), FALSE, FALSE, 0 );
230
 
 
231
 
        $drawing_vbox->pack_start( $drawing_hbox, TRUE, TRUE, 0 );
 
357
        $self->{_table}->attach( $self->{_scrolled_window}, 1, 2, 1, 2, [ 'expand', 'fill' ], [ 'expand', 'fill' ], 0, 0 );
 
358
        $self->{_table}->attach( $self->{_hruler}, 1, 2, 0, 1, [ 'expand', 'shrink', 'fill' ], [], 0, 0 );
 
359
        $self->{_table}->attach( $self->{_vruler}, 0, 1, 1, 2, [], [ 'fill', 'expand', 'shrink' ], 0, 0 );
 
360
 
 
361
        $self->{_bhbox} = $self->setup_bottom_hbox;     
 
362
        $self->{_drawing_inner_vbox}->pack_start( $self->{_table}, TRUE, TRUE,  0 );
 
363
        $self->{_drawing_inner_vbox}->pack_start( $self->{_bhbox}, FALSE, TRUE, 0 );
 
364
        
 
365
        #CROPPING TOOL CONTAINER
 
366
        #-------------------------------------------------
 
367
        #scrolled window for the cropping tool
 
368
        $self->{_scrolled_window_c} = Gtk2::ImageView::ScrollWin->new ($self->{_view}); 
 
369
        $self->{_rframe_c} = $self->setup_right_vbox_c; #be careful => frame is returned
 
370
        $self->{_drawing_hbox_c}->pack_start( $self->{_scrolled_window_c}, TRUE, TRUE, 0 );
 
371
        $self->{_drawing_hbox_c}->pack_start( $self->{_rframe_c}, FALSE, FALSE, 3 );
 
372
 
 
373
        $self->{_drawing_inner_vbox_c}->pack_start( $self->{_drawing_hbox_c}, TRUE, TRUE, 0 );
 
374
 
 
375
        #MAIN CONTAINER
 
376
        #-------------------------------------------------      
 
377
        #pack both containers to the main hbox
 
378
        $self->{_drawing_hbox}->pack_start( $self->{_drawing_inner_vbox},   TRUE, TRUE,  0 );
 
379
        $self->{_drawing_hbox}->pack_start( $self->{_drawing_inner_vbox_c},   TRUE, TRUE,  0 );
 
380
        
 
381
        $self->{_drawing_vbox}->pack_start( $self->{_uimanager}->get_widget("/ToolBar"), FALSE, FALSE, 0 );
 
382
        $self->{_drawing_vbox}->pack_start( $self->{_drawing_hbox}, TRUE, TRUE, 0 );
232
383
 
233
384
        $self->{_drawing_statusbar} = Gtk2::Statusbar->new;
234
 
        $drawing_vbox->pack_start( $self->{_drawing_statusbar}, FALSE, FALSE, 0 );
 
385
        $self->{_drawing_vbox}->pack_start( $self->{_drawing_statusbar}, FALSE, FALSE, 0 );
235
386
 
236
387
        $self->{_drawing_window}->show_all();
237
388
 
 
389
        
 
390
        #STARTUP PROCEDURE
 
391
        #-------------------------------------------------      
238
392
        $self->{_drawing_window}->window->focus(time);
239
393
 
240
394
        $self->adjust_rulers;
242
396
        #save start time to show in close dialog
243
397
        $self->{_start_time} = time;
244
398
 
 
399
        #init current tool
 
400
        $self->set_drawing_action(int($self->{_current_mode}/10));
 
401
 
 
402
        #remember drawing colors, line width and font settings
 
403
        #maybe we have to restore them
 
404
        $self->{_last_fill_color}         = $self->{_fill_color_w}->get_color;
 
405
        $self->{_last_fill_color_alpha}   = $self->{_fill_color_w}->get_alpha / 65535;
 
406
        $self->{_last_stroke_color}       = $self->{_stroke_color_w}->get_color;
 
407
        $self->{_last_stroke_color_alpha} = $self->{_stroke_color_w}->get_alpha / 65535;
 
408
        $self->{_last_line_width}                 = $self->{_line_spin_w}->get_value;
 
409
        $self->{_last_font}                       = $self->{_font_btn_w}->get_font_name;
 
410
 
 
411
        #init last mode
 
412
        $self->{_last_mode}               = 0;
 
413
        $self->{_last_mode_descr}         = ''; 
 
414
 
 
415
        #do show these actions because the user would be confused
 
416
        #to see multiple shortcuts to handle zooming
 
417
        #controlequal is used for english keyboard layouts for example
 
418
        $self->{_uimanager}->get_action("/MenuBar/View/ControlEqual")->set_visible(FALSE);
 
419
        $self->{_uimanager}->get_action("/MenuBar/View/ControlKpAdd")->set_visible(FALSE);
 
420
        $self->{_uimanager}->get_action("/MenuBar/View/ControlKpSub")->set_visible(FALSE);
 
421
 
245
422
        Gtk2->main;
246
423
 
247
424
        return TRUE;
250
427
sub setup_bottom_hbox {
251
428
        my $self = shift;
252
429
 
253
 
        my $d = $self->{_shutter_common}->get_gettext;
254
 
 
255
430
        #Tooltips
256
431
        my $tooltips = $self->{_shutter_common}->get_tooltips;
257
432
 
258
433
        my $drawing_bottom_hbox = Gtk2::HBox->new( FALSE, 5 );
259
434
 
260
435
        #fill color
261
 
        my $fill_color_label = Gtk2::Label->new( $d->get("Fill color") . ":" );
262
 
        my $fill_color       = Gtk2::ColorButton->new();
263
 
        $fill_color->set_color( $self->{_fill_color} );
264
 
        $fill_color->set_alpha( int( $self->{_fill_color_alpha} * 65636 ) );
265
 
        $fill_color->set_use_alpha(TRUE);
266
 
        $fill_color->set_title( $d->get("Choose fill color") );
267
 
        $fill_color->signal_connect(
268
 
                'color-set' => sub {
269
 
                        $self->{_fill_color}       = $fill_color->get_color;
270
 
                        $self->{_fill_color_alpha} = $fill_color->get_alpha / 65636;
271
 
                }
272
 
        );
 
436
        my $fill_color_label = Gtk2::Label->new( $self->{_d}->get("Fill color") . ":" );
 
437
        $self->{_fill_color_w} = Gtk2::ColorButton->new();
 
438
        $self->{_fill_color_w}->set_color( $self->{_fill_color} );
 
439
        $self->{_fill_color_w}->set_alpha( int( $self->{_fill_color_alpha} * 65636 ) );
 
440
        $self->{_fill_color_w}->set_use_alpha(TRUE);
 
441
        $self->{_fill_color_w}->set_title( $self->{_d}->get("Choose fill color") );
273
442
 
274
 
        $tooltips->set_tip( $fill_color_label, $d->get("Adjust fill color and opacity") );
275
 
        $tooltips->set_tip( $fill_color,       $d->get("Adjust fill color and opacity") );
 
443
        $tooltips->set_tip( $fill_color_label, $self->{_d}->get("Adjust fill color and opacity") );
 
444
        $tooltips->set_tip( $self->{_fill_color_w}, $self->{_d}->get("Adjust fill color and opacity") );
276
445
 
277
446
        $drawing_bottom_hbox->pack_start( $fill_color_label, FALSE, FALSE, 5 );
278
 
        $drawing_bottom_hbox->pack_start( $fill_color,       FALSE, FALSE, 5 );
 
447
        $drawing_bottom_hbox->pack_start( $self->{_fill_color_w}, FALSE, FALSE, 5 );
279
448
 
280
449
        #stroke color
281
 
        my $stroke_color_label = Gtk2::Label->new( $d->get("Stroke color") . ":" );
282
 
        my $stroke_color       = Gtk2::ColorButton->new();
283
 
        $stroke_color->set_color( $self->{_stroke_color} );
284
 
        $stroke_color->set_alpha( int( $self->{_stroke_color_alpha} * 65535 ) );
285
 
        $stroke_color->set_use_alpha(TRUE);
286
 
        $stroke_color->set_title( $d->get("Choose stroke color") );
287
 
        $stroke_color->signal_connect(
288
 
                'color-set' => sub {
289
 
                        $self->{_stroke_color}       = $stroke_color->get_color;
290
 
                        $self->{_stroke_color_alpha} = $stroke_color->get_alpha / 65535;
291
 
                }
292
 
        );
 
450
        my $stroke_color_label = Gtk2::Label->new( $self->{_d}->get("Stroke color") . ":" );
 
451
        $self->{_stroke_color_w} = Gtk2::ColorButton->new();
 
452
        $self->{_stroke_color_w}->set_color( $self->{_stroke_color} );
 
453
        $self->{_stroke_color_w}->set_alpha( int( $self->{_stroke_color_alpha} * 65535 ) );
 
454
        $self->{_stroke_color_w}->set_use_alpha(TRUE);
 
455
        $self->{_stroke_color_w}->set_title( $self->{_d}->get("Choose stroke color") );
293
456
 
294
 
        $tooltips->set_tip( $stroke_color_label, $d->get("Adjust stroke color and opacity") );
295
 
        $tooltips->set_tip( $stroke_color,       $d->get("Adjust stroke color and opacity") );
 
457
        $tooltips->set_tip( $stroke_color_label, $self->{_d}->get("Adjust stroke color and opacity") );
 
458
        $tooltips->set_tip( $self->{_stroke_color_w}, $self->{_d}->get("Adjust stroke color and opacity") );
296
459
 
297
460
        $drawing_bottom_hbox->pack_start( $stroke_color_label, FALSE, FALSE, 5 );
298
 
        $drawing_bottom_hbox->pack_start( $stroke_color,       FALSE, FALSE, 5 );
 
461
        $drawing_bottom_hbox->pack_start( $self->{_stroke_color_w}, FALSE, FALSE, 5 );
299
462
 
300
463
        #line_width
301
 
        my $linew_label = Gtk2::Label->new( $d->get("Line width") . ":" );
302
 
        my $line_spin = Gtk2::SpinButton->new_with_range( 0.5, 10, 0.1 );
303
 
        $line_spin->set_value( $self->{_line_width} );
304
 
        $line_spin->signal_connect(
305
 
                'value-changed' => sub {
306
 
                        $self->{_line_width} = $line_spin->get_value;
307
 
                }
308
 
        );
 
464
        my $linew_label = Gtk2::Label->new( $self->{_d}->get("Line width") . ":" );
 
465
        $self->{_line_spin_w} = Gtk2::SpinButton->new_with_range( 0.5, 20, 0.1 );
 
466
        $self->{_line_spin_w}->set_value( $self->{_line_width} );
309
467
 
310
 
        $tooltips->set_tip( $linew_label, $d->get("Adjust line width") );
311
 
        $tooltips->set_tip( $line_spin,   $d->get("Adjust line width") );
 
468
        $tooltips->set_tip( $linew_label, $self->{_d}->get("Adjust line width") );
 
469
        $tooltips->set_tip( $self->{_line_spin_w},   $self->{_d}->get("Adjust line width") );
312
470
 
313
471
        $drawing_bottom_hbox->pack_start( $linew_label, FALSE, FALSE, 5 );
314
 
        $drawing_bottom_hbox->pack_start( $line_spin,   FALSE, FALSE, 5 );
 
472
        $drawing_bottom_hbox->pack_start( $self->{_line_spin_w},   FALSE, FALSE, 5 );
315
473
 
316
474
        #font button
317
 
        my $font_label = Gtk2::Label->new( $d->get("Font") . ":" );
318
 
        my $font_btn   = Gtk2::FontButton->new();
319
 
        $font_btn->set_font_name( $self->{_font} );
320
 
        $font_btn->signal_connect(
321
 
                'font-set' => sub {
322
 
                        my $font_descr = Gtk2::Pango::FontDescription->from_string( $font_btn->get_font_name );
323
 
                        $self->{_font} = $font_descr->to_string;
324
 
                }
325
 
        );
 
475
        my $font_label = Gtk2::Label->new( $self->{_d}->get("Font") . ":" );
 
476
        $self->{_font_btn_w} = Gtk2::FontButton->new();
 
477
        $self->{_font_btn_w}->set_font_name( $self->{_font} );
326
478
 
327
 
        $tooltips->set_tip( $font_label, $d->get("Select font family and size") );
328
 
        $tooltips->set_tip( $font_btn,   $d->get("Select font family and size") );
 
479
        $tooltips->set_tip( $font_label, $self->{_d}->get("Select font family and size") );
 
480
        $tooltips->set_tip( $self->{_font_btn_w}, $self->{_d}->get("Select font family and size") );
329
481
 
330
482
        $drawing_bottom_hbox->pack_start( $font_label, FALSE, FALSE, 5 );
331
 
        $drawing_bottom_hbox->pack_start( $font_btn,   FALSE, FALSE, 5 );
 
483
        $drawing_bottom_hbox->pack_start( $self->{_font_btn_w}, FALSE, FALSE, 5 );
332
484
 
333
485
        #image button
334
 
        my $image_label = Gtk2::Label->new( $d->get("Insert image") . ":" );
 
486
        my $image_label = Gtk2::Label->new( $self->{_d}->get("Insert image") . ":" );
335
487
        my $image_btn = Gtk2::MenuToolButton->new( undef, undef );
336
 
        $image_btn->set_menu( $self->ret_objects_menu($image_btn) );
337
 
 
338
 
        #~ $image_btn->signal_connect( 'show-menu' => sub { my ($widget) = @_; $self->ret_objects_menu($widget, 'noinit') } );
 
488
 
 
489
        Glib::Idle->add (
 
490
                sub {
 
491
                        $image_btn->set_menu( $self->import_from_filesystem($image_btn) );
 
492
                        return FALSE;
 
493
                }
 
494
        );
 
495
 
 
496
        #handle property changes 
 
497
        #changes are applied directly to the current item
 
498
        $self->{_line_spin_wh} = $self->{_line_spin_w}->signal_connect(
 
499
                'value-changed' => sub {
 
500
                        $self->{_line_width} = $self->{_line_spin_w}->get_value;
 
501
 
 
502
                        if($self->{_current_item}){
 
503
                                #apply all changes directly
 
504
                                my $item        = $self->{_current_item};
 
505
                                if(my $child = $self->get_child_item($item)){
 
506
                                        $item = $child;
 
507
                                }
 
508
                                my $parent      = $self->get_parent_item($item);
 
509
                                #determine key for item hash
 
510
                                my $key = $self->get_item_key($item, $parent);
 
511
 
 
512
                                $self->apply_properties($item, $parent, $key, $self->{_fill_color_w}, 
 
513
                                                                                $self->{_stroke_color_w}, $self->{_line_spin_w}, 
 
514
                                                                                $self->{_stroke_color_w}, $self->{_font_btn_w});
 
515
                                                                                
 
516
                        }
 
517
 
 
518
                }
 
519
        );
 
520
        
 
521
        $self->{_stroke_color_wh} = $self->{_stroke_color_w}->signal_connect(
 
522
                'color-set' => sub {
 
523
                        $self->{_stroke_color}       = $self->{_stroke_color_w}->get_color;
 
524
                        $self->{_stroke_color_alpha} = $self->{_stroke_color_w}->get_alpha / 65535;
 
525
 
 
526
                        if($self->{_current_item}){
 
527
                                #apply all changes directly
 
528
                                my $item        = $self->{_current_item};
 
529
                                if(my $child = $self->get_child_item($item)){
 
530
                                        $item = $child;
 
531
                                }
 
532
                                my $parent      = $self->get_parent_item($item);
 
533
                                #determine key for item hash
 
534
                                my $key = $self->get_item_key($item, $parent);
 
535
 
 
536
                                $self->apply_properties($item, $parent, $key, $self->{_fill_color_w}, 
 
537
                                                                                $self->{_stroke_color_w}, $self->{_line_spin_w}, 
 
538
                                                                                $self->{_stroke_color_w}, $self->{_font_btn_w});
 
539
                                                                                
 
540
                        }       
 
541
 
 
542
                }
 
543
        );
 
544
        
 
545
        $self->{_fill_color_wh} = $self->{_fill_color_w}->signal_connect(
 
546
                'color-set' => sub {
 
547
                        $self->{_fill_color}       = $self->{_fill_color_w}->get_color;
 
548
                        $self->{_fill_color_alpha} = $self->{_fill_color_w}->get_alpha / 65636;
 
549
 
 
550
                        if($self->{_current_item}){
 
551
                                #apply all changes directly
 
552
                                my $item        = $self->{_current_item};
 
553
                                if(my $child = $self->get_child_item($item)){
 
554
                                        $item = $child;
 
555
                                }
 
556
                                my $parent      = $self->get_parent_item($item);
 
557
                                #determine key for item hash
 
558
                                my $key = $self->get_item_key($item, $parent);
 
559
 
 
560
                                $self->apply_properties($item, $parent, $key, $self->{_fill_color_w}, 
 
561
                                                                                $self->{_stroke_color_w}, $self->{_line_spin_w}, 
 
562
                                                                                $self->{_stroke_color_w}, $self->{_font_btn_w});
 
563
                                                                                
 
564
                        }
 
565
                
 
566
                }
 
567
        );
 
568
        
 
569
        $self->{_font_btn_wh} = $self->{_font_btn_w}->signal_connect(
 
570
                'font-set' => sub {
 
571
                        my $font_descr = Gtk2::Pango::FontDescription->from_string( $self->{_font_btn_w}->get_font_name );
 
572
                        $self->{_font} = $font_descr->to_string;
 
573
 
 
574
                        if($self->{_current_item}){
 
575
                                #apply all changes directly
 
576
                                my $item        = $self->{_current_item};
 
577
                                if(my $child = $self->get_child_item($item)){
 
578
                                        $item = $child;
 
579
                                }
 
580
                                my $parent      = $self->get_parent_item($item);
 
581
                                #determine key for item hash
 
582
                                my $key = $self->get_item_key($item, $parent);
 
583
 
 
584
                                $self->apply_properties($item, $parent, $key, $self->{_fill_color_w}, 
 
585
                                                                                $self->{_stroke_color_w}, $self->{_line_spin_w}, 
 
586
                                                                                $self->{_stroke_color_w}, $self->{_font_btn_w});
 
587
                                                                                
 
588
                        }       
 
589
 
 
590
                }
 
591
        );
 
592
        
339
593
        $image_btn->signal_connect(
340
594
                'clicked' => sub {
341
 
                        $self->{_canvas}->window->set_cursor($self->change_cursor_to_current_pixbuf());
 
595
                        $self->{_canvas}->window->set_cursor($self->change_cursor_to_current_pixbuf);
342
596
                }
343
597
        );
344
598
 
345
 
        $tooltips->set_tip( $image_label, $d->get("Insert an arbitrary object or file") );
346
 
        $tooltips->set_tip( $image_btn,   $d->get("Insert an arbitrary object or file") );
 
599
        $tooltips->set_tip( $image_label, $self->{_d}->get("Insert an arbitrary object or file") );
 
600
        $tooltips->set_tip( $image_btn,   $self->{_d}->get("Insert an arbitrary object or file") );
347
601
 
348
602
        $drawing_bottom_hbox->pack_start( $image_label, FALSE, FALSE, 5 );
349
603
        $drawing_bottom_hbox->pack_start( $image_btn,   FALSE, FALSE, 5 );
351
605
        return $drawing_bottom_hbox;
352
606
}
353
607
 
 
608
sub setup_right_vbox_c {
 
609
        my $self = shift;
 
610
 
 
611
        #Tooltips
 
612
        my $tooltips = $self->{_shutter_common}->get_tooltips;
 
613
 
 
614
        my $cropping_bottom_vbox = Gtk2::VBox->new( FALSE, 5 );
 
615
 
 
616
        #get current pixbuf
 
617
        my $pixbuf = $self->{_view}->get_pixbuf || $self->{_drawing_pixbuf};
 
618
 
 
619
        #X
 
620
        my $xw_label = Gtk2::Label->new( $self->{_d}->get("X") . ":" );
 
621
        $self->{_x_spin_w} = Gtk2::SpinButton->new_with_range( 0, $pixbuf->get_width, 1 );
 
622
        $self->{_x_spin_w}->set_value( 0 );
 
623
        $self->{_x_spin_w_handler} = $self->{_x_spin_w}->signal_connect(
 
624
                'value-changed' => sub {
 
625
                        $self->{_selector}->set_selection(
 
626
                                Gtk2::Gdk::Rectangle->new(
 
627
                                $self->{_x_spin_w}->get_value, $self->{_y_spin_w}->get_value,
 
628
                                $self->{_width_spin_w}->get_value, $self->{_height_spin_w}->get_value
 
629
                                )
 
630
                        );
 
631
                }
 
632
        );
 
633
 
 
634
        my $xw_hbox = Gtk2::HBox->new( FALSE, 5 );
 
635
        $xw_hbox->pack_start( $xw_label, FALSE, FALSE, 5 );
 
636
        $xw_hbox->pack_start( $self->{_x_spin_w}, FALSE, FALSE, 5 );
 
637
 
 
638
        #y
 
639
        my $yw_label = Gtk2::Label->new( $self->{_d}->get("Y") . ":" );
 
640
        $self->{_y_spin_w} = Gtk2::SpinButton->new_with_range( 0, $pixbuf->get_height, 1 );
 
641
        $self->{_y_spin_w}->set_value( 0 );
 
642
        $self->{_y_spin_w_handler} = $self->{_y_spin_w}->signal_connect(
 
643
                'value-changed' => sub {
 
644
                        $self->{_selector}->set_selection(
 
645
                                Gtk2::Gdk::Rectangle->new(
 
646
                                $self->{_x_spin_w}->get_value, $self->{_y_spin_w}->get_value,
 
647
                                $self->{_width_spin_w}->get_value, $self->{_height_spin_w}->get_value
 
648
                                )
 
649
                        );
 
650
                }
 
651
        );
 
652
 
 
653
        my $yw_hbox = Gtk2::HBox->new( FALSE, 5 );
 
654
        $yw_hbox->pack_start( $yw_label, FALSE, FALSE, 5 );
 
655
        $yw_hbox->pack_start( $self->{_y_spin_w}, FALSE, FALSE, 5 );
 
656
 
 
657
        #width
 
658
        my $widthw_label = Gtk2::Label->new( $self->{_d}->get("Width") . ":" );
 
659
        $self->{_width_spin_w} = Gtk2::SpinButton->new_with_range( 0, $pixbuf->get_width, 1 );
 
660
        $self->{_width_spin_w}->set_value( 0 );
 
661
        $self->{_width_spin_w_handler} = $self->{_width_spin_w}->signal_connect(
 
662
                'value-changed' => sub {
 
663
                        $self->{_selector}->set_selection(
 
664
                                Gtk2::Gdk::Rectangle->new(
 
665
                                $self->{_x_spin_w}->get_value, $self->{_y_spin_w}->get_value,
 
666
                                $self->{_width_spin_w}->get_value, $self->{_height_spin_w}->get_value
 
667
                                )
 
668
                        );
 
669
                }
 
670
        );
 
671
 
 
672
        my $ww_hbox = Gtk2::HBox->new( FALSE, 5 );
 
673
        $ww_hbox->pack_start( $widthw_label, FALSE, FALSE, 5 );
 
674
        $ww_hbox->pack_start( $self->{_width_spin_w}, FALSE, FALSE, 5 );
 
675
 
 
676
        #height
 
677
        my $heightw_label = Gtk2::Label->new( $self->{_d}->get("Height") . ":" );
 
678
        $self->{_height_spin_w} = Gtk2::SpinButton->new_with_range( 0, $pixbuf->get_height, 1 );
 
679
        $self->{_height_spin_w}->set_value( 0 );
 
680
        $self->{_height_spin_w_handler} = $self->{_height_spin_w}->signal_connect(
 
681
                'value-changed' => sub {
 
682
                        $self->{_selector}->set_selection(
 
683
                                Gtk2::Gdk::Rectangle->new(
 
684
                                $self->{_x_spin_w}->get_value, $self->{_y_spin_w}->get_value,
 
685
                                $self->{_width_spin_w}->get_value, $self->{_height_spin_w}->get_value
 
686
                                )
 
687
                        );
 
688
                }
 
689
        );
 
690
 
 
691
        my $hw_hbox = Gtk2::HBox->new( FALSE, 5 );
 
692
        $hw_hbox->pack_start( $heightw_label, FALSE, FALSE, 5 );
 
693
        $hw_hbox->pack_start( $self->{_height_spin_w}, FALSE, FALSE, 5 );
 
694
 
 
695
        #the above values are changed when the selection is changed
 
696
        $self->{_selector_handler} = $self->{_selector}->signal_connect(
 
697
                'selection-changed' => sub {
 
698
                        $self->adjust_crop_values($pixbuf);
 
699
                }
 
700
        );
 
701
        
 
702
        #cancel button
 
703
        my $crop_c = Gtk2::Button->new_from_stock ('gtk-cancel');
 
704
        $crop_c->signal_connect('clicked' => sub { $self->abort_current_mode} );
 
705
 
 
706
        #crop button
 
707
        my $crop_ok = Gtk2::Button->new_with_mnemonic ($self->{_d}->get("_Crop"));
 
708
        $crop_ok->set_image( Gtk2::Image->new_from_file($self->{_dicons}.'/transform-crop.png') );
 
709
        $crop_ok->signal_connect('clicked' => sub { 
 
710
                
 
711
                my $s = $self->{_selector}->get_selection;
 
712
                my $p = $self->{_view}->get_pixbuf;
 
713
                
 
714
                if ($s && $p) {
 
715
 
 
716
                        #add to undo stack
 
717
                        $self->store_to_xdo_stack($self->{_canvas_bg}, 'modify', 'undo', $s);   
 
718
                        
 
719
                        #create new pixbuf
 
720
                        #create temp pixbuf because selected area might be bigger than
 
721
                        #source pixbuf (screenshot) => canvas area is resizeable
 
722
                        my $temp = Gtk2::Gdk::Pixbuf->new ($self->{_drawing_pixbuf}->get_colorspace, TRUE, 8,  $p->get_width, $p->get_height);          
 
723
                        #whole pixbuf is transparent
 
724
                        $temp->fill(0x00000000);
 
725
                
 
726
                        #copy source image to temp pixbuf (temp pixbuf's size == $self->{_view}->get_pixbuf)                    
 
727
                        $self->{_drawing_pixbuf}->copy_area(0, 0, $self->{_drawing_pixbuf}->get_width, $self->{_drawing_pixbuf}->get_height, $temp, 0, 0);
 
728
                        
 
729
                        #and create a new subpixbuf from the temp pixbuf
 
730
                        my $new_p = $temp->new_subpixbuf ($s->x, $s->y, $s->width, $s->height);
 
731
                        $self->{_drawing_pixbuf} = $new_p->copy;
 
732
                        
 
733
                        #update bounds and bg_rects
 
734
                        $self->{_canvas_bg_rect}->set('width' => $s->width, 'height' => $s->height);
 
735
                        $self->handle_bg_rects( 'update' );
 
736
                        
 
737
                        #update canvas and show the new pixbuf
 
738
                        $self->{_canvas_bg}->set('pixbuf' => $new_p);
 
739
                        
 
740
                        #now move all items, 
 
741
                        #so they are in the right position
 
742
                        #~ print $s->x ." - ".$s->y."\n";
 
743
                        $self->move_all($s->x, $s->y);
 
744
                        
 
745
                        #adjust stack order
 
746
                        $self->{_canvas_bg}->lower;
 
747
                        $self->{_canvas_bg_rect}->lower;
 
748
                        $self->handle_bg_rects( 'raise' );
 
749
                        
 
750
                } else {
 
751
                        #nothing here right now
 
752
                }
 
753
                                
 
754
                #finally reset mode to select tool
 
755
                $self->abort_current_mode;
 
756
                
 
757
                }
 
758
        );
 
759
 
 
760
        #put buttons in a separated box
 
761
        #all buttons = one size
 
762
        my $sg_butt = Gtk2::SizeGroup->new('vertical');
 
763
        $sg_butt->add_widget($crop_c);
 
764
        $sg_butt->add_widget($crop_ok);
 
765
 
 
766
        my $cropping_bottom_vbox_b = Gtk2::VBox->new( FALSE, 5 );
 
767
        $cropping_bottom_vbox_b->pack_start( $crop_c, FALSE, FALSE, 0 );
 
768
        $cropping_bottom_vbox_b->pack_start( $crop_ok, FALSE, FALSE, 0 );
 
769
 
 
770
        #final_packing
 
771
        #all labels = one size
 
772
        $xw_label->set_alignment( 0, 0.5 );
 
773
        $yw_label->set_alignment( 0, 0.5 );
 
774
        $widthw_label->set_alignment( 0, 0.5 );
 
775
        $heightw_label->set_alignment( 0, 0.5 );
 
776
 
 
777
        my $sg_main = Gtk2::SizeGroup->new('horizontal');
 
778
        $sg_main->add_widget($xw_label);
 
779
        $sg_main->add_widget($yw_label);
 
780
        $sg_main->add_widget($widthw_label);
 
781
        $sg_main->add_widget($heightw_label);
 
782
 
 
783
        $cropping_bottom_vbox->pack_start( $xw_hbox, FALSE, FALSE, 3 );
 
784
        $cropping_bottom_vbox->pack_start( $yw_hbox, FALSE, FALSE, 3 );
 
785
        $cropping_bottom_vbox->pack_start( $ww_hbox, FALSE, FALSE, 3 );
 
786
        $cropping_bottom_vbox->pack_start( $hw_hbox, FALSE, FALSE, 3 );
 
787
        $cropping_bottom_vbox->pack_start( $cropping_bottom_vbox_b, TRUE, TRUE, 3 );    
 
788
 
 
789
        #nice frame as well
 
790
        my $crop_frame_label = Gtk2::Label->new;
 
791
        $crop_frame_label->set_markup( "<b>" . $self->{_d}->get("Selection") . "</b>" );
 
792
 
 
793
        my $crop_frame = Gtk2::Frame->new();
 
794
        $crop_frame->set_border_width(5);
 
795
        $crop_frame->set_label_widget($crop_frame_label);
 
796
        $crop_frame->set_shadow_type('none');
 
797
 
 
798
        $crop_frame->add($cropping_bottom_vbox);
 
799
 
 
800
        return $crop_frame;
 
801
}       
 
802
 
 
803
sub adjust_crop_values{
 
804
        my $self        = shift;
 
805
        my $pixbuf      = shift;
 
806
 
 
807
        #block 'value-change' handlers for widgets
 
808
        #so we do not apply the changes twice
 
809
        $self->{_x_spin_w}->signal_handler_block ($self->{_x_spin_w_handler});
 
810
        $self->{_y_spin_w}->signal_handler_block ($self->{_y_spin_w_handler});
 
811
        $self->{_width_spin_w}->signal_handler_block ($self->{_width_spin_w_handler});
 
812
        $self->{_height_spin_w}->signal_handler_block ($self->{_height_spin_w_handler});
 
813
        
 
814
        my $s = $self->{_selector}->get_selection;
 
815
 
 
816
        if ($s) {
 
817
                $self->{_x_spin_w}->set_value( $s->x );
 
818
                $self->{_x_spin_w}->set_range( 0, $pixbuf->get_width - $s->width );
 
819
                
 
820
                $self->{_y_spin_w}->set_value( $s->y );
 
821
                $self->{_y_spin_w}->set_range( 0, $pixbuf->get_height - $s->height );
 
822
                
 
823
                $self->{_width_spin_w}->set_value( $s->width );
 
824
                $self->{_width_spin_w}->set_range( 0, $pixbuf->get_width - $s->x );
 
825
                
 
826
                $self->{_height_spin_w}->set_value( $s->height );                               
 
827
                $self->{_height_spin_w}->set_range( 0, $pixbuf->get_height - $s->y );                   
 
828
        }       
 
829
 
 
830
        #unblock 'value-change' handlers for widgets
 
831
        $self->{_x_spin_w}->signal_handler_unblock ($self->{_x_spin_w_handler});
 
832
        $self->{_y_spin_w}->signal_handler_unblock ($self->{_y_spin_w_handler});
 
833
        $self->{_width_spin_w}->signal_handler_unblock ($self->{_width_spin_w_handler});
 
834
        $self->{_height_spin_w}->signal_handler_unblock ($self->{_height_spin_w_handler});
 
835
        
 
836
        return TRUE;
 
837
 
 
838
}
 
839
 
354
840
sub push_to_statusbar {
355
841
        my $self = shift;
356
842
        my $x = shift;
357
843
        my $y = shift;
358
844
        my $action = shift || 'none';
359
845
 
360
 
        my $d = $self->{_shutter_common}->get_gettext;
361
 
 
362
846
        my $status_text = int( $x ) . " x " . int( $y );
363
847
                
364
848
        if ( $self->{_current_mode} == 10 ) {
365
849
 
366
850
                if($action eq 'resize'){
367
 
                        $status_text .= " ".$d->get("Click-Drag to scale (try Control to scale uniformly)");    
 
851
                        $status_text .= " ".$self->{_d}->get("Click-Drag to scale (try Control to scale uniformly)");   
 
852
                }elsif($action eq 'canvas_resize'){
 
853
                        $status_text .= " ".$self->{_d}->get("Click-Drag to resize the canvas");                                
368
854
                }
369
855
                
370
 
        } elsif ( $self->{_current_mode} == 20 ) {
 
856
        } elsif ( $self->{_current_mode} == 20 || $self->{_current_mode} == 30) {
371
857
 
372
 
                $status_text .= " ".$d->get("Click to paint (try Control or Shift for a straight line)");
 
858
                $status_text .= " ".$self->{_d}->get("Click to paint (try Control or Shift for a straight line)");
373
859
                
374
 
        } elsif ( $self->{_current_mode} == 30 ) {
375
 
 
376
 
                $status_text .= " ".$d->get("Click-Drag to create a new straight line");
377
 
 
378
860
        } elsif ( $self->{_current_mode} == 40 ) {
379
861
 
380
 
                $status_text .= " ".$d->get("Click-Drag to create a new rectangle");
 
862
                $status_text .= " ".$self->{_d}->get("Click-Drag to create a new straight line");
381
863
 
382
864
        } elsif ( $self->{_current_mode} == 50 ) {
383
865
 
384
 
                $status_text .= " ".$d->get("Click-Drag to create a new ellipse");
 
866
                $status_text .= " ".$self->{_d}->get("Click-Drag to create a new arrow");
385
867
 
386
868
        } elsif ( $self->{_current_mode} == 60 ) {
387
869
 
388
 
                $status_text .= " ".$d->get("Click-Drag to add a new text area");
 
870
                $status_text .= " ".$self->{_d}->get("Click-Drag to create a new rectangle");
389
871
 
390
872
        } elsif ( $self->{_current_mode} == 70 ) {
391
873
 
392
 
                $status_text .= " ".$d->get("Click to censor (try Control or Shift for a straight line)");
 
874
                $status_text .= " ".$self->{_d}->get("Click-Drag to create a new ellipse");
393
875
 
394
876
        } elsif ( $self->{_current_mode} == 80 ) {
395
877
 
396
 
                $status_text .= " ".$d->get("Select an object to delete it from the canvas");
 
878
                $status_text .= " ".$self->{_d}->get("Click-Drag to add a new text area");
397
879
 
398
880
        } elsif ( $self->{_current_mode} == 90 ) {
399
881
 
400
 
                $status_text .= " ".$d->get("Delete all objects");
401
 
 
402
 
        }       
 
882
                $status_text .= " ".$self->{_d}->get("Click to censor (try Control or Shift for a straight line)");
 
883
 
 
884
        } elsif ( $self->{_current_mode} == 100 ) {
 
885
 
 
886
                $status_text .= " ".$self->{_d}->get("Click to add an auto-increment shape");
 
887
 
 
888
        } elsif ( $self->{_current_mode} == 110 ) {
 
889
 
 
890
                #nothing to do here....
 
891
 
 
892
        }
403
893
 
404
894
        #update statusbar
405
895
        $self->{_drawing_statusbar}->push( 0, $status_text );
412
902
        my $self   = shift;
413
903
        my $action = shift;
414
904
 
 
905
        #~ print "change_drawing_tool_cb\n";
 
906
 
415
907
        eval { $self->{_current_mode} = $action->get_current_value; };
416
908
        if ($@) {
417
909
                $self->{_current_mode} = $action;
418
910
        }
419
911
 
420
 
        #define own icons
421
 
        my $dicons = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool";
422
912
        my $cursor = Gtk2::Gdk::Cursor->new('left-ptr');
423
913
 
 
914
        #tool is switched from "highlighter" OR censor to something else (excluding select tool)
 
915
        if( $self->{_current_mode} != 10  &&
 
916
                $self->{_current_mode} != 30  && 
 
917
                $self->{_current_mode} != 90  && 
 
918
                $self->{_current_mode} != 110 ){
 
919
        
 
920
                $self->restore_drawing_properties;
 
921
        
 
922
        }
 
923
        
 
924
        #show drawing tool widgets
 
925
        if($self->{_current_mode} != 110){
 
926
 
 
927
                #show drawing tool widgets
 
928
                $self->{_table}->show_all;
 
929
                $self->{_bhbox}->show_all;
 
930
 
 
931
                $self->{_drawing_inner_vbox}->show_all; 
 
932
 
 
933
                #hide cropping tool             
 
934
                $self->{_drawing_inner_vbox_c}->hide_all;       
 
935
 
 
936
        }
 
937
 
424
938
        if ( $self->{_current_mode} == 10 ) {
425
939
 
426
940
                $self->{_current_mode_descr} = "select";
428
942
        } elsif ( $self->{_current_mode} == 20 ) {
429
943
 
430
944
                $self->{_current_mode_descr} = "freehand";
431
 
                $cursor = Gtk2::Gdk::Cursor->new('pencil');
432
 
 
 
945
        
433
946
        } elsif ( $self->{_current_mode} == 30 ) {
434
947
 
 
948
                $self->{_current_mode_descr} = "highlighter";
 
949
                $cursor = Gtk2::Gdk::Cursor->new('dotbox');
 
950
 
 
951
        } elsif ( $self->{_current_mode} == 40 ) {
 
952
 
435
953
                $self->{_current_mode_descr} = "line";
436
 
                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
437
 
                        Gtk2::Gdk::Display->get_default,
438
 
                        Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-line.png"),
439
 
                        Gtk2::IconSize->lookup('menu')
440
 
                );
441
 
 
442
 
        } elsif ( $self->{_current_mode} == 40 ) {
 
954
 
 
955
        } elsif ( $self->{_current_mode} == 50 ) {
 
956
 
 
957
                $self->{_current_mode_descr} = "arrow";
 
958
 
 
959
        } elsif ( $self->{_current_mode} == 60 ) {
443
960
 
444
961
                $self->{_current_mode_descr} = "rect";
445
 
                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
446
 
                        Gtk2::Gdk::Display->get_default,
447
 
                        Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-rectangle.png"),
448
 
                        Gtk2::IconSize->lookup('menu')
449
 
                );
450
962
 
451
 
        } elsif ( $self->{_current_mode} == 50 ) {
 
963
        } elsif ( $self->{_current_mode} == 70 ) {
452
964
 
453
965
                $self->{_current_mode_descr} = "ellipse";
454
 
                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
455
 
                        Gtk2::Gdk::Display->get_default,
456
 
                        Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-ellipse.png"),
457
 
                        Gtk2::IconSize->lookup('menu')
458
 
                );
459
966
 
460
 
        } elsif ( $self->{_current_mode} == 60 ) {
 
967
        } elsif ( $self->{_current_mode} == 80 ) {
461
968
 
462
969
                $self->{_current_mode_descr} = "text";
463
 
                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
464
 
                        Gtk2::Gdk::Display->get_default,
465
 
                        Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-text.png"),
466
 
                        Gtk2::IconSize->lookup('menu')
467
 
                );
468
 
        } elsif ( $self->{_current_mode} == 70 ) {
 
970
 
 
971
        } elsif ( $self->{_current_mode} == 90 ) {
469
972
 
470
973
                $self->{_current_mode_descr} = "censor";
471
 
                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
472
 
                        Gtk2::Gdk::Display->get_default,
473
 
                        Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-censor.png"),
474
 
                        Gtk2::IconSize->lookup('menu')
475
 
                );
476
 
 
477
 
        } elsif ( $self->{_current_mode} == 80 ) {
478
 
 
479
 
                $self->{_current_mode_descr} = "clear";
480
 
 
481
 
        } elsif ( $self->{_current_mode} == 90 ) {
482
 
 
483
 
                $self->{_current_mode_descr} = "clear_all";
484
 
 
485
 
                foreach(keys %{$self->{_items}}){
486
 
                        $self->clear_item_from_canvas($self->{_items}{$_});     
 
974
 
 
975
        } elsif ( $self->{_current_mode} == 100 ) {
 
976
 
 
977
                $self->{_current_mode_descr} = "number";
 
978
 
 
979
        } elsif ( $self->{_current_mode} == 110 ) {
 
980
 
 
981
                $self->{_current_mode_descr} = "crop";
 
982
                
 
983
                #show cropping tool             
 
984
                $self->{_view}->set_pixbuf($self->save(TRUE));
 
985
                $self->{_view}->set_zoom(1);
 
986
                $self->{_view}->show_all;
 
987
 
 
988
                $self->{_drawing_inner_vbox_c}->show_all;       
 
989
 
 
990
                #hide drawing tool widgets
 
991
                $self->{_drawing_inner_vbox}->hide_all;
 
992
 
 
993
        }
 
994
 
 
995
        if($self->{_canvas} && $self->{_canvas}->window){
 
996
                
 
997
                if(exists $self->{_cursors}{$self->{_current_mode_descr}}){
 
998
                        $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
 
999
                                Gtk2::Gdk::Display->get_default,
 
1000
                                $self->{_cursors}{$self->{_current_mode_descr}},
 
1001
                                $self->{_cursors}{$self->{_current_mode_descr}}{'x_hot'},
 
1002
                                $self->{_cursors}{$self->{_current_mode_descr}}{'y_hot'},
 
1003
                        );
487
1004
                }
488
 
                
489
 
                $self->set_drawing_action(0);
490
 
                $self->change_drawing_tool_cb(10);
491
 
 
492
 
        } 
493
 
 
494
 
        if($self->{_canvas}){
 
1005
 
495
1006
                $self->{_canvas}->window->set_cursor($cursor);
496
1007
        }
497
1008
 
500
1011
 
501
1012
sub zoom_in_cb {
502
1013
        my $self = shift;
503
 
        $self->{_canvas}->set_scale( $self->{_canvas}->get_scale + 0.25 );
504
 
        $self->adjust_rulers;
 
1014
        
 
1015
        if($self->{_current_mode_descr} ne "crop"){
 
1016
                $self->{_canvas}->set_scale( $self->{_canvas}->get_scale + 0.2 );
 
1017
                #~ $self->adjust_rulers;
 
1018
        }else{
 
1019
                $self->{_view}->zoom_in;                
 
1020
        }
 
1021
 
505
1022
        return TRUE;
506
1023
}
507
1024
 
508
1025
sub zoom_out_cb {
509
1026
        my $self      = shift;
510
 
        my $new_scale = $self->{_canvas}->get_scale - 0.25;
511
 
        if ( $new_scale < 0.25 ) {
512
 
                $self->{_canvas}->set_scale(0.25);
513
 
        } else {
514
 
                $self->{_canvas}->set_scale($new_scale);
 
1027
        
 
1028
        if($self->{_current_mode_descr} ne "crop"){
 
1029
                my $new_scale = $self->{_canvas}->get_scale - 0.2;
 
1030
                if ( $new_scale < 0.2 ) {
 
1031
                        $self->{_canvas}->set_scale(0.2);
 
1032
                } else {
 
1033
                        $self->{_canvas}->set_scale($new_scale);
 
1034
                }
 
1035
                #~ $self->adjust_rulers;
 
1036
        }else{
 
1037
                $self->{_view}->zoom_out;
515
1038
        }
516
 
        $self->adjust_rulers;
 
1039
 
517
1040
        return TRUE;
518
1041
}
519
1042
 
520
1043
sub zoom_normal_cb {
521
1044
        my $self = shift;
522
 
        $self->{_canvas}->set_scale(1);
523
 
        $self->adjust_rulers;
 
1045
        
 
1046
        if($self->{_current_mode_descr} ne "crop"){
 
1047
                $self->{_canvas}->set_scale(1);
 
1048
                #~ $self->adjust_rulers;
 
1049
        }else{
 
1050
                $self->{_view}->set_zoom(1);    
 
1051
        }
 
1052
        
524
1053
        return TRUE;
525
1054
}
526
1055
 
527
1056
sub adjust_rulers {
528
 
        my $self = shift;
529
 
        my $ev   = shift;
530
 
        my $item = shift;
 
1057
        my ($self, $ev, $item) = @_;
 
1058
        
 
1059
        my $s = $self->{_canvas}->get_scale;
 
1060
 
531
1061
        my ( $hlower, $hupper, $hposition, $hmax_size ) = $self->{_hruler}->get_range;
532
1062
        my ( $vlower, $vupper, $vposition, $vmax_size ) = $self->{_vruler}->get_range;
533
 
 
534
 
        my $s = $self->{_canvas}->get_scale;
535
 
 
536
 
        my ( $x, $y, $width, $height, $depth ) = $self->{_canvas}->window->get_geometry;
537
 
        my $ha = $self->{_scrolled_window}->get_hadjustment->value / $s;
538
 
        my $va = $self->{_scrolled_window}->get_vadjustment->value / $s;
539
 
 
540
 
        my $xpos = 0;
541
 
        my $ypos = 0;
542
 
        if ($ev) {
543
 
                $xpos = $ev->x;
544
 
                $ypos = $ev->y;
 
1063
                
 
1064
        if($ev){
 
1065
                
 
1066
                my $copy_event = $ev->copy;
 
1067
                                                
 
1068
                #modify event to respect scrollbars and canvas scale
 
1069
                $copy_event->x( ($copy_event->x_root - $hlower) * $s);
 
1070
                $copy_event->y( ($copy_event->y_root - $vlower) * $s);  
 
1071
 
 
1072
                $self->{_hruler}->signal_emit('motion-notify-event', $copy_event);
 
1073
                $self->{_vruler}->signal_emit('motion-notify-event', $copy_event);
 
1074
        
 
1075
        }else{
 
1076
 
 
1077
                #modify rulers (e.g. done when scrolling or zooming)
 
1078
                if($self->{_hruler} && $self->{_hruler}){
 
1079
 
 
1080
                        my ( $x, $y, $width, $height, $depth ) = $self->{_canvas}->window->get_geometry;
 
1081
                        my $ha = $self->{_scrolled_window}->get_hadjustment->value / $s;
 
1082
                        my $va = $self->{_scrolled_window}->get_vadjustment->value / $s;
 
1083
 
 
1084
                        $self->{_hruler}->set_range( $ha, $ha + $width  / $s, 0, $hmax_size );
 
1085
                        $self->{_vruler}->set_range( $va, $va + $height / $s, 0, $vmax_size );
 
1086
 
 
1087
                }
 
1088
                
545
1089
        }
546
1090
 
547
 
        $self->{_hruler}->set_range( $ha, $ha + $width / $s,  $xpos, $hmax_size );
548
 
        $self->{_vruler}->set_range( $va, $va + $height / $s, $ypos, $vmax_size );
549
1091
        return TRUE;
550
1092
}
551
1093
 
552
1094
sub quit {
553
 
        my $self         = shift;
554
 
        my $show_warning = shift;
555
 
 
556
 
        my $d = $self->{_shutter_common}->get_gettext;
 
1095
        my ($self, $show_warning) = @_;
557
1096
 
558
1097
        my ( $name, $folder, $type ) = fileparse( $self->{_filename}, '\..*' );
559
1098
 
560
 
        #we are closing the drawing tool as well after saving the changes
561
 
        #so save changes to a file in the shutter folder
 
1099
        #save settings to a file in the shutter folder
562
1100
        #is there already a .shutter folder?
563
1101
        mkdir("$ENV{ 'HOME' }/.shutter")
564
1102
                unless ( -d "$ENV{ 'HOME' }/.shutter" );
565
1103
 
566
 
        $self->save_settings;
567
 
 
568
1104
        if ( $show_warning && scalar( keys %{ $self->{_items} } ) > 0 ) {
569
1105
 
570
1106
                #warn the user if there are any unsaved changes
571
1107
                my $warn_dialog = Gtk2::MessageDialog->new( $self->{_drawing_window}, [qw/modal destroy-with-parent/], 'other', 'none', undef );
572
1108
 
573
1109
                #set question text
574
 
                $warn_dialog->set( 'text' => sprintf( $d->get("Save the changes to image %s before closing?"), "'$name$type'" ) );
 
1110
                $warn_dialog->set( 'text' => sprintf( $self->{_d}->get("Save the changes to image %s before closing?"), "'$name$type'" ) );
575
1111
 
576
1112
                #set text...
577
1113
                $self->update_warning_text($warn_dialog);
587
1123
 
588
1124
                $warn_dialog->set( 'image' => Gtk2::Image->new_from_stock( 'gtk-save', 'dialog' ) );
589
1125
 
590
 
                $warn_dialog->set( 'title' => $d->get("Close") . " " . $name . $type );
 
1126
                $warn_dialog->set( 'title' => $self->{_d}->get("Close") . " " . $name . $type );
591
1127
 
592
1128
                #don't save button
593
 
                my $dsave_btn = Gtk2::Button->new_with_mnemonic( $d->get("Do_n't save") );
 
1129
                my $dsave_btn = Gtk2::Button->new_with_mnemonic( $self->{_d}->get("Do_n't save") );
594
1130
                $dsave_btn->set_image( Gtk2::Image->new_from_stock( 'gtk-delete', 'button' ) );
595
1131
 
596
1132
                #cancel button
615
1151
                } elsif ( $response == 30 ) {
616
1152
                        $self->save();
617
1153
                }
618
 
 
 
1154
                
 
1155
                $self->{_drawing_window}->hide if $self->{_drawing_window};
 
1156
                $warn_dialog->hide;
619
1157
                $warn_dialog->destroy;
620
1158
 
621
1159
        }
 
1160
        
 
1161
        $self->save_settings;
 
1162
        
 
1163
        if($self->{_selector_handler}){ 
 
1164
                $self->{_selector}->signal_handler_disconnect ($self->{_selector_handler});
 
1165
        }
 
1166
 
 
1167
        $self->{_drawing_window}->hide if $self->{_drawing_window};
 
1168
 
622
1169
        $self->{_drawing_window}->destroy if $self->{_drawing_window};
 
1170
        
 
1171
        #delete hash entries to avoid any
 
1172
        #possible circularity
 
1173
        #
 
1174
        #this would lead to a memory leak
 
1175
        foreach ( keys %{ $self } ) {
 
1176
                delete $self->{$_};
 
1177
        }       
 
1178
 
623
1179
        Gtk2->main_quit();
624
1180
 
625
1181
        return FALSE;
626
1182
}
627
1183
 
628
1184
sub update_warning_text {
629
 
        my $self        = shift;
630
 
        my $warn_dialog = shift;
631
 
 
632
 
        my $d = $self->{_shutter_common}->get_gettext;
 
1185
        my ($self, $warn_dialog) = @_;
633
1186
 
634
1187
        my $minutes = int( ( time - $self->{_start_time} ) / 60 );
635
1188
        $minutes = 1 if $minutes == 0;
636
1189
        $warn_dialog->set(
637
1190
                'secondary-text' => sprintf(
638
 
                        $d->nget(
 
1191
                        $self->{_d}->nget(
639
1192
                                "If you don't save the image, changes from the last minute will be lost",
640
1193
                                "If you don't save the image, changes from the last %d minutes will be lost",
641
1194
                                $minutes
658
1211
        my $settings_xml;
659
1212
        if ( $shutter_hfunct->file_exists($settingsfile) ) {
660
1213
                eval {
661
 
                        $settings_xml = XMLin($settingsfile);
 
1214
                        $settings_xml = XMLin( IO::File->new($settingsfile) );
662
1215
        
663
1216
                        #window size and position
664
1217
                        if($settings_xml->{'drawing'}->{'x'} && $settings_xml->{'drawing'}->{'y'}){
671
1224
                        
672
1225
                        #current mode
673
1226
                        if($settings_xml->{'drawing'}->{'mode'}){
674
 
                                $self->set_drawing_action($settings_xml->{'drawing'}->{'mode'} % 10);
675
 
                                $self->change_drawing_tool_cb($settings_xml->{'drawing'}->{'mode'});
 
1227
                                $self->{_current_mode} = $settings_xml->{'drawing'}->{'mode'};
676
1228
                        }
677
1229
                                        
678
1230
                        #autoscroll
684
1236
                        $self->{_fill_color_alpha}   = $settings_xml->{'drawing'}->{'fill_color_alpha'};
685
1237
                        $self->{_stroke_color}       = Gtk2::Gdk::Color->parse( $settings_xml->{'drawing'}->{'stroke_color'} );
686
1238
                        $self->{_stroke_color_alpha} = $settings_xml->{'drawing'}->{'stroke_color_alpha'};
687
 
 
688
1239
                        #line_width
689
1240
                        $self->{_line_width} = $settings_xml->{'drawing'}->{'line_width'};
690
 
 
691
1241
                        #font
692
 
                        $self->{_font} = $settings_xml->{'drawing'}->{'font'};
 
1242
                        $self->{_font} = $settings_xml->{'drawing'}->{'font'};  
 
1243
                        
693
1244
                };
694
1245
                if ($@) {
695
1246
                        warn "ERROR: Settings of DrawingTool could not be restored: $@ - ignoring\n";
701
1252
sub save_settings {
702
1253
        my $self = shift;
703
1254
 
 
1255
        #to avoid saving the properties of the highlighter
 
1256
        #this does not make any sense
 
1257
        $self->restore_drawing_properties;
 
1258
 
704
1259
        #settings file
705
1260
        my $settingsfile = "$ENV{ HOME }/.shutter/drawingtool.xml";
706
1261
 
 
1262
        #hash to store settings
 
1263
        my %settings;
 
1264
 
 
1265
        #window size and position
 
1266
        my ($w, $h) = $self->{_drawing_window}->get_size;
 
1267
        my ($x, $y) = $self->{_drawing_window}->get_position;
 
1268
        $settings{'drawing'}->{'x'} = $x;
 
1269
        $settings{'drawing'}->{'y'} = $y;
 
1270
        $settings{'drawing'}->{'width'} = $w;
 
1271
        $settings{'drawing'}->{'height'} = $h;
 
1272
        
 
1273
        #current action
 
1274
        #but don't save the crop tool as last action
 
1275
        #as it would be confusing to open the drawing tool 
 
1276
        #with crop tool enabled
 
1277
        if($self->{_current_mode_descr} ne "crop"){
 
1278
                $settings{'drawing'}->{'mode'} = $self->{_current_mode}; 
 
1279
        }else{
 
1280
                $settings{'drawing'}->{'mode'} = 10;
 
1281
        }
 
1282
 
 
1283
        #autoscroll
 
1284
        my $autoscroll_toggle = $self->{_uimanager}->get_widget("/MenuBar/Edit/Autoscroll");
 
1285
        $settings{'drawing'}->{'autoscroll'} = $autoscroll_toggle->get_active();
 
1286
 
 
1287
        #drawing colors
 
1288
        $settings{'drawing'}->{'fill_color'}
 
1289
                = sprintf( "#%04x%04x%04x", $self->{_fill_color}->red, $self->{_fill_color}->green, $self->{_fill_color}->blue );
 
1290
        $settings{'drawing'}->{'fill_color_alpha'} = $self->{_fill_color_alpha};
 
1291
        $settings{'drawing'}->{'stroke_color'}
 
1292
                = sprintf( "#%04x%04x%04x", $self->{_stroke_color}->red, $self->{_stroke_color}->green, $self->{_stroke_color}->blue );
 
1293
        $settings{'drawing'}->{'stroke_color_alpha'} = $self->{_stroke_color_alpha};
 
1294
 
 
1295
        #line_width
 
1296
        $settings{'drawing'}->{'line_width'} = $self->{_line_width};
 
1297
 
 
1298
        #font
 
1299
        $settings{'drawing'}->{'font'} = $self->{_font};
 
1300
 
707
1301
        eval {
708
 
                open( SETTFILE, ">$settingsfile" );
709
 
 
710
 
                my %settings;    #hash to store settings
711
 
 
712
 
                #window size and position
713
 
                my ($w, $h) = $self->{_drawing_window}->get_size;
714
 
                my ($x, $y) = $self->{_drawing_window}->get_position;
715
 
                $settings{'drawing'}->{'x'} = $x;
716
 
                $settings{'drawing'}->{'y'} = $y;
717
 
                $settings{'drawing'}->{'width'} = $w;
718
 
                $settings{'drawing'}->{'height'} = $h;
719
 
                
720
 
                #current action
721
 
                $settings{'drawing'}->{'mode'} = $self->{_current_mode}; 
722
 
 
723
 
                #autoscroll
724
 
                my $autoscroll_toggle = $self->{_uimanager}->get_widget("/MenuBar/Edit/Autoscroll");
725
 
                $settings{'drawing'}->{'autoscroll'} = $autoscroll_toggle->get_active();
726
 
 
727
 
                #drawing colors
728
 
                $settings{'drawing'}->{'fill_color'}
729
 
                        = sprintf( "#%04x%04x%04x", $self->{_fill_color}->red, $self->{_fill_color}->green, $self->{_fill_color}->blue );
730
 
                $settings{'drawing'}->{'fill_color_alpha'} = $self->{_fill_color_alpha};
731
 
                $settings{'drawing'}->{'stroke_color'}
732
 
                        = sprintf( "#%04x%04x%04x", $self->{_stroke_color}->red, $self->{_stroke_color}->green, $self->{_stroke_color}->blue );
733
 
                $settings{'drawing'}->{'stroke_color_alpha'} = $self->{_stroke_color_alpha};
734
 
 
735
 
                #line_width
736
 
                $settings{'drawing'}->{'line_width'} = $self->{_line_width};
737
 
 
738
 
                #font
739
 
                $settings{'drawing'}->{'font'} = $self->{_font};
740
 
 
741
 
                #settings
 
1302
 
 
1303
                #save to file
 
1304
                open( SETTFILE, ">$settingsfile" ) or die $!;
742
1305
                print SETTFILE XMLout( \%settings );
743
 
 
744
 
                close(SETTFILE);
 
1306
                close(SETTFILE) or die $!;
 
1307
                
745
1308
        };
746
1309
        if ($@) {
747
1310
                warn "ERROR: Settings of DrawingTool could not be saved: $@ - ignoring\n";
751
1314
}
752
1315
 
753
1316
sub save {
754
 
        my $self = shift;
755
 
 
756
 
        #we are closing the drawing tool as well after saving the changes
757
 
        #so save changes to a file in the shutter folder
758
 
        #is there already a .shutter folder?
759
 
        mkdir("$ENV{ 'HOME' }/.shutter")
760
 
                unless ( -d "$ENV{ 'HOME' }/.shutter" );
761
 
 
762
 
        $self->save_settings;
 
1317
        my $self                = shift;
 
1318
        my $save_to_mem = shift;
763
1319
 
764
1320
        #make sure not to save the bounding rectangles
765
1321
        $self->deactivate_all;
766
1322
 
767
 
        my $surface = Cairo::ImageSurface->create( 'argb32', $self->{_canvas_bg}->get('width'), $self->{_canvas_bg}->get('height') );
768
 
 
 
1323
        #hide line and change background color, e.g. for saving
 
1324
        $self->handle_bg_rects('hide');
 
1325
 
 
1326
        #image format supports transparency or not
 
1327
        #we need to support more formats here I think
 
1328
        if($self->{_filetype} eq 'jpeg' || $self->{_filetype} eq 'bmp'){        
 
1329
                $self->{_canvas_bg_rect}->set(
 
1330
                        'fill-pattern'  => $self->create_color('white', 1.0),
 
1331
                        'line-width'    => 0,
 
1332
                );
 
1333
        }else{
 
1334
                $self->{_canvas_bg_rect}->set(
 
1335
                        'visibility' => 'hidden',
 
1336
                );              
 
1337
        }
 
1338
 
 
1339
        my $surface = Cairo::ImageSurface->create( 'argb32', $self->{_canvas_bg_rect}->get('width'), $self->{_canvas_bg_rect}->get('height') );
 
1340
        #~ my $surface = Cairo::SvgSurface->create( '/home/mario/Desktop/test.svg', $self->{_canvas_bg_rect}->get('width'), $self->{_canvas_bg_rect}->get('height') );
 
1341
        
769
1342
        my $cr   = Cairo::Context->create($surface);
770
 
        my $root = $self->{_canvas}->get_root_item;
771
 
        $root->paint( $cr, $self->{_canvas_bg}->get_bounds, 1 );
 
1343
        #~ $self->{_canvas}->get_root_item->paint( $cr, $self->{_canvas_bg_rect}->get_bounds, 1 );
 
1344
        $self->{_canvas}->render( $cr, $self->{_canvas_bg_rect}->get_bounds, 1 );
772
1345
 
773
1346
        my $loader = Gtk2::Gdk::PixbufLoader->new;
774
1347
        $surface->write_to_png_stream(
780
1353
        $loader->close;
781
1354
        my $pixbuf = $loader->get_pixbuf;
782
1355
 
 
1356
        #just return pixbuf
 
1357
        if ($save_to_mem){
 
1358
                #update the canvas_rect again
 
1359
                $self->{_canvas_bg_rect}->set(
 
1360
                        'fill-pattern'  => $self->create_color('gray', 1.0),
 
1361
                        'line-width'    => 1,
 
1362
                        'visibility'    => 'visible',
 
1363
                        
 
1364
                );              
 
1365
                $self->handle_bg_rects('show');
 
1366
                return $pixbuf ;
 
1367
        }
 
1368
                
783
1369
        #save pixbuf to file
784
1370
        my $pixbuf_save = Shutter::Pixbuf::Save->new( $self->{_shutter_common}, $self->{_drawing_window} );
785
1371
        return $pixbuf_save->save_pixbuf_to_file($pixbuf, $self->{_filename}, $self->{_filename}, $self->{_filetype});
840
1426
sub event_item_on_motion_notify {
841
1427
        my ( $self, $item, $target, $ev ) = @_;
842
1428
 
843
 
        $self->adjust_rulers($ev);
 
1429
        $self->adjust_rulers($ev, $item);
844
1430
        
845
1431
        #autoscroll if enabled
846
1432
        if (   $self->{_autoscroll}
847
 
                && $self->{_current_mode_descr} ne "clear"
848
1433
                && $ev->state >= 'button1-mask' )
849
1434
        {
850
 
 
 
1435
                
851
1436
                my ( $x, $y, $width, $height, $depth ) = $self->{_canvas}->window->get_geometry;
852
 
 
853
 
                my $scale = $self->{_canvas}->get_scale;
 
1437
                my $s  = $self->{_canvas}->get_scale;
 
1438
                my $ha = $self->{_scrolled_window}->get_hadjustment->value;
 
1439
                my $va = $self->{_scrolled_window}->get_vadjustment->value;
854
1440
 
855
1441
                #autoscroll >> down and right
856
 
                if (   $ev->x > ( $self->{_scrolled_window}->get_hadjustment->value / $scale + $width / $scale - 100 / $scale )
857
 
                        && $ev->y > ( $self->{_scrolled_window}->get_vadjustment->value / $scale + $height / $scale - 100 / $scale ) )
 
1442
                if (   $ev->x_root > ( $ha / $s + $width / $s - 100 / $s )
 
1443
                        && $ev->y_root > ( $va / $s + $height / $s - 100 / $s ) )
858
1444
                {
859
1445
                        $self->{_canvas}->scroll_to(
860
 
                                $self->{_scrolled_window}->get_hadjustment->value / $scale + 10 / $scale,
861
 
                                $self->{_scrolled_window}->get_vadjustment->value / $scale + 10 / $scale
862
 
                        );
863
 
                } elsif ( $ev->x > ( $self->{_scrolled_window}->get_hadjustment->value / $scale + $width / $scale - 100 / $scale ) ) {
864
 
                        $self->{_canvas}->scroll_to(
865
 
                                $self->{_scrolled_window}->get_hadjustment->value / $scale + 10 / $scale,
866
 
                                $self->{_scrolled_window}->get_vadjustment->value / $scale
867
 
                        );
868
 
                } elsif ( $ev->y > ( $self->{_scrolled_window}->get_vadjustment->value / $scale + $height / $scale - 100 / $scale ) ) {
869
 
                        $self->{_canvas}->scroll_to(
870
 
                                $self->{_scrolled_window}->get_hadjustment->value / $scale,
871
 
                                $self->{_scrolled_window}->get_vadjustment->value / $scale + 10 / $scale
 
1446
                                $ha / $s + 10 / $s,
 
1447
                                $va / $s + 10 / $s
 
1448
                        );
 
1449
                } elsif ( $ev->x_root > ( $ha / $s + $width / $s - 100 / $s ) ) {
 
1450
                        $self->{_canvas}->scroll_to(
 
1451
                                $ha / $s + 10 / $s,
 
1452
                                $va / $s
 
1453
                        );
 
1454
                } elsif ( $ev->y_root > ( $va / $s + $height / $s - 100 / $s ) ) {
 
1455
                        $self->{_canvas}->scroll_to(
 
1456
                                $ha / $s,
 
1457
                                $va / $s + 10 / $s
872
1458
                        );
873
1459
                }
874
1460
 
875
1461
                #autoscroll >> up and left
876
 
                if (   $ev->x < ( $self->{_scrolled_window}->get_hadjustment->value / $scale + 100 / $scale )
877
 
                        && $ev->y < ( $self->{_scrolled_window}->get_vadjustment->value / $scale + 100 / $scale ) )
 
1462
                if (   $ev->x_root < ( $ha / $s + 100 / $s )
 
1463
                        && $ev->y_root < ( $va / $s + 100 / $s ) )
878
1464
                {
879
1465
                        $self->{_canvas}->scroll_to(
880
 
                                $self->{_scrolled_window}->get_hadjustment->value / $scale - 10 / $scale,
881
 
                                $self->{_scrolled_window}->get_vadjustment->value / $scale - 10 / $scale
882
 
                        );
883
 
                } elsif ( $ev->x < ( $self->{_scrolled_window}->get_hadjustment->value / $scale + 100 / $scale ) ) {
884
 
                        $self->{_canvas}->scroll_to(
885
 
                                $self->{_scrolled_window}->get_hadjustment->value / $scale - 10 / $scale,
886
 
                                $self->{_scrolled_window}->get_vadjustment->value / $scale
887
 
                        );
888
 
                } elsif ( $ev->y < ( $self->{_scrolled_window}->get_vadjustment->value / $scale + 100 / $scale ) ) {
889
 
                        $self->{_canvas}->scroll_to(
890
 
                                $self->{_scrolled_window}->get_hadjustment->value / $scale,
891
 
                                $self->{_scrolled_window}->get_vadjustment->value / $scale - 10 / $scale
 
1466
                                $ha / $s - 10 / $s,
 
1467
                                $va / $s - 10 / $s
 
1468
                        );
 
1469
                } elsif ( $ev->x_root < ( $ha / $s + 100 / $s ) ) {
 
1470
                        $self->{_canvas}->scroll_to(
 
1471
                                $ha / $s - 10 / $s,
 
1472
                                $va / $s
 
1473
                        );
 
1474
                } elsif ( $ev->y_root < ( $va / $s + 100 / $s ) ) {
 
1475
                        $self->{_canvas}->scroll_to(
 
1476
                                $ha / $s,
 
1477
                                $va / $s - 10 / $s
892
1478
                        );
893
1479
                }
894
1480
        }
898
1484
 
899
1485
                if ( $item->isa('Goo::Canvas::Rect') ) {
900
1486
 
901
 
                        my $new_x = $self->{_items}{$item}->get('x') + $ev->x - $item->{drag_x};
902
 
                        my $new_y = $self->{_items}{$item}->get('y') + $ev->y - $item->{drag_y};
 
1487
                        my $new_x = $self->{_items}{$item}->get('x') + $ev->x_root - $item->{drag_x};
 
1488
                        my $new_y = $self->{_items}{$item}->get('y') + $ev->y_root - $item->{drag_y};
903
1489
 
904
1490
                        $self->{_items}{$item}->set(
905
1491
                                'x' => $new_x,
906
1492
                                'y' => $new_y,
907
1493
                        );
908
1494
 
909
 
                        $item->{drag_x} = $ev->x;
910
 
                        $item->{drag_y} = $ev->y;
 
1495
                        $item->{drag_x} = $ev->x_root;
 
1496
                        $item->{drag_y} = $ev->y_root;
911
1497
 
912
1498
                        $self->handle_rects( 'update', $item );
913
1499
                        $self->handle_embedded( 'update', $item );
918
1504
                                unless $item == $self->{_canvas_bg};
919
1505
                }
920
1506
 
 
1507
                #add to undo stack
 
1508
                if($item->{dragging_start}){
 
1509
                        $self->store_to_xdo_stack($item, 'modify', 'undo');
 
1510
                        $item->{dragging_start} = FALSE;
 
1511
                }
 
1512
 
921
1513
                #freehand line
922
 
        } elsif ( ($self->{_current_mode_descr} eq "freehand" || $self->{_current_mode_descr} eq "censor") && $ev->state >= 'button1-mask' ) {
923
 
 
924
 
                my $item = $self->{_current_new_item};
925
 
 
 
1514
        } elsif ( ($self->{_current_mode_descr} eq "freehand" || $self->{_current_mode_descr} eq "highlighter" ||$self->{_current_mode_descr} eq "censor") && $ev->state >= 'button1-mask' ) {
 
1515
 
 
1516
                #mark as active item
 
1517
                my $item = undef;
 
1518
                if($self->{_current_new_item}){
 
1519
                        $item = $self->{_current_new_item};
 
1520
                        $self->{_current_new_item} = undef;
 
1521
                        $self->{_current_item} = $item;
 
1522
                        
 
1523
                        #apply item properties to widgets
 
1524
                        #line width, fill color, stroke color etc.
 
1525
                        $self->set_and_save_drawing_properties($item, FALSE);
 
1526
 
 
1527
                        #add to undo stack
 
1528
                        $self->store_to_xdo_stack($self->{_current_item} , 'create', 'undo');
 
1529
 
 
1530
                }else{
 
1531
                        $item = $self->{_current_item}; 
 
1532
                }
926
1533
                
927
1534
                if($ev->state >= 'control-mask'){
 
1535
                        
928
1536
                        my $last_point = pop @{ $self->{_items}{$item}{'points'} };
929
 
                        $last_point = $ev->y unless $last_point;
930
 
                        push @{ $self->{_items}{$item}{'points'} }, $last_point, $ev->x, $last_point;
 
1537
                        $last_point = $ev->y_root unless $last_point;
 
1538
                        push @{ $self->{_items}{$item}{'points'} }, $last_point, $ev->x_root, $last_point;
 
1539
                
931
1540
                }elsif($ev->state >= 'shift-mask'){
 
1541
                
932
1542
                        my $last_point_y = pop @{ $self->{_items}{$item}{'points'} };
933
1543
                        my $last_point_x = pop @{ $self->{_items}{$item}{'points'} };
934
 
                        $last_point_x = $ev->x unless $last_point_x;
935
 
                        $last_point_y = $ev->y unless $last_point_y;
936
 
                        push @{ $self->{_items}{$item}{'points'} }, $last_point_x, $last_point_y, $last_point_x, $ev->y;                
 
1544
                        $last_point_x = $ev->x_root unless $last_point_x;
 
1545
                        $last_point_y = $ev->y_root unless $last_point_y;
 
1546
                        push @{ $self->{_items}{$item}{'points'} }, $last_point_x, $last_point_y, $last_point_x, $ev->y_root;           
 
1547
                
937
1548
                }else{
938
 
                        push @{ $self->{_items}{$item}{'points'} }, $ev->x, $ev->y;             
 
1549
                
 
1550
                        push @{ $self->{_items}{$item}{'points'} }, $ev->x_root, $ev->y_root;           
 
1551
                
939
1552
                }
940
1553
                $self->{_items}{$item}->set( points => Goo::Canvas::Points->new( $self->{_items}{$item}{'points'} ) );
941
1554
 
942
 
                #items
 
1555
                #new item is already on the canvas with small initial size
 
1556
                #drawing is like resizing, so set up for resizing
943
1557
        } elsif (
944
1558
                (      $self->{_current_mode_descr} eq "rect"
945
1559
                        || $self->{_current_mode_descr} eq "line"
 
1560
                        || $self->{_current_mode_descr} eq "arrow"
946
1561
                        || $self->{_current_mode_descr} eq "ellipse"
947
1562
                        || $self->{_current_mode_descr} eq "text"
948
1563
                        || $self->{_current_mode_descr} eq "image"
 
1564
                        || $self->{_current_mode_descr} eq "number"
949
1565
                )
950
1566
                && $ev->state >= 'button1-mask'
 
1567
                && !$item->{resizing} #if item is not in resize mode already
951
1568
                )
952
1569
        {
953
1570
 
954
 
                #new item is already on the canvas with small initial size
955
 
                #drawing is like resizing, so set up tool for resizing
 
1571
                #~ print "start resizing\n";
 
1572
        
956
1573
                my $item = $self->{_current_new_item};
957
 
                #~ $self->{_current_new_item} = undef;
958
 
                $self->set_drawing_action(0);
959
 
                $self->change_drawing_tool_cb(10);
960
 
                $self->{_current_item} = $item;
961
 
                $self->{_items}{$item}{'bottom-right-corner'}->{res_x}    = $ev->x;
962
 
                $self->{_items}{$item}{'bottom-right-corner'}->{res_y}    = $ev->y;
 
1574
 
 
1575
                return FALSE unless $item;
 
1576
 
 
1577
                $self->{_current_new_item}      = undef;
 
1578
                $self->{_last_item}             = $item;
 
1579
                $self->{_current_item}          = $item;
 
1580
        
 
1581
                #apply item properties to widgets / or only save it
 
1582
                #line width, fill color, stroke color etc.
 
1583
                $self->set_and_save_drawing_properties($self->{_current_item}, TRUE);   
 
1584
                
 
1585
                $self->{_items}{$item}{'bottom-right-corner'}->{res_x}    = $ev->x_root;
 
1586
                $self->{_items}{$item}{'bottom-right-corner'}->{res_y}    = $ev->y_root;
963
1587
                $self->{_items}{$item}{'bottom-right-corner'}->{resizing} = TRUE;
964
 
                $self->{_canvas}->pointer_grab( $self->{_items}{$item}{'bottom-right-corner'}, [ 'pointer-motion-mask', 'button-release-mask' ], Gtk2::Gdk::Cursor->new('bottom-right-corner'), $ev->time );
965
 
 
966
 
        #resizing
 
1588
                #~ $self->{_canvas}->pointer_grab( $self->{_items}{$item}{'bottom-right-corner'}, [ 'pointer-motion-mask', 'button-release-mask' ], Gtk2::Gdk::Cursor->new('bottom-right-corner'), $ev->time );
 
1589
                $self->{_canvas}->pointer_grab( $self->{_items}{$item}{'bottom-right-corner'}, [ 'pointer-motion-mask', 'button-release-mask' ], undef, $ev->time );
 
1590
 
 
1591
                #add to undo stack
 
1592
                $self->store_to_xdo_stack($self->{_current_item} , 'create', 'undo');
 
1593
 
 
1594
        #item is resizing mode already
967
1595
        } elsif ( $item->{resizing} && $ev->state >= 'button1-mask' ) {
968
1596
 
 
1597
                #~ print "resizing\n";
 
1598
 
969
1599
                $self->{_current_mode_descr} = "resize";
970
1600
 
971
 
                my $curr_item = $self->{_current_item};
972
 
                my $cursor = undef;
973
 
 
974
 
                #calculate aspect ratio (resizing when control is pressed)
975
 
                my $ratio = 1;
976
 
                $ratio = $self->{_items}{$curr_item}->get('width')/$self->{_items}{$curr_item}->get('height') if $self->{_items}{$curr_item}->get('height') != 0;
977
 
 
978
 
                foreach ( keys %{ $self->{_items}{$curr_item} } ) {
979
 
 
980
 
                        #fancy resizing using our little resize boxes
981
 
                        if ( $item == $self->{_items}{$curr_item}{$_} ) {
982
 
 
983
 
                                my $new_x      = 0;
984
 
                                my $new_y      = 0;
985
 
                                my $new_width  = 0;
986
 
                                my $new_height = 0;
987
 
 
988
 
                                if ( $_ eq 'top-left-corner' ) {
989
 
                                        
990
 
                                        $cursor = $_;
991
 
                                        
992
 
                                        if($ev->state >= 'control-mask'){
993
 
                                                $new_x = $self->{_items}{$curr_item}->get('x') + ($ev->y - $item->{res_y}) * $ratio;
994
 
                                                $new_y = $self->{_items}{$curr_item}->get('y') + ($ev->y - $item->{res_y});                                             
995
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $self->{_items}{$curr_item}->get('x') - $new_x );
996
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );
997
 
                                        }else{
998
 
                                                $new_x = $self->{_items}{$curr_item}->get('x') + $ev->x - $item->{res_x};
999
 
                                                $new_y = $self->{_items}{$curr_item}->get('y') + $ev->y - $item->{res_y};                                               
1000
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $self->{_items}{$curr_item}->get('x') - $new_x );
1001
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );
1002
 
                                        }
1003
 
 
1004
 
                                } elsif ( $_ eq 'top-side' ) {
1005
 
 
1006
 
                                        $cursor = $_;
1007
 
 
1008
 
                                        $new_x = $self->{_items}{$curr_item}->get('x');
1009
 
                                        $new_y = $self->{_items}{$curr_item}->get('y') + $ev->y - $item->{res_y};
1010
 
 
1011
 
                                        $new_width = $self->{_items}{$curr_item}->get('width');
1012
 
                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );
1013
 
                                
1014
 
                                } elsif ( $_ eq 'top-right-corner' ) {
1015
 
 
1016
 
                                                $cursor = $_;
1017
 
 
1018
 
                                                $new_x = $self->{_items}{$curr_item}->get('x');
1019
 
                                                $new_y = $self->{_items}{$curr_item}->get('y') + $ev->y - $item->{res_y};
1020
 
 
1021
 
                                        if($ev->state >= 'control-mask'){
1022
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') - ( $ev->y - $item->{res_y} ) * $ratio;
1023
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );          
1024
 
                                        }else{
1025
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $ev->x - $item->{res_x} );
1026
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );                                  
1027
 
                                        }
1028
 
 
1029
 
                                } elsif ( $_ eq 'left-side' ) {
1030
 
 
1031
 
                                        $cursor = $_;
1032
 
 
1033
 
                                        $new_x = $self->{_items}{$curr_item}->get('x') + $ev->x - $item->{res_x};
1034
 
                                        $new_y = $self->{_items}{$curr_item}->get('y');
1035
 
 
1036
 
                                        $new_width = $self->{_items}{$curr_item}->get('width') + ( $self->{_items}{$curr_item}->get('x') - $new_x );
1037
 
                                        $new_height = $self->{_items}{$curr_item}->get('height');
1038
 
 
1039
 
                                } elsif ( $_ eq 'right-side' ) {
1040
 
 
1041
 
                                        $cursor = $_;
1042
 
        
1043
 
                                        $new_x = $self->{_items}{$curr_item}->get('x');
1044
 
                                        $new_y = $self->{_items}{$curr_item}->get('y');
1045
 
 
1046
 
                                        $new_width = $self->{_items}{$curr_item}->get('width') + ( $ev->x - $item->{res_x} );
1047
 
                                        $new_height = $self->{_items}{$curr_item}->get('height');
1048
 
 
1049
 
                                } elsif ( $_ eq 'bottom-left-corner' ) {
1050
 
 
1051
 
                                        $cursor = $_;
1052
 
 
1053
 
                                        if($ev->state >= 'control-mask'){
1054
 
                                                $new_x = $self->{_items}{$curr_item}->get('x') - $ev->y + $item->{res_y};
1055
 
                                                $new_y = $self->{_items}{$curr_item}->get('y');
1056
 
                                                
1057
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') + ( $self->{_items}{$curr_item}->get('x') - $new_x );
1058
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y - $item->{res_y} ) / $ratio;
1059
 
                                        }else{
1060
 
                                                $new_x = $self->{_items}{$curr_item}->get('x') + $ev->x - $item->{res_x};
1061
 
                                                $new_y = $self->{_items}{$curr_item}->get('y');
1062
 
 
1063
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $self->{_items}{$curr_item}->get('x') - $new_x );
1064
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y - $item->{res_y} );                                 
1065
 
                                        }
1066
 
 
1067
 
                                } elsif ( $_ eq 'bottom-side' ) {
1068
 
 
1069
 
                                        $cursor = $_;
1070
 
 
1071
 
                                        $new_x = $self->{_items}{$curr_item}->get('x');
1072
 
                                        $new_y = $self->{_items}{$curr_item}->get('y');
1073
 
 
1074
 
                                        $new_width = $self->{_items}{$curr_item}->get('width');
1075
 
                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y - $item->{res_y} );
1076
 
 
1077
 
                                } elsif ( $_ eq 'bottom-right-corner' ) {
1078
 
 
1079
 
                                        $cursor = $_;
1080
 
 
1081
 
                                        $new_x = $self->{_items}{$curr_item}->get('x');
1082
 
                                        $new_y = $self->{_items}{$curr_item}->get('y');
1083
 
 
1084
 
                                        if($ev->state >= 'control-mask'){
1085
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $ev->y - $item->{res_y} ) * $ratio;
1086
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y - $item->{res_y} );                                         
1087
 
                                        }else{
1088
 
                                                $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $ev->x - $item->{res_x} );
1089
 
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y - $item->{res_y} );                                 
1090
 
                                        }
1091
 
 
1092
 
 
1093
 
                                }
1094
 
 
1095
 
                                #set cursor
1096
 
                                $self->{_canvas}->window->set_cursor( Gtk2::Gdk::Cursor->new($cursor) );
1097
 
 
1098
 
                                $item->{res_x} = $ev->x;
1099
 
                                $item->{res_y} = $ev->y;
1100
 
 
1101
 
                                #when width or height are too small we switch to opposite rectangle and do the resizing in this way
1102
 
                                if ( $new_width < 0 || $new_height < 0) {
1103
 
                                        $self->{_canvas}->pointer_ungrab($item, $ev->time);
1104
 
                                        my $oppo = $self->get_opposite_rect($item, $curr_item, $new_width, $new_height);                                
1105
 
                                        $self->{_items}{$curr_item}{$oppo}->{res_x}    = $ev->x;
1106
 
                                        $self->{_items}{$curr_item}{$oppo}->{res_y}    = $ev->y;
1107
 
                                        $self->{_items}{$curr_item}{$oppo}->{resizing} = TRUE;
1108
 
                                        $self->{_canvas}->pointer_grab( $self->{_items}{$curr_item}{$oppo}, [ 'pointer-motion-mask', 'button-release-mask' ], Gtk2::Gdk::Cursor->new($oppo), $ev->time );
1109
 
                                        $self->handle_embedded( 'mirror', $curr_item );
1110
 
                                        $new_width = 0 if $new_width < 0;
1111
 
                                        $new_height = 0 if $new_height < 0;
1112
 
                                }
1113
 
 
1114
 
                                $self->{_items}{$curr_item}->set(
1115
 
                                        'x'      => $new_x,
1116
 
                                        'y'      => $new_y,
1117
 
                                        'width'  => $new_width,
1118
 
                                        'height' => $new_height,
1119
 
                                );
1120
 
 
1121
 
                                $self->handle_rects( 'update', $curr_item );
1122
 
                                $self->handle_embedded( 'update', $curr_item );
1123
 
                                        
1124
 
                        }
 
1601
                        #canvas resizing shape
 
1602
                if ( $self->{_canvas_bg_rect}{'right-side'} == $item ) {
 
1603
 
 
1604
                        my $new_width = $self->{_canvas_bg_rect}->get('width') +  ( $ev->x_root - $item->{res_x} );
 
1605
 
 
1606
                        unless ( $new_width < 0 ) {
 
1607
 
 
1608
                                $self->{_canvas_bg_rect}->set(
 
1609
                                        'width'  => $new_width,
 
1610
                                );
 
1611
                                
 
1612
                                $self->handle_bg_rects('update');                       
 
1613
 
 
1614
                        }
 
1615
        
 
1616
                } elsif ( $self->{_canvas_bg_rect}{'bottom-side'} == $item ) {
 
1617
 
 
1618
                        my $new_height = $self->{_canvas_bg_rect}->get('height') + ( $ev->y_root - $item->{res_y} );
 
1619
        
 
1620
                        unless ( $new_height < 0 ) {
 
1621
                                                
 
1622
                                $self->{_canvas_bg_rect}->set(
 
1623
                                        'height'  => $new_height,
 
1624
                                );
 
1625
                                
 
1626
                                $self->handle_bg_rects('update');
 
1627
                
 
1628
                        }
 
1629
                
 
1630
                } elsif ( $self->{_canvas_bg_rect}{'bottom-right-corner'} == $item ) {                  
 
1631
 
 
1632
                        my $new_width = $self->{_canvas_bg_rect}->get('width') +  ( $ev->x_root - $item->{res_x} );
 
1633
                        my $new_height = $self->{_canvas_bg_rect}->get('height') + ( $ev->y_root - $item->{res_y} );
 
1634
 
 
1635
                        unless ( $new_width < 0 || $new_height < 0) {           
 
1636
                        
 
1637
                                $self->{_canvas_bg_rect}->set(
 
1638
                                        'width'  => $new_width,
 
1639
                                        'height'  => $new_height,
 
1640
                                );
 
1641
                                
 
1642
                                $self->handle_bg_rects('update');
 
1643
 
 
1644
                        }
 
1645
                        
 
1646
                        #item resizing shape
 
1647
                }else {
 
1648
                        
 
1649
                        my $curr_item = $self->{_current_item};
 
1650
                        #~ my $cursor = undef;
 
1651
 
 
1652
                        return FALSE unless $curr_item;
 
1653
 
 
1654
                        #calculate aspect ratio (resizing when control is pressed)
 
1655
                        my $ratio = 1;
 
1656
                        $ratio = $self->{_items}{$curr_item}->get('width')/$self->{_items}{$curr_item}->get('height') if $self->{_items}{$curr_item}->get('height') != 0;
 
1657
 
 
1658
                        my $new_x      = 0;
 
1659
                        my $new_y      = 0;
 
1660
                        my $new_width  = 0;
 
1661
                        my $new_height = 0;
 
1662
 
 
1663
                        foreach ( keys %{ $self->{_items}{$curr_item} } ) {
 
1664
 
 
1665
                                next unless $_ =~ m/(corner|side)/;
 
1666
                                
 
1667
                                #fancy resizing using our little resize boxes
 
1668
                                if ( $item == $self->{_items}{$curr_item}{$_} ) {
 
1669
                                        
 
1670
                                        #~ $cursor = $_;
 
1671
 
 
1672
                                        if ( $_ eq 'bottom-side' ) {
 
1673
 
 
1674
                                                $new_x = $self->{_items}{$curr_item}->get('x');
 
1675
                                                $new_y = $self->{_items}{$curr_item}->get('y');
 
1676
 
 
1677
                                                $new_width = $self->{_items}{$curr_item}->get('width');
 
1678
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y_root - $item->{res_y} );
 
1679
 
 
1680
                                                last;
 
1681
 
 
1682
                                        } elsif ( $_ eq 'bottom-right-corner' ) {
 
1683
 
 
1684
                                                $new_x = $self->{_items}{$curr_item}->get('x');
 
1685
                                                $new_y = $self->{_items}{$curr_item}->get('y');
 
1686
 
 
1687
                                                if($ev->state >= 'control-mask'){
 
1688
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $ev->y_root - $item->{res_y} ) * $ratio;
 
1689
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y_root - $item->{res_y} );                                            
 
1690
                                                }else{
 
1691
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $ev->x_root - $item->{res_x} );
 
1692
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y_root - $item->{res_y} );                                    
 
1693
                                                }
 
1694
                                                
 
1695
                                                last;
 
1696
 
 
1697
                                        }elsif ( $_ eq 'top-left-corner' ) {
 
1698
                                                
 
1699
                                                if($ev->state >= 'control-mask'){
 
1700
                                                        $new_x = $self->{_items}{$curr_item}->get('x') + ($ev->y_root - $item->{res_y}) * $ratio;
 
1701
                                                        $new_y = $self->{_items}{$curr_item}->get('y') + ($ev->y_root - $item->{res_y});                                                
 
1702
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $self->{_items}{$curr_item}->get('x') - $new_x );
 
1703
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );
 
1704
                                                }else{
 
1705
                                                        $new_x = $self->{_items}{$curr_item}->get('x') + $ev->x_root - $item->{res_x};
 
1706
                                                        $new_y = $self->{_items}{$curr_item}->get('y') + $ev->y_root - $item->{res_y};                                          
 
1707
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $self->{_items}{$curr_item}->get('x') - $new_x );
 
1708
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );
 
1709
                                                }
 
1710
                                                
 
1711
                                                last;
 
1712
 
 
1713
                                        } elsif ( $_ eq 'top-side' ) {
 
1714
 
 
1715
                                                $new_x = $self->{_items}{$curr_item}->get('x');
 
1716
                                                $new_y = $self->{_items}{$curr_item}->get('y') + $ev->y_root - $item->{res_y};
 
1717
 
 
1718
                                                $new_width = $self->{_items}{$curr_item}->get('width');
 
1719
                                                $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );
 
1720
                                        
 
1721
                                                last;
 
1722
                                        
 
1723
                                        } elsif ( $_ eq 'top-right-corner' ) {
 
1724
 
 
1725
                                                        $new_x = $self->{_items}{$curr_item}->get('x');
 
1726
                                                        $new_y = $self->{_items}{$curr_item}->get('y') + $ev->y_root - $item->{res_y};
 
1727
 
 
1728
                                                if($ev->state >= 'control-mask'){
 
1729
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') - ( $ev->y_root - $item->{res_y} ) * $ratio;
 
1730
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );          
 
1731
                                                }else{
 
1732
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $ev->x_root - $item->{res_x} );
 
1733
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $self->{_items}{$curr_item}->get('y') - $new_y );                                  
 
1734
                                                }
 
1735
                                                
 
1736
                                                last;
 
1737
 
 
1738
                                        } elsif ( $_ eq 'left-side' ) {
 
1739
 
 
1740
                                                $new_x = $self->{_items}{$curr_item}->get('x') + $ev->x_root - $item->{res_x};
 
1741
                                                $new_y = $self->{_items}{$curr_item}->get('y');
 
1742
 
 
1743
                                                $new_width = $self->{_items}{$curr_item}->get('width') + ( $self->{_items}{$curr_item}->get('x') - $new_x );
 
1744
                                                $new_height = $self->{_items}{$curr_item}->get('height');
 
1745
 
 
1746
                                                last;
 
1747
 
 
1748
                                        } elsif ( $_ eq 'right-side' ) {
 
1749
                
 
1750
                                                $new_x = $self->{_items}{$curr_item}->get('x');
 
1751
                                                $new_y = $self->{_items}{$curr_item}->get('y');
 
1752
 
 
1753
                                                $new_width = $self->{_items}{$curr_item}->get('width') + ( $ev->x_root - $item->{res_x} );
 
1754
                                                $new_height = $self->{_items}{$curr_item}->get('height');
 
1755
 
 
1756
                                                last;
 
1757
                
 
1758
                                        } elsif ( $_ eq 'bottom-left-corner' ) {
 
1759
 
 
1760
                                                if($ev->state >= 'control-mask'){
 
1761
                                                        $new_x = $self->{_items}{$curr_item}->get('x') - $ev->y_root + $item->{res_y};
 
1762
                                                        $new_y = $self->{_items}{$curr_item}->get('y');
 
1763
                                                        
 
1764
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') + ( $self->{_items}{$curr_item}->get('x') - $new_x );
 
1765
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y_root - $item->{res_y} ) / $ratio;
 
1766
                                                }else{
 
1767
                                                        $new_x = $self->{_items}{$curr_item}->get('x') + $ev->x_root - $item->{res_x};
 
1768
                                                        $new_y = $self->{_items}{$curr_item}->get('y');
 
1769
 
 
1770
                                                        $new_width  = $self->{_items}{$curr_item}->get('width') +  ( $self->{_items}{$curr_item}->get('x') - $new_x );
 
1771
                                                        $new_height = $self->{_items}{$curr_item}->get('height') + ( $ev->y_root - $item->{res_y} );                                    
 
1772
                                                }
 
1773
                                                
 
1774
                                                last;
 
1775
                                                                                                        
 
1776
                                        }
 
1777
                                }
 
1778
                        }
 
1779
 
 
1780
                        #set cursor
 
1781
                        
 
1782
                        #~ $self->{_canvas}->window->set_cursor( Gtk2::Gdk::Cursor->new($cursor) );
 
1783
                        
 
1784
                        #when width or height are too small we switch to opposite rectangle and do the resizing in this way
 
1785
                        if($ev->state >= 'control-mask' && $new_width < 1 && $new_height < 1){
 
1786
                        
 
1787
                                $new_x = $self->{_items}{$curr_item}->get('x');
 
1788
                                $new_y = $self->{_items}{$curr_item}->get('y');
 
1789
                                $new_width = $self->{_items}{$curr_item}->get('width');
 
1790
                                $new_height = $self->{_items}{$curr_item}->get('height');
 
1791
                        
 
1792
                        }elsif ( $new_width < 0 || $new_height < 0) {
 
1793
                                
 
1794
                                $self->{_canvas}->pointer_ungrab($item, $ev->time);
 
1795
                                my $oppo = $self->get_opposite_rect($item, $curr_item, $new_width, $new_height);                                
 
1796
                                $self->{_items}{$curr_item}{$oppo}->{res_x}    = $ev->x_root;
 
1797
                                $self->{_items}{$curr_item}{$oppo}->{res_y}    = $ev->y_root;
 
1798
                                $self->{_items}{$curr_item}{$oppo}->{resizing} = TRUE;
 
1799
                                
 
1800
                                #don'change cursor if this item was just started
 
1801
                                if($self->{_last_item} && $self->{_current_item} && $self->{_last_item} == $self->{_current_item}){
 
1802
                                        $self->{_canvas}->pointer_grab( $self->{_items}{$curr_item}{$oppo}, [ 'pointer-motion-mask', 'button-release-mask' ], undef, $ev->time );       
 
1803
                                }else{
 
1804
                                        $self->{_canvas}->pointer_grab( $self->{_items}{$curr_item}{$oppo}, [ 'pointer-motion-mask', 'button-release-mask' ], Gtk2::Gdk::Cursor->new($oppo), $ev->time );                               
 
1805
                                }
 
1806
                                
 
1807
                                $self->handle_embedded( 'mirror', $curr_item, $new_width, $new_height);
 
1808
                                
 
1809
                                #adjust new values                                              
 
1810
                                if ($new_width < 0){
 
1811
                                        $new_x += $new_width;
 
1812
                                        $new_width = abs($new_width);
 
1813
                                }
 
1814
                                if ($new_height < 0){
 
1815
                                        $new_y += $new_height;
 
1816
                                        $new_height = abs($new_height);
 
1817
                                }
 
1818
 
 
1819
                        }
 
1820
                        
 
1821
                        #apply new values...
 
1822
                        $self->{_items}{$curr_item}->set(
 
1823
                                'x'      => $new_x,
 
1824
                                'y'      => $new_y,
 
1825
                                'width'  => $new_width,
 
1826
                                'height' => $new_height,
 
1827
                        );
 
1828
                        
 
1829
                        #and update rectangles and embedded items
 
1830
                        $self->handle_rects( 'update', $curr_item );
 
1831
                        $self->handle_embedded( 'update', $curr_item );
 
1832
                                
1125
1833
                }
 
1834
 
 
1835
                $item->{res_x} = $ev->x_root;
 
1836
                $item->{res_y} = $ev->y_root;
1126
1837
                
1127
1838
        }else {
1128
1839
 
1129
1840
                if (   $item->isa('Goo::Canvas::Rect') ) {
1130
1841
 
1131
 
                        #embedded item?
 
1842
                                #embedded item?
1132
1843
                        my $parent = $self->get_parent_item($item);
1133
1844
                        $item = $parent if $parent;
1134
1845
 
1135
 
                        #resizing shape
1136
 
                        unless ( exists $self->{_items}{$item} ) {
1137
 
                                $self->push_to_statusbar( int( $ev->x ), int( $ev->y ), 'resize' );     
 
1846
                                #shape or canvas background (resizeable rectangle)
 
1847
                        if ( exists $self->{_items}{$item} or $item == $self->{_canvas_bg_rect}) {
 
1848
                                $self->push_to_statusbar( int( $ev->x_root ), int( $ev->y_root ) );
 
1849
                        
 
1850
                                #canvas resizing shape
 
1851
                        } elsif (  $self->{_canvas_bg_rect}{'right-side'} == $item
 
1852
                                        || $self->{_canvas_bg_rect}{'bottom-side'} == $item
 
1853
                                        || $self->{_canvas_bg_rect}{'bottom-right-corner'} == $item ) 
 
1854
                        {
 
1855
                                $self->push_to_statusbar( int( $ev->x_root ), int( $ev->y_root ), 'canvas_resize' );            
 
1856
                        
 
1857
                                #resizing shape
1138
1858
                        }else{
1139
 
                                $self->push_to_statusbar( int( $ev->x ), int( $ev->y ) );                               
 
1859
                                                                
 
1860
                                $self->push_to_statusbar( int( $ev->x_root ), int( $ev->y_root ), 'resize' );                                   
1140
1861
                        }
1141
1862
                }else{
1142
 
                        $self->push_to_statusbar( int( $ev->x ), int( $ev->y ) );       
 
1863
                        $self->push_to_statusbar( int( $ev->x_root ), int( $ev->y_root ) );     
1143
1864
                }
1144
1865
 
1145
1866
        }
1161
1882
 
1162
1883
                        if ( $_ eq 'top-left-corner' ) {
1163
1884
                        
 
1885
                                return 'bottom-right-corner' if $width < 0 && $height < 0;
1164
1886
                                return 'top-right-corner' if $width < 0;        
1165
1887
                                return 'bottom-left-corner' if $height < 0;
1166
1888
                                
1170
1892
        
1171
1893
                        } elsif ( $_ eq 'top-right-corner' ) {
1172
1894
 
 
1895
                                return 'bottom-left-corner' if $width < 0 && $height < 0;
1173
1896
                                return 'top-left-corner' if $width < 0; 
1174
1897
                                return 'bottom-right-corner' if $height < 0;
1175
1898
 
1183
1906
 
1184
1907
                        } elsif ( $_ eq 'bottom-left-corner' ) {
1185
1908
 
 
1909
                                return 'top-right-corner' if $width < 0 && $height < 0;
1186
1910
                                return 'bottom-right-corner' if $width < 0;     
1187
1911
                                return 'top-left-corner' if $height < 0;
1188
1912
 
1191
1915
                                return 'top-side';
1192
1916
 
1193
1917
                        } elsif ( $_ eq 'bottom-right-corner' ) {
1194
 
                                
 
1918
 
 
1919
                                return 'top-left-corner' if $width < 0 && $height < 0;                          
1195
1920
                                return 'bottom-left-corner' if $width < 0;      
1196
1921
                                return 'top-right-corner' if $height < 0;
1197
1922
 
1203
1928
}
1204
1929
 
1205
1930
sub get_parent_item {
1206
 
        my $self = shift;
1207
 
        my $item = shift;
 
1931
        my ($self, $item) = @_;
1208
1932
 
1209
1933
        my $parent = undef;
1210
1934
        foreach ( keys %{ $self->{_items} } ) {
1211
 
                $parent = $self->{_items}{$_} if $self->{_items}{$_}{ellipse} == $item;
1212
 
                $parent = $self->{_items}{$_} if $self->{_items}{$_}{text} == $item;
1213
 
                $parent = $self->{_items}{$_} if $self->{_items}{$_}{image} == $item;
1214
 
                $parent = $self->{_items}{$_} if $self->{_items}{$_}{line} == $item;
 
1935
                $parent = $self->{_items}{$_} if exists $self->{_items}{$_}{ellipse} && $self->{_items}{$_}{ellipse} == $item;
 
1936
                $parent = $self->{_items}{$_} if exists $self->{_items}{$_}{text} && $self->{_items}{$_}{text} == $item;
 
1937
                $parent = $self->{_items}{$_} if exists $self->{_items}{$_}{image} && $self->{_items}{$_}{image} == $item;
 
1938
                $parent = $self->{_items}{$_} if exists $self->{_items}{$_}{line} && $self->{_items}{$_}{line} == $item;
1215
1939
        }
1216
1940
 
1217
1941
        return $parent;
1218
1942
}
1219
1943
 
 
1944
sub get_highest_auto_digit {
 
1945
        my ($self) = @_;
 
1946
        
 
1947
        my $number = 0;
 
1948
        foreach ( keys %{ $self->{_items} } ) {
 
1949
 
 
1950
                my $item = $self->{_items}{$_};
 
1951
                
 
1952
                #numbered shape
 
1953
                if ( exists $self->{_items}{$item}{text} 
 
1954
                        && $self->{_items}{$item}{text}->get('visibility') ne 'hidden' ) {
 
1955
                        $number = $self->{_items}{$item}{text}{digit} if $self->{_items}{$item}{text}{digit} > $number;
 
1956
                }               
 
1957
        
 
1958
        }
 
1959
 
 
1960
        return $number;
 
1961
}
 
1962
 
1220
1963
sub get_child_item {
1221
 
        my $self = shift;
1222
 
        my $item = shift;
 
1964
        my ($self, $item) = @_;
1223
1965
 
1224
1966
        my $child = undef;
1225
1967
 
1226
 
        $child = $self->{_items}{$item}{ellipse} if exists $self->{_items}{$item}{ellipse};
1227
 
        $child = $self->{_items}{$item}{text}    if exists $self->{_items}{$item}{text};
1228
 
        $child = $self->{_items}{$item}{image}   if exists $self->{_items}{$item}{image};
1229
 
        $child = $self->{_items}{$item}{line}   if exists $self->{_items}{$item}{line};
 
1968
        #notice (special shapes like numbered ellipse do deliver ellipse here => NOT text!)
 
1969
        #therefore the order matters
 
1970
        if (defined $item && exists $self->{_items}{$item}){
 
1971
                $child = $self->{_items}{$item}{text}    if exists $self->{_items}{$item}{text};
 
1972
                $child = $self->{_items}{$item}{ellipse} if exists $self->{_items}{$item}{ellipse};
 
1973
                $child = $self->{_items}{$item}{image}   if exists $self->{_items}{$item}{image};
 
1974
                $child = $self->{_items}{$item}{line}    if exists $self->{_items}{$item}{line};
 
1975
        }
1230
1976
 
1231
1977
        return $child;
1232
1978
}
1233
1979
 
1234
1980
sub abort_current_mode {
1235
 
        my $self = shift;
1236
 
 
1237
 
        $self->set_drawing_action(0);
1238
 
        $self->change_drawing_tool_cb(10);
 
1981
        my ($self) = @_;
 
1982
 
 
1983
        if($self->{_current_item}){
 
1984
                $self->{_canvas}->pointer_ungrab( $self->{_current_item}, time );
 
1985
        }
 
1986
 
 
1987
        #~ print "abort_current_mode\n";
 
1988
 
 
1989
        $self->set_drawing_action(1);
1239
1990
 
1240
1991
        return TRUE;
1241
1992
}       
1242
1993
 
1243
1994
sub clear_item_from_canvas {
1244
 
        my $self = shift;
1245
 
        my $item = shift;
 
1995
        my ($self, $item) = @_;
 
1996
 
 
1997
        #~ print "clear_item_from_canvas\n";
 
1998
 
 
1999
        $self->{_last_item}        = undef;
 
2000
        $self->{_current_item}     = undef;
 
2001
        $self->{_current_new_item} = undef;     
1246
2002
 
1247
2003
        if ($item) {
1248
 
                my @items_to_delete;
1249
 
                push @items_to_delete, $item;
1250
 
 
 
2004
                
1251
2005
                #maybe there is a parent item to delete?
1252
2006
                my $parent = $self->get_parent_item($item);
1253
 
 
1254
 
                if ($parent) {
1255
 
                        push @items_to_delete, $parent;
1256
 
                        foreach ( keys %{ $self->{_items}{$parent} } ) {
1257
 
                                push @items_to_delete, $self->{_items}{$parent}{$_};
1258
 
                        }
1259
 
                } else {
1260
 
                        foreach ( keys %{ $self->{_items}{$item} } ) {
1261
 
                                push @items_to_delete, $self->{_items}{$item}{$_};
1262
 
                        }
1263
 
                }
1264
 
 
1265
 
                foreach (@items_to_delete) {
1266
 
                        eval{
1267
 
                                $self->store_to_xdo_stack($_, 'delete', 'undo');
1268
 
                                $_->set('visibility' => 'GOO_CANVAS_ITEM_HIDDEN');
1269
 
                                $self->handle_rects('hide', $_);
1270
 
                                $self->handle_embedded('hide', $_);
1271
 
                        };
1272
 
                }
 
2007
                $item = $parent if $parent;
 
2008
                
 
2009
                #get child
 
2010
                my $child = $self->get_child_item($item);
 
2011
                
 
2012
                #only delete if not already deleted (hidden)
 
2013
                return FALSE if($child && $child->get('visibility') eq 'hidden');
 
2014
                #~ print "1st passed\n";
 
2015
                return FALSE if(!$child && $item->get('visibility') eq 'hidden');
 
2016
                #~ print "2nd passed\n";
 
2017
                
 
2018
                $self->store_to_xdo_stack($item, 'delete', 'undo');
 
2019
                $item->set('visibility' => 'hidden');
 
2020
                $self->handle_rects('hide', $item);
 
2021
                $self->handle_embedded('hide', $item);
 
2022
                
1273
2023
        }
1274
 
        
1275
 
        $self->{_last_item}        = undef;
1276
 
        $self->{_current_item}     = undef;
1277
 
        $self->{_current_new_item} = undef;     
1278
2024
 
1279
2025
        return TRUE;
1280
2026
}
1281
2027
 
1282
2028
sub store_to_xdo_stack {
1283
 
        #~ my $self = shift;
1284
 
        #~ my $item = shift;
1285
 
        #~ my $action = shift;
1286
 
        #~ my $xdo = shift;
1287
 
#~ 
1288
 
        #~ return FALSE unless $item; 
1289
 
        #~ 
1290
 
        #~ my %do_info = ();
1291
 
        #~ #general properties for ellipse, rectangle, image, text
1292
 
        #~ if($item->isa('Goo::Canvas::Rect')){
1293
 
#~ 
1294
 
                #~ my $stroke_pattern = $self->create_color( $self->{_items}{$item}{stroke_color}, $self->{_items}{$item}{stroke_color_alpha} ) if exists $self->{_items}{$item}{stroke_color};
1295
 
                #~ my $fill_pattern   = $self->create_color( $self->{_items}{$item}{fill_color},   $self->{_items}{$item}{fill_color_alpha} ) if exists $self->{_items}{$item}{fill_color};
1296
 
                #~ my $line_width = $self->{_items}{$item}->get('line-width');
1297
 
#~ 
1298
 
                #~ #rectangle props
1299
 
                #~ %do_info = (
1300
 
                        #~ 'item' => $self->{_items}{$item},
1301
 
                        #~ 'action' => $action,
1302
 
                        #~ 'x' => $self->{_items}{$item}->get('x'),
1303
 
                        #~ 'y' => $self->{_items}{$item}->get('y'),
1304
 
                        #~ 'width' => $self->{_items}{$item}->get('width'),
1305
 
                        #~ 'height' => $self->{_items}{$item}->get('height'),
1306
 
                        #~ 'fill-pattern' => $fill_pattern,
1307
 
                        #~ 'stroke-pattern' => $stroke_pattern,
1308
 
                        #~ 'line-width' => $line_width,
1309
 
                #~ );
1310
 
#~ 
1311
 
                #~ if ( exists $self->{_items}{$item}{ellipse} ) {
1312
 
#~ 
1313
 
                #~ }elsif ( exists $self->{_items}{$item}{text} ) {
1314
 
#~ 
1315
 
                #~ }elsif ( exists $self->{_items}{$item}{image} ) {
1316
 
#~ 
1317
 
                #~ }elsif ( exists $self->{_items}{$item}{line} ) {
1318
 
                #~ 
1319
 
                #~ }else{
1320
 
                #~ 
1321
 
                #~ }                    
1322
 
                #~ 
1323
 
        #~ }
1324
 
#~ 
1325
 
        #~ #add polyline specific properties to hash
1326
 
        #~ if($item->isa('Goo::Canvas::Polyline')){
1327
 
                #~ %do_info = (
1328
 
                        #~ item => $self->{_items}{$item},
1329
 
                        #~ action => $action,
1330
 
                        #~ points => $self->{_items}{$item}->get('points'),
1331
 
                #~ );
1332
 
        #~ }
1333
 
        #~ 
1334
 
        #~ if($xdo eq 'undo'){
1335
 
                #~ push @{ $self->{_undo} }, \%do_info;                 
1336
 
        #~ }elsif($xdo eq 'redo'){
1337
 
                #~ push @{ $self->{_redo} }, \%do_info; 
1338
 
        #~ }
1339
 
#~ 
1340
 
        #~ #disable undo/redo actions at startup
1341
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Undo")->set_sensitive(scalar @{ $self->{_undo} }) if defined $self->{_undo};
1342
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Redo")->set_sensitive(scalar @{ $self->{_redo} }) if defined $self->{_redo};
1343
 
        #~ 
1344
 
        #~ return TRUE; 
1345
 
}
1346
 
 
1347
 
sub undo {
1348
 
        #~ my $self = shift;
1349
 
#~ 
1350
 
        #~ my $undo = pop @{ $self->{_undo} };
1351
 
#~ 
1352
 
        #~ my $item = $undo->{'item'};
1353
 
        #~ my $action = $undo->{'action'};
1354
 
#~ 
1355
 
        #~ #store to redo stack
1356
 
        #~ $self->store_to_xdo_stack($item, $action, 'redo'); 
1357
 
#~ 
1358
 
        #~ $self->deactivate_all;
1359
 
        #~ 
1360
 
        #~ #finally undo the last event
1361
 
        #~ if($action eq 'modify'){
1362
 
                #~ $self->{_items}{$item}->set(
1363
 
                        #~ 'x' => $undo->{'x'},
1364
 
                        #~ 'y' => $undo->{'y'},
1365
 
                        #~ 'width' =>   $undo->{'width'},
1366
 
                        #~ 'height' => $undo->{'height'},
1367
 
                        #~ 'fill-pattern' => $undo->{'fill-pattern'},
1368
 
                        #~ 'stroke-pattern' => $undo->{'stroke-pattern'},
1369
 
                        #~ 'line-width' => $undo->{'line-width'},       
1370
 
                #~ );
1371
 
                #~ $self->handle_rects( 'update', $self->{_items}{$item} );
1372
 
                #~ $self->handle_embedded( 'update', $self->{_items}{$item} );          
1373
 
                #~ $self->{_current_item} = $item;      
1374
 
        #~ }elsif($action eq 'delete'){
1375
 
                #~ $self->{_items}{$item}->set('visibility' => 'GOO_CANVAS_ITEM_VISIBLE');
1376
 
                #~ $self->handle_rects( 'update', $self->{_items}{$item} );
1377
 
                #~ $self->handle_embedded( 'update', $self->{_items}{$item} );
1378
 
                #~ $self->{_current_item} = $item;              
1379
 
        #~ }elsif($action eq 'create'){
1380
 
                #~ $self->{_items}{$item}->set('visibility' => 'GOO_CANVAS_ITEM_HIDDEN');
1381
 
                #~ $self->handle_rects( 'hide', $self->{_items}{$item} );
1382
 
                #~ $self->handle_embedded( 'hide', $self->{_items}{$item} );            
1383
 
        #~ }
1384
 
        #~ 
1385
 
        #~ #disable undo/redo actions at startup
1386
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Undo")->set_sensitive(scalar @{ $self->{_undo} }) if defined $self->{_undo};
1387
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Redo")->set_sensitive(scalar @{ $self->{_redo} }) if defined $self->{_redo};  
1388
 
        #~ 
1389
 
        #~ return TRUE; 
1390
 
}
1391
 
 
1392
 
sub redo {
1393
 
        #~ my $self = shift;
1394
 
#~ 
1395
 
        #~ my $redo = pop @{ $self->{_redo} };
1396
 
#~ 
1397
 
        #~ my $item = $redo->{'item'};
1398
 
        #~ my $action = $redo->{'action'};
1399
 
#~ 
1400
 
        #~ #store to undo stack
1401
 
        #~ $self->store_to_xdo_stack($item, $action, 'undo'); 
1402
 
#~ 
1403
 
        #~ $self->deactivate_all;
1404
 
#~ 
1405
 
        #~ #finally undo the last event
1406
 
        #~ if($action eq 'modify'){
1407
 
                #~ $self->{_items}{$item}->set(
1408
 
                        #~ 'x' => $redo->{'x'},
1409
 
                        #~ 'y' => $redo->{'y'},
1410
 
                        #~ 'width' =>   $redo->{'width'},
1411
 
                        #~ 'height' => $redo->{'height'},
1412
 
                        #~ 'fill-pattern' => $redo->{'fill-pattern'},
1413
 
                        #~ 'stroke-pattern' => $redo->{'stroke-pattern'},
1414
 
                        #~ 'line-width' => $redo->{'line-width'},                       
1415
 
                #~ );
1416
 
                #~ $self->handle_rects( 'update', $self->{_items}{$item} );
1417
 
                #~ $self->handle_embedded( 'update', $self->{_items}{$item} );          
1418
 
                #~ $self->{_current_item} = $item;      
1419
 
        #~ }elsif($action eq 'delete'){
1420
 
                #~ $self->{_items}{$item}->set('visibility' => 'GOO_CANVAS_ITEM_HIDDEN');
1421
 
                #~ $self->handle_rects( 'hide', $self->{_items}{$item} );
1422
 
                #~ $self->handle_embedded( 'hide', $self->{_items}{$item} );
1423
 
                #~ $self->{_current_item} = $item;              
1424
 
        #~ }elsif($action eq 'create'){
1425
 
                #~ $self->{_items}{$item}->set('visibility' => 'GOO_CANVAS_ITEM_VISIBLE');
1426
 
                #~ $self->handle_rects( 'update', $self->{_items}{$item} );
1427
 
                #~ $self->handle_embedded( 'update', $self->{_items}{$item} );          
1428
 
        #~ }
1429
 
#~ 
1430
 
        #~ #disable undo/redo actions at startup
1431
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Undo")->set_sensitive(scalar @{ $self->{_undo} }) if defined $self->{_undo};
1432
 
        #~ $self->{_uimanager}->get_widget("/MenuBar/Edit/Redo")->set_sensitive(scalar @{ $self->{_redo} }) if defined $self->{_redo};  
1433
 
        #~ 
1434
 
        #~ return TRUE; 
 
2029
        #opt1 is currently only used when cropping the image
 
2030
        #it stores the selection
 
2031
        my ($self, $item, $action, $xdo, $opt1) = @_;
 
2032
 
 
2033
        return FALSE unless $item; 
 
2034
 
 
2035
        #~ print "xdo - $item\n";
 
2036
        
 
2037
        my %do_info = ();
 
2038
        #general properties for ellipse, rectangle, image, text
 
2039
        if($item->isa('Goo::Canvas::Rect') && $item != $self->{_canvas_bg_rect}){
 
2040
 
 
2041
                my $stroke_pattern = $self->create_color( $self->{_items}{$item}{stroke_color}, $self->{_items}{$item}{stroke_color_alpha} ) if exists $self->{_items}{$item}{stroke_color};
 
2042
                my $fill_pattern   = $self->create_color( $self->{_items}{$item}{fill_color}, $self->{_items}{$item}{fill_color_alpha} ) if exists $self->{_items}{$item}{fill_color};
 
2043
                my $line_width = $self->{_items}{$item}->get('line-width');
 
2044
                
 
2045
                #line
 
2046
                my $mirrored_w          = undef;
 
2047
                my $mirrored_h          = undef;
 
2048
                my $end_arrow           = undef;
 
2049
                my $start_arrow         = undef; 
 
2050
                my $arrow_width         = undef; 
 
2051
                my $arrow_length        = undef;
 
2052
                my $tip_length          = undef;
 
2053
                
 
2054
                #text
 
2055
                my $text                        = undef;
 
2056
                
 
2057
                #numbered ellipse
 
2058
                my $digit                       = undef;
 
2059
 
 
2060
                if ( exists $self->{_items}{$item}{ellipse} ) {
 
2061
                        
 
2062
                        $line_width = $self->{_items}{$item}{ellipse}->get('line-width');
 
2063
                        
 
2064
                        #numbered ellipse
 
2065
                        if ( exists $self->{_items}{$item}{text} ) {
 
2066
                                $text   = $self->{_items}{$item}{text}->get('text');
 
2067
                                $digit  = $self->{_items}{$item}{text}{digit};
 
2068
                        }
 
2069
                        
 
2070
                }elsif ( exists $self->{_items}{$item}{text} ) {
 
2071
 
 
2072
                        $text = $self->{_items}{$item}{text}->get('text');
 
2073
 
 
2074
                }elsif ( exists $self->{_items}{$item}{image} ) {
 
2075
 
 
2076
                }elsif ( exists $self->{_items}{$item}{line} ) {
 
2077
                        
 
2078
                        #line width
 
2079
                        $line_width = $self->{_items}{$item}{line}->get('line-width');          
 
2080
                        
 
2081
                        #arrow properties
 
2082
                        $end_arrow              = $self->{_items}{$item}{line}->get('end-arrow');
 
2083
                        $start_arrow    = $self->{_items}{$item}{line}->get('start-arrow');
 
2084
                        $arrow_width    = $self->{_items}{$item}{line}->get('arrow-width');
 
2085
                        $arrow_length   = $self->{_items}{$item}{line}->get('arrow-length');
 
2086
                        $tip_length             = $self->{_items}{$item}{line}->get('arrow-tip-length');
 
2087
                        
 
2088
                        #mirror flag
 
2089
                        $mirrored_w = $self->{_items}{$item}{mirrored_w};
 
2090
                        $mirrored_h = $self->{_items}{$item}{mirrored_h};
 
2091
                
 
2092
                }else{
 
2093
                
 
2094
                }
 
2095
 
 
2096
                #item props
 
2097
                %do_info = (
 
2098
                        'item'                          => $self->{_items}{$item},
 
2099
                        'action'                        => $action,
 
2100
                        'x'                             => $self->{_items}{$item}->get('x'),
 
2101
                        'y'                             => $self->{_items}{$item}->get('y'),
 
2102
                        'width'                         => $self->{_items}{$item}->get('width'),
 
2103
                        'height'                        => $self->{_items}{$item}->get('height'),
 
2104
                        'stroke_color'          => $self->{_items}{$item}{stroke_color},
 
2105
                        'stroke_color_alpha'=> $self->{_items}{$item}{stroke_color_alpha},
 
2106
                        'fill_color'            => $self->{_items}{$item}{fill_color},
 
2107
                        'fill_color_alpha'      => $self->{_items}{$item}{fill_color_alpha},
 
2108
                        'fill-pattern'          => $fill_pattern,
 
2109
                        'stroke-pattern'        => $stroke_pattern,
 
2110
                        'line-width'            => $line_width,
 
2111
                        'mirrored_w'            => $mirrored_w,
 
2112
                        'mirrored_h'            => $mirrored_h,
 
2113
                        'end-arrow'             => $end_arrow,          
 
2114
                        'start-arrow'           => $start_arrow,
 
2115
                        'arrow-length'          => $arrow_length,
 
2116
                        'arrow-width'           => $arrow_width,
 
2117
                        'arrow-tip-length'      => $tip_length, 
 
2118
                        'text'                          => $text,
 
2119
                        'digit'                         => $digit,
 
2120
                        'opt1'                          => $opt1,                       
 
2121
                );
 
2122
 
 
2123
        }elsif($item->isa('Goo::Canvas::Image') && $item == $self->{_canvas_bg}){
 
2124
 
 
2125
                #canvas_bg_image and bg_rect properties
 
2126
                %do_info = (
 
2127
                        'item'                          => $self->{_canvas_bg},
 
2128
                        'action'                        => $action,
 
2129
                        'drawing_pixbuf'        => $self->{_drawing_pixbuf},
 
2130
                        'x'                             => $self->{_canvas_bg_rect}->get('x'),
 
2131
                        'y'                             => $self->{_canvas_bg_rect}->get('y'),
 
2132
                        'width'                         => $self->{_canvas_bg_rect}->get('width'),
 
2133
                        'height'                        => $self->{_canvas_bg_rect}->get('height'),
 
2134
                        'opt1'                          => $opt1,                                       
 
2135
                );
 
2136
 
 
2137
        }elsif($item->isa('Goo::Canvas::Rect') && $item == $self->{_canvas_bg_rect}){
 
2138
 
 
2139
                #canvas_bg_rect properties
 
2140
                %do_info = (
 
2141
                        'item'                          => $self->{_canvas_bg_rect},
 
2142
                        'action'                        => $action,
 
2143
                        'x'                             => $self->{_canvas_bg_rect}->get('x'),
 
2144
                        'y'                             => $self->{_canvas_bg_rect}->get('y'),
 
2145
                        'width'                         => $self->{_canvas_bg_rect}->get('width'),
 
2146
                        'height'                        => $self->{_canvas_bg_rect}->get('height'),
 
2147
                        'opt1'                          => $opt1,       
 
2148
                );
 
2149
 
 
2150
        #polyline specific properties to hash
 
2151
        }elsif($item->isa('Goo::Canvas::Polyline')){
 
2152
 
 
2153
                my $stroke_pattern = $self->create_color( $self->{_items}{$item}{stroke_color}, $self->{_items}{$item}{stroke_color_alpha} );
 
2154
                my $transform = $self->{_items}{$item}->get('transform');
 
2155
                my $line_width = $self->{_items}{$item}->get('line-width');
 
2156
                my $points = $self->{_items}{$item}->get('points');     
 
2157
                
 
2158
                %do_info = (
 
2159
                        'item'                          => $self->{_items}{$item},
 
2160
                        'action'                        => $action,
 
2161
                        'points'                        => $points,
 
2162
                        'stroke-pattern'        => $stroke_pattern,
 
2163
                        'line-width'            => $line_width,
 
2164
                        'transform'             => $transform,
 
2165
                        'opt1'                          => $opt1,
 
2166
                );
 
2167
        
 
2168
        }
 
2169
 
 
2170
        #reset undo when creating new item after redo
 
2171
        if($action eq 'create'){
 
2172
                while (defined $self->{_redo} && scalar @{ $self->{_redo} } > 0){
 
2173
                        shift @{ $self->{_redo} };      
 
2174
                }       
 
2175
        }       
 
2176
        
 
2177
        if($xdo eq 'undo'){
 
2178
                push @{ $self->{_undo} }, \%do_info;            
 
2179
        }elsif($xdo eq 'redo'){
 
2180
                push @{ $self->{_redo} }, \%do_info; 
 
2181
        }
 
2182
 
 
2183
        #disable undo/redo actions
 
2184
        $self->{_uimanager}->get_widget("/MenuBar/Edit/Undo")->set_sensitive(scalar @{ $self->{_undo} }) if defined $self->{_undo};
 
2185
        $self->{_uimanager}->get_widget("/MenuBar/Edit/Redo")->set_sensitive(scalar @{ $self->{_redo} }) if defined $self->{_redo};
 
2186
 
 
2187
        $self->{_uimanager}->get_widget("/ToolBar/Undo")->set_sensitive(scalar @{ $self->{_undo} }) if defined $self->{_undo};
 
2188
        $self->{_uimanager}->get_widget("/ToolBar/Redo")->set_sensitive(scalar @{ $self->{_redo} }) if defined $self->{_redo};  
 
2189
        
 
2190
        return TRUE;    
 
2191
}
 
2192
 
 
2193
sub xdo {
 
2194
        my $self = shift;
 
2195
        my $xdo  = shift;
 
2196
 
 
2197
        my $do = undef; 
 
2198
        if($xdo eq 'undo'){
 
2199
                $do     = pop @{ $self->{_undo} };              
 
2200
        }elsif($xdo eq 'redo'){
 
2201
                $do     = pop @{ $self->{_redo} };              
 
2202
        }
 
2203
 
 
2204
        my $item        = $do->{'item'};
 
2205
        my $action      = $do->{'action'};
 
2206
        my $opt1        = $do->{'opt1'};
 
2207
 
 
2208
        return FALSE unless $item;
 
2209
        return FALSE unless $action;
 
2210
 
 
2211
        if($item->isa('Goo::Canvas::Image') && $item == $self->{_canvas_bg}){
 
2212
                $opt1->x($do->{'opt1'}->x*-1) ; 
 
2213
                $opt1->y($do->{'opt1'}->y*-1) ; 
 
2214
        }       
 
2215
 
 
2216
        #create reverse action
 
2217
        my $reverse_action = 'modify';
 
2218
        if ($action eq 'raise'){
 
2219
                $reverse_action = 'lower_xdo';
 
2220
        }elsif ($action eq 'raise_xdo'){
 
2221
                $reverse_action = 'lower_xdo';
 
2222
        }elsif($action eq 'lower'){
 
2223
                $reverse_action = 'raise_xdo';
 
2224
        }elsif($action eq 'lower_xdo'){
 
2225
                $reverse_action = 'raise_xdo';
 
2226
        }elsif($action eq 'create'){
 
2227
                $reverse_action = 'delete_xdo';
 
2228
        }elsif($action eq 'delete'){
 
2229
                $reverse_action = 'create_xdo';
 
2230
        }elsif($action eq 'create_xdo'){
 
2231
                $reverse_action = 'delete_xdo';
 
2232
        }elsif($action eq 'delete_xdo'){
 
2233
                $reverse_action = 'create_xdo';
 
2234
        }
 
2235
        
 
2236
        #undo or redo?
 
2237
        if($xdo eq 'undo'){
 
2238
                #store to redo stack
 
2239
                $self->store_to_xdo_stack($item, $reverse_action, 'redo', $opt1);       
 
2240
        }elsif($xdo eq 'redo'){
 
2241
                #store to undo stack
 
2242
                $self->store_to_xdo_stack($item, $reverse_action, 'undo', $opt1); 
 
2243
        }
 
2244
        
 
2245
        #finally undo the last event
 
2246
        if($action eq 'modify'){
 
2247
 
 
2248
                if($item->isa('Goo::Canvas::Rect') && $item != $self->{_canvas_bg_rect}){
 
2249
 
 
2250
                                $self->{_items}{$item}->set(
 
2251
                                        'x' => $do->{'x'},
 
2252
                                        'y' => $do->{'y'},
 
2253
                                        'width' =>      $do->{'width'},
 
2254
                                        'height' => $do->{'height'},
 
2255
                                );      
 
2256
                        
 
2257
                        if ( exists $self->{_items}{$item}{ellipse} ) {
 
2258
 
 
2259
                                $self->{_items}{$item}{ellipse}->set(
 
2260
                                        'fill-pattern'          => $do->{'fill-pattern'},
 
2261
                                        'stroke-pattern'        => $do->{'stroke-pattern'},
 
2262
                                        'line-width'            => $do->{'line-width'}, 
 
2263
                                );
 
2264
                                
 
2265
                                #numbered ellipse
 
2266
                                if ( exists $self->{_items}{$item}{text} ) {
 
2267
                                        $self->{_items}{$item}{text}->set(
 
2268
                                                'text'                          => $do->{'text'},
 
2269
                                                'fill-pattern'          => $do->{'stroke-pattern'},
 
2270
                                        );
 
2271
                                        $self->{_items}{$item}{text}{digit} = $do->{'digit'};
 
2272
                                }
 
2273
 
 
2274
                                #restore color and opacity as well
 
2275
                                $self->{_items}{$item}{fill_color}         = $do->{'fill_color'};
 
2276
                                $self->{_items}{$item}{fill_color_alpha}   = $do->{'fill_color_alpha'};
 
2277
                                $self->{_items}{$item}{stroke_color}       = $do->{'stroke_color'};
 
2278
                                $self->{_items}{$item}{stroke_color_alpha} = $do->{'stroke_color_alpha'};
 
2279
 
 
2280
                        }elsif ( exists $self->{_items}{$item}{text} ) {
 
2281
 
 
2282
                                $self->{_items}{$item}{text}->set(
 
2283
                                        'text'                          => $do->{'text'},
 
2284
                                        'fill-pattern'          => $do->{'stroke-pattern'},
 
2285
                                );
 
2286
 
 
2287
                                #restore color and opacity as well
 
2288
                                $self->{_items}{$item}{stroke_color}       = $do->{'stroke_color'};
 
2289
                                $self->{_items}{$item}{stroke_color_alpha} = $do->{'stroke_color_alpha'};
 
2290
 
 
2291
                        }elsif ( exists $self->{_items}{$item}{image} ) {
 
2292
 
 
2293
                                my $copy = undef;
 
2294
                                eval{
 
2295
                                        $copy = Gtk2::Gdk::Pixbuf->new_from_file_at_scale($self->{_items}{$item}{orig_pixbuf_filename},$self->{_items}{$item}->get('width'), $self->{_items}{$item}->get('height'), FALSE);
 
2296
                                };
 
2297
                                unless($@){             
 
2298
                                        $self->{_items}{$item}{image}->set(
 
2299
                                                'x'      => int $self->{_items}{$item}->get('x'),
 
2300
                                                'y'      => int $self->{_items}{$item}->get('y'),
 
2301
                                                'width'  => $self->{_items}{$item}->get('width'),
 
2302
                                                'height' => $self->{_items}{$item}->get('height'),
 
2303
                                                'pixbuf' => $copy
 
2304
                                        );
 
2305
                                }else{
 
2306
                                        my $response = $self->{_dialogs}->dlg_error_message( 
 
2307
                                                sprintf( $self->{_d}->get("Error while opening image %s."), "'" . $self->{_items}{$item}{orig_pixbuf_filename} . "'"),
 
2308
                                                $self->{_d}->get( "There was an error opening the image." ),
 
2309
                                                undef, undef, undef,
 
2310
                                                undef, undef, undef,
 
2311
                                                $@
 
2312
                                        );
 
2313
                                }       
 
2314
 
 
2315
                        }elsif ( exists $self->{_items}{$item}{line} ) {
 
2316
 
 
2317
                                #save arrow specific properties
 
2318
                                $self->{_items}{$item}{end_arrow}                       = $do->{'end-arrow'};
 
2319
                                $self->{_items}{$item}{start_arrow}             = $do->{'start-arrow'};
 
2320
                                $self->{_items}{$item}{arrow_width}             = $do->{'arrow-width'};
 
2321
                                $self->{_items}{$item}{arrow_length}            = $do->{'arrow-length'};
 
2322
                                $self->{_items}{$item}{arrow_tip_length}        = $do->{'arrow-tip-length'};
 
2323
 
 
2324
                                $self->{_items}{$item}{line}->set(
 
2325
                                        'fill-pattern'          => $do->{'fill-pattern'},
 
2326
                                        'stroke-pattern'        => $do->{'stroke-pattern'},
 
2327
                                        'line-width'            => $do->{'line-width'},
 
2328
                                        'end-arrow'             => $self->{_items}{$item}{end_arrow}, 
 
2329
                                        'start-arrow'           => $self->{_items}{$item}{start_arrow},
 
2330
                                        'arrow-length'          => $self->{_items}{$item}{arrow_length},
 
2331
                                        'arrow-width'           => $self->{_items}{$item}{arrow_width}, 
 
2332
                                        'arrow-tip-length'      => $self->{_items}{$item}{arrow_tip_length},            
 
2333
                                );
 
2334
 
 
2335
                                $self->{_items}{$item}{mirrored_w} = $do->{'mirrored_w'} if exists $do->{'mirrored_w'};
 
2336
                                $self->{_items}{$item}{mirrored_h} = $do->{'mirrored_h'} if exists $do->{'mirrored_h'};
 
2337
 
 
2338
                                #restore color and opacity as well
 
2339
                                $self->{_items}{$item}{stroke_color}       = $do->{'stroke_color'};
 
2340
                                $self->{_items}{$item}{stroke_color_alpha} = $do->{'stroke_color_alpha'};
 
2341
                        
 
2342
                        }else{
 
2343
 
 
2344
                                $self->{_items}{$item}->set(
 
2345
                                        'fill-pattern'          => $do->{'fill-pattern'},
 
2346
                                        'stroke-pattern'        => $do->{'stroke-pattern'},
 
2347
                                        'line-width'            => $do->{'line-width'}, 
 
2348
                                );
 
2349
 
 
2350
                                #restore color and opacity as well
 
2351
                                $self->{_items}{$item}{fill_color}         = $do->{'fill_color'};
 
2352
                                $self->{_items}{$item}{fill_color_alpha}   = $do->{'fill_color_alpha'};
 
2353
                                $self->{_items}{$item}{stroke_color}       = $do->{'stroke_color'};
 
2354
                                $self->{_items}{$item}{stroke_color_alpha} = $do->{'stroke_color_alpha'};
 
2355
                        
 
2356
                        }
 
2357
 
 
2358
                }elsif($item->isa('Goo::Canvas::Image') && $item == $self->{_canvas_bg}){
 
2359
 
 
2360
                        my $new_w = $do->{'drawing_pixbuf'}->get_width;
 
2361
                        my $new_h = $do->{'drawing_pixbuf'}->get_height;
 
2362
                        
 
2363
                        #update bounds and bg_rects
 
2364
                        $self->{_canvas_bg_rect}->set(
 
2365
                                'width'         => $new_w, 
 
2366
                                'height'        => $new_h,
 
2367
                        );
 
2368
 
 
2369
                        #we need to move the shapes
 
2370
                        $self->move_all($opt1->x, $opt1->y);
 
2371
 
 
2372
                        #update canvas and show the new pixbuf
 
2373
                        $self->{_canvas_bg}->set('pixbuf' => $do->{'drawing_pixbuf'});
 
2374
                                                
 
2375
                        #save new pixbuf in var
 
2376
                        $self->{_drawing_pixbuf} = $do->{'drawing_pixbuf'}->copy;
 
2377
 
 
2378
                        #update bounds and bg_rects
 
2379
                        $self->{_canvas_bg_rect}->set(
 
2380
                                'x' => $do->{'x'},
 
2381
                                'y' => $do->{'y'},
 
2382
                                'width' =>      $do->{'width'},
 
2383
                                'height' => $do->{'height'},
 
2384
                        );
 
2385
                                                
 
2386
                        #adjust stack order
 
2387
                        $self->{_canvas_bg}->lower;
 
2388
                        $self->{_canvas_bg_rect}->lower;
 
2389
                        $self->handle_bg_rects( 'raise' );      
 
2390
 
 
2391
                }elsif($item->isa('Goo::Canvas::Rect') && $item == $self->{_canvas_bg_rect}){
 
2392
                        
 
2393
                        $self->{_canvas_bg_rect}->set(
 
2394
                                'x' => $do->{'x'},
 
2395
                                'y' => $do->{'y'},
 
2396
                                'width' =>      $do->{'width'},
 
2397
                                'height' => $do->{'height'},
 
2398
                        );
 
2399
                                                
 
2400
                #polyline specific properties
 
2401
                }elsif($item->isa('Goo::Canvas::Polyline')){
 
2402
                        
 
2403
                        #if pattern exists
 
2404
                        #e.g. censor tool does not have a pattern
 
2405
                        if($do->{'stroke-pattern'}){
 
2406
                                        
 
2407
                                $self->{_items}{$item}->set(
 
2408
                                        'stroke-pattern' => $do->{'stroke-pattern'},
 
2409
                                        'line-width'     => $do->{'line-width'},        
 
2410
                                        'points'                 => $do->{'points'},
 
2411
                                        'transform'              => $do->{'transform'},
 
2412
                                );
 
2413
 
 
2414
                                $self->{_items}{$item}{stroke_color}       = $do->{'stroke_color'};
 
2415
                                $self->{_items}{$item}{stroke_color_alpha} = $do->{'stroke_color_alpha'};       
 
2416
                                
 
2417
                        }else{
 
2418
 
 
2419
                                $self->{_items}{$item}->set(
 
2420
                                        'line-width'     => $do->{'line-width'},        
 
2421
                                        'points'                 => $do->{'points'},
 
2422
                                        'transform'              => $do->{'transform'},
 
2423
                                );
 
2424
                        }       
 
2425
                        
 
2426
                }               
 
2427
 
 
2428
                #handle resize rectangles and embedded objects
 
2429
                if ($item == $self->{_canvas_bg_rect} || $item == $self->{_canvas_bg}){
 
2430
 
 
2431
                        $self->handle_bg_rects( 'update', $self->{_canvas_bg_rect} );           
 
2432
                
 
2433
                }else{
 
2434
 
 
2435
                        $self->handle_rects( 'update', $self->{_items}{$item} );
 
2436
                        $self->handle_embedded( 'update', $self->{_items}{$item} );             
 
2437
                        $self->{_current_item} = $item; 
 
2438
 
 
2439
                        #apply item properties to widgets
 
2440
                        #line width, fill color, stroke color etc.
 
2441
                        $self->set_and_save_drawing_properties($self->{_current_item}, FALSE);  
 
2442
                                        
 
2443
                }
 
2444
 
 
2445
        }elsif($action eq 'raise' || $action eq 'raise_xdo'){ 
 
2446
                        
 
2447
                my $child = $self->get_child_item($item);
 
2448
                if ($child) {
 
2449
                        $self->handle_rects( 'lower', $item );
 
2450
                        $child->lower;
 
2451
                        $item->lower;
 
2452
                } else {
 
2453
                        $self->handle_rects( 'lower', $item );
 
2454
                        $item->lower;
 
2455
                }
 
2456
                $self->{_canvas_bg}->lower;
 
2457
                $self->{_canvas_bg_rect}->lower;
 
2458
        
 
2459
        }elsif($action eq 'lower' || $action eq 'lower_xdo'){ 
 
2460
 
 
2461
                my $child = $self->get_child_item($item);
 
2462
                if ($child) {
 
2463
                        $child->raise;
 
2464
                        $item->raise;
 
2465
                        $self->handle_rects( 'raise', $item );
 
2466
                } else {
 
2467
                        $item->raise;
 
2468
                        $self->handle_rects( 'raise', $item );
 
2469
                }
 
2470
                
 
2471
        }elsif($action eq 'delete' || $action eq 'delete_xdo'){ 
 
2472
                        
 
2473
                        #mark as current
 
2474
                        $self->{_last_item}        = $self->{_current_item};            
 
2475
                        $self->{_current_item}     = $item;
 
2476
                        $self->{_current_new_item} = undef;
 
2477
 
 
2478
                        $self->{_items}{$item}->set('visibility' => 'visible');
 
2479
                        $self->handle_rects( 'update', $self->{_items}{$item} );
 
2480
                        $self->handle_embedded( 'update', $self->{_items}{$item} );     
 
2481
        
 
2482
        }elsif($action eq 'create' || $action eq 'create_xdo'){
 
2483
        
 
2484
                        $self->{_items}{$item}->set('visibility' => 'hidden');
 
2485
                        $self->handle_rects( 'hide', $self->{_items}{$item} );
 
2486
                        $self->handle_embedded( 'hide', $self->{_items}{$item} );
 
2487
 
 
2488
        }
 
2489
                        
 
2490
        #disable undo/redo actions
 
2491
        $self->{_uimanager}->get_widget("/MenuBar/Edit/Undo")->set_sensitive(scalar @{ $self->{_undo} }) if defined $self->{_undo};
 
2492
        $self->{_uimanager}->get_widget("/MenuBar/Edit/Redo")->set_sensitive(scalar @{ $self->{_redo} }) if defined $self->{_redo};     
 
2493
 
 
2494
        $self->{_uimanager}->get_widget("/ToolBar/Undo")->set_sensitive(scalar @{ $self->{_undo} }) if defined $self->{_undo};
 
2495
        $self->{_uimanager}->get_widget("/ToolBar/Redo")->set_sensitive(scalar @{ $self->{_redo} }) if defined $self->{_redo};  
 
2496
 
 
2497
        $self->deactivate_all;
 
2498
        
 
2499
        return TRUE;    
 
2500
}
 
2501
 
 
2502
sub set_and_save_drawing_properties {
 
2503
        my $self          = shift;
 
2504
        my $item          = shift;
 
2505
        my $save_only = shift;
 
2506
 
 
2507
        return FALSE unless $item;
 
2508
 
 
2509
        #~ print "set_and_save_drawing_properties\n";
 
2510
 
 
2511
        #determine key for item hash
 
2512
        if(my $child = $self->get_child_item($item)){
 
2513
                $item = $child;
 
2514
        }
 
2515
        my $parent      = $self->get_parent_item($item);
 
2516
        my $key = $self->get_item_key($item, $parent);
 
2517
 
 
2518
        #we do not remember the properties for some tools
 
2519
        #and don't remember them when just selecting items with the cursor
 
2520
        if($self->{_items}{$key}{type} ne "highlighter" && 
 
2521
           $self->{_items}{$key}{type} ne "image" &&
 
2522
           $self->{_current_mode} != 10 )
 
2523
        {
 
2524
                                
 
2525
                #remember drawing colors, line width and font settings
 
2526
                #maybe we have to restore them
 
2527
                $self->{_last_fill_color}         = $self->{_fill_color_w}->get_color;
 
2528
                $self->{_last_fill_color_alpha}   = $self->{_fill_color_w}->get_alpha / 65535;
 
2529
                $self->{_last_stroke_color}       = $self->{_stroke_color_w}->get_color;
 
2530
                $self->{_last_stroke_color_alpha} = $self->{_stroke_color_w}->get_alpha / 65535;
 
2531
                $self->{_last_line_width}                 = $self->{_line_spin_w}->get_value;
 
2532
                $self->{_last_font}                       = $self->{_font_btn_w}->get_font_name;
 
2533
 
 
2534
                #remember the last mode as well
 
2535
                $self->{_last_mode}               = $self->{_current_mode};
 
2536
                $self->{_last_mode_descr}         = $self->{_current_mode_descr};
 
2537
 
 
2538
        }
 
2539
        
 
2540
        return TRUE if $save_only;
 
2541
        
 
2542
        #block 'value-change' handlers for widgets
 
2543
        #so we do not apply the changes twice
 
2544
        $self->{_line_spin_w}->signal_handler_block ($self->{_line_spin_wh});
 
2545
        $self->{_stroke_color_w}->signal_handler_block ($self->{_stroke_color_wh});
 
2546
        $self->{_fill_color_w}->signal_handler_block ($self->{_fill_color_wh});
 
2547
        $self->{_font_btn_w}->signal_handler_block ($self->{_font_btn_wh});
 
2548
 
 
2549
        if (   $item->isa('Goo::Canvas::Rect')
 
2550
                || $item->isa('Goo::Canvas::Ellipse')
 
2551
                || $item->isa('Goo::Canvas::Polyline') )
 
2552
        {
 
2553
                                
 
2554
                #line width
 
2555
                $self->{_line_spin_w}->set_value( $item->get('line-width') );
 
2556
                        
 
2557
                #stroke color
 
2558
                #some items, e.g. censor tool, do not have a color - skip them
 
2559
                if($self->{_items}{$key}{stroke_color}){
 
2560
                        $self->{_stroke_color_w}->set_color( $self->{_items}{$key}{stroke_color} );
 
2561
                        $self->{_stroke_color_w}->set_alpha( int( $self->{_items}{$key}{stroke_color_alpha} * 65535 ) );
 
2562
                }
 
2563
        
 
2564
                if ( $item->isa('Goo::Canvas::Rect') || $item->isa('Goo::Canvas::Ellipse') ) {
 
2565
        
 
2566
                        #fill color
 
2567
                        $self->{_fill_color_w}->set_color( $self->{_items}{$key}{fill_color} );
 
2568
                        $self->{_fill_color_w}->set_alpha( int( $self->{_items}{$key}{fill_color_alpha} * 65535 ) );
 
2569
                        
 
2570
                        #numbered shapes
 
2571
                        if(exists($self->{_items}{$key}{text})){
 
2572
                                #determine font description from string
 
2573
                                my ( $attr_list, $text_raw, $accel_char ) = Gtk2::Pango->parse_markup( $self->{_items}{$key}{text}->get('text') );
 
2574
                                my $font_desc = Gtk2::Pango::FontDescription->from_string( $self->{_font} );
 
2575
 
 
2576
                                #FIXME, maybe the pango version installed is too old
 
2577
                                eval {
 
2578
                                        $attr_list->filter(
 
2579
                                                sub {
 
2580
                                                        my $attr = shift;
 
2581
                                                        $font_desc = $attr->copy->desc
 
2582
                                                                if $attr->isa('Gtk2::Pango::AttrFontDesc');
 
2583
                                                        return TRUE;
 
2584
                                                },
 
2585
                                        );
 
2586
                                };
 
2587
                                if ($@) {
 
2588
                                        print "\nERROR: Pango Markup could not be parsed:\n$@";
 
2589
                                }
 
2590
 
 
2591
                                #apply current font settings to button
 
2592
                                $self->{_font_btn_w}->set_font_name( $font_desc->to_string );
 
2593
                                
 
2594
                        }
 
2595
                }
 
2596
 
 
2597
        }elsif ( $item->isa('Goo::Canvas::Text') ) {
 
2598
 
 
2599
                #determine font description from string
 
2600
                my ( $attr_list, $text_raw, $accel_char ) = Gtk2::Pango->parse_markup( $item->get('text') );
 
2601
                my $font_desc = Gtk2::Pango::FontDescription->from_string( $self->{_font} );
 
2602
 
 
2603
                #FIXME, maybe the pango version installed is too old
 
2604
                eval {
 
2605
                        $attr_list->filter(
 
2606
                                sub {
 
2607
                                        my $attr = shift;
 
2608
                                        $font_desc = $attr->copy->desc
 
2609
                                                if $attr->isa('Gtk2::Pango::AttrFontDesc');
 
2610
                                        return TRUE;
 
2611
                                },
 
2612
                        );
 
2613
                };
 
2614
                if ($@) {
 
2615
                        print "\nERROR: Pango Markup could not be parsed:\n$@";
 
2616
                }
 
2617
 
 
2618
                #font color
 
2619
                $self->{_stroke_color_w}->set_color( $self->{_items}{$key}{stroke_color} );
 
2620
                $self->{_stroke_color_w}->set_alpha( int( $self->{_items}{$key}{stroke_color_alpha} * 65535 ) );
 
2621
 
 
2622
                #apply current font settings to button
 
2623
                $self->{_font_btn_w}->set_font_name( $font_desc->to_string );
 
2624
                
 
2625
        }
 
2626
 
 
2627
        #update global values
 
2628
        $self->{_line_width}                    = $self->{_line_spin_w}->get_value;     
 
2629
        $self->{_stroke_color}          = $self->{_stroke_color_w}->get_color;
 
2630
        $self->{_stroke_color_alpha}    = $self->{_stroke_color_w}->get_alpha / 65535;          
 
2631
        $self->{_fill_color}                    = $self->{_fill_color_w}->get_color;
 
2632
        $self->{_fill_color_alpha}              = $self->{_fill_color_w}->get_alpha / 65636;
 
2633
        my $font_descr = Gtk2::Pango::FontDescription->from_string( $self->{_font_btn_w}->get_font_name );
 
2634
        $self->{_font}                                  = $font_descr->to_string;
 
2635
 
 
2636
        #unblock 'value-change' handlers for widgets
 
2637
        $self->{_line_spin_w}->signal_handler_unblock ($self->{_line_spin_wh});
 
2638
        $self->{_stroke_color_w}->signal_handler_unblock ($self->{_stroke_color_wh});
 
2639
        $self->{_fill_color_w}->signal_handler_unblock ($self->{_fill_color_wh});
 
2640
        $self->{_font_btn_w}->signal_handler_unblock ($self->{_font_btn_wh});
 
2641
 
 
2642
}
 
2643
 
 
2644
sub restore_drawing_properties {
 
2645
        my $self = shift;
 
2646
 
 
2647
        #saved properties available?
 
2648
        return FALSE unless defined $self->{_last_fill_color};
 
2649
 
 
2650
        #anything done until now?
 
2651
        return FALSE unless defined $self->{_last_mode};
 
2652
 
 
2653
        #~ print "restore_drawing_properties\n";
 
2654
 
 
2655
        #block 'value-change' handlers for widgets
 
2656
        #so we do not apply the changes twice
 
2657
        $self->{_line_spin_w}->signal_handler_block ($self->{_line_spin_wh});
 
2658
        $self->{_stroke_color_w}->signal_handler_block ($self->{_stroke_color_wh});
 
2659
        $self->{_fill_color_w}->signal_handler_block ($self->{_fill_color_wh});
 
2660
        $self->{_font_btn_w}->signal_handler_block ($self->{_font_btn_wh});
 
2661
 
 
2662
        #restore them
 
2663
        $self->{_fill_color_w}->set_color($self->{_last_fill_color});
 
2664
        $self->{_fill_color_w}->set_alpha( int($self->{_last_fill_color_alpha} * 65535) );
 
2665
        $self->{_stroke_color_w}->set_color($self->{_last_stroke_color});
 
2666
        $self->{_stroke_color_w}->set_alpha( int($self->{_last_stroke_color_alpha} * 65535) );
 
2667
        $self->{_line_spin_w}->set_value($self->{_last_line_width});
 
2668
        $self->{_font_btn_w}->set_font_name($self->{_last_font});       
 
2669
 
 
2670
        #update global values
 
2671
        $self->{_line_width}                    = $self->{_line_spin_w}->get_value;     
 
2672
        $self->{_stroke_color}          = $self->{_stroke_color_w}->get_color;
 
2673
        $self->{_stroke_color_alpha}    = $self->{_stroke_color_w}->get_alpha / 65535;          
 
2674
        $self->{_fill_color}                    = $self->{_fill_color_w}->get_color;
 
2675
        $self->{_fill_color_alpha}              = $self->{_fill_color_w}->get_alpha / 65636;
 
2676
        my $font_descr = Gtk2::Pango::FontDescription->from_string( $self->{_font_btn_w}->get_font_name );
 
2677
        $self->{_font}                                  = $font_descr->to_string;
 
2678
                
 
2679
        #unblock 'value-change' handlers for widgets
 
2680
        $self->{_line_spin_w}->signal_handler_unblock ($self->{_line_spin_wh});
 
2681
        $self->{_stroke_color_w}->signal_handler_unblock ($self->{_stroke_color_wh});
 
2682
        $self->{_fill_color_w}->signal_handler_unblock ($self->{_fill_color_wh});
 
2683
        $self->{_font_btn_w}->signal_handler_unblock ($self->{_font_btn_wh});
 
2684
        
1435
2685
}
1436
2686
 
1437
2687
sub event_item_on_button_press {
1438
2688
        my ( $self, $item, $target, $ev ) = @_;
1439
2689
 
1440
 
        my $d      = $self->{_shutter_common}->get_gettext;
 
2690
        #~ print "button-press\n";
 
2691
 
 
2692
        #canvas is busy now...
 
2693
        $self->{_busy} = TRUE;
 
2694
 
1441
2695
        my $cursor = Gtk2::Gdk::Cursor->new('left-ptr');
1442
2696
 
1443
 
        my $valid = FALSE;
1444
 
        $valid = TRUE if $self->{_canvas}->get_item_at( $ev->x, $ev->y, TRUE );
1445
 
 
1446
2697
        #activate item
1447
 
        if ( $valid && $self->{_current_mode_descr} eq "select" ) {
 
2698
        #if it is not activated yet
 
2699
        #
 
2700
        #single click
 
2701
        if ($ev->type eq 'button-press' && $self->{_current_mode_descr} eq "select") {
1448
2702
 
1449
2703
                #embedded item?
1450
2704
                my $parent = $self->get_parent_item($item);
1453
2707
                #real shape
1454
2708
                if ( exists $self->{_items}{$item} ) {
1455
2709
 
1456
 
                        $self->{_last_item}        = $self->{_current_item};
1457
 
                        $self->{_current_item}     = $item;
1458
 
                        $self->{_current_new_item} = undef;
1459
 
                        $self->handle_rects( 'hide',   $self->{_last_item} );
1460
 
                        $self->handle_rects( 'update', $self->{_current_item} );
 
2710
                        unless (defined $self->{_current_item} && $item == $self->{_current_item}){
1461
2711
 
 
2712
                                $self->{_last_item}        = $self->{_current_item};            
 
2713
                                $self->{_current_item}     = $item;
 
2714
                                $self->{_current_new_item} = undef;
 
2715
                                $self->handle_rects( 'update', $self->{_current_item} );
 
2716
                                $self->handle_rects( 'hide',   $self->{_last_item} );
 
2717
                
 
2718
                                #apply item properties to widgets
 
2719
                                #line width, fill color, stroke color etc.
 
2720
                                $self->set_and_save_drawing_properties($self->{_current_item}, FALSE);
 
2721
                
 
2722
                        }
 
2723
                        
 
2724
                        #no item selected, deactivate all items and leave sub
 
2725
                }elsif($item == $self->{_canvas_bg} || $item == $self->{_canvas_bg_rect}){
 
2726
                                
 
2727
                        $self->deactivate_all;
 
2728
                        return FALSE;
 
2729
                        
1462
2730
                }
1463
 
        } else {
1464
 
                $self->deactivate_all;
1465
 
        }
1466
 
 
1467
 
        if ( $ev->button == 1 && $valid ) {
1468
 
 
1469
 
                my $canvas = $item->get_canvas;
1470
 
                my $root   = $canvas->get_root_item;
1471
 
 
1472
 
                #CLEAR
1473
 
                if ( $self->{_current_mode_descr} eq "clear" ) {
1474
 
 
1475
 
                        return TRUE if $item == $self->{_canvas_bg};
1476
 
 
1477
 
                        #only real shapes can be deleted
1478
 
                        #don't delete resize boxes or boundaries
1479
 
                        if ( exists $self->{_items}{$item} ) {
1480
 
 
1481
 
                                $self->clear_item_from_canvas($item);
1482
 
                                        
1483
 
                        }
1484
 
 
1485
 
                        $self->{_canvas}->window->set_cursor($cursor);
 
2731
        } 
 
2732
        
 
2733
        #left mouse click to drag, resize, create or delelte items
 
2734
        if ( $ev->type eq 'button-press' && $ev->button == 1 ) {
 
2735
 
 
2736
                my $root   = $self->{_canvas}->get_root_item;
1486
2737
 
1487
2738
                #MOVE AND SELECT
1488
 
                } elsif ( $self->{_current_mode_descr} eq "select" ) {
1489
 
 
1490
 
                        #                       return TRUE if $item == $self->{_canvas_bg};
 
2739
                if ( $self->{_current_mode_descr} eq "select" ) {
1491
2740
 
1492
2741
                        if ( $item->isa('Goo::Canvas::Rect') ) {
1493
 
 
1494
 
                                #real shape
 
2742
                                
 
2743
                                        #don't_move the bounding rectangle
 
2744
                                return TRUE if $item == $self->{_canvas_bg_rect};
 
2745
                        
 
2746
                                        #real shape => move 
1495
2747
                                if ( exists $self->{_items}{$item} ) {
1496
 
                                        $item->{drag_x}   = $ev->x;
1497
 
                                        $item->{drag_y}   = $ev->y;
1498
 
                                        $item->{dragging} = TRUE;
 
2748
                                        $item->{drag_x}                 = $ev->x_root;
 
2749
                                        $item->{drag_y}                 = $ev->y_root;
 
2750
                                        $item->{dragging}               = TRUE;
 
2751
                                        $item->{dragging_start} = TRUE;
1499
2752
 
1500
2753
                                        $cursor = Gtk2::Gdk::Cursor->new('fleur');
1501
2754
                                        
1502
 
                                        #add to undo stack
1503
 
                                        $self->store_to_xdo_stack($self->{_current_item} , 'modify', 'undo');
1504
 
 
1505
 
                                        #resizing shape
 
2755
                                        #resizing shape => resize
1506
2756
                                } else {
1507
2757
 
1508
 
                                        $item->{res_x}    = $ev->x;
1509
 
                                        $item->{res_y}    = $ev->y;
1510
 
                                        $item->{resizing} = TRUE;
 
2758
                                        $item->{res_x}                  = $ev->x_root;
 
2759
                                        $item->{res_y}                  = $ev->y_root;
 
2760
                                        $item->{resizing}               = TRUE;
1511
2761
 
1512
2762
                                        $cursor = undef;
1513
 
 
1514
 
                                        #add to undo stack
1515
 
                                        $self->store_to_xdo_stack($self->{_current_item} , 'modify', 'undo');
 
2763
                                        
 
2764
                                        #resizing the canvas_bg_rect
 
2765
                                        if ($self->{_canvas_bg_rect}{'right-side'} == $item
 
2766
                                                || $self->{_canvas_bg_rect}{'bottom-side'} == $item
 
2767
                                                || $self->{_canvas_bg_rect}{'bottom-right-corner'} == $item ){
 
2768
 
 
2769
                                                #add to undo stack
 
2770
                                                $self->store_to_xdo_stack($self->{_canvas_bg_rect} , 'modify', 'undo');                                                         
 
2771
                                        
 
2772
                                        #other resizing rectangles
 
2773
                                        }else{
 
2774
 
 
2775
                                                #add to undo stack
 
2776
                                                $self->store_to_xdo_stack($self->{_current_item} , 'modify', 'undo');
 
2777
                                
 
2778
                                        }
1516
2779
 
1517
2780
                                }
1518
 
 
 
2781
                        
 
2782
                        #no rectangle, e.g. polyline
1519
2783
                        } else {
1520
2784
 
1521
 
                                #click on background => deactivate all selected items
1522
 
                                if ( $item == $self->{_canvas_bg} ) {
1523
 
 
1524
 
                                        $self->deactivate_all;
1525
 
 
1526
 
                                }
1527
 
 
1528
 
                                #no rect and no background, just move it ...
1529
 
                                $item->{drag_x}   = $ev->x;
1530
 
                                $item->{drag_y}   = $ev->y;
1531
 
                                $item->{dragging} = TRUE;
 
2785
                                #no rect, just move it ...
 
2786
                                $item->{drag_x}                 = $ev->x;
 
2787
                                $item->{drag_y}                 = $ev->y;
 
2788
                                $item->{dragging}               = TRUE;
 
2789
                                $item->{dragging_start} = TRUE;
1532
2790
 
1533
2791
                                #add to undo stack
1534
 
                                $self->store_to_xdo_stack($self->{_current_item} , 'modify', 'undo');
 
2792
                                #~ $self->store_to_xdo_stack($self->{_current_item} , 'modify', 'undo');
1535
2793
 
1536
2794
                                $cursor = undef;
1537
2795
 
1538
2796
                        }
1539
2797
 
1540
 
                        $canvas->pointer_grab( $item, [ 'pointer-motion-mask', 'button-release-mask' ], $cursor, $ev->time );
 
2798
                        $self->{_canvas}->pointer_grab( $item, [ 'pointer-motion-mask', 'button-release-mask' ], $cursor, $ev->time );
1541
2799
 
 
2800
                #CREATE 
1542
2801
                } else {
1543
2802
 
1544
 
                        #FREEHAND
 
2803
                        $self->deactivate_all;
 
2804
 
 
2805
                                #freehand
1545
2806
                        if ( $self->{_current_mode_descr} eq "freehand" ) {
1546
2807
 
1547
 
                                $self->create_polyline( $ev, undef );
 
2808
                                $self->create_polyline( $ev, undef, FALSE );
 
2809
 
 
2810
                                #highlighter
 
2811
                        } elsif ( $self->{_current_mode_descr} eq "highlighter" ) {
 
2812
 
 
2813
                                $self->create_polyline( $ev, undef, TRUE );
1548
2814
 
1549
2815
                                #Line
1550
2816
                        } elsif ( $self->{_current_mode_descr} eq "line" ) {
1551
2817
 
1552
2818
                                $self->create_line( $ev, undef );
 
2819
 
 
2820
                                #Arrow
 
2821
                        } elsif ( $self->{_current_mode_descr} eq "arrow" ) {
 
2822
 
 
2823
                                $self->create_line( $ev, undef, TRUE, FALSE );
1553
2824
                                
1554
2825
                                #Censor
1555
2826
                        } elsif ( $self->{_current_mode_descr} eq "censor" ) {
1556
2827
 
1557
2828
                                $self->create_censor( $ev, undef );
 
2829
                                
 
2830
                                #Number
 
2831
                        } elsif ( $self->{_current_mode_descr} eq "number" ) {
 
2832
 
 
2833
                                $self->create_ellipse( $ev, undef, TRUE );
1558
2834
 
1559
2835
                                #RECTANGLES
1560
2836
                        } elsif ( $self->{_current_mode_descr} eq "rect" ) {
1578
2854
 
1579
2855
                        }
1580
2856
                }
1581
 
        } elsif ( $ev->button == 2 && $valid ) {
1582
 
 
1583
 
                #right click => show context menu
1584
 
        } elsif ( $ev->button == 3 && $valid ) {
1585
 
 
1586
 
                if ( $item->isa('Goo::Canvas::Rect') || $item->isa('Goo::Canvas::Polyline') ) {
1587
 
 
1588
 
                        if ( exists $self->{_items}{$item} ) {
1589
 
 
1590
 
                                my $child = $self->get_child_item($item);
1591
 
                                #~ print $child."\n";
1592
 
                                if ($child) {
1593
 
                                        $item = $child;
1594
 
                                } else {
1595
 
 
1596
 
                                        my $item_menu = $self->ret_item_menu($item);
1597
 
 
1598
 
                                        $item_menu->popup(
1599
 
                                                undef,    # parent menu shell
1600
 
                                                undef,    # parent menu item
1601
 
                                                undef,    # menu pos func
1602
 
                                                undef,    # data
1603
 
                                                $ev->button,
1604
 
                                                $ev->time
1605
 
                                        );
1606
 
 
1607
 
                                }
1608
 
 
1609
 
                        }
 
2857
 
 
2858
                #right click => show context menu, double-click => show properties directly 
 
2859
        } elsif ( ($ev->type eq '2button-press' || $ev->button == 3) && $self->{_current_mode_descr} eq "select") {
 
2860
                
 
2861
                #no menu for background and image
 
2862
                return TRUE if ($item == $self->{_canvas_bg} || $item == $self->{_canvas_bg_rect});
 
2863
        
 
2864
                $self->{_canvas}->pointer_ungrab( $item, $ev->time );
 
2865
 
 
2866
                #determine key for item hash
 
2867
                if(my $child = $self->get_child_item($item)){
 
2868
                        $item = $child;
1610
2869
                }
1611
 
 
1612
 
                if (   $item->isa('Goo::Canvas::Ellipse')
1613
 
                        || $item->isa('Goo::Canvas::Text')
1614
 
                        || $item->isa('Goo::Canvas::Image') 
1615
 
                        || $item->isa('Goo::Canvas::Polyline') )
1616
 
                {
1617
 
 
1618
 
                        return TRUE if $item == $self->{_canvas_bg};
1619
 
 
1620
 
                        #embedded item?
1621
 
                        my $parent = $self->get_parent_item($item);
1622
 
 
1623
 
                        #real shape
1624
 
                        if ( exists $self->{_items}{$parent} ) {
1625
 
 
1626
 
                                my $item_menu = $self->ret_item_menu( $item, $parent );
 
2870
                my $parent      = $self->get_parent_item($item);
 
2871
                my $key = $self->get_item_key($item, $parent);
 
2872
 
 
2873
                #no real shape, maybe resizing rectangle of bg_rect
 
2874
                return TRUE unless $key;
 
2875
 
 
2876
                #real shape
 
2877
                if ( exists $self->{_items}{$key} ) {
 
2878
                        if( $ev->type eq '2button-press' ) {
 
2879
 
 
2880
                                #some items do not have properties, e.g. images or censor
 
2881
                                return FALSE if $item->isa('Goo::Canvas::Image') || !exists($self->{_items}{$key}{stroke_color});
 
2882
                                
 
2883
                                $self->show_item_properties($item, $parent, $key);
 
2884
                                
 
2885
                        }elsif( $ev->type eq 'button-press' ){
 
2886
                                                                
 
2887
                                my $item_menu = $self->ret_item_menu($item, $parent, $key);
1627
2888
 
1628
2889
                                $item_menu->popup(
1629
2890
                                        undef,    # parent menu shell
1632
2893
                                        undef,    # data
1633
2894
                                        $ev->button,
1634
2895
                                        $ev->time
1635
 
                                );
1636
 
                        }
1637
 
 
 
2896
                                );                                                              
 
2897
                        }                               
1638
2898
                }
1639
2899
 
1640
 
        #zooming using the mouse wheel
1641
 
        #~ } elsif ( $ev->button == 4  ) {
1642
 
                #~ $self->zoom_in_cb;           
1643
 
        #~ } elsif ( $ev->button == 5  ) {
1644
 
                #~ $self->zoom_out_cb;
1645
2900
        }               
1646
2901
 
1647
2902
        return TRUE;
1651
2906
        my $self   = shift;
1652
2907
        my $item   = shift;
1653
2908
        my $parent = shift;
1654
 
 
1655
 
        #determine key for item hash
1656
 
        my $key = undef;
1657
 
        if ( exists $self->{_items}{$item} ) {
1658
 
                $key = $item;
1659
 
        } else {
1660
 
                $key = $parent;
1661
 
        }
1662
 
 
1663
 
        my $d      = $self->{_shutter_common}->get_gettext;
1664
 
        my $dicons = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool";
 
2909
        my $key    = shift;
 
2910
 
 
2911
        #~ print "ret_item_menu\n";
1665
2912
 
1666
2913
        my $menu_item = Gtk2::Menu->new;
1667
2914
 
1668
2915
        #raise
1669
 
        my $raise_item = Gtk2::ImageMenuItem->new( $d->get("Raise") );
 
2916
        my $raise_item = Gtk2::ImageMenuItem->new( $self->{_d}->get("Raise") );
1670
2917
        $raise_item->set_image(
1671
 
                Gtk2::Image->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$dicons/draw-raise.png", Gtk2::IconSize->lookup('menu') ) ) );
 
2918
                Gtk2::Image->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file_at_size( $self->{_dicons}.'/draw-raise.png', Gtk2::IconSize->lookup('menu') ) ) );
1672
2919
        $raise_item->signal_connect(
1673
2920
                'activate' => sub {
1674
 
                        $item->raise;
1675
2921
                        if ($parent) {
 
2922
                                #add to undo stack
 
2923
                                $self->store_to_xdo_stack($parent, 'raise', 'undo');
1676
2924
                                $parent->raise;
 
2925
                                $item->raise;
1677
2926
                                $self->handle_rects( 'raise', $parent );
1678
2927
                        } else {
 
2928
                                #add to undo stack
 
2929
                                $self->store_to_xdo_stack($item, 'raise', 'undo');
 
2930
                                $item->raise;
1679
2931
                                $self->handle_rects( 'raise', $item );
1680
2932
                        }
1681
2933
                }
1684
2936
        $menu_item->append($raise_item);
1685
2937
 
1686
2938
        #lower
1687
 
        my $lower_item = Gtk2::ImageMenuItem->new( $d->get("Lower") );
 
2939
        my $lower_item = Gtk2::ImageMenuItem->new( $self->{_d}->get("Lower") );
1688
2940
        $lower_item->set_image(
1689
 
                Gtk2::Image->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file_at_size( "$dicons/draw-lower.png", Gtk2::IconSize->lookup('menu') ) ) );
 
2941
                Gtk2::Image->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file_at_size( $self->{_dicons}.'/draw-lower.png', Gtk2::IconSize->lookup('menu') ) ) );
1690
2942
 
1691
2943
        $lower_item->signal_connect(
1692
 
                'activate' => sub {
1693
 
                        $item->lower;
 
2944
                'activate' => sub {                     
1694
2945
                        if ($parent) {
 
2946
                                #add to undo stack
 
2947
                                $self->store_to_xdo_stack($parent, 'lower', 'undo');
 
2948
                                $self->handle_rects( 'lower', $parent );
 
2949
                                $item->lower;
1695
2950
                                $parent->lower;
1696
 
                                $self->handle_rects( 'lower', $parent );
1697
2951
                        } else {
 
2952
                                #add to undo stack
 
2953
                                $self->store_to_xdo_stack($item, 'lower', 'undo');
1698
2954
                                $self->handle_rects( 'lower', $item );
 
2955
                                $item->lower;
1699
2956
                        }
1700
2957
                        $self->{_canvas_bg}->lower;
 
2958
                        $self->{_canvas_bg_rect}->lower;
1701
2959
                }
1702
2960
        );
1703
2961
 
1720
2978
 
1721
2979
        #properties
1722
2980
        my $prop_item = Gtk2::ImageMenuItem->new_from_stock('gtk-properties');
1723
 
        $prop_item->set_sensitive(FALSE) if $item->isa('Goo::Canvas::Image');
 
2981
        
 
2982
        #some items do not have properties, e.g. images or censor
 
2983
        $prop_item->set_sensitive(FALSE) if $item->isa('Goo::Canvas::Image') || !exists($self->{_items}{$key}{stroke_color});
 
2984
        
1724
2985
        $prop_item->signal_connect(
1725
2986
                'activate' => sub {
1726
2987
 
1727
 
                        #create dialog
1728
 
                        my $prop_dialog = Gtk2::Dialog->new(
1729
 
                                $d->get("Preferences"),
1730
 
                                $self->{_drawing_window},
1731
 
                                [qw/modal destroy-with-parent/],
1732
 
                                'gtk-cancel' => 'cancel',
1733
 
                                'gtk-apply'  => 'apply'
1734
 
                        );
1735
 
 
1736
 
                        $prop_dialog->set_default_response('apply');
1737
 
 
1738
 
                        #RECT OR ELLIPSE
1739
 
                        my $line_spin;
1740
 
                        my $fill_color;
1741
 
                        my $stroke_color;
1742
 
                        if (   $item->isa('Goo::Canvas::Rect')
1743
 
                                || $item->isa('Goo::Canvas::Ellipse')
1744
 
                                || $item->isa('Goo::Canvas::Polyline') )
1745
 
                        {
1746
 
 
1747
 
                                my $general_vbox = Gtk2::VBox->new( FALSE, 5 );
1748
 
 
1749
 
                                my $label_general = Gtk2::Label->new;
1750
 
                                $label_general->set_markup( $d->get("<i>Main</i>") );
1751
 
                                my $frame_general = Gtk2::Frame->new();
1752
 
                                $frame_general->set_label_widget($label_general);
1753
 
                                $frame_general->set_border_width(5);
1754
 
                                $prop_dialog->vbox->add($frame_general);
1755
 
 
1756
 
                                #line_width
1757
 
                                my $line_hbox = Gtk2::HBox->new( TRUE, 5 );
1758
 
                                $line_hbox->set_border_width(5);
1759
 
                                my $linew_label = Gtk2::Label->new( $d->get("Line width") );
1760
 
                                $line_spin = Gtk2::SpinButton->new_with_range( 0.5, 10, 0.1 );
1761
 
 
1762
 
                                $line_spin->set_value( $item->get('line-width') );
1763
 
 
1764
 
                                $line_hbox->pack_start_defaults($linew_label);
1765
 
                                $line_hbox->pack_start_defaults($line_spin);
1766
 
                                $general_vbox->pack_start( $line_hbox, FALSE, FALSE, 0 );
1767
 
 
1768
 
                                if ( $item->isa('Goo::Canvas::Rect') || $item->isa('Goo::Canvas::Ellipse') ) {
1769
 
 
1770
 
                                        #fill color
1771
 
                                        my $fill_color_hbox = Gtk2::HBox->new( TRUE, 5 );
1772
 
                                        $fill_color_hbox->set_border_width(5);
1773
 
                                        my $fill_color_label = Gtk2::Label->new( $d->get("Fill color") );
1774
 
                                        $fill_color = Gtk2::ColorButton->new();
1775
 
 
1776
 
                                        $fill_color->set_color( $self->{_items}{$key}{fill_color} );
1777
 
                                        $fill_color->set_alpha( int( $self->{_items}{$key}{fill_color_alpha} * 65535 ) );
1778
 
                                        $fill_color->set_use_alpha(TRUE);
1779
 
                                        $fill_color->set_title( $d->get("Choose fill color") );
1780
 
 
1781
 
                                        $fill_color_hbox->pack_start_defaults($fill_color_label);
1782
 
                                        $fill_color_hbox->pack_start_defaults($fill_color);
1783
 
                                        $general_vbox->pack_start( $fill_color_hbox, FALSE, FALSE, 0 );
1784
 
                                }
1785
 
 
1786
 
                                #stroke color
1787
 
                                my $stroke_color_hbox = Gtk2::HBox->new( TRUE, 5 );
1788
 
                                $stroke_color_hbox->set_border_width(5);
1789
 
                                my $stroke_color_label = Gtk2::Label->new( $d->get("Stroke color") );
1790
 
                                $stroke_color = Gtk2::ColorButton->new();
1791
 
 
1792
 
                                $stroke_color->set_color( $self->{_items}{$key}{stroke_color} );
1793
 
                                $stroke_color->set_alpha( int( $self->{_items}{$key}{stroke_color_alpha} * 65535 ) );
1794
 
                                $stroke_color->set_use_alpha(TRUE);
1795
 
                                $stroke_color->set_title( $d->get("Choose stroke color") );
1796
 
 
1797
 
                                $stroke_color_hbox->pack_start_defaults($stroke_color_label);
1798
 
                                $stroke_color_hbox->pack_start_defaults($stroke_color);
1799
 
                                $general_vbox->pack_start( $stroke_color_hbox, FALSE, FALSE, 0 );
1800
 
 
1801
 
                                $frame_general->add($general_vbox);
1802
 
 
1803
 
                        }
1804
 
 
1805
 
                        #TEXT
1806
 
                        my $font_btn;
1807
 
                        my $text;
1808
 
                        my $textview;
1809
 
                        my $font_color;
1810
 
                        if ( $item->isa('Goo::Canvas::Text') ) {
1811
 
 
1812
 
                                my $text_vbox = Gtk2::VBox->new( FALSE, 5 );
1813
 
 
1814
 
                                my $label_text = Gtk2::Label->new;
1815
 
                                $label_text->set_markup( $d->get("<i>Text</i>") );
1816
 
                                my $frame_text = Gtk2::Frame->new();
1817
 
                                $frame_text->set_label_widget($label_text);
1818
 
                                $frame_text->set_border_width(5);
1819
 
                                $prop_dialog->vbox->add($frame_text);
1820
 
 
1821
 
                                #font button
1822
 
                                my $font_hbox = Gtk2::HBox->new( TRUE, 5 );
1823
 
                                $font_hbox->set_border_width(5);
1824
 
                                my $font_label = Gtk2::Label->new( $d->get("Font") );
1825
 
                                $font_btn = Gtk2::FontButton->new();
1826
 
 
1827
 
                                #determine font description from string
1828
 
                                my ( $attr_list, $text_raw, $accel_char ) = Gtk2::Pango->parse_markup( $item->get('text') );
1829
 
                                my $font_desc = Gtk2::Pango::FontDescription->from_string( $self->{_font} );
1830
 
 
1831
 
                                #FIXME, maybe the pango version installed is too old
1832
 
                                eval {
1833
 
                                        $attr_list->filter(
1834
 
                                                sub {
1835
 
                                                        my $attr = shift;
1836
 
                                                        $font_desc = $attr->copy->desc
1837
 
                                                                if $attr->isa('Gtk2::Pango::AttrFontDesc');
1838
 
                                                        return TRUE;
1839
 
                                                },
1840
 
                                        );
1841
 
                                };
1842
 
                                if ($@) {
1843
 
                                        print "\nERROR: Pango Markup could not be parsed:\n$@";
1844
 
                                }
1845
 
 
1846
 
                                $font_hbox->pack_start_defaults($font_label);
1847
 
                                $font_hbox->pack_start_defaults($font_btn);
1848
 
                                $text_vbox->pack_start( $font_hbox, FALSE, FALSE, 0 );
1849
 
 
1850
 
                                #font color
1851
 
                                my $font_color_hbox = Gtk2::HBox->new( TRUE, 5 );
1852
 
                                $font_color_hbox->set_border_width(5);
1853
 
                                my $font_color_label = Gtk2::Label->new( $d->get("Font color") );
1854
 
                                $font_color = Gtk2::ColorButton->new();
1855
 
                                $font_color->set_use_alpha(TRUE);
1856
 
 
1857
 
                                $font_color->set_alpha( int( $self->{_items}{$key}{stroke_color_alpha} * 65535 ) );
1858
 
                                $font_color->set_color( $self->{_items}{$key}{stroke_color} );
1859
 
                                $font_color->set_title( $d->get("Choose font color") );
1860
 
 
1861
 
                                $font_color_hbox->pack_start_defaults($font_color_label);
1862
 
                                $font_color_hbox->pack_start_defaults($font_color);
1863
 
 
1864
 
                                $text_vbox->pack_start( $font_color_hbox, FALSE, FALSE, 0 );
1865
 
 
1866
 
                                #initial buffer
1867
 
                                my $text = Gtk2::TextBuffer->new;
1868
 
                                $text->set_text($text_raw);
1869
 
 
1870
 
                                #textview
1871
 
                                my $textview_hbox = Gtk2::HBox->new( FALSE, 5 );
1872
 
                                $textview_hbox->set_border_width(5);
1873
 
                                $textview = Gtk2::TextView->new_with_buffer($text);
1874
 
                                $textview->set_size_request( 150, 200 );
1875
 
                                $textview_hbox->pack_start_defaults($textview);
1876
 
 
1877
 
                                $text_vbox->pack_start_defaults($textview_hbox);
1878
 
 
1879
 
                                #apply changes directly
1880
 
                                $font_btn->signal_connect(
1881
 
                                        'font-set' => sub {
1882
 
 
1883
 
                                                $self->modify_text_in_properties( $font_btn, $textview, $font_color, $item );
1884
 
 
1885
 
                                        }
1886
 
                                );
1887
 
 
1888
 
                                $font_color->signal_connect(
1889
 
                                        'color-set' => sub {
1890
 
 
1891
 
                                                $self->modify_text_in_properties( $font_btn, $textview, $font_color, $item );
1892
 
 
1893
 
                                        }
1894
 
                                );
1895
 
 
1896
 
                                #apply current font settings to button
1897
 
                                $font_btn->set_font_name( $font_desc->to_string );
1898
 
 
1899
 
                                #FIXME >> why do we have to invoke this manually??
1900
 
                                $font_btn->signal_emit('font-set');
1901
 
 
1902
 
                                $frame_text->add($text_vbox);
1903
 
                        }
1904
 
 
1905
 
                        #run dialog
1906
 
                        $prop_dialog->show_all;
1907
 
                        my $prop_dialog_res = $prop_dialog->run;
1908
 
                        if ( $prop_dialog_res eq 'apply' ) {
1909
 
 
1910
 
                                #add to undo stack
1911
 
                                $self->store_to_xdo_stack($self->{_current_item} , 'modify', 'undo');
1912
 
 
1913
 
                                #apply rect or ellipse options
1914
 
                                if ( $item->isa('Goo::Canvas::Rect') || $item->isa('Goo::Canvas::Ellipse') ) {
1915
 
 
1916
 
                                        my $fill_pattern   = $self->create_color( $fill_color->get_color,   $fill_color->get_alpha / 65535 );
1917
 
                                        my $stroke_pattern = $self->create_color( $stroke_color->get_color, $stroke_color->get_alpha / 65535 );
1918
 
                                        $item->set(
1919
 
                                                'line-width'     => $line_spin->get_value,
1920
 
                                                'fill-pattern'   => $fill_pattern,
1921
 
                                                'stroke-pattern' => $stroke_pattern
1922
 
                                        );
1923
 
 
1924
 
                                        #save color and opacity as well
1925
 
                                        $self->{_items}{$key}{fill_color}         = $fill_color->get_color;
1926
 
                                        $self->{_items}{$key}{fill_color_alpha}   = $fill_color->get_alpha / 65535;
1927
 
                                        $self->{_items}{$key}{stroke_color}       = $stroke_color->get_color;
1928
 
                                        $self->{_items}{$key}{stroke_color_alpha} = $stroke_color->get_alpha / 65535;
1929
 
                                }
1930
 
 
1931
 
                                #apply polyline options
1932
 
                                if ( $item->isa('Goo::Canvas::Polyline') ) {
1933
 
                                        my $stroke_pattern = $self->create_color( $stroke_color->get_color, $stroke_color->get_alpha / 65535 );
1934
 
                                        $item->set(
1935
 
                                                'line-width'     => $line_spin->get_value,
1936
 
                                                'stroke-pattern' => $stroke_pattern
1937
 
                                        );
1938
 
 
1939
 
                                        #save color and opacity as well
1940
 
                                        $self->{_items}{$key}{stroke_color}       = $stroke_color->get_color;
1941
 
                                        $self->{_items}{$key}{stroke_color_alpha} = $stroke_color->get_alpha / 65535;
1942
 
                                }
1943
 
 
1944
 
                                #apply text options
1945
 
                                if ( $item->isa('Goo::Canvas::Text') ) {
1946
 
                                        my $font_descr = Gtk2::Pango::FontDescription->from_string( $font_btn->get_font_name );
1947
 
 
1948
 
                                        my $new_text
1949
 
                                                = $textview->get_buffer->get_text( $textview->get_buffer->get_start_iter, $textview->get_buffer->get_end_iter, FALSE )
1950
 
                                                || "New Text...";
1951
 
 
1952
 
                                        my $fill_pattern = $self->create_color( $font_color->get_color, $font_color->get_alpha / 65535 );
1953
 
 
1954
 
                                        $item->set(
1955
 
                                                'text'         => "<span font_desc=' " . $font_descr->to_string . " ' >" . $new_text . "</span>",
1956
 
                                                'use-markup'   => TRUE,
1957
 
                                                'fill-pattern' => $fill_pattern
1958
 
                                        );
1959
 
 
1960
 
                                        #adjust rectangle to display text properly
1961
 
                                        my $no_lines  = $textview->get_buffer->get_line_count;
1962
 
                                        my $font_size = $font_descr->get_size / 1024;
1963
 
 
1964
 
                                        if ( ( $no_lines * $font_size ) + $parent->get('height') > ( $self->{_drawing_pixbuf}->get_height - 50 ) ) {
1965
 
                                                $parent->set( 'height' => ( $self->{_drawing_pixbuf}->get_height - $parent->get('height') ) );
1966
 
                                        } else {
1967
 
                                                $parent->set( 'height' => $no_lines * $font_size + $no_lines * 20 );
1968
 
                                        }
1969
 
 
1970
 
                                        $self->handle_rects( 'update', $parent );
1971
 
                                        $self->handle_embedded( 'update', $parent );
1972
 
 
1973
 
                                        #save color and opacity as well
1974
 
                                        $self->{_items}{$key}{stroke_color}       = $font_color->get_color;
1975
 
                                        $self->{_items}{$key}{stroke_color_alpha} = $font_color->get_alpha / 65535;
1976
 
 
1977
 
                                }
1978
 
                                $prop_dialog->destroy;
1979
 
                                return TRUE;
1980
 
                        } else {
1981
 
 
1982
 
                                $prop_dialog->destroy;
1983
 
                                return FALSE;
1984
 
                        }
 
2988
                        $self->show_item_properties($item, $parent, $key);
1985
2989
 
1986
2990
                }
1987
2991
        );
1993
2997
        return $menu_item;
1994
2998
}
1995
2999
 
 
3000
sub get_item_key {
 
3001
        my ($self, $item, $parent) = @_;
 
3002
        if ( exists $self->{_items}{$item} ) {
 
3003
                return $item;
 
3004
        }else{
 
3005
                return $parent;
 
3006
        }
 
3007
}
 
3008
 
 
3009
sub show_item_properties {
 
3010
        my ($self, $item, $parent, $key) = @_;
 
3011
 
 
3012
        #~ print "show_item_properties\n";
 
3013
 
 
3014
        #create dialog
 
3015
        my $prop_dialog = Gtk2::Dialog->new(
 
3016
                $self->{_d}->get("Preferences"),
 
3017
                $self->{_drawing_window},
 
3018
                [qw/modal destroy-with-parent/],
 
3019
                'gtk-cancel' => 'cancel',
 
3020
                'gtk-apply'  => 'apply'
 
3021
        );
 
3022
 
 
3023
        $prop_dialog->set_default_response('apply');
 
3024
 
 
3025
        #RECT OR ELLIPSE OR POLYLINE
 
3026
        my $line_spin           = undef;
 
3027
        my $fill_color          = undef;
 
3028
        my $stroke_color        = undef;
 
3029
 
 
3030
        #NUMBERED ELLIPSE
 
3031
        my $number_spin         = undef;
 
3032
 
 
3033
        #ARROW
 
3034
        my $end_arrow           = undef;
 
3035
        my $start_arrow         = undef;        
 
3036
        my $arrow_spin          = undef;
 
3037
        my $arrowl_spin         = undef;
 
3038
        my $arrowt_spin         = undef;
 
3039
 
 
3040
        #TEXT
 
3041
        my $font_btn;
 
3042
        my $text;
 
3043
        my $textview;
 
3044
        my $font_color;
 
3045
 
 
3046
        #RECT OR ELLIPSE OR POLYLINE
 
3047
        #GENERAL SETTINGS       
 
3048
        if (   $item->isa('Goo::Canvas::Rect')
 
3049
                || $item->isa('Goo::Canvas::Ellipse')
 
3050
                || $item->isa('Goo::Canvas::Polyline') )
 
3051
        {
 
3052
 
 
3053
                my $general_vbox = Gtk2::VBox->new( FALSE, 5 );
 
3054
 
 
3055
                my $label_general = Gtk2::Label->new;
 
3056
                $label_general->set_markup( $self->{_d}->get("<i>Main</i>") );
 
3057
                my $frame_general = Gtk2::Frame->new();
 
3058
                $frame_general->set_label_widget($label_general);
 
3059
                $frame_general->set_border_width(5);
 
3060
                $prop_dialog->vbox->add($frame_general);
 
3061
 
 
3062
                #line_width
 
3063
                my $line_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3064
                $line_hbox->set_border_width(5);
 
3065
                my $linew_label = Gtk2::Label->new( $self->{_d}->get("Line width") );
 
3066
                $line_spin = Gtk2::SpinButton->new_with_range( 0.5, 20, 0.1 );
 
3067
 
 
3068
                $line_spin->set_value( $item->get('line-width') );
 
3069
 
 
3070
                $line_hbox->pack_start_defaults($linew_label);
 
3071
                $line_hbox->pack_start_defaults($line_spin);
 
3072
                $general_vbox->pack_start( $line_hbox, FALSE, FALSE, 0 );
 
3073
 
 
3074
                if ( $item->isa('Goo::Canvas::Rect') || $item->isa('Goo::Canvas::Ellipse') ) {
 
3075
 
 
3076
                        #fill color
 
3077
                        my $fill_color_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3078
                        $fill_color_hbox->set_border_width(5);
 
3079
                        my $fill_color_label = Gtk2::Label->new( $self->{_d}->get("Fill color") );
 
3080
                        $fill_color = Gtk2::ColorButton->new();
 
3081
 
 
3082
                        $fill_color->set_color( $self->{_items}{$key}{fill_color} );
 
3083
                        $fill_color->set_alpha( int( $self->{_items}{$key}{fill_color_alpha} * 65535 ) );
 
3084
                        $fill_color->set_use_alpha(TRUE);
 
3085
                        $fill_color->set_title( $self->{_d}->get("Choose fill color") );
 
3086
 
 
3087
                        $fill_color_hbox->pack_start_defaults($fill_color_label);
 
3088
                        $fill_color_hbox->pack_start_defaults($fill_color);
 
3089
                        $general_vbox->pack_start( $fill_color_hbox, FALSE, FALSE, 0 );
 
3090
                        
 
3091
                }
 
3092
 
 
3093
                #some items, e.g. censor tool, do not have a color - skip them
 
3094
                if($self->{_items}{$key}{stroke_color}){
 
3095
                        #stroke color
 
3096
                        my $stroke_color_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3097
                        $stroke_color_hbox->set_border_width(5);
 
3098
                        my $stroke_color_label = Gtk2::Label->new( $self->{_d}->get("Stroke color") );
 
3099
                        $stroke_color = Gtk2::ColorButton->new();
 
3100
 
 
3101
                        $stroke_color->set_color( $self->{_items}{$key}{stroke_color} );
 
3102
                        $stroke_color->set_alpha( int( $self->{_items}{$key}{stroke_color_alpha} * 65535 ) );
 
3103
                        $stroke_color->set_use_alpha(TRUE);
 
3104
                        $stroke_color->set_title( $self->{_d}->get("Choose stroke color") );
 
3105
 
 
3106
                        $stroke_color_hbox->pack_start_defaults($stroke_color_label);
 
3107
                        $stroke_color_hbox->pack_start_defaults($stroke_color);
 
3108
                        $general_vbox->pack_start( $stroke_color_hbox, FALSE, FALSE, 0 );
 
3109
                }
 
3110
 
 
3111
                $frame_general->add($general_vbox);
 
3112
 
 
3113
                #special shapes like numbered ellipse
 
3114
                if(defined $self->{_items}{$key}{text}){
 
3115
                        
 
3116
                        my $numbered_vbox = Gtk2::VBox->new( FALSE, 5 );
 
3117
                        
 
3118
                        my $label_numbered = Gtk2::Label->new;
 
3119
                        $label_numbered->set_markup( $self->{_d}->get("<i>Numbering</i>") );
 
3120
                        my $frame_numbered = Gtk2::Frame->new();
 
3121
                        $frame_numbered->set_label_widget($label_numbered);
 
3122
                        $frame_numbered->set_border_width(5);
 
3123
                        $prop_dialog->vbox->add($frame_numbered);
 
3124
 
 
3125
                        #current digit
 
3126
                        my $number_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3127
                        $number_hbox->set_border_width(5);
 
3128
                        my $numberw_label = Gtk2::Label->new( $self->{_d}->get("Current value") );
 
3129
                        $number_spin = Gtk2::SpinButton->new_with_range( 0, 999, 1 );
 
3130
 
 
3131
                        $number_spin->set_value( $self->{_items}{$key}{text}{digit} );
 
3132
 
 
3133
                        $number_hbox->pack_start_defaults($numberw_label);
 
3134
                        $number_hbox->pack_start_defaults($number_spin);
 
3135
                        $numbered_vbox->pack_start( $number_hbox, FALSE, FALSE, 0 );
 
3136
 
 
3137
                        #font button
 
3138
                        my $font_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3139
                        $font_hbox->set_border_width(5);
 
3140
                        my $font_label = Gtk2::Label->new( $self->{_d}->get("Font") );
 
3141
                        $font_btn = Gtk2::FontButton->new();
 
3142
 
 
3143
                        #determine font description from string
 
3144
                        my ( $attr_list, $text_raw, $accel_char ) = Gtk2::Pango->parse_markup( $self->{_items}{$key}{text}->get('text') );
 
3145
                        my $font_desc = Gtk2::Pango::FontDescription->from_string( $self->{_font} );
 
3146
 
 
3147
                        #FIXME, maybe the pango version installed is too old
 
3148
                        eval {
 
3149
                                $attr_list->filter(
 
3150
                                        sub {
 
3151
                                                my $attr = shift;
 
3152
                                                $font_desc = $attr->copy->desc
 
3153
                                                        if $attr->isa('Gtk2::Pango::AttrFontDesc');
 
3154
                                                return TRUE;
 
3155
                                        },
 
3156
                                );
 
3157
                        };
 
3158
                        if ($@) {
 
3159
                                print "\nERROR: Pango Markup could not be parsed:\n$@";
 
3160
                        }
 
3161
 
 
3162
                        #apply current font settings to button
 
3163
                        $font_btn->set_font_name( $font_desc->to_string );
 
3164
 
 
3165
                        $font_hbox->pack_start_defaults($font_label);
 
3166
                        $font_hbox->pack_start_defaults($font_btn);
 
3167
                        $numbered_vbox->pack_start( $font_hbox, FALSE, FALSE, 0 );
 
3168
                        
 
3169
                        $frame_numbered->add($numbered_vbox);
 
3170
                                                
 
3171
                }
 
3172
 
 
3173
        }
 
3174
 
 
3175
        #ARROW item
 
3176
        if ($item->isa('Goo::Canvas::Polyline') 
 
3177
                && defined $self->{_items}{$key}{end_arrow} 
 
3178
                && defined $self->{_items}{$key}{start_arrow})
 
3179
        {
 
3180
                my $arrow_vbox = Gtk2::VBox->new( FALSE, 5 );
 
3181
 
 
3182
                my $label_arrow = Gtk2::Label->new;
 
3183
                $label_arrow->set_markup( $self->{_d}->get("<i>Arrow</i>") );
 
3184
                my $frame_arrow = Gtk2::Frame->new();
 
3185
                $frame_arrow->set_label_widget($label_arrow);
 
3186
                $frame_arrow->set_border_width(5);
 
3187
                $prop_dialog->vbox->add($frame_arrow);
 
3188
 
 
3189
                #arrow_width
 
3190
                my $arrow_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3191
                $arrow_hbox->set_border_width(5);
 
3192
                my $arroww_label = Gtk2::Label->new( $self->{_d}->get("Width") );
 
3193
                $arrow_spin = Gtk2::SpinButton->new_with_range( 0.5, 10, 0.1 );
 
3194
 
 
3195
                $arrow_spin->set_value( $item->get('arrow-width') );
 
3196
 
 
3197
                $arrow_hbox->pack_start_defaults($arroww_label);
 
3198
                $arrow_hbox->pack_start_defaults($arrow_spin);
 
3199
                $arrow_vbox->pack_start( $arrow_hbox, FALSE, FALSE, 0 );
 
3200
 
 
3201
                #arrow_length
 
3202
                my $arrowl_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3203
                $arrowl_hbox->set_border_width(5);
 
3204
                my $arrowl_label = Gtk2::Label->new( $self->{_d}->get("Length") );
 
3205
                $arrowl_spin = Gtk2::SpinButton->new_with_range( 0.5, 10, 0.1 );
 
3206
 
 
3207
                $arrowl_spin->set_value( $item->get('arrow-length') );
 
3208
 
 
3209
                $arrowl_hbox->pack_start_defaults($arrowl_label);
 
3210
                $arrowl_hbox->pack_start_defaults($arrowl_spin);
 
3211
                $arrow_vbox->pack_start( $arrowl_hbox, FALSE, FALSE, 0 );
 
3212
 
 
3213
                #arrow_tip_length
 
3214
                my $arrowt_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3215
                $arrowt_hbox->set_border_width(5);
 
3216
                my $arrowt_label = Gtk2::Label->new( $self->{_d}->get("Tip length") );
 
3217
                $arrowt_spin = Gtk2::SpinButton->new_with_range( 0.5, 10, 0.1 );
 
3218
 
 
3219
                $arrowt_spin->set_value( $item->get('arrow-tip-length') );
 
3220
 
 
3221
                $arrowt_hbox->pack_start_defaults($arrowt_label);
 
3222
                $arrowt_hbox->pack_start_defaults($arrowt_spin);
 
3223
                $arrow_vbox->pack_start( $arrowt_hbox, FALSE, FALSE, 0 );
 
3224
        
 
3225
                #checkboxes for start and end arrows
 
3226
                $end_arrow   = Gtk2::CheckButton->new ($self->{_d}->get("Display an arrow at the end of the line"));
 
3227
                $end_arrow->set_active($self->{_items}{$key}{end_arrow});
 
3228
                $start_arrow = Gtk2::CheckButton->new ($self->{_d}->get("Display an arrow at the start of the line"));
 
3229
                $start_arrow->set_active($self->{_items}{$key}{start_arrow});
 
3230
 
 
3231
                my $end_arrow_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3232
                $end_arrow_hbox->set_border_width(5);
 
3233
                
 
3234
                my $start_arrow_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3235
                $start_arrow_hbox->set_border_width(5);
 
3236
                
 
3237
                $end_arrow_hbox->pack_start_defaults($end_arrow);
 
3238
                $start_arrow_hbox->pack_start_defaults($start_arrow);
 
3239
 
 
3240
                $arrow_vbox->pack_start( $start_arrow_hbox, FALSE, FALSE, 0 );
 
3241
                $arrow_vbox->pack_start( $end_arrow_hbox, FALSE, FALSE, 0 );
 
3242
                
 
3243
                #final packing
 
3244
                $frame_arrow->add($arrow_vbox);
 
3245
 
 
3246
        #simple TEXT item (no numbered ellipse)
 
3247
        }elsif ( $item->isa('Goo::Canvas::Text')
 
3248
                && !defined $self->{_items}{$key}{ellipse} ) {
 
3249
 
 
3250
                my $text_vbox = Gtk2::VBox->new( FALSE, 5 );
 
3251
 
 
3252
                my $label_text = Gtk2::Label->new;
 
3253
                $label_text->set_markup( $self->{_d}->get("<i>Text</i>") );
 
3254
                my $frame_text = Gtk2::Frame->new();
 
3255
                $frame_text->set_label_widget($label_text);
 
3256
                $frame_text->set_border_width(5);
 
3257
                $prop_dialog->vbox->add($frame_text);
 
3258
 
 
3259
                #font button
 
3260
                my $font_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3261
                $font_hbox->set_border_width(5);
 
3262
                my $font_label = Gtk2::Label->new( $self->{_d}->get("Font") );
 
3263
                $font_btn = Gtk2::FontButton->new();
 
3264
 
 
3265
                #determine font description from string
 
3266
                my ( $attr_list, $text_raw, $accel_char ) = Gtk2::Pango->parse_markup( $item->get('text') );
 
3267
                my $font_desc = Gtk2::Pango::FontDescription->from_string( $self->{_font} );
 
3268
 
 
3269
                #FIXME, maybe the pango version installed is too old
 
3270
                eval {
 
3271
                        $attr_list->filter(
 
3272
                                sub {
 
3273
                                        my $attr = shift;
 
3274
                                        $font_desc = $attr->copy->desc
 
3275
                                                if $attr->isa('Gtk2::Pango::AttrFontDesc');
 
3276
                                        return TRUE;
 
3277
                                },
 
3278
                        );
 
3279
                };
 
3280
                if ($@) {
 
3281
                        print "\nERROR: Pango Markup could not be parsed:\n$@";
 
3282
                }
 
3283
 
 
3284
                $font_hbox->pack_start_defaults($font_label);
 
3285
                $font_hbox->pack_start_defaults($font_btn);
 
3286
                $text_vbox->pack_start( $font_hbox, FALSE, FALSE, 0 );
 
3287
 
 
3288
                #font color
 
3289
                my $font_color_hbox = Gtk2::HBox->new( TRUE, 5 );
 
3290
                $font_color_hbox->set_border_width(5);
 
3291
                my $font_color_label = Gtk2::Label->new( $self->{_d}->get("Font color") );
 
3292
                $font_color = Gtk2::ColorButton->new();
 
3293
                $font_color->set_use_alpha(TRUE);
 
3294
 
 
3295
                $font_color->set_alpha( int( $self->{_items}{$key}{stroke_color_alpha} * 65535 ) );
 
3296
                $font_color->set_color( $self->{_items}{$key}{stroke_color} );
 
3297
                $font_color->set_title( $self->{_d}->get("Choose font color") );
 
3298
 
 
3299
                $font_color_hbox->pack_start_defaults($font_color_label);
 
3300
                $font_color_hbox->pack_start_defaults($font_color);
 
3301
 
 
3302
                $text_vbox->pack_start( $font_color_hbox, FALSE, FALSE, 0 );
 
3303
 
 
3304
                #initial buffer
 
3305
                my $text = Gtk2::TextBuffer->new;
 
3306
                $text->set_text($text_raw);
 
3307
 
 
3308
                #textview
 
3309
                my $textview_hbox = Gtk2::HBox->new( FALSE, 5 );
 
3310
                $textview_hbox->set_border_width(5);
 
3311
                $textview = Gtk2::TextView->new_with_buffer($text);
 
3312
                $textview->set_size_request( 150, 200 );
 
3313
                $textview_hbox->pack_start_defaults($textview);
 
3314
 
 
3315
                $text_vbox->pack_start_defaults($textview_hbox);
 
3316
 
 
3317
                #apply changes directly
 
3318
                $font_btn->signal_connect(
 
3319
                        'font-set' => sub {
 
3320
 
 
3321
                                $self->modify_text_in_properties( $font_btn, $textview, $font_color, $item );
 
3322
 
 
3323
                        }
 
3324
                );
 
3325
 
 
3326
                $font_color->signal_connect(
 
3327
                        'color-set' => sub {
 
3328
 
 
3329
                                $self->modify_text_in_properties( $font_btn, $textview, $font_color, $item );
 
3330
 
 
3331
                        }
 
3332
                );
 
3333
 
 
3334
                #apply current font settings to button
 
3335
                $font_btn->set_font_name( $font_desc->to_string );
 
3336
 
 
3337
                #FIXME >> why do we have to invoke this manually??
 
3338
                $font_btn->signal_emit('font-set');
 
3339
 
 
3340
                $frame_text->add($text_vbox);
 
3341
 
 
3342
        }
 
3343
 
 
3344
        #run dialog
 
3345
        $prop_dialog->show_all;
 
3346
        my $prop_dialog_res = $prop_dialog->run;
 
3347
        if ( $prop_dialog_res eq 'apply' ) {
 
3348
 
 
3349
                $self->apply_properties($item, $parent, $key, 
 
3350
                                                                $fill_color, $stroke_color, $line_spin, 
 
3351
                                                                $font_color, $font_btn, $textview, 
 
3352
                                                                $end_arrow , $start_arrow, $arrow_spin, $arrowl_spin, $arrowt_spin,
 
3353
                                                                $number_spin);
 
3354
 
 
3355
                #apply item properties to widgets
 
3356
                #line width, fill color, stroke color etc.
 
3357
                $self->set_and_save_drawing_properties($self->{_current_item}, FALSE);
 
3358
 
 
3359
                #FIXME - we need to save the changed values in this case
 
3360
                $self->set_and_save_drawing_properties($self->{_current_item}, TRUE);
 
3361
 
 
3362
                $prop_dialog->destroy;
 
3363
                return TRUE;
 
3364
        } else {
 
3365
 
 
3366
                $prop_dialog->destroy;
 
3367
                return FALSE;
 
3368
        }
 
3369
        
 
3370
}
 
3371
 
 
3372
sub apply_properties {
 
3373
        my (
 
3374
        $self,
 
3375
        
 
3376
        #item related infos
 
3377
        $item,
 
3378
        $parent,
 
3379
        $key,
 
3380
        
 
3381
        #general properties
 
3382
        $fill_color,
 
3383
        $stroke_color,
 
3384
        $line_spin,
 
3385
        
 
3386
        #only text
 
3387
        $font_color,
 
3388
        $font_btn,
 
3389
        $textview,
 
3390
        
 
3391
        #only arrow
 
3392
        $end_arrow,
 
3393
        $start_arrow,   
 
3394
        $arrow_spin,
 
3395
        $arrowl_spin,
 
3396
        $arrowt_spin,
 
3397
        
 
3398
        #only numbered shapes
 
3399
        $number_spin
 
3400
        
 
3401
        ) = @_;
 
3402
 
 
3403
        #~ print "apply_properties\n";
 
3404
 
 
3405
        #remember drawing colors, line width and font settings
 
3406
        #maybe we have to restore them
 
3407
        if($self->{_items}{$key}{type} ne "highlighter" && 
 
3408
           $self->{_items}{$key}{type} ne "censor")
 
3409
        {
 
3410
                                
 
3411
                $self->{_last_fill_color}         = $self->{_fill_color_w}->get_color;
 
3412
                $self->{_last_fill_color_alpha}   = $self->{_fill_color_w}->get_alpha / 65535;
 
3413
                $self->{_last_stroke_color}       = $self->{_stroke_color_w}->get_color;
 
3414
                $self->{_last_stroke_color_alpha} = $self->{_stroke_color_w}->get_alpha / 65535;
 
3415
                $self->{_last_line_width}                 = $self->{_line_spin_w}->get_value;
 
3416
                $self->{_last_font}                       = $self->{_font_btn_w}->get_font_name;
 
3417
 
 
3418
                #remember the last mode as well
 
3419
                $self->{_last_mode}               = $self->{_current_mode};
 
3420
                $self->{_last_mode_descr}         = $self->{_current_mode_descr};
 
3421
 
 
3422
        }
 
3423
        
 
3424
        #add to undo stack
 
3425
        $self->store_to_xdo_stack($self->{_current_item} , 'modify', 'undo');
 
3426
 
 
3427
        #apply rect or ellipse options
 
3428
        if ( $item->isa('Goo::Canvas::Rect') || $item->isa('Goo::Canvas::Ellipse') ) {
 
3429
 
 
3430
                my $fill_pattern   = $self->create_color( $fill_color->get_color,   $fill_color->get_alpha / 65535 );
 
3431
                my $stroke_pattern = $self->create_color( $stroke_color->get_color, $stroke_color->get_alpha / 65535 );
 
3432
                $item->set(
 
3433
                        'line-width'     => $line_spin->get_value,
 
3434
                        'fill-pattern'   => $fill_pattern,
 
3435
                        'stroke-pattern' => $stroke_pattern
 
3436
                );
 
3437
 
 
3438
                #special shapes like numbered ellipse (digit changed)
 
3439
                if(defined $self->{_items}{$key}{text}){
 
3440
 
 
3441
                        #determine new or current digit
 
3442
                        my $digit = undef;
 
3443
                        if(defined $number_spin){
 
3444
                                $digit = $number_spin->get_value;
 
3445
                        }else{
 
3446
                                $digit = $self->{_items}{$key}{text}{digit};    
 
3447
                        }       
 
3448
                        
 
3449
                        my $fill_pattern = undef;
 
3450
                        if(defined $font_color){
 
3451
                                $fill_pattern = $self->create_color( $font_color->get_color, $font_color->get_alpha / 65535 );
 
3452
                        }elsif(defined $stroke_color){
 
3453
                                $fill_pattern = $self->create_color( $stroke_color->get_color, $stroke_color->get_alpha / 65535 );                              
 
3454
                        }
 
3455
                        
 
3456
                        my $font_descr = Gtk2::Pango::FontDescription->from_string( $font_btn->get_font_name ); 
 
3457
                        $self->{_items}{$key}{text}->set(
 
3458
                                'text' => "<span font_desc=' " . $font_descr->to_string . " ' >" . $digit . "</span>",
 
3459
                                'fill-pattern' => $fill_pattern,
 
3460
                        );      
 
3461
 
 
3462
                        #adjust parent rectangle
 
3463
                        my $tb = $self->{_items}{$key}{text}->get_bounds;
 
3464
        
 
3465
                        #keep ratio = 1
 
3466
                        my $qs = abs($tb->x1 - $tb->x2);
 
3467
                        $qs = abs($tb->y1 - $tb->y2) if abs($tb->y1 - $tb->y2) > abs($tb->x1 - $tb->x2); 
 
3468
                        
 
3469
                        #add line width of parent ellipse
 
3470
                        $qs += $self->{_items}{$key}{ellipse}->get('line-width')+5;
 
3471
                        
 
3472
                        $parent->set(           
 
3473
                                'width'         => $qs,
 
3474
                                'height'        => $qs,
 
3475
                        );      
 
3476
                        
 
3477
                        #save digit in hash as well (only item properties dialog)
 
3478
                        if(defined $number_spin){
 
3479
                                $self->{_items}{$key}{text}{digit} = $digit;
 
3480
                        }
 
3481
                
 
3482
                        $self->handle_rects( 'update', $parent );
 
3483
                        $self->handle_embedded( 'update', $parent );
 
3484
                
 
3485
                }       
 
3486
 
 
3487
                #save color and opacity as well
 
3488
                $self->{_items}{$key}{fill_color}         = $fill_color->get_color;
 
3489
                $self->{_items}{$key}{fill_color_alpha}   = $fill_color->get_alpha / 65535;
 
3490
                $self->{_items}{$key}{stroke_color}       = $stroke_color->get_color;
 
3491
                $self->{_items}{$key}{stroke_color_alpha} = $stroke_color->get_alpha / 65535;
 
3492
        }
 
3493
 
 
3494
        #apply polyline options (arrow) 
 
3495
        if ($item->isa('Goo::Canvas::Polyline') 
 
3496
                && defined $self->{_items}{$key}{end_arrow} 
 
3497
                && defined $self->{_items}{$key}{start_arrow})
 
3498
        {
 
3499
 
 
3500
                my $stroke_pattern = $self->create_color( $stroke_color->get_color, $stroke_color->get_alpha / 65535 );
 
3501
 
 
3502
                #these values are only available in the item menu
 
3503
                if(        defined $arrowl_spin 
 
3504
                        && defined $arrow_spin 
 
3505
                        && defined $arrowt_spin 
 
3506
                        && defined $end_arrow 
 
3507
                        && defined $start_arrow)
 
3508
                {
 
3509
                        $item->set(
 
3510
                                'line-width'            => $line_spin->get_value,
 
3511
                                'stroke-pattern'        => $stroke_pattern,
 
3512
                                'end-arrow'             => $end_arrow->get_active,
 
3513
                                'start-arrow'           => $start_arrow->get_active,
 
3514
                                'arrow-length'          => $arrowl_spin->get_value,
 
3515
                                'arrow-width'           => $arrow_spin->get_value,
 
3516
                                'arrow-tip-length'      => $arrowt_spin->get_value,             
 
3517
                        );
 
3518
                                                
 
3519
                }else{
 
3520
                        $item->set(
 
3521
                                'line-width'            => $line_spin->get_value,
 
3522
                                'stroke-pattern'        => $stroke_pattern,     
 
3523
                                'end-arrow'             => $self->{_items}{$key}{line}->get('end-arrow'),
 
3524
                                'start-arrow'           => $self->{_items}{$key}{line}->get('start-arrow'),
 
3525
                        );                      
 
3526
                }
 
3527
 
 
3528
                #save color and opacity as well
 
3529
                $self->{_items}{$key}{stroke_color}       = $stroke_color->get_color;
 
3530
                $self->{_items}{$key}{stroke_color_alpha} = $stroke_color->get_alpha / 65535;           
 
3531
 
 
3532
                #save arrow specific properties
 
3533
                $self->{_items}{$key}{end_arrow}                = $self->{_items}{$key}{line}->get('end-arrow');
 
3534
                $self->{_items}{$key}{start_arrow}              = $self->{_items}{$key}{line}->get('start-arrow');
 
3535
                $self->{_items}{$key}{arrow_width}              = $self->{_items}{$key}{line}->get('arrow-width');
 
3536
                $self->{_items}{$key}{arrow_length}     = $self->{_items}{$key}{line}->get('arrow-length');
 
3537
                $self->{_items}{$key}{arrow_tip_length} = $self->{_items}{$key}{line}->get('arrow-tip-length');
 
3538
 
 
3539
        #apply polyline options (freehand, highlighter) 
 
3540
        }elsif ( $item->isa('Goo::Canvas::Polyline') 
 
3541
                && defined $self->{_items}{$key}{stroke_color}) 
 
3542
        {
 
3543
                my $stroke_pattern = $self->create_color( $stroke_color->get_color, $stroke_color->get_alpha / 65535 );
 
3544
                $item->set(
 
3545
                        'line-width'     => $line_spin->get_value,
 
3546
                        'stroke-pattern' => $stroke_pattern,
 
3547
                );
 
3548
 
 
3549
                #save color and opacity as well
 
3550
                $self->{_items}{$key}{stroke_color}       = $stroke_color->get_color;
 
3551
                $self->{_items}{$key}{stroke_color_alpha} = $stroke_color->get_alpha / 65535;
 
3552
        }
 
3553
 
 
3554
        #apply text options
 
3555
        if ( $item->isa('Goo::Canvas::Text') ) {
 
3556
                my $font_descr = Gtk2::Pango::FontDescription->from_string( $font_btn->get_font_name );
 
3557
 
 
3558
                my $fill_pattern = $self->create_color( $font_color->get_color, $font_color->get_alpha / 65535 );
 
3559
                
 
3560
                my $new_text = undef;
 
3561
                if($textview){
 
3562
                        $new_text
 
3563
                                = $textview->get_buffer->get_text( $textview->get_buffer->get_start_iter, $textview->get_buffer->get_end_iter, FALSE )
 
3564
                                || "New Text...";
 
3565
                }else{
 
3566
                        #determine font description and text from string
 
3567
                        my ( $attr_list, $text_raw, $accel_char ) = Gtk2::Pango->parse_markup( $item->get('text') );
 
3568
                        $new_text = $text_raw;  
 
3569
                }
 
3570
 
 
3571
                $item->set(
 
3572
                        'text'         => "<span font_desc=' " . $font_descr->to_string . " ' >" . $new_text . "</span>",
 
3573
                        'use-markup'   => TRUE,
 
3574
                        'fill-pattern' => $fill_pattern
 
3575
                );
 
3576
 
 
3577
                #adjust parent rectangle
 
3578
                my $tb = $item->get_bounds;
 
3579
                $parent->set(           
 
3580
                        'width'         => abs($tb->x1 - $tb->x2),
 
3581
                        'height'        => abs($tb->y1 - $tb->y2),
 
3582
                );              
 
3583
 
 
3584
                $self->handle_rects( 'update', $parent );
 
3585
                $self->handle_embedded( 'update', $parent );
 
3586
 
 
3587
                #save color and opacity as well
 
3588
                $self->{_items}{$key}{stroke_color}       = $font_color->get_color;
 
3589
                $self->{_items}{$key}{stroke_color_alpha} = $font_color->get_alpha / 65535;
 
3590
 
 
3591
        }
 
3592
                
 
3593
}
 
3594
 
1996
3595
sub modify_text_in_properties {
1997
3596
        my $self       = shift;
1998
3597
        my $font_btn   = shift;
2019
3618
        return TRUE;
2020
3619
}
2021
3620
 
 
3621
sub move_all {
 
3622
        my ($self, $x, $y) = @_;
 
3623
 
 
3624
        foreach ( keys %{ $self->{_items} } ) { 
 
3625
                
 
3626
                my $item = $self->{_items}{$_};
 
3627
 
 
3628
                #embedded item?
 
3629
                my $parent = $self->get_parent_item($item);
 
3630
                $item = $parent if $parent;
 
3631
 
 
3632
                #real shape
 
3633
                if ( exists $self->{_items}{$item} ) {
 
3634
 
 
3635
                        if ( $item->isa('Goo::Canvas::Rect') ) {
 
3636
                                
 
3637
                                $item->set(
 
3638
                                        'x' => $item->get('x')-$x, 
 
3639
                                        'y' => $item->get('y')-$y,
 
3640
                                );  
 
3641
                                
 
3642
                                my $child = $self->get_child_item($item);
 
3643
                                $child = $item unless $child;
 
3644
                                
 
3645
                                #it item is hidden, keep the status
 
3646
                                if($child->get('visibility') eq 'hidden'){
 
3647
                                        $self->handle_rects( 'hide', $item );
 
3648
                                        $self->handle_embedded( 'hide', $item );                                                
 
3649
                                }else{
 
3650
                                        $self->handle_rects( 'update', $item );
 
3651
                                        $self->handle_embedded( 'update', $item );                                      
 
3652
                                }               
 
3653
 
 
3654
                        #freehand line for example
 
3655
                        } else {
 
3656
                                
 
3657
                                $item->translate( -$x, -$y );
 
3658
                        
 
3659
                        }                       
 
3660
                
 
3661
                }
 
3662
        }
 
3663
        
 
3664
        #deactivate all after move
 
3665
        $self->deactivate_all;
 
3666
        
 
3667
        return TRUE;
 
3668
}
 
3669
 
2022
3670
sub deactivate_all {
2023
3671
        my $self    = shift;
2024
 
        my $exclude = shift;
 
3672
        my $exclude = shift || 0;
 
3673
 
 
3674
        #~ print "deactivate_all\n";
2025
3675
 
2026
3676
        foreach ( keys %{ $self->{_items} } ) {
2027
 
 
 
3677
                
2028
3678
                my $item = $self->{_items}{$_};
2029
3679
 
2030
3680
                next if $item == $exclude;
2047
3697
        return TRUE;
2048
3698
}
2049
3699
 
2050
 
sub handle_embedded {
2051
 
        my $self   = shift;
2052
 
        my $action = shift;
2053
 
        my $item   = shift;
 
3700
sub handle_embedded {   
 
3701
        my ($self, $action, $item, $new_width, $new_height) = @_;
2054
3702
 
2055
3703
        return FALSE unless ( $item && exists $self->{_items}{$item} );
2056
3704
 
2072
3720
                                'radius-y' => $item->get('y') + $self->{_items}{$item}->get('height') - $self->{_items}{$item}{ellipse}->get('center-y'),
2073
3721
                                'visibility' => $visibilty,
2074
3722
                        );
 
3723
                        
 
3724
                        #numbered ellipse
 
3725
                        if ( exists $self->{_items}{$item}{text} ) {
 
3726
                                $self->{_items}{$item}{text}->set(
 
3727
                                        'x'     => $self->{_items}{$item}{ellipse}->get('center-x'),
 
3728
                                        'y'     => $self->{_items}{$item}{ellipse}->get('center-y'),
 
3729
                                        'visibility' => $visibilty,
 
3730
                                );                              
 
3731
                        }       
2075
3732
 
2076
3733
                } elsif ( exists $self->{_items}{$item}{text} ) {
2077
3734
                        $self->{_items}{$item}{text}->set(
2081
3738
                                'visibility' => $visibilty,
2082
3739
                        );
2083
3740
                } elsif ( exists $self->{_items}{$item}{line} ) {
2084
 
                        
2085
 
                        if($self->{_items}{$item}{mirrored}){
2086
 
                                $self->{_items}{$item}{line}->set(
2087
 
                                        'points' => Goo::Canvas::Points->new( 
2088
 
                                        [$self->{_items}{$item}->get('x'),
2089
 
                                        $self->{_items}{$item}->get('y')+$self->{_items}{$item}->get('height'),
2090
 
                                        $self->{_items}{$item}->get('x')+$self->{_items}{$item}->get('width'),
2091
 
                                        $self->{_items}{$item}->get('y')]), 
2092
 
                                        'visibility' => $visibilty,
2093
 
                                        
2094
 
                                );                                              
2095
 
                        }else{
2096
 
                                $self->{_items}{$item}{line}->set(
2097
 
                                        'points' => Goo::Canvas::Points->new( 
2098
 
                                        [$self->{_items}{$item}->get('x'),
2099
 
                                        $self->{_items}{$item}->get('y'),
2100
 
                                        $self->{_items}{$item}->get('x')+$self->{_items}{$item}->get('width'),
2101
 
                                        $self->{_items}{$item}->get('y')+$self->{_items}{$item}->get('height')]),
2102
 
                                        'visibility' => $visibilty,
2103
 
                                );                                      
2104
 
                        }
2105
 
 
 
3741
                
 
3742
                                #handle possible arrows properly
 
3743
                                #arrow is always and end-arrow
 
3744
                                if($self->{_items}{$item}{mirrored_w} < 0 && $self->{_items}{$item}{mirrored_h} < 0){           
 
3745
                                        $self->{_items}{$item}{line}->set(
 
3746
                                                'points' => Goo::Canvas::Points->new( 
 
3747
                                                [$self->{_items}{$item}->get('x')+$self->{_items}{$item}->get('width'),
 
3748
                                                $self->{_items}{$item}->get('y')+$self->{_items}{$item}->get('height'),
 
3749
                                                $self->{_items}{$item}->get('x'),
 
3750
                                                $self->{_items}{$item}->get('y')]), 
 
3751
                                                'visibility'  => $visibilty     
 
3752
                                        );
 
3753
                                }elsif($self->{_items}{$item}{mirrored_w} < 0){                 
 
3754
                                        $self->{_items}{$item}{line}->set(
 
3755
                                                'points' => Goo::Canvas::Points->new( 
 
3756
                                                [$self->{_items}{$item}->get('x')+$self->{_items}{$item}->get('width'),
 
3757
                                                $self->{_items}{$item}->get('y'),
 
3758
                                                $self->{_items}{$item}->get('x'),
 
3759
                                                $self->{_items}{$item}->get('y')+$self->{_items}{$item}->get('height')]), 
 
3760
                                                'visibility'  => $visibilty     
 
3761
                                        );
 
3762
                                }elsif($self->{_items}{$item}{mirrored_h} < 0){
 
3763
                                        $self->{_items}{$item}{line}->set(
 
3764
                                                'points' => Goo::Canvas::Points->new( 
 
3765
                                                [$self->{_items}{$item}->get('x'),
 
3766
                                                $self->{_items}{$item}->get('y')+$self->{_items}{$item}->get('height'),
 
3767
                                                $self->{_items}{$item}->get('x')+$self->{_items}{$item}->get('width'),
 
3768
                                                $self->{_items}{$item}->get('y')]), 
 
3769
                                                'visibility'  => $visibilty     
 
3770
                                        );
 
3771
                                }else{
 
3772
                                        $self->{_items}{$item}{line}->set(
 
3773
                                                'points' => Goo::Canvas::Points->new( 
 
3774
                                                [$self->{_items}{$item}->get('x'),
 
3775
                                                $self->{_items}{$item}->get('y'),
 
3776
                                                $self->{_items}{$item}->get('x')+$self->{_items}{$item}->get('width'),
 
3777
                                                $self->{_items}{$item}->get('y')+$self->{_items}{$item}->get('height')]),
 
3778
                                                'visibility' => $visibilty
 
3779
                                        );                                                      
 
3780
                                }       
 
3781
                
2106
3782
                } elsif ( exists $self->{_items}{$item}{image} ) {
2107
3783
 
2108
3784
                        if($self->{_items}{$item}->get('width') == $self->{_items}{$item}{image}->get('width') && $self->{_items}{$item}->get('height') == $self->{_items}{$item}{image}->get('height')){
2110
3786
                                $self->{_items}{$item}{image}->set(
2111
3787
                                        'x'      => int $self->{_items}{$item}->get('x'),
2112
3788
                                        'y'      => int $self->{_items}{$item}->get('y'),
2113
 
                                        'width'  => $self->{_items}{$item}->get('width'),
2114
 
                                        'height' => $self->{_items}{$item}->get('height'),
2115
3789
                                        'visibility' => $visibilty,
2116
3790
                                );                      
2117
3791
 
2134
3808
                                                'y'      => int $self->{_items}{$item}->get('y'),
2135
3809
                                                'width'  => $self->{_items}{$item}->get('width'),
2136
3810
                                                'height' => $self->{_items}{$item}->get('height'),
2137
 
                                                'pixbuf' => undef,
2138
3811
                                                'visibility' => $visibilty,
2139
3812
                                        );                                              
2140
3813
                                }
2167
3840
                }               
2168
3841
 
2169
3842
        }elsif( $action eq 'mirror' ) {
2170
 
                if ( exists $self->{_items}{$item}{line} ) {
2171
 
                        if ($self->{_items}{$item}{mirrored}){
2172
 
                                $self->{_items}{$item}{mirrored} = FALSE;
2173
 
                        }else{
2174
 
                                $self->{_items}{$item}{mirrored} = TRUE;        
 
3843
                if ( exists $self->{_items}{$item}{line} ) {                            
 
3844
                        #width
 
3845
                        if ($new_width < 0 && $self->{_items}{$item}{mirrored_w} >= 0){
 
3846
                                $self->{_items}{$item}{mirrored_w} = $new_width;
 
3847
                        }elsif($new_width < 0 && $self->{_items}{$item}{mirrored_w} < 0){
 
3848
                                $self->{_items}{$item}{mirrored_w} = 0;                         
 
3849
                        }
 
3850
                        
 
3851
                        #height
 
3852
                        if ($new_height < 0 && $self->{_items}{$item}{mirrored_h} >= 0){
 
3853
                                $self->{_items}{$item}{mirrored_h} = $new_height;
 
3854
                        }elsif($new_height < 0 && $self->{_items}{$item}{mirrored_h} < 0){
 
3855
                                $self->{_items}{$item}{mirrored_h} = 0;
2175
3856
                        }
2176
3857
                }
2177
3858
        }
2179
3860
        return TRUE;
2180
3861
}
2181
3862
 
 
3863
sub handle_bg_rects {
 
3864
        my ($self, $action) = @_;
 
3865
 
 
3866
        my $x                   = $self->{_canvas_bg_rect}->get('x');
 
3867
        my $y                   = $self->{_canvas_bg_rect}->get('y');
 
3868
        my $width               = $self->{_canvas_bg_rect}->get('width');
 
3869
        my $height              = $self->{_canvas_bg_rect}->get('height');
 
3870
        
 
3871
        my $middle_h    = $x + $width / 2 ;
 
3872
        my $middle_v    = $y + $height / 2 ;
 
3873
        my $bottom              = $y + $height;
 
3874
        my $top                 = $y;
 
3875
        my $left                = $x;
 
3876
        my $right               = $x + $width;
 
3877
        
 
3878
        if ( $action eq 'create' ) {
 
3879
 
 
3880
                my $pattern = $self->create_color( $self->{_style_bg}, 1 );
 
3881
 
 
3882
                $self->{_canvas_bg_rect}{'bottom-side'} = Goo::Canvas::Rect->new(
 
3883
                        $self->{_canvas}->get_root_item, $middle_h, $bottom, 8, 8,
 
3884
                        'fill-pattern' => $pattern,
 
3885
                        'line-width'   => 1,
 
3886
                        'antialias'    => 'none',
 
3887
                );
 
3888
 
 
3889
                $self->{_canvas_bg_rect}{'bottom-right-corner'} = Goo::Canvas::Rect->new(
 
3890
                        $self->{_canvas}->get_root_item, $right, $bottom, 8, 8,
 
3891
                        'fill-pattern' => $pattern,
 
3892
                        'line-width'   => 1,
 
3893
                        'antialias'    => 'none',
 
3894
                );
 
3895
 
 
3896
                $self->{_canvas_bg_rect}{'right-side'} = Goo::Canvas::Rect->new(
 
3897
                        $self->{_canvas}->get_root_item, $right, $middle_v, 8, 8,
 
3898
                        'fill-pattern' => $pattern,
 
3899
                        'line-width'   => 1,
 
3900
                        'antialias'    => 'none',
 
3901
                );
 
3902
 
 
3903
                $self->setup_item_signals( $self->{_canvas_bg_rect}{'bottom-side'} );
 
3904
                $self->setup_item_signals( $self->{_canvas_bg_rect}{'bottom-right-corner'} );
 
3905
                $self->setup_item_signals( $self->{_canvas_bg_rect}{'right-side'} );
 
3906
                $self->setup_item_signals_extra( $self->{_canvas_bg_rect}{'bottom-side'} );
 
3907
                $self->setup_item_signals_extra( $self->{_canvas_bg_rect}{'bottom-right-corner'} );
 
3908
                $self->setup_item_signals_extra( $self->{_canvas_bg_rect}{'right-side'} );
 
3909
 
 
3910
        }elsif($action eq 'hide' || $action eq 'show'){
 
3911
 
 
3912
                my $visibilty = undef; 
 
3913
                if($action eq 'hide'){
 
3914
                        $visibilty = 'hidden';
 
3915
                }elsif($action eq 'show'){
 
3916
                        $visibilty = 'visible';
 
3917
                }
 
3918
 
 
3919
                foreach ( keys %{ $self->{_canvas_bg_rect} } ) {
 
3920
                        $self->{_canvas_bg_rect}{$_}->set(
 
3921
                                'visibility' => $visibilty,
 
3922
                        );
 
3923
                }    #end determine rect
 
3924
 
 
3925
        }elsif($action eq 'update'){
 
3926
 
 
3927
                #update the canvas bounds as well
 
3928
                $self->{_canvas}->set_bounds(0, 0, $self->{_canvas_bg_rect}->get('width'), $self->{_canvas_bg_rect}->get('height'));
 
3929
                        
 
3930
                $self->{_canvas_bg_rect}{'bottom-side'}->set(
 
3931
                        'x'          => $middle_h - 8,
 
3932
                        'y'          => $bottom - 8,
 
3933
                );
 
3934
 
 
3935
                $self->{_canvas_bg_rect}{'bottom-right-corner'}->set(
 
3936
                        'x'          => $right - 8,
 
3937
                        'y'          => $bottom - 8,
 
3938
                );
 
3939
 
 
3940
                $self->{_canvas_bg_rect}{'right-side'}->set(
 
3941
                        'x'          => $right - 8,
 
3942
                        'y'          => $middle_v - 8,
 
3943
                );
 
3944
 
 
3945
                $self->handle_bg_rects('raise');
 
3946
 
 
3947
        }elsif($action eq 'raise'){
 
3948
                $self->{_canvas_bg_rect}{'bottom-side'}->raise;
 
3949
                $self->{_canvas_bg_rect}{'bottom-right-corner'}->raise;
 
3950
                $self->{_canvas_bg_rect}{'right-side'}->raise;                  
 
3951
        }
 
3952
}
 
3953
 
2182
3954
sub handle_rects {
2183
 
        my $self   = shift;
2184
 
        my $action = shift;
2185
 
        my $item   = shift;
 
3955
        my ($self, $action, $item) = @_;
2186
3956
 
2187
3957
        return FALSE unless $item;
2188
3958
        return FALSE unless exists $self->{_items}{$item};
2191
3961
        my $root = $self->{_canvas}->get_root_item;
2192
3962
 
2193
3963
        #do we have a blessed reference?
2194
 
        eval { $self->{_items}{$item}->can('isa'); };
2195
 
        if ($@) {
2196
 
                return FALSE;
2197
 
        }
 
3964
        #~ eval { $self->{_items}{$item}->can('isa'); };
 
3965
        #~ if ($@) {
 
3966
                #~ print $@;
 
3967
                #~ return FALSE;
 
3968
        #~ }
2198
3969
 
2199
3970
        if ( $self->{_items}{$item}->isa('Goo::Canvas::Rect') ) {
2200
 
 
2201
 
                my $middle_h = $self->{_items}{$item}->get('x') + $self->{_items}{$item}->get('width') / 2 ;
2202
 
 
2203
 
                my $middle_v = $self->{_items}{$item}->get('y') + $self->{_items}{$item}->get('height') / 2 ;
2204
 
 
2205
 
                my $bottom = $self->{_items}{$item}->get('y') + $self->{_items}{$item}->get('height');
2206
 
 
2207
 
                my $top = $self->{_items}{$item}->get('y');
2208
 
 
2209
 
                my $left = $self->{_items}{$item}->get('x');
2210
 
 
2211
 
                my $right = $self->{_items}{$item}->get('x') + $self->{_items}{$item}->get('width');
 
3971
                
 
3972
                my $x                   = $self->{_items}{$item}->get('x');
 
3973
                my $y                   = $self->{_items}{$item}->get('y');
 
3974
                my $width               = $self->{_items}{$item}->get('width');
 
3975
                my $height              = $self->{_items}{$item}->get('height');
 
3976
                
 
3977
                my $middle_h    = $x + $width / 2 ;
 
3978
                my $middle_v    = $y + $height / 2 ;
 
3979
                my $bottom              = $y + $height;
 
3980
                my $top                 = $y;
 
3981
                my $left                = $x;
 
3982
                my $right               = $x + $width;
2212
3983
 
2213
3984
                if ( $action eq 'create' ) {
2214
3985
 
2215
 
                        my $pattern = $self->create_color( 'green', 0.3 );
 
3986
                        my $pattern  = $self->create_color( $self->{_style_bg}, 1 );
2216
3987
 
2217
3988
                        $self->{_items}{$item}{'top-side'} = Goo::Canvas::Rect->new(
2218
3989
                                $root, $middle_h, $top, 8, 8,
2219
 
                                'fill-pattern' => $pattern,
2220
 
                                'visibility'   => 'hidden',
2221
 
                                'line-width'   => 1
 
3990
                                'fill-pattern'   => $pattern,
 
3991
                                'visibility'     => 'hidden',
 
3992
                                'line-width'     => 0.5,
2222
3993
                        );
2223
 
 
 
3994
        
2224
3995
                        $self->{_items}{$item}{'top-left-corner'} = Goo::Canvas::Rect->new(
2225
3996
                                $root, $left, $top, 8, 8,
2226
 
                                'fill-pattern' => $pattern,
2227
 
                                'visibility'   => 'hidden',
2228
 
                                'line-width'   => 1
 
3997
                                'fill-pattern'   => $pattern,
 
3998
                                'visibility'     => 'hidden',
 
3999
                                'line-width'     => 0.5,
 
4000
                                'radius-x'           => 8,
 
4001
                                'radius-y'           => 8,
2229
4002
                        );
2230
4003
 
2231
4004
                        $self->{_items}{$item}{'top-right-corner'} = Goo::Canvas::Rect->new(
2232
4005
                                $root, $right, $top, 8, 8,
2233
 
                                'fill-pattern' => $pattern,
2234
 
                                'visibility'   => 'hidden',
2235
 
                                'line-width'   => 1
 
4006
                                'fill-pattern'   => $pattern,
 
4007
                                'visibility'     => 'hidden',
 
4008
                                'line-width'     => 0.5,
 
4009
                                'radius-x'           => 8,
 
4010
                                'radius-y'           => 8,
2236
4011
                        );
2237
4012
 
2238
4013
                        $self->{_items}{$item}{'bottom-side'} = Goo::Canvas::Rect->new(
2239
4014
                                $root, $middle_h, $bottom, 8, 8,
2240
 
                                'fill-pattern' => $pattern,
2241
 
                                'visibility'   => 'hidden',
2242
 
                                'line-width'   => 1
 
4015
                                'fill-pattern'   => $pattern,
 
4016
                                'visibility'     => 'hidden',
 
4017
                                'line-width'     => 0.5,
2243
4018
                        );
2244
4019
 
2245
4020
                        $self->{_items}{$item}{'bottom-left-corner'} = Goo::Canvas::Rect->new(
2246
4021
                                $root, $left, $bottom, 8, 8,
2247
 
                                'fill-pattern' => $pattern,
2248
 
                                'visibility'   => 'hidden',
2249
 
                                'line-width'   => 1
 
4022
                                'fill-pattern'   => $pattern,
 
4023
                                'visibility'     => 'hidden',
 
4024
                                'line-width'     => 0.5,
 
4025
                                'radius-x'           => 8,
 
4026
                                'radius-y'           => 8,
2250
4027
                        );
2251
4028
 
2252
4029
                        $self->{_items}{$item}{'bottom-right-corner'} = Goo::Canvas::Rect->new(
2253
4030
                                $root, $right, $bottom, 8, 8,
2254
 
                                'fill-pattern' => $pattern,
2255
 
                                'visibility'   => 'hidden',
2256
 
                                'line-width'   => 1
 
4031
                                'fill-pattern'   => $pattern,
 
4032
                                'visibility'     => 'hidden',
 
4033
                                'line-width'     => 0.5,
 
4034
                                'radius-x'           => 8,
 
4035
                                'radius-y'           => 8,
2257
4036
                        );
2258
4037
 
2259
4038
                        $self->{_items}{$item}{'left-side'} = Goo::Canvas::Rect->new(
2260
4039
                                $root, $left - 8, $middle_v, 8, 8,
2261
 
                                'fill-pattern' => $pattern,
2262
 
                                'visibility'   => 'hidden',
2263
 
                                'line-width'   => 1
 
4040
                                'fill-pattern'   => $pattern,
 
4041
                                'visibility'     => 'hidden',
 
4042
                                'line-width'     => 0.5,
2264
4043
                        );
2265
4044
 
2266
4045
                        $self->{_items}{$item}{'right-side'} = Goo::Canvas::Rect->new(
2267
4046
                                $root, $right, $middle_v, 8, 8,
2268
 
                                'fill-pattern' => $pattern,
2269
 
                                'visibility'   => 'hidden',
2270
 
                                'line-width'   => 1
 
4047
                                'fill-pattern'   => $pattern,
 
4048
                                'visibility'     => 'hidden',
 
4049
                                'line-width'     => 0.5,
2271
4050
                        );
2272
4051
 
2273
4052
                        $self->setup_item_signals( $self->{_items}{$item}{'top-side'} );
2292
4071
                        my $visibilty = 'visible';
2293
4072
                        $visibilty = 'hidden' if $action eq 'hide';
2294
4073
 
 
4074
                        my $lw = $item->get('line-width');
 
4075
 
2295
4076
                        #ellipse => hide rectangle as well
2296
4077
                        if ( exists $self->{_items}{$item}{ellipse} ) {
2297
4078
                                $self->{_items}{$item}->set( 'visibility' => $visibilty );
2312
4093
                                $self->{_items}{$item}->set( 'visibility' => $visibilty );
2313
4094
                        }
2314
4095
 
 
4096
                        #just to make sure the update routines are not
 
4097
                        #called in wrong order
 
4098
                        #we test the first value, if this is ok
 
4099
                        #we believe all other resize rects are ok as well
 
4100
                        return FALSE unless defined $self->{_items}{$item}{'top-side'};
 
4101
        
2315
4102
                        $self->{_items}{$item}{'top-side'}->set(
2316
4103
                                'x'          => $middle_h - 4,
2317
4104
                                'y'          => $top - 8,
2358
4145
                                'visibility' => $visibilty,
2359
4146
                        );
2360
4147
 
 
4148
                        #~ $self->handle_bg_rects('raise');
 
4149
 
2361
4150
                } elsif ( $action eq 'raise' ) {
2362
4151
 
2363
4152
                        $self->{_items}{$item}{'top-side'}->raise;
2388
4177
 
2389
4178
sub event_item_on_button_release {
2390
4179
        my ( $self, $item, $target, $ev ) = @_;
2391
 
        my $canvas = $item->get_canvas;
2392
 
        $canvas->pointer_ungrab( $item, $ev->time );
2393
 
 
2394
 
        my $d = $self->{_shutter_common}->get_gettext;
 
4180
 
 
4181
        $self->{_canvas}->pointer_ungrab( $item, $ev->time );
 
4182
 
 
4183
        #canvas is idle now...
 
4184
        $self->{_busy} = FALSE;
2395
4185
 
2396
4186
        #we handle some minimum sizes here if the new items are too small
2397
4187
        #maybe the user just wanted to place an rect or an object on the canvas
2400
4190
 
2401
4191
        if ($nitem) {
2402
4192
 
 
4193
                #mark as active item
 
4194
                $self->{_current_item}          = $nitem;
 
4195
                        
 
4196
                #apply item properties to widgets
 
4197
                #line width, fill color, stroke color etc.
 
4198
                $self->set_and_save_drawing_properties($nitem, FALSE);
 
4199
 
2403
4200
                #set minimum sizes
2404
4201
                if ( $nitem->isa('Goo::Canvas::Rect') ) {
2405
4202
 
2406
4203
                        #real shape
2407
4204
                        if ( exists $self->{_items}{$nitem} ) {
2408
4205
 
 
4206
                                #images
2409
4207
                                if (exists $self->{_items}{$nitem}{image}){
2410
4208
                                        
2411
4209
                                        #~ my ($maxw, $maxh) = Gtk2::Gdk::Display->get_default->get_maximal_cursor_size;
2415
4213
                                        #~ );
2416
4214
 
2417
4215
                                        $self->{_items}{$nitem}->set(
2418
 
                                                'width' => $self->{_items}{$nitem}{orig_pixbuf}->get_width,
2419
 
                                                'height' => $self->{_items}{$nitem}{orig_pixbuf}->get_height
 
4216
                                                'x'             => $ev->x_root - int($self->{_items}{$nitem}{orig_pixbuf}->get_width  / 2),
 
4217
                                                'y'             => $ev->y_root - int($self->{_items}{$nitem}{orig_pixbuf}->get_height / 2),
 
4218
                                                'width'         => $self->{_items}{$nitem}{orig_pixbuf}->get_width,
 
4219
                                                'height'        => $self->{_items}{$nitem}{orig_pixbuf}->get_height,
2420
4220
                                        );
 
4221
 
 
4222
                                #texts
 
4223
                                }elsif (exists $self->{_items}{$nitem}{text}){
 
4224
 
 
4225
                                        #~ #adjust parent rectangle
 
4226
                                        #~ my $tb = $self->{_items}{$nitem}{text}->get_bounds;
 
4227
                                                                        #~ 
 
4228
                                        #~ $nitem->set( 
 
4229
                                                #~ 'x'                  => $ev->x_root - 50, 
 
4230
                                                #~ 'y'          => $ev->y_root - 50,                    
 
4231
                                                #~ 'width'      => abs($tb->x1 - $tb->x2),
 
4232
                                                #~ 'height'     => abs($tb->y1 - $tb->y2),
 
4233
                                        #~ );                           
2421
4234
                        
 
4235
                                #all other objects
2422
4236
                                }else{
2423
 
 
2424
 
                                        $nitem->set( 'width'  => 100 ) if ( $nitem->get('width') < 10 );
2425
 
                                        $nitem->set( 'height' => 100 ) if ( $nitem->get('height') < 10 );
 
4237
                                        
 
4238
                                        $nitem->set( 
 
4239
                                                'x'             => $ev->x_root - 50, 
 
4240
                                                'y'             => $ev->y_root - 50,                    
 
4241
                                                'width'         => 50,
 
4242
                                                'height'        => 50,
 
4243
                                        );
2426
4244
                                        
2427
4245
                                }
2428
4246
 
2432
4250
 
2433
4251
                $self->handle_rects( 'update', $nitem );
2434
4252
                $self->handle_embedded( 'update', $nitem );
 
4253
                
 
4254
                #add to undo stack
 
4255
                $self->store_to_xdo_stack($nitem , 'create', 'undo');           
2435
4256
 
2436
4257
        }
2437
4258
 
 
4259
        #uncheck previous active items
 
4260
        $self->{_current_new_item}      = undef;
 
4261
        $self->{_last_item}                     = undef;
 
4262
 
2438
4263
        #unset action flags
2439
 
        $item->{dragging} = FALSE;
2440
 
        $item->{resizing} = FALSE;
 
4264
        $item->{dragging}               = FALSE if exists $item->{dragging};
 
4265
        $item->{dragging_start} = FALSE if exists $item->{dragging_start};
 
4266
        $item->{resizing}               = FALSE if exists $item->{resizing};
 
4267
        #~ $item->{resizing_start} = FALSE if exists $item->{resizing_start};
2441
4268
 
2442
4269
        #because of performance reason we load the current image new from file when
2443
4270
        #the current action is over => button-release
2449
4276
        if ( $child && $child->isa('Goo::Canvas::Image') ){
2450
4277
                my $parent = $self->get_parent_item($child);
2451
4278
                
2452
 
                my $copy = Gtk2::Gdk::Pixbuf->new_from_file_at_scale($self->{_items}{$parent}{orig_pixbuf_filename},$self->{_items}{$parent}->get('width'), $self->{_items}{$parent}->get('height'), FALSE);
2453
 
                                
2454
 
                $self->{_items}{$parent}{image}->set(
2455
 
                        'x'      => int $self->{_items}{$parent}->get('x'),
2456
 
                        'y'      => int $self->{_items}{$parent}->get('y'),
2457
 
                        'width'  => $self->{_items}{$parent}->get('width'),
2458
 
                        'height' => $self->{_items}{$parent}->get('height'),
2459
 
                        'pixbuf' => $copy
2460
 
                );
 
4279
                my $copy = undef;
 
4280
                eval{
 
4281
                        $copy = Gtk2::Gdk::Pixbuf->new_from_file_at_scale($self->{_items}{$parent}{orig_pixbuf_filename},$self->{_items}{$parent}->get('width'), $self->{_items}{$parent}->get('height'), FALSE);
 
4282
                };
 
4283
                unless($@){             
 
4284
                        $self->{_items}{$parent}{image}->set(
 
4285
                                'x'      => int $self->{_items}{$parent}->get('x'),
 
4286
                                'y'      => int $self->{_items}{$parent}->get('y'),
 
4287
                                'width'  => $self->{_items}{$parent}->get('width'),
 
4288
                                'height' => $self->{_items}{$parent}->get('height'),
 
4289
                                'pixbuf' => $copy
 
4290
                        );
 
4291
                }else{
 
4292
                        my $response = $self->{_dialogs}->dlg_error_message( 
 
4293
                                sprintf( $self->{_d}->get("Error while opening image %s."), "'" . $self->{_items}{$parent}{orig_pixbuf_filename} . "'"),
 
4294
                                $self->{_d}->get( "There was an error opening the image." ),
 
4295
                                undef, undef, undef,
 
4296
                                undef, undef, undef,
 
4297
                                $@
 
4298
                        );
 
4299
                        $self->abort_current_mode;                                                                                      
 
4300
                }       
2461
4301
        }       
2462
 
                        
2463
 
        $self->set_drawing_action(0);
2464
 
        $self->change_drawing_tool_cb(10);
2465
4302
 
 
4303
        $self->set_drawing_action(int($self->{_current_mode}/10));
 
4304
                
2466
4305
        return TRUE;
2467
4306
}
2468
4307
 
2469
4308
sub event_item_on_enter_notify {
2470
4309
        my ( $self, $item, $target, $ev ) = @_;
2471
 
 
 
4310
        
 
4311
        return TRUE if $self->{_busy};
 
4312
        
2472
4313
        if (   $item->isa('Goo::Canvas::Rect')
2473
4314
                || $item->isa('Goo::Canvas::Ellipse')
2474
4315
                || $item->isa('Goo::Canvas::Text')
2484
4325
 
2485
4326
                #real shape
2486
4327
                if ( exists $self->{_items}{$item} ) {
2487
 
 
 
4328
                        
2488
4329
                        $cursor = Gtk2::Gdk::Cursor->new('fleur');
2489
4330
 
2490
4331
                        #set cursor
2491
4332
                        if ( $self->{_current_mode_descr} eq "select" ) {
2492
4333
                                $self->{_canvas}->window->set_cursor($cursor);
2493
 
                        } elsif ( $self->{_current_mode_descr} eq "clear" ) {
2494
 
                                my $dicons = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool";
2495
 
                                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
2496
 
                                        Gtk2::Gdk::Display->get_default,
2497
 
                                        Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-eraser.png"),
2498
 
                                        Gtk2::IconSize->lookup('menu')
2499
 
                                );
2500
 
                                $self->{_canvas}->window->set_cursor($cursor);
2501
 
                        }
 
4334
                        } 
 
4335
                        
 
4336
                #canvas resizing shape
 
4337
                } elsif (  $self->{_canvas_bg_rect}{'right-side'} == $item
 
4338
                                || $self->{_canvas_bg_rect}{'bottom-side'} == $item
 
4339
                                || $self->{_canvas_bg_rect}{'bottom-right-corner'} == $item ) 
 
4340
                {
 
4341
 
 
4342
                        if ( $self->{_current_mode_descr} eq "select" ) {
 
4343
 
 
4344
                                foreach ( keys %{ $self->{_canvas_bg_rect} } ) {
 
4345
                                        if ( $item == $self->{_canvas_bg_rect}{$_} ) {
 
4346
                                                my $cursor = Gtk2::Gdk::Cursor->new($_);
 
4347
                                                $self->{_canvas}->window->set_cursor($cursor);
 
4348
                                                last;
 
4349
                                        }
 
4350
                                }    #end determine cursor
 
4351
                        }               
2502
4352
 
2503
4353
                        #resizing shape
2504
4354
                } else {
2505
4355
                        
2506
 
                        #don't change color when an action is already taking place
2507
 
                        #e.g. resizing
2508
 
                        if ( $self->{_current_mode_descr} eq "select" ) {
2509
 
                                my $pattern = $self->create_color( 'red', 0.5 );
2510
 
                                $item->set( 'fill-pattern' => $pattern );
2511
 
                        }
2512
 
 
2513
 
                        #activate correct item if not activated yet
2514
4356
                        my $curr_item = $self->{_current_new_item} || $self->{_current_item};
2515
 
 
2516
 
                        $self->{_current_new_item} = undef;
2517
 
                        $self->{_last_item}        = $curr_item;
2518
 
                        $self->{_current_item}     = $curr_item;
2519
 
 
2520
 
                        $self->handle_rects( 'hide',   $self->{_last_item} );
2521
 
                        $self->handle_rects( 'update', $curr_item );
2522
 
 
2523
4357
                        if ( $self->{_current_mode_descr} eq "select" ) {
2524
4358
                                foreach ( keys %{ $self->{_items}{$curr_item} } ) {
 
4359
                                        next unless $_ =~ m/(corner|side)/;
2525
4360
                                        if ( $item == $self->{_items}{$curr_item}{$_} ) {
2526
4361
                                                $cursor = Gtk2::Gdk::Cursor->new($_);
2527
4362
                                                $self->{_canvas}->window->set_cursor($cursor);
 
4363
                                                last;
2528
4364
                                        }
2529
4365
                                }    #end determine cursor
2530
4366
                        }
2531
 
 
2532
4367
                }
2533
 
 
2534
4368
        }
2535
4369
 
2536
4370
        return TRUE;
2539
4373
sub event_item_on_leave_notify {
2540
4374
        my ( $self, $item, $target, $ev ) = @_;
2541
4375
 
2542
 
        if (   $item->isa('Goo::Canvas::Rect')
2543
 
                || $item->isa('Goo::Canvas::Ellipse')
2544
 
                || $item->isa('Goo::Canvas::Text')
2545
 
                || $item->isa('Goo::Canvas::Image')
2546
 
                || $item->isa('Goo::Canvas::Polyline') )
2547
 
        {
2548
 
 
2549
 
                #embedded item?
2550
 
                my $parent = $self->get_parent_item($item);
2551
 
                $item = $parent if $parent;
2552
 
 
2553
 
                #real shape
2554
 
                if ( exists $self->{_items}{$item} ) {
2555
 
 
2556
 
                        #resizing shape
2557
 
                } else {
2558
 
                        my $pattern = $self->create_color( 'green', 0.3 );
2559
 
                        $item->set( 'fill-pattern' => $pattern );
2560
 
                }
 
4376
        if ( $self->{_current_mode_descr} eq "select" ){
 
4377
                $self->{_canvas}->window->set_cursor(Gtk2::Gdk::Cursor->new('left-ptr'));
2561
4378
        }
2562
4379
 
2563
 
        my $cursor = Gtk2::Gdk::Cursor->new('left-ptr');
2564
 
        $self->{_canvas}->window->set_cursor($cursor)
2565
 
                if ( $self->{_current_mode_descr} eq "select"
2566
 
                || $self->{_current_mode_descr} eq "clear" );
2567
 
 
2568
4380
        return TRUE;
2569
4381
}
2570
4382
 
2571
4383
sub create_stipple {
2572
4384
        my $self = shift;
 
4385
        
2573
4386
        our @stipples;
2574
4387
        my ( $color_name, $stipple_data ) = @_;
2575
4388
        my $color = Gtk2::Gdk::Color->parse($color_name);
2581
4394
        my $surface = Cairo::ImageSurface->create_for_data( $stipple_str, 'argb32', 2, 2, 8 );
2582
4395
        my $pattern = Cairo::SurfacePattern->create($surface);
2583
4396
        $pattern->set_extend('repeat');
 
4397
 
2584
4398
        return Goo::Cairo::Pattern->new($pattern);
2585
4399
}
2586
4400
 
2614
4428
#ui related stuff
2615
4429
sub setup_uimanager {
2616
4430
        my $self = shift;
2617
 
        my $d    = $self->{_shutter_common}->get_gettext;
2618
 
 
2619
 
        #define own icons
2620
 
        my $dicons = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool";
2621
4431
 
2622
4432
        $self->{_factory} = Gtk2::IconFactory->new();
2623
 
        $self->{_factory}->add( 'shutter-ellipse',   Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-ellipse.png") ) );
2624
 
        $self->{_factory}->add( 'shutter-eraser',    Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-eraser.png") ) );
2625
 
        $self->{_factory}->add( 'shutter-freehand',  Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-freehand.png") ) );
2626
 
        $self->{_factory}->add( 'shutter-pointer',   Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-pointer.png") ) );
2627
 
        $self->{_factory}->add( 'shutter-rectangle', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-rectangle.png") ) );
2628
 
        $self->{_factory}->add( 'shutter-line', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-line.png") ) );
2629
 
        $self->{_factory}->add( 'shutter-text',      Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-text.png") ) );
2630
 
        $self->{_factory}->add( 'shutter-censor',      Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-censor.png") ) );
 
4433
        $self->{_factory}->add( 'shutter-ellipse', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-ellipse.png') ) );
 
4434
        $self->{_factory}->add( 'shutter-eraser', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-eraser.png') ) );
 
4435
        $self->{_factory}->add( 'shutter-freehand', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-freehand.png') ) );
 
4436
        $self->{_factory}->add( 'shutter-highlighter', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-highlighter.png') ) );
 
4437
        $self->{_factory}->add( 'shutter-pointer', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-pointer.png') ) );
 
4438
        $self->{_factory}->add( 'shutter-rectangle', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-rectangle.png') ) );
 
4439
        $self->{_factory}->add( 'shutter-line', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-line.png') ) );
 
4440
        $self->{_factory}->add( 'shutter-arrow', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-arrow.png') ) );
 
4441
        $self->{_factory}->add( 'shutter-text', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-text.png') ) );
 
4442
        $self->{_factory}->add( 'shutter-censor', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-censor.png') ) );
 
4443
        $self->{_factory}->add( 'shutter-number', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-number.png') ) );
 
4444
        $self->{_factory}->add( 'shutter-crop', Gtk2::IconSet->new_from_pixbuf( Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/transform-crop.png') ) );
2631
4445
        $self->{_factory}->add_default();
2632
4446
 
2633
 
        my @default_actions = ( [ "File", undef, $d->get("_File") ], [ "Edit", undef, $d->get("_Edit") ], [ "View", undef, $d->get("_View") ] );
2634
 
 
2635
 
        my @menu_actions = (
2636
 
                [ "Undo", 'gtk-undo', undef, "<control>Z", undef, sub { $self->undo } ],
2637
 
                [ "Redo", 'gtk-redo', undef, "<control>Y", undef, sub { $self->redo } ],
2638
 
                [ "Copy", 'gtk-copy', undef, "<control>C", undef, sub { $self->{_cut} = FALSE; $self->{_current_copy_item} = $self->{_current_item}; } ],
2639
 
                [ "Cut", 'gtk-cut', undef, "<control>X", undef, sub { $self->{_cut} = TRUE; $self->{_current_copy_item} = $self->{_current_item}; $self->clear_item_from_canvas( $self->{_current_copy_item}); } ],
2640
 
                [ "Paste", 'gtk-paste', undef, "<control>V", undef, sub { $self->paste_item($self->{_current_copy_item}, $self->{_cut} ); $self->{_cut} = FALSE; } ],
2641
 
                [ "Delete", 'gtk-delete', undef, "Delete", undef, sub { $self->clear_item_from_canvas( $self->{_current_item}); } ],
2642
 
                [ "Stop", 'gtk-stop', undef, "Escape", undef, sub { $self->abort_current_mode } ]
2643
 
 
2644
 
        );
2645
 
 
2646
 
        my @menu_toggle_actions = (
2647
 
                [   "Autoscroll", undef, $d->get("Automatic scrolling"), undef, undef, sub { my $widget = shift; $self->{_autoscroll} = $widget->get_active; }
2648
 
                ]
2649
 
        );
2650
 
 
2651
 
        my @toolbar_actions = (
2652
 
                [ "Close", 'gtk-close', undef, "<control>Q", undef, sub { $self->quit(TRUE) } ],
2653
 
                [ "Save",       'gtk-save',     undef, "<control>S",     undef, sub { $self->save(), $self->quit(FALSE) } ],
2654
 
                [ "ZoomIn",     'gtk-zoom-in',  undef, "<control>plus",  undef, sub { $self->zoom_in_cb($self) } ],
2655
 
                [ "ControlEqual",  'gtk-zoom-in',  undef, "<control>equal",  undef, sub { $self->zoom_in_cb($self) } ],
2656
 
                [ "ControlKpAdd",  'gtk-zoom-in',  undef, "<control>KP_Add",  undef, sub { $self->zoom_in_cb($self) } ],
2657
 
                [ "ZoomOut",    'gtk-zoom-out', undef, "<control>minus", undef, sub { $self->zoom_out_cb($self) } ],
2658
 
                [ "ControlKpSub",    'gtk-zoom-out', undef, "<control>KP_Subtract", undef, sub { $self->zoom_out_cb($self) } ],
2659
 
                [ "ZoomNormal", 'gtk-zoom-100', undef, "<control>0",     undef, sub { $self->zoom_normal_cb($self) } ]
2660
 
        );
2661
 
 
2662
 
        my @toolbar_drawing_actions = (
2663
 
                [ "Select",  'shutter-pointer',   undef, undef, $d->get("Select item to move or resize it"),    10 ],
2664
 
                [ "Freehand",    'shutter-freehand',  undef, undef, $d->get("Draw a freehand line"), 20 ],
2665
 
                [ "Line",    'shutter-line', undef, undef, $d->get("Draw a straight line"),                    30 ],
2666
 
                [ "Rect",    'shutter-rectangle', undef, undef, $d->get("Draw a rectangle"),                    40 ],
2667
 
                [ "Ellipse", 'shutter-ellipse',   undef, undef, $d->get("Draw a ellipse"),                      50 ],
2668
 
                [ "Text",    'shutter-text',      undef, undef, $d->get("Add some text to the screenshot"),     60 ],
2669
 
                [ "Censor",    'shutter-censor',      undef, undef, $d->get("Censor portions of your screenshot to hide private data"),     70 ],
2670
 
                [ "Clear",   'shutter-eraser',    undef, undef, $d->get("Delete objects"),                      80 ],
2671
 
                [ "ClearAll",'gtk-clear',        undef, undef, $d->get("Delete all objects"),                  90 ]
 
4447
        my @main_actions = (
 
4448
                [ "File", undef, $self->{_d}->get("_File") ], 
 
4449
                [ "Edit", undef, $self->{_d}->get("_Edit") ], 
 
4450
                [ "View", undef, $self->{_d}->get("_View") ],
 
4451
                [ "Undo", 'gtk-undo', undef, "<control>Z", undef, sub { 
 
4452
                        $self->abort_current_mode; $self->xdo('undo'); 
 
4453
                } ],
 
4454
                [ "Redo", 'gtk-redo', undef, "<control>Y", undef, sub { 
 
4455
                        $self->abort_current_mode; $self->xdo('redo'); 
 
4456
                } ],
 
4457
                [ "Copy", 'gtk-copy', undef, "<control>C", undef, sub { 
 
4458
                        $self->{_cut} = FALSE; 
 
4459
                        $self->{_current_copy_item} = $self->{_current_item}; 
 
4460
                } ],
 
4461
                [ "Cut", 'gtk-cut', undef, "<control>X", undef, sub { 
 
4462
                        $self->{_cut} = TRUE; 
 
4463
                        $self->{_current_copy_item} = $self->{_current_item}; 
 
4464
                        $self->clear_item_from_canvas( $self->{_current_copy_item} ); 
 
4465
                } ],
 
4466
                [ "Paste", 'gtk-paste', undef, "<control>V", undef, sub { 
 
4467
                        $self->paste_item($self->{_current_copy_item}, $self->{_cut} ); $self->{_cut} = FALSE; 
 
4468
                } ],
 
4469
                [ "Delete", 'gtk-delete', undef, "Delete", undef, sub { 
 
4470
                        $self->clear_item_from_canvas( $self->{_current_item} ); 
 
4471
                } ],
 
4472
                [ "Clear", 'gtk-clear', undef, "<control>Delete", undef, sub { 
 
4473
                        #store items to delete in temporary hash
 
4474
                        #sort them uid
 
4475
                        my %time_hash;
 
4476
                        foreach (keys %{$self->{_items}}){
 
4477
                                $time_hash{$self->{_items}{$_}{uid}} = $self->{_items}{$_};     
 
4478
                        }
 
4479
                        
 
4480
                        #delete items
 
4481
                        foreach (sort keys %time_hash){
 
4482
                                $self->clear_item_from_canvas($time_hash{$_});
 
4483
                        }                       
 
4484
                } ],
 
4485
                [ "Stop", 'gtk-stop', undef, "Escape", undef, sub { 
 
4486
                        $self->abort_current_mode 
 
4487
                } ],
 
4488
                [ "Close", 'gtk-close', undef, "<control>Q", undef, sub { 
 
4489
                        $self->quit(TRUE) 
 
4490
                } ],
 
4491
                [ "Save",       'gtk-save',     undef, "<control>S", undef, sub { 
 
4492
                        $self->save(), $self->quit(FALSE) 
 
4493
                } ],
 
4494
                [ "ZoomIn",     'gtk-zoom-in',  undef, "<control>plus", undef, sub { 
 
4495
                        $self->zoom_in_cb($self) 
 
4496
                } ],
 
4497
                [ "ControlEqual",  'gtk-zoom-in',  undef, "<control>equal", undef, sub { 
 
4498
                        $self->zoom_in_cb($self) 
 
4499
                } ],
 
4500
                [ "ControlKpAdd",  'gtk-zoom-in',  undef, "<control>KP_Add", undef, sub { 
 
4501
                        $self->zoom_in_cb($self) 
 
4502
                } ],
 
4503
                [ "ZoomOut",    'gtk-zoom-out', undef, "<control>minus", undef, sub { 
 
4504
                        $self->zoom_out_cb($self) 
 
4505
                } ],
 
4506
                [ "ControlKpSub",    'gtk-zoom-out', undef, "<control>KP_Subtract", undef, sub { 
 
4507
                        $self->zoom_out_cb($self) 
 
4508
                } ],
 
4509
                [ "ZoomNormal", 'gtk-zoom-100', undef, "<control>0", undef, sub { 
 
4510
                        $self->zoom_normal_cb($self) 
 
4511
                } ],
 
4512
        );
 
4513
 
 
4514
        my @toggle_actions = (
 
4515
                [ "Autoscroll", undef, $self->{_d}->get("Automatic scrolling"), undef, undef, 
 
4516
                        sub { 
 
4517
                                my $widget = shift; 
 
4518
                                
 
4519
                                if($widget->get_active){ 
 
4520
                                        $self->{_autoscroll} = TRUE;
 
4521
                                }else{ 
 
4522
                                        $self->{_autoscroll} = FALSE;
 
4523
                                }
 
4524
 
 
4525
                                #'redraw-when-scrolled' to reduce the flicker of static items
 
4526
                                #
 
4527
                                #this property is not available in older versions
 
4528
                                #it was added to goocanvas on Mon Nov 17 10:28:07 2008 UTC
 
4529
                                #http://svn.gnome.org/viewvc/goocanvas?view=revision&revision=28        
 
4530
                                if($self->{_canvas} && $self->{_canvas}->find_property ('redraw-when-scrolled')){
 
4531
                                        $self->{_canvas}->set( 
 
4532
                                                'redraw-when-scrolled'  => !$self->{_autoscroll}
 
4533
                                        );              
 
4534
                                }                                                               
 
4535
                        } 
 
4536
                ],
 
4537
                [ "Fullscreen", 'gtk-fullscreen', undef, "F11", undef, 
 
4538
                        sub { 
 
4539
                                my $action = shift; 
 
4540
                                
 
4541
                                if($action->get_active){ 
 
4542
                                        $self->{_drawing_window}->fullscreen 
 
4543
                                }else{ 
 
4544
                                        $self->{_drawing_window}->unfullscreen 
 
4545
                                } 
 
4546
                        }       
 
4547
                ],
 
4548
        );
 
4549
 
 
4550
        my @drawing_actions = (
 
4551
                [ "Select",  'shutter-pointer', undef, undef, $self->{_d}->get("Select item to move or resize it"), 10 ],
 
4552
                [ "Freehand",    'shutter-freehand', undef, undef, $self->{_d}->get("Draw a freehand line"), 20 ],
 
4553
                [ "Highlighter",    'shutter-highlighter', undef, undef, $self->{_d}->get("Highlighter"), 30 ],
 
4554
                [ "Line",    'shutter-line', undef, undef, $self->{_d}->get("Draw a straight line"), 40 ],
 
4555
                [ "Arrow",    'shutter-arrow', undef, undef, $self->{_d}->get("Draw an arrow"), 50 ],
 
4556
                [ "Rect",    'shutter-rectangle', undef, undef, $self->{_d}->get("Draw a rectangle"), 60 ],
 
4557
                [ "Ellipse", 'shutter-ellipse', undef, undef, $self->{_d}->get("Draw a ellipse"), 70 ],
 
4558
                [ "Text",    'shutter-text', undef, undef, $self->{_d}->get("Add some text to the screenshot"), 80 ],
 
4559
                [ "Censor",    'shutter-censor', undef, undef, $self->{_d}->get("Censor portions of your screenshot to hide private data"), 90 ],
 
4560
                [ "Number",    'shutter-number', undef, undef, $self->{_d}->get("Add an auto-increment shape to the screenshot"), 100 ],
 
4561
                [ "Crop",    'shutter-crop', undef, undef, $self->{_d}->get("Crop your screenshot"), 110 ]
2672
4562
        );
2673
4563
 
2674
4564
        my $uimanager = Gtk2::UIManager->new();
2677
4567
        my $accelgroup = $uimanager->get_accel_group;
2678
4568
        $self->{_drawing_window}->add_accel_group($accelgroup);
2679
4569
 
2680
 
        # Setup the default group.
2681
 
        my $default_group = Gtk2::ActionGroup->new("default");
2682
 
        $default_group->add_actions( \@default_actions );
2683
 
 
2684
 
        # Setup the menu group.
2685
 
        my $menu_group = Gtk2::ActionGroup->new("menu");
2686
 
        $menu_group->add_actions( \@menu_actions );
 
4570
        # Setup the main group.
 
4571
        my $main_group = Gtk2::ActionGroup->new("main");
 
4572
        $main_group->add_actions( \@main_actions );
2687
4573
 
2688
4574
        #setup the menu toggle group
2689
 
        my $menu_toggle_group = Gtk2::ActionGroup->new("menu_toggle");
2690
 
        $menu_toggle_group->add_toggle_actions( \@menu_toggle_actions );
2691
 
 
2692
 
        # Setup the toolbar group.
2693
 
        my $toolbar_group = Gtk2::ActionGroup->new("toolbar");
2694
 
        $toolbar_group->add_actions( \@toolbar_actions );
 
4575
        my $toggle_group = Gtk2::ActionGroup->new("toggle");
 
4576
        $toggle_group->add_toggle_actions( \@toggle_actions );
2695
4577
 
2696
4578
        # Setup the drawing group.
2697
 
        my $toolbar_drawing_group = Gtk2::ActionGroup->new("drawing");
2698
 
        $toolbar_drawing_group->add_radio_actions( \@toolbar_drawing_actions, 10, sub { my $action = shift; $self->change_drawing_tool_cb($action); } );
2699
 
 
2700
 
        $uimanager->insert_action_group( $default_group,         0 );
2701
 
        $uimanager->insert_action_group( $menu_group,            0 );
2702
 
        $uimanager->insert_action_group( $menu_toggle_group,     0 );
2703
 
        $uimanager->insert_action_group( $toolbar_group,         0 );
2704
 
        $uimanager->insert_action_group( $toolbar_drawing_group, 0 );
2705
 
 
2706
 
      #~ <menuitem action = 'Undo'/>
2707
 
      #~ <menuitem action = 'Redo'/>
2708
 
          #~ <separator/>
 
4579
        my $drawing_group = Gtk2::ActionGroup->new("drawing");
 
4580
        $drawing_group->add_radio_actions( \@drawing_actions, 10, sub { my $action = shift; $self->change_drawing_tool_cb($action); } );
 
4581
 
 
4582
        $uimanager->insert_action_group( $main_group, 0 );
 
4583
        $uimanager->insert_action_group( $toggle_group, 0 );
 
4584
        $uimanager->insert_action_group( $drawing_group, 0 );
2709
4585
 
2710
4586
        my $ui_info = "
2711
 
<ui>
2712
 
  <menubar name = 'MenuBar'>
2713
 
    <menu action = 'File'>
2714
 
      <menuitem action = 'Save'/>
2715
 
      <separator/>
2716
 
      <menuitem action = 'Close'/>
2717
 
    </menu>
2718
 
    <menu action = 'Edit'>
2719
 
 
2720
 
      <menuitem action = 'Copy'/>
2721
 
      <menuitem action = 'Cut'/>
2722
 
      <menuitem action = 'Paste'/>
2723
 
      <menuitem action = 'Delete'/>
2724
 
      <separator/>
2725
 
      <menuitem action = 'Stop'/>
2726
 
      <separator/>
2727
 
      <menuitem action = 'Autoscroll'/>
2728
 
    </menu>
2729
 
    <menu action = 'View'>
2730
 
      <menuitem action = 'ControlEqual'/>       
2731
 
      <menuitem action = 'ControlKpAdd'/>       
2732
 
      <menuitem action = 'ZoomIn'/>
2733
 
      <menuitem action = 'ZoomOut'/>
2734
 
      <menuitem action = 'ControlKpSub'/>                 
2735
 
      <menuitem action = 'ZoomNormal'/>
2736
 
    </menu>
2737
 
  </menubar>
2738
 
  <toolbar name = 'ToolBar'>
2739
 
    <toolitem action='Close'/>
2740
 
    <toolitem action='Save'/>
2741
 
    <separator/>
2742
 
    <toolitem action='ZoomIn'/>
2743
 
    <toolitem action='ZoomOut'/>
2744
 
    <toolitem action='ZoomNormal'/>
2745
 
  </toolbar>
2746
 
  <toolbar name = 'ToolBarDrawing'>
2747
 
    <toolitem action='Select'/>
2748
 
    <separator/>
2749
 
    <toolitem action='Freehand'/>
2750
 
    <toolitem action='Line'/>
2751
 
    <toolitem action='Rect'/>
2752
 
    <toolitem action='Ellipse'/>
2753
 
    <toolitem action='Text'/>
2754
 
    <toolitem action='Censor'/>
2755
 
    <separator/>
2756
 
    <toolitem action='Clear'/>
2757
 
    <toolitem action='ClearAll'/>
2758
 
  </toolbar>  
2759
 
</ui>";
 
4587
        <ui>
 
4588
          <menubar name = 'MenuBar'>
 
4589
                <menu action = 'File'>
 
4590
                  <menuitem action = 'Save'/>
 
4591
                  <separator/>
 
4592
                  <menuitem action = 'Close'/>
 
4593
                </menu>
 
4594
                <menu action = 'Edit'>
 
4595
                  <menuitem action = 'Undo'/>
 
4596
                  <menuitem action = 'Redo'/>
 
4597
                  <separator/>
 
4598
                  <menuitem action = 'Copy'/>
 
4599
                  <menuitem action = 'Cut'/>
 
4600
                  <menuitem action = 'Paste'/>
 
4601
                  <menuitem action = 'Delete'/>
 
4602
                  <menuitem action = 'Clear'/>                    
 
4603
                  <separator/>
 
4604
                  <menuitem action = 'Stop'/>
 
4605
                  <separator/>
 
4606
                  <menuitem action = 'Autoscroll'/>
 
4607
                </menu>
 
4608
                <menu action = 'View'>
 
4609
                  <menuitem action = 'ControlEqual'/>   
 
4610
                  <menuitem action = 'ControlKpAdd'/>   
 
4611
                  <menuitem action = 'ZoomIn'/>
 
4612
                  <menuitem action = 'ZoomOut'/>
 
4613
                  <menuitem action = 'ControlKpSub'/>             
 
4614
                  <menuitem action = 'ZoomNormal'/>
 
4615
                  <separator/>
 
4616
                  <menuitem action = 'Fullscreen'/>
 
4617
                </menu>
 
4618
          </menubar>
 
4619
          <toolbar name = 'ToolBar'>
 
4620
                <toolitem action='Close'/>
 
4621
                <toolitem action='Save'/>
 
4622
                <separator/>
 
4623
                <toolitem action='ZoomIn'/>
 
4624
                <toolitem action='ZoomOut'/>
 
4625
                <toolitem action='ZoomNormal'/>
 
4626
                <separator/>
 
4627
                <toolitem action='Undo'/>
 
4628
                <toolitem action='Redo'/>
 
4629
                <separator/>
 
4630
                <toolitem action='Copy'/>
 
4631
                <toolitem action='Cut'/>
 
4632
                <toolitem action='Paste'/>
 
4633
                <toolitem action='Delete'/>             
 
4634
                <toolitem action='Clear'/>              
 
4635
          </toolbar>
 
4636
          <toolbar name = 'ToolBarDrawing'>
 
4637
                <toolitem action='Select'/>
 
4638
                <separator/>
 
4639
                <toolitem action='Freehand'/>
 
4640
                <toolitem action='Highlighter'/>
 
4641
                <toolitem action='Line'/>
 
4642
                <toolitem action='Arrow'/>
 
4643
                <toolitem action='Rect'/>
 
4644
                <toolitem action='Ellipse'/>
 
4645
                <toolitem action='Text'/>
 
4646
                <toolitem action='Censor'/>
 
4647
                <toolitem action='Number'/>
 
4648
                <separator/>
 
4649
                <toolitem action='Crop'/>
 
4650
          </toolbar>  
 
4651
        </ui>";
2760
4652
 
2761
4653
        eval { $uimanager->add_ui_from_string($ui_info) };
2762
4654
 
2767
4659
        return $uimanager;
2768
4660
}
2769
4661
 
2770
 
sub ret_objects_menu {
2771
 
        my $self   = shift;
2772
 
        my $button = shift;
 
4662
sub import_from_filesystem {
 
4663
        my $self                = shift;
 
4664
        my $button              = shift;
 
4665
        
 
4666
        #used when called recursively
 
4667
        my $parent              = shift;
 
4668
        my $directory   = shift;
2773
4669
 
2774
4670
        my $menu_objects = Gtk2::Menu->new;
2775
4671
 
2776
 
        my $d = $self->{_shutter_common}->get_gettext;
2777
 
 
2778
 
        my $dobjects = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool/objects";
2779
 
 
 
4672
        my $dobjects = $directory || $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool/objects";
 
4673
        
 
4674
        #first directory flag (see description above)
 
4675
        my $fd = TRUE;
 
4676
        my $ff = FALSE;
 
4677
        
2780
4678
        my @objects = glob("$dobjects/*");
2781
 
        foreach my $filename (@objects) {
2782
 
 
 
4679
        foreach my $name ( sort { -d $a <=> -d $b } @objects) {
 
4680
                                
2783
4681
                #parse filename
2784
 
                my ( $short, $folder, $type ) = fileparse( $filename, '\..*' );
2785
 
 
2786
 
                #create pixbufs
2787
 
                my $orig_pixbuf;
2788
 
                eval{
2789
 
                        $orig_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($filename);             
2790
 
                };
2791
 
                unless($@){
2792
 
 
2793
 
                        my $small_image = Gtk2::Image->new_from_pixbuf( $orig_pixbuf->scale_down_pixbuf (Gtk2::IconSize->lookup('menu')));
2794
 
                        #~ my $small_image_button = Gtk2::Image->new_from_pixbuf( $orig_pixbuf->scale_down_pixbuf (Gtk2::IconSize->lookup('menu')));
2795
 
                        my $small_image_button = Gtk2::Image->new_from_pixbuf( $small_image->get_pixbuf );
2796
 
 
2797
 
                        #create items
2798
 
                        my $new_item = Gtk2::ImageMenuItem->new_with_label($short);
2799
 
                        $new_item->set_image($small_image);
2800
 
 
2801
 
                        #~ &fct_load_pixbuf_async ($small_image, $filename, $new_item);
2802
 
 
2803
 
                        #init
2804
 
                        unless ( $button->get_icon_widget ) {
2805
 
                                $button->set_icon_widget($small_image_button);
2806
 
                                $self->{_current_pixbuf} = $orig_pixbuf->copy;
2807
 
                                $self->{_current_pixbuf_filename} = $filename;
2808
 
                        }
2809
 
 
2810
 
                        $new_item->signal_connect(
2811
 
                                'activate' => sub {
2812
 
                                        $self->{_current_pixbuf} = $orig_pixbuf->copy;
2813
 
                                        $self->{_current_pixbuf_filename} = $filename;
2814
 
                                        $button->set_icon_widget($small_image_button);
2815
 
                                        $button->show_all;
2816
 
                                        $self->{_canvas}->window->set_cursor( $self->change_cursor_to_current_pixbuf );
2817
 
                                }
2818
 
                        );
2819
 
 
2820
 
                        $menu_objects->append($new_item);
2821
 
                        
2822
 
                }else{
2823
 
                        my $response = $self->{_dialogs}->dlg_error_message( 
2824
 
                                sprintf( $d->get("Error while opening image %s."), "'" . $filename . "'" ),
2825
 
                                $d->get( "There was an error opening the image." ),
2826
 
                                undef, undef, undef,
2827
 
                                undef, undef, undef,
2828
 
                                $@
2829
 
                        );              
2830
 
                } 
2831
 
 
2832
 
        }
2833
 
 
2834
 
        $menu_objects->append( Gtk2::SeparatorMenuItem->new );
2835
 
 
2836
 
        #objects from session
2837
 
        my $session_menu_item = Gtk2::MenuItem->new_with_label( $d->get("Import from session...") );
2838
 
        $session_menu_item->set_submenu( $self->import_from_session($button) );
2839
 
 
2840
 
        $menu_objects->append($session_menu_item);
2841
 
 
2842
 
        #objects from filesystem
2843
 
        my $filesystem_menu_item = Gtk2::MenuItem->new_with_label( $d->get("Import from filesystem...") );
2844
 
        $filesystem_menu_item->signal_connect(
2845
 
                'activate' => sub {
2846
 
 
2847
 
                        my $fs = Gtk2::FileChooserDialog->new(
2848
 
                                $d->get("Choose file to open"), $self->{_drawing_window}, 'open',
2849
 
                                'gtk-cancel' => 'reject',
2850
 
                                'gtk-open'   => 'accept'
2851
 
                        );
2852
 
 
2853
 
                        $fs->set_select_multiple(FALSE);
2854
 
 
2855
 
                        my $filter_all = Gtk2::FileFilter->new;
2856
 
                        $filter_all->set_name( $d->get("All compatible image formats") );
2857
 
                        $fs->add_filter($filter_all);
2858
 
 
2859
 
                        foreach ( Gtk2::Gdk::Pixbuf->get_formats ) {
2860
 
                                my $filter = Gtk2::FileFilter->new;
2861
 
                                $filter->set_name( $_->{name} . " - " . $_->{description} );
2862
 
                                foreach ( @{ $_->{extensions} } ) {
2863
 
                                        $filter->add_pattern( "*." . uc $_ );
2864
 
                                        $filter_all->add_pattern( "*." . uc $_ );
2865
 
                                        $filter->add_pattern( "*." . $_ );
2866
 
                                        $filter_all->add_pattern( "*." . $_ );
2867
 
                                }
2868
 
                                $fs->add_filter($filter);
2869
 
                        }
2870
 
 
2871
 
                        if ( $ENV{'HOME'} ) {
2872
 
                                $fs->set_current_folder( $ENV{'HOME'} );
2873
 
                        }
2874
 
                        my $fs_resp = $fs->run;
2875
 
 
2876
 
                        my $new_file;
2877
 
                        if ( $fs_resp eq "accept" ) {
2878
 
                                $new_file = $fs->get_filenames;
2879
 
 
2880
 
                                #create pixbufs
2881
 
                                my $small_image        = Gtk2::Image->new_from_stock( 'gtk-new', 'menu' );
2882
 
                                my $small_image_button = Gtk2::Image->new_from_stock( 'gtk-new', 'menu' );
2883
 
                                
2884
 
                                my $orig_pixbuf;
2885
 
                                eval{
2886
 
                                        $orig_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($new_file);     
2887
 
                                };
2888
 
                                #check if there is any error while loading this file
2889
 
                                unless($@){
2890
 
                                        $self->{_current_pixbuf}          = $orig_pixbuf->copy;
2891
 
                                        $self->{_current_pixbuf_filename} = $new_file;
2892
 
                                        $button->set_icon_widget($small_image_button);
2893
 
                                        $button->show_all;
2894
 
                                        $self->{_canvas}->window->set_cursor( $self->change_cursor_to_current_pixbuf );
2895
 
                                }else{
2896
 
                                        my $response = $self->{_dialogs}->dlg_error_message( 
2897
 
                                                sprintf( $d->get("Error while opening image %s."), "'" . $new_file. "'"),
2898
 
                                                $d->get( "There was an error opening the image." ),
2899
 
                                                undef, undef, undef,
2900
 
                                                undef, undef, undef,
2901
 
                                                $@
2902
 
                                        );                                                                                      
2903
 
                                }
2904
 
                                
2905
 
                                $fs->destroy();
2906
 
                        } else {
2907
 
                                $fs->destroy();
2908
 
                        }
2909
 
 
2910
 
                }
2911
 
        );
2912
 
 
2913
 
        $menu_objects->append($filesystem_menu_item);
 
4682
                my ( $short, $folder, $type ) = fileparse( $name, '\..*' );
 
4683
                
 
4684
                #if current object is a directory we call the current sub
 
4685
                #recursively
 
4686
                if(-d $name){
 
4687
                                                        
 
4688
                        #objects from each directory are sorted (files first)
 
4689
                        #we display a separator when the first directory is listed
 
4690
                        if($fd && $ff){
 
4691
                                $menu_objects->append( Gtk2::SeparatorMenuItem->new );
 
4692
                                $fd = FALSE;
 
4693
                        }
 
4694
                        
 
4695
                        #objects from directory $name
 
4696
                        my $subdir_item = Gtk2::ImageMenuItem->new_with_label( $short );
 
4697
                        $subdir_item->set_image (Gtk2::Image->new_from_stock ('gtk-directory', 'menu'));
 
4698
                
 
4699
                        #add empty menu first
 
4700
                        my $menu_empty = Gtk2::Menu->new;
 
4701
                        my $empty_item = Gtk2::MenuItem->new_with_label( $self->{_d}->get("No icon was found") );
 
4702
                        $empty_item->set_sensitive(FALSE);
 
4703
                        $menu_empty->append($empty_item);
 
4704
                        $subdir_item->set_submenu( $menu_empty );
 
4705
                        
 
4706
                        #and populate later (performance)
 
4707
                        $subdir_item->{'nid'} = $subdir_item->signal_connect('activate' => sub {
 
4708
                                        $subdir_item->set_image(Gtk2::Image->new_from_file($self->{_icons}."/throbber_16x16.gif"));
 
4709
                                        my $submenu = $self->import_from_filesystem($button, $subdir_item, $dobjects . "/$short");
 
4710
                                        
 
4711
                                        if($submenu->get_children){
 
4712
                                        
 
4713
                                                $subdir_item->set_submenu( $submenu );
 
4714
                                        
 
4715
                                        }else{
 
4716
                                                
 
4717
                                                $subdir_item->set_image (Gtk2::Image->new_from_stock ('gtk-directory', 'menu'));                
 
4718
                                        
 
4719
                                        }
 
4720
                                        
 
4721
                                        return TRUE;
 
4722
                                }
 
4723
                        );
 
4724
                        
 
4725
                        #diconnect handler when this event occurs
 
4726
                        $subdir_item->signal_connect('leave-notify-event' => sub {
 
4727
                                        if($subdir_item->signal_handler_is_connected ($subdir_item->{'nid'})){
 
4728
                                                $subdir_item->signal_handler_disconnect($subdir_item->{'nid'});
 
4729
                                        }
 
4730
                                }
 
4731
                        );
 
4732
                        $menu_objects->append($subdir_item);
 
4733
                        next;
 
4734
                }
 
4735
                
 
4736
                #there is at least one single file
 
4737
                #set the flag
 
4738
                $ff = TRUE;
 
4739
                
 
4740
                #init item with filename first
 
4741
                my $new_item = Gtk2::ImageMenuItem->new_with_label($short);
 
4742
                $menu_objects->append($new_item);
 
4743
                
 
4744
                #sfsdc
 
4745
                $new_item->{'name'} = $name;
 
4746
 
 
4747
        }
 
4748
        
 
4749
        #do not do that when called recursively
 
4750
        #top level call
 
4751
        unless($directory){
 
4752
 
 
4753
                $menu_objects->append( Gtk2::SeparatorMenuItem->new );
 
4754
 
 
4755
                #objects from icontheme         
 
4756
                if (Gtk2->CHECK_VERSION( 2, 12, 0 )){
 
4757
                        my $icontheme = Gtk2::IconTheme->get_default;
 
4758
                        
 
4759
                        my $utheme_item = Gtk2::ImageMenuItem->new_with_label( $self->{_d}->get("Import from current theme...") );              
 
4760
                        if($icontheme->has_icon('preferences-desktop-theme')){
 
4761
                                $utheme_item->set_image(Gtk2::Image->new_from_icon_name( 'preferences-desktop-theme', 'menu' ));                
 
4762
                        }
 
4763
                        
 
4764
                        $utheme_item->set_submenu( $self->import_from_utheme($icontheme, $button) );
 
4765
                        
 
4766
                        $menu_objects->append( $utheme_item );
 
4767
 
 
4768
                        $menu_objects->append( Gtk2::SeparatorMenuItem->new );
 
4769
                }
 
4770
                
 
4771
                #objects from session
 
4772
                my $session_menu_item = Gtk2::ImageMenuItem->new_with_label( $self->{_d}->get("Import from session...") );
 
4773
                $session_menu_item->set_image (Gtk2::Image->new_from_stock ('gtk-index', 'menu'));
 
4774
                $session_menu_item->set_submenu( $self->import_from_session($button) );
 
4775
 
 
4776
                #gen thumbnails in an idle callback
 
4777
                $self->gen_thumbnail_on_idle('gtk-index', $session_menu_item, $button, TRUE, $session_menu_item->get_submenu->get_children);    
 
4778
 
 
4779
                $menu_objects->append($session_menu_item);
 
4780
 
 
4781
                #objects from filesystem
 
4782
                my $filesystem_menu_item = Gtk2::ImageMenuItem->new_with_label( $self->{_d}->get("Import from filesystem...") );
 
4783
                $filesystem_menu_item->set_image (Gtk2::Image->new_from_stock ('gtk-open', 'menu'));
 
4784
                $filesystem_menu_item->signal_connect(
 
4785
                        'activate' => sub {
 
4786
 
 
4787
                                my $fs = Gtk2::FileChooserDialog->new(
 
4788
                                        $self->{_d}->get("Choose file to open"), $self->{_drawing_window}, 'open',
 
4789
                                        'gtk-cancel' => 'reject',
 
4790
                                        'gtk-open'   => 'accept'
 
4791
                                );
 
4792
 
 
4793
                                $fs->set_select_multiple(FALSE);
 
4794
 
 
4795
                                my $filter_all = Gtk2::FileFilter->new;
 
4796
                                $filter_all->set_name( $self->{_d}->get("All compatible image formats") );
 
4797
                                $fs->add_filter($filter_all);
 
4798
 
 
4799
                                foreach ( Gtk2::Gdk::Pixbuf->get_formats ) {
 
4800
                                        my $filter = Gtk2::FileFilter->new;
 
4801
                                        $filter->set_name( $_->{name} . " - " . $_->{description} );
 
4802
                                        foreach ( @{ $_->{extensions} } ) {
 
4803
                                                $filter->add_pattern( "*." . uc $_ );
 
4804
                                                $filter_all->add_pattern( "*." . uc $_ );
 
4805
                                                $filter->add_pattern( "*." . $_ );
 
4806
                                                $filter_all->add_pattern( "*." . $_ );
 
4807
                                        }
 
4808
                                        $fs->add_filter($filter);
 
4809
                                }
 
4810
 
 
4811
                                if ( $ENV{'HOME'} ) {
 
4812
                                        $fs->set_current_folder( $ENV{'HOME'} );
 
4813
                                }
 
4814
                                my $fs_resp = $fs->run;
 
4815
 
 
4816
                                my $new_file;
 
4817
                                if ( $fs_resp eq "accept" ) {
 
4818
                                        $new_file = $fs->get_filenames;
 
4819
                                
 
4820
                                        eval{
 
4821
                                                $self->{_current_pixbuf} = Gtk2::Gdk::Pixbuf->new_from_file($new_file); 
 
4822
                                        };
 
4823
                                        #check if there is any error while loading this file
 
4824
                                        unless($@){
 
4825
                                                $self->{_current_pixbuf_filename} = $new_file;
 
4826
                                                $button->set_icon_widget(Gtk2::Image->new_from_pixbuf(Gtk2::Gdk::Pixbuf->new_from_file_at_size($self->{_dicons}.'/draw-image.svg', Gtk2::IconSize->lookup('menu'))));
 
4827
                                                $button->show_all;
 
4828
                                                $self->{_canvas}->window->set_cursor( $self->change_cursor_to_current_pixbuf );
 
4829
                                        }else{
 
4830
                                                my $response = $self->{_dialogs}->dlg_error_message( 
 
4831
                                                        sprintf( $self->{_d}->get("Error while opening image %s."), "'" . $new_file. "'"),
 
4832
                                                        $self->{_d}->get( "There was an error opening the image." ),
 
4833
                                                        undef, undef, undef,
 
4834
                                                        undef, undef, undef,
 
4835
                                                        $@
 
4836
                                                );
 
4837
                                                $self->abort_current_mode;                                                                                      
 
4838
                                        }
 
4839
                                        
 
4840
                                        $fs->destroy();
 
4841
                                } else {
 
4842
                                        $fs->destroy();
 
4843
                                }
 
4844
 
 
4845
                        }
 
4846
                );
 
4847
 
 
4848
                $menu_objects->append($filesystem_menu_item);
 
4849
        
 
4850
        }
2914
4851
 
2915
4852
        $button->show_all;
2916
4853
        $menu_objects->show_all;
2917
4854
 
 
4855
        #generate thumbnails in an idle callback
 
4856
        $self->gen_thumbnail_on_idle('gtk-directory', $parent, $button, FALSE, $menu_objects->get_children);
 
4857
                        
2918
4858
        return $menu_objects;
2919
4859
}
2920
4860
 
2921
 
#~ sub fct_load_pixbuf_async {
2922
 
#~ 
2923
 
        #~ print Dumper @_;
2924
 
#~ 
2925
 
#~ 
2926
 
        #~ my $image = shift;
2927
 
        #~ my $filename = shift;
2928
 
        #~ my $menu_item = shift;
2929
 
        #~ 
2930
 
        #~ my $loader = Gtk2::Gdk::PixbufLoader->new;
2931
 
        #~ my $handle = Gnome2::VFS::Async->open_uri (Gnome2::VFS::URI->new ($filename), 'read', 10, \&fct_open_async, $loader);        
2932
 
#~ 
2933
 
        #~ $loader->signal_connect('closed' => sub{
2934
 
                #~ print "closed\n";
2935
 
                #~ $image->set_from_pixbuf($loader->get_pixbuf);
2936
 
                #~ $menu_item->set_image($image);
2937
 
                #~ $image->show_all;
2938
 
                #~ $menu_item->show_all;
2939
 
#~ 
2940
 
        #~ });
2941
 
        #~ $loader->signal_connect('area-updated' => sub{
2942
 
                #~ print "updated\n";
2943
 
                #~ $image->set_from_pixbuf($loader->get_pixbuf);
2944
 
                #~ $image->show_all;
2945
 
                #~ $menu_item->set_image($image);
2946
 
                #~ $menu_item->show_all;
2947
 
#~ 
2948
 
        #~ });          
2949
 
        #~ 
2950
 
#~ }
2951
 
#~ 
2952
 
#~ sub fct_open_async {
2953
 
#~ 
2954
 
        #~ print Dumper @_;
2955
 
#~ 
2956
 
        #~ my $handle = shift;
2957
 
        #~ my $result = shift;
2958
 
        #~ my $loader = shift;
2959
 
        #~ 
2960
 
        #~ if($result eq 'ok'){
2961
 
                #~ $handle->read (10000, \&fct_read_async, $loader); 
2962
 
        #~ }else{
2963
 
                #~ print "Error!\n";
2964
 
                #~ $handle->close(\&fct_close_async, $loader);  
2965
 
#~ 
2966
 
        #~ }
2967
 
#~ }
2968
 
#~ 
2969
 
#~ sub fct_read_async {
2970
 
#~ 
2971
 
        #~ print Dumper @_;
2972
 
#~ 
2973
 
        #~ my $handle = shift;
2974
 
        #~ my $result = shift;
2975
 
        #~ my $buffer = shift;
2976
 
        #~ my $size = shift;
2977
 
        #~ my $size2 = shift;
2978
 
        #~ my $loader = shift;
2979
 
#~ 
2980
 
        #~ if($result eq 'ok'){
2981
 
                #~ $loader->write($buffer);
2982
 
                #~ $handle->read(10000, \&fct_read_async, $loader);     
2983
 
        #~ }else{
2984
 
                #~ $handle->close(\&fct_close_async, $loader);  
2985
 
        #~ }
2986
 
#~ }
2987
 
#~ 
2988
 
#~ sub fct_close_async {
2989
 
#~ 
2990
 
        #~ print Dumper @_;
2991
 
#~ 
2992
 
        #~ my $handle = shift;
2993
 
        #~ my $result = shift;
2994
 
        #~ my $loader = shift;
2995
 
        #~ 
2996
 
        #~ $loader->close;
2997
 
#~ 
2998
 
#~ }
 
4861
sub import_from_utheme {
 
4862
        my $self                = shift;
 
4863
        my $icontheme   = shift;
 
4864
        my $button              = shift;
 
4865
 
 
4866
        my $menu_ctxt = Gtk2::Menu->new;
 
4867
 
 
4868
        foreach my $context (sort $icontheme->list_contexts){
 
4869
                                        
 
4870
                #objects from current theme (contexts)
 
4871
                my $utheme_ctxt = Gtk2::ImageMenuItem->new_with_label( $context );
 
4872
                $utheme_ctxt->set_image (Gtk2::Image->new_from_stock ('gtk-directory', 'menu'));
 
4873
                        
 
4874
                #add empty menu first
 
4875
                my $menu_empty = Gtk2::Menu->new;
 
4876
                my $empty_item = Gtk2::MenuItem->new_with_label( $self->{_d}->get("No icon was found") );
 
4877
                $empty_item->set_sensitive(FALSE);
 
4878
                $menu_empty->append($empty_item);
 
4879
                $utheme_ctxt->set_submenu( $menu_empty );
 
4880
                        
 
4881
                #and populate later (performance)
 
4882
                my @menu_items;
 
4883
                $utheme_ctxt->{'nid'} = $utheme_ctxt->signal_connect('activate' => sub {
 
4884
                                
 
4885
                        $utheme_ctxt->set_image(Gtk2::Image->new_from_file($self->{_icons}."/throbber_16x16.gif"));                             
 
4886
                        my $context_submenu = $self->import_from_utheme_ctxt($icontheme, $context, $button);
 
4887
                        
 
4888
                        if($context_submenu->get_children){
 
4889
                                
 
4890
                                $utheme_ctxt->set_submenu( $context_submenu );
 
4891
                
 
4892
                                #gen thumbnails in an idle callback
 
4893
                                $self->gen_thumbnail_on_idle('gtk-directory', $utheme_ctxt, $button, TRUE, $utheme_ctxt->get_submenu->get_children);
 
4894
                        
 
4895
                        }else{
 
4896
                                $utheme_ctxt->set_image (Gtk2::Image->new_from_stock ('gtk-directory', 'menu'));        
 
4897
                        }                       
 
4898
                                                
 
4899
                        return TRUE;
 
4900
                });
 
4901
                
 
4902
                #disconnect handler when this event occurs
 
4903
                $utheme_ctxt->signal_connect('leave-notify-event' => sub {
 
4904
                                if($utheme_ctxt->signal_handler_is_connected ($utheme_ctxt->{'nid'})){                                  
 
4905
                                        $utheme_ctxt->signal_handler_disconnect($utheme_ctxt->{'nid'});
 
4906
                                }
 
4907
                        }
 
4908
                );
 
4909
                
 
4910
                $menu_ctxt->append($utheme_ctxt);
 
4911
 
 
4912
        }
 
4913
 
 
4914
        $menu_ctxt->show_all;
 
4915
 
 
4916
        return $menu_ctxt;                      
 
4917
}
 
4918
 
 
4919
sub import_from_utheme_ctxt {
 
4920
        my $self                = shift;
 
4921
        my $icontheme   = shift;
 
4922
        my $context     = shift;
 
4923
        my $button              = shift;
 
4924
        
 
4925
        my $menu_ctxt_items = Gtk2::Menu->new;
 
4926
        
 
4927
        my $size = Gtk2::IconSize->lookup('dialog');
 
4928
        
 
4929
        foreach my $icon (sort $icontheme->list_icons($context)){
 
4930
                        
 
4931
                #objects from current theme (icons for specific contexts)
 
4932
                my $utheme_ctxt_item = Gtk2::ImageMenuItem->new_with_label( $icon );
 
4933
                my $iconinfo = $icontheme->lookup_icon ($icon, $size, 'generic-fallback');
 
4934
                
 
4935
                #save filename and generate thumbnail later
 
4936
                #idle callback  
 
4937
                $utheme_ctxt_item->{'name'} = $iconinfo->get_filename;
 
4938
                
 
4939
                $menu_ctxt_items->append($utheme_ctxt_item);    
 
4940
        }
 
4941
        
 
4942
        $menu_ctxt_items->show_all;
 
4943
 
 
4944
        return $menu_ctxt_items;                
 
4945
}
2999
4946
 
3000
4947
sub import_from_session {
3001
 
        my $self                 = shift;
3002
 
        my $button               = shift;
 
4948
        my $self        = shift;
 
4949
        my $button  = shift;
 
4950
        
3003
4951
        my $menu_session_objects = Gtk2::Menu->new;
3004
4952
 
3005
 
        my $d = $self->{_shutter_common}->get_gettext;
3006
 
 
3007
4953
        my %import_hash = %{ $self->{_import_hash} };
3008
4954
 
3009
 
        foreach my $key ( sort keys %import_hash ) {
3010
 
 
3011
 
                my $orig_pixbuf;
3012
 
                eval{
3013
 
                        $orig_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file( $import_hash{$key}->{'long'} );
3014
 
                };
3015
 
                unless($@){
3016
 
 
3017
 
                        #try to generate a new thumbnail
3018
 
                        my $thumb = $self->{_thumbs}->get_thumbnail(
3019
 
                                $import_hash{$key}->{'uri'}->to_string,
3020
 
                                $import_hash{$key}->{'mime_type'},
3021
 
                                $import_hash{$key}->{'mtime'},
3022
 
                                0.2
3023
 
                        );                      
3024
 
 
3025
 
                        my $small_image = Gtk2::Image->new_from_pixbuf( $thumb );
3026
 
                        #~ my $small_image_button = Gtk2::Image->new_from_pixbuf( $orig_pixbuf->scale_down_pixbuf (Gtk2::IconSize->lookup('menu')));
3027
 
                        my $small_image_button = Gtk2::Image->new_from_pixbuf( $small_image->get_pixbuf );
3028
 
 
3029
 
                        my $screen_menu_item = Gtk2::ImageMenuItem->new_with_label( $import_hash{$key}->{'short'} );
3030
 
                        $screen_menu_item->set_image($small_image);
3031
 
 
3032
 
                        #set sensitive == FALSE if image eq current file
3033
 
                        $screen_menu_item->set_sensitive(FALSE)
3034
 
                                if $import_hash{$key}->{'long'} eq $self->{_filename};
3035
 
 
3036
 
                        $screen_menu_item->signal_connect(
3037
 
                                'activate' => sub {
3038
 
                                        $self->{_current_pixbuf}          = $orig_pixbuf->copy;
3039
 
                                        $self->{_current_pixbuf_filename} = $import_hash{$key}->{'long'};
3040
 
                                        $button->set_icon_widget($small_image_button);
3041
 
                                        $button->show_all;
3042
 
                                        $self->{_canvas}->window->set_cursor( $self->change_cursor_to_current_pixbuf );
3043
 
                                }
3044
 
                        );
3045
 
 
3046
 
                        $menu_session_objects->append($screen_menu_item);
3047
 
 
3048
 
                }else{
3049
 
                        my $response = $self->{_dialogs}->dlg_error_message( 
3050
 
                                sprintf( $d->get("Error while opening image %s."), "'" . $import_hash{$key}->{'long'} . "'" ),
3051
 
                                $d->get( "There was an error opening the image." ),
3052
 
                                undef, undef, undef,
3053
 
                                undef, undef, undef,
3054
 
                                $@
3055
 
                        );                              
3056
 
                }
3057
 
 
 
4955
        foreach my $key ( Sort::Naturally::nsort(keys %import_hash) ) {
 
4956
 
 
4957
                #init item with filename
 
4958
                my $screen_menu_item = Gtk2::ImageMenuItem->new_with_label( $import_hash{$key}->{'short'} );
 
4959
 
 
4960
                #set sensitive == FALSE if image eq current file
 
4961
                $screen_menu_item->set_sensitive(FALSE)
 
4962
                        if $import_hash{$key}->{'long'} eq $self->{_filename};
 
4963
                
 
4964
                #save filename and attributes
 
4965
                $screen_menu_item->{'name'}             = $import_hash{$key}->{'long'};
 
4966
                $screen_menu_item->{'mime_type'}        = $import_hash{$key}->{'mime_type'};
 
4967
                $screen_menu_item->{'mtime'}            = $import_hash{$key}->{'mtime'};
 
4968
                $screen_menu_item->{'uri'}                      = $import_hash{$key}->{'uri'};
 
4969
        
 
4970
                $menu_session_objects->append($screen_menu_item);
3058
4971
        }
3059
4972
 
3060
4973
        $menu_session_objects->show_all;
3062
4975
        return $menu_session_objects;
3063
4976
}
3064
4977
 
 
4978
sub gen_thumbnail_on_idle {
 
4979
        my $self                = shift;
 
4980
        my $stock               = shift;
 
4981
        my $parent              = shift;
 
4982
        my $button              = shift;
 
4983
        my $no_init             = shift;
 
4984
        my @menu_items  = @_;
 
4985
        
 
4986
        #generate thumbnails in an idle callback
 
4987
        my $next_item = 0;
 
4988
        Glib::Idle->add(sub{
 
4989
                
 
4990
                #get next item
 
4991
                my $child = $menu_items[$next_item];
 
4992
                
 
4993
                #no valid item - stop the idle handler                          
 
4994
                unless ($child){                                                
 
4995
                        $parent->set_image (Gtk2::Image->new_from_stock ($stock, 'menu')) if $parent;
 
4996
                        return FALSE;
 
4997
                }
 
4998
                
 
4999
                my $name = $child->{'name'};
 
5000
 
 
5001
                #no valid item - stop the idle handler  
 
5002
                unless ($name){                                         
 
5003
                        $parent->set_image (Gtk2::Image->new_from_stock ($stock, 'menu')) if $parent;
 
5004
                        return FALSE;
 
5005
                }
 
5006
                
 
5007
                #increment counter
 
5008
                $next_item++;
 
5009
                                                                
 
5010
                #create thumbnail
 
5011
                my $small_image;
 
5012
                eval{
 
5013
                        #if uri exists we generate a thumbnail
 
5014
                        #with Shutter::Pixbuf::Thumbnail
 
5015
                        if(exists $child->{'uri'}){
 
5016
                                $small_image = Gtk2::Image->new_from_pixbuf( $self->{_thumbs}->get_thumbnail(
 
5017
                                        $child->{'uri'}->to_string,
 
5018
                                        $child->{'mime_type'},
 
5019
                                        $child->{'mtime'},
 
5020
                                        0.2
 
5021
                                ));                                     
 
5022
                        }else{ 
 
5023
                                my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file ($name);
 
5024
                                #16x16 is minimum size
 
5025
                                if($pixbuf->get_width >= 16 && $pixbuf->get_height >= 16){
 
5026
                                        $small_image = Gtk2::Image->new_from_pixbuf( 
 
5027
                                                $pixbuf->scale_down_pixbuf(Gtk2::IconSize->lookup('menu'))
 
5028
                                        );
 
5029
                                }
 
5030
                        }
 
5031
                };
 
5032
                unless($@){
 
5033
                        if($small_image){
 
5034
                                $child->set_image($small_image);
 
5035
 
 
5036
                                #init when toplevel
 
5037
                                unless ($no_init) {
 
5038
                                        unless($button->get_icon_widget){
 
5039
                                                $button->set_icon_widget(Gtk2::Image->new_from_pixbuf($small_image->get_pixbuf));
 
5040
                                                $self->{_current_pixbuf_filename} = $name;
 
5041
                                                $button->show_all;
 
5042
                                        }
 
5043
                                }
 
5044
 
 
5045
                                $child->signal_connect(
 
5046
                                        'activate' => sub {                                     
 
5047
                                                $self->{_current_pixbuf_filename} = $name;
 
5048
                                                $button->set_icon_widget(Gtk2::Image->new_from_pixbuf($small_image->get_pixbuf));
 
5049
                                                $button->show_all;
 
5050
                                                $self->{_canvas}->window->set_cursor( $self->change_cursor_to_current_pixbuf );
 
5051
                                        }
 
5052
                                );
 
5053
                        }else{
 
5054
                                $child->destroy;
 
5055
                        }
 
5056
                }else{
 
5057
                        $child->destroy;
 
5058
                }
 
5059
                
 
5060
                return TRUE;
 
5061
        });#end idle callback
 
5062
 
 
5063
}
 
5064
 
3065
5065
sub set_drawing_action {
3066
5066
        my $self  = shift;
3067
5067
        my $index = shift;
3068
5068
 
 
5069
        #~ print "set_drawing_action\n";
 
5070
                
 
5071
        my $item_index = 0;
3069
5072
        my $toolbar = $self->{_uimanager}->get_widget("/ToolBarDrawing");
3070
5073
        for ( my $i = 0; $i < $toolbar->get_n_items; $i++ ) {
3071
 
                my $item       = $toolbar->get_nth_item($i);
3072
 
                my $item_index = $toolbar->get_item_index($item);
3073
 
                $item->set_active(TRUE) if $item_index == $index;
 
5074
                my $item = $toolbar->get_nth_item($i);
 
5075
                
 
5076
                #skip separators
 
5077
                #we only want to activate tools
 
5078
                next if $item->isa('Gtk2::SeparatorToolItem');
 
5079
 
 
5080
                #add 1 to item index
 
5081
                $item_index++;
 
5082
                
 
5083
                if ($item_index == $index){
 
5084
                        if($item->get_active){
 
5085
                                $self->change_drawing_tool_cb($item_index*10);
 
5086
                        }else{
 
5087
                                $item->set_active(TRUE);                                
 
5088
                        }
 
5089
                        last;
 
5090
                }
3074
5091
        }
3075
5092
 
3076
5093
}
3078
5095
sub change_cursor_to_current_pixbuf {
3079
5096
        my $self = shift;
3080
5097
 
 
5098
        #~ print "change_cursor_to_current_pixbuf\n";
 
5099
 
3081
5100
        $self->{_current_mode_descr} = "image";
3082
5101
 
3083
 
        #define own icons
3084
 
        my $dicons = $self->{_shutter_common}->get_root . "/share/shutter/resources/icons/drawing_tool";
3085
5102
        my $cursor = undef; 
3086
5103
        
3087
 
        #very big image usually don't work as a cursor (no error though??)
3088
 
        if($self->{_current_pixbuf}->get_width < 1000 && $self->{_current_pixbuf}->get_height < 1000 ){
3089
 
                my $cpixbuf = Gtk2::Gdk::Pixbuf->new_from_file_at_scale($self->{_current_pixbuf_filename}, Gtk2::Gdk::Display->get_default->get_maximal_cursor_size, TRUE);
3090
 
                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf( Gtk2::Gdk::Display->get_default, $cpixbuf, undef, undef );
 
5104
        #load file
 
5105
        eval{
 
5106
                $self->{_current_pixbuf} = Gtk2::Gdk::Pixbuf->new_from_file($self->{_current_pixbuf_filename});
 
5107
        };                              
 
5108
        if($@){
 
5109
                my $response = $self->{_dialogs}->dlg_error_message( 
 
5110
                        sprintf( $self->{_d}->get("Error while opening image %s."), "'" . $self->{_current_pixbuf_filename} . "'" ),
 
5111
                        $self->{_d}->get( "There was an error opening the image." ),
 
5112
                        undef, undef, undef,
 
5113
                        undef, undef, undef,
 
5114
                        $@
 
5115
                );
 
5116
                $self->abort_current_mode;      
 
5117
                return FALSE;   
 
5118
        }
 
5119
        
 
5120
        #very big images usually don't work as a cursor (no error though??)
 
5121
        my $pb_w = $self->{_current_pixbuf}->get_width;
 
5122
        my $pb_h = $self->{_current_pixbuf}->get_height;
 
5123
        
 
5124
        if($pb_w < 800 && $pb_h < 800){
 
5125
                eval{
 
5126
                                                
 
5127
                        #maximum cursor size
 
5128
                        my ($cw, $ch) = Gtk2::Gdk::Display->get_default->get_maximal_cursor_size;
 
5129
                        
 
5130
                        #images smaller than max cursor size? 
 
5131
                        # => don't scale to a bigger size
 
5132
                        if($cw > $pb_w || $ch > $pb_w){
 
5133
                                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf( Gtk2::Gdk::Display->get_default, $self->{_current_pixbuf}, int($pb_w / 2), int($pb_h / 2));                               
 
5134
                        }else{
 
5135
                                my $cpixbuf = Gtk2::Gdk::Pixbuf->new_from_file_at_scale($self->{_current_pixbuf_filename}, $cw, $ch, TRUE);     
 
5136
                                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf( Gtk2::Gdk::Display->get_default, $cpixbuf, int($cpixbuf->get_width / 2), int($cpixbuf->get_height / 2));
 
5137
                        }
 
5138
                        
 
5139
                };                              
 
5140
                if($@){
 
5141
                        my $response = $self->{_dialogs}->dlg_error_message( 
 
5142
                                sprintf( $self->{_d}->get("Error while opening image %s."), "'" . $self->{_current_pixbuf_filename} . "'" ),
 
5143
                                $self->{_d}->get( "There was an error opening the image." ),
 
5144
                                undef, undef, undef,
 
5145
                                undef, undef, undef,
 
5146
                                $@
 
5147
                        );
 
5148
                        $self->abort_current_mode;              
 
5149
                }
3091
5150
        }else{
3092
5151
                $cursor = Gtk2::Gdk::Cursor->new_from_pixbuf(
3093
5152
                                Gtk2::Gdk::Display->get_default,
3094
 
                                Gtk2::Gdk::Pixbuf->new_from_file("$dicons/draw-image.svg"),
 
5153
                                Gtk2::Gdk::Pixbuf->new_from_file($self->{_dicons}.'/draw-image.svg'),
3095
5154
                                Gtk2::IconSize->lookup('menu')
3096
5155
                );              
3097
5156
        }
3112
5171
        
3113
5172
        my $child = $self->get_child_item($item);
3114
5173
        
 
5174
        my $new_item = undef;
3115
5175
        if ( $item->isa('Goo::Canvas::Rect') && !$child ) {
3116
5176
                #~ print "Creating Rectangle...\n";
3117
 
                $self->create_rectangle( undef, $item );
 
5177
                $new_item = $self->create_rectangle( undef, $item );
3118
5178
        }elsif ( $item->isa('Goo::Canvas::Polyline') && !$child ){
3119
5179
                #~ print "Creating Polyline...\n";
3120
 
                $self->create_polyline( undef, $item );
 
5180
                $new_item = $self->create_polyline( undef, $item );
3121
5181
        }elsif ( $child->isa('Goo::Canvas::Polyline') && exists $self->{_items}{$item}{stroke_color} ){
3122
5182
                #~ print "Creating Line...\n";
3123
 
                $self->create_line( undef, $item );
 
5183
                $new_item = $self->create_line( undef, $item );
3124
5184
        }elsif ( $child->isa('Goo::Canvas::Polyline') ){
3125
5185
                #~ print "Creating Censor...\n";
3126
 
                $self->create_censor( undef, $item );
 
5186
                $new_item = $self->create_censor( undef, $item );
3127
5187
        }elsif ( $child->isa('Goo::Canvas::Ellipse') ){
3128
5188
                #~ print "Creating Ellipse...\n";
3129
 
                $self->create_ellipse( undef, $item);
 
5189
                $new_item = $self->create_ellipse( undef, $item);
3130
5190
        }elsif ( $child->isa('Goo::Canvas::Text') ){
3131
5191
                #~ print "Creating Text...\n";
3132
 
                $self->create_text( undef, $item );
 
5192
                $new_item = $self->create_text( undef, $item );
3133
5193
        }elsif ( $child->isa('Goo::Canvas::Image') ){
3134
5194
                #~ print "Creating Image...\n";
3135
 
                $self->create_image( undef, $item );
 
5195
                $new_item = $self->create_image( undef, $item );
3136
5196
        }       
3137
5197
 
3138
5198
        #cut instead of copy
3142
5202
                $self->{_current_copy_item} = undef;
3143
5203
        }
3144
5204
 
 
5205
        #add to undo stack
 
5206
        $self->store_to_xdo_stack($new_item , 'create', 'undo');
 
5207
 
3145
5208
        return TRUE;
3146
5209
}       
3147
5210
 
3148
5211
sub create_polyline {
3149
 
        my $self      = shift;
3150
 
        my $ev        = shift;
3151
 
        my $copy_item = shift;
 
5212
        my $self        = shift;
 
5213
        my $ev          = shift;
 
5214
        my $copy_item   = shift;
 
5215
        
 
5216
        #this is a highlighter? 
 
5217
        #we need different default values in this case
 
5218
        my $highlighter = shift;
3152
5219
 
3153
5220
        my @points = ();
3154
5221
        my $stroke_pattern = $self->create_color( $self->{_stroke_color}, $self->{_stroke_color_alpha} );
3157
5224
        
3158
5225
        #use event coordinates
3159
5226
        if ($ev) {
3160
 
                @points = ( $ev->x, $ev->y, $ev->x, $ev->y );
 
5227
                @points = ( $ev->x_root, $ev->y_root, $ev->x_root, $ev->y_root );
3161
5228
        #use source item coordinates
3162
5229
        } elsif ($copy_item) {
3163
5230
                foreach(@{$self->{_items}{$copy_item}{points}}){
3169
5236
                $line_width = $self->{_items}{$copy_item}->get('line_width');
3170
5237
        }
3171
5238
 
3172
 
        my $item = Goo::Canvas::Polyline->new_line(
3173
 
                $self->{_canvas}->get_root_item, $points[0],$points[1],$points[2],$points[3],
3174
 
                'stroke-pattern' => $stroke_pattern,
3175
 
                'line-width'     => $line_width,
3176
 
                'line-cap'       => 'CAIRO_LINE_CAP_ROUND',
3177
 
                'line-join'      => 'CAIRO_LINE_JOIN_ROUND'
3178
 
        );
3179
 
 
3180
 
        $self->{_current_new_item} = $item;
 
5239
        my $item = undef;
 
5240
        if($highlighter){
 
5241
                $item = Goo::Canvas::Polyline->new_line(
 
5242
                        $self->{_canvas}->get_root_item, $points[0],$points[1],$points[2],$points[3],
 
5243
                        'stroke-pattern' => $self->create_color( Gtk2::Gdk::Color->parse('#FFFF00'), 0.5 ),
 
5244
                        'line-width'     => 18,
 
5245
                        'fill-rule'      => 'CAIRO_FILL_RULE_EVEN_ODD',
 
5246
                        'line-cap'       => 'CAIRO_LINE_CAP_SQUARE',
 
5247
                        'line-join'      => 'CAIRO_LINE_JOIN_BEVEL',    
 
5248
                );              
 
5249
        }else{
 
5250
                $item = Goo::Canvas::Polyline->new_line(
 
5251
                        $self->{_canvas}->get_root_item, $points[0],$points[1],$points[2],$points[3],
 
5252
                        'stroke-pattern' => $stroke_pattern,
 
5253
                        'line-width'     => $line_width,
 
5254
                        'line-cap'       => 'CAIRO_LINE_CAP_ROUND',
 
5255
                        'line-join'      => 'CAIRO_LINE_JOIN_ROUND',
 
5256
                );              
 
5257
        }
 
5258
         
 
5259
        $self->{_current_new_item} = $item unless($copy_item);
3181
5260
        $self->{_items}{$item} = $item;
3182
5261
 
3183
5262
        #need at least 2 points
3185
5264
        $self->{_items}{$item}->set( points => Goo::Canvas::Points->new( $self->{_items}{$item}{'points'} ) );  
3186
5265
        $self->{_items}{$item}->set( transform => $transform) if $transform;
3187
5266
 
3188
 
        $self->{_items}{$item}{stroke_color}       = $self->{_stroke_color};
3189
 
        $self->{_items}{$item}{stroke_color_alpha} = $self->{_stroke_color_alpha};
 
5267
        if($highlighter){
 
5268
                #set type flag
 
5269
                $self->{_items}{$item}{type} = 'highlighter';
 
5270
                $self->{_items}{$item}{uid} = $self->{_uid}++;  
 
5271
                $self->{_items}{$item}{stroke_color}       = Gtk2::Gdk::Color->parse('#FFFF00');
 
5272
                $self->{_items}{$item}{stroke_color_alpha} = 0.5;
 
5273
        }else{
 
5274
                #set type flag
 
5275
                $self->{_items}{$item}{type} = 'freehand';
 
5276
                $self->{_items}{$item}{uid} = $self->{_uid}++;
 
5277
                $self->{_items}{$item}{stroke_color}       = $self->{_stroke_color};
 
5278
                $self->{_items}{$item}{stroke_color_alpha} = $self->{_stroke_color_alpha};              
 
5279
        }
3190
5280
 
3191
5281
        $self->setup_item_signals( $self->{_items}{$item} );
3192
5282
        $self->setup_item_signals_extra( $self->{_items}{$item} );
3193
5283
 
3194
 
        #add to undo stack
3195
 
        $self->store_to_xdo_stack($item , 'create', 'undo');
3196
 
 
3197
 
        return TRUE;
3198
 
 
 
5284
        return $item;
3199
5285
}
3200
5286
 
3201
5287
sub create_censor {
3208
5294
        
3209
5295
        #use event coordinates
3210
5296
        if ($ev) {
3211
 
                @points = ( $ev->x, $ev->y, $ev->x, $ev->y );
 
5297
                @points = ( $ev->x_root, $ev->y_root, $ev->x_root, $ev->y_root );
3212
5298
        #use source item coordinates
3213
5299
        } elsif ($copy_item) {
3214
5300
                foreach(@{$self->{_items}{$copy_item}{points}}){
3219
5305
 
3220
5306
    my @stipple_data = (255, 255, 255, 255,  255, 255, 255, 255,   255, 255, 255, 255,  255, 255, 255, 255);
3221
5307
        my $stroke_pattern = $self->create_stipple('black', \@stipple_data);
3222
 
                
 
5308
 
3223
5309
        my $item = Goo::Canvas::Polyline->new_line(
3224
5310
                $self->{_canvas}->get_root_item, $points[0],$points[1],$points[2],$points[3],
3225
5311
                'stroke-pattern' => $stroke_pattern,
3226
5312
                'line-width'     => 14,
3227
5313
                'line-cap'       => 'CAIRO_LINE_CAP_ROUND',
3228
 
                'line-join'      => 'CAIRO_LINE_JOIN_ROUND'
 
5314
                'line-join'      => 'CAIRO_LINE_JOIN_ROUND',
3229
5315
        );
3230
5316
 
3231
 
        $self->{_current_new_item} = $item;
 
5317
        $self->{_current_new_item} = $item unless($copy_item);
3232
5318
        $self->{_items}{$item} = $item;
3233
5319
 
 
5320
        #set type flag
 
5321
        $self->{_items}{$item}{type} = 'censor';
 
5322
        $self->{_items}{$item}{uid} = $self->{_uid}++;
 
5323
 
3234
5324
        #need at least 2 points
3235
5325
        push @{ $self->{_items}{$item}{'points'} }, @points;
3236
5326
        $self->{_items}{$item}->set( points => Goo::Canvas::Points->new( $self->{_items}{$item}{'points'} ) );  
3239
5329
        $self->setup_item_signals( $self->{_items}{$item} );
3240
5330
        $self->setup_item_signals_extra( $self->{_items}{$item} );
3241
5331
 
3242
 
        #add to undo stack
3243
 
        $self->store_to_xdo_stack($item , 'create', 'undo');
3244
 
 
3245
 
        return TRUE;
3246
 
 
 
5332
        
 
5333
        return $item;
3247
5334
}
3248
5335
 
3249
5336
sub create_image {
3255
5342
 
3256
5343
        #use event coordinates
3257
5344
        if ($ev) {
3258
 
                @dimensions = ( $ev->x, $ev->y, 2, 2 );
 
5345
                @dimensions = ( $ev->x_root, $ev->y_root, 0, 0 );
3259
5346
        #use source item coordinates
3260
5347
        } elsif ($copy_item) {
3261
5348
                @dimensions = ( $copy_item->get('x') + 20, $copy_item->get('y') + 20, $self->{_items}{$copy_item}->get('width'), $self->{_items}{$copy_item}->get('height'));
3268
5355
                'line-dash'    => Goo::Canvas::LineDash->new( [ 5, 5 ] ),
3269
5356
                'line-width'   => 1,
3270
5357
                'stroke-color' => 'gray',
 
5358
                'antialias'    => 'none',
3271
5359
        );
3272
5360
 
3273
 
        $self->{_current_new_item} = $item;
 
5361
        $self->{_current_new_item} = $item unless($copy_item);
3274
5362
        $self->{_items}{$item} = $item;
3275
5363
 
3276
5364
 
3283
5371
        }
3284
5372
        
3285
5373
        $self->{_items}{$item}{image}
3286
 
                = Goo::Canvas::Image->new( $self->{_canvas}->get_root_item, $self->{_items}{$item}{orig_pixbuf}, $item->get('x'), $item->get('y') );
 
5374
                = Goo::Canvas::Image->new( 
 
5375
                $self->{_canvas}->get_root_item, 
 
5376
                $self->{_items}{$item}{orig_pixbuf}, 
 
5377
                $item->get('x'), 
 
5378
                $item->get('y'),
 
5379
                'width' => 2,
 
5380
                'height' => 2,
 
5381
        );
 
5382
 
 
5383
        #set type flag
 
5384
        $self->{_items}{$item}{type} = 'image';
 
5385
        $self->{_items}{$item}{uid} = $self->{_uid}++;  
3287
5386
 
3288
5387
        #create rectangles
3289
5388
        $self->handle_rects( 'create', $item );
3309
5408
                
3310
5409
        }       
3311
5410
 
3312
 
        #add to undo stack
3313
 
        $self->store_to_xdo_stack($item , 'create', 'undo');
3314
 
        
3315
 
        return TRUE;    
 
5411
        return $item;   
3316
5412
}
3317
5413
 
3318
5414
sub create_text{
3322
5418
 
3323
5419
        my @dimensions = ( 0, 0, 0, 0 );
3324
5420
        my $stroke_pattern = $self->create_color( $self->{_stroke_color}, $self->{_stroke_color_alpha} );
3325
 
        my $text = 'New Text...';
 
5421
        my $text = $self->{_d}->get('New text...');
3326
5422
        my $line_width = $self->{_line_width};
3327
5423
 
3328
5424
        #use event coordinates and selected color
3329
5425
        if ($ev) {
3330
 
                @dimensions = ( $ev->x, $ev->y, 2, 2 );
 
5426
                @dimensions = ( $ev->x_root, $ev->y_root, 0, 0 );
3331
5427
                #use source item coordinates and item color
3332
5428
        } elsif ($copy_item) {
3333
5429
                @dimensions = ( $copy_item->get('x') + 20, $copy_item->get('y') + 20, $copy_item->get('width'), $copy_item->get('height') );
3343
5439
                'line-dash'    => Goo::Canvas::LineDash->new( [ 5, 5 ] ),
3344
5440
                'line-width'   => 1,
3345
5441
                'stroke-color' => 'gray',
 
5442
                'antialias'    => 'none',
3346
5443
        );
3347
5444
 
3348
 
        $self->{_current_new_item} = $item;
 
5445
        $self->{_current_new_item} = $item unless($copy_item);
3349
5446
        $self->{_items}{$item} = $item;
3350
5447
 
3351
 
        my $stroke_pattern = $self->create_color( $self->{_stroke_color}, $self->{_stroke_color_alpha} );
3352
 
 
3353
5448
        $self->{_items}{$item}{text} = Goo::Canvas::Text->new(
3354
5449
                $self->{_canvas}->get_root_item, "<span font_desc='" . $self->{_font} . "' >".$text."</span>",
3355
5450
                $item->get('x'),
3356
 
                $item->get('y'), $item->get('width'),
 
5451
                $item->get('y'), 
 
5452
                0,
3357
5453
                'nw',
3358
 
                'use-markup'   => TRUE,
3359
 
                'fill-pattern' => $stroke_pattern,
3360
 
                'line-width'   => $line_width,
 
5454
                'use-markup'    => TRUE,
 
5455
                'fill-pattern'  => $stroke_pattern,
 
5456
                'line-width'    => $line_width,
3361
5457
        );
3362
5458
 
 
5459
        #adjust parent rectangle
 
5460
        my $tb = $self->{_items}{$item}{text}->get_bounds;
 
5461
        my $w  = abs($tb->x1 - $tb->x2);
 
5462
        my $h  = abs($tb->y1 - $tb->y2);
 
5463
        
 
5464
        if($copy_item){                         
 
5465
                $self->{_items}{$item}->set( 
 
5466
                        'x'             => $self->{_items}{$item}->get('x') + 20, 
 
5467
                        'y'             => $self->{_items}{$item}->get('y') + 20,                       
 
5468
                        'width'         => $w,
 
5469
                        'height'        => $h,
 
5470
                        'visibility' => 'hidden',
 
5471
                );
 
5472
        }else{
 
5473
                $self->{_items}{$item}->set( 
 
5474
                        'x'             => $ev->x_root - $w, 
 
5475
                        'y'             => $ev->y_root - $h,                    
 
5476
                        'width'         => $w,
 
5477
                        'height'        => $h,
 
5478
                        'visibility' => 'hidden',
 
5479
                );              
 
5480
        }       
 
5481
 
 
5482
        #update text
 
5483
        $self->handle_embedded('update', $item); 
 
5484
 
 
5485
        #set type flag
 
5486
        $self->{_items}{$item}{type} = 'text';
 
5487
        $self->{_items}{$item}{uid} = $self->{_uid}++;
 
5488
 
3363
5489
        $self->{_items}{$item}{stroke_color}       = $self->{_stroke_color};
3364
5490
        $self->{_items}{$item}{stroke_color_alpha} = $self->{_stroke_color_alpha};
3365
5491
 
3366
5492
        #create rectangles
3367
5493
        $self->handle_rects( 'create', $item );
3368
 
        if ($copy_item){        
3369
 
                $self->handle_embedded('update', $item); 
 
5494
        if ($copy_item){                        
3370
5495
                $self->handle_rects('hide', $item);     
3371
5496
        }
3372
5497
 
3376
5501
        $self->setup_item_signals( $self->{_items}{$item} );
3377
5502
        $self->setup_item_signals_extra( $self->{_items}{$item} );
3378
5503
 
3379
 
        #add to undo stack
3380
 
        $self->store_to_xdo_stack($item , 'create', 'undo');
3381
 
        
3382
 
        return TRUE;
3383
 
        
 
5504
        return $item;
3384
5505
}       
3385
5506
 
3386
5507
sub create_line {
3387
 
        my $self      = shift;
3388
 
        my $ev        = shift;
3389
 
        my $copy_item = shift;
 
5508
        my $self                        = shift;
 
5509
        my $ev                          = shift;
 
5510
        my $copy_item                   = shift;
 
5511
        my $end_arrow                   = shift;
 
5512
        my $start_arrow                 = shift;
3390
5513
        
3391
5514
        my @dimensions = ( 0, 0, 0, 0 );
3392
5515
        my $stroke_pattern = $self->create_color( $self->{_stroke_color}, $self->{_stroke_color_alpha} );
3393
5516
        my $line_width = $self->{_line_width};
3394
 
        my $mirrored = FALSE;
3395
 
 
 
5517
        my $mirrored_w = 0;
 
5518
        my $mirrored_h = 0;
 
5519
        
 
5520
        #default values
 
5521
        my $arrow_width                 = 4;
 
5522
        my $arrow_length                = 5;
 
5523
        my $arrow_tip_length    = 4;
 
5524
        
3396
5525
        #use event coordinates and selected color
3397
5526
        if ($ev) {
3398
 
                @dimensions = ( $ev->x, $ev->y, 2, 2 );
 
5527
                @dimensions = ( $ev->x_root, $ev->y_root, 0, 0 );
3399
5528
                #use source item coordinates and item color
3400
5529
        } elsif ($copy_item) {
3401
 
                @dimensions = ( $copy_item->get('x') + 20, $copy_item->get('y') + 20, $copy_item->get('width'), $copy_item->get('height') );
3402
 
                $stroke_pattern = $self->create_color( $self->{_items}{$copy_item}{stroke_color}, $self->{_items}{$copy_item}{stroke_color_alpha} );
3403
 
                $line_width = $self->{_items}{$copy_item}{line}->get('line-width');
3404
 
                $mirrored = $self->{_items}{$copy_item}{mirrored};
 
5530
                @dimensions             = ( $copy_item->get('x') + 20, $copy_item->get('y') + 20, $copy_item->get('width'), $copy_item->get('height') );
 
5531
                $stroke_pattern         = $self->create_color( $self->{_items}{$copy_item}{stroke_color}, $self->{_items}{$copy_item}{stroke_color_alpha} );
 
5532
                $line_width             = $self->{_items}{$copy_item}{line}->get('line-width');
 
5533
                $mirrored_w             = $self->{_items}{$copy_item}{mirrored_w};
 
5534
                $mirrored_h             = $self->{_items}{$copy_item}{mirrored_h};
 
5535
                #arrow specific properties
 
5536
                $end_arrow              = $self->{_items}{$copy_item}{end_arrow};
 
5537
                $start_arrow            = $self->{_items}{$copy_item}{start_arrow};
 
5538
                $arrow_width            = $self->{_items}{$copy_item}{arrow_width};
 
5539
                $arrow_length           = $self->{_items}{$copy_item}{arrow_length};
 
5540
                $arrow_tip_length       = $self->{_items}{$copy_item}{arrow_tip_length};
3405
5541
        }
3406
5542
 
3407
5543
        my $pattern = $self->create_alpha;
3411
5547
                'line-dash'    => Goo::Canvas::LineDash->new( [ 5, 5 ] ),
3412
5548
                'line-width'   => 1,
3413
5549
                'stroke-color' => 'gray',
 
5550
                'antialias'    => 'none',
3414
5551
        );
3415
5552
 
3416
 
        $self->{_current_new_item} = $item;
 
5553
        $self->{_current_new_item} = $item unless($copy_item);
3417
5554
        $self->{_items}{$item} = $item;
3418
5555
 
3419
5556
        $self->{_items}{$item}{line} = Goo::Canvas::Polyline->new_line(
3422
5559
                $item->get('y'), 
3423
5560
                $item->get('x') + $item->get('width'),
3424
5561
                $item->get('y') + $item->get('height'),
3425
 
                'stroke-pattern' => $stroke_pattern,
3426
 
                'line-width'     => $line_width,
3427
 
                'line-cap'       => 'CAIRO_LINE_CAP_ROUND',
3428
 
                'line-join'      => 'CAIRO_LINE_JOIN_ROUND'
 
5562
                'stroke-pattern'        => $stroke_pattern,
 
5563
                'line-width'            => $line_width,
 
5564
                'line-cap'              => 'CAIRO_LINE_CAP_ROUND',
 
5565
                'line-join'             => 'CAIRO_LINE_JOIN_ROUND',
 
5566
                'end-arrow'             => $end_arrow,          
 
5567
                'start-arrow'           => $start_arrow,
 
5568
                'arrow-length'          => $arrow_length,
 
5569
                'arrow-width'           => $arrow_width,
 
5570
                'arrow-tip-length'      => $arrow_tip_length,                                   
3429
5571
        );                              
3430
 
 
3431
 
        $self->{_items}{$item}{mirrored} = $mirrored;
 
5572
        
 
5573
        if(defined $end_arrow || defined $start_arrow){
 
5574
                #save arrow specific properties
 
5575
                $self->{_items}{$item}{end_arrow}                       = $self->{_items}{$item}{line}->get('end-arrow');
 
5576
                $self->{_items}{$item}{start_arrow}             = $self->{_items}{$item}{line}->get('start-arrow');
 
5577
                $self->{_items}{$item}{arrow_width}             = $self->{_items}{$item}{line}->get('arrow-width');
 
5578
                $self->{_items}{$item}{arrow_length}            = $self->{_items}{$item}{line}->get('arrow-length');
 
5579
                $self->{_items}{$item}{arrow_tip_length}        = $self->{_items}{$item}{line}->get('arrow-tip-length');
 
5580
        }
 
5581
 
 
5582
        #set type flag
 
5583
        $self->{_items}{$item}{type} = 'line';
 
5584
        $self->{_items}{$item}{uid} = $self->{_uid}++;
 
5585
 
 
5586
        $self->{_items}{$item}{mirrored_w} = $mirrored_w;
 
5587
        $self->{_items}{$item}{mirrored_h} = $mirrored_h;
3432
5588
 
3433
5589
        $self->{_items}{$item}{stroke_color}       = $self->{_stroke_color};
3434
5590
        $self->{_items}{$item}{stroke_color_alpha} = $self->{_stroke_color_alpha};
3445
5601
 
3446
5602
        $self->setup_item_signals( $self->{_items}{$item} );
3447
5603
        $self->setup_item_signals_extra( $self->{_items}{$item} );
3448
 
 
3449
 
        #add to undo stack
3450
 
        $self->store_to_xdo_stack($item , 'create', 'undo');
3451
5604
        
3452
 
        return TRUE;
3453
 
 
 
5605
        return $item;
3454
5606
}
3455
5607
 
3456
5608
sub create_ellipse {
3457
5609
        my $self      = shift;
3458
5610
        my $ev        = shift;
3459
5611
        my $copy_item = shift;
 
5612
        my $numbered  = shift;
3460
5613
 
3461
5614
        my @dimensions = ( 0, 0, 0, 0 );
3462
5615
        my $stroke_pattern = $self->create_color( $self->{_stroke_color}, $self->{_stroke_color_alpha} );
3465
5618
 
3466
5619
        #use event coordinates and selected color
3467
5620
        if ($ev) {
3468
 
                @dimensions = ( $ev->x, $ev->y, 2, 2 );
3469
 
                #use source item coordinates and item color
 
5621
                @dimensions = ( $ev->x_root, $ev->y_root, 0, 0 );
 
5622
        #use source item coordinates and item color
3470
5623
        } elsif ($copy_item) {
3471
5624
                @dimensions = ( $copy_item->get('x') + 20, $copy_item->get('y') + 20, $copy_item->get('width'), $copy_item->get('height') );
3472
5625
                $stroke_pattern = $self->create_color( $self->{_items}{$copy_item}{stroke_color}, $self->{_items}{$copy_item}{stroke_color_alpha} );
3473
5626
                $fill_pattern   = $self->create_color( $self->{_items}{$copy_item}{fill_color},   $self->{_items}{$copy_item}{fill_color_alpha} );
3474
5627
                $line_width = $self->{_items}{$copy_item}{ellipse}->get('line-width');
 
5628
                $numbered = TRUE if exists $self->{_items}{$copy_item}{text};
3475
5629
        }
3476
5630
 
3477
5631
        my $pattern = $self->create_alpha;
3481
5635
                'line-dash'    => Goo::Canvas::LineDash->new( [ 5, 5 ] ),
3482
5636
                'line-width'   => 1,
3483
5637
                'stroke-color' => 'gray',
 
5638
                'antialias'    => 'none',
3484
5639
        );
3485
5640
 
3486
 
        $self->{_current_new_item} = $item;
 
5641
        $self->{_current_new_item} = $item unless($copy_item);
3487
5642
        $self->{_items}{$item} = $item;
3488
5643
 
3489
5644
        $self->{_items}{$item}{ellipse} = Goo::Canvas::Ellipse->new(
3494
5649
                'line-width'     => $line_width,
3495
5650
        );
3496
5651
 
 
5652
        #numbered ellipse
 
5653
        if($numbered){
 
5654
                
 
5655
                my $number = $self->get_highest_auto_digit();
 
5656
                $number++;
 
5657
                
 
5658
                $self->{_items}{$item}{text} = Goo::Canvas::Text->new(
 
5659
                        $self->{_canvas}->get_root_item, "<span font_desc='" . $self->{_font} . "' >".$number."</span>",
 
5660
                        $self->{_items}{$item}{ellipse}->get('center-x'),
 
5661
                        $self->{_items}{$item}{ellipse}->get('center-y'),
 
5662
                        0,
 
5663
                        'GTK_ANCHOR_CENTER',
 
5664
                        'use-markup'   => TRUE,
 
5665
                        'fill-pattern' => $stroke_pattern,
 
5666
                        'line-width'   => $line_width,
 
5667
                );
 
5668
                
 
5669
                #save used number
 
5670
                $self->{_items}{$item}{text}{digit} = $number;
 
5671
                
 
5672
                #set type flag
 
5673
                $self->{_items}{$item}{type} = 'number';
 
5674
                $self->{_items}{$item}{uid} = $self->{_uid}++;
 
5675
 
 
5676
                #adjust parent rectangle if numbered ellipse            
 
5677
                my $tb = $self->{_items}{$item}{text}->get_bounds;
 
5678
                                                
 
5679
                #keep ratio = 1
 
5680
                my $qs = abs($tb->x1 - $tb->x2);
 
5681
                $qs = abs($tb->y1 - $tb->y2) if abs($tb->y1 - $tb->y2) > abs($tb->x1 - $tb->x2); 
 
5682
 
 
5683
                #add line width of parent ellipse
 
5684
                $qs += $self->{_items}{$item}{ellipse}->get('line-width')+5;
 
5685
                
 
5686
                if($copy_item){
 
5687
                        $self->{_items}{$item}->set(
 
5688
                                'x'              => $self->{_items}{$item}->get('x') + 20,
 
5689
                                'y'              => $self->{_items}{$item}->get('y') + 20,
 
5690
                                'width'          => $qs,
 
5691
                                'height'         => $qs,
 
5692
                                'visibility' => 'hidden',
 
5693
                        );
 
5694
                }else{
 
5695
                        $self->{_items}{$item}->set(
 
5696
                                'x'              => $self->{_items}{$item}->get('x') - $qs,
 
5697
                                'y'              => $self->{_items}{$item}->get('y') - $qs,
 
5698
                                'width'          => $qs,
 
5699
                                'height'         => $qs,
 
5700
                                'visibility' => 'hidden',
 
5701
                        );                      
 
5702
                }
 
5703
 
 
5704
                $self->handle_embedded('update', $item); 
 
5705
                                                
 
5706
        }else{
 
5707
                #set type flag
 
5708
                $self->{_items}{$item}{type} = 'ellipse';               
 
5709
                $self->{_items}{$item}{uid} = $self->{_uid}++;
 
5710
        }
 
5711
 
3497
5712
        #save color and opacity as well
3498
5713
        $self->{_items}{$item}{fill_color}         = $self->{_fill_color};
3499
5714
        $self->{_items}{$item}{fill_color_alpha}   = $self->{_fill_color_alpha};
3507
5722
                $self->handle_rects('hide', $item);     
3508
5723
        }
3509
5724
 
 
5725
        if($numbered){
 
5726
                $self->setup_item_signals( $self->{_items}{$item}{text} );
 
5727
                $self->setup_item_signals_extra( $self->{_items}{$item}{text} );
 
5728
        }
 
5729
 
3510
5730
        $self->setup_item_signals( $self->{_items}{$item}{ellipse} );
3511
5731
        $self->setup_item_signals_extra( $self->{_items}{$item}{ellipse} );
3512
5732
 
3513
5733
        $self->setup_item_signals( $self->{_items}{$item} );
3514
5734
        $self->setup_item_signals_extra( $self->{_items}{$item} );
3515
5735
 
3516
 
        #add to undo stack
3517
 
        $self->store_to_xdo_stack($item , 'create', 'undo');
3518
 
        
3519
 
        return TRUE;
3520
 
 
 
5736
        return $item;
3521
5737
}
3522
5738
 
3523
5739
 
3526
5742
        my $ev        = shift;
3527
5743
        my $copy_item = shift;
3528
5744
 
3529
 
        my @dimensions = ( 0, 0, 0, 0 );
 
5745
        my @dimensions     = ( 0, 0, 0, 0 );
3530
5746
        my $stroke_pattern = $self->create_color( $self->{_stroke_color}, $self->{_stroke_color_alpha} );
3531
 
        my $fill_pattern   = $self->create_color( $self->{_fill_color},   $self->{_fill_color_alpha} );
3532
 
        my $line_width = $self->{_line_width};
 
5747
        my $fill_pattern   = $self->create_color( $self->{_fill_color}, $self->{_fill_color_alpha} );
 
5748
        my $line_width     = $self->{_line_width};
3533
5749
 
3534
5750
        #use event coordinates and selected color
3535
5751
        if ($ev) {
3536
 
                @dimensions = ( $ev->x, $ev->y, 2, 2 );
 
5752
                @dimensions = ( $ev->x_root, $ev->y_root, 0, 0 );
3537
5753
 
3538
 
                #use source item coordinates and item color
 
5754
        #use source item coordinates and item color
3539
5755
        } elsif ($copy_item) {
3540
5756
                @dimensions = ( $copy_item->get('x') + 20, $copy_item->get('y') + 20, $copy_item->get('width'), $copy_item->get('height') );
3541
5757
                $stroke_pattern = $self->create_color( $self->{_items}{$copy_item}{stroke_color}, $self->{_items}{$copy_item}{stroke_color_alpha} );
3548
5764
                'fill-pattern'   => $fill_pattern,
3549
5765
                'stroke-pattern' => $stroke_pattern,
3550
5766
                'line-width'     => $line_width,
 
5767
                'antialias'      => 'none',
3551
5768
        );
3552
 
 
3553
 
        $self->{_current_new_item} = $item;
 
5769
        
 
5770
        $self->{_current_new_item} = $item unless($copy_item);
3554
5771
        $self->{_items}{$item} = $item;
3555
5772
 
 
5773
        #set type flag
 
5774
        $self->{_items}{$item}{type} = 'rectangle';
 
5775
        $self->{_items}{$item}{uid} = $self->{_uid}++;
 
5776
 
3556
5777
        $self->{_items}{$item}{fill_color}         = $self->{_fill_color};
3557
5778
        $self->{_items}{$item}{fill_color_alpha}   = $self->{_fill_color_alpha};
3558
5779
        $self->{_items}{$item}{stroke_color}       = $self->{_stroke_color};
3564
5785
        $self->setup_item_signals( $self->{_items}{$item} );
3565
5786
        $self->setup_item_signals_extra( $self->{_items}{$item} );
3566
5787
 
3567
 
        #add to undo stack
3568
 
        $self->store_to_xdo_stack($item , 'create', 'undo');
3569
 
 
3570
 
        return TRUE;
 
5788
        return $item;
3571
5789
}
3572
5790
 
3573
5791
1;
 
5792