Changeset 6137
- Timestamp:
- 07/16/09 19:31:07 (3 years ago)
- File:
-
- 1 edited
-
branches/Padre-0.40/lib/Padre/Wx/Directory.pm (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/Padre-0.40/lib/Padre/Wx/Directory.pm
r6132 r6137 13 13 our @ISA = 'Wx::TreeCtrl'; 14 14 15 my %CACHED;16 my %SKIP = map { $_ => 1 } ( '.', '..', '.svn', 'CVS', '.git' );17 18 # TODO - This violates encapsulation.19 # Do not store application state in package variables.20 my $current_dir;21 my $current_item;22 23 15 sub new { 24 16 my $class = shift; … … 33 25 | Wx::wxTR_FULL_ROW_HIGHLIGHT 34 26 ); 27 28 $self->{SKIP} = { map { $_ => 1 } ( '.', '..', '.svn', 'CVS', '.git' ) }; 29 $self->{CACHED} = {}; 30 $self->{force_next} = 0; 31 $self->{current_item} = {}; 32 $self->{current_project} = ''; 33 34 $self->_setup_events; 35 $self->_add_root(); 36 35 37 $self->SetIndent(10); 36 $self->{force_next} = 0; 37 38 Wx::Event::EVT_TREE_ITEM_ACTIVATED( 39 $self, $self, 40 sub { 41 $self->on_tree_item_activated( $_[1] ); 42 }, 43 ); 44 45 Wx::Event::EVT_SET_FOCUS( 46 $self, 47 \&_on_focus 48 ); 49 50 Wx::Event::EVT_TREE_ITEM_MENU( 51 $self, $self, 52 \&_on_tree_item_menu, 53 ); 54 55 Wx::Event::EVT_TREE_SEL_CHANGED( 56 $self, $self, 57 \&_on_tree_sel_changed, 58 ); 59 60 Wx::Event::EVT_TREE_ITEM_EXPANDING( 61 $self, $self, 62 \&_on_tree_item_expanding, 63 ); 64 65 Wx::Event::EVT_TREE_ITEM_COLLAPSING( 66 $self, $self, 67 \&_on_tree_item_collapsing, 68 ); 69 70 Wx::Event::EVT_TREE_BEGIN_LABEL_EDIT( 71 $self, $self, 72 \&_on_tree_begin_label_edit, 73 ); 74 75 Wx::Event::EVT_TREE_END_LABEL_EDIT( 76 $self, $self, 77 \&_on_tree_end_label_edit, 78 ); 79 80 my $root = $self->AddRoot( 81 Wx::gettext('Directory'), 82 -1, 83 -1, 84 Wx::TreeItemData->new('') 85 ); 86 87 $self->GetBestSize; 88 $self->Thaw; 89 90 $self->Hide; 38 39 # Do they need to be used? 40 # $self->GetBestSize; 41 # $self->Thaw; 42 # $self->Hide; 91 43 92 44 return $self; … … 110 62 111 63 sub clear { 112 unless ( $_[0]->current->filename ) { 113 $_[0]->DeleteChildren( $_[0]->GetRootItem ); 114 $current_dir = ""; 64 my $self = shift; 65 unless ( $self->current->filename ) { 66 $self->DeleteChildren( $self->GetRootItem ); 67 $self->{current_project} = ''; 115 68 } 116 69 return; … … 127 80 } 128 81 82 sub _setup_events { 83 my $self = shift; 84 Wx::Event::EVT_TREE_ITEM_ACTIVATED( 85 $self, $self, 86 \&_on_tree_item_activated 87 ); 88 89 Wx::Event::EVT_SET_FOCUS( 90 $self, 91 \&_on_focus 92 ); 93 94 Wx::Event::EVT_TREE_ITEM_MENU( 95 $self, $self, 96 \&_on_tree_item_menu, 97 ); 98 99 Wx::Event::EVT_TREE_SEL_CHANGED( 100 $self, $self, 101 \&_on_tree_sel_changed, 102 ); 103 104 Wx::Event::EVT_TREE_ITEM_EXPANDING( 105 $self, $self, 106 \&_on_tree_item_expanding, 107 ); 108 109 Wx::Event::EVT_TREE_ITEM_COLLAPSING( 110 $self, $self, 111 \&_on_tree_item_collapsing, 112 ); 113 114 Wx::Event::EVT_TREE_BEGIN_LABEL_EDIT( 115 $self, $self, 116 \&_on_tree_begin_label_edit, 117 ); 118 119 Wx::Event::EVT_TREE_END_LABEL_EDIT( 120 $self, $self, 121 \&_on_tree_end_label_edit, 122 ); 123 124 } 125 126 sub _add_root { 127 my ( $self, $name, $data ) = @_; 128 129 $name |= Wx::gettext('Directory'); 130 $data |= {}; 131 132 $self->AddRoot( 133 $name, 134 -1, 135 -1, 136 Wx::TreeItemData->new($data) 137 ); 138 } 139 129 140 ##################################################################### 130 141 # Event Handlers 131 142 132 sub on_tree_item_activated { 133 my ( $self, $event ) = @_; 134 135 my $itemObj = $event->GetItem; 136 my $item = $self->GetPlData($itemObj); 137 138 return if not defined $item; 139 140 if ( $item->{type} eq "folder" ) { 141 $self->Toggle($itemObj); 142 return; 143 } 144 145 my $path = File::Spec->catfile( $item->{dir}, $item->{name} ); 146 return if not defined $path; 147 my $main = $self->main; 148 if ( my $id = $main->find_editor_of_file($path) ) { 149 my $page = $main->notebook->GetPage($id); 150 $page->SetFocus; 151 } else { 152 $main->setup_editors($path); 153 } 154 return; 155 } 156 157 sub list_dir { 158 my $dir = shift; 159 my @data; 160 161 if ( UpdatedDir($dir) ) { 162 163 $CACHED{$dir}->{Change} = ( stat $dir )[10]; 143 sub _list_dir { 144 my ( $self, $dir ) = @_; 145 146 my $cached = $self->{CACHED}->{$dir}; 147 148 if ( $self->_updated_dir($dir) ) { 149 150 $cached->{Change} = ( stat $dir )[10]; 164 151 165 152 if ( opendir my $dh, $dir ) { 166 153 167 my @items = sort { lc($a) cmp lc($b) } grep { not $SKIP{$_} } readdir $dh; 168 @items = grep { not /^\./ } @items unless $CACHED{$dir}->{ShowHidden}; 169 154 my @items = sort { lc($a) cmp lc($b) } grep { not $self->{SKIP}->{$_} } readdir $dh; 155 156 157 unless ( $cached->{ShowHidden} ) { 158 159 ##################################################################### 160 # Show/Hide Windows hidden files and directories - NEED TO BE TESTED 161 # 162 # if ( $^O !~ /^win32/i ) { 163 # require Win32::File; 164 # my $attribs; 165 # @items = grep { Win32::File::GetAttributes( $_, $attribs ) and !( $attribs & HIDDEN ) } @items; 166 # } 167 # else { 168 # 169 @items = grep { not /^\./ } @items; 170 171 # 172 # } 173 ##################################################################### 174 } 175 176 my @data; 170 177 foreach my $thing (@items) { 171 178 my $path = File::Spec->catfile( $dir, $thing ); … … 178 185 } 179 186 180 @{ $ CACHED{$dir}->{Data} } = sort { $b->{isDir} <=> $a->{isDir} } @data;187 @{ $cached->{Data} } = sort { $b->{isDir} <=> $a->{isDir} } @data; 181 188 closedir $dh; 182 189 } 183 190 } 184 return $CACHED{$dir}->{Data}; 185 } 186 187 sub UpdatedDir { 188 my $dir = shift; 189 my $dirChange = ( stat $dir )[10]; 190 return ( !defined $CACHED{$dir} 191 || !$CACHED{$dir}->{Data} 192 || !$CACHED{$dir}->{Change} 193 || $dirChange != $CACHED{$dir}->{Change} ) ? 1 : 0; 194 } 191 return $cached->{Data}; 192 } 193 195 194 196 195 sub update_gui { … … 203 202 || File::Basename::dirname($filename); 204 203 205 my $updated = UpdatedDir($dir); 206 list_dir($dir); 207 return unless @{ $CACHED{$dir}->{Data} }; 208 209 my $directory = $self->main->directory; 210 my $root = $directory->GetRootItem; 211 212 if ( ( defined($current_dir) and $current_dir ne $dir ) or $updated ) { 213 $directory->DeleteChildren($root); 214 _update_treectrl( $directory, $CACHED{$dir}->{Data}, $root ); 215 } 216 217 $current_dir = $dir; 218 _update_subdirs( $directory, $root ); 204 my $updated = $self->_updated_dir($dir); 205 my $data = $self->_list_dir($dir); 206 return unless @{$data}; 207 208 my $root = $self->GetRootItem; 209 my $project = $self->{current_project}; 210 211 if ( ( defined($project) and $project ne $dir ) or $updated ) { 212 $self->DeleteChildren($root); 213 _update_treectrl( $self, $data, $root ); 214 } 215 216 $project = $dir; 217 _update_subdirs( $self, $root ); 218 } 219 220 sub _updated_dir { 221 my $self = shift; 222 my $dir = shift; 223 my $cached = $self->{CACHED}->{$dir}; 224 225 if ( not defined($cached) or !$cached->{Data} or !$cached->{Change} or ( stat $dir )[10] != $cached->{Change} ) { 226 return 1; 227 } 228 return 0; 219 229 } 220 230 221 231 sub _update_subdirs { 222 232 my ( $self, $root ) = @_; 233 my $project = $self->{current_project}; 223 234 224 235 my $cookie; … … 232 243 if ( defined $itemData->{type} 233 244 and $itemData->{type} eq 'folder' 234 and defined $ CACHED{$current_dir}->{Expanded}->{$path} )245 and defined $self->{CACHED}->{$project}->{Expanded}->{$path} ) 235 246 { 236 247 237 248 $self->Expand($node); 238 249 239 if ( UpdatedDir($path) ) {250 if ( $self->_updated_dir($path) ) { 240 251 $self->DeleteChildren($node); 241 _update_treectrl( $self, list_dir($path), $node );252 _update_treectrl( $self, $self->_list_dir($path), $node ); 242 253 } 243 254 _update_subdirs( $self, $node ); 244 255 } 245 if ( defined $ current_item->{$current_dir} and $current_item->{$current_dir} eq $path ) {256 if ( defined $self->{current_item}->{$project} and $self->{current_item}->{$project} eq $path ) { 246 257 $self->SelectItem($node); 247 258 $self->ScrollTo($node); … … 254 265 my $main = $self->main; 255 266 256 if ( $main->has_directory ) { 257 $main->directory->update_gui; 258 } 267 $self->update_gui if $main->has_directory; 268 } 269 270 sub _on_tree_item_activated { 271 my ( $self, $event ) = @_; 272 273 my $itemObj = $event->GetItem; 274 my $item = $self->GetPlData($itemObj); 275 276 return if not defined $item; 277 278 if ( $item->{type} eq "folder" ) { 279 $self->Toggle($itemObj); 280 return; 281 } 282 283 my $path = File::Spec->catfile( $item->{dir}, $item->{name} ); 284 return if not defined $path; 285 my $main = $self->main; 286 if ( my $id = $main->find_editor_of_file($path) ) { 287 my $page = $main->notebook->GetPage($id); 288 $page->SetFocus; 289 } else { 290 $main->setup_editors($path); 291 } 292 return; 259 293 } 260 294 … … 277 311 my $newFile = File::Spec->catfile( $itemData->{dir}, $newLabel ); 278 312 313 if ( -e $newFile ){ 314 $event->Veto(); 315 return; 316 } 317 279 318 if ( rename $oldFile, $newFile ) { 280 319 281 320 $itemData->{name} = $newLabel; 282 $current_item->{$current_dir} = $newFile; 283 284 if ( defined $CACHED{$current_dir}->{Expanded}->{$oldFile} ) { 285 $CACHED{$current_dir}->{Expanded}->{$newFile} = 1; 286 delete $CACHED{$current_dir}->{Expanded}->{$oldFile}; 321 my $project = $self->{current_project}; 322 $self->{current_item}->{$project} = $newFile; 323 324 my $cached = $self->{CACHED}; 325 326 if ( defined $cached->{$project}->{Expanded}->{$oldFile} ) { 327 $cached->{$project}->{Expanded}->{$newFile} = 1; 328 delete $cached->{$project}->{Expanded}->{$oldFile}; 287 329 } 288 330 map { 289 $ CACHED{ $newFile . ( defined $1 ? $1 : '' ) } = $CACHED{$_}, delete $CACHED{$_}331 $cached->{ $newFile . ( defined $1 ? $1 : '' ) } = $cached->{$_}, delete $cached->{$_} 290 332 if $_ =~ m#^$oldFile(\/.+)?$# 291 } keys % CACHED;333 } keys %$cached; 292 334 } else { 293 335 $event->Veto(); … … 300 342 my $itemData = $self->GetPlData($itemObj); 301 343 if ( ref $itemData eq 'HASH' ) { 302 $current_item->{$current_dir} = File::Spec->catfile( $itemData->{dir}, $itemData->{name} ); 344 $self->{current_item}->{ $self->{current_project} } = 345 File::Spec->catfile( $itemData->{dir}, $itemData->{name} ); 303 346 } 304 347 } … … 313 356 314 357 my $path = File::Spec->catfile( $itemData->{dir}, $itemData->{name} ); 315 $ CACHED{$current_dir}->{Expanded}->{$path} = 1;316 317 if ( UpdatedDir($path) or !$self->GetChildrenCount($itemObj) ) {358 $self->{CACHED}->{ $self->{current_project} }->{Expanded}->{$path} = 1; 359 360 if ( $self->_updated_dir($path) or !$self->GetChildrenCount($itemObj) ) { 318 361 $self->DeleteChildren($itemObj); 319 _update_treectrl( $self, list_dir($path), $itemObj );362 _update_treectrl( $self, $self->_list_dir($path), $itemObj ); 320 363 } 321 364 } … … 329 372 if ( defined( $itemData->{type} ) && $itemData->{type} eq 'folder' ) { 330 373 my $path = File::Spec->catfile( $itemData->{dir}, $itemData->{name} ); 331 delete $ CACHED{$current_dir}->{Expanded}->{$path};374 delete $self->{CACHED}->{ $self->{current_project} }->{Expanded}->{$path}; 332 375 } 333 376 } 334 377 335 378 sub _on_tree_item_menu { 336 my ( $ dir, $event ) = @_;379 my ( $self, $event ) = @_; 337 380 338 381 my $itemObj = $event->GetItem; 339 my $itemData = $dir->GetPlData($itemObj); 340 my $SelectDir = $itemData->{dir}; 341 342 if ( defined $itemData ) { 343 344 my $menu = Wx::Menu->new; 345 346 if ( defined( $itemData->{type} ) 347 && $itemData->{type} eq 'folder' ) 382 my $item_data = $self->GetPlData($itemObj); 383 384 if ( defined $item_data ) { 385 386 my $menu = Wx::Menu->new; 387 my $selected_dir = $item_data->{dir}; 388 389 ################################################ 390 # Default action - same when the item is activated 391 # 392 if ( defined $item_data->{type} 393 and $item_data->{type} eq 'folder' ) 348 394 { 349 395 my $default = $menu->Append( -1, Wx::gettext("Expand / Collapse") ); 350 396 Wx::Event::EVT_MENU( 351 $dir, $default, 352 sub { 353 $dir->Toggle($itemObj); 354 } 397 $self, $default, 398 sub { $self->Toggle($itemObj) }, 355 399 ); 356 400 } else { 357 401 my $default = $menu->Append( -1, Wx::gettext("Open File") ); 358 402 Wx::Event::EVT_MENU( 359 $dir, $default, 360 sub { 361 $dir->on_tree_item_activated($event); 362 }, 403 $self, $default, 404 sub { $self->on_tree_item_activated($event) }, 363 405 ); 364 406 } … … 366 408 $menu->AppendSeparator(); 367 409 410 ############################################# 411 # Rename and/or move the item 368 412 my $rename = $menu->Append( -1, Wx::gettext("Rename") ); 369 413 Wx::Event::EVT_MENU( 370 $ dir, $rename,414 $self, $rename, 371 415 sub { 372 $ dir->EditLabel($itemObj);416 $self->EditLabel($itemObj); 373 417 }, 374 418 ); 375 419 376 420 377 if ( defined ( $itemData->{type} )378 && ( $itemData->{type} eq 'modules' || $itemData->{type} eq 'pragmata' ) )421 if ( defined $item_data->{type} 422 and ( $item_data->{type} eq 'modules' or $item_data->{type} eq 'pragmata' ) ) 379 423 { 380 424 my $pod = $menu->Append( -1, Wx::gettext("Open &Documentation") ); 381 425 Wx::Event::EVT_MENU( 382 $ dir, $pod,426 $self, $pod, 383 427 sub { 384 428 … … 386 430 require Padre::Wx::DocBrowser; 387 431 my $help = Padre::Wx::DocBrowser->new; 388 $help->help( $item Data->{name} );432 $help->help( $item_data->{name} ); 389 433 $help->SetFocus; 390 434 $help->Show(1); … … 397 441 398 442 ##################################################################### 399 # Shows / Hides dot started files and folers 443 # Shows / Hides dot started files and folers (N/A on Windows) 400 444 if ( $^O !~ /^win32/i ) { 445 401 446 my $hiddenFiles = $menu->AppendCheckItem( -1, Wx::gettext("Show hidden files") ); 402 403 $SelectDir = File::Spec->catfile( $itemData->{dir}, $itemData->{name} ) if $itemData->{type} eq 'folder'; 404 405 my $show = $CACHED{$SelectDir}->{ShowHidden}; 447 if ( $item_data->{type} eq 'folder' ) { 448 $selected_dir = File::Spec->catfile( $item_data->{dir}, $item_data->{name} ); 449 } 450 my $cached = $self->{CACHED}->{$selected_dir}; 451 my $show = $cached->{ShowHidden}; 406 452 $hiddenFiles->Check($show); 407 453 408 454 Wx::Event::EVT_MENU( 409 $ dir,455 $self, 410 456 $hiddenFiles, 411 457 sub { 412 $ CACHED{$SelectDir}->{ShowHidden} = !$show;413 delete $ CACHED{$SelectDir}->{Data};458 $cached->{ShowHidden} = !$show; 459 delete $cached->{Data}; 414 460 }, 415 461 ); … … 417 463 ##################################################################### 418 464 # Updates the directory listing 419 420 465 my $reload = $menu->Append( -1, Wx::gettext("Reload") ); 421 466 Wx::Event::EVT_MENU( 422 $ dir, $reload,467 $self, $reload, 423 468 sub { 424 delete $ CACHED{ $dir->GetPlData($itemObj)->{dir} }->{Change};469 delete $self->{CACHED}->{ $self->GetPlData($itemObj)->{dir} }->{Change}; 425 470 } 426 471 ); 427 472 473 ##################################################################### 474 # Pops up the context menu 428 475 my $x = $event->GetPoint->x; 429 476 my $y = $event->GetPoint->y; 430 $ dir->PopupMenu( $menu, $x, $y );477 $self->PopupMenu( $menu, $x, $y ); 431 478 } 432 479 return;
Note: See TracChangeset
for help on using the changeset viewer.
