rawfilewizard

git clone https://git.clttr.info/rawfilewizard.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

MainForm.cs (22817B)


      1 using SilkypixFileMover.Properties;
      2 using SilkypixFileMover.Objects;
      3 using SilkypixFileMover.Enums;
      4 using System;
      5 using System.Collections.Generic;
      6 using System.IO;
      7 using System.Linq;
      8 using System.Windows.Forms;
      9 using System.Text;
     10 
     11 namespace SilkypixFileMover
     12 {
     13     // TODO: Texte in Ressourcen verschieben wegen Lokalisierung
     14     public partial class MainForm : Form
     15     {
     16         List<RawFile> pendingFiles = new List<RawFile>();
     17 
     18         string startDir;
     19 
     20         private History destinationDirHistory;
     21 
     22         public MainForm()
     23         {
     24             InitializeComponent();
     25 
     26             destinationDirHistory = new History( (int)Settings.Default.DestinationDirHistoryCount );
     27             // wenn schon Verzeichnisse gespeichert sind, dann übernehmen
     28             if ( Settings.Default.DestinationDirHistory != null )
     29             {
     30                 destinationDirHistory.EntrysAsSpecializedStringCollection = Settings.Default.DestinationDirHistory;
     31             }
     32             // Zielpfad vorbelegen wenn vorhanden
     33             SetDestinationDirPath( Settings.Default.LastDestinationFolder );
     34         }
     35 
     36         #region EventHandler für die Listview
     37 
     38         private void lviFiles_SelectedIndexChanged( object sender, EventArgs e )
     39         {
     40             if ( lviFiles.SelectedItems.Count > 0 )
     41             {
     42                 btnRemoveFile.Enabled = true;
     43             }
     44             else
     45             {
     46                 btnRemoveFile.Enabled = false;
     47             }
     48         }
     49 
     50         /// <summary>
     51         /// Bei Doppelklick auf 1 Datei diese im Standardanzeiger öffnen
     52         /// </summary>
     53         /// <param name="sender"></param>
     54         /// <param name="e"></param>
     55         private void lviFiles_MouseDoubleClick( object sender, MouseEventArgs e )
     56         {
     57             if ( e.Button == MouseButtons.Left )
     58             {
     59                 OpenFirstSelectedFile();
     60             }
     61         }
     62 
     63         /// <summary>
     64         /// Reagiert auf Tastendrücke in der Listview
     65         /// </summary>
     66         /// <param name="sender"></param>
     67         /// <param name="e"></param>
     68         private void lviFiles_KeyUp( object sender, KeyEventArgs e )
     69         {
     70             switch ( e.KeyCode )
     71             {
     72                 case Keys.A:
     73                     if ( e.Modifiers == Keys.Control )
     74                     {
     75                         lviFiles.Items.OfType<ListViewItem>().ToList().ForEach( item => item.Selected = true );
     76                     }
     77                     break;
     78 
     79                 case Keys.Delete:
     80                     RemoveSelectItemsFromListview();
     81                     break;
     82 
     83                 case Keys.Enter:
     84                     OpenFirstSelectedFile();
     85                     break;
     86             }
     87         }
     88 
     89         private void RemoveSelectItemsFromListview()
     90         {
     91             if ( lviFiles.SelectedItems.Count > 0 )
     92             {
     93                 foreach ( ListViewItem item in lviFiles.SelectedItems )
     94                 {
     95                     RawFile selectedFile = item.Tag as RawFile;
     96                     pendingFiles.Remove( selectedFile );
     97                 }
     98 
     99                 UpdateListView(false);
    100             }
    101         }
    102 
    103         /// <summary>
    104         /// Fügt die übergebenen Dateien zur Liste der PendingFiles hinzu
    105         /// </summary>
    106         /// <param name="files">Ein Array von Dateinamen inkl. Verzeichnisangabe.</param>
    107         private void AddItemsToListView(string[] files)
    108         {
    109             statusLabel.Text = string.Empty;
    110             bool added = false;
    111             foreach ( string file in files )
    112             {
    113                 if ( ConditionalAdd( file ) )
    114                 {
    115                     added = true;
    116                 }
    117             }
    118 
    119             UpdateListView(added);
    120         }
    121 
    122         #endregion
    123 
    124         #region Hilfsmethoden für die ListView
    125 
    126         private void OpenFirstSelectedFile()
    127         {
    128             RawFile selectedFile = lviFiles.SelectedItems[ 0 ].Tag as RawFile;
    129             if ( selectedFile != null )
    130             {
    131                 // Bild oder Datei offnen mit Pfad 
    132                 NativeMethods.ShellExecute( 0, "open", selectedFile.RawFileFullPath, "", "", 5 );
    133             }
    134         }
    135 
    136         /// <summary>
    137         /// Aktualisiert den Inhalt der ListView mit der aktuellen Dateiliste
    138         /// </summary>
    139         private void UpdateListView(bool showBalloon )
    140         {
    141             lviFiles.SuspendLayout();
    142             lviFiles.Items.Clear();
    143 
    144             foreach ( RawFile dng in pendingFiles )
    145             {
    146                 // keine Datei-Duplikate zulassen
    147                 if ( lviFiles.Items.Contains( new ListViewItem( dng.RawFileName ) ) )
    148                 {
    149                     continue;
    150                 }
    151 
    152                 // nach Quellverzeichnis gruppieren
    153                 if ( lviFiles.Groups[ dng.RawFileSourcePath ] == null )
    154                 {
    155                     lviFiles.Groups.Add( new ListViewGroup( dng.RawFileSourcePath, dng.RawFileSourcePath ) );
    156                 }
    157 
    158                 // Item hinzufügen
    159                 ListViewItem newItem = lviFiles.Items.Add(
    160                     new ListViewItem( new string[] { dng.RawFileName, dng.Size, dng.TimeStamp.ToString() },
    161                     lviFiles.Groups[ dng.RawFileSourcePath ] ) );
    162                 newItem.Tag = dng;
    163             }
    164 
    165             lviFiles.ResumeLayout();
    166 
    167             UpdateNotifyIconText(showBalloon);
    168             SetActionButtonState();
    169         }
    170 
    171         /// <summary>
    172         /// Setz den Text des NotifyIcons auf den übergebenen Text oder den Standardtext
    173         /// </summary>
    174         /// <param name="showBalloon">Gibt an, ob der BalloonTip angezeigt werden soll oder nicht.</param>
    175         private void UpdateNotifyIconText(bool showBalloon)
    176         {
    177             string text;
    178 
    179             if ( pendingFiles.Count == 0 )
    180             {
    181                 text = "Kein Bild ausgewählt";
    182                 trayIcon.Icon = Resources.backups;
    183             }
    184             else
    185             {
    186                 text = string.Format( "{0} {1} ausgewählt", pendingFiles.Count, pendingFiles.Count == 1 ? "Bild" : "Bilder" );
    187                 trayIcon.Icon = Resources.backup_wizard;
    188             }
    189 
    190             trayIcon.Text = string.Format( "{0} - RawFileWizard", text );
    191             if ( showBalloon )
    192             {
    193                 ShowBalloonTipText( text );
    194             }
    195         }
    196 
    197         /// <summary>
    198         /// Zeigt eine Info mit dem übergebenen Text an
    199         /// </summary>
    200         /// <param name="text">Der anzuzeigende Text</param>
    201         /// <param name="timeInSeconds">Anzeigedauer des Infobanners in Sekunden</param>
    202         private void ShowBalloonTipText( string text, int timeInSeconds = 1 )
    203         {
    204             trayIcon.BalloonTipText = text;
    205             trayIcon.ShowBalloonTip( timeInSeconds * 1000 );
    206         }
    207 
    208         #endregion
    209 
    210         #region Eventhandler für die Buttons
    211 
    212         /// <summary>
    213         /// Button für Auswahl des Zielordners wurde angeklickt
    214         /// </summary>
    215         /// <param name="sender"></param>
    216         /// <param name="e"></param>
    217         private void btnSelectDestination_Click( object sender, EventArgs e )
    218         {
    219             FolderBrowserDialog fbd = new FolderBrowserDialog();
    220             fbd.ShowNewFolderButton = true;
    221             fbd.Description = "Wählen Sie das Zielverzeichnis aus:";
    222 
    223             // Dialog vorbelegen
    224             if ( !string.IsNullOrEmpty( cboHistory.Text ) && Directory.Exists( cboHistory.Text ) )
    225             {
    226                 fbd.SelectedPath = cboHistory.Text;
    227             }
    228 
    229             if ( fbd.ShowDialog() == DialogResult.OK )
    230             {
    231                 SetDestinationDirPath( fbd.SelectedPath );
    232             }
    233         }
    234 
    235         /// <summary>
    236         /// Dateien löschen
    237         /// </summary>
    238         /// <param name="sender"></param>
    239         /// <param name="e"></param>
    240         private void btnDelete_Click( object sender, EventArgs e )
    241         {
    242             if ( Settings.Default.MoveToRecycleBin || 
    243                  MessageBox.Show("Wollen sie wirklich alle gelisteten Dateien löschen?", "Dateien löschen", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2 ) == DialogResult.Yes )
    244             {
    245                 PrepareWorker( WorkerAction.Delete );
    246             }
    247         }
    248 
    249         /// <summary>
    250         /// Dateien verschieben!
    251         /// </summary>
    252         /// <param name="sender"></param>
    253         /// <param name="e"></param>
    254         private void btnMove_Click( object sender, EventArgs e )
    255         {
    256             PrepareWorker( WorkerAction.Move );
    257         }
    258 
    259         private void PrepareWorker( WorkerAction workerAction )
    260         {
    261             statusLabel.Text = string.Empty;
    262             if ( !bgwWorker.IsBusy )
    263             {
    264                 statusProgress.Maximum = pendingFiles.Count;
    265                 statusProgress.Value = 0;
    266                 SetAllButtonState( false );
    267 
    268                 bgwWorker.RunWorkerAsync( new WorkerParams()
    269                 {
    270                     Action = workerAction,
    271                     DestinationDir = cboHistory.Text
    272                 } );
    273             }
    274         }
    275 
    276         private void btnRemoveFile_Click( object sender, EventArgs e )
    277         {
    278             RemoveSelectItemsFromListview();
    279         }
    280 
    281         /// <summary>
    282         /// Button für den Dateiauswahl-Dialog wurde gedrückt.
    283         /// </summary>
    284         /// <param name="sender"></param>
    285         /// <param name="e"></param>
    286         private void btnAddFile_Click( object sender, EventArgs e )
    287         {
    288             // Parameter für den OpenFile-Dialog setzen
    289             OpenFileDialog fd = new OpenFileDialog();
    290             fd.AutoUpgradeEnabled = true;
    291             fd.CheckFileExists = true;
    292             fd.CheckPathExists = true;
    293             fd.Multiselect = true;
    294             fd.ReadOnlyChecked = true;
    295             fd.Title = "Bilder auswählen";
    296             fd.Filter = CreateFileFilter();
    297 
    298             // zuletzt verwendeten Ordner wiederherstellen
    299             if ( !string.IsNullOrWhiteSpace( Settings.Default.LastSourceFolder ) )
    300             {
    301                 fd.InitialDirectory = Settings.Default.LastSourceFolder;
    302             }
    303 
    304             if ( string.IsNullOrWhiteSpace( fd.InitialDirectory ) )
    305             {
    306                 fd.InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.MyPictures );
    307             }
    308 
    309             if ( fd.ShowDialog() == DialogResult.OK )
    310             {
    311                 Settings.Default.LastSourceFolder = Path.GetDirectoryName( fd.FileName );
    312                 Settings.Default.Save();
    313 
    314                 AddItemsToListView( fd.FileNames );
    315             }
    316         }
    317 
    318         private string CreateFileFilter()
    319         {
    320             StringBuilder sb = new StringBuilder();
    321             sb.Append( "Bilddateien|*." );
    322             sb.Append( Settings.Default.RawFileExtension );
    323             sb.Append( ";*." );
    324             sb.Append( string.Join( ";*.", Settings.Default.JpegFileExtensions.Split( '|' ) ) );
    325             sb.Append("|Alle Dateien|*.*");
    326             return sb.ToString();
    327         }
    328 
    329         private bool ConditionalAdd( string file )
    330         {
    331             string fileExt = Path.GetExtension( file ).TrimStart( '.' ).ToLowerInvariant();
    332 
    333             if ( fileExt.Equals( Settings.Default.RawFileExtension.ToLowerInvariant() ) ||
    334                  Settings.Default.JpegFileExtensions.Split( '|' ).Any( p => p.ToLowerInvariant() == fileExt ) )
    335             {
    336                 RawFile dng = new RawFile( file );
    337 
    338                 // Dateien übernehmen, wenn noch nicht ausgewählt
    339                 if ( !pendingFiles.Contains( dng ) )
    340                 {
    341                     pendingFiles.Add( dng );
    342                     return true;
    343                 }
    344             }
    345 
    346             return false;
    347         }
    348 
    349         #endregion
    350 
    351         /// <summary>
    352         /// Setzt den Ziel-Pfad und aktualisiert die Buttons
    353         /// </summary>
    354         /// <param name="path">Pfad der gesetzt werden sollen</param>
    355         private void SetDestinationDirPath( string path )
    356         {
    357             if ( !string.IsNullOrEmpty( path ) )
    358             {
    359                 if ( !Directory.Exists( path ) )
    360                 {
    361                     if ( MessageBox.Show( "Soll das Verzeichnis angelegt werden?", "Frage",
    362                         MessageBoxButtons.YesNo,
    363                         MessageBoxIcon.Question,
    364                         MessageBoxDefaultButton.Button1 ) == DialogResult.Yes )
    365                     {
    366                         Directory.CreateDirectory( path );
    367                     }
    368                 }
    369 
    370                 if ( Directory.Exists( path ) )
    371                 {
    372                     cboHistory.Text = path;
    373                     startDir = path;
    374 
    375                     destinationDirHistory.Add( path );
    376                     Settings.Default.DestinationDirHistory = destinationDirHistory.EntrysAsSpecializedStringCollection;
    377                     Settings.Default.LastDestinationFolder = path;
    378                     Settings.Default.Save();
    379 
    380                     SetActionButtonState();
    381                     return;
    382                 }
    383             }
    384 
    385             if ( !string.IsNullOrEmpty( startDir ) )
    386             {
    387                 cboHistory.Text = startDir;
    388             }
    389         }
    390 
    391         /// <summary>
    392         /// Aktualisiert den Status des Verschieben-Buttons je nachdem ob was ausgewählt ist
    393         /// </summary>
    394         private void SetActionButtonState()
    395         {
    396             if ( pendingFiles != null &&
    397                 pendingFiles.Count > 0 )
    398             {
    399                 if ( !string.IsNullOrWhiteSpace( cboHistory.Text ) &&
    400                      Directory.Exists( cboHistory.Text ) )
    401                 {
    402                     btnMove.Enabled = true;
    403                 }
    404                 btnDelete.Enabled = true;
    405             }
    406             else
    407             {
    408                 btnMove.Enabled = false;
    409                 btnDelete.Enabled = false;
    410             }
    411         }
    412         
    413         private void SetAllButtonState( bool enabled )
    414         {
    415             btnMove.Enabled = enabled;
    416             btnDelete.Enabled = enabled;
    417             btnAddFile.Enabled = enabled;
    418             btnRemoveFile.Enabled = enabled;
    419             btnDirUp.Enabled = enabled;
    420             btnSelectDestination.Enabled = enabled;
    421             cboHistory.Enabled = enabled;
    422         }
    423 
    424         #region Eventhandler für das Zielverzeichnis-Feld
    425 
    426         private void btnDirUp_Click( object sender, EventArgs e )
    427         {
    428             int index = cboHistory.Text.LastIndexOf( Path.DirectorySeparatorChar );
    429             if ( index > 0 )
    430             {
    431                 SetDestinationDirPath( cboHistory.Text.Substring( 0, index ) );
    432             }
    433         }
    434 
    435         private void txtDestDir_KeyUp( object sender, KeyEventArgs e )
    436         {
    437 
    438         }
    439 
    440         private void txtDestDir_MouseDoubleClick( object sender, MouseEventArgs e )
    441         {
    442             switch ( e.Button )
    443             {
    444                 case MouseButtons.Right:
    445                     NativeMethods.ShellExecute( 0, "open", cboHistory.Text, "", "", 5 );
    446                     break;
    447             }
    448         }
    449 
    450         #endregion
    451 
    452         #region Eventhandler für Drag&Drop
    453 
    454         private void lviFiles_DragDrop( object sender, DragEventArgs e )
    455         {
    456             if ( e.Data.GetDataPresent( DataFormats.FileDrop ) )
    457             {
    458                 try
    459                 {
    460                     string[] files = ( string[] )e.Data.GetData( DataFormats.FileDrop );
    461                     AddItemsToListView( files );
    462                 }
    463                 catch ( Exception ex )
    464                 {
    465                     ShowBalloonTipText( ex.Message, 2 );
    466                     return;
    467                 }
    468             }
    469         }
    470 
    471         private void lviFiles_DragEnter( object sender, DragEventArgs e )
    472         {
    473             if ( e.Data.GetDataPresent( DataFormats.FileDrop ) )
    474             {
    475                 e.Effect = DragDropEffects.Copy;
    476             }
    477         }
    478 
    479         #endregion
    480 
    481         #region Handling der Combobox
    482 
    483         private void cboHistory_Leave( object sender, EventArgs e )
    484         {
    485             cboHistory_KeyUp( sender, new KeyEventArgs( Keys.Enter ) );
    486         }
    487 
    488         private void cboHistory_KeyUp( object sender, KeyEventArgs e )
    489         {
    490             switch ( e.KeyCode )
    491             {
    492                 case Keys.Enter:
    493                     SetDestinationDirPath( cboHistory.Text );
    494                     break;
    495 
    496                 case Keys.Escape:
    497                     SetDestinationDirPath( startDir );
    498                     break;
    499             }
    500         }
    501 
    502         private void cboHistory_DragEnter( object sender, DragEventArgs e )
    503         {
    504             if ( e.Data.GetDataPresent( DataFormats.FileDrop ) )
    505             {
    506                 e.Effect = DragDropEffects.Copy;
    507             }
    508         }
    509 
    510         private void cboHistory_DragDrop( object sender, DragEventArgs e )
    511         {
    512             if ( e.Data.GetDataPresent( DataFormats.FileDrop ) )
    513             {
    514                 try
    515                 {
    516                     string[] files = ( string[] )e.Data.GetData( DataFormats.FileDrop );
    517                     string path = files.FirstOrDefault();
    518                     if ( !Directory.Exists( path ) )
    519                     {
    520                         path = Path.GetDirectoryName( files.FirstOrDefault() );
    521                     }
    522                     SetDestinationDirPath( path );
    523                 }
    524                 catch ( Exception ex )
    525                 {
    526                     MessageBox.Show( ex.Message, "Fehler" );
    527                     return;
    528                 }
    529             }
    530         }
    531 
    532         private void cboHistory_DropDown( object sender, EventArgs e )
    533         {
    534             cboHistory.Items.Clear();
    535             cboHistory.Items.AddRange( destinationDirHistory.Entrys.Where( x => !string.IsNullOrWhiteSpace( x ) ).ToArray() );
    536         }
    537 
    538         private void cboHistory_SelectedIndexChanged( object sender, EventArgs e )
    539         {
    540             string path = ( string )cboHistory.SelectedItem;
    541 
    542             if ( !string.IsNullOrWhiteSpace( path ) )
    543             {
    544                 SetDestinationDirPath( path );
    545             }
    546         }
    547 
    548         #endregion
    549 
    550         #region Handling des BackgroundWorkers
    551 
    552         private void bgwWorker_DoWork( object sender, System.ComponentModel.DoWorkEventArgs e )
    553         {
    554             WorkerParams param = ( WorkerParams )e.Argument;
    555             if ( pendingFiles != null && param.Action != WorkerAction.None )
    556             {
    557                 // Statusbar zurücksetzen
    558                 int currentProgress = 0;
    559                 int errorCount = 0;
    560 
    561                 List<RawFile> removeFiles = new List<RawFile>();
    562 
    563                 // Dateien verschieben
    564                 foreach ( RawFile dng in pendingFiles )
    565                 {
    566                     try
    567                     {
    568                         switch ( param.Action )
    569                         {
    570                             case WorkerAction.Move:
    571                                 dng.Move( param.DestinationDir );
    572                                 break;
    573                             case WorkerAction.Delete:
    574                                 dng.Delete();
    575                                 break;
    576                         }
    577                         removeFiles.Add( dng );
    578                     }
    579                     catch ( Exception ex )
    580                     {
    581                         errorCount++;
    582                         string exceptionText = ex.Message;
    583                         // TODO: ExceptionText is too long for the status label
    584                         //statusLabel.Text = exceptionText;
    585                         ShowBalloonTipText( exceptionText, 2 );
    586                     }
    587                     currentProgress++;
    588                     bgwWorker.ReportProgress( currentProgress );
    589                 }
    590 
    591                 foreach ( RawFile dng in removeFiles )
    592                 {
    593                     pendingFiles.Remove( dng );
    594                 }
    595 
    596                 string okText = string.Empty;
    597                 string errorText = string.Empty;
    598                 switch ( param.Action )
    599                 {
    600                     case WorkerAction.None:
    601                         break;
    602                     case WorkerAction.Move:
    603                         okText = string.Format("Alle {0} Bilder verschoben.", currentProgress );
    604                         errorText = string.Format( "Von {0} Bildern konnten {1} nicht verschoben werden.", currentProgress, errorCount );
    605                         break;
    606                     case WorkerAction.Delete:
    607                         okText = string.Format( "Alle {0} Bilder gelöscht.", currentProgress );
    608                         errorText = string.Format("Von {0} Bildern konnten {1} nicht gelöscht werden.", currentProgress, errorCount );
    609                         break;
    610                 }
    611 
    612                 if ( errorCount == 0 )
    613                 {
    614                     statusLabel.Text = okText;
    615                     ShowBalloonTipText(okText, 1);
    616                 }
    617                 else
    618                 {
    619                     statusLabel.Text = errorText;
    620                     ShowBalloonTipText( errorText, 1 );
    621                 }
    622             }
    623         }
    624 
    625         private void bgwWorker_ProgressChanged( object sender, System.ComponentModel.ProgressChangedEventArgs e )
    626         {
    627             statusProgress.Value = e.ProgressPercentage;
    628             statusCounter.Text = string.Format( "Datei {0} von {1}", e.ProgressPercentage, statusProgress.Maximum );
    629         }
    630 
    631         private void bgwWorker_RunWorkerCompleted( object sender, System.ComponentModel.RunWorkerCompletedEventArgs e )
    632         {
    633             statusProgress.Value = 0;
    634             statusCounter.Text = string.Empty;
    635             UpdateListView(false);
    636             SetAllButtonState( true );
    637             SetActionButtonState();
    638         }
    639 
    640         #endregion
    641 
    642         private void btnAbout_Click( object sender, EventArgs e )
    643         {
    644             new About().ShowDialog();
    645         }
    646 
    647         private void btnSettings_Click( object sender, EventArgs e )
    648         {
    649             if ( new SettingsForm().ShowDialog() == DialogResult.OK )
    650             {
    651                 TopMost = Settings.Default.WindowTopMost;
    652             }
    653         }
    654 
    655         #region Eventhandler fürs TrayIcon
    656 
    657         private void trayIcon_DoubleClick( object sender, EventArgs e )
    658         {
    659             ToogleVisibility();
    660         }
    661 
    662         #endregion
    663 
    664         private void beendenItem_Click( object sender, EventArgs e )
    665         {
    666             Close();
    667         }
    668 
    669         private void toogleWindowItem_Click( object sender, EventArgs e )
    670         {
    671             ToogleVisibility();
    672         }
    673 
    674         private void ToogleVisibility()
    675         {
    676             if ( Visible )
    677             {
    678                 Hide();
    679             }
    680             else
    681             {
    682                 Show();
    683             }
    684         }
    685     }
    686 }