Rayburn Davis
2014-08-28 25f44935484f40cfca2dc8f9b9a4babe601a3ce7
commit | author | age
344044 1 ´╗┐using System;
RD 2 using System.Collections;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.Data;
6 using System.Drawing;
7 //using System.Linq;
8 using System.Text;
9 using System.Windows.Forms;
10 using System.Runtime.InteropServices;
11 using System.Threading;
12 using System.IO;
13 using System.Diagnostics;
14 using Microsoft.Win32;
15 using System.Net;
16 using System.Text.RegularExpressions;
17 using System.Security.Cryptography;
18 using System.Xml;
19 using System.Resources;
20 using System.Reflection;
21 using System.Globalization;
22 using System.Net.Sockets;
23
24 //using System.Design;
25
26
27 namespace DupliDelete
28 {
29     public partial class Form1 : Form
30     {
31         public bool filelist_mode = false;
32         public bool in_search = false; // true if a search phrase is entered
33         RunUndoScript ruds1;
34         bool search_thread_running = false;
35         public string version_string;// = GetVersionString();
36         Thread search_thread;
37
38         DuplicateListView.DrawIndex BackwardIndex, ForwardIndex;
39
40         private string GetVersionString()
41         {
42             return this.Text.Substring(this.Text.LastIndexOf(' ') + 1);
43         }
44
45         public string ReturnVersion()
46         {
47             return GetVersionString();
48         }
49
50         public ArrayList listview_items = new ArrayList(1);
51
52         [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
53         static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);
54
55         [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError=true)]
56         static extern bool CreateSymbolicLink(string lpFileName, string lpExistingFileName, Int32 dwFlags);
57
58         [DllImport("User32.dll", CharSet = CharSet.Unicode)]
59         static extern int SendMessage(IntPtr hwnd, int Msg, IntPtr wParam, IntPtr lParam);
60
61         [DllImport("User32.dll", CharSet = CharSet.Unicode)]
62         static extern int SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int X, int Y, int cx, int cy, uint flags);
63
64         [DllImport("User32.dll", CharSet = CharSet.Unicode)]
65         static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
66
67         [DllImport("shlwapi.dll", SetLastError = true)]
68         static extern int PathRelativePathTo(StringBuilder pszPath, string pszFrom, int dwAttrFrom, string pszTo, int dwAttrTo);
69
70         public Form1()
71         {
72             InitializeComponent();
73         }
74
75         private void toolStripButton1_Click(object sender, EventArgs e)
76         {
77             if (GlobalBuffers.working)
78                 return;
79             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
80                 return;
81
82             //if (listView1.CheckedIndices.Count == 0)
83             //return;
84
85             string search_mode;
86             search_mode = GlobalBuffers.SettingsManager.FindSettingStringSingle("search_mode");
87
88             if (search_mode == "cbad" && filelist_mode == false)
89             {
90                 MessageBox.Show("Since Duplicate Commander is currently set to find files based on actual data, this command is not available.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
91                 return;
92             }
93
94             ThreadStart ts = new ThreadStart(CompareGroup);
95             Thread t = new Thread(ts);
96
97             checking_window = new Checking();
98             checking_window.Text = "Comparing groups...";
99             checking_window.statusText.Text = "Please wait...";
100             checking_window.staticText = false;
101
102             long_process_listener = new LongProcessListener(checking_window, this);
103
104             t.Start();
105         }
106
107         public void CompareGroup()
108         {
109             double prg = (double)100 / GlobalBuffers.Duplicates.Count;
110             double prg2 = (double)0.0;
111             int i, j, k;
112             ObjectInfo file;
113             ErrorClass errors = new ErrorClass(this, "The following files could not be compared.");
114             DuplicateFinder.ChecksumReadStatus checksum_status;
115             ObjectInfoCollection file_collection = new ObjectInfoCollection();
116             int same_count = 0;
117             int sum = -1;
118
119             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
120             {
121                 if (GlobalBuffers.Duplicates[i].GetGroupCheckState() != 2)
122                 {
123                     if (checking_window.cancel_clicked == true)
124                     {
125                         long_process_listener.Complete = true;
126                         return;
127                     }
128
129                     for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
130                     {
131                         if (checking_window.cancel_clicked == true)
132                         {
133                             long_process_listener.Complete = true;
134                             return;
135                         }
136
137                         checking_window.progressText = "Comparing file " + (j + 1) + " of group " + (i + 1);
138
139                         file = new ObjectInfo(GlobalBuffers.Duplicates[i][j].Filename, GlobalBuffers.Duplicates[i][j].Size, ObjectInfo.FileType.File);
140
141                         checksum_status = ReadFileChecksum(file, 100);
142
143                         if (checksum_status != DuplicateFinder.ChecksumReadStatus.Success)
144                         {
145                             if (checksum_status == DuplicateFinder.ChecksumReadStatus.AccessDenied)
146                                 errors.AddError(GlobalBuffers.Duplicates[i][j].Filename, "Access was denied.");
147                             if (checksum_status == DuplicateFinder.ChecksumReadStatus.FileNotFound)
148                                 errors.AddError(GlobalBuffers.Duplicates[i][j].Filename, "The file was not found.");
149                             if (checksum_status == DuplicateFinder.ChecksumReadStatus.UnknownError)
150                                 errors.AddError(GlobalBuffers.Duplicates[i][j].Filename, "The error is unknown.");
151                         }
152                         else
153                             file_collection.Add(file);
154                     }
155
156                     if (file_collection.Count == GlobalBuffers.Duplicates[i].Count)
157                     {
158                         for (k = 0; k < file_collection.Count; k++)
159                         {
160                             if (sum != -1 && sum != file_collection[k].ChecksumSum.Sum)
161                                 break;
162                             else
163                                 same_count++;
164
165                             sum = file_collection[k].ChecksumSum.Sum;
166                         }
167
168                         if (same_count == GlobalBuffers.Duplicates[i].Count)
169                         {
170                             GlobalBuffers.Duplicates[i].State = DuplicateGroup.GroupState.TrueDuplicate;
171                         }
172                         else
173                             GlobalBuffers.Duplicates[i].State = DuplicateGroup.GroupState.FalseDuplicate;
174                     }
175                     else
176                         GlobalBuffers.Duplicates[i].State = DuplicateGroup.GroupState.FalseDuplicate;
177
178                     file_collection.Clear();
179                     same_count = 0;
180                     sum = -1;
181                 }
182
183                 prg2 = (double)prg * i;
184
185                 checking_window.progress = (double)prg2;
186
187             }
188
189
190
191             long_process_listener.Complete = true;
192
193             GlobalBuffers.mainList.Invalidate();
194
195             errors.ShowErrorWindow();
196
197         }
198
199         private DuplicateFinder.ChecksumReadStatus ReadFileChecksum(ObjectInfo fileInfo, int percent)
200         {
201             if (fileInfo.Checksum == null)
202             {
203                 byte[] temp;
204                 int j;
205                 double percent_size = (double)0.0;
206                 SHA1 sha_handle;
207                 byte[] checksum_data = new byte[2097152];
208
209                 FileChecksum checksum1 = new FileChecksum();
210
211                 double progress;
212
213                 sha_handle = SHA1.Create();
214
215                 if (DirectoryEnumerator.Exists(fileInfo.Name))
216                 {
217                     FileStream fs1;
218                     try
219                     {
220                         fs1 = new FileStream(fileInfo.Name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
221                     }
222                     catch (UnauthorizedAccessException)
223                     {
224                         return DuplicateFinder.ChecksumReadStatus.AccessDenied;
225                     }
226                     catch (FileNotFoundException)
227                     {
228                         return DuplicateFinder.ChecksumReadStatus.FileNotFound;
229                     }
230                     catch (IOException)
231                     {
232                         return DuplicateFinder.ChecksumReadStatus.UnknownError;
233                     }
234
235                     // FileChecksumScanInProgress = true;
236                     // FileChecksumObject = fileInfo;
237
238                     // GetFileInformationByHandle(fs1.SafeFileHandle.DangerousGetHandle(), out fileInfo.FileInfo);
239
240                     percent_size = (double)percent / 100 * fs1.Length;
241                     percent_size = RoundSize(percent_size);
242
243                     double loop_count = (double)percent_size / 2097152;
244
245                     // FileChecksumProgress = (double)0;
246                     progress = (double)100 / loop_count;
247
248                     int i;
249                     double remainder;
250
251                     for (i = 0; i < (int)loop_count; i++)
252                     {
253                         if (checking_window.cancel_clicked == true)
254                             break;
255
256                         /*  if (cancel_clicked == true)
257                           {
258                               fs1.Close();
259                               return -1;
260                           } */
261                         fs1.Read(checksum_data, 0, 2097152);
262
263                         temp = sha_handle.ComputeHash(checksum_data, 0, 2097152);
264
265                         for (j = 0; j < 16; j++)
266                             checksum1.checksum[j] += temp[j];
267
268
269
270                         //  FileChecksumProgress += (double)progress;
271                     }
272                     if ((double)loop_count > (int)loop_count)
273                     {
274                         /* if (cancel_clicked == true)
275                          {
276                              fs1.Close();
277                              return -1;
278                          }*/
279                         remainder = loop_count - (int)loop_count;
280                         remainder = (double)remainder * 2097152;
281
282                         fs1.Read(checksum_data, 0, (int)remainder);
283
284                         temp = sha_handle.ComputeHash(checksum_data, 0, (int)remainder);
285
286                         for (j = 0; j < 16; j++)
287                             checksum1.checksum[j] += temp[j];
288
289                         //compare_prg2 += (double)compare_prg;
290                     }
291
292                     fs1.Close();
293
294                     fileInfo.Checksum = checksum1.checksum;
295                     fileInfo.ChecksumSum = new ChecksumSum(ChecksumSum.returnSum(checksum1.checksum));
296
297                 }
298                 else
299                 {
300                     // FileChecksumScanInProgress = false;
301                     return DuplicateFinder.ChecksumReadStatus.FileNotFound;
302                 }
303
304             }
305             else
306             {
307                 // FileChecksumScanInProgress = false;
308                 return DuplicateFinder.ChecksumReadStatus.UnknownError;
309             }
310
311             //FileChecksumScanInProgress = false;
312
313             return DuplicateFinder.ChecksumReadStatus.Success;
314         }
315
316         private double RoundSize(double percent_size)
317         {
318             return ((double)percent_size > (int)percent_size ? (double)percent_size + 1 : (double)percent_size);
319         }
320
321         private void Form1_Load(object sender, EventArgs e)
322         {
323
324             //    Duplicate_Commander.RSTreeView.RSTreeNode tn = new Duplicate_Commander.RSTreeView.RSTreeNode();
325
326             //    tn.Text = "Test";
327             //  rsTreeView1.Nodes.Add(tn);
328
329             /*     IndeterminableTreeNode item = new IndeterminableTreeNode();
330                  item.Text = "Test!";
331                  item.Checked = 0;
332
333                  IndeterminableTreeNode item2 = new IndeterminableTreeNode();
334                  item2.Text = "Test2";
335                  item2.Checked = 0;
336                  item.Nodes.Add(item2);
337
338                  item.Expand();
339                  fileSystemTreeview.Nodes.Add(item); */
340
341             if (!File.Exists(GlobalBuffers.OptionsPath))
342             {
343                 MessageBox.Show("The options.ini file does not exist at \"" + Application.StartupPath + "\". Please reinstall or redownload Duplicate Commander.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
344                 this.Dispose(true);
345                 Application.Exit();
346             }
347             else
348             {
349                 GlobalBuffers.SettingsManager = SettingsManager.Load(GlobalBuffers.OptionsPath);
350
351                 GlobalBuffers.main_form = this;
352
353                // int t = 0;
354                 //int z = 1 / t;
355
356                 GlobalBuffers.mainList = mainList;
357
358                 OperatingSystem OSVer = System.Environment.OSVersion;
359
360                 if (OSVer.Version.Major >= 5)
361                 {
362                     menuStrip.BackgroundImage = global::DupliDelete.Properties.Resources.toolbar;
363                     commandStrip.BackgroundImage = global::DupliDelete.Properties.Resources.toolbarbg;
364                     commandStrip.BackgroundImageLayout = ImageLayout.Stretch;
365
366                     searchStrip.BackgroundImage = global::DupliDelete.Properties.Resources.toolbarbg;
367                     searchStrip.BackgroundImageLayout = ImageLayout.Stretch;
368
369                 }
370
371                 // get this version; it's stored in the title of the window
372                 version_string = GetVersionString();
25f449 373                 Text = "Duplicate Commander " + Assembly.GetExecutingAssembly().GetName().Version.Major + "." + Assembly.GetExecutingAssembly().GetName().Version.Minor + "." + Assembly.GetExecutingAssembly().GetName().Version.Revision;
344044 374
RD 375                 // check for updates
376                 ThreadStart ts1 = new ThreadStart(CheckForUpdates);
377                 Thread update_checker_thread = new Thread(ts1);
378                 if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "update_check") == "0")
379                     update_checker_thread.Start();
380
381                 // hide the listview until it's time to scan
382                 // mainList.Visible = false;
383
384                 // if the user's manual doesn't exist, this is the portable version; hide the User's Manual menu entry
385                 if (!File.Exists(Application.StartupPath + "\\" + "dcum.chm"))
386                 {
387                     usersManualToolStripMenuItem.Visible = false;
388                     toolStripSeparator2.Visible = false;
389                 }
390
391                 if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "portable") == "1")
392                     GlobalBuffers.Portable = true;
393                 else
394                     GlobalBuffers.Portable = false;
395
396                 // check if this is the user's first time running DC
397                 CheckIfFirstTime();
398
399                 // check for drives that do not support hard links
400                 CheckFilesystems();
401
402
403                 LoadSettings(); // load listview and other settings into memory that we need now
404
405                 timer1.Start();
406
407                 GlobalBuffers.MainFormLoaded = true;
408
409                 GlobalBuffers.mainList.Columns[0].Width = Width - 470;
410
411             }
412         }
413
414         protected override void OnLoad(EventArgs e)
415         {
416             base.OnLoad(e);
417         }
418
419
420
421         protected override void OnPaintBackground(PaintEventArgs e)
422         {
423             base.OnPaintBackground(e);
424         }
425
426         // the delete button was clicked in the listview (?)
427         void Delete_ButtonClicked(EventArgs e)
428         {
429             DeleteSelectedItem();
430         }
431
432         // The Search button on the toolbar was clicked
433         /*void Search_ButtonClicked(EventArgs e)
434         {
435             if (GlobalBuffers.working)
436                 return;
437             ScanCriteria sc1 = new ScanCriteria();
438
439             sc1.Owner = this;
440             sc1.ShowDialog();
441             sc1.Tag = null;
442         }*/
443
444         /// <summary>
445         /// Checks to see if there are any drives that do not support hard links
446         /// </summary>
447         private void CheckFilesystems()
448         {
449             int i, fat32_count = 0;
450             DriveInfo[] drives = DriveInfo.GetDrives();
451
452             for (i = 0; i < drives.Length; i++)
453             {
454                 if (drives[i].DriveType == DriveType.Fixed && drives[i].IsReady == true && drives[i].DriveFormat != "NTFS")
455                     fat32_count++;
456             }
457
458             if (fat32_count > 0 && GlobalBuffers.SettingsManager.FindSettingStringSingle( "dont_warn_ntfs") == "0")
459                 MessageBox.Show("One or more fixed drives on your system is not formatted with the NTFS filesystem. You will not be able to create hard links on these drives.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
460         }
461
462         private void viewToolStripMenuItem_Click(object sender, EventArgs e)
463         {
464
465         }
466
467         private void toolStripTextBox1_Click(object sender, EventArgs e)
468         {
469         }
470
471         private void toolStripTextBox1_KeyPress(object sender, KeyPressEventArgs e)
472         {
473         }
474
475         // the user typed something into the search box
476         private void toolStripTextBox1_TextChanged(object sender, EventArgs e)
477         {
478             if (DontUpdateSearchQuery == false)
479             {
480                 ThreadStart ts1 = new ThreadStart(ProcessSearchBoxThread);
481                 search_thread = new Thread(ts1);
482
483                 search_thread.Start();
484             }
485         }
486
487         public void ProcessSearchBoxThread()
488         {
489             if (search_thread_running == false)
490             {
491                 ProcessSearchBox();
492             }
493         }
494
495         public void ProcessSearchBox()
496         {
497             if (mainList.Visible != true)
498                 return;
499
500             search_thread_running = true;
501             int i, j;
502             int item_count = 0;
503             bool ensure_visible = true;
504             string search_text = "", old_search_text = "";
505             double prg;
506
507             this.Invoke((MethodInvoker)delegate
508             {
509                 search_text = searchListTextbox.Text;
510             });
511
512             if (search_text != "")
513             {
514                 while (search_text != old_search_text && search_text != "")
515                 {
516                     old_search_text = search_text;
517                     Thread.Sleep(200);
518                     this.Invoke((MethodInvoker)delegate
519                     {
520                         search_text = searchListTextbox.Text;
521                     });
522                 }
523
524                 if (search_text == "")
525                 {
526                     goto no_text;
527                 }
528
529
530                 in_search = true;
531
532                 GlobalBuffers.mainList.HighLightedIndexes.Clear();
533
534                 prg = (double)100 / GlobalBuffers.Duplicates.Count;
535
536                 for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
537                 {
538                     for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
539                     {
540                         if ((GlobalBuffers.Duplicates[i][j].Filename.ToLower().IndexOf(search_text.ToLower())) != -1)
541                         {
542                             if (ensure_visible == true)
543                             {
544                                 GlobalBuffers.mainList.EnsureVisible(new DuplicateListView.DrawIndex(i, -1, null));
545                                 ensure_visible = false;
546                             }
547
548                             GlobalBuffers.Duplicates[i][j].Highlighted = true;
549                             GlobalBuffers.mainList.HighLightedIndexes.Add(GlobalBuffers.Duplicates[i].RollingTotal + j);
550
551                             item_count++;
552                         }
553                         else
554                             GlobalBuffers.Duplicates[i][j].Highlighted = false;
555
556                     }
557
558                 }
559
560                 
561
562                 this.Invoke((MethodInvoker)delegate
563                 {
564                     jumpUpButton.ToolTipText = "Jump to previous page of search matches";
565                     jumpDownButton.ToolTipText = "Jump to next page of search matches";
566
567                     statusBarPanel5.Text = (item_count != 1 ? item_count + " items " : "1 item ") + "found";
568
569                     EnableArrows(false);
570                 });
571                 search_thread_running = false;
572             }
573         no_text:
574             if (search_text == "")
575             {
576
577                 this.Invoke((MethodInvoker)delegate
578                 {
579                    // GlobalBuffers.mainList.verticalScrollbar.Value = 0;
580                    // GlobalBuffers.mainList.DrawStartIndex.Group = 0;
581                    // GlobalBuffers.mainList.DrawStartIndex.Duplicate = -1;
582                     GlobalBuffers.mainList.HighLightedIndexes.Clear();
583
584                     for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
585                     {
586                         for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
587                         {
588                             GlobalBuffers.Duplicates[i][j].Highlighted = false;
589                         }
590                     }
591
592                     jumpUpButton.ToolTipText = "Jump to previous checked item";
593                     jumpDownButton.ToolTipText = "Jump to next of checked item";
594
595                     SetStatusBarData(true);
596                 });
597
598                 in_search = false;
599             }
600             search_thread_running = false;
601
602             mainList.Invalidate();
603         }
604
605         private void ParseExtensions(string in_exp, ArrayList extensions)
606         {
607             int ext_start = in_exp.ToLower().IndexOf("ext(");
608             if (ext_start == -1)
609                 return;
610             int ext_end = in_exp.ToLower().IndexOf(")", ext_start);
611             int comma_index = ext_start + 4;
612             int i;
613             int count = 0;
614             string out_ext;
615
616             for (i = ext_start + 4; i <= ext_end; i++)
617             {
618                 if (in_exp[i] == ',' || i == ext_end)
619                 {
620                     out_ext = in_exp.Substring(comma_index, count);
621                     extensions.Add((string)out_ext);
622
623                     comma_index = i + 1;
624                     count = -1;
625                 }
626                 count++;
627             }
628         }
629
630         private void listView1_Click(object sender, EventArgs e)
631         {
632             //EnableArrows(false);
633         }
634
635         private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
636         {
637             DuplicateObject selected_item = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Duplicate);
638             DuplicateObject selected_item_group = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, -1);
639
640
641             if (selected_item == null || selected_item_group == null)
642             {
643                 e.Cancel = true;
644                 return;
645             }
646
647             //  if (GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Data))
648             //      e.Cancel = true;
649
650
651             if (selected_item.ObjectType == DuplicateObject.Type.Group)
652             {
653                 if (selected_item_group.DuplicateGroup.ContainsLink == true)
654                 {
655                     checkAllFiles.Visible = false;
656                     checkAllFilesInThisGroupExcept.Visible = false;
657                     unCheckAllFilesInThisGroupExcept.Visible = false;
658                     openContainingFolder.Visible = false;
659                     deleteThisFile.Visible = false;
660                     openThisFile.Visible = false;
661                     deleteThisFolder.Visible = false;
662                     itemRightClickSeperator.Visible = false;
663                     disconnectFileFromHardLinkGroup.Visible = false;
664                     excludeContainingOrParentFolder.Visible = false;
665                     excludeThisFilesExtensionToolStripMenuItem.Visible = false;
666                     disconnectAllFilesFromHardLinkGroupToolStrip.Visible = true;
667                 }
668                 else
669                 {
670                     e.Cancel = true;
671                 }
672             }
673             else
674             {
675                 checkAllFiles.Visible = true;
676                 openContainingFolder.Visible = true;
677                 deleteThisFile.Visible = true;
678                 openThisFile.Visible = true;
679                 deleteThisFolder.Visible = true;
680                 itemRightClickSeperator.Visible = true;
681                 disconnectFileFromHardLinkGroup.Visible = true;
682                 excludeContainingOrParentFolder.Visible = true;
683                 disconnectAllFilesFromHardLinkGroupToolStrip.Visible = false;
684
685
686                 if (selected_item_group.DuplicateGroup.ContainsLink == true)
687                     disconnectFileFromHardLinkGroup.Visible = true;
688                 else
689                     disconnectFileFromHardLinkGroup.Visible = false;
690             }
691         }
692
693         public void LoadSettings()
694         {
695             ExtendedDebugData.AddEntry(1, "Loading settings");
696
697
698
699             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "show_delete") == "1")
700                 mainList.DeleteButton = true;
701             else
702                 mainList.DeleteButton = false;
703
704             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "show_link") == "1")
705                 mainList.LinkButton = true;
706             else
707                 mainList.LinkButton = false;
708
709             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "highlight_items") == "1")
710                 mainList.HighlightMouseOverItems = true;
711             else
712                 mainList.HighlightMouseOverItems = false;
713
714             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "auto_remove_1") == "1")
715                 GlobalBuffers.DeleteOneFileGroups = true;
716             else
717                 GlobalBuffers.DeleteOneFileGroups = false;
718
719             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "display_style") == "1")
720                 GlobalBuffers.DisplayStyle = GlobalBuffers.FileNameDisplayStyle.FullPath;
721             else
722                 GlobalBuffers.DisplayStyle = GlobalBuffers.FileNameDisplayStyle.FilenameThenPath;
723
724             GlobalBuffers.MinimumFileSize = Convert.ToInt64(GlobalBuffers.SettingsManager.FindSettingStringSingle( "minimum_size"));
725             GlobalBuffers.MinimumFileSizeMetric = Convert.ToInt32(GlobalBuffers.SettingsManager.FindSettingStringSingle( "minimum_size_metric"));
726
727             GlobalBuffers.MaximumFileSize = Convert.ToInt64(GlobalBuffers.SettingsManager.FindSettingStringSingle( "maximum_size"));
728             GlobalBuffers.MaximumFileSizeMetric = Convert.ToInt32(GlobalBuffers.SettingsManager.FindSettingStringSingle( "maximum_size_metric"));
729
730             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "search_mode") == "cbf")
731             {
732                 GlobalBuffers.CompareByActualData = false;
733                 GlobalBuffers.CompareByFilename = true;
734             }
735             else
736             {
737                 GlobalBuffers.CompareByFilename = false;
738                 GlobalBuffers.CompareByActualData = true;
739             }
740
741             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "check_extension") == "1")
742                 GlobalBuffers.CompareByExtension = true;
743             else
744                 GlobalBuffers.CompareByExtension = false;
745             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "check_file_size") == "1")
746                 GlobalBuffers.CompareBySize = true;
747             else
748                 GlobalBuffers.CompareBySize = false;
749             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "check_date_time") == "1")
750                 GlobalBuffers.CompareByTimestamp = true;
751             else
752                 GlobalBuffers.CompareByTimestamp = false;
753
754             string[] folders, inclusions;
755             folders = GlobalBuffers.SettingsManager.FindSettingStringMultiple( "folders");
756             inclusions = GlobalBuffers.SettingsManager.FindSettingStringMultiple( "inclusions");
757
758             GlobalBuffers.scan_folders = folders;
759
760             if (inclusions != null && inclusions.Length != 0)
761                 GlobalBuffers.FileTypeInclusions = inclusions;
762             else
763                 GlobalBuffers.FileTypeInclusions = null;
764
765             if (GlobalBuffers.MainFormLoaded == false)
766             {
767                 if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "maximized") == "yes")
768                     this.WindowState = FormWindowState.Maximized;
769                 else
770                 {
771
772                     int pos_x = Convert.ToInt32(GlobalBuffers.SettingsManager.FindSettingStringSingle( "pos_x"));
773                     int pos_y = Convert.ToInt32(GlobalBuffers.SettingsManager.FindSettingStringSingle( "pos_y"));
774
775                     int width = Convert.ToInt32(GlobalBuffers.SettingsManager.FindSettingStringSingle( "size_width"));
776                     int height = Convert.ToInt32(GlobalBuffers.SettingsManager.FindSettingStringSingle( "size_height"));
777
778                     if (width == 0 || height == 0)
779                     {
780                         width = 700;
781                         height = 500;
782                     }
783
784                     this.Size = new System.Drawing.Size(width, height);
785
786                     this.Location = new Point(pos_x, pos_y);
787
788                 }
789             }
790
791             int scroll_step = GlobalBuffers.SettingsManager.FindSettingStringSingleInt("scroll_step");
792             GlobalBuffers.WheelSkip = scroll_step;
793
794             LoadRecentFileList();
795
796             if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "large_icons") == "0")
797                 LoadSmallToolbar();
798             
799           //  LoadPinnedList();
800         }
801
802         public void LoadSmallToolbar()
803         {
804             int i;
805
806             //commandStrip.ImageList = null;
807             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(global::DupliDelete.Properties.Resources));
808
809             for (i = 0; i < commandStrip.Items.Count; i++)
810             {
811                 if (!(commandStrip.Items[i] is ToolStripSeparator))
812                 {
813
814                     if ((string)commandStrip.Items[i].Tag != null)
815                     {
816                         commandStrip.Items[i].Size = new System.Drawing.Size(16, 16);
817                         commandStrip.Items[i].Image = ((System.Drawing.Image)(resources.GetObject(commandStrip.Items[i].Tag + "_classic")));
818                     }
819                 }
820             }
821
822
823             for (i = 0; i < searchStrip.Items.Count; i++)
824             {
825                 if (!(searchStrip.Items[i] is ToolStripSeparator || searchStrip.Items[i] is ToolStripTextBox))
826                 {
827                     //commandStrip.Items[i].Image = ((System.Drawing.Image)(resources.GetObject(commandStrip.Items[i].Tag + "_smaller")));
828
829                     if ((string)searchStrip.Items[i].Tag != null)
830                     {
831                         searchStrip.Items[i].Size = new System.Drawing.Size(16, 16);
832                         searchStrip.Items[i].Image = ((System.Drawing.Image)(resources.GetObject(searchStrip.Items[i].Tag + "_classic")));
833                     }
834                 }
835             }
836         }
837
838         private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
839         {
840             Options opt_wnd1 = new Options();
841
842             opt_wnd1.Owner = this;
843             opt_wnd1.ShowDialog();
844
845             LoadSettings();
846             GlobalBuffers.mainList.Invalidate();
847         }
848
849         private void toolStripButton3_Click(object sender, EventArgs e)
850         {
851             if (GlobalBuffers.working)
852                 return;
853             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
854                 return;
855             if (GlobalBuffers.Duplicates.TotalCheckedItems == 0)
856             {
857                 MessageBox.Show("Please check an item first.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
858                 return;
859             }
860             int i, j;
861             int checked_group_count = 0;
862             //HardLinkWindow hlw1 = new HardLinkWindow();
863
864             GlobalBuffers.CreateHardLinkData = new CreateHardLinkData();
865
866             //int no_confirm = GlobalBuffers.SettingsManager.FindSettingStringSingleInt( "no_confirm");
867
868             //if (no_confirm == 0 && (DialogResult)MessageBox.Show("This command will create hard links from the checked file in every group. This means that every file in a group that is not checked will be deleted and replaced with a hard link that points to the checked file in the group. Please be sure of what you're doing before you proceed.\n\nAre you sure?", "Duplicate Commander", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
869                // return;
870
871             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
872             {
873                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
874                 {
875                     if (GlobalBuffers.Duplicates[i][j].Checked == true)
876                     {
877                         checked_group_count++;
878                         if (checked_group_count > 1)
879                         {
880                             MessageBox.Show("More than 1 file out of one or more groups are checked. In order to create hard links, only 1 file must be checked from each group because that is the file that all other files in the group will point to.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
881                             //duplicateList.EnsureVisible(i);
882                             return;
883                         }
884                     }
885                 }
886
887                 checked_group_count = 0;
888             }
889
890             Forms.CreateHardLinksWindow chl = new Forms.CreateHardLinksWindow();
891             chl.Owner = this;
892             chl.ShowDialog();
893
894            /* DialogResult r = MessageBox.Show("Would you like to create an undo script? If you think you may need to undo this operation in the future, it is highly recommended.", "Duplicate Commander", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
895             if (r == System.Windows.Forms.DialogResult.Yes)
896             {
897                 SaveFileDialog sfd1 = new SaveFileDialog();
898                 sfd1.Title = "Please specify the place to save the undo script...";
899                 sfd1.Filter = "Duplicate Commander Undo Script (*.dds)|*.dds||";
900                 sfd1.ShowDialog();
901
902                 if (sfd1.FileName == "")
903                 {
904                     if ((DialogResult)MessageBox.Show("You did not specify a place to save an undo script. To continue without saving one, click OK.", "Duplicate Commander", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.Cancel)
905                         return;
906                     GlobalBuffers.CreateHardLinkData.CreateUndoScript = false;
907                 }
908                 else
909                 {
910                     GlobalBuffers.CreateHardLinkData.CreateUndoScript = true;
911                     GlobalBuffers.CreateHardLinkData.UndoScriptPath = sfd1.FileName;
912                 }
913             }
914             else if (r == System.Windows.Forms.DialogResult.No)
915             {
916                 GlobalBuffers.CreateHardLinkData.CreateUndoScript = false;
917
918                 //EnableArrows(false);
919             }
920
921             */
922
923             if (GlobalBuffers.CreateHardLinkData.Canceled == false)
924             {
925                 checking_window = new Checking();
926                 checking_window.Text = "Creating hard links";
927                 checking_window.Owner = this;
928
929                 long_process_listener = new LongProcessListener(checking_window, this);
930
931                 ThreadStart ts = new ThreadStart(CreateHardLinks);
932                 Thread t = new Thread(ts);
933
934                 t.Start();
935             }
936         }
937
938         private void toolStripButton4_Click(object sender, EventArgs e)
939         {
940             if (GlobalBuffers.working)
941                 return;
942             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
943                 return;
944             if (GlobalBuffers.Duplicates.TotalCheckedItems == 0)
945             {
946                 MessageBox.Show("Please check an item first.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
947                 return;
948             }
949             ThreadStart ts1;
950             Thread t;
951
952             int no_confirm = GlobalBuffers.SettingsManager.FindSettingStringSingleInt( "no_confirm");
953
954             if (no_confirm == 0 && (DialogResult)MessageBox.Show("You are about to delete all checked files to the Recycle Bin. Are you sure?", "Duplicate Commander", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
955                 return;
956             else
957             {
958
959                 checking_window = new Checking();
960                 checking_window.Text = "Deleting items...";
961                 checking_window.statusText.Text = "Please wait...";
962                 long_process_listener = new LongProcessListener(checking_window, this);
963
964                 ts1 = new ThreadStart(DeleteChecked);
965                 t = new Thread(ts1);
966                 t.Start();
967
968                 EnableArrows(false);
969             }
970         }
971
972         private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
973         {
974             About ab1 = new About();
975
976             ab1.Owner = this;
977             ab1.ShowDialog();
978         }
979
980         private void toolStripButton6_Click(object sender, EventArgs e)
981         {
982             if (GlobalBuffers.working)
983                 return;
984             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
985                 return;
986
987             ThreadStart ts = new ThreadStart(CheckAllButFirst);
988             Thread t = new Thread(ts);
989
990             checking_window = new Checking();
991             long_process_listener = new LongProcessListener(checking_window, this);
992
993             t.Start();
994         }
995
996         private void CheckAllButFirst()
997         {
998             int i = 0, j = 0;
999             double prg = (double)100 / GlobalBuffers.Duplicates.Count, prg2 = (double)0.0;
1000             int group_count = 0, duplicate_count = 0;
1001
1002
1003             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1004             {
1005                 duplicate_count = 0;
1006
1007                 if (checking_window.cancel_clicked == true)
1008                     break;
1009
1010                 GlobalBuffers.Duplicates[i][0].Checked = false;
1011
1012                 for (j = 1; j < GlobalBuffers.Duplicates[i].Count; j++)
1013                 {
1014                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1015
1016                     GlobalBuffers.Duplicates[i][j].Checked = true;
1017                     duplicate_count++;
1018                 }
1019
1020                 prg2 += (double)prg;
1021                 group_count++;
1022             }
1023
1024             mainList.Invalidate();
1025
1026             this.Invoke((MethodInvoker)delegate
1027             {
1028                 SetStatusBarData(false);
1029
1030                 EnableArrows(false);
1031             });
1032
1033             long_process_listener.Complete = true;
1034         }
1035
1036         private void toolStripButton7_Click(object sender, EventArgs e)
1037         {
1038             if (GlobalBuffers.working)
1039                 return;
1040             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1041                 return;
1042             if (GlobalBuffers.Duplicates.TotalCheckedItems == 0)
1043             {
1044                 MessageBox.Show("Please check an item first.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
1045                 return;
1046             }
1047
1048             MoveCheckedWindow mcw1 = new MoveCheckedWindow();
1049
1050             mcw1.Owner = this;
1051             mcw1.ShowDialog();
1052             if (GlobalBuffers.folders_ok_clicked == true)
1053             {
1054                 ThreadStart ts = new ThreadStart(MoveCheckedItemsToFolder);
1055                 Thread t = new Thread(ts);
1056
1057                 checking_window = new Checking();
1058                 checking_window.Text = "Moving files...";
1059                 checking_window.statusText.Text = "Please wait...";
1060
1061                 long_process_listener = new LongProcessListener(checking_window, this);
1062
1063                 t.Start();
1064             }
1065         }
1066
1067         private void MoveCheckedItemsToFolder()
1068         {
1069             int i, j;
1070             string folder = GlobalBuffers.MoveFilesData.Folder;
1071             double prg = (double)100 / GlobalBuffers.Duplicates.Count;
1072             double prg2 = (double)0.0;
1073             TextFileStream tfs1 = null;
1074             if (GlobalBuffers.MoveFilesData.UndoListPath != "" && GlobalBuffers.MoveFilesData.CreateUndoList == true)
1075                 tfs1 = new TextFileStream(GlobalBuffers.MoveFilesData.UndoListPath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
1076             string moved_filename;
1077             int copy_filename_loop = 1;
1078             int group_count = 0, duplicate_count = 0;
1079             ErrorClass errors = new ErrorClass(this, "The following files could not be moved.");
1080
1081             GlobalBuffers.working = true;
1082
1083             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1084             {
1085                 duplicate_count = 0;
1086                 if (checking_window.cancel_clicked == true)
1087                 {
1088                     break;
1089                 }
1090
1091                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1092                 {
1093                     if (checking_window.cancel_clicked == true)
1094                     {
1095                         break;
1096                     }
1097
1098                     if (GlobalBuffers.Duplicates[i][j].Checked == true)
1099                     {
1100                         moved_filename = folder + "\\" + System.IO.Path.GetFileName(GlobalBuffers.Duplicates[i][j].Filename);
1101
1102                         copy_filename_loop = 1;
1103
1104                         while (System.IO.File.Exists(moved_filename) == true)
1105                         {
1106                             moved_filename = folder + "\\" + System.IO.Path.GetFileNameWithoutExtension(GlobalBuffers.Duplicates[i][j].Filename) + "(" + copy_filename_loop + ")" + System.IO.Path.GetExtension(System.IO.Path.GetFileNameWithoutExtension(GlobalBuffers.Duplicates[i][j].Filename)) + System.IO.Path.GetExtension(GlobalBuffers.Duplicates[i][j].Filename);
1107                             copy_filename_loop++;
1108                         }
1109
1110                         try
1111                         {
1112                             if (File.Exists(GlobalBuffers.Duplicates[i][j].Filename))
1113                                 File.Move(GlobalBuffers.Duplicates[i][j].Filename, moved_filename);
1114                             else
1115                             {
1116                                 errors.AddError(GlobalBuffers.Duplicates[i][j].Filename, "The source file does not exist.");
1117                                 continue;
1118                             }
1119
1120                         }
1121                         catch
1122                         {
1123
1124                         }
1125                         if (GlobalBuffers.MoveFilesData.CreateUndoList == true)
1126                             tfs1.WriteLine(tfs1, "<move>" + "\"" + moved_filename + "\"" + ",?," + "\"" + GlobalBuffers.Duplicates[i][j].Filename + "\"");
1127
1128                     }
1129                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1130                     duplicate_count++;
1131
1132                 }
1133
1134                 group_count++;
1135                 prg2 += (double)prg;
1136                 checking_window.progress = (int)prg2;
1137
1138             }
1139
1140             if (GlobalBuffers.MoveFilesData.UndoListPath != "" && GlobalBuffers.MoveFilesData.CreateUndoList == true)
1141                 tfs1.Close();
1142
1143             this.Invoke((MethodInvoker)delegate
1144             {
1145                 SetStatusBarData(false);
1146             });
1147
1148             GlobalBuffers.working = false;
1149
1150             long_process_listener.Complete = true;
1151             errors.ShowErrorWindow();
1152         }
1153
1154         public static void WriteUndoScript(TextFileStream tfs1, int operation, string file_to_process, string destination_path)
1155         {
1156             tfs1.WriteLine(tfs1, (operation == 1 ? "<copy>" : "<move>") + "\"" + file_to_process + "\"" + ",?," + "\"" + destination_path + "\"");
1157         }
1158
1159         private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
1160         {
1161             if (GlobalBuffers.working)
1162                 return;
1163             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1164                 return;
1165
1166             ThreadStart ts = new ThreadStart(CheckAll);
1167             checking_window = new Checking();
1168             long_process_listener = new LongProcessListener(checking_window, this);
1169
1170             Thread t = new Thread(ts);
1171             t.Start();
1172
1173         }
1174
1175         private void CheckAll()
1176         {
1177             int i, j;
1178             double progress_step = (double)100 / GlobalBuffers.Duplicates.Count;
1179             int group_count = 0, duplicate_count = 0;
1180
1181
1182             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1183             {
1184                 if (checking_window.cancel_clicked == true)
1185                     break;
1186
1187                 duplicate_count = 0;
1188
1189                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1190                 {
1191                     if (checking_window.cancel_clicked == true)
1192                         break;
1193                     GlobalBuffers.Duplicates[i][j].Checked = true;
1194
1195                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1196                     duplicate_count++;
1197
1198                 }
1199
1200                 group_count++;
1201             }
1202
1203             mainList.Invalidate();
1204
1205             this.Invoke((MethodInvoker)delegate
1206             {
1207                 SetStatusBarData(false);
1208
1209                 EnableArrows(false);
1210             });
1211
1212             long_process_listener.Complete = true;
1213         }
1214
1215         public void uncheckAllItemsToolStripMenuItem_Click(object sender, EventArgs e)
1216         {
1217             if (GlobalBuffers.working)
1218                 return;
1219             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1220                 return;
1221
1222             ThreadStart ts = new ThreadStart(UncheckAll);
1223             checking_window = new Checking();
1224             long_process_listener = new LongProcessListener(checking_window, this);
1225
1226             Thread t = new Thread(ts);
1227             t.Start();
1228
1229         }
1230
1231         public void UncheckAll()
1232         {
1233             int i, j;
1234             double progress_step = (double)100 / GlobalBuffers.Duplicates.Count;
1235             int group_count = 0, duplicate_count = 0;
1236
1237             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1238             {
1239                 duplicate_count = 0;
1240                 if (checking_window.cancel_clicked == true)
1241                     break;
1242
1243                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1244                 {
1245                     if (checking_window.cancel_clicked == true)
1246                         break;
1247                     GlobalBuffers.Duplicates[i][j].Checked = false;
1248
1249                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1250                     duplicate_count++;
1251                 }
1252                 group_count++;
1253             }
1254
1255             mainList.Invalidate();
1256
1257             this.Invoke((MethodInvoker)delegate
1258             {
1259                 SetStatusBarData(false);
1260
1261                 EnableArrows(false);
1262             });
1263
1264             long_process_listener.Complete = true;
1265         }
1266
1267         public void DeleteChecked()
1268         {
1269             GlobalBuffers.working = true;
1270             int i, j;
1271             ErrorClass errors = new ErrorClass(GlobalBuffers.main_form, "The following files could not be deleted.");
1272             double prg, prg2 = (double)0.0;
1273             GlobalBuffers.working = true;
1274             int group_count = 0, duplicate_count = 0;
1275
1276             prg = (double)100 / GlobalBuffers.Duplicates.Count;
1277
1278             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1279             {
1280                 duplicate_count = 0;
1281
1282                 if (checking_window.cancel_clicked == true)
1283                     break;
1284
1285                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1286                 {
1287                     if (checking_window.cancel_clicked == true)
1288                         break;
1289
1290                     if (GlobalBuffers.Duplicates[i][j].Checked == true)
1291                     {
1292                         if (File.Exists(GlobalBuffers.Duplicates[i][j].Filename) == false)
1293                             errors.AddError(GlobalBuffers.Duplicates[i][j].Filename, "The file does not exist.");
1294
1295                         try
1296                         {
1297                             FileOperationAPIWrapper.MoveToRecycleBin(GlobalBuffers.Duplicates[i][j].Filename);
1298                         }
1299                         catch (Exception)
1300                         {
1301                             errors.AddError(GlobalBuffers.Duplicates[i][j].Filename, "The file may be read-only or in use by another process.");
1302                             checking_window.cancel_clicked = true;
1303                             break;
1304                         }
1305
1306                         if (GlobalBuffers.Duplicates[i].RemoveAt(j, true) == DuplicateGroup.RemoveStatus.RemovedFile)
1307                             j--;
1308                         else
1309                         {
1310                             i--;
1311                             break;
1312                         }
1313                     }
1314
1315                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1316                     duplicate_count++;
1317
1318                 }
1319
1320                 prg2 += (double)prg;
1321                 checking_window.progress = (int)prg2;
1322                 group_count++;
1323             }
1324
1325             GlobalBuffers.working = false;
1326             long_process_listener.Complete = true;
1327
1328             SetStatusBarData(false);
1329
1330             mainList.Invalidate();
1331
1332             long_process_listener.Complete = true;
1333
1334             errors.ShowErrorWindow();
1335         }
1336
1337
1338         private void toolStripMenuItem3_Click(object sender, EventArgs e)
1339         {
1340             try
1341             {
1342                 DuplicateObject selected = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Duplicate);
1343                 string folder = Path.GetDirectoryName(selected.DuplicateFile.Filename);
1344
1345                 if (selected.ObjectType == DuplicateObject.Type.File)
1346                 {
1347                     if (!Directory.Exists(folder))
1348                         MessageBox.Show("The selected file's containing folder does not exist.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Information);
1349
1350                     System.Diagnostics.Process.Start(folder);
1351                 }
1352             }
1353             catch (Win32Exception)
1354             {
1355                 MessageBox.Show("Could not open the selected file's containing folder.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Information);
1356             }
1357         }
1358
1359         private void toolStripMenuItem5_Click(object sender, EventArgs e)
1360         {
1361             try
1362             {
1363                 DuplicateObject selected = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Duplicate);
1364
1365                 if (selected.ObjectType == DuplicateObject.Type.File)
1366                 {
1367                     if (!File.Exists(selected.DuplicateFile.Filename))
1368                     {
1369                         MessageBox.Show(this, "The selected file does not exist.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
1370                         return;
1371                     }
1372
1373                     System.Diagnostics.Process.Start(selected.DuplicateFile.Filename);
1374                 }
1375             }
1376             catch (Win32Exception)
1377             {
1378                 MessageBox.Show(this, "Could not open the selected file.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
1379             }
1380         }
1381
1382         private void toolStripMenuItem4_Click(object sender, EventArgs e)
1383         {
1384             DeleteSelectedItem();
1385         }
1386
1387
1388
1389         public void DeleteSelectedItem()
1390         {
1391             if (GlobalBuffers.mainList.SelectedItem.Group == -1 || GlobalBuffers.mainList.SelectedItem.Group >= GlobalBuffers.mainList.SelectedItem.Data.Count)
1392                 return;
1393             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1394                 return;
1395
1396             int i;
1397             DialogResult dr = DialogResult.No;
1398             int no_confirm = GlobalBuffers.SettingsManager.FindSettingStringSingleInt( "no_confirm");
1399             ErrorClass errors = new ErrorClass(this, "The following files could not be deleted.");
1400             DuplicateListView.DrawIndex selected_item = new DuplicateListView.DrawIndex(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Duplicate, GlobalBuffers.mainList.DrawStartIndex.Data);
1401             DuplicateObject selected_object = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Duplicate);
1402
1403             if (selected_object.ObjectType == DuplicateObject.Type.File)
1404             {
1405                 if (no_confirm == 0)
1406                     dr = MessageBox.Show("Are you sure you want to delete the selected file?", "Duplicate Commander", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
1407                 if (no_confirm == 1 || dr == DialogResult.Yes)
1408                 {
1409                     if (!File.Exists(selected_object.DuplicateFile.Filename))
1410                     {
1411                         MessageBox.Show("The selected file does not exist. It may have already been deleted.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
1412                         return;
1413                     }
1414
1415                     try
1416                     {
1417                         FileOperationAPIWrapper.MoveToRecycleBin(selected_object.DuplicateFile.Filename);
1418                     }
1419                     catch (Exception)
1420                     {
1421                         errors.AddError(selected_object.DuplicateFile.Filename, "The file may be read-only or in use by another process.");
1422                         errors.ShowErrorWindow();
1423                         return;
1424                     }
1425                 }
1426                 else
1427                     return;
1428
1429
1430
1431                 GlobalBuffers.Duplicates[selected_item.Group].RemoveAt(selected_item.Duplicate, true);
1432
1433             }
1434             else
1435             {
1436                 if (no_confirm == 0)
1437                     dr = MessageBox.Show("Are you sure you want to delete the selected group?", "Duplicate Commander", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
1438                 if (no_confirm == 1 || dr == DialogResult.Yes)
1439                 {
1440                     DuplicateObject group = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, -1);
1441
1442                     for (i = 0; i < group.DuplicateGroup.Count; i++)
1443                     {
1444                         try
1445                         {
1446                             FileOperationAPIWrapper.MoveToRecycleBin(GlobalBuffers.Duplicates[GlobalBuffers.mainList.SelectedItem.Group][i].Filename);
1447                         }
1448                         catch (Exception)
1449                         {
1450                             errors.AddError(GlobalBuffers.Duplicates[GlobalBuffers.mainList.SelectedItem.Group][i].Filename, "The file may be read-only or in use by another process.");
1451                             errors.ShowErrorWindow();
1452                             return;
1453                         }
1454
1455                         if (GlobalBuffers.Duplicates[GlobalBuffers.mainList.SelectedItem.Group].RemoveAt(i, true) == DuplicateGroup.RemoveStatus.RemovedFile)
1456                             i--;
1457                         else
1458                             break;
1459                     }
1460                 }
1461                 else
1462                     return;
1463
1464
1465             }
1466
1467             SetStatusBarData(false);
1468             mainList.Invalidate();
1469         }
1470
1471         private void listView1_KeyDown(object sender, KeyEventArgs e)
1472         {
1473             if (e.KeyData == Keys.Delete)
1474             {
1475                 DeleteSelectedItem();
1476             }
1477         }
1478
1479         private void toolStripButton1_Click_1(object sender, EventArgs e)
1480         {
1481
1482         }
1483
1484
1485
1486         private void toolStripButton12_Click(object sender, EventArgs e)
1487         {
1488             if (GlobalBuffers.working)
1489                 return;
1490             if (mainList.Visible == false)
1491                 return;
1492             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1493                 return;
1494             ThreadStart ts = new ThreadStart(CheckFirst);
1495             Thread t = new Thread(ts);
1496             checking_window = new Checking();
1497             long_process_listener = new LongProcessListener(checking_window, this);
1498
1499             t.Start();
1500         }
1501
1502         private void CheckFirst()
1503         {
1504             int i, j;
1505             double prg = (double)100 / GlobalBuffers.Duplicates.Count, prg2 = (double)0.0;
1506             int group_count = 0, duplicate_count = 0;
1507
1508             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1509             {
1510                 duplicate_count = 0;
1511                 if (checking_window.cancel_clicked == true)
1512                     break;
1513
1514                 if (GlobalBuffers.Duplicates[i].Count >= 1)
1515                 {
1516                     for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1517                     {
1518                         GlobalBuffers.Duplicates[i][j].Checked = j == 0 ? true : false;
1519
1520                         checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1521
1522                         duplicate_count++;
1523                     }
1524                 }
1525
1526                 group_count++;
1527                 prg2 += (double)prg;
1528                 checking_window.progress = prg2;
1529             }
1530
1531             mainList.Invalidate();
1532
1533             this.Invoke((MethodInvoker)delegate
1534             {
1535                 SetStatusBarData(false);
1536
1537                 EnableArrows(false);
1538             });
1539
1540             long_process_listener.Complete = true;
1541         }
1542
1543         private void runUndoScriptToolStripMenuItem_Click(object sender, EventArgs e)
1544         {
1545             if (GlobalBuffers.working)
1546                 return;
1547             OpenFileDialog ofd1 = new OpenFileDialog();
1548             ruds1 = new RunUndoScript();
1549
1550             ofd1.Title = "Specify the undo script...";
1551             ofd1.Filter = "Duplicate Commander Undo Script (*.dds)|*.dds||";
1552
1553             ofd1.InitialDirectory = "C:\\";
1554
1555             ofd1.ShowDialog();
1556
1557             if (ofd1.FileName != "")
1558             {
1559                 ParseUndoScript(ofd1.FileName);
1560
1561                 ruds1.Tag = (string)ofd1.FileName;
1562                 ruds1.Owner = this;
1563                 ruds1.ShowDialog();
1564             }
1565             //ExecuteUndoScript(ofd1.FileName);
1566         }
1567
1568         private void ParseUndoScript(string in_file)
1569         {
1570             string[] contents = File.ReadAllLines(in_file);
1571             string file1, file2;
1572             ListViewItem lvi1;
1573             int i = 0;
1574             int operation;
1575
1576             for (i = 0; i < contents.Length; i++)
1577             {
1578                 if (contents[i].Substring(0, 6) == "<copy>")
1579                     operation = 1;
1580                 else
1581                     operation = 2;
1582                 file1 = contents[i].Substring(7, contents[i].IndexOf(",?,") - 8);
1583                 file2 = contents[i].Substring(contents[i].LastIndexOf(",?,") + 4, contents[i].Length - (contents[i].LastIndexOf(",?,") + 4) - 1);
1584
1585                 lvi1 = new ListViewItem();
1586                 if (operation == 1)
1587                     lvi1.Text = "Copy";
1588                 else
1589                     lvi1.Text = "Move";
1590                 lvi1.SubItems.Add(file1);
1591                 lvi1.SubItems.Add(file2);
1592                 lvi1.SubItems.Add("");
1593                 lvi1.Tag = (int)operation;
1594
1595                 ruds1.listView1.Items.Add(lvi1);
1596             }
1597         }
1598
1599         private void ExecuteUndoScript(string in_file)
1600         {
1601             TextFileStream tfs1 = new TextFileStream(in_file, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Read);
1602             string buffer, file1, file2;
1603             StringByte sb1 = new StringByte();
1604             int operation;
1605
1606             while (tfs1.Position < tfs1.Length)
1607             {
1608                 sb1 = tfs1.ReadLine();
1609
1610                 buffer = sb1.out_string;
1611                 if (buffer.Substring(0, 5) == "<copy>")
1612                     operation = 1;
1613                 else
1614                     operation = 2;
1615                 file1 = buffer.Substring(5, buffer.LastIndexOf(",?,"));
1616                 file2 = buffer.Substring(5, buffer.LastIndexOf(",?,") + 3);
1617
1618                 if ((File.Exists(file1)))
1619                 {
1620                     if (operation == 1)
1621                         System.IO.File.Copy(file1, file2);
1622                     else
1623                         System.IO.File.Move(file1, file2);
1624                 }
1625             }
1626
1627             tfs1.Close();
1628         }
1629
1630         private void toolStripButton5_Click(object sender, EventArgs e)
1631         {
1632             if (GlobalBuffers.working)
1633                 return;
1634             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1635                 return;
1636
1637             ThreadStart ts = new ThreadStart(CheckSmallest);
1638             checking_window = new Checking();
1639             long_process_listener = new LongProcessListener(checking_window, this);
1640
1641             Thread t = new Thread(ts);
1642             t.Start();
1643         }
1644
1645         private void CheckSmallest()
1646         {
1647             int i, j, index = -1;
1648             long smallest = -1;
1649             double prg_step = (double)100 / GlobalBuffers.Duplicates.Count;
1650             double prg = 0;
1651             int group_count = 0, duplicate_count = 0;
1652
1653             //   checking_window = new Checking();
1654
1655             //   long_process_listener = new LongProcessListener(checking_window, this);
1656
1657             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1658             {
1659                 duplicate_count = 0;
1660                 if (checking_window.cancel_clicked == true)
1661                     break;
1662
1663                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1664                 {
1665                     if (GlobalBuffers.Duplicates[i][j].Size < smallest || smallest == -1)
1666                     {
1667                         smallest = GlobalBuffers.Duplicates[i][j].Size;
1668                         index = j;
1669                     }
1670
1671                     GlobalBuffers.Duplicates[i][j].Checked = false;
1672
1673                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1674                     duplicate_count++;
1675                 }
1676
1677                 GlobalBuffers.Duplicates[i][index].Checked = true;
1678
1679                 smallest = -1;
1680
1681                 prg += (double)prg_step;
1682                 group_count++;
1683                 checking_window.progress = prg;
1684
1685             }
1686             mainList.Invalidate();
1687
1688             this.Invoke((MethodInvoker)delegate
1689             {
1690                 SetStatusBarData(false);
1691                 EnableArrows(false);
1692             });
1693
1694             long_process_listener.Complete = true;
1695
1696         }
1697
1698         private void toolStripButton13_Click(object sender, EventArgs e)
1699         {
1700             if (GlobalBuffers.working)
1701                 return;
1702             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1703                 return;
1704
1705             ThreadStart ts = new ThreadStart(CheckLargest);
1706             checking_window = new Checking();
1707             long_process_listener = new LongProcessListener(checking_window, this);
1708
1709             Thread t = new Thread(ts);
1710             t.Start();
1711         }
1712
1713         private void CheckLargest()
1714         {
1715             int i, j, index = -1;
1716             long largest = -1;
1717             double prg_step = (double)100 / GlobalBuffers.Duplicates.Count;
1718             double prg = 0;
1719             int group_count = 0, duplicate_count = 0;
1720
1721             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1722             {
1723                 duplicate_count = 0;
1724                 if (checking_window.cancel_clicked == true)
1725                     break;
1726
1727                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1728                 {
1729                     if (GlobalBuffers.Duplicates[i][j].Size > largest || largest == -1)
1730                     {
1731                         largest = GlobalBuffers.Duplicates[i][j].Size;
1732                         index = j;
1733                     }
1734
1735                     GlobalBuffers.Duplicates[i][j].Checked = false;
1736
1737                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1738                     duplicate_count++;
1739                 }
1740
1741                 GlobalBuffers.Duplicates[i][index].Checked = true;
1742
1743                 largest = -1;
1744
1745                 prg += (double)prg_step;
1746
1747                 checking_window.progress = prg;
1748                 group_count++;
1749             }
1750             mainList.Invalidate();
1751
1752             this.Invoke((MethodInvoker)delegate
1753             {
1754                 SetStatusBarData(false);
1755                 EnableArrows(false);
1756             });
1757
1758             long_process_listener.Complete = true;
1759         }
1760
1761         private void toolStripButton14_Click(object sender, EventArgs e)
1762         {
1763             if (GlobalBuffers.working)
1764                 return;
1765             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1766                 return;
1767
1768             checking_window = new Checking();
1769             long_process_listener = new LongProcessListener(checking_window, this);
1770
1771             ThreadStart ts = new ThreadStart(CheckOldest);
1772             Thread t = new Thread(ts);
1773
1774             t.Start();
1775         }
1776
1777         private void CheckOldest()
1778         {
1779             double oldest = (double)-1;
1780             int i, j, index = -1;
1781             double prg_step = 100 / GlobalBuffers.Duplicates.Count;
1782             int group_count = 0, duplicate_count = 0;
1783
1784             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1785             {
1786                 duplicate_count = 0;
1787                 if (checking_window.cancel_clicked == true)
1788                     break;
1789
1790                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1791                 {
1792                     double quantity = (double)quantizeTime(GlobalBuffers.Duplicates[i][j].DateModified);
1793
1794                     if (quantity < oldest || oldest == -1)
1795                     {
1796                         oldest = (double)quantity;
1797                         index = j;
1798                     }
1799
1800                     GlobalBuffers.Duplicates[i][j].Checked = false;
1801
1802                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1803                     duplicate_count++;
1804                 }
1805
1806                 GlobalBuffers.Duplicates[i][index].Checked = true;
1807                 oldest = -1;
1808
1809                 group_count++;
1810                 checking_window.progress += (double)prg_step;
1811             }
1812             mainList.Invalidate();
1813
1814             SetStatusBarData(false);
1815
1816             EnableArrows(false);
1817
1818             long_process_listener.Complete = true;
1819         }
1820
1821         private void toolStripButton15_Click(object sender, EventArgs e)
1822         {
1823             if (GlobalBuffers.working)
1824                 return;
1825             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1826                 return;
1827
1828             checking_window = new Checking();
1829             long_process_listener = new LongProcessListener(checking_window, this);
1830
1831             ThreadStart ts = new ThreadStart(CheckNewest);
1832             Thread t = new Thread(ts);
1833
1834             t.Start();
1835
1836         }
1837
1838         private void CheckNewest()
1839         {
1840             double newest = (double)-1;
1841             int i, j, index = -1;
1842             double prg_step = 100 / GlobalBuffers.Duplicates.Count;
1843             int group_count = 0, duplicate_count = 0;
1844
1845             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1846             {
1847                 duplicate_count = 0;
1848                 if (checking_window.cancel_clicked == true)
1849                     break;
1850
1851                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1852                 {
1853                     double quantity = (double)quantizeTime(GlobalBuffers.Duplicates[i][j].DateModified);
1854
1855                     if (quantity > newest || newest == -1)
1856                     {
1857                         newest = (double)quantity;
1858                         index = j;
1859                     }
1860
1861                     GlobalBuffers.Duplicates[i][j].Checked = false;
1862
1863                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1864                     duplicate_count++;
1865                 }
1866
1867                 GlobalBuffers.Duplicates[i][index].Checked = true;
1868                 newest = -1;
1869
1870                 checking_window.progress += (double)prg_step;
1871                 group_count++;
1872             }
1873             mainList.Invalidate();
1874
1875             SetStatusBarData(false);
1876
1877             EnableArrows(false);
1878
1879             long_process_listener.Complete = true;
1880         }
1881
1882         string copy_selected_path;
1883
1884         private void toolStripButton16_Click(object sender, EventArgs e)
1885         {
1886             if (GlobalBuffers.working)
1887                 return;
1888             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1889                 return;
1890             if (GlobalBuffers.Duplicates.TotalCheckedItems == 0)
1891             {
1892                 MessageBox.Show("Please check an item first.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
1893                 return;
1894             }
1895
1896             FolderBrowserDialog fbd1 = new FolderBrowserDialog();
1897
1898             fbd1.Description = "Specify the folder where you want the checked duplicates copied to.";
1899             fbd1.ShowNewFolderButton = true;
1900
1901             fbd1.ShowDialog();
1902
1903             if (fbd1.SelectedPath != "")
1904             {
1905                 copy_selected_path = fbd1.SelectedPath;
1906
1907                 checking_window = new Checking();
1908                 checking_window.Text = "Copying files...";
1909                 checking_window.statusText.Text = "Please wait...";
1910
1911                 long_process_listener = new LongProcessListener(checking_window, this);
1912
1913                 ThreadStart ts = new ThreadStart(CopyChecked);
1914                 Thread t = new Thread(ts);
1915                 t.Start();
1916             }
1917         }
1918
1919         public void CopyChecked()
1920         {
1921             int i, j;
1922             double prg = (double)100 / GlobalBuffers.Duplicates.Count;
1923             double prg2 = (double)0.0;
1924             string copy_filename = "";
1925             int group_count = 0, duplicate_count = 0;
1926             int copy_filename_loop = 1;
1927             ErrorClass errors = new ErrorClass(this, "The following files could not be copied.");
1928
1929
1930             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
1931             {
1932                 duplicate_count = 0;
1933
1934                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
1935                 {
1936                     if (GlobalBuffers.Duplicates[i][j].Checked == true)
1937                     {
1938                         copy_filename_loop = 1;
1939                         copy_filename = copy_selected_path + "\\" + Path.GetFileName(GlobalBuffers.Duplicates[i][j].Filename);
1940
1941                         while (System.IO.File.Exists(copy_filename) == true)
1942                         {
1943                             copy_filename = copy_selected_path + "\\" + System.IO.Path.GetFileNameWithoutExtension(GlobalBuffers.Duplicates[i][j].Filename) + "(" + copy_filename_loop + ")" + System.IO.Path.GetExtension(System.IO.Path.GetFileNameWithoutExtension(GlobalBuffers.Duplicates[i][j].Filename)) + System.IO.Path.GetExtension(GlobalBuffers.Duplicates[i][j].Filename);
1944                             copy_filename_loop++;
1945                         }
1946
1947                         if (File.Exists(GlobalBuffers.Duplicates[i][j].Filename))
1948                             File.Copy(GlobalBuffers.Duplicates[i][j].Filename, copy_filename, true);
1949                         else
1950                             errors.AddError(GlobalBuffers.Duplicates[i][j].Filename, "The source file does not exist.");
1951                     }
1952
1953
1954                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
1955                     duplicate_count++;
1956
1957                 }
1958
1959                 group_count++;
1960                 prg2 += (double)prg;
1961                 checking_window.progress = (double)prg2;
1962             }
1963
1964             long_process_listener.Complete = true;
1965             errors.ShowErrorWindow();
1966         }
1967
1968
1969         CheckAllInFolder check_all_dialog;
1970
1971         private void toolStripButton17_Click(object sender, EventArgs e)
1972         {
1973             if (GlobalBuffers.working)
1974                 return;
1975             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
1976                 return;
1977
1978             check_all_dialog = new CheckAllInFolder();
1979
1980             check_all_dialog.Owner = this;
1981             check_all_dialog.ShowDialog();
1982
1983             checking_window = new Checking();
1984             long_process_listener = new LongProcessListener(checking_window, this);
1985
1986             ThreadStart ts = new ThreadStart(CheckAllInFolder);
1987             Thread t = new Thread(ts);
1988
1989             t.Start();
1990
1991         }
1992
1993         private void CheckAllInFolder()
1994         {
1995             string folder;
1996             int i, j, k;
1997             bool already_checked_first = false;
1998             string old_status_text = statusBarPanel1.Text;
1999             double prg = (double)100 / GlobalBuffers.Duplicates.Count, prg2 = 0;
2000             int group_count = 0, duplicate_count = 0;
2001
2002             if (GlobalBuffers.folders_ok_clicked == true)
2003             {
2004                 if (GlobalBuffers.CheckAllInFolderData.FoldersToCheck.Count > 0)
2005                 {
2006                     if (GlobalBuffers.CheckAllInFolderData.PersistentCheck == false)
2007                     {
2008                         for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
2009                         {
2010                             if (checking_window.cancel_clicked == true)
2011                                 break;
2012
2013                             for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
2014                             {
2015                                 GlobalBuffers.Duplicates[i][j].Checked = false;
2016                             }
2017                         }
2018                     }
2019
2020                     for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
2021                     {
2022                         duplicate_count = 0;
2023                         if (checking_window.cancel_clicked == true)
2024                             break;
2025
2026                         for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
2027                         {
2028                             folder = Path.GetDirectoryName(GlobalBuffers.Duplicates[i][j].Filename);
2029
2030                             for (k = 0; k < GlobalBuffers.CheckAllInFolderData.FoldersToCheck.Count; k++)
2031                             {
2032                                 if (GlobalBuffers.CheckAllInFolderData.CheckOnlyOne == true
2033                                         && already_checked_first == true)
2034                                     break;
2035
2036                                 if (folder == (string)GlobalBuffers.CheckAllInFolderData.FoldersToCheck[k])
2037                                 {
2038                                     if (GlobalBuffers.CheckAllInFolderData.CheckOnlyOne == true && already_checked_first == false || GlobalBuffers.CheckAllInFolderData.CheckOnlyOne == false)
2039                                     {
2040                                        // GlobalBuffers.Duplicates[i][j].Checked = true;
2041                                         GlobalBuffers.Duplicates[i][j].Checked = GlobalBuffers.CheckAllInFolderData.CheckType == CheckJobDialogData.CheckTypes.Check ? true : false;
2042                                         already_checked_first = true;
2043                                     }
2044                                     if (GlobalBuffers.CheckAllInFolderData.CheckOnlyOne == true
2045                                         && already_checked_first == true)
2046                                         break;
2047                                 }
2048                             }
2049
2050                             checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
2051                             duplicate_count++;
2052
2053                         }
2054                         already_checked_first = false;
2055
2056                         prg2 += (double)prg;
2057
2058                         checking_window.progress = prg2;
2059                         group_count++;
2060                     }
2061
2062                     statusBarPanel1.Text = old_status_text;
2063                     mainList.Invalidate();
2064
2065                     SetStatusBarData(false);
2066
2067                     EnableArrows(false);
2068                 }
2069
2070             }
2071             long_process_listener.Complete = true;
2072         }
2073
2074         CheckAllByExtension check_by_extension;
2075
2076         private void toolStripButton18_Click(object sender, EventArgs e)
2077         {
2078             if (GlobalBuffers.working)
2079                 return;
2080             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
2081                 return;
2082
2083             check_by_extension = new CheckAllByExtension();
2084             check_by_extension.Owner = this;
2085             check_by_extension.ShowDialog();
2086
2087             ThreadStart ts = new ThreadStart(CheckByExtension);
2088             Thread t = new Thread(ts);
2089
2090             checking_window = new Checking();
2091             long_process_listener = new LongProcessListener(checking_window, this);
2092
2093             t.Start();
2094         }
2095
2096         private void CheckByExtension()
2097         {
2098             int i, j, k, l;
2099             bool check_item = false;
2100             string extension;
2101             ArrayList check_folders = new ArrayList();
2102             double prg = (double)100 / GlobalBuffers.Duplicates.Count, prg2 = 0;
2103             string old_status_text = statusBarPanel1.Text;
2104             bool already_checked_first = false;
2105             int group_count = 0, duplicate_count = 0;
2106
2107             if (GlobalBuffers.folders_ok_clicked == true) // if the user clicked some extensions
2108             {                                                 // to check,
2109
2110                 // loop through all files in the file list
2111                 for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
2112                 {
2113                     duplicate_count = 0;
2114                     if (checking_window.cancel_clicked == true)
2115                         break;
2116                     // Has to be a file and not a group descriptor
2117                     for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
2118                     {
2119                         // get the extension of the current item
2120                         extension = Path.GetExtension(GlobalBuffers.Duplicates[i][j].Filename);
2121
2122                         // loop through the extensions that the user wanted to check
2123                         for (k = 0; k < GlobalBuffers.CheckByExtensionData.ExtensionsToCheck.Count; k++)
2124                         {
2125                             if (checking_window.cancel_clicked == true)
2126                                 break;
2127
2128                             // loop through any folders the user limited the file check by
2129                             for (l = 0; l < GlobalBuffers.CheckByExtensionData.FolderExclusions.Count; l++)
2130                             {
2131                                 if (checking_window.cancel_clicked == true)
2132                                     break;
2133
2134                                 // if the current item equals one of the checked folders to limit to,
2135                                 if (Path.GetDirectoryName(GlobalBuffers.Duplicates[i][j].Filename) == (string)GlobalBuffers.CheckByExtensionData.FolderExclusions[l])
2136                                 {
2137                                     check_item = true; // set the check item flag
2138                                     break;
2139                                 }
2140                             }
2141
2142                             // if we have an item to check, and the user limited the file check to specific folders,
2143                             // and the extension of the current item equals the current checked extension
2144                             // OR
2145                             // the user didn't limit the check by specfic folders and the extension of the current file
2146                             // matches the current checked extension
2147                             if (check_item == true && GlobalBuffers.CheckByExtensionData.ExcludeToCertainFolders == true && extension == (string)GlobalBuffers.CheckByExtensionData.ExtensionsToCheck[k] || GlobalBuffers.CheckByExtensionData.ExcludeToCertainFolders == false && extension.ToLower() == ((string)GlobalBuffers.CheckByExtensionData.ExtensionsToCheck[k]).ToLower())
2148                             {
2149                                 if (GlobalBuffers.CheckByExtensionData.CheckOnlyOne == true && already_checked_first == false || GlobalBuffers.CheckByExtensionData.CheckOnlyOne == false)
2150                                 {
2151                                     if(GlobalBuffers.CheckByExtensionData.CheckType == CheckJobDialogData.CheckTypes.Check)
2152                                         GlobalBuffers.Duplicates[i][j].Checked = true;
2153                                     else
2154                                         GlobalBuffers.Duplicates[i][j].Checked = false;
2155
2156                                     already_checked_first = true;
2157
2158                                     check_item = false;
2159
2160                                     continue;
2161                                 }
2162                             }
2163                             else
2164                             {
2165                                 if (GlobalBuffers.CheckByExtensionData.PersistentCheck != true)
2166                                     GlobalBuffers.Duplicates[i][j].Checked = false;
2167
2168                                 check_item = false;
2169
2170                                 continue;
2171                             }
2172
2173                             check_item = false;
2174
2175                         }
2176
2177                         checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
2178                         duplicate_count++;
2179
2180                     }
2181
2182                     already_checked_first = false;
2183
2184                     prg2 += (double)prg;
2185
2186                     checking_window.progress = prg2;
2187                     group_count++;
2188                 }
2189
2190                 statusBarPanel1.Text = old_status_text;
2191
2192                 mainList.Invalidate();
2193
2194                 SetStatusBarData(false);
2195
2196                 EnableArrows(false);
2197
2198             }
2199
2200             long_process_listener.Complete = true;
2201
2202         }
2203
2204         private void toolStripButton19_Click(object sender, EventArgs e)
2205         {
2206             if (GlobalBuffers.working)
2207                 return;
2208             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
2209                 return;
2210
2211             CheckByFileSize cs1 = new CheckByFileSize();
2212
2213             cs1.Owner = this;
2214             cs1.ShowDialog();
2215
2216             ThreadStart ts = new ThreadStart(CheckByFileSize);
2217             Thread t = new Thread(ts);
2218
2219             checking_window = new Checking();
2220             long_process_listener = new LongProcessListener(checking_window, this);
2221
2222             t.Start();
2223         }
2224
2225         private void toolStripButton20_Click(object sender, EventArgs e)
2226         {
2227             if (GlobalBuffers.working)
2228                 return;
2229
2230             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
2231                 return;
2232
2233             if (GlobalBuffers.mainList.SelectedItem.Group == -1 && GlobalBuffers.mainList.SelectedItem.Duplicate == -1)
2234                 return;
2235
2236             ThreadStart ts = new ThreadStart(CheckAllOfSelectedGroup);
2237             Thread t = new Thread(ts);
2238
2239             checking_window = new Checking();
2240             long_process_listener = new LongProcessListener(checking_window, this);
2241
2242             t.Start();
2243         }
2244
2245         private void CheckAllOfSelectedGroup()
2246         {
2247             int i, old_selected;
2248             double prg, prg2 = (double)0.0;
2249
2250             old_selected = GlobalBuffers.mainList.SelectedItem.Duplicate;
2251
2252             GlobalBuffers.mainList.SelectedItem.Duplicate = -1;
2253             DuplicateObject selected_group = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Duplicate);
2254
2255             prg = (double)100 / selected_group.DuplicateGroup.Count;
2256
2257             for (i = 0; i < selected_group.DuplicateGroup.Count; i++)
2258             {
2259                 if (checking_window.cancel_clicked == true)
2260                     break;
2261
2262                 selected_group.DuplicateGroup[i].Checked = true;
2263
2264                 prg2 += (double)prg;
2265                 checking_window.progress = prg2;
2266             }
2267
2268             GlobalBuffers.mainList.SelectedItem.Duplicate = old_selected;
2269
2270             mainList.Invalidate();
2271
2272             this.Invoke((MethodInvoker)delegate
2273             {
2274                 SetStatusBarData(false);
2275
2276                 EnableArrows(false);
2277             });
2278
2279             long_process_listener.Complete = true;
2280         }
2281
2282         private void usersManualToolStripMenuItem_Click(object sender, EventArgs e)
2283         {
2284             Process p1 = new Process();
2285
2286             p1.StartInfo = new ProcessStartInfo { FileName = "dcum.chm", UseShellExecute = true };
2287             p1.Start();
2288         }
2289
2290         private void toolStripButton10_Click_2(object sender, EventArgs e)
2291         {
2292             if (GlobalBuffers.working)
2293                 return;
2294             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
2295                 return;
2296
2297             ThreadStart ts = new ThreadStart(InvertChecked);
2298             Thread t = new Thread(ts);
2299             checking_window = new Checking();
2300             long_process_listener = new LongProcessListener(checking_window, this);
2301
2302             t.Start();
2303         }
2304
2305         private void InvertChecked()
2306         {
2307             int i, j;
2308             double prg = (double)100 / GlobalBuffers.Duplicates.Count;
2309             double prg2 = (double)0.0;
2310
2311             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
2312             {
2313                 if (checking_window.cancel_clicked == true)
2314                     break;
2315
2316                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
2317                 {
2318                     if (checking_window.cancel_clicked == true)
2319                         break;
2320
2321                     if (GlobalBuffers.Duplicates[i][j].Checked == true)
2322                         GlobalBuffers.Duplicates[i][j].Checked = false;
2323                     else
2324                         GlobalBuffers.Duplicates[i][j].Checked = true;
2325                 }
2326
2327                 prg2 += (double)prg;
2328                 checking_window.progress = prg2;
2329             }
2330
2331             GlobalBuffers.mainList.Invalidate();
2332
2333             if (filelist_mode == false)
2334             {
2335                 this.Invoke((MethodInvoker)delegate
2336                 {
2337                     statusBarPanel1.Text = GlobalBuffers.DuplicateCountStatusText;
2338                     statusBarPanel2.Text = GlobalBuffers.SetCountStatusText;
2339                     statusBarPanel3.Text = GlobalBuffers.WastedSpaceStatusText;
2340                     statusBarPanel4.Text = GlobalBuffers.duration;
2341                 });
2342             }
2343             else
2344             {
2345                 SetStatusBarData(false);
2346             }
2347
2348             EnableArrows(false);
2349
2350             long_process_listener.Complete = true;
2351         }
2352
2353         private void toolStripMenuItem6_Click_1(object sender, EventArgs e)
2354         {
2355             DeleteFolder df1 = new DeleteFolder();
2356             DialogResult dr = DialogResult.No;
2357             int no_confirm = GlobalBuffers.SettingsManager.FindSettingStringSingleInt( "no_confirm");
2358
2359
2360             DuplicateObject selected = GlobalBuffers.mainList.GetItem(GlobalBuffers.mainList.SelectedItem.Group, GlobalBuffers.mainList.SelectedItem.Duplicate);
2361
2362             df1.Owner = this;
2363             df1.Tag = (string)selected.DuplicateFile.Filename;
2364             df1.ShowDialog();
2365
2366             if ((string)df1.Tag != "")
2367             {
2368                 //if (no_confirm == 0)
2369                 dr = MessageBox.Show("CAUTION! You are about to delete " + "\"" + (string)df1.Tag + "\", as well as all of its files and subfolders to the Recycle Bin. Know what you're doing before you proceed.\n\nAre you sure?", "Duplicate Commander", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
2370                 if (dr == DialogResult.Yes)
2371                 {
2372                     checking_window = new Checking();
2373                     checking_window.Text = "Deleting folder and subfolders";
2374                     checking_window.staticText = false;
2375                     checking_window.statusText.Text = "Please wait...";
2376                     long_process_listener = new LongProcessListener(checking_window, this);
2377
2378                     folder_to_delete = (string)df1.Tag;
2379
2380                     ThreadStart ts = new ThreadStart(DeleteFolderThread);
2381                     Thread t = new Thread(ts);
2382
2383                     t.Start();
2384
2385                 }
2386             }
2387         }
2388
2389         string folder_to_delete;
2390
2391         private void DeleteFolderThread()
2392         {
2393             int i, j;
2394             string folder;
2395
2396             DeleteFolder(folder_to_delete);
2397
2398             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
2399             {
2400                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
2401                 {
2402                     folder = Path.GetDirectoryName(GlobalBuffers.Duplicates[i][j].Filename);
2403
2404                     if (folder.Contains(folder_to_delete))
2405                     {
2406                         if (GlobalBuffers.Duplicates[i].RemoveAt(j, false) == DuplicateGroup.RemoveStatus.RemovedFile)
2407                         {
2408                             j--;
2409                         }
2410                         else
2411                         {
2412                             i--;
2413                             break;
2414                         }
2415                     }
2416                 }
2417             }
2418
2419
2420             GlobalBuffers.mainList.Invalidate();
2421
2422             this.Invoke((MethodInvoker)delegate
2423             {
2424                 SetStatusBarData(false);
2425
2426                 EnableArrows(false);
2427             });
2428
2429             long_process_listener.Complete = true;
2430
2431         }
2432
2433         public void DeleteFolder(string folder)
2434         {
2435             int i = 0, j = 0;
2436             string[] found_folders;
2437             string[] found_files;
2438             List<string> folders = new List<string>();
2439             List<string> files = new List<string>();
2440             ErrorClass errors = new ErrorClass(checking_window, "The files below could not be deleted.");
2441             double prg = (double)0.0;
2442             double prg2 = (double)0.0;
2443             bool return_bool = false;
2444
2445             if (Directory.Exists(folder))
2446             {
2447                 folders.Clear();
2448                 files.Clear();
2449                 folders.Add(folder);
2450
2451                 for (i = 0; i < folders.Count; i++)
2452                 {
2453                     found_folders = Directory.GetDirectories(folders[(int)i]);
2454                     found_files = Directory.GetFiles(folders[i]);
2455
2456                     for (j = 0; j < found_folders.Length; j++)
2457                     {
2458                         folders.Add(found_folders[j]);
2459                     }
2460
2461                     for (j = 0; j < found_files.Length; j++)
2462                     {
2463                         files.Add(found_files[j]);
2464                     }
2465                 }
2466
2467                 prg = (double)100 / files.Count;
2468
2469                 for (i = 0; i < files.Count; i++)
2470                 {
2471                     try
2472                     {
2473                         FileOperationAPIWrapper.MoveToRecycleBin(files[i]);
2474                     }
2475                     catch
2476                     {
2477                         errors.AddError(files[i], "The file may be read-only or in use by another process.");
2478                     }
2479                     prg2 += (double)prg;
2480                     checking_window.progress = (int)prg2;
2481                 }
2482                 if (return_bool == false)
2483                 {
2484                     if (errors.GetErrorCount() == 0)
2485                     {
2486                         for (i = folders.Count - 1; i > -1; i--)
2487                         {
2488                             try
2489                             {
2490                                 Directory.Delete(folders[i], true);
2491                             }
2492                             catch (Exception e)
2493                             {
2494                                 errors.AddError(folders[i], e.Message);
2495                             }
2496                         }
2497                     }
2498                 }
2499                 errors.ShowErrorWindow();
2500             }
2501             else
2502                 MessageBox.Show("The selected folder does not exist. It may have already been deleted.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
2503
2504         }
2505
2506         public void CheckForUpdates()
2507         {
2508
2509             Process p1 = new Process();
2510             string update_string, alphabeta, alphabetaverstring;
2511             string temp = Path.GetTempFileName();
2512
2513             try
2514             {
2515                 WebClient wc1 = new WebClient();
2516                 wc1.DownloadFile("http://www.rayburnsoft.net/updates/DC/updateinfo.txt", temp);
2517             }
2518             catch
2519             {
2520                 return;
2521             }
2522
2523             if (File.Exists(temp))
2524             {
2525                 try
2526                 {
2527                     SettingsManager tempManager = SettingsManager.Load(temp);
2528
2529                     update_string = tempManager.FindSettingStringSingle("latest");
2530                     alphabeta = tempManager.FindSettingStringSingle("alphabeta");
2531                     alphabetaverstring = tempManager.FindSettingStringSingle("alphabetaverstring");
2532
2533
2534                     if (alphabeta == "yes" && GlobalBuffers.SettingsManager.FindSettingStringSingle( "notify_alphabeta") == "1" || alphabeta == "no")
2535                     {
2536                         if (Convert.ToDouble(update_string) > Convert.ToDouble(version_string))
2537                         {
2538                             this.Invoke((MethodInvoker)delegate
2539                             {
2540                                 if (GlobalBuffers.SettingsManager.FindSettingStringSingle( "dont_notify") != update_string)
2541                                 {
2542                                     GlobalBuffers.NewVersionString = update_string + (alphabeta == "yes" ? " " + alphabetaverstring : "");
2543                                     updateButton.Visible = true;
2544                                     updateButton.ToolTipText = "New version available!";
2545                                     updateFlasher.Start();
2546                                 }
2547                             });
2548                         }
2549                     }
2550
2551                 }
2552                 catch (Exception e)
2553                 {
2554                     System.Diagnostics.EventLog.WriteEntry("Duplicate Commander", "An error occurred while checking for updates, the error returned was:\r\t" + e.Message, EventLogEntryType.FailureAudit);
2555                 }
2556             }
2557
2558         }
2559
2560         private void saveFileListToolStripMenuItem_Click(object sender, EventArgs e)
2561         {
2562             if (GlobalBuffers.working)
2563                 return;
2564             if (mainList.Visible == false || GlobalBuffers.Duplicates.Count == 0)
2565             {
2566                 MessageBox.Show("There's nothing to save!", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
2567                 return;
2568             }
2569             SaveFileDialog sfd1 = new SaveFileDialog();
2570
2571             sfd1.Title = "Specify where to save the file list...";
2572             sfd1.Filter = "Duplicate Commander list file|*.dcl";
2573
2574             sfd1.ShowDialog();
2575
2576             if (sfd1.FileName != "")
2577             {
2578                 if (Path.GetExtension(sfd1.FileName).ToLower() == ".dcl")
2579                     ExportListDCL(sfd1.FileName);
2580                 // else if (Path.GetExtension(sfd1.FileName).ToLower() == ".xml")
2581                 //     ExportListXML(sfd1.FileName);
2582             }
2583         }
2584
2585         /*private void ExportListXML(string filename)
2586         {
2587             XMLEntity list = new XMLEntity();
2588             XMLNode files = new XMLNode(XMLNode.NodeType.START_TAG, "files", "");
2589             int i, j;
2590             XMLNode group = null;
2591             XMLNode duplicate = null;
2592
2593             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
2594             {
2595                 group = new XMLNode(XMLNode.NodeType.MARKUP, "g", "");
2596                 group.Attributes.Add(new XMLAttribute("name", GlobalBuffers.Duplicates[i].GroupName));
2597
2598                 if (GlobalBuffers.Duplicates[i].State == DuplicateGroup.GroupState.TrueDuplicate)
2599                     group.Attributes.Add(new XMLAttribute("type", "true"));
2600                 else if (GlobalBuffers.Duplicates[i].State == DuplicateGroup.GroupState.FalseDuplicate)
2601                     group.Attributes.Add(new XMLAttribute("type", "false"));
2602                 else if (GlobalBuffers.Duplicates[i].State == DuplicateGroup.GroupState.Undeterminable)
2603                     group.Attributes.Add(new XMLAttribute("type", "unknown"));
2604
2605                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
2606                 {
2607                     duplicate = new XMLNode(XMLNode.NodeType.MARKUP, "d", "");
2608
2609                     duplicate.Attributes.Add(new XMLAttribute("path", GlobalBuffers.Duplicates[i][j].Filename.Replace("\"", "?")));
2610                     duplicate.Attributes.Add(new XMLAttribute("size", GlobalBuffers.Duplicates[i][j].Size.ToString()));
2611                     duplicate.Attributes.Add(new XMLAttribute("date_modified", GlobalBuffers.Duplicates[i][j].DateModified.ToString()));
2612                     duplicate.Attributes.Add(new XMLAttribute("link", GlobalBuffers.Duplicates[i][j].Link == true ? "true" : "false"));
2613
2614                     group.Children.Add(duplicate);
2615                 }
2616
2617                 files.Children.Add(group);
2618             }
2619
2620             files.Children.Add(new XMLNode(XMLNode.NodeType.END_TAG, "files", ""));
2621             list.Collection.Add(files);
2622
2623             group = new XMLNode(XMLNode.NodeType.START_TAG, "folders", "");
2624
2625             for (i = 0; i < GlobalBuffers.folders.Count; i++)
2626             {
2627                 group.Children.Add(new XMLNode(XMLNode.NodeType.ELEMENT, "folder", GlobalBuffers.folders[i]));
2628             }
2629
2630             group.Children.Add(new XMLNode(XMLNode.NodeType.END_TAG, "folders", ""));
2631
2632             list.addToCollection(group);
2633
2634             list.dumpToDisk(filename);
2635         }*/
2636
2637         private void ExportListDCL(string filename)
2638         {
2639             int i, j;
2640             string line;
2641             TextWriter output = new StreamWriter(filename);
2642
2643             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
2644             {
2645                 line = GlobalBuffers.Duplicates[i].GroupName + ".?..?..?.";
2646
2647                 if (GlobalBuffers.Duplicates[i].State == DuplicateGroup.GroupState.TrueDuplicate)
2648                     line += "Yes";
2649                 else if (GlobalBuffers.Duplicates[i].State == DuplicateGroup.GroupState.FalseDuplicate)
2650                     line += "No";
2651                 else
2652                     line += "Unknown";
2653
2654                 output.WriteLine(line);
2655
2656                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
2657                 {
2658                     line = GlobalBuffers.Duplicates[i][j].Filename + ".?." + DuplicateListView.DuplicateListView.FormatSizeString(GlobalBuffers.Duplicates[i][j].Size) + ".?." + GlobalBuffers.Duplicates[i][j].DateModified.ToShortDateString() + "   " + GlobalBuffers.Duplicates[i][j].DateModified.ToShortTimeString() + ".?.";
2659
2660                     output.WriteLine(line);
2661                 }
2662             }
2663
2664             for (i = 0; i < GlobalBuffers.folders.Count; i++)
2665             {
2666                 output.WriteLine("??.Folder?," + GlobalBuffers.folders[i]);
2667             }
2668
2669             output.Close();
2670         }
2671
2672         public void LoadPinnedList()
2673         {
2674             int i;
2675
2676             fileSystemTreeview.Nodes[fileSystemTreeview.Nodes.Count - 1].Nodes.Clear();
2677
2678             PinnedListCollection collection = PinnedListReaderWriter.ReadAll();
2679
2680             for (i = 0; i < collection.Count; i++)
2681             {
2682                 fileSystemTreeview.Nodes[fileSystemTreeview.Nodes.Count - 1].Nodes.Add(collection[i].Name, collection[i].Name, 3, 3);
2683             }
2684         }
2685
2686         private void loadFileListToolStripMenuItem_Click(object sender, EventArgs e)
2687         {
2688             if (GlobalBuffers.working)
2689                 return;
2690             OpenFileDialog ofd1 = new OpenFileDialog();
2691
2692             ofd1.Title = "Specify the location of the file list...";
2693             ofd1.Filter = "Duplicate Commander List File (*.dcl)|*.dcl";
2694
2695             ofd1.ShowDialog();
2696
2697             if (ofd1.FileName != "")
2698             {
2699                 filelist_path = ofd1.FileName;
2700
2701                 GlobalBuffers.Duplicates = new DuplicateGroupCollection();
2702
2703                 ThreadStart ts = new ThreadStart(OpenFileList);
2704                 Thread t = new Thread(ts);
2705
2706                 checking_window = new Checking();
2707                 checking_window.Text = "Loading file list";
2708                 checking_window.staticText = true;
2709                 checking_window.progressText = "Please wait...";
2710
2711                 long_process_listener = new LongProcessListener(checking_window, this);
2712
2713                 t.Start();
2714
2715
2716             }
2717         }
2718
2719         string filelist_path;
2720         private void OpenFileList()
2721         {
2722             int i, rv;
2723             GlobalBuffers.folders.Clear();
2724             GlobalBuffers.extensions.Clear();
2725
2726             //if (Path.GetExtension(filelist_path) == ".xml")
2727             //   ImportListXML(filelist_path);
2728             if (Path.GetExtension(filelist_path) == ".dcl")
2729             {
2730                 rv = ImportListDCL(filelist_path);
2731
2732                 if (rv == -1)
2733                 {
2734                     long_process_listener.Complete = true;
2735                     return;
2736                 }
2737             }
2738
2739             filelist_mode = true;
2740
2741             GlobalBuffers.duration = "";
2742
2743
2744             this.Invoke((MethodInvoker)delegate
2745             {
2746                 mainList.AssociateWithDataProvider(GlobalBuffers.Duplicates);
2747                 mainList.Visible = true;
2748
2749                 mainList.Invalidate();
2750
2751                 SetStatusBarData(false);
2752
2753                 if (recentFileList.Items.Count == 1 && recentFileList.Items[0].Enabled == false)
2754                     recentFileList.Items.RemoveAt(0);
2755
2756                 if (recentFileList.Items.Count < 5)
2757                 {
2758                     bool found = false;
2759
2760                     for (i = 0; i < recentFileList.Items.Count; i++)
2761                     {
2762                         if (recentFileList.Items[i].Text == filelist_path)
2763                         {
2764                             found = true;
2765                             break;
2766                         }
2767                     }
2768
2769                     if (found == false)
2770                     {
2771                         recentFileList.Items.RemoveAt(0);
2772
2773                         ToolStripMenuItem new_item = new ToolStripMenuItem(filelist_path);
2774                         new_item.Click += new EventHandler(RecentClick);
2775
2776                         recentFileList.Items.Insert(0, new_item);
2777                     }
2778                     else
2779                     {
2780                         ToolStripMenuItem new_item = new ToolStripMenuItem(filelist_path);
2781                         new_item.Click += new EventHandler(RecentClick);
2782
2783                         this.Invoke((MethodInvoker)delegate
2784                         {
2785                             recentFileList.Items.RemoveAt(i);
2786                             recentFileList.Items.Insert(0, new_item);
2787                         });
2788                     }
2789                 }
2790                 else
2791                 {
2792
2793                 }
2794
2795                 ExportRecentFileList();
2796                 //LoadRecentFileList();
2797
2798             });
2799
2800         }
2801
2802
2803         private void ExportRecentFileList()
2804         {
2805             int i;
2806
2807             for (i = 0; i < 5; i++)
2808             {
2809                 if (i < recentFileList.Items.Count)
2810                 {
2811                     if (recentFileList.Items[i].Text.Contains("\\"))
2812                         GlobalBuffers.SettingsManager.Add("recent" + i.ToString(), recentFileList.Items[i].Text);
2813                 }
2814                 else
2815                 {
2816                     GlobalBuffers.SettingsManager.Add("recent" + i.ToString(), "");
2817                 }
2818             }
2819
2820             GlobalBuffers.SettingsManager.Dump(GlobalBuffers.OptionsPath);
2821         }
2822
2823         private void LoadRecentFileList()
2824         {
2825             int i;
2826
2827             recentFileList.Items.Clear();
2828
2829             for (i = 0; i < 5; i++)
2830             {
2831                 string path = GlobalBuffers.SettingsManager.FindSettingStringSingle( "recent" + i.ToString());
2832
2833                 if (path != "" && path != "-1")
2834                     recentFileList.Items.Add(path).Click += new EventHandler(RecentClick);
2835             }
2836             if (recentFileList.Items.Count == 0)
2837                 recentFileList.Items.Add("No recently opened lists").Enabled = false;
2838
2839             recentFileList.Items.Add(new ToolStripSeparator());
2840             recentFileList.Items.Add("Clear list").Click += new EventHandler(clearList_Click);
2841         }
2842
2843         void RecentClick(object sender, EventArgs e)
2844         {
2845             ToolStripDropDownItem clicked_item = (ToolStripDropDownItem)sender;
2846
2847             filelist_path = clicked_item.Text;
2848
2849             if (!File.Exists(filelist_path))
2850             {
2851                 MessageBox.Show("The selected file list doesn't exist.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
2852
2853                 return;
2854             }
2855
2856             GlobalBuffers.Duplicates = new DuplicateGroupCollection();
2857
2858             ThreadStart ts = new ThreadStart(OpenFileList);
2859             Thread t = new Thread(ts);
2860
2861             checking_window = new Checking();
2862             checking_window.Text = "Loading file list";
2863             checking_window.staticText = true;
2864             checking_window.progressText = "Please wait...";
2865
2866             long_process_listener = new LongProcessListener(checking_window, this);
2867
2868             t.Start();
2869         }
2870
2871         void PinnedClick(object sender, EventArgs e)
2872         {
2873             /*ToolStripDropDownItem clicked_item = (ToolStripDropDownItem)sender;
2874
2875             filelist_path = clicked_item.Text;
2876
2877             ThreadStart ts = new ThreadStart(OpenFileList);
2878             Thread t = new Thread(ts);
2879             t.Start();*/
2880         }
2881
2882         /* private int ImportListXML(string filename)
2883          {
2884              if (!File.Exists(filename))
2885                  return -1;
2886              int i, j;
2887              XMLEntity xml = XMLEntity.loadFromFile(filename);
2888              XMLNode group;
2889              DuplicateGroup new_group;
2890              DuplicateFile new_file;
2891              string group_type;
2892
2893              GlobalBuffers.ListMode = true;
2894
2895              XMLNode files = xml.findByName("files");
2896
2897              double prg = (double)100 / files.Children.Count;
2898
2899              for (i = 0; i < files.Children.Count; i++)
2900              {
2901                  if (files.Children[i].Type == XMLNode.NodeType.MARKUP)
2902                  {
2903                      group = files.Children[i];
2904
2905                      new_group = new DuplicateGroup();
2906                      new_group.GroupName = group.findAttribute("name");
2907
2908                      group_type = group.findAttribute("type");
2909
2910                      if (group_type == "true")
2911                          new_group.State = DuplicateGroup.GroupState.TrueDuplicate;
2912                      else if (group_type == "false")
2913                          new_group.State = DuplicateGroup.GroupState.FalseDuplicate;
2914                      else
2915                          new_group.State = DuplicateGroup.GroupState.Undeterminable;
2916
2917                      for (j = 0; j < group.Children.Count; j++)
2918                      {
2919                          new_file = new DuplicateFile(group.Children[j].findAttribute("path").Replace("?", "\""), Convert.ToInt64(group.Children[j].findAttribute("size")), DateTime.Parse(group.Children[j].findAttribute("date_modified")));
2920
2921                          if (group.Children[j].findAttribute("link") == "true")
2922                              new_file.Link = true;
2923                          else
2924                              new_file.Link = false;
2925
2926                          new_group.Add(new_file);
2927                      }
2928
2929                      GlobalBuffers.Duplicates.Add(new_group);
2930                  }
2931
2932                  checking_window.progress = (double)i * prg;
2933              }
2934
2935              XMLNode folders = xml.findByName("folders");
2936
2937              for (i = 0; i < folders.Children.Count; i++)
2938              {
2939                  if (folders.Children[i].Type == XMLNode.NodeType.ELEMENT)
2940                      GlobalBuffers.folders.Add(folders.Children[i].Value);
2941              }
2942
2943              GlobalBuffers.mainList.Invalidate();
2944
2945              long_process_listener.Complete = true;
2946
2947              return 0;
2948          }*/
2949
2950         private int ImportListDCL(string filename)
2951         {
2952             //  try
2953             // {
2954             DuplicateGroup new_group = null;
2955             DuplicateFile new_file = null;
2956             string[] list;
2957             int i, j;
2958             double prg;
2959             int delimiter_index = 0, delimiter_count = 0, old_delimiter_index = 0;
2960             bool list_mode = false;
2961
2962
2963
2964             list = File.ReadAllLines(filename);
2965
2966             prg = (double)100 / (list.Length - 1);
2967
2968             for (i = 0; i < list.Length; i++)
2969             {
2970                 if (i == 1140)
2971                 {
2972                     int zx = 0;
2973                     zx = 122;
2974                 }
2975                 if (list[i].Contains(".?..?..?."))
2976                 {
2977                     if (new_group != null)
2978                         GlobalBuffers.Duplicates.Add(new_group);
2979
2980                     new_group = new DuplicateGroup();
2981
2982                     new_group.GroupName = list[i].Substring(0, list[i].IndexOf(".?."));
2983                 }
2984                 else if (list[i].Contains("??.Folder?,"))
2985                 {
2986                     list_mode = true;
2987
2988                     GlobalBuffers.folders.Add(list[i].Substring(11));
2989                 }
2990                 else
2991                 {
2992                     for (j = 0; j < 3; j++)
2993                     {
2994                         old_delimiter_index = delimiter_index;
2995
2996                         if (delimiter_count == 0)
2997                             delimiter_index = list[i].IndexOf(".?.");
2998                         else
2999                         {
3000                             delimiter_index = list[i].IndexOf(".?.", delimiter_index + 2);
3001                         }
3002
3003                         if (delimiter_count == 0)
3004                         {
3005                             new_file = new DuplicateFile(list[i].Substring(0, delimiter_index), 0, DateTime.Now);
3006                         }
3007                         else if (delimiter_count == 1)
3008                         {
3009                             new_file.Size = (long)DuplicateFinder.formatSizeString(list[i].Substring(old_delimiter_index + 3, delimiter_index - old_delimiter_index - 3));
3010                         }
3011                         else if (delimiter_count == 2)
3012                         {
3013                             int date_time_len = list[i].Length - 3 - (old_delimiter_index + 3);
3014                             new_file.DateModified = DateTime.Parse(list[i].Substring(old_delimiter_index + 3, date_time_len));
3015                         }
3016
3017                         delimiter_count++;
3018
3019                         if (delimiter_count == 3)
3020                         {
3021                             delimiter_count = 0;
3022                             delimiter_index = 0;
3023
3024                             new_group.Add(new_file);
3025                         }
3026                     }
3027
3028                     // if (i < list.Length - 1)
3029                     //     i++;
3030                     //  else
3031                     //     break;
3032                 }
3033
3034
3035                 // if (i < list.Length - 1)
3036                 //    i--;
3037
3038                 checking_window.progress = (double)i * prg;
3039
3040                 // checking_window.progress = prg2;
3041             }
3042
3043             GlobalBuffers.ListMode = true;
3044
3045             if (list_mode == false) // we haven't found the folders section so we probably are in a legacy list
3046             {
3047                 CacheFoldersLegacy();
3048             }
3049
3050             long_process_listener.Complete = true;
3051
3052             this.Invoke((MethodInvoker)delegate
3053             {
3054                 BackColor = Color.FromKnownColor(KnownColor.Control);
3055                 mainList.AssociateWithDataProvider(GlobalBuffers.Duplicates);
3056                 mainList.Visible = true;
3057                 mainList.Invalidate();
3058             });
3059             // }
3060             // catch
3061             // {
3062             //     MessageBox.Show(this, "The specified file is invalid.", "Duplicate Commander", MessageBoxButtons.OK, MessageBoxIcon.Error);
3063             long_process_listener.Complete = true;
3064             //     return -1;
3065             // }
3066
3067             return 0;
3068         }
3069
3070         private void CacheFoldersLegacy()
3071         {
3072             this.Invoke((MethodInvoker)delegate
3073             {
3074                 statusBarPanel1.Text = "Caching folders...";
3075             });
3076
3077             string folder;
3078             bool dont_add = false;
3079             int i, j, k;
3080             FileInfo finfo1;
3081             double div = 0;
3082             double prg, prg2 = (double)0.0;
3083
3084             prg = (double)100 / GlobalBuffers.Duplicates.Count;
3085
3086             for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
3087             {
3088                 for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
3089                 {
3090                     finfo1 = new System.IO.FileInfo(GlobalBuffers.Duplicates[i][j].Filename);
3091                     folder = finfo1.DirectoryName;
3092
3093                     for (k = 0; k < GlobalBuffers.folders.Count; k++)
3094                     {
3095                         if (GlobalBuffers.folders[k] == folder)
3096                         {
3097                             dont_add = true;
3098                             continue;
3099                         }
3100                     }
3101                     if (dont_add == true)
3102                         dont_add = false;
3103                     else
3104                     {
3105                         GlobalBuffers.folders.Add(folder);
3106                     }
3107                 }
3108
3109                 prg2 += (double)prg;
3110                 div = (double)prg2 / 5;
3111
3112                 this.Invoke((MethodInvoker)delegate
3113                 {
3114                     statusBarPanel1.Text = "Caching folders (may take a minute)...(" + ((int)prg2).ToString() + "%)";
3115                 });
3116
3117             }
3118         }
3119
3120         private void checkbyString_Click(object sender, EventArgs e)
3121         {
3122             if (GlobalBuffers.working)
3123                 return;
3124             if (GlobalBuffers.Duplicates == null || GlobalBuffers.Duplicates.Count == 0)
3125                 return;
3126
3127             CheckByString cbs1 = new CheckByString();
3128
3129             cbs1.Owner = this;
3130             cbs1.ShowDialog();
3131
3132             ThreadStart ts = new ThreadStart(CheckByString);
3133             Thread t = new Thread(ts);
3134
3135             checking_window = new Checking();
3136             long_process_listener = new LongProcessListener(checking_window, this);
3137
3138             t.Start();
3139         }
3140
3141         private void CheckByString()
3142         {
3143             int i, j, k;
3144             bool check_item = false;
3145             double prg = (double)100 / GlobalBuffers.Duplicates.Count, prg2 = 0;
3146             bool already_checked_first = false;
3147             int group_count = 0, duplicate_count = 0;
3148
3149             if (GlobalBuffers.CheckByStringData.String == "")
3150                 return;
3151
3152             if (GlobalBuffers.folders_ok_clicked == true)
3153             {
3154                 for (i = 0; i < GlobalBuffers.Duplicates.Count; i++)
3155                 {
3156                     duplicate_count = 0;
3157                     if (checking_window.cancel_clicked == true)
3158                         break;
3159
3160                     for (j = 0; j < GlobalBuffers.Duplicates[i].Count; j++)
3161                     {
3162                         for (k = 0; k < GlobalBuffers.CheckByStringData.FolderExclusions.Count; k++)
3163                         {
3164                             if (checking_window.cancel_clicked == true)
3165                                 break;
3166
3167                             // see if the item matches one of the included folders we're to limit
3168                             // the check to, and if it is, break the loop and handle it
3169                             //if ((duplicateList.Items[i]).Text.Substring(0, (duplicateList.Items[i]).Text.LastIndexOf("\\") + (CountOccurrencesInString((duplicateList.Items[i]).Text, "\\") == 1 ? 1 : 0)) == (string)GlobalBuffers.CheckByStringData.FolderExclusions[k])
3170                             if (Path.GetDirectoryName(GlobalBuffers.Duplicates[i][j].Filename) == GlobalBuffers.CheckByStringData.FolderExclusions[k])
3171                             {
3172                                 check_item = true;
3173                                 break;
3174                             }
3175                         }
3176
3177                         // if the user did select to limit to specific folders, and this is one of the folders,
3178                         // see if it contains the inserted string and if it does, check the ite,
3179                         if (check_item == true && GlobalBuffers.CheckByStringData.ExcludeToCertainFolders == true || GlobalBuffers.CheckByStringData.ExcludeToCertainFolders == false)
3180                         {
3181                             // this complicated line simply checks if match case is enabled or not, along with the string check
3182                             // the only difference between the true and false portions is the presence of ToLower
3183
3184                             if (!GlobalBuffers.CheckByStringData.RegularExpression)
3185                             {
3186                                 if ((GlobalBuffers.CheckByStringData.MatchCase == true ? GlobalBuffers.Duplicates[i][j].Filename.Contains(GlobalBuffers.CheckByStringData.String) : GlobalBuffers.Duplicates[i][j].Filename.ToLower().Contains(GlobalBuffers.CheckByStringData.String.ToLower())))
3187                                 {
3188                                     if (GlobalBuffers.CheckByStringData.CheckOnlyOne == true && already_checked_first == false || GlobalBuffers.CheckByStringData.CheckOnlyOne == false)
3189                                     {
3190                                         GlobalBuffers.Duplicates[i][j].Checked = true;
3191                                         already_checked_first = true; // check one item
3192                                     }
3193                                 }
3194                                 else
3195                                 {
3196                                     // persistent check equals false
3197                                     if (GlobalBuffers.CheckByStringData.PersistentCheck == false)
3198                                         GlobalBuffers.Duplicates[i][j].Checked = false;
3199                                 }
3200                             }
3201                             else
3202                             {
3203                                 // exp_match = new Regex(GlobalBuffers.CheckByStringData.String, RegexOptions.IgnoreCase | RegexOptions.Singleline);
3204                                 //  if(exp_match.IsMatch(GlobalBuffers.CheckByStringData.String( 
3205                             }
3206                         }
3207                         else if (check_item == false && GlobalBuffers.CheckByStringData.ExcludeToCertainFolders == false)
3208                         {
3209                             if (GlobalBuffers.CheckByStringData.PersistentCheck == false)
3210                                 GlobalBuffers.Duplicates[i][j].Checked = false;
3211                         }
3212                         check_item = false;
3213                     }
3214
3215                     already_checked_first = false;
3216
3217                     prg2 += (double)prg;
3218
3219                     checking_window.progress = prg2;
3220
3221                     checking_window.progressText = "Processing duplicate " + (duplicate_count + 1).ToString() + " of group " + (group_count + 1).ToString();
3222                     duplicate_count++;
3223                 }
3224
3225                 group_count++;
3226             }
3227
3228             GlobalBuffers.mainList.Invalidate();
3229
3230             this.Invoke((MethodInvoker)delegate
3231             {
3232                 SetStatusBarData(false);
3233
3234                 EnableArrows(false);
3235             });
3236
3237             long_process_listener.Complete = true;
3238         }
3239
3240         private int CountOccurrencesInString(string in_string, string what)
3241         {
3242             int index = -2, count = 0;
3243             bool first_time = true;
3244
3245             while (index != -1)
3246             {
3247                 if (first_time == true)
3248                 {
3249                     index = -1;
3250                     first_time = false;
3251                 }
3252                 index = in_string.IndexOf(what, index + 1);
3253
3254                 if (index != -1)
3255                     count++;
3256             }
3257
3258             return count;
3259         }
3260
3261         private void timer1_Tick(object sender, EventArgs e)
3262         {
3263             EnableArrows(true);
3264         }
3265
3266
3267         public void EnableArrows(bool timer)
3268         {/*
3269             if (GlobalBuffers.mainList.Visible == false || GlobalBuffers.working == true)
3270                 return;
3271
3272             if (!in_search)
3273             {
3274                 DuplicateListView.DrawIndex currentIndex = new DuplicateListView.DrawIndex(mainList.DrawStartIndex.Group, mainList.DrawStartIndex.Duplicate, mainList.DrawStartIndex.Data);
3275                 DuplicateListView.DrawIndex.IndexReturnStatus currentIndexExistence = DuplicateListView.DrawIndex.IndexReturnStatus.Exists;
3276
3277                 while (currentIndexExistence == DuplicateListView.DrawIndex.IndexReturnStatus.Exists)
3278                 {
3279                     currentIndexExistence = currentIndex.Decrement();
3280
3281                     if (currentIndexExistence == DuplicateListView.DrawIndex.IndexReturnStatus.Exists && currentIndex.ReturnItem().Checked == true)
3282                     {
3283                         this.Invoke((MethodInvoker)delegate
3284                         {
3285                             jumpUpButton.Enabled = true;
3286                         });
3287                         break;
3288                     }
3289                     else
3290                         this.Invoke((MethodInvoker)delegate
3291                         {
3292                             jumpUpButton.Enabled = false;
3293                         });
3294                 }
3295
3296                 currentIndex = mainList.DrawStartIndex.IncrementReturn(mainList.MaximumVisibleItems());
3297
3298                 if (currentIndex != null)
3299                 {
3300                     currentIndexExistence = DuplicateListView.DrawIndex.IndexReturnStatus.Exists;
3301
3302                     while (currentIndexExistence == DuplicateListView.DrawIndex.IndexReturnStatus.Exists)
3303                     {
3304                         currentIndexExistence = currentIndex.Increment();
3305
3306                         if (currentIndexExistence == DuplicateListView.DrawIndex.IndexReturnStatus.Exists && currentIndex.ReturnItem().Checked == true)
3307                         {
3308                             this.Invoke((MethodInvoker)delegate
3309                             {
3310                                 jumpDownButton.Enabled = true;
3311                             });
3312                             break;
3313                         }
3314                         else
3315                         {
3316                             this.Invoke((MethodInvoker)delegate
3317                             {
3318                                 jumpDownButton.Enabled = false;
3319                             });
3320                         }
3321                     }
3322                 }
3323                 else
3324                 {
3325                     this.Invoke((MethodInvoker)delegate
3326                     {
3327                         jumpDownButton.Enabled = false;
3328                     });
3329                 }
3330
3331             }
3332             else
3333             {
3334                /* for (int i = 0; i < mainList.HighLightedIndexes.Count; i++)
3335                 {
3336                     if (mainList.HighLightedIndexes[i] < mainList.DrawStartIndex.ReturnItem().RollingTotal)
3337                     {
3338                         this.Invoke((MethodInvoker)delegate
3339                         {
3340                             jumpUpButton.Enabled = true;
3341                         });
3342
3343                         break;
3344                     }
3345
3346                     
3347
3348                 }
3349
3350                 for (int i = 0; i < mainList.HighLightedIndexes.Count; i++)
3351                 {
3352
3353                     if (mainList.HighLightedIndexes[i] + mainList.MaximumVisibleItems() > mainList.DrawStartIndex.IncrementReturn(mainList.MaximumVisibleItems()).ReturnItem().RollingTotal)
3354                     {
3355                         this.Invoke((MethodInvoker)delegate
3356                         {
3357                             jumpDownButton.Enabled = true;
3358                         });
3359
3360                         break;
3361                     }
3362                 }00
3363             }*/
3364         }
3365
3366         /*
3367         public void EnableArrows(bool timer)
3368         {
3369             if (GlobalBuffers.mainList.Visible == false || GlobalBuffers.working == true)
3370                 return;
3371
3372             if (!in_search)
3373             {
3374                 if (GlobalBuffers.Duplicates.CheckedItems.Count == 0)
3375                 {
3376                     jumpUpButton.Enabled = false;
3377                     jumpDownButton.Enabled = false;
3378                     return;
3379                 }
3380
3381                 if (GlobalBuffers.Duplicates.CheckedItems[0].Group < mainList.DrawStartIndex.Group && GlobalBuffers.Duplicates.CheckedItems[0].Duplicate < mainList.DrawStartIndex.Duplicate)
3382                     jumpUpButton.Enabled = true;
3383                 else
3384                     jumpUpButton.Enabled = false;
3385
3386                 if (GlobalBuffers.Duplicates.CheckedItems[GlobalBuffers.Duplicates.CheckedItems.Count - 1].Group >= mainList.DrawStartIndex.IncrementReturn(mainList.MaximumVisibleItems()).Group && GlobalBuffers.Duplicates.CheckedItems[GlobalBuffers.Duplicates.CheckedItems.Count - 1].Group >= mainList.DrawStartIndex.IncrementReturn(mainList.MaximumVisibleItems()).Duplicate)
3387                     jumpDownButton.Enabled = true;
3388                 else
3389                     jumpDownButton.Enabled = false;
3390             }
3391             else
3392             {
3393                 if (GlobalBuffers.mainList.HighLightedIndexes.Count > 0 && GlobalBuffers.mainList.HighLightedIndexes[0] < GlobalBuffers.mainList.verticalScrollbar.Value + GlobalBuffers.mainList.MaximumVisibleItems())
3394                 {
3395                     jumpUpButton.Enabled = false;
3396                     jumpDownButton.Enabled = false;
3397                     return;
3398                 }
3399
3400                 if (GlobalBuffers.mainList.HighLightedIndexes.Count > 0 && GlobalBuffers.mainList.HighLightedIndexes[0] < GlobalBuffers.mainList.verticalScrollbar.Value)
3401                     jumpUpButton.Enabled = true;
3402                 else
3403                     jumpUpButton.Enabled = false;
3404
3405                 if (GlobalBuffers.mainList.HighLightedIndexes.Count > 0 && GlobalBuffers.mainList.HighLightedIndexes[GlobalBuffers.mainList.HighLightedIndexes.Count - 1] > GlobalBuffers.mainList.verticalScrollbar.Value + GlobalBuffers.mainList.MaximumVisibleItems())
3406                     jumpDownButton.Enabled = true;
3407                 else
3408                     jumpDownButton.Enabled = false;
3409             }
3410         }*/
3411
3412
3413         /*
3414         public void EnableArrows(bool timer)
3415         {
3416             if (GlobalBuffers.mainList.Visible == false || GlobalBuffers.working == true)
3417                 return;
3418
3419             int count_per_page = GlobalBuffers.mainList.MaximumVisibleItems();
3420             DuplicateObject top_object;
3421             DuplicateListView.DrawIndex backward_index = new DuplicateListView.DrawIndex(GlobalBuffers.mainList.DrawStartIndex.Group, GlobalBuffers.mainList.DrawStartIndex.Duplicate, GlobalBuffers.mainList.DrawStartIndex.Data);
3422             DuplicateListView.DrawIndex forward_index = new DuplicateListView.DrawIndex(GlobalBuffers.mainList.DrawStartIndex.Group, GlobalBuffers.mainList.DrawStartIndex.Duplicate, GlobalBuffers.mainList.DrawStartIndex.Data);
3423             DuplicateListView.DrawIndex.IndexReturnStatus in_bounds = DuplicateListView.DrawIndex.IndexReturnStatus.Exists;
3424
3425             if (in_search == false)
3426             {
3427                 if (mainList.Visible == true)
3428                 {
3429                     in_bounds = forward_index.Increment(GlobalBuffers.mainList.MaximumVisibleItems() - 1);
3430
3431                     while (in_bounds == DuplicateListView.DrawIndex.IndexReturnStatus.Exists)
3432                     {
3433                         in_bounds = forward_index.Increment();
3434
3435
3436                         if (in_bounds == DuplicateListView.DrawIndex.IndexReturnStatus.Exists)
3437                         {
3438                             top_object = mainList.GetItem(forward_index.Group, forward_index.Duplicate);
3439
3440                             if (top_object == null)
3441                                 return;
3442
3443                             if (top_object.ObjectType == DuplicateObject.Type.File)
3444                             {
3445                                 if (top_object.DuplicateFile.Checked == true)
3446                                 {
3447                                     jumpDownButton.Enabled = true;
3448                                     ForwardIndex = forward_index;
3449                                     break;
3450                                 }
3451                                 else
3452                                 {
3453                                     jumpDownButton.Enabled = false;
3454                                 }
3455                             }
3456                             if (top_object.ObjectType == DuplicateObject.Type.Group)
3457                             {
3458                                 if (top_object.DuplicateGroup.Checked == true)
3459                                 {
3460                                     jumpDownButton.Enabled = true;
3461                                     ForwardIndex = forward_index;
3462                                     break;
3463                                 }
3464                                 else
3465                                 {
3466                                     jumpDownButton.Enabled = false;
3467                                 }
3468
3469                             }
3470                         }
3471                         else
3472                             jumpDownButton.Enabled = false;
3473                     }
3474                     if (in_bounds == DuplicateListView.DrawIndex.IndexReturnStatus.OutOfBounds)
3475                         jumpDownButton.Enabled = false;
3476
3477                     in_bounds = DuplicateListView.DrawIndex.IndexReturnStatus.Exists;
3478
3479                     while (in_bounds == DuplicateListView.DrawIndex.IndexReturnStatus.Exists)
3480                     {
3481                         in_bounds = backward_index.Decrement(1);
3482
3483