File Coverage

blib/lib/Prima/CodeManager/CodeManager.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             ################################################################################
2             # This is CodeManager
3             # Copyright 2009-2013 by Waldemar Biernacki
4             # http://codemanager.sao.pl\n" .
5             #
6             # License statement:
7             #
8             # This program/library is free software; you can redistribute it
9             # and/or modify it under the same terms as Perl itself.
10             #
11             # Last modified (DMYhms): 14-01-2013 07:25:17.
12             ################################################################################
13              
14             package Prima::CodeManager::CodeManager;
15              
16             our $VERSION = '0.05';
17              
18             1;
19              
20             #######################################################################
21              
22             package Prima::CodeManager;
23              
24 1     1   41142 use strict;
  1         3  
  1         158  
25 1     1   6 use warnings;
  1         2  
  1         32  
26              
27 1     1   5 use Cwd;
  1         6  
  1         220  
28              
29 1     1   687 use Prima qw(Application);
  0            
  0            
30             use Prima::Buttons;
31             use Prima::FileDialog;
32             use Prima::FrameSet;
33             use Prima::ExtLists;
34             use Prima::ImageViewer;
35             use Prima::MsgBox;
36             use Prima::ScrollWidget;
37             use Prima::StdDlg;
38              
39              
40             use Prima::CodeManager::Outlines;
41             use Prima::CodeManager::Notebooks;
42             use Prima::CodeManager::Label;
43             use Prima::CodeManager::Image;
44              
45             use base "Prima::CodeManager::Misc";
46             use base "Prima::CodeManager::File";
47             #use base "Prima::CodeManager::Remote";
48              
49             use File::Copy;
50             use File::Path qw(make_path remove_tree);
51             use File::Copy::Recursive qw(fcopy rcopy dircopy fmove rmove dirmove);
52             use File::HomeDir;
53              
54             our $VERSION = '0.04';
55              
56             ########################################################################################
57              
58             my ( $screen_width, $screen_height ) = $::application->size;
59             $::application-> wantUnicodeInput(1);
60              
61             #-------------------------------------------------------
62              
63             #setting OS
64             our $_OS;
65             $_OS = 'unknown';
66             $_OS = 'os' if $::application-> get_system_info()->{apc} == 1;
67             $_OS = 'windows' if $::application-> get_system_info()->{apc} == 2;
68             $_OS = 'linux' if $::application-> get_system_info()->{apc} == 3;
69              
70             #-------------------------------------------------------
71             our $CodeManager_encoding = '';
72             #-------------------------------------------------------
73              
74             #setting CodeManager.pm directory
75             our $CodeManager_directory = '';
76              
77             if ( $PerlApp::BUILD ) {
78              
79             # $CodeManager_directory = PerlApp::exe();
80             # $CodeManager_directory =~ s/(\\|\/)[^\\\/]*\.exe$//;
81             # $CodeManager_directory .= '/Prima/CodeManager';
82             $CodeManager_directory = 'Prima/CodeManager';
83              
84             } else {
85              
86             $CodeManager_directory = $INC{'Prima/CodeManager/CodeManager.pm'};
87             $CodeManager_directory =~ s/\/CodeManager\.pm$//;
88             }
89              
90             #print "CodeManager_directory=$CodeManager_directory\n";
91              
92             #-------------------------------------------------------
93              
94             #setting user home directory
95             our $home_directory = File::HomeDir-> my_home.'/.CodeManager';
96              
97             #-------------------------------------------------------
98              
99             our %developer;
100             our %info_of_files;
101             our @list_of_files;
102             our %file_encodings; #this is a hash of the files encodings
103             our %all_extensions;
104             our $file_number = 0;
105              
106             my $popup;
107              
108             #-------------------------------------------------------
109             my $int_color = int(rand(360));
110             my $int_white = 170;
111             my $int_black = 40;
112             my $project_color = Prima::CodeManager::Misc::angle_color( undef, $int_color, $int_white, $int_black );
113              
114             #-------------------------------------------------------
115              
116             sub new
117             {
118             my ( $project ) = ( shift );
119             my $this = {};
120             bless ( $this, $project );
121              
122             use Prima::Application (
123             title => 'CodeManager',
124             wantUnicodeInput => 1,
125             hintFont => {
126             name => 'DejaVu Sans',
127             size => 10,
128             style => fs::Italic,
129             },
130             font => {
131             name => 'DejaVu Sans',
132             size => 10,
133             style => fs::Normal,
134             },
135             );
136             #-------------------------------------------------------
137             $this-> create_user_home_directory ( $home_directory ) unless -d "$home_directory";
138             Prima::message ( "I can't create your CodeManager home directory:\n$home_directory" ) unless -d $home_directory;
139             #-------------------------------------------------------
140             my $DIR;
141             #reading names of the hiliting files in "Prima/CodeManager/hilite" subdirectory:
142             my @hilite_files = [];
143             my @hilite_files_ext; # = <$CodeManager_directory/hilite/hilite_*.pl>; (doesn't work on Windows)
144             if ( opendir $DIR, "$CodeManager_directory/hilite" ) {
145              
146             @hilite_files_ext = sort grep { $_ =~ /hilite_\w+\.pl/ } readdir $DIR;
147             closedir $DIR;
148             }
149              
150             ##################################################
151              
152             for ( my $i = 0; $i < @hilite_files_ext; $i++ ) {
153             if ( $hilite_files_ext[$i] =~ /hilite_(\w+)\.pl/ ) {
154             my $ext = $1;
155             $hilite_files[$i] = [ $1 => sub { $this->file_edit ( "$CodeManager_directory/hilite/hilite_$ext.pl" ) } ];
156             eval ( $this-> read_file( "$CodeManager_directory/hilite/hilite_$ext.pl" ));
157             $all_extensions{$ext} = $ext if $ext;
158             $all_extensions{'pm'} = 'pm' if $ext eq 'pl';
159             }
160             }
161             #-------------------------------------------------------
162              
163             #reading images:
164             my @images_files_ext; # = <$CodeManager_directory/img/*.png>;
165             if ( opendir $DIR, "$CodeManager_directory/img" ) {
166             @images_files_ext = sort grep { $_ =~ /\.png/ } readdir $DIR;
167             closedir $DIR;
168             }
169             for ( my $i = 0; $i < @images_files_ext; $i++ ) {
170             if ( $images_files_ext[$i] =~ /(\w+)\.png$/ ) {
171             $this->{images}->{$1} = $this-> load_icon( "$CodeManager_directory/img/$1.png" );
172             $this->{images}->{$1} = $this-> load_icon( "$CodeManager_directory/img/nil.png" ) unless $this->{images}->{$1};
173             }
174             }
175             #-------------------------------------------------------
176             #reading names of the projects file names in the user CodeManager home "~/.CodeManager/projects" subdirectory:
177             my @projects_files_open;
178             my @projects_files_edit;
179             my @projects_files_name;
180             if ( opendir $DIR, "$home_directory/projects" ) {
181             @projects_files_name = sort grep { $_ =~ /\.cm/ } readdir $DIR;
182             closedir $DIR;
183             }
184             my $_group = '`';
185             my @files_open;
186             my @files_edit;
187             foreach ( sort map {
188             if ( $_ =~ /([^\/]+)\.cm/ ) {
189             my $content = $this-> read_file( "$home_directory/projects/$1.cm" );
190             my ( $group, $name, $file ) = ( '', $_, $1 );
191             $group = $1 if $content =~ /\n\s*group\s*=\s*\b(.*)\b\s*\n/;
192             $name = $1 if $content =~ /\n\s*name\s*=\s*\b(.*)\b\s*\n/;
193             $_ = "$group`$name`$file";
194             }
195             } @projects_files_name ) {
196             if ( $_ =~ /(.*)`(.*)`(.*)/ ) {
197             my ( $group, $name, $file ) = ( $1, $2, $3 );
198             if ( $_group && $_group ne $group && $_group ne '`' ) {
199             push @projects_files_open, [ $_group => [ @files_open ]];
200             push @projects_files_edit, [ $_group => [ @files_edit ]];
201             undef @files_open;
202             undef @files_edit;
203             }
204             $_group = $group;
205             push @files_open, [ $name => sub { $this-> open ( "$home_directory/projects/$file.cm" )}];
206             push @files_edit, [ $name => sub { $this-> file_edit ( "$home_directory/projects/$file.cm" )}];
207             }
208             }
209             push @projects_files_open, [ $_group => [ @files_open ]];
210             push @projects_files_edit, [ $_group => [ @files_edit ]];
211              
212             #print Dumper(@projects_files_edit);
213              
214             # for ( my $i = 0; $i < @projects_files_name; $i++ ) {
215             # if ( $projects_files_name[$i] =~ /([^\/]+)\.cm/ ) {
216             # my $name = $1;
217             # if ( -f "$home_directory/projects/$name.cm" ) {
218             # my $content = $this-> read_file( "$home_directory/projects/$name.cm" );
219             # $name = $1 if $content =~ /\n\s*name\s*=\s*\b(.*)\b\s*\n/;
220             # $projects_files_open[$i] = [ $name => sub { $this-> open ( "$home_directory/projects/$name.cm" )}];
221             # $projects_files_edit[$i] = [ $name => sub { $this-> file_edit ( "$home_directory/projects/$name.cm" )}];
222             # }
223             # }
224             # }
225             #-------------------------------------------------------
226             $this->{mw} = Prima::MainWindow-> create(
227             icon => $this-> load_icon( "$CodeManager_directory/img/cm32.png" ),
228             name => 'CodeManager',
229             text => 'CodeManager',
230             title => 'CodeManager',
231             size => [[$::application-> size]->[0]-400, [$::application-> size ]->[1]-300],
232             origin => [ 0, 300 ],
233             centered => 1,
234             menuFont => {
235             name => 'DejaVu Sans',
236             size => 9,
237             style => fs::Normal,
238             },
239             menuBackColor => $this->licz_kolor( 0xffffff, $project_color, 0.3 ),
240             menuItems => [
241             [ '~System' => [
242             [ '~Hiliting Files' => [ @hilite_files ]],
243             [ '~Meld' => 'AltM' => '@M' => sub { $this-> meld }],
244             # [ '~Hiliting Files' => 'CtrlH' => '^H' => sub { &hilite_open }]
245             # ],
246             [],
247             [ 'E~xit' => 'AltX' => '@X' => sub { $::application-> close}],
248             ]],
249             [ '~Project' => [
250             [ '~Open project' => [ @projects_files_open ]],
251             [],
252             [ '~Open from disk' => 'F4' => 'F4' => sub { $this-> open }],
253             [ '~Refresh' => 'F5' => 'F5' => sub { $this-> make_tree }],
254             [ '~Save' => 'F2' => 'F2' => sub { $this-> save }],
255             [],
256             [ '~Edit projects files'=> [ @projects_files_edit ]],
257             ]],
258             [ '~Edit' => [
259             [ 'Undo' => 'CtrlZ' => '^Z', q(undo)],
260             [ 'Undo' => 'AltBackspace' => km::Alt|kb::Backspace, q(undo)],
261             [ 'Redo' => 'CtrlD' => '^D', q(redo)],
262             ]],
263             [ '~File' => [
264             [ '~New' => 'CtrlN' => '^N' => sub { $this-> file_new($this) } ],
265             [ '~Open...' => 'CtrlO' => '^O' => sub { $this-> file_open } ],
266             [ '~Save' => 'CtrlS' => '^S' => sub { $this-> file_save } ],
267             [ 'Save ~as...' => 'CtrlA' => '^A' => sub { $this-> file_save_as($this) } ],
268             [ '~Find...' => 'CtrlF' => '^F' => sub { $this-> find } ],
269             [ '~Jump the line...' => 'CtrlJ' => '^J' => sub { $this-> jump } ],
270             ['~Replace...' => 'CtrlR' => '^R' => sub { $this-> replace } ],
271             ['Find n~ext' => 'F3' => 'F3' => sub { $this-> find_next } ],
272             [],
273             ['Show next' => 'AltRight' => km::Alt|kb::Right => sub { $this->show_tab( 1) } ],
274             ['Show next' => 'CtrlTab' => km::Ctrl|kb::Tab => sub { $this->show_tab( 1) } ],
275             ['Show prev' => 'AltLeft' => km::Alt|kb::Left => sub { $this->show_tab(-1) } ],
276             ['Show prev' => 'CtrlShiftTab' => km::Ctrl|kb::Tab|km::Shift => sub { $this->show_tab(-1) } ],
277             [],
278             ['Font size -' => 'CtrlUp' => km::Ctrl|kb::Up => sub { $this->show_size(-1, 0) } ],
279             ['Font size +' => 'CtrlDown' => km::Ctrl|kb::Down => sub { $this->show_size( 1, 0) } ],
280             ['Line spacing -' => 'AltUp' => km::Alt|kb::Up => sub { $this->show_size( 0,-1) } ],
281             ['Line spacing +' => 'AltDown' => km::Alt|kb::Down => sub { $this->show_size( 0, 1) } ],
282             [],
283             ['~Close' => 'CtrlW' => '^W' => sub { $this-> file_close }],
284             # ['Re~place pages' => 'Ctrl+L' => '^L' => sub { $this-> file_replace }],
285             ]],
286             [ '~Help' => [
287             ["~About ver. $VERSION" => sub { $this-> about }],
288             ]],
289             ],
290             onClose => sub {
291             my $r = 0;
292             for ( my $i = 0; $i < $Prima::CodeManager::developer{notes}->pageCount; $i++ ) {
293             $r = 0;
294             if ( $Prima::CodeManager::developer{ "notes_$i" }-> modified ) {
295             $r = Prima::MsgBox::message_box (
296             "File not saved! ",
297             'File '.$Prima::CodeManager::list_of_files[$i].' has been modified. Save?', mb::YesNoCancel | mb::Warning
298             );
299             $this-> file_save_batch( $i ) if $r == mb::Yes;
300             $_[0]-> clear_event, return if $r == mb::Cancel;
301             }
302             }
303             $_[0]-> clear_event, return if mb::Cancel == $r;
304             },
305             );
306              
307             return $this;
308             }
309             ################################################################################
310             sub loop
311             {
312             my ( $self ) = shift;
313             run Prima;
314             }
315             ################################################################################
316             sub load_icon {
317             my ( $self, $file ) = @_;
318             my $dir = '';
319             $file = $dir.$file;
320             return undef unless -e $file;
321             my $im = Prima::Icon-> new( type=>im::RGB, ) || return undef;
322             $im->load( $file ) || return undef;
323             return $im;
324             }
325             ################################################################################
326             sub open
327             {
328             my ( $self, $project_file ) = ( shift, shift );
329             my $sliderWidth = 4;
330             unless ( $self->{frame_main} ) {
331             $self-> {frame_main} = $self->{mw}-> insert(
332             FrameSet =>
333             owner => $self->{mw},
334             frameProfile => {
335             borderWidth => 0,
336             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
337             },
338             arrangement => fra::Vertical,
339             size => [$self->{mw}-> size],
340             origin => [0,0],
341             frameSizes => [qw(3% *)],
342             opaqueResize => 1,
343             sliderWidth => $sliderWidth,
344             sliderProfile => {
345             borderWidth => 1,
346             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
347             light3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.6 ),
348             dark3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.4 ),
349             },
350             );
351             $self-> {frame_top} = $self-> {frame_main}-> insert_to_frame(
352             1,
353             FrameSet =>
354             frameProfile => {
355             borderWidth => 0,
356             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
357             },
358             size => [$self-> {frame_main}-> frames-> [1]-> size],
359             origin => [0,0],
360             frameSizes => [qw(20% *)],
361             opaqueResize => 1,
362             sliderWidth => $sliderWidth,
363             sliderProfile => {
364             borderWidth => 1,
365             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
366             light3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.6 ),
367             dark3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.4 ),
368             },
369             );
370             $self-> {frame_left} = $self-> {frame_top}-> insert_to_frame(
371             0,
372             FrameSet =>
373             frameProfile => {
374             borderWidth => 1,
375             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
376             },
377             arrangement => fra::Vertical,
378             size => [$self-> {frame_top}-> frames-> [0]-> size],
379             origin => [0,0],
380             frameSizes => [qw(20% *)],
381             opaqueResize => 1,
382             sliderWidth => $sliderWidth,
383             sliderProfile => {
384             borderWidth => 1,
385             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
386             light3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.6 ),
387             dark3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.4 ),
388             },
389             );
390             }
391             #-------------------------------------------------------------------------------
392             #if no project is defined we define empty one:
393             $project_file ||= '';
394             #if does not exixts we look in project directories; local and home ones:
395             unless ( -f $project_file ) {
396             $project_file = "./projects/$project_file" if -f "./projects/$project_file";
397             $project_file = "$home_directory/projects/$project_file" if -f "$home_directory/projects/$project_file";
398             }
399             #if still does not exists then it should be choosen:
400             unless ( -f $project_file ) {
401             my $win = Prima::OpenDialog-> new(
402             filter => [[ 'CodeManager project files' => '*.cm' ],],
403             directory => "$home_directory/projects/",
404             system => 0,
405             font => {
406             name => 'DejaVu Sans Mono',
407             size => 9,
408             style => fs::Normal,
409             },
410             );
411             $project_file = $win-> fileName() if $win-> execute();
412             }
413             #if still does not exists then we resign:
414             return unless -f $project_file;
415             #-------------------------------------------------------------------------------
416             undef $self->{global};
417             if ( -f $project_file && CORE::open ( my $FH, "<", $project_file ))
418             {
419             my $group = '';
420             my $directory_nr = -1;
421             my $directory_if = 0;
422             while ( my $wiersz = <$FH> ) {
423             next if $wiersz =~ /^(;|#|--)/;
424             $wiersz =~ s/\n*//g;
425             $wiersz =~ s/\r*//g;
426             $wiersz =~ s/\t*//g;
427             next unless $wiersz;
428             $wiersz =~ s/^([^#]*)#.*$/$1/;
429             if ( $wiersz =~ /^\s*\[(.+)\]/ ) {
430             $group = $1;
431             if ( $group eq 'DIRECTORY' ) {
432             $directory_nr++;
433             $directory_if = "_$directory_nr";
434             } else {
435             $directory_if = '';
436             }
437             } else {
438             if ( $wiersz =~ /^([^=]+?)\s*=\s*(.*)$/ ) {
439             my $name = $1;
440             my $value = $2;
441             $value =~ s/%\[([^%]*)\]([^%]*)%/$self->{global}->{$1}->{$2}/g;
442             $self->{global}->{$group}->{$name.$directory_if} = $value if $group && $name;
443             }
444             }
445             }
446             CORE::close ($FH);
447             }
448              
449             unless ( $self->{global}->{GLOBAL}->{name} ) {
450             $self->{global}->{GLOBAL}->{name} = $project_file;
451             $self->{global}->{GLOBAL}->{name} =~ s/\.cm$//;
452             }
453             $self->{mw}->set( text => $self->{global}->{GLOBAL}->{name});
454             $self->{global}->{GLOBAL}{notebook_fontSize} ||= 10;
455              
456             $self->{global}->{extensions} = '';
457             my $i = 0;
458             while ( $self->{global}->{DIRECTORY}->{$_OS."_$i"} ) {
459             $self->{global}->{DIRECTORY}->{"directories_$i"} ||= '';
460             $self->{global}->{DIRECTORY}->{$_OS."_$i"} =~ s/\~/$home_directory/g;
461             $self->{global}->{DIRECTORY}->{"directory_$i"} = $self->{global}->{DIRECTORY}->{$_OS."_$i"};
462             $self->{global}->{DIRECTORY}->{"directory_$i"} =~ s/\%CodeManager\%/$CodeManager_directory/g;
463             $self->{global}->{DIRECTORY}->{"extensions_$i"} ||= '';
464             $self->{global}->{extensions} .= '|'.$self->{global}->{DIRECTORY}->{"extensions_$i"} if $self->{global}->{DIRECTORY}->{"extensions_$i"};
465             $self->{global}->{DIRECTORY}->{"sorting_$i"} ||= 'by extension';
466             $self->{BRANCH}->[$i]->{sao_library} = $self->{global}->{DIRECTORY}->{"sao_library_$i"} || '.';
467              
468             $i++;
469             }
470             $self->{global}->{extensions} = 'nil|dir|'.$self->{global}->{extensions};
471             $self->{global}->{extensions} =~ s/\s+//g;
472             $self->{global}->{extensions} =~ s/\|+/\|/g;
473             my @exten = split '\|', $self->{global}->{extensions};
474             # for (@exten) {
475             # $self->{images}->{$_} = $self-> load_icon( "$CodeManager_directory/img/$_.png" );
476             # $self->{images}->{$_} = $self-> load_icon( "$CodeManager_directory/img/nil.png" ) unless $self->{images}->{$_};
477             # eval( $self->read_file( "$CodeManager_directory/hilite/hilite_$_.pl")) if -e "$CodeManager_directory/hilite/hilite_$_.pl";
478             # }
479             $self->{global}->{GLOBAL}->{CodeManager_encoding} ||= '';
480             $main::CodeManager_encoding = $self->{global}->{GLOBAL}->{CodeManager_encoding};
481             $self->{global}->{GLOBAL}->{backup} = 0 unless $self->{global}->{GLOBAL}->{backup};
482             $self-> make_tree;
483             $self-> make_notebook;
484              
485             return;
486             }
487              
488             ####################################################################
489              
490             sub make_tree
491             {
492             my ( $self ) = shift;
493              
494             #we remember the topItem in the tree before refreshing:
495             $self->{expanded}->{topItem} = 0;
496             $self->{expanded}->{topItem} = $self->{tree}->topItem if $self->{tree};
497              
498             $self->{global}->{GLOBAL}{tree_itemHeight} += 0;
499             $self->{global}->{GLOBAL}{tree_itemHeight} = 12 if $self->{global}->{GLOBAL}{tree_itemHeight} < 12;
500              
501             $self->{global}->{GLOBAL}{tree_itemIndent} += 0;
502             $self->{global}->{GLOBAL}{tree_itemIndent} =
503             $self->{global}->{GLOBAL}{tree_itemIndent} < $self->{global}->{GLOBAL}{tree_itemHeight}
504             ? $self->{global}->{GLOBAL}{tree_itemHeight}
505             : $self->{global}->{GLOBAL}{tree_itemIndent}
506             ;
507              
508             my ( $type_dimen, $font_dimen ) = ( 'size', int( 0.625 * $self->{global}->{GLOBAL}{tree_itemHeight}));
509              
510             if ( $self->{global}->{GLOBAL}{tree_fontHeight} && $self->{global}->{GLOBAL}{tree_fontHeight} > 0 ) {
511              
512             $type_dimen = 'height';
513             $font_dimen =
514             $self->{global}->{GLOBAL}{tree_fontHeight} < $self->{global}->{GLOBAL}{tree_itemHeight}
515             ? $self->{global}->{GLOBAL}{tree_fontHeight}
516             : $self->{global}->{GLOBAL}{tree_itemHeight}
517             ;
518              
519             } elsif ( $self->{global}->{GLOBAL}{tree_fontSize} && $self->{global}->{GLOBAL}{tree_fontSize} > 0 ) {
520              
521             $type_dimen = 'size';
522             $font_dimen =
523             $self->{global}->{GLOBAL}{tree_fontSize} < 0.625 * $self->{global}->{GLOBAL}{tree_itemHeight}
524             ? $self->{global}->{GLOBAL}{tree_fontSize}
525             : 0.625 * $self->{global}->{GLOBAL}{tree_itemHeight}
526             ;
527             }
528              
529             $self->{global}->{GLOBAL}{tree_fontName} ||= 'DejaVu Sans Mono';
530             my @items = [];
531             my $i = 0;
532             while ( my $directory = $self->{global}->{DIRECTORY}->{"directory_$i"} ) {
533             $self->{global}->{DIRECTORY}->{"directory_$i"} .= '/' unless $self->{global}->{DIRECTORY}->{"directory_$i"} =~ /\/$/;
534             $self->{global}->{DIRECTORY}->{"image_$i"} = '' unless $self->{global}->{DIRECTORY}->{"image_$i"};
535             $self->{images}->{"dir_$i"} =
536             $self-> load_icon( $self->{global}->{DIRECTORY}->{"image_$i"} )
537             || $self-> load_icon( "$CodeManager_directory/img/".$self->{global}->{DIRECTORY}->{"image_$i"} )
538             || $self-> load_icon( "$CodeManager_directory/img/nil.png" );
539             my $name = $self->{global}->{DIRECTORY}->{"name_$i"};
540             $name = $self->{global}->{DIRECTORY}->{name}.'-'.$i unless $name;
541             $items[0]->[$i][0] = [ $name, $self->{images}->{"dir_$i"}, 0, '', $directory, $i, $name ];
542             $items[0]->[$i][1] = [];
543              
544             my $ext_exclude = '\.~CodeManager'; $ext_exclude .= '|'.$self->{global}->{DIRECTORY}->{"ext_exclude_$i"} if $self->{global}->{DIRECTORY}->{"ext_exclude_$i"};
545             my $dir_exclude = '\.~CodeManager'; $dir_exclude .= '|'.$self->{global}->{DIRECTORY}->{"dir_exclude_$i"} if $self->{global}->{DIRECTORY}->{"dir_exclude_$i"};
546              
547              
548             # if ( $self->{global}->{DIRECTORY}->{"host_$i"} ) {
549             # $self->connect( $i );
550             # }
551              
552             $items[0]->[$i][1] = [] unless $self-> read_tree( $items[0]->[$i][1], $directory, 1, $i, $ext_exclude, $dir_exclude );
553             $items[0]->[$i][2] = $self->{expanded}->{$name} || 0;
554             $self->{list}->[$i] = $items[0]->[$i][0];
555             $i++;
556             }
557             $self->{listdim} = 1;
558             delete $self->{tree} if $self->{tree};
559              
560             $self->{tree} = $self->{frame_left}-> insert_to_frame(
561             1,
562             'CodeManager::Outline' =>
563             name => 'tree',
564             multiSelect => 0,
565             extendedSelect => 0,
566             path => './',
567             buffered => 0,
568             borderWidth => 1,
569             place => {
570             x=>0, relx => 0.5, width =>-6, relwidth => 1,
571             y=>-2, rely => 0.5, height =>-6, relheight => 1,
572             },
573             light3DColor=> $self->licz_kolor( 0xffffff, $project_color, 0.2 ),
574             dark3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.4 ),
575             darkColor => $self->licz_kolor( 0xf7f7f7, $self->angle_color( $int_color , 255, 220 ), 0 ),
576              
577             frameProfile => {
578             borderWidth => 1,
579             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
580             light3DColor=> $self->licz_kolor( 0xffffff, $project_color, 0.6 ),
581             dark3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.4 ),
582             },
583             items => @items,
584             indent => $self->{global}->{GLOBAL}{tree_itemIndent},
585             itemHeight => $self->{global}->{GLOBAL}{tree_itemHeight},
586             # multiSelect => 1,
587             hScroll => 1,
588             vScroll => 1,
589             popupFont => {
590             name => 'DejaVu Sans',
591             size => 9,
592             style => fs::Normal,
593             },
594             font => {
595             name => $self->{global}->{GLOBAL}{tree_fontName},
596             $type_dimen => $font_dimen,
597             style => fs::Normal,
598             },
599             onMouseClick => sub {
600             my ($this, $btn, $mod, $x, $y, $dblclk) = @_;
601             my $clicked = int( $this->topItem + ($self->{tree}-> height - $y)/$this-> itemHeight );
602             if ( $btn == 4 && !$dblclk ) {
603             $this-> deselect_all ();
604             $this-> select_item ( $clicked );
605             $this-> focusedItem ( $clicked );
606             $popup = $self->popup_show (
607             $this,
608             $clicked,
609             left => $self->{frame_left}-> left + $x,
610             bottom => $self->{frame_left}-> bottom + $y,
611             title => 'Making tree',
612             itemHeight => $this-> itemHeight,
613             );
614             }
615             my @arr = $this-> get_item( $clicked );
616             if ( $arr[0]->[0] ) {
617             my $fn = $arr[0]->[0]->[4].'/'.$arr[0]->[0]->[0];
618             if ( $arr[0]->[0]->[3] eq 'file' && $fn && -e $fn && $dblclk ) {
619             $self->file_edit( $fn, $arr[0]->[0]->[5] );
620             }
621             }
622             #we remember (for later refreshing) if the branch is expanded:
623             $self->{expanded}->{$arr[0]->[0]->[6]} = $arr[0]->[2] if defined $arr[0]->[2];
624             },
625             onKeyDown => sub {
626             my ($this, $code, $key, $mode) = @_;
627             # print "$this, $code, $key, $mode\n";
628             if ( $code == 13 ) {
629             my $current = $this->focusedItem;
630             my @arr = $this-> get_item( $current );
631             if ( $arr[0]->[0] ) {
632             my $fn = $arr[0]->[0]->[4].'/'.$arr[0]->[0]->[0];
633             if ( $arr[0]->[0]->[3] eq 'file' && $fn && -e $fn ) {
634             $self->file_edit( $fn, $arr[0]->[0]->[5] );
635             }
636             }
637             #we remember (for later refreshing) if the branch is expanded:
638             $self->{expanded}->{$arr[0]->[0]->[6]} = $arr[0]->[2] if defined $arr[0]->[2];
639             }
640             },
641             );
642              
643             $self->{tree}->set( topItem => $self->{expanded}->{topItem} ) if $self->{expanded}->{topItem};
644             $developer{ftt} = $self-> {frame_left}-> insert_to_frame (
645             0,
646             CheckList =>
647             items => [],
648             multiColumn => 0,
649             vertical => 1,
650             multiSelect => 1,
651             extendedSelect => 0,
652             place => {
653             x => 0, relx => 0.5, width => -6, relwidth => 1,
654             y => 0, rely => 0.5, height => -6, relheight => 1,
655             },
656             font => {
657             name => 'DejaVu Sans Mono',
658             size => 9,
659             style => fs::Normal,
660             },
661             frameProfile => {
662             borderWidth => 1,
663             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
664             light3DColor=> $self->licz_kolor( 0xffffff, $project_color, 0.6 ),
665             dark3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.4 ),
666             },
667             borderWidth => 1,
668             light3DColor=> $self->licz_kolor( 0xffffff, $project_color, 0.2 ),
669             dark3DColor => $self->licz_kolor( 0xffffff, $project_color, 0.2 ),
670             );
671             }
672              
673              
674             ####################################################################
675              
676             sub save
677             {
678             my $r = Prima::MsgBox::message_box (
679             'Project saving',
680             'Sorry! Project saving is not ready yet...', mb::OK
681             );
682             }
683              
684             ####################################################################
685              
686             sub read_tree {
687             my ( $self, $object, $dir, $level, $nr_of_dir, $ext_exclude, $dir_exclude ) = @_;
688             $dir =~ s/\/$//;
689              
690             my $k = 0;
691             my $type = '';
692             my @fils = $self-> read_dir( $dir, 'all', $nr_of_dir );
693             # @fils = sort_ext( @fils );
694             # @fils = sort mysort ( @fils );
695              
696             foreach (@fils) {
697             # ( $type, $_ ) = ( $1, $2 ) if $_ =~ /^(.*?)\-.*?([^\/]*)$/;
698             # if ( $type eq 'fil' ) {
699             $_ = $1 if $_ =~ /^.*?([^\/]*)$/;
700              
701             if ( -f "$dir/$_" ) {
702             next if $ext_exclude && $_ =~ /$ext_exclude$/;
703             $_ =~ /\.(\w+)$/;
704             my $ext = lc($1);
705             $ext = '' unless $ext;
706             $object->[$k][0] = [ $_, $self->{images}->{$ext}||$self->{images}->{nil}, $level, 'file', $dir, $nr_of_dir, "$dir/$_" ];
707             $self->{listdim} ++;
708             $self->{list}->[ $self->{listdim} ] = $object->[$k][0];
709             $k++;
710             }
711              
712             if ( -d "$dir/$_" ) {
713             next if $dir_exclude && $_ =~ /$dir_exclude$/;
714             $object->[$k][0] = [ $_, $self->{images}->{dir}, $level, '', $dir, $nr_of_dir, "$dir/$_" ];
715             $object->[$k][1] = [];
716             $object->[$k][1] = [] unless $self-> read_tree( $object->[$k][1], "$dir/$_", $level + 1, $nr_of_dir, $ext_exclude, $dir_exclude );
717             $object->[$k][2] = $self->{expanded}->{"$dir/$_"}||0;
718             $self->{listdim} ++;
719             $self->{list}->[ $self->{listdim} ] = $object->[$k][0];
720             $k++;
721             }
722             }
723              
724             return $k;
725             }
726              
727             ################################################################################
728              
729             sub read_dir {
730             my ( $self, $dir, $type, $nr_of_dir ) = @_;
731             my @contents;
732             if ( opendir(my $DIR, $dir )) {
733             @contents = readdir( $DIR );
734             closedir( $DIR );
735             }
736             # if ( $self->{global}->{sorting} =~ /names/i ) {
737             # print "sorting_$nr_of_dir = ",$self->{global}->{DIRECTORY}->{"sorting_$nr_of_dir"},"\n";
738              
739             if ( $self->{global}->{DIRECTORY}->{"sorting_$nr_of_dir"} =~ /name/i ) {
740             @contents = sort mysort @contents;
741             } else {
742             @contents = sort_ext( @contents );
743             }
744              
745             # @contents = sort @contents;
746              
747             # foreach my $ext (sort {lc($contents{$a}) cmp lc($contents{$b}) } keys %contents) {
748             # push @cont, $contents{$ext}
749             # }
750             # @contents = @cont;
751              
752             my @result;
753             $self->{global}->{GLOBAL}->{search_directories} ||= '';
754             foreach (@contents) {
755             if ( $_ ne '.' && $_ ne '..' ) {
756             if ( -d "$dir/$_" ) {
757             # push @result, "dir-$dir/$_"
758             push @result, "$dir/$_" if $type =~ /dir|all/ &&
759             ( $_ =~ /$self->{global}->{DIRECTORY}->{"directories_$nr_of_dir"}/i
760             || $self->{global}->{DIRECTORY}->{"directories_$nr_of_dir"} =~ /all/i
761             );
762             } else {
763             $_ =~ /\.(\w+)$/;
764             my $ext = $1 ? lc($1) : '';
765             $ext = '' unless $ext;
766             # push @result, "fil-$dir/$_"
767             push @result, "$dir/$_" if $type =~ /file|all/ &&
768             ( $_ =~ /$self->{global}->{DIRECTORY}->{"extensions_$nr_of_dir"}/i
769             || $self->{global}->{DIRECTORY}->{"extensions_$nr_of_dir"} =~ /all/i
770             );
771             }
772             }
773             }
774             return @result;
775             }
776             ################################################################################
777             sub close
778             {
779             my ( $self ) = shift;
780             my $nr = 0;
781             return 0;
782             }
783             ################################################################################
784             sub mysort
785             {
786             lc($a) cmp lc($b);
787             }
788             # ------------------------------------------------------------------------------
789             sub sort_ext
790             {
791             my %ext_contents;
792             while ( my $file = shift @_ ) {
793             my $ext = chr(254);
794             $ext = $1 if $file =~ /\.([^\.]*)$/;
795             $ext_contents{"ext_${ext}_$file"} = $file;
796             }
797             my @contents;
798             # according extentions:
799             foreach my $ext (sort mysort (keys(%ext_contents))) {
800             push @contents, $ext_contents{$ext}
801             }
802             # according names:
803             # foreach my $ext (sort {lc($ext_contents{$a}) cmp lc($ext_contents{$b}) } keys %ext_contents) {
804             # push @contents, $ext_contents{$ext}
805             # }
806             return @contents;
807             }
808             ################################################################################
809             sub make_notebook
810             {
811             my ( $self ) = shift;
812             my $fontSize = $self->{global}->{GLOBAL}{notebook_fontSize} + 0; $fontSize = 10 if $fontSize < 1;
813             my $fontName = $self->{global}->{GLOBAL}{notebook_fontName} || 'DejaVu Sans Mono';
814             my $sliderWidth = 4;
815             undef $developer{notes};
816             $developer{notes} = $self->{frame_top}->insert_to_frame (
817             1,
818             'CodeManager::TabbedScrollNotebook' =>
819             tabs => [],
820             place => {
821             x=>0, relx => 0.5, width =>-6, relwidth => 1,
822             y=>0, rely => 0.5, height=>-6, relheight => 1,
823             },
824             colored => 1,
825             enabled => 1,
826             style => tns::Standard,
827             font => {
828             name => $fontName,
829             size => $fontSize,
830             style => fs::Normal,
831             },
832             orientation => tno::Top,
833             borderWidth => 1,
834             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5 ),
835             arrangement => fra::Vertical,
836             size => [$self->{mw}-> size],
837             origin => [0,0],
838             # frameSizes => [qw(3% *)],
839             opaqueResize => 1,
840             );
841             # for ( my $page = 0; $page < $file_number; $page++ ) {
842             # Prima::Notebook::delete_page( $developer{notes}, $page, 1 ) ;
843             # }
844             @list_of_files = ();
845             $file_number = 0;
846             $developer{notes}-> set_tabs( @list_of_files );
847             $developer{notes}-> repaint;
848             }
849              
850             ################################################################################
851              
852             sub popup_show
853             {
854             my ( $self, $tree, $clicked ) = @_;
855             my @arr = $tree-> get_item( $clicked );
856             my $level = $arr[0]->[0]->[2];
857             my $name = $arr[0]->[0]->[0];
858             my $type = $arr[0]->[0]->[3]||'',
859             my $dir = $arr[0]->[0]->[4],
860             my $bra = $arr[0]->[0]->[5],
861             my %par;
862             my $i = 3;
863             while ( my $key = $_[$i] ) { $par{$key} = $_[$i+1]; $i += 2 }
864             $par{left} = 0 unless $par{left};
865             $par{bottom} = 0 unless $par{bottom};
866             $par{width} = 740;
867             $par{height} = 240;
868             my $x = [$self->{mw}->origin]->[0] + [$self->{frame_left}->pointerPos]->[0];
869             my $y = [$self->{mw}->origin]->[1] + [$self->{frame_left}->pointerPos]->[1] - $par{height} + $par{itemHeight};
870             my $tmp_popup = Prima::Dialog-> create(
871             title => $par{title},
872             text => $par{title},
873             origin => [ $x, $y ],
874             size => [ $par{width}, $par{height} ],
875             # borderIcons => 0,
876             # borderStyle => bs::None,
877             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.5, 0 ),
878             onPaint => sub {
879             my ( $this, $canvas) = @_;
880             $canvas-> clear;
881             $canvas-> color( $self->licz_kolor( 0xffffff, $project_color, 0.2, 0 ) );
882             $canvas-> bar( 0, 0, $this-> width, $this-> height);
883             my $margin = 2;
884             my $width = 1;
885             $canvas-> color( $self->licz_kolor( 0xffffff, $project_color, 0.8, 0 ) );
886             $canvas-> fillpoly([
887             $margin, $margin,
888             $margin, $this-> height - $margin - 1,
889             $this-> width - $margin - 1, $this-> height - $margin - 1,
890             $this-> width - $margin - 1, $margin
891             ]);
892             $canvas-> color( $self->licz_kolor( 0xffffff, $project_color, 0.5, 0 ) );
893             $canvas-> fillpoly([
894             $margin + $width, $margin + $width,
895             $margin + $width, $this-> height - $margin - 1 - $width,
896             $this-> width - $margin - 1 - $width, $this-> height - $margin - 1 - $width,
897             $this-> width - $margin - 1 - $width, $margin + $width
898             ]);
899             },
900             );
901             $tmp_popup->insert( Label =>
902             origin => [ 10, $par{height} - 30 ],
903             size => [ $par{width} - 20, 20 ],
904             text => $name,
905             flat => 1,
906             x_centered => 1,
907             alignment => ta::Center,
908             color => $self->licz_kolor( 0x000000, $project_color, 0.8, 0 ),
909             borderWidth => 1,
910             font => { size => 10, style => fs::Normal, },
911             );
912             $tmp_popup->insert( Button =>
913             origin => [ 10, 10 ],
914             size => [ 80, 20 ],
915             text => 'Cancel',
916             enabled => 1,
917             flat => 0,
918             color => 0x000000,
919             borderWidth => 1,
920             borderColor => 0xffffff,
921             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.8, 0 ),
922             font => { size => 9, style => fs::Normal, },
923             onClick => sub {
924             $tmp_popup->close;
925             undef $popup;
926             },
927             );
928             #----------------------------------------------------------------
929             my $input = $tmp_popup-> insert( InputLine =>
930             origin => [ 10, $par{height} -55 ],
931             size => [ 480, 20 ],
932             text => $name,
933             flat => 0,
934             alignment => ta::Left,
935             color => 0x000000,
936             borderWidth => 1,
937             font => {
938             size => 10,
939             style => fs::Normal,
940             },
941             backColor => 0xffffff,
942             );
943             #----------------------------------------------------------------
944             my @lista = split /\n/, $self->read_file( "$home_directory/templates/templates.ini" );
945             my @template_names = ('...');
946             my @template_files = ('' );
947             my $j = 0;
948             foreach (@lista) {
949             if ( $_ =~ /^(.*?)=(.*)$/ ) {
950             my ( $file, $name ) = ( $1, $2 );
951             $file =~ s/^\s*//; $file =~ s/\s*$//;
952             $name =~ s/^\s*//; $name =~ s/\s*$//;
953             next unless $file && $name;
954             if ( $file ne 'line' ) {
955             $j++;
956             push @template_files, $file;
957             push @template_names, "$j. $name";
958             } else {
959             push @template_names, "";
960             }
961             }
962             }
963             my $check1 = $tmp_popup-> insert( ComboBox =>
964             origin => [ 10, $par{height} -80 ],
965             size => [ 480, 20 ],
966             style => (cs::DropDownList),
967             items => [( @template_names )],
968             flat => 1,
969             font => {
970             size => 9,
971             style => fs::Normal,
972             },
973             );
974             #-------------------------------------------------------------
975             $tmp_popup-> insert( Button =>
976             origin => [ 500, $par{height} - 55 ],
977             size => [ 230, 20 ],
978             text => 'Insert',
979             enabled => 1,
980             flat => 0,
981             color => 0x000000,
982             borderWidth => 1,
983             borderColor => 0xffffff,
984             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.8, 0 ),
985             font => { size => 9, style => fs::Normal, },
986             onClick => sub {
987             if ( $input-> text eq '' ) {
988             Prima::message ( "No name!" );
989             } else {
990             my $go = 1;
991             foreach (@{$self->{list}}) {
992             if ( "$dir/$name" eq $_->[4] && $_->[3] eq '' ) {
993             if ( $input-> text eq $_->[0] ) {
994             $go = 0;
995             last;
996             }
997             }
998             }
999              
1000             if ( $go ) {
1001             my $tmp_name = "$name/";
1002             $tmp_name = '' unless $level;
1003             my $template_file = '';
1004             if ( $check1-> text =~ /(\d+)\./ ) { $template_file = $template_files[$1] if $1 }
1005             my $info = $self-> make_object (
1006             action => 'Insert',
1007             name => "$dir/$tmp_name".$input-> text,
1008             branch => $bra,
1009             template=> $template_file,
1010             );
1011             if ( $info eq 'OK' ) {
1012             $self-> make_tree;
1013             } else {
1014             Prima::message ( $info );
1015             }
1016             $tmp_popup-> close();
1017             undef $popup ;
1018             } else {
1019             Prima::message ( "The name [$name] already exists!" );
1020             }
1021             }
1022             },
1023             );
1024             #-------------------------------------------------------------
1025             $tmp_popup->insert( Button =>
1026             origin => [ 500, $par{height} - 80 ],
1027             size => [ 230, 20 ],
1028             text => 'Update',
1029             enabled => 1,
1030             flat => 0,
1031             color => 0x000000,
1032             borderWidth => 1,
1033             borderColor => 0xffffff,
1034             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.8, 0 ),
1035             font => { size => 9, style => fs::Normal, },
1036             onClick => sub {
1037             if ( $input->text eq '' ) {
1038             Prima::message ( "No name!" );
1039             } elsif ( $input->text eq $name ) {
1040             Prima::message ( "The same name!" );
1041             } else {
1042             my $info = $self-> make_object (
1043             action => 'Update',
1044             name => "$dir/".$input->text,
1045             branch => $bra,
1046             old_name => "$dir/".$name,
1047             );
1048             if ( $info eq 'OK' ) {
1049             $self-> make_tree;
1050             $tmp_popup->close();
1051             undef $popup ;
1052             } else {
1053             Prima::message ( $info );
1054             }
1055             }
1056             },
1057             );
1058             #-------------------------------------------------------------
1059             $tmp_popup->insert( Button =>
1060             origin => [ 500, $par{height} -105 ],
1061             size => [ 230, 20 ],
1062             text => 'Backup',
1063             enabled => 1,
1064             flat => 0,
1065             color => 0x000000,
1066             borderWidth => 1,
1067             borderColor => 0xffffff,
1068             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.8, 0 ),
1069             font => { size => 9, style => fs::Normal, },
1070             onClick => sub {
1071             my $info = $self-> make_object (
1072             action => 'Backup',
1073             name => "$dir/".$name,
1074             branch => $bra,
1075             );
1076             if ( $info eq 'OK' ) {
1077             my ( $x, $l ) = $tree-> get_item( $tree-> focusedItem );
1078             $tree-> delete_item ( $x );
1079             $tmp_popup->close();
1080             undef $popup ;
1081             } else {
1082             Prima::message ( $info );
1083             }
1084             },
1085             );
1086             #-------------------------------------------------------------
1087             $tmp_popup->insert( Button =>
1088             origin => [ 500, $par{height} -130 ],
1089             size => [ 230, 20 ],
1090             text => 'Copy',
1091             enabled => 1,
1092             flat => 0,
1093             color => 0x000000,
1094             borderWidth => 1,
1095             borderColor => 0xffffff,
1096             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.8, 0 ),
1097             font => { size => 9, style => fs::Normal, },
1098             onClick => sub {
1099             if ( $input->text eq '' ) {
1100             Prima::message ( "No name!" );
1101             } elsif ( $input->text eq $name ) {
1102             Prima::message ( "The same name!" );
1103             } else {
1104             my $info = $self-> make_object (
1105             action => 'Copy',
1106             old_name => "$dir/".$name,
1107             name => "$dir/".$input->text,
1108             branch => $bra,
1109             );
1110             if ( $info eq 'OK' ) {
1111             $self-> make_tree;
1112             $tmp_popup->close();
1113             undef $popup ;
1114             } else {
1115             Prima::message ( $info );
1116             }
1117             }
1118             },
1119             );
1120              
1121             #-------------------------------------------------------------
1122              
1123             $tmp_popup->insert( Button =>
1124             origin => [ 500, $par{height} -155 ],
1125             size => [ 230, 20 ],
1126             text => 'Delete',
1127             enabled => 1,
1128             flat => 0,
1129             color => 0x000000,
1130             borderWidth => 1,
1131             borderColor => 0xffffff,
1132             backColor => $self->licz_kolor( 0xffffff, $project_color, 0.8, 0 ),
1133             font => { size => 9, style => fs::Normal, },
1134             onClick => sub {
1135             my $info = $self-> make_object (
1136             action => 'Delete',
1137             name => "$dir/".$name,
1138             branch => $bra,
1139             );
1140             if ( $info eq 'OK' ) {
1141             my ( $x, $l ) = $tree-> get_item( $tree-> focusedItem );
1142             $tree-> delete_item ( $x );
1143             $tmp_popup->close();
1144             undef $popup ;
1145             } else {
1146             Prima::message ( $info );
1147             }
1148             },
1149             );
1150             #-------------------------------------------------------------
1151             $tmp_popup->insert( Button =>
1152             origin => [ 500, 10 ],
1153             size => [ 230, 20 ],
1154             text => 'find files with the text',
1155             enabled => 1,
1156             flat => 0,
1157             color => 0x000000,
1158             borderWidth => 1,
1159             borderColor => 0xffffff,
1160             backColor => $self-> licz_kolor( 0xffffff, $project_color, 0.8, 0 ),
1161             font => { size => 9, style => fs::Normal, },
1162             onClick => sub {
1163             my @files = ();
1164              
1165             foreach ( @{$self->{list}} ) {
1166             my $fn = $_->[4]."/".$_->[0];
1167             next unless $_->[3] eq 'file' && $fn =~ /$self->{global}->{DIRECTORY}->{"directory_$bra"}/;
1168             push @files, $fn if ftt_has_feature( $fn, $input-> text );
1169             }
1170              
1171             my $cap = join "\n",@files,"\n";
1172             $developer{ftt}-> set (
1173             items => [@files],
1174             onMouseClick => sub {
1175             my ($this, $btn, $mod, $x, $y, $dblclk ) = @_;
1176             my $clicked = int( $this-> topItem + ($developer{ftt}-> height - $y)/$this-> itemHeight );
1177             my $fn = $developer{ftt}-> items-> [$clicked] ? $developer{ftt}-> items-> [$clicked] : '';
1178             $self-> file_edit( $fn, $bra ) if $dblclk && -f $fn;
1179             }
1180             );
1181             $tmp_popup-> close();
1182             undef $popup ;
1183             },
1184             );
1185             $tmp_popup->execute;
1186             return $tmp_popup;
1187             }
1188              
1189             ########################################################################
1190              
1191             sub make_object
1192             {
1193             my ( $self ) = shift;
1194             my %par;
1195             while ( my $key = shift ) { $par{$key} = shift }
1196             return "No name defined!" unless $par{name};
1197             my $ext = '';
1198             my $default = '';
1199             if ( $par{name} =~ /\.([^\.\\\/]+)$/ ) {
1200             $ext = $1;
1201             $default = "$home_directory/templates/default/$ext.pl";
1202             }
1203              
1204             if ( $par{action} eq 'Insert' ) {
1205              
1206             if ( -e $par{name} ) {
1207              
1208             return "Object with the name: ['$par{name}'] already exists!";
1209              
1210             } else {
1211              
1212             # file is created when extension is defined:
1213             if ( $ext ) {
1214             # if there is template chosen:
1215             if ( $par{template} && -e "$home_directory/templates/".$par{template} ) {
1216             our @_ARGV = ( $self, $self->{global}->{DIRECTORY}->{"directory_".$par{branch}}, $par{name}, $par{branch}||0 );
1217             eval $self-> read_file( "$home_directory/templates/".$par{template});
1218             # next if there is a default extension template:
1219             } elsif ( -e $default ) {
1220             our @_ARGV = ( $self, $self->{global}->{DIRECTORY}->{"directory_".$par{branch}}, $par{name} );
1221             eval $self-> read_file( $default );
1222             # remain only to create empty file:
1223             } else {
1224              
1225             eval { $self-> write_to_file( $par{name}, '' ); };
1226             }
1227             } else {
1228             # if no extension there is a directory:
1229             # if there is template chosen:
1230             if ( $par{template} && -e "$home_directory/templates/".$par{template} ) {
1231              
1232             our @_ARGV = ( $self, $self->{global}->{DIRECTORY}->{"directory_".$par{branch}}, $par{name}, $par{branch}||0 );
1233             eval $self-> read_file( "$home_directory/templates/".$par{template} );
1234             # remain only to create empty directory (with .exists file only:
1235              
1236             } else {
1237             eval { make_path ( $par{name} ) };
1238             # $self->write_to_file( $par{name}.'/.exists','');
1239             }
1240             }
1241              
1242             return $@ || 'OK';
1243             }
1244              
1245             } elsif ( $par{action} eq 'Copy' ) {
1246              
1247             if ( -f $par{old_name} ) {
1248              
1249             eval { fcopy( $par{old_name}, $par{name} ) };
1250              
1251             } elsif ( -d $par{old_name} ) {
1252              
1253             eval { dircopy( $par{old_name}, $par{name} ) } ;
1254             }
1255              
1256             return $@ || 'OK';
1257              
1258             } elsif ( $par{action} eq 'Update' ) {
1259              
1260             if ( -f $par{old_name} ) {
1261              
1262             eval { move( $par{old_name}, $par{name} ) };
1263              
1264             } elsif ( -d $par{old_name} ) {
1265              
1266             eval { dirmove( $par{old_name}, $par{name} ) } ;
1267             }
1268              
1269             return $@ || 'OK';
1270              
1271             } elsif ( $par{action} eq 'Backup' ) {
1272              
1273             if ( -f $par{name} ) {
1274              
1275             eval { unlink( $par{name}.".~CodeManager" ) };
1276             return $@ if $@;
1277              
1278             eval { move( $par{name}, $par{name}.".~CodeManager" ) };
1279              
1280             } elsif ( -d $par{name} ) {
1281              
1282             eval { dirmove( $par{name}, $par{name}.".~CodeManager" ) } ;
1283             }
1284              
1285             return $@ || 'OK';
1286              
1287             } elsif ( $par{action} eq 'Delete' ) {
1288              
1289             my $what = Prima::MsgBox::message_box( 'Delete the file?', "Confirm deleting:\n".$par{name}, mb::YesNo );
1290              
1291             return unless $what == 2;
1292              
1293             if ( -f $par{name} ) {
1294              
1295             eval { unlink( $par{name} ) };
1296              
1297             } elsif ( -d $par{name} ) {
1298              
1299             eval { remove_tree( $par{name} ) };
1300             }
1301              
1302             return $@ || 'OK';
1303              
1304             } else {
1305              
1306             return "Incorect action: ".$par{action};
1307             }
1308             return '';
1309             }
1310              
1311             ################################################################################
1312              
1313             sub ftt_has_feature {
1314             my ( $name, $str ) = @_;
1315             if ( CORE::open( my $FH, "<$name" )) {
1316             my(@lines) = <$FH>;
1317             foreach (@lines) {
1318             return 1 if $_ =~ /$str/i;
1319             }
1320             CORE::close($FH);
1321             }
1322             return 0;
1323             }
1324              
1325             ##########################################################################
1326              
1327             sub meld
1328             {
1329             my ( $self ) = shift;
1330              
1331             my ( $file1, $file2 ) = splice( @Prima::CodeManager::list_of_files, -2 );
1332              
1333             system( "meld $file1 $file2 > /dev/null &") if -f $file1 && -f $file2;
1334              
1335             return
1336             }
1337              
1338             1;
1339              
1340             __END__