Index: /extras/pLoader/trunk/src/Uploader/GUI/wxApp.pm
===================================================================
--- /extras/pLoader/trunk/src/Uploader/GUI/wxApp.pm	(revision 3226)
+++ /extras/pLoader/trunk/src/Uploader/GUI/wxApp.pm	(revision 3227)
@@ -302,4 +302,8 @@
           locale
           current_language
+          version
+          imagelist_version
+          use_offline
+          login_dlg
       / 
 );
@@ -313,6 +317,16 @@
 }
 
+
 sub OnInit {
     my( $self ) = @_;
+    
+    $self->version(
+        '2.0.1a'
+    );
+    
+    # to check if we can use stored cache
+    $self->imagelist_version(
+        '2'
+    );
 
     Wx::InitAllImageHandlers();
@@ -353,33 +367,49 @@
         $self->{current_language}||wxLANGUAGE_ENGLISH
     );
-
     
     $self->init_locale;
-    
-
-
-    my $ok = $self->Login();
+
+    my $not_exit = $self->Login();
     # user pressed OK
-    if($ok){
-        $self->pwg(
-            # get these parameters from dialog or from file
-            Uploader::PWG->new(
-                {
-                    site_url       => $self->site_url,
-                    site_username  => $self->site_username,
-                    site_password  => $self->site_password,
-                }
-            )
-        );
-      
-    
+    if($not_exit){
+    	if( !$self->use_offline ){
+            while( $not_exit and !$self->_is_connected ){
+            	$not_exit = $self->Login();
+            }
+    	}
         $self->_init_imagelist;
         $self->_init_thumbimagelist;
-        
         $self->_init_frame;
     }
 
-    $ok;
-}
+    $not_exit;
+}
+
+
+sub _is_connected {
+    my ( $self ) = @_;
+
+    my $is_connected;
+
+    if($self->pwg->login_result->{stat} eq 'ok'){
+        $is_connected = 1;
+    }
+    else{
+        Wx::MessageBox( 
+            sprintf(
+                "%s\n\n%s %s %s",
+                $self->pwg->login_result->{message},
+                gettext("Connection to"),
+                $self->site_url,
+                gettext("failed"),
+            ),
+            gettext("Piwigo login error"),
+            wxOK | wxICON_EXCLAMATION, 
+        );
+    }
+    
+    $is_connected;
+}
+
 
 my $locale;
@@ -397,5 +427,5 @@
     $locale->AddCatalogLookupPathPrefix( '../locale');
     if(!$locale->AddCatalog( 'pLoader.mo' )){
-        print "Cannot find translation catalog files. Use default language\n";
+        Wx::LogMessage gettext("Cannot find translation catalog files. Use default language");
     }
 	
@@ -428,4 +458,6 @@
     my $stored_imagelist;
     
+    my $use_new_imagelist;
+    
     if( -e $self->storable_file ){
         eval {
@@ -434,14 +466,26 @@
         if($@){
             Wx::LogMessage(
-                "An error has occured. Can not read %s\n%s",
+                gettext("An error has occured. Can not read %s\n%s"),
                 $self->storable_file,
                 $@
             );
-            $stored_imagelist = $self->_default_imagelist_params ;
+            $use_new_imagelist = 1 ;
         }
+        # should have a valid imagelist
+        else{
+            $use_new_imagelist = 1 unless $self->imagelist_version eq $stored_imagelist->{imagelist_version};
+            if($use_new_imagelist){
+            	Wx::LogMessage(gettext("pLoader has to reset image cache."));
+            }
+        }
     }
     else{
+        $use_new_imagelist = 1 ;
+    }
+
+    if($use_new_imagelist){
         $stored_imagelist = $self->_default_imagelist_params ;
     }
+
 
     $self->imagelist(
@@ -449,4 +493,8 @@
             $stored_imagelist
         )
+    );
+
+    $self->imagelist->RescaleCallback(
+        sub { $self->RescaleImage(@_) }
     );
 
@@ -483,9 +531,13 @@
       	count            => 0,
         storable_file    => $self->storable_file,
-        images           => [],
         userdata_dir     => $self->userdata_dir,
         default_name_prefix => 'Photo',
-        upload_rejects  =>  [],
-        ResizeCallback  => sub { $self->ResizeImage(@_) },
+        upload_rejects   =>  [],
+        image_sums       => {},
+        sums             => [],
+        version          => $self->version,
+        imagelist_version => $self->imagelist_version,
+        RescaleCallback  => sub { $self->RescaleImage(@_) },
+        ResizeCallback   => sub { $self->ResizeImage(@_) },
     };
 
@@ -496,20 +548,34 @@
     my ( $self ) = @_;	
 
-    my $dlg = Uploader::GUI::wxLoginDlg->new(
-        {
-            title         => gettext("Piwigo login"),
-            site_url      => sub { $self->site_url(@_) },
-            site_username => sub { $self->site_username(@_) },	
-            site_password => sub { $self->site_password(@_) },	
-        }
-    );
+    $self->login_dlg( 
+        Uploader::GUI::wxLoginDlg->new(
+            {
+                title         => gettext("Piwigo login"),
+                site_url      => sub { $self->site_url(@_) },
+                site_username => sub { $self->site_username(@_) },	
+                site_password => sub { $self->site_password(@_) },
+                use_offline   => sub { $self->use_offline(@_) },	
+            }
+        )
+    ) unless $self->login_dlg;
 
     my $icon = Wx::Icon->new();
     $icon->LoadFile('../res/favicon.ico', wxBITMAP_TYPE_ICO);
-    $dlg->SetIcon($icon);	
-
-    
-    my $rval = $dlg->ShowModal();
-    $dlg->Destroy;
+    $self->login_dlg->SetIcon($icon);	
+
+    
+    my $rval = $self->login_dlg->ShowModal();
+    $self->login_dlg->Show(0);
+
+    $self->pwg(
+        # get these parameters from dialog or from file
+        Uploader::PWG->new(
+            {
+                site_url       => $self->site_url,
+                site_username  => $self->site_username,
+                site_password  => $self->site_password,
+            }
+        )
+    );
     
     $rval;
@@ -605,15 +671,17 @@
     
     my $wximagelist = $self->imagelist->wx_thumb_imglist;
-    my $images = $self->imagelist->images;
+    my $sums = $self->imagelist->sums;
 
     map {
+    	my $image = $self->imagelist->image_sums->{$_};
+
         $wximagelist->Add(
             Wx::Bitmap->new( 
-                $_->wx_thumb_file, 
+                $image->wx_thumb_file, 
                 $self->GetWxBitmapType($self->imagelist->type), 
             )
         );
     }
-    @$images ;
+    @$sums ;
 
 }
@@ -626,5 +694,5 @@
 
 
-sub ResizeImage {
+sub RescaleImage {
     my ( $self, $image_file, $image_file_out, $type, $ratio, $width, $height, $quality ) = @_;
    
@@ -682,5 +750,5 @@
     )){
     	Wx::LogMessage(
-    	    "An error has occured. Can not save file %s",
+    	    gettext("An error has occured. Can not save file %s"),
     	    $image_file_out,
     	)
@@ -688,6 +756,68 @@
 }
 
+sub ResizeImage {
+    my ( $self, $image_file, $image_file_out, $type, $width, $height, $quality ) = @_;
+   
+
+    my $image = Wx::Image->new(
+            $image_file, 
+            $self->GetWxBitmapType($type),
+            0
+    );
+
+    my $w;
+    my $h;
+
+    my $img_w = $image->GetWidth;
+    my $img_h = $image->GetHeight;
+    
+        # portrait
+        if( $img_w < $img_h ){
+            $w = $height;
+        }
+        else{
+            $w = $width;
+        }
+        # to respect aspect ratio
+        $h = sprintf(
+            "%.0f",
+            ($w*$img_h)/$img_w
+        );
+
+    
+
+    $image->Rescale(
+        $w,
+        $h,
+        wxIMAGE_QUALITY_HIGH
+    );
+
+    $image->Resize(
+        [ $width, $height ], [ 0, 20],
+    );
+    
+    $quality ||= 90;
+    
+    $image->SetOption( 
+        "quality", 
+        $quality 
+    );
+    
+    if(!$image->SaveFile(
+        $image_file_out,
+        $self->GetWxBitmapType($type),
+    )){
+    	Wx::LogMessage(
+    	    gettext("An error has occured. Can not save file %s"),
+    	    $image_file_out,
+    	)
+    };
+}
+
+
+
+
 sub _init_frame {
-    my ( $self ) = @_ ;	
+    my ( $self ) = @_;	
 
     my $config = Wx::ConfigBase::Get;
@@ -699,26 +829,10 @@
     my $sv = $config->ReadInt( "splitVertical", 150 );
     my $sh = $config->ReadInt( "splitHorizontal", 300 );
-	
-    my $url;
-    my $is_connected;
-    if($self->pwg->login_result->{stat} eq 'ok'){
-        $url = $self->site_url;
-        $is_connected = 1;    
-    }
-    else{
-        $url = gettext("Not connected");
-        Wx::MessageBox( 
-            sprintf(
-                "%s\n\n%s %s %s",
-                $self->pwg->login_result->{message},
-                gettext("Connection to"),
-                $self->site_url,
-                gettext("failed"),
-            ),
-            gettext("Piwigo login error"),
-            wxOK | wxICON_EXCLAMATION, 
-        );
-    }	
-    	
+    
+    my $url = $self->site_url;
+    
+    if($self->use_offline){
+    	$url = gettext("Work Offline");
+    }
 
     my ( $frame ) = Uploader::GUI::wxFrameAUI->new( 
@@ -728,8 +842,7 @@
             width     => $w,
             height    => $h,
-            title     => "pLoader - Piwigo uploader 2.0.1a - [$url]" ,
+            title     => sprintf("pLoader - Piwigo uploader %s - [%s]", $self->version, $url),
             pwg       => $self->pwg,
             imagelist => $self->imagelist,
-            is_connected => $is_connected,
         }
     );
@@ -743,9 +856,5 @@
     $icon->LoadFile('../res/favicon.ico', wxBITMAP_TYPE_ICO);
     $frame->SetIcon($icon);	
-
-
-    return 1;
-}
-
+}
 
 sub _readParams {
Index: /extras/pLoader/trunk/src/Uploader/GUI/wxFrameAUI.pm
===================================================================
--- /extras/pLoader/trunk/src/Uploader/GUI/wxFrameAUI.pm	(revision 3226)
+++ /extras/pLoader/trunk/src/Uploader/GUI/wxFrameAUI.pm	(revision 3227)
@@ -298,4 +298,5 @@
 use File::Spec;
 use Wx::Locale qw/:default/;
+use Encode qw/encode decode is_utf8/;;
 
 
@@ -333,6 +334,5 @@
           thumbnail_settings
           preview_settings
-          is_connected
-
+          toolbar
       /;
 __PACKAGE__->mk_accessors( @properties );
@@ -346,5 +346,6 @@
           EVT_LIST_ITEM_SELECTED
           EVT_TREE_ITEM_RIGHT_CLICK
-          EVT_LIST_KEY_DOWN       
+          EVT_LIST_KEY_DOWN
+          EVT_UPDATE_UI       
       /;
       
@@ -373,7 +374,4 @@
                                       wxDEFAULT_FRAME_STYLE|wxMAXIMIZE
                                    );
-    $self->is_connected(
-        $params->{is_connected}
-    );
     $self->pwg( $params->{pwg} );
     $self->imagelist( $params->{imagelist} );
@@ -467,19 +465,19 @@
             },
             {
-                label => "Comment :",
+                label => gettext("Comment :"),
                 value => sub { $self->imagelist->current_image->site_comment(@_) },
                 type  => "LongText",
             },
             {
-                label => "Author :",
+                label => gettext("Author :"),
                 value => sub { $self->imagelist->current_image->site_author(@_) },
             },
             {
-                label    => "File name :",
+                label    => gettext("File name :"),
                 value    => sub { $self->imagelist->current_image->file(@_) },
                 readonly => 1,
             },
             {
-                label    => "Create date :",
+                label    => gettext("Create date :"),
                 value    => sub { $self->imagelist->current_image->create_date(@_) },
                 readonly => 1,
@@ -699,6 +697,6 @@
     $self->init_aui;
     $self->init_dnd_targets;
-
     if( $self->imagelist->wx_thumb_imglist->GetImageCount){
+printf("%s images\n", $self->imagelist->wx_thumb_imglist->GetImageCount); 
     	$self->ShowImageViewer;
         
@@ -876,5 +874,9 @@
 
 sub init_aui {
-    my ( $self ) = @_;	
+    my ( $self ) = @_;
+    
+    my $url = wxTheApp->site_url;
+    
+    $url = gettext("empty - work Offline") if wxTheApp->use_offline;
 
     $self->manager->AddPane
@@ -884,5 +886,5 @@
     $self->manager->AddPane
       ( $self->create_tree, Wx::AuiPaneInfo->new->Name( "categories" )->Caption(
-          sprintf("%s - %s", gettext("Piwigo categories"), wxTheApp->site_url )
+          sprintf("%s - %s", gettext("Piwigo categories"), $url )
       )
         ->Right->Position( 0 )->Resizable->CloseButton(0) );
@@ -895,9 +897,11 @@
     $self->_init_aui_settings_panels;
 
-    my $tb = $self->create_toolbar;
+    $self->toolbar(
+        $self->create_toolbar
+    );
 
     $self->manager->AddPane
-      ( $tb, Wx::AuiPaneInfo->new->Name( "tb1" )->Caption( gettext("Tools") )
-        ->ToolbarPane->Top->Row( 1 )->LeftDockable( 0 )->RightDockable( 0 ) ) if defined $tb;
+      ( $self->toolbar, Wx::AuiPaneInfo->new->Name( "tb1" )->Caption( gettext("Tools") )
+        ->ToolbarPane->Top->Row( 1 )->LeftDockable( 0 )->RightDockable( 0 ) ) if defined $self->toolbar;
 
     $self->manager->Update;
@@ -921,4 +925,5 @@
     my ( $self ) = @_;
 
+    $self->toolbar->EnableTool(104, 0 );
     $self->manager->GetPane("global_settings")->Show(1);
     $self->manager->Update();    
@@ -1076,5 +1081,5 @@
 
     $self->tree->SetImageList( $self->treeimglist );
-    $self->populate_tree_categories if $self->is_connected;
+    $self->populate_tree_categories if !wxTheApp->use_offline;
     $self->tree ;
 }
@@ -1198,4 +1203,5 @@
     EVT_LIST_KEY_DOWN($self, $self->imageviewer, \&OnImageViewerKeyDown) ;
     EVT_CLOSE( $self, \&OnClose );
+    Wx::Event::EVT_UPDATE_UI( $self, $self, \&OnUpdateUI );
 
 
@@ -1225,4 +1231,17 @@
 }
 
+sub OnUpdateUI {
+    my( $self, $event ) = @_;
+    
+    if( $self->manager ){
+        if($self->manager->GetPane("global_settings")->IsShown){
+            $self->toolbar->EnableTool(104, 0);         	
+        }
+        else{
+            $self->toolbar->EnableTool(104, 1);         	
+        }
+    }
+}
+
 sub OnRemoveImages {
     my( $self, $event ) = @_;
@@ -1247,7 +1266,20 @@
     $self->progressdlg->Show(1);
     Wx::Yield();
+    
+    my $files = [
+        map {
+            encode('iso-8859-1', $_)
+        }@$file_paths    
+    ];
+    
+    # last is first !
+    if ( scalar @$files > 1 ){
+        my $first = shift @$files;
+        push @$files, $first;	
+    }
+    #print Dumper $files;
 
     $self->imagelist->SetNewFiles(
-        $file_paths
+        $files
     );
 
@@ -1335,5 +1367,5 @@
     my( $self, $event ) = @_;
   
-    my $image = $self->imagelist->images->[$event->GetIndex];
+    my $image = $self->imagelist->GetImage($event->GetIndex);
     $image->site_name(
         $event->GetLabel
@@ -1389,7 +1421,7 @@
     my( $self, $event ) = @_;
 
-#    eval {
+    eval {
         $self->ProcessImageSelection();    
-#    };
+    };
 }
 
@@ -1495,5 +1527,5 @@
         )
     ) if defined $self->imagelist->current_image->wx_thumb_file;
-    
+    print $self->imagelist->current_image->wx_thumb_file, " added with index ", $indx, "\n";    
     $self->imageviewer->Refresh(
         $wximagelist
@@ -1509,5 +1541,5 @@
     my ( $self ) = @_;
 
-    return if !scalar @{$self->imagelist->images};
+    return if !scalar @{$self->imagelist->sums};
 
     if( scalar @{$self->imagelist->categories} ){
@@ -1518,5 +1550,5 @@
             Uploader::GUI::wxImageProcessingProgressDlg->new(
                 { 
-                    title => gettext("Image upload progress information"),
+                    title    => gettext("Image upload progress information"),
                     bt_label => gettext("Cancel upload"), 
                  }
@@ -1587,8 +1619,9 @@
 
     # allways store
-    
+  
     wxTheApp->StoreConnectionProperties;
     
     $self->imagelist->Store;
+    wxTheApp->login_dlg->Destroy;	
     $self->Destroy;
 }
@@ -1619,17 +1652,47 @@
     (
         [
-            101, gettext("Add photo to selection"), '../res/tb_add.png', wxBITMAP_TYPE_PNG, 1, '../res/tb_add.png', gettext("Add photo to selection for resizing and uploading")
+            101, 
+            gettext("Add photo to selection"), 
+            '../res/tb_add.png', 
+            wxBITMAP_TYPE_PNG, 
+            1, 
+            '../res/tb_add.png', 
+            gettext("Add photo to selection for resizing and uploading")
         ],
         [
-            102, gettext("Remove photo from selection"), '../res/tb_remove.png', wxBITMAP_TYPE_PNG, 1, '../res/tb_remove.png',gettext("Remove photo from selection. Files are not deleted ")
+            102, 
+            gettext("Remove photo from selection"), 
+            '../res/tb_remove.png', 
+            wxBITMAP_TYPE_PNG, 
+            1, 
+            '../res/tb_remove.png',
+            gettext("Remove photo from selection. Files are not deleted ")
         ],
         [
-            103, gettext("Upload to Piwigo"), '../res/tb_upload.png', wxBITMAP_TYPE_PNG, 1, '../res/tb_upload.png',gettext("Upload photos to Piwigo.")
+            103, 
+            gettext("Upload to Piwigo"), 
+            '../res/tb_upload.png', 
+            wxBITMAP_TYPE_PNG, 
+            wxTheApp->use_offline ? 0 : 1, 
+            '../res/tb_upload.png',
+            gettext("Upload photos to Piwigo.")
         ],
         [
-            104, gettext("Global settings"), '../res/tb_settings.png', wxBITMAP_TYPE_PNG, 1, '../res/tb_settings.png',gettext("Change global settings.")
+            104, 
+            gettext("Global settings"), 
+            '../res/tb_settings.png', 
+            wxBITMAP_TYPE_PNG, 
+            0, 
+            '../res/tb_settings.png',
+            gettext("Change global settings.")
         ],
         [
-            105, gettext("Language choice"), '../res/tb_i18n.png', wxBITMAP_TYPE_PNG, 1, '../res/tb_i18n.png',gettext("Language choice")
+            105, 
+            gettext("Language choice"), 
+            '../res/tb_i18n.png', 
+            wxBITMAP_TYPE_PNG, 
+            1, 
+            '../res/tb_i18n.png',
+            gettext("Language choice")
         ],
     
@@ -1700,4 +1763,7 @@
   $self->frame->SetNewFiles($files) ;
 }
+
+
+
 
 1;
Index: /extras/pLoader/trunk/src/Uploader/GUI/wxLoginDlg.pm
===================================================================
--- /extras/pLoader/trunk/src/Uploader/GUI/wxLoginDlg.pm	(revision 3226)
+++ /extras/pLoader/trunk/src/Uploader/GUI/wxLoginDlg.pm	(revision 3227)
@@ -39,4 +39,5 @@
            username
            password
+           use_offline
       / 
 );
@@ -52,4 +53,8 @@
     # load controls
     &main::Login($self, 1);
+
+    $self->use_offline(
+        $params->{use_offline}
+    );
     
     $self->url(
@@ -91,8 +96,15 @@
     EVT_BUTTON( $self, $main::ID_PWG_OK, \&OnLoginOK );
     EVT_BUTTON( $self, $main::ID_PWG_CANCEL, \&OnLoginCancel );
+    EVT_BUTTON( $self, $main::ID_PWG_OFFLINE, \&OnLoginOffline );
     
 	
 }
 
+sub OnLoginOffline {
+    my ( $self, $event ) = @_;
+    $self->use_offline->(1);
+       	
+    $self->EndModal(2);
+}
 
 
