Rayburn Davis
2014-09-15 fb4519e5c864e7c153b6bafcf79275ed36a9bda3
commit | author | age
d7103d 1 ´╗┐using System;
R 2 using System.Collections;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.Drawing;
6 using System.Drawing.Drawing2D;
7 using System.Data;
8 using System.Text;
9 using System.Windows.Forms;
10
11 namespace DupliDelete.DuplicateListView
12 {
13     public partial class DuplicateListView : UserControl
14     {
15         // Variables
16
17         /// <summary>
18         /// Defines what to draw first at the top of the list.
19         /// </summary>
20         public DrawIndex DrawStartIndex=new DrawIndex();
21
22         /// <summary>
23         /// Defines the place where the text should start to be drawn
24         /// </summary>
25         public int ItemTextStartX = 25, ItemTextStartY = 21;
26
27         /// <summary>
28         /// Item height
29         /// </summary>
30         public int ItemHeight = 21;
31
32         /// <summary>
33         /// Index relative to top item that the mouse is over
34         /// </summary>
35         public int MouseOverIndex=-1;
36
37         /// <summary>
38         /// Current mouse position
39         /// </summary>
40         public new Point MousePosition;
41
42         /// <summary>
43         /// True if the user has opted to highlight the item the mouse is over
44         /// </summary>
45         public bool HighlightMouseOverItems = true;
46
47         /// <summary>
48         /// The selected index
49         /// </summary>
50         public DrawIndex SelectedItem = new DrawIndex();
51
52         /// <summary>
53         /// Color for mouse over items
54         /// </summary>
55         Color MouseOverColor = Color.FromArgb(242, 242, 242);
56         SolidBrush MouseOverBrush;
57
58         /// <summary>
59         /// The font that draws the duplicates
60         /// </summary>
61         Font GroupFont = new Font("Courier", Convert.ToSingle(8));
62
63         /// <summary>
64         /// The font that draws the duplicates
65         /// </summary>
66         Font DuplicateFont = new Font("Courier", Convert.ToSingle(8));
67
68         /// <summary>
69         /// Column collection
70         /// </summary>
71         public ColumnGroupCollection Columns = new ColumnGroupCollection();
72
73         public int OldVerticalScrollBarValue=0;
74
75         /// <summary>
76         /// Image for header
77         /// </summary>
78         Image header_image;
79
80         /// <summary>
81         /// Image for selected header
82         /// </summary>
83         Image selected_header;
84
85         /// <summary>
86         /// Image for sizing grip
87         /// </summary>
88         Image sizing_grip;
89
90         /// <summary>
91         /// Color of the shaded color
92         /// </summary>
93         Color shade_color = Color.FromArgb(247, 247, 247);
94
95         SolidBrush shade_color_brush;
96
97         /// <summary>
98         /// X where the group is written
99         /// </summary>
100         int GroupStartX = 8;
101
102         /// <summary>
103         /// Font the group is drawn in
104         /// </summary>
105         Font GroupDrawFont = new Font("Microsoft Sans Serif", 8, FontStyle.Bold);
106
107         /// <summary>
108         /// Delete button
109         /// </summary>
110         public bool DeleteButton = true;
111
112         /// <summary>
113         /// The delete button is down
114         /// </summary>
115         public bool DeleteButtonDown = false;
116
117         /// <summary>
118         /// The mouse is over the delete button
119         /// </summary>
120         public bool MouseOverDelete = false;
121
122         /// <summary>
123         /// The index of the item that the mouse is over the delete button of
124         /// </summary>
125         public int MouseOverDeleteIndex;
126
127         /// <summary>
128         /// Link button
129         /// </summary>
130         public bool LinkButton = true;
131
132         /// <summary>
133         /// The link button is down
134         /// </summary>
135         public bool LinkButtonDown = false;
136
137         /// <summary>
138         /// The mouse is over the link button
139         /// </summary>
140         public bool MouseOverLink = false;
141
142         /// <summary>
143         /// The index of the item that the mouse is over the link button of
144         /// </summary>
145         public int MouseOverLinkIndex;
146
147         public bool MouseOverCheck = false;
148
149         public int MouseOverCheckIndex;
150
151         public bool MouseOverGroupStatus = false;
152
153         public bool CheckDown = false;
154
155         public bool MouseOnFileGrip = false;
156         public bool MouseFileGripDown = false;
157
158         public bool MouseOnSizeGrip = false;
159         public bool MouseSizeGripDown = false;
160
161         public bool MouseOnDateGrip = false;
162         public bool MouseDateGripDown = false;
163
164         public bool MouseOnItemArea = false;
165
166         public int MouseDoubleClickIndex;
167
168         /// <summary>
344044 169         /// Event that occurs when the list has changed
RD 170         /// </summary>
171         /// <param name="e"></param>
172
173         public delegate void ListChangedDelegate(EventArgs e);
174
175         public event ListChangedDelegate ListChanged;
176
177         /// <summary>
d7103d 178         /// The item whose delete or link button was clicked
R 179         /// </summary>
180         public DrawIndex DeleteLinkItem;
181
182         public delegate void DeleteButtonClickedDelegate(ItemButtonClickedArgs e);
183
184         public event DeleteButtonClickedDelegate DeleteButtonClicked;
185
186         public delegate void LinkButtonClickedDelegate(ItemButtonClickedArgs e);
187
188         public event LinkButtonClickedDelegate LinkButtonClicked;
189
190         public class ItemButtonClickedArgs : EventArgs
191         {
192             /// <summary>
193             /// The index of the item whose button was clicked
194             /// </summary>
195             public int ItemIndex;
196             public int Group, Duplicate;
197
198             public ItemButtonClickedArgs(int index, int group, int duplicate)
199             {
200                 ItemIndex = index;
201                 Group = group;
202                 Duplicate = duplicate;
203             }
204         }
205
206         public event ItemDoubleClickedDelegate ItemDoubleClicked;
207
208         public delegate void ItemDoubleClickedDelegate(ItemDoubleClickedArgs e);
209
210         public class ItemDoubleClickedArgs : EventArgs
211         {
212             /// <summary>
213             /// The index of the item whose button was clicked
214             /// </summary>
215
216             DuplicateObject DuplicateObject;
217
218             public ItemDoubleClickedArgs(int index, DrawIndex draw_index)
219             {
220                 if(draw_index.InBounds() == DrawIndex.IndexReturnStatus.Exists)
221                     DuplicateObject = draw_index.ReturnDrawableItem();
222             }
223         }
224
225         public event ItemRightClickedDelegate ItemRightClicked;
226
227         public delegate void ItemRightClickedDelegate(MouseEventArgs e);
228
229         public class ItemCheckedArgs : EventArgs
230         {
231             /// <summary>
232             /// The index of the item whose button was clicked
233             /// </summary>
234
235             DuplicateObject DuplicateObject;
236
237             public ItemCheckedArgs(int index, DrawIndex draw_index)
238             {
239                 DuplicateObject = draw_index.ReturnDrawableItem();
240             }
241         }
242
243         public delegate void ItemCheckedDelegate(ItemCheckedArgs e);
244         public event ItemCheckedDelegate ItemChecked;
245
246         public bool EnsureVisibleEvent = false;
247
248         public ToolTip DuplicateGroupStatus;
249
250         public LinearGradientBrush SelectedItemBrush;
251
252         bool DataRemoved=false;
253
254         // event to notify the main form that the number of checked items has been updated
255         public delegate void CheckedItemsUpdatedDelegate(EventArgs e);
256
257         public event CheckedItemsUpdatedDelegate CheckedItemsUpdated;
258
259         // event to notify the main form that the number of highlighted items has been updated
260         public delegate void HighlightedItemsUpdatedDelegate(EventArgs e);
261
262         public event HighlightedItemsUpdatedDelegate HighlightedItemsUpdated;
263
264         Point LinePointStart = new Point(); // point where the vertical line is drawn beside the filename (only on FilenameThenPath mode)
265         Point LinePointEnd = new Point(); // point where the vertical line is drawn beside the filename (only on FilenameThenPath mode)
266
267         //
268         public DuplicateListView()
269         {
270             InitializeComponent();
271
272             MouseOverBrush = new SolidBrush(MouseOverColor);
273
274             header_image = global::DupliDelete.Properties.Resources.header;
275
276             selected_header = global::DupliDelete.Properties.Resources.selectedheader;
277
278             sizing_grip = global::DupliDelete.Properties.Resources.sizinggrip;
279
280             MouseWheel += new MouseEventHandler(DuplicateListView_MouseWheel);
281
282             Columns.Add(new Column("File", 850));
283             Columns.Add(new Column("Size", 100));
284             Columns.Add(new Column("Date Modified", 150));
285
286             DuplicateGroupStatus = new ToolTip();
287         }
288
289         void DuplicateListView_MouseWheel(object sender, MouseEventArgs e)
290         {
291             if (e.Delta == -120 && verticalScrollbar.Value < verticalScrollbar.Maximum + 4) // scroll down
292             {
293                 if (verticalScrollbar.Value + GlobalBuffers.WheelSkip < 0) // edited 6/6/12
294                     verticalScrollbar.Value = 0;
295
296                 else if (verticalScrollbar.Value + GlobalBuffers.WheelSkip > verticalScrollbar.Maximum)
297                     verticalScrollbar.Value = verticalScrollbar.Maximum;
298                 else
299                     verticalScrollbar.Value += GlobalBuffers.WheelSkip;
300
301                 
302             }
303             if (e.Delta == 120 && verticalScrollbar.Value > 0) // scroll up
304             {
305                 if (verticalScrollbar.Value - GlobalBuffers.WheelSkip < 0) // edited 6/6/12
306                     verticalScrollbar.Value = 0;
307
308                 else if (verticalScrollbar.Value - GlobalBuffers.WheelSkip > verticalScrollbar.Maximum)
309                     verticalScrollbar.Value = verticalScrollbar.Maximum;
310                 else
311                     verticalScrollbar.Value -= GlobalBuffers.WheelSkip;
312             }
313         }
314
315         private void DuplicateListView_Load(object sender, EventArgs e)
316         {
317             DrawStartIndex = new DrawIndex(0, -1, GlobalBuffers.Duplicates);
318
319             HighLightedIndexes = new HighlightedIndexCollection(this);
320         }
321
322         public void AssociateWithDataProvider(DuplicateGroupCollection data)
323         {
324             DrawStartIndex = new DrawIndex(0, -1, data);
325             verticalScrollbar.Maximum = data.GroupDuplicateTotal;
326             verticalScrollbar.Value = 0;
327
328             data.DataRemoved += new DuplicateGroupCollection.DataRemovedDelegate(data_DataRemoved);
329         }
330
344044 331         void data_DataRemoved(DuplicateGroupCollection.ItemRemovedEventArgs e)
d7103d 332         {
R 333             if (DrawStartIndex != null && DrawStartIndex.Data != null)
334             {
335                 if (DrawStartIndex.InBounds() == DrawIndex.IndexReturnStatus.OutOfBounds)
336                 {
337                     while (DrawStartIndex.InBounds() == DrawIndex.IndexReturnStatus.OutOfBounds && !(DrawStartIndex.Group == 0 && DrawStartIndex.Duplicate == -1))
338                         DrawStartIndex.Decrement();
339
340                     if (DrawStartIndex.Decrement(MaximumVisibleItems() - 1) == DrawIndex.IndexReturnStatus.OutOfBounds)
341                     {
342                         DrawStartIndex.Group = 0;
343                         DrawStartIndex.Duplicate = -1;
344                     }
345                 }
346
347             }
348
349             if (SelectedItem != null && SelectedItem.Data != null)
350             {
351                 if (SelectedItem.InBounds() == DrawIndex.IndexReturnStatus.OutOfBounds)
352                 {
353                     while (SelectedItem.InBounds() == DrawIndex.IndexReturnStatus.OutOfBounds && !(SelectedItem.Group == 0 && SelectedItem.Duplicate == -1))
354                         SelectedItem.Decrement();
355                 }
356
357               //  Invalidate();
358             }
359
344044 360             HighLightedIndexes.RemoveAt(e.RollingTotal);
RD 361
d7103d 362             DataRemoved = true;
344044 363
RD 364             if (ListChanged != null)
365                 ListChanged(new EventArgs());
d7103d 366
R 367         }
368
369         public DuplicateObject GetItem(int group, int duplicate)
370         {
371             DrawIndex item_index = new DrawIndex(group, duplicate, DrawStartIndex.Data);
372
373             if (item_index.InBounds() == DrawIndex.IndexReturnStatus.Exists)
374                 return item_index.ReturnDrawableItem();
375             else
376                 return null;
377         }
378
379         public DuplicateObject GetGroupOfItem(DrawIndex item)
380         {
381             return GetItem(item.Group, -1);
382         }
383
384         public bool IsDataIndexVisible(DrawIndex index)
385         {
386             DrawIndex draw_item = new DrawIndex(DrawStartIndex.Group, DrawStartIndex.Duplicate, DrawStartIndex.Data);
387             int i;
388
389             for (i = 0; i < MaximumVisibleItems(); i++)
390             {
391                 if (draw_item.Group == index.Group && draw_item.Duplicate == index.Duplicate)
392                     return true;
393                 else
394                 {
395                     if (draw_item.Increment() == DrawIndex.IndexReturnStatus.OutOfBounds)
396                         return false;
397                 }
398             }
399
400             return false;
401         }
402
344044 403         public enum RedrawParam
RD 404         {
405             All, Columns, Items, Item
406         }
407
408         RedrawParam DrawParam = RedrawParam.All;
409
410         DrawIndex paint_start = new DrawIndex();
411
d7103d 412         private void DuplicateListView_Paint(object sender, PaintEventArgs e)
R 413         {
414             int i;
415             DuplicateObject draw_object;
416
417
418
419             int start_x = ItemTextStartX - horizontalScrollbar.Value, start_y = ItemTextStartY;
344044 420             paint_start.Group = DrawStartIndex.Group;
RD 421             paint_start.Duplicate = DrawStartIndex.Duplicate;
422             paint_start.Data = DrawStartIndex.Data;
d7103d 423             int mouse_item = PointToItem(MousePosition);
R 424             Region clipping_region;
425             int column_draw_start = 0 - horizontalScrollbar.Value;
426             int group_start_x = GroupStartX - horizontalScrollbar.Value;
427             int item_start_x = 55 - horizontalScrollbar.Value;
428
429             e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
430             e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
431            
432             // paint columns here
433
434             // draw the columns
435
344044 436            // if (DrawParam == RedrawParam.All || DrawParam == RedrawParam.Columns)
RD 437           //  {
438                 for (i = 0; i < Columns.Count; i++)
439                 {
440                     // exclude everything but the column region
441                     clipping_region = new Region(new Rectangle(column_draw_start, 0, Columns[i].Width, 21));
442                     e.Graphics.Clip = clipping_region;
d7103d 443
344044 444                     // draw the column
RD 445                     // if (i != MouseOverColumn)
d7103d 446                     e.Graphics.DrawImage(header_image, column_draw_start, 0, Columns[i].Width, 21);
344044 447                     // else
RD 448                     //     e.Graphics.DrawImage(selected_header, column_draw_start, 0, Columns[i].Width + 15, 21);
d7103d 449
344044 450                     // reset the exclusion
d7103d 451                     e.Graphics.ResetClip();
R 452
344044 453                     // draw the sizing grip
RD 454                     if (i > 0)
455                         e.Graphics.DrawImage(sizing_grip, column_draw_start - 3, 0, sizing_grip.Width, 21);
d7103d 456
344044 457                     // draw the column name
RD 458                     e.Graphics.DrawString(Columns[i].Name, DuplicateFont, Brushes.Black, Convert.ToSingle(column_draw_start + 5), Convert.ToSingle(5));
459
460                     // shade the columns
461                     if (Columns[i].Shaded == true)
462                     {
463                         e.Graphics.FillRectangle(shade_color_brush, column_draw_start, ItemTextStartY, Columns[i].Width /* - hScrollBar1.Height*/, this.Height - ItemTextStartY);
464                     }
465
466                     // set up the horizontal scrollbar
467                     if (i == Columns.Count - 1 && column_draw_start >= 0)
468                     {
469                         horizontalScrollbar.Maximum = column_draw_start;
470                     }
471
472                     // increment the position where the column starts
473                     column_draw_start += Columns[i].Width;
474
475                     if (i == Columns.Count - 1)
476                     {
477                         e.Graphics.DrawImage(sizing_grip, column_draw_start, 0, sizing_grip.Width, 21);
478                         e.Graphics.DrawImage(header_image, column_draw_start + 2, 0, this.Width - column_draw_start, 21);
479                     }
480
481                     e.Graphics.ResetClip();
482                 }
483
484                 //
485                 e.Graphics.ResetClip();
486            // }
487
488           //  if (DrawParam == RedrawParam.Items || DrawParam == RedrawParam.All)
489             {
490
491                 for (i = 0; i < MaximumVisibleItems(); i++)
492                 {
493                     if (DrawStartIndex.InBounds() == DrawIndex.IndexReturnStatus.Exists)
494                     {
495                         // paint item here
496
497                         // get the item to be drawn
498                         draw_object = paint_start.ReturnDrawableItem();
499
fb4519 500                         // Fil; the item if it's selected
344044 501                         if (ItemSelected(paint_start) == true)
RD 502                         {
503                             //SelectedItemBrush = new LinearGradientBrush(new Rectangle(0, start_y, this.Width, ItemHeight), SystemColors.Highlight, Color.DeepSkyBlue, LinearGradientMode.Vertical);
504                             e.Graphics.FillRectangle(SystemBrushes.Highlight, new Rectangle(0, start_y, this.Width, ItemHeight));
505                         }
506
507                         // lightly highlight the item if the mouse is over it
508                         else if (HighlightMouseOverItems == true && mouse_item == i)
509                         {
510                             e.Graphics.FillRectangle(MouseOverBrush, new Rectangle(0, start_y, this.Width, ItemHeight));
511                         }
512
fb4519 513                        /* else if ( draw_object.ObjectType == DuplicateObject.Type.File)
344044 514                         {
RD 515                             if (draw_object.DuplicateGroup.Highlighted == true)
516                             {
517                                 e.Graphics.FillRectangle(Brushes.LightSteelBlue, new Rectangle(0, start_y, this.Width, ItemHeight));
518                             }
519                         }
fb4519 520
RD 521                         else if(draw_object.ObjectType == DuplicateObject.Type.Group)
344044 522                         {
fb4519 523                             if(draw_object.DuplicateGroup.Highlighted)
RD 524                                  e.Graphics.FillRectangle(Brushes.LightSteelBlue, new Rectangle(0, start_y, this.Width, ItemHeight));
525                         }*/
344044 526
RD 527                         // draw the item
528                         e.Graphics.SetClip(new Rectangle(0 - horizontalScrollbar.Value, start_y, Columns[0].Width, ItemHeight));
529
530                         // draw the checkbox
531                         if (draw_object.ObjectType == DuplicateObject.Type.Group)
532                         {
533                             if (MouseOverCheck == true && MouseOverCheckIndex == i)
534                             {
535                                 int group_check_state = draw_object.DuplicateGroup.GetGroupCheckState();
536                                 if (group_check_state == 1)
537                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.CheckedHot);
538                                 else if (group_check_state == 2)
539                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedHot);
540                                 else if (group_check_state == 3)
541                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.MixedHot);
542                             }
543                             else
544                             {
545                                 int group_check_state = draw_object.DuplicateGroup.GetGroupCheckState();
546                                 if (group_check_state == 1)
547                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal);
548                                 else if (group_check_state == 2)
549                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
550                                 else if (group_check_state == 3)
551                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.MixedNormal);
552                             }
553                         }
554                         else
555                         {
556                             if (MouseOverCheck == true && MouseOverCheckIndex == i)
557                             {
558                                 if (draw_object.DuplicateFile.Checked == false)
559                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x + 13, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedHot);
560                                 else
561                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x + 13, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.CheckedHot);
562                             }
563                             else
564                             {
565                                 if (draw_object.DuplicateFile.Checked == false)
566                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x + 13, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
567                                 else
568                                     CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(group_start_x + 13, start_y + 4), System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal);
569                             }
570                         }
571
572                         // Draw the group state
573                         if (draw_object.ObjectType == DuplicateObject.Type.Group)
574                         {
575                             switch (draw_object.DuplicateGroup.State)
576                             {
577                                 case DuplicateGroup.GroupState.TrueDuplicate:
578                                     e.Graphics.DrawImage(global::DupliDelete.Properties.Resources.bytebybyte, group_start_x + 20, start_y + 2);
579                                     break;
580                                 case DuplicateGroup.GroupState.FalseDuplicate:
581                                     e.Graphics.DrawImage(global::DupliDelete.Properties.Resources.nobytebybyte, group_start_x + 20, start_y + 2);
582                                     break;
583                                 case DuplicateGroup.GroupState.Undeterminable:
584                                     e.Graphics.DrawImage(global::DupliDelete.Properties.Resources.bytebybyteunknown, group_start_x + 20, start_y + 2);
585                                     break;
586                             }
587
588                             e.Graphics.DrawString(draw_object.DuplicateGroup.GroupName, GroupDrawFont, ItemSelected(paint_start) == true ? Brushes.White : Brushes.Black, group_start_x + 38, start_y + 4);
589
590                             // draw delete button
591                             if (DeleteButton == true)
592                             {
593                                 if (mouse_item == i)
594                                 {
595                                     e.Graphics.SetClip(new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value, start_y, 75, 21));
596
597                                     if (DeleteButtonDown == false && MouseOverDelete == true)
598                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value, start_y, 75, 21), "Delete", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Hot);
599                                     else if (DeleteButtonDown == true)
600                                     {
601                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value, start_y, 75, 21), "Delete", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Pressed);
602                                     }
603                                     else if (DeleteButtonDown == false && MouseOverDelete == false)
604                                     {
605                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value, start_y, 75, 21), "Delete", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Normal);
606                                     }
607                                 }
608                             }
609
610                         }
611                         else
612                         {
613                             // draw the link icon if needed
614                             if (draw_object.DuplicateFile.Link == true)
615                                 e.Graphics.DrawImage(global::DupliDelete.Properties.Resources.hardlink, item_start_x + 11, start_y + 3);
616
617                             // draw the network icon if needed
618                             if (draw_object.DuplicateFile.Network == true)
619                             {
620                                 e.Graphics.DrawImage(global::DupliDelete.Properties.Resources.computer_icon, item_start_x - 17, start_y + 3);
621                             }
622
623                             item_start_x = 55 - horizontalScrollbar.Value;
624
625                             // draw the filename
626                             if (GlobalBuffers.DisplayStyle == GlobalBuffers.FileNameDisplayStyle.FullPath)
627                             {
628                                 e.Graphics.DrawString(draw_object.DuplicateFile.Network == false ? draw_object.DuplicateFile.Filename : draw_object.DuplicateFile.NetworkIP + ": " + draw_object.DuplicateFile.Filename, DuplicateFont, ItemSelected(paint_start) == true ? Brushes.White : Brushes.Black, item_start_x, start_y + 4);
629                             }
630                             else
631                             {
632                                 e.Graphics.DrawString(System.IO.Path.GetFileName(draw_object.DuplicateFile.Filename), DuplicateFont, ItemSelected(paint_start) == true ? Brushes.White : Brushes.Black, item_start_x, start_y + 4);
633                                 item_start_x = item_start_x + Convert.ToInt32(e.Graphics.MeasureString(System.IO.Path.GetFileName(draw_object.DuplicateFile.Filename), DuplicateFont).ToSize().Width) + 15;
634
635                                 LinePointStart.X = item_start_x;
636                                 LinePointStart.Y = start_y;
637                                 LinePointEnd.X = item_start_x + 1;
638                                 LinePointEnd.Y = start_y;
639
640                                 e.Graphics.DrawLine(Pens.Black, LinePointStart, LinePointEnd);
641
642                                 LinePointStart.X += 1;
643                                 LinePointEnd.X += 1;
644
645                                 e.Graphics.DrawLine(Pens.LightGray, LinePointStart, LinePointEnd);
646
647                                 item_start_x += 5;
648
649                                 e.Graphics.DrawString(System.IO.Path.GetDirectoryName(draw_object.DuplicateFile.Filename), DuplicateFont, ItemSelected(paint_start) == true ? Brushes.White : Brushes.Black, item_start_x, start_y + 4);
650
651                             }
652
653                             e.Graphics.ResetClip();
654
655                             e.Graphics.SetClip(new Rectangle(Columns[0].Width - horizontalScrollbar.Value, start_y, Columns[1].Width, ItemHeight));
656
657                             // draw the size
658                             e.Graphics.DrawString(FormatSizeString(draw_object.DuplicateFile.Size), DuplicateFont, ItemSelected(paint_start) == true ? Brushes.White : Brushes.Black, Columns[0].Width + 4 - horizontalScrollbar.Value, start_y + 4);
659
660                             e.Graphics.ResetClip();
661
662                             // draw the date modified
663                             e.Graphics.SetClip(new Rectangle(Columns[0].Width + Columns[1].Width - horizontalScrollbar.Value, start_y, Columns[2].Width, ItemHeight));
664
665                             e.Graphics.DrawString(FormatDate(draw_object.DuplicateFile.DateModified) + "   " + FormatTime(draw_object.DuplicateFile.DateModified), DuplicateFont, ItemSelected(paint_start) == true ? Brushes.White : Brushes.Black, Columns[0].Width + Columns[1].Width + 4 - horizontalScrollbar.Value, start_y + 4);
666
667                             e.Graphics.ResetClip();
668
669                             // draw delete button
670                             if (DeleteButton == true)
671                             {
672                                 if (mouse_item == i)
673                                 {
674                                     if (DeleteButtonDown == false && MouseOverDelete == true)
675                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value, start_y, 75, 21), "Delete", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Hot);
676                                     else if (DeleteButtonDown == true)
677                                     {
678                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value, start_y, 75, 21), "Delete", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Pressed);
679                                     }
680                                     else if (DeleteButtonDown == false && MouseOverDelete == false)
681                                     {
682                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value, start_y, 75, 21), "Delete", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Normal);
683                                     }
684                                 }
685                             }
686
687                             // draw link button
688                             if (LinkButton == true)
689                             {
690                                 if (mouse_item == i && draw_object.DuplicateFile.Parent.State == DuplicateGroup.GroupState.TrueDuplicate && draw_object.DuplicateFile.Network == false)
691                                 {
692                                     if (LinkButtonDown == false && MouseOverLink == true)
693                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 87 - horizontalScrollbar.Value, start_y, 75, 21), "Link", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Hot);
694                                     else if (LinkButtonDown == true)
695                                     {
696                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 87 - horizontalScrollbar.Value, start_y, 75, 21), "Link", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Pressed);
697                                     }
698                                     else if (LinkButtonDown == false && MouseOverLink == false)
699                                     {
700                                         ButtonRenderer.DrawButton(e.Graphics, new Rectangle(Columns[0].Width + Columns[1].Width + Columns[2].Width + 87 - horizontalScrollbar.Value, start_y, 75, 21), "Link", GroupDrawFont, false, System.Windows.Forms.VisualStyles.PushButtonState.Normal);
701                                     }
702                                 }
703                             }
704                         }
705
706
707                         //
708
709                         // if we drew the last item, break out of the loop
710                         if (paint_start.Increment() == DrawIndex.IndexReturnStatus.OutOfBounds)
711                         {
712                             break;
713                         }
714
715                         // increment draw position
716                         start_y += ItemHeight;
717
718                         e.Graphics.ResetClip();
719
720                         item_start_x = start_x;
721                     }
722                     else
723                     {
724
725                     }
d7103d 726                 }
R 727             }
728
729
730             if (DrawStartIndex.Data != null)
731             {
344044 732                 verticalScrollbar.Maximum = DrawStartIndex.Data.ComputeRollingTotal(new DrawIndex(DrawStartIndex.Data.Count, 0, DrawStartIndex.Data));
RD 733                     //verticalScrollbar.Maximum = DrawStartIndex.Data.GroupDuplicateTotal;// -(MaximumVisibleItems() - 3);
d7103d 734             }
R 735             else
736             {
737                 verticalScrollbar.Value = 0;
738             }
739
740             if (HighLightedIndexes.Count > 0)
741                 DrawLineIndexes(e);
344044 742
RD 743             DrawParam = RedrawParam.All;
d7103d 744
R 745         }
746
747         public static string FormatSizeString(long size)
748         {
749             string size_string=null;
750
751             if (size == 1)
752                 size_string = size.ToString() + " byte";
753
754             if (size != 1 && size <= 1023)
755                 size_string = size.ToString() + " bytes";
756
757             if (size >= 1024 && size < 1048576)
758             {
759                 size_string = ((double)size / 1024).ToString();
760                 size_string = size_string.Substring(0, size_string.Contains(".") == true ? size_string.IndexOf(".") + (size_string.IndexOf(".") > size_string.Length - 3 ? 2 : 3) : size_string.Length) + " KB";
761             }
762
763             if (size >= 1048576 && size < 1073741824)
764             {
765                 size_string = ((double)size / 1024 / 1024).ToString();
766                 size_string = size_string.Substring(0, size_string.Contains(".") == true ? size_string.IndexOf(".") + (size_string.IndexOf(".") > size_string.Length - 3 ? 2 : 3) : size_string.Length) + " MB";
767             }
768
769             if (size >= 1073741824 && size < 1099511627776)
770             {
771                 size_string = ((double)size / 1024 / 1024 / 1024).ToString();
772                 size_string = size_string.Substring(0, size_string.Contains(".") == true ? size_string.IndexOf(".") + (size_string.IndexOf(".") > size_string.Length - 3 ? 2 : 3) : size_string.Length) + " GB";
773             }
774
775             if (size >= 1099511627776 && size < 1125899906842624)
776             {
777                 size_string = ((double)size / 1024 / 1024 / 1024 / 1024).ToString();
778                 size_string = size_string.Substring(0, size_string.Contains(".") == true ? size_string.IndexOf(".") + (size_string.IndexOf(".") > size_string.Length - 3 ? 2 : 3) : size_string.Length) + " TB";
779             }
780
781             return size_string;
782         }
783
784         private string FormatDate(DateTime dateTime)
785         {
786             string output;
787
788             output = dateTime.ToLocalTime().Month.ToString() + "/" + dateTime.Day.ToString() + "/" + dateTime.Year.ToString();
789
790             return output;
791         }
792
793         private string FormatTime(DateTime dateTime)
794         {
795             string output;
796             string AMPM;
797
798             AMPM = (dateTime.Hour > 12 ? " PM" : " AM");
799
800             output = (dateTime.Hour == 0 ? 12 : (dateTime.Hour > 12 ? dateTime.Hour - 12 : dateTime.Hour)) + ":" + (dateTime.Minute < 10 ? "0" + dateTime.Minute.ToString() : dateTime.Minute.ToString()) + AMPM;
801
802             return output;
803         }
804
805         public bool ItemSelected(DrawIndex item)
806         {
807             if (item.Group == SelectedItem.Group && item.Duplicate == SelectedItem.Duplicate)
808                 return true;
809             else
810                 return false;
811         }
812
813         public int PointToItem(Point point)
814         {
815             int i;
816             int draw_y = ItemTextStartY;
817             DrawIndex test_index = new DrawIndex(DrawStartIndex.Group, DrawStartIndex.Duplicate, DrawStartIndex.Data);
818
819             for (i = 0; i < MaximumVisibleItems(); i++)
820             {
821                 if (point.Y >= draw_y && point.Y < draw_y + ItemHeight)
822                 {
823                     if (test_index.InBoundsIncremented(i) !=  DrawIndex.IndexReturnStatus.Exists)
824                         return -1;
825                     return i;
826                 }
827
828                 draw_y += ItemHeight;
829             }
830
831             return -1;
832         }
833
834         public int MaximumVisibleItems()
835         {
836             double output = (double)(this.Height - ItemTextStartY - horizontalScrollbar.Height) / ItemHeight;
837             return (int)output;
838         }
839
840         private void DuplicateListView_MouseMove(object sender, MouseEventArgs e)
841         {
842
843             MousePosition = e.Location;
844             int item_index = PointToItem(e.Location);
845
846
847
848             // see if the user is moving the file grip column
849
850             if (MouseFileGripDown == true && e.X >= 4 - horizontalScrollbar.Value)
851             {
852                 Columns[0].Width = e.X + horizontalScrollbar.Value;
853             }
854             else if (Columns[0].Width < 7)
855                 Columns[0].Width = 6;
856
857             // see if the user is moving the size grip column
858
859             if (MouseSizeGripDown == true && e.X >= 4 + Columns[0].Width - horizontalScrollbar.Value)
860             {
861                 Columns[1].Width = e.X + horizontalScrollbar.Value - Columns[0].Width;
862             }
863             else if(Columns[1].Width < 7)
864                 Columns[1].Width = 6;
865
866             // see if the user is moving the date grip column
867
868             if (MouseDateGripDown == true && e.X >= 4 + Columns[0].Width + Columns[1].Width)
869             {
870                 Columns[2].Width = e.X + horizontalScrollbar.Value - Columns[1].Width - Columns[0].Width;
871             }
872             else if (Columns[2].Width < 7)
873                 Columns[2].Width = 6;
874
875             // check to see if the mouse is on the grips
876
877             if (e.Y < 21 && e.X >= Columns[0].Width - 4 - horizontalScrollbar.Value && e.X <= Columns[0].Width + 4 - horizontalScrollbar.Value)
878             {
879                 MouseOnFileGrip = true;
880                 Cursor.Current = Cursors.VSplit;
881             }
882             else if (e.Y < 21 && e.X >= Columns[0].Width + Columns[1].Width - 4 - horizontalScrollbar.Value && e.X <= Columns[0].Width + Columns[1].Width + 4 - horizontalScrollbar.Value)
883             {
884                 MouseOnSizeGrip = true;
885                 Cursor.Current = Cursors.VSplit;
886             }
887             else if (e.Y < 21 && e.X >= Columns[0].Width + Columns[1].Width + Columns[2].Width - 4 - horizontalScrollbar.Value && e.X <= Columns[0].Width + Columns[1].Width + Columns[2].Width + 4 - horizontalScrollbar.Value)
888             {
889                 MouseOnDateGrip = true;
890                 Cursor.Current = Cursors.VSplit;
891             }
892             else
893             {
894                 MouseOnFileGrip = false;
895                 MouseOnSizeGrip = false;
896                 MouseOnDateGrip = false;
897                 Cursor.Current = Cursors.Default;
898             }
899             //
900
901             if (DrawStartIndex.Data.Count > 0)
902             {
903
904                 DrawIndex item_draw_index = new DrawIndex(DrawStartIndex.Group, DrawStartIndex.Duplicate, DrawStartIndex.Data);
905                 item_draw_index.Increment(item_index);
906
907                 if ((DeleteButtonDown == true && item_index != MouseOverDeleteIndex || LinkButtonDown == true && item_index != MouseOverLinkIndex))
908                 {
909                     DeleteButtonDown = false;
910                     LinkButtonDown = false;
911                 }
912
913                 else if (DeleteButtonDown == false || LinkButtonDown == false)
914                 {
915                     if (e.X - horizontalScrollbar.Value >= Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value && e.X - horizontalScrollbar.Value < Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value + 75)
916                     {
917                         MouseOverDeleteIndex = item_index;
918                         MouseOverDelete = true;
919                     }
920                     else
921                     {
922                         MouseOverDelete = false;
923                         DeleteButtonDown = false;
924                     }
925
926                     if (e.X - horizontalScrollbar.Value >= Columns[0].Width + Columns[1].Width + Columns[2].Width + 87 - horizontalScrollbar.Value && e.X - horizontalScrollbar.Value < Columns[0].Width + Columns[1].Width + Columns[2].Width + 162 - horizontalScrollbar.Value)
927                     {
928                         MouseOverLinkIndex = item_index;
929                         MouseOverLink = true;
930                     }
931                     else
932                     {
933                         MouseOverLink = false;
934                         LinkButtonDown = false;
935                     }
936                 }
937
938                 if (item_index > -1)
939                 {
940                     if (e.X >= GroupStartX - horizontalScrollbar.Value && e.X < GroupStartX - horizontalScrollbar.Value + 15 && e.Y >= 21 + (ItemHeight * item_index) && e.Y < 21 + (ItemHeight * item_index) + 16 && item_draw_index.ReturnDrawableItem().ObjectType == DuplicateObject.Type.Group)
941                     {
942                         MouseOverCheck = true;
943                         MouseOverCheckIndex = item_index;
944                     }
945                     else if (e.X >= GroupStartX + 13 - horizontalScrollbar.Value && e.X < GroupStartX + 13 - horizontalScrollbar.Value + 15 && e.Y >= 21 + (ItemHeight * item_index) && e.Y < 21 + (ItemHeight * item_index) + 16 && item_draw_index.ReturnDrawableItem().ObjectType == DuplicateObject.Type.File)
946                     {
947                         MouseOverCheck = true;
948                         MouseOverCheckIndex = item_index;
949                     }
950                     else
951                         MouseOverCheck = false;
952                 }
953                 else
954                     MouseOverCheck = false;
955
956                 if (e.X > GroupStartX + 21 && e.X < GroupStartX + 21 + 16)
957                 {
958                     if (item_draw_index.Duplicate == -1)
959                     {
960                         //DuplicateGroupStatus.SetToolTip(this, "True duplicate group based on actual data");
961
962                         if (MouseOverGroupStatus == false)
963                         {
964                             MouseOverGroupStatus = true;
965
966                             if(item_draw_index.Data[item_draw_index.Group].State == DuplicateGroup.GroupState.TrueDuplicate)
967                                 DuplicateGroupStatus.Show("Verified duplicate group based on actual data", this);
968                             else if (item_draw_index.Data[item_draw_index.Group].State == DuplicateGroup.GroupState.FalseDuplicate)
969                                 DuplicateGroupStatus.Show("Duplicate group only by filename and NOT by actual data", this);
970                             else
971                                 DuplicateGroupStatus.Show("Duplicate group by filename, but actual data status is unknown", this);
972                         }
973                     }
974                 }
975                 else
976                 {
977                     MouseOverGroupStatus = false;
978                     DuplicateGroupStatus.Hide(this);
979                 }
980             }
981
982             Invalidate();
983         }
984
985         private void DuplicateListView_MouseDown(object sender, MouseEventArgs e)
986         {
987             int item_index = PointToItem(e.Location);
988             int i;
989             DrawIndex item_draw_index = null;
990             DuplicateObject duplicate_object= null;
991
992             if (DrawStartIndex.Data.Count > 0)
993             {
344044 994                 // get the item the user
d7103d 995                 item_draw_index = new DrawIndex(DrawStartIndex.Group, DrawStartIndex.Duplicate, DrawStartIndex.Data);
R 996
997                 if(item_draw_index.Increment(item_index) == DrawIndex.IndexReturnStatus.Exists)
998                     duplicate_object = item_draw_index.ReturnDrawableItem();
999             }
1000
344044 1001             // the user clicked on the File column sizing grip
d7103d 1002             if (e.Y < 21 && e.X >= Columns[0].Width - 4 - horizontalScrollbar.Value && e.X <= Columns[0].Width + 4 - horizontalScrollbar.Value)
R 1003             {
1004                 MouseOnFileGrip = true;
1005                 MouseFileGripDown = true;
1006                 Cursor.Current = Cursors.VSplit;
1007             }
344044 1008
RD 1009             // the user clicked on the Size column sizing grip
d7103d 1010             else if (e.Y < 21 && e.X >= Columns[0].Width + Columns[1].Width - 4 - horizontalScrollbar.Value && e.X <= Columns[0].Width + Columns[1].Width + 4 - horizontalScrollbar.Value)
R 1011             {
1012                 MouseOnSizeGrip = true;
1013                 MouseSizeGripDown = true;
1014                 Cursor.Current = Cursors.VSplit;
1015             }
344044 1016
RD 1017             // the user clicked on the Date column sizing grip
d7103d 1018             else if (e.Y < 21 && e.X >= Columns[0].Width + Columns[1].Width + Columns[2].Width - 4 - horizontalScrollbar.Value && e.X <= Columns[0].Width + Columns[1].Width + Columns[2].Width + 4 - horizontalScrollbar.Value)
R 1019             {
1020                 MouseOnDateGrip = true;
1021                 MouseDateGripDown = true;
1022                 Cursor.Current = Cursors.VSplit;
1023             }
344044 1024
RD 1025             // the mouse isn't on any sizing grip
d7103d 1026             else
R 1027             {
1028                 MouseOnFileGrip = false;
1029                 MouseOnSizeGrip = false;
1030                 MouseOnDateGrip = false;
1031                 MouseFileGripDown = false;
1032                 MouseSizeGripDown = false;
1033                 MouseDateGripDown = false;
1034                 Cursor.Current = Cursors.Default;
1035             }
1036
1037             // see if the mouse is down in the item area
1038             if (e.Y <= 21)
1039                 MouseOnItemArea = false;
1040             else
1041                 MouseOnItemArea = true;
1042
1043             if(DrawStartIndex.Data.Count > 0)
1044             {
344044 1045                 // the mouse is over a checkmark of a group
RD 1046                 if (e.X >= GroupStartX - horizontalScrollbar.Value && e.X < GroupStartX - horizontalScrollbar.Value + 15 && e.Y >= 21 + (ItemHeight * item_index) && e.Y < 21 + (ItemHeight * item_index) + 16 && duplicate_object.ObjectType == DuplicateObject.Type.Group)
d7103d 1047                 {
344044 1048                     MouseOverCheck = true;
RD 1049                     MouseOverCheckIndex = item_index;
1050                     CheckDown = true;
1051
1052                     int check_state = duplicate_object.DuplicateGroup.GetGroupCheckState();
1053
1054                     if (check_state == 1 || check_state == 3)
d7103d 1055                     {
344044 1056                         for (i = 0; i < duplicate_object.DuplicateGroup.Count; i++)
RD 1057                         {
1058                             duplicate_object.DuplicateGroup[i].Checked = false;
1059
1060                             if (ItemChecked != null)
1061                                 ItemChecked(new ItemCheckedArgs(item_draw_index.Duplicate, item_draw_index));
1062                         }
1063                     }
1064                     else
1065                     {
1066                         for (i = 0; i < duplicate_object.DuplicateGroup.Count; i++)
1067                         {
1068                             duplicate_object.DuplicateGroup[i].Checked = true;
1069
1070                             if (ItemChecked != null)
1071                                 ItemChecked(new ItemCheckedArgs(item_draw_index.Duplicate, item_draw_index));
1072                         }
1073                     }
1074
1075                     DrawParam = RedrawParam.Items;
1076                     Invalidate();
1077
1078                     return;
1079                 }
1080
1081                 // the mouse is over the checkmark of an item
1082                 else if (e.X >= GroupStartX + 13 - horizontalScrollbar.Value && e.X < GroupStartX + 13 - horizontalScrollbar.Value + 15 && e.Y >= 21 + (ItemHeight * item_index) && e.Y < 21 + (ItemHeight * item_index) + 16 && duplicate_object.ObjectType == DuplicateObject.Type.File)
1083                 {
1084                     MouseOverCheck = true;
1085                     MouseOverCheckIndex = item_index;
1086                     CheckDown = true;
1087
1088                     item_draw_index.ReturnDrawableItem().DuplicateFile.Checked = !item_draw_index.ReturnDrawableItem().DuplicateFile.Checked;
1089
1090                     if (item_draw_index.ReturnDrawableItem().DuplicateFile.Checked == true)
1091                     {
d7103d 1092
R 1093                         if (ItemChecked != null)
1094                             ItemChecked(new ItemCheckedArgs(item_draw_index.Duplicate, item_draw_index));
1095                     }
344044 1096                     else
d7103d 1097                     {
R 1098
1099                         if (ItemChecked != null)
1100                             ItemChecked(new ItemCheckedArgs(item_draw_index.Duplicate, item_draw_index));
1101                     }
344044 1102
RD 1103                     DrawParam = RedrawParam.Items;
1104                     Invalidate();
1105
1106                     return;
d7103d 1107                 }
R 1108
344044 1109                 // the user clicked the delete button
RD 1110                 if (e.X - horizontalScrollbar.Value >= Columns[0].Width + Columns[1].Width + Columns[2].Width + 7 - horizontalScrollbar.Value && e.X - horizontalScrollbar.Value < Columns[0].Width + Columns[1].Width + Columns[2].Width - horizontalScrollbar.Value + 75)
1111                 {
1112                     MouseOverDeleteIndex = item_index;
d7103d 1113
344044 1114                     DeleteLinkItem = new DrawIndex(DrawStartIndex.Group, DrawStartIndex.Duplicate, DrawStartIndex.Data);
RD 1115                     DeleteLinkItem.Increment(item_index);
d7103d 1116
344044 1117                     MouseOverDelete = true;
RD 1118                     DeleteButtonDown = true;
d7103d 1119
344044 1120                     DrawParam = RedrawParam.Items;
RD 1121                     Invalidate();
1122
1123                     return;
1124                 }
1125
1126                 // the user clicked the link button
1127                 if (e.X - horizontalScrollbar.Value >= Columns[0].Width + Columns[1].Width + Columns[2].Width + 87 - horizontalScrollbar.Value && e.X - horizontalScrollbar.Value < Columns[0].Width + Columns[1].Width + Columns[2].Width + 162 - horizontalScrollbar.Value && duplicate_object.ObjectType == DuplicateObject.Type.File && duplicate_object.DuplicateFile.Parent.State == DuplicateGroup.GroupState.TrueDuplicate)
1128                 {
1129                     MouseOverLinkIndex = item_index;
1130
1131                     DeleteLinkItem = new DrawIndex(DrawStartIndex.Group, DrawStartIndex.Duplicate, DrawStartIndex.Data);
1132                     DeleteLinkItem.Increment(item_index);
1133
1134                     MouseOverLink = true;
1135                     LinkButtonDown = true;
1136
1137                     DrawParam = RedrawParam.Items;
1138                     Invalidate();
1139
1140                     return;
1141                 }
1142
1143                 if (item_index != -1)
d7103d 1144                 {
R 1145
344044 1146                     SelectedItem.Group = item_draw_index.Group;
RD 1147                     SelectedItem.Duplicate = item_draw_index.Duplicate;
1148                     SelectedItem.Data = DrawStartIndex.Data;
d7103d 1149                 }
R 1150                 else
1151                 {
344044 1152                     if(e.Y > 21)
RD 1153                     {
1154                         SelectedItem.Group = -1;
1155                         SelectedItem.Duplicate = -1;
1156                     }
d7103d 1157                 }
R 1158         }
1159
1160             Invalidate();
1161         }
1162
1163         private void DuplicateListView_MouseUp(object sender, MouseEventArgs e)
1164         {
1165             if (DeleteButtonDown == true && DeleteButtonClicked != null)
1166             {
1167                 DeleteButtonClicked(new ItemButtonClickedArgs(MouseOverDeleteIndex, DeleteLinkItem.Group, DeleteLinkItem.Duplicate));
1168             }
1169
1170             if (LinkButtonDown == true && LinkButtonClicked != null)
1171             {
1172                 LinkButtonClicked(new ItemButtonClickedArgs(MouseOverDeleteIndex, DeleteLinkItem.Group, DeleteLinkItem.Duplicate));
1173             }
1174
1175             DeleteButtonDown = false;
1176             LinkButtonDown = false;
1177             CheckDown = false;
1178
1179             MouseFileGripDown = false;
1180             MouseSizeGripDown = false;
1181             MouseDateGripDown = false;
1182
344044 1183             DrawParam = RedrawParam.Items;
d7103d 1184             Invalidate();
R 1185         }
1186
1187         private void DuplicateListView_MouseDoubleClick(object sender, MouseEventArgs e)
1188         {
1189             // don't trigger if the mouse is over the link or delete buttons
344044 1190             if (ItemDoubleClicked != null && PointToItem(new Point(e.X, e.Y)) != -1)
d7103d 1191             {
344044 1192                 if (MouseOverDelete == false && MouseOverLink == false && MouseOverCheck == false)
d7103d 1193                 {
R 1194                     int clicked_index = PointToItem(e.Location);
1195                     DrawIndex item_index = new DrawIndex(DrawStartIndex.Group, DrawStartIndex.Duplicate, DrawStartIndex.Data);
1196
1197                     item_index.Increment(clicked_index);
1198
1199                     ItemDoubleClicked(new ItemDoubleClickedArgs(clicked_index, item_index));
1200                 }
1201             }
1202         }
1203
1204         private void DuplicateListView_MouseClick(object sender, MouseEventArgs e)
1205         {
1206             if (e.Button == System.Windows.Forms.MouseButtons.Right)
1207             {
1208                 if(ItemRightClicked != null)
1209                     ItemRightClicked(e);
1210             }
1211         }
1212
1213         private void horizontalScrollbar_ValueChanged(object sender, EventArgs e)
1214         {
344044 1215             if (ListChanged != null)
RD 1216                 ListChanged(new EventArgs());
1217
1218             DrawParam = RedrawParam.All;
d7103d 1219             Invalidate();
R 1220         }
1221
1222         private void verticalScrollbar_ValueChanged(ScrollEventArgs e)
1223         {
1224             if (EnsureVisibleEvent == false)
1225             {
1226                 if (verticalScrollbar.Value == 0)
1227                 {
1228                     DrawStartIndex.Group = 0;
1229                     DrawStartIndex.Duplicate = -1;
1230                 }
1231
1232                 if (DataRemoved == true)
1233                     DataRemoved = false;
1234                 else
1235                 {
1236                     if (verticalScrollbar.Value < OldVerticalScrollBarValue)
1237                         DrawStartIndex.Decrement(OldVerticalScrollBarValue - verticalScrollbar.Value);
1238                     else
1239                         DrawStartIndex.Increment(verticalScrollbar.Value - OldVerticalScrollBarValue);
1240                 }
1241
344044 1242                 DrawParam = RedrawParam.All;
d7103d 1243                 Invalidate();
R 1244             }
1245
1246             OldVerticalScrollBarValue = verticalScrollbar.Value;
1247             EnsureVisibleEvent = false;
1248         }
1249
1250         private void DuplicateListView_Resize(object sender, EventArgs e)
1251         {
1252           //  verticalScrollbar.
1253           //  verticalScrollbar.StepIncrementer = MaximumVisibleItems();
1254         }
1255
1256         public void EnsureVisible(DrawIndex index)
1257         {
1258             EnsureVisibleEvent = true;
1259             DrawStartIndex.Group = index.Group;
1260             DrawStartIndex.Duplicate = index.Duplicate;
1261
344044 1262             this.Invoke((MethodInvoker)delegate
RD 1263             {
1264                 verticalScrollbar.Value = DrawStartIndex.Data.ComputeRollingTotal(index);
1265             });
d7103d 1266
R 1267             Invalidate();
1268         }
1269
1270         private void verticalScrollbar_ValueChanged(Object sender, ScrollEventArgs e)
1271         {
1272             if (EnsureVisibleEvent == false)
1273             {
1274                 if (verticalScrollbar.Value == 0)
1275                 {
1276                     DrawStartIndex.Group = 0;
1277                     DrawStartIndex.Duplicate = -1;
1278                 }
1279
1280                 if (DataRemoved == true)
1281                     DataRemoved = false;
1282                 else
1283                 {
1284                     if (verticalScrollbar.Value < OldVerticalScrollBarValue)
1285                         DrawStartIndex.Decrement(OldVerticalScrollBarValue - verticalScrollbar.Value);
1286                     else
1287                         DrawStartIndex.Increment(verticalScrollbar.Value - OldVerticalScrollBarValue);
1288                 }
1289
1290                 Invalidate();
1291             }
1292             else
1293             {
1294                 // verticalScrollbar.RedrawOnValueChange = false;
1295
1296             }
1297
1298             OldVerticalScrollBarValue = verticalScrollbar.Value;
1299             EnsureVisibleEvent = false;
344044 1300
RD 1301             if (ListChanged != null)
1302                 ListChanged(new EventArgs());
d7103d 1303         }
R 1304
1305
1306         public HighlightedIndexCollection HighLightedIndexes;
1307
1308         public class HighlightedIndexCollection : ArrayList
1309         {
1310             public DuplicateListView Owner;
1311
1312             bool _suspendEventNotification;
1313             public bool SuspendEventNotification
1314             {
1315                 get
1316                 {
1317                     return _suspendEventNotification;
1318                 }
1319                 set
1320                 {
1321                     _suspendEventNotification = value;
1322
1323                     if (value == false)
1324                     {
1325                         if (Owner.HighlightedItemsUpdated != null)
1326                             Owner.HighlightedItemsUpdated(new EventArgs());
1327                     }
1328                 }
1329             }
1330
1331             public int Add(int value)
1332             {
1333                 if (Owner.DrawStartIndex.Data.Count == 0)
1334                     Owner.PopoutScrollBar();
1335
1336                 int return_val = base.Add(value);
1337
1338                 if (_suspendEventNotification == false)
1339                 {
1340                     Owner.Invalidate();
1341
1342                     if (Owner.HighlightedItemsUpdated != null)
1343                         Owner.HighlightedItemsUpdated(new EventArgs());
1344                 }
1345
344044 1346                 if (Owner.ListChanged != null)
RD 1347                     Owner.ListChanged(new EventArgs());
1348
d7103d 1349                 return return_val;
R 1350             }
1351
1352             public override void Clear()
1353             {
1354                 if (Owner.DrawStartIndex.Data.Count > 0)
1355                     Owner.PopinScrollBar();
1356
1357                 base.Clear();
344044 1358
RD 1359                 if (Owner.ListChanged != null)
1360                     Owner.ListChanged(new EventArgs());
1361
d7103d 1362                 Owner.Invalidate();
R 1363             }
1364
1365             public new int this[int index]
1366             {
1367                 get
1368                 {
1369                     return (int)base[index];
1370                 }
1371                 set
1372                 {
1373                     base[index] = value;
1374                 }
1375             }
1376
1377             public new void RemoveAt(int index)
1378             {
1379                 if (Owner.DrawStartIndex.Data.Count > 0)
1380                     Owner.PopinScrollBar();
344044 1381
RD 1382                 if (Owner.ListChanged != null)
1383                     Owner.ListChanged(new EventArgs());
d7103d 1384             }
R 1385
1386             public HighlightedIndexCollection(DuplicateListView owner)
1387             {
1388                 Owner = owner;
1389             }
1390
1391
1392         }
1393
1394         public void PopoutScrollBar()
1395         {
1396            // verticalScrollbar.Location = new Point(Width - 16, 21);
1397         }
1398
1399         public void PopinScrollBar()
1400         {
1401            // verticalScrollbar.Location = new Point(Width - 32, 21);
1402         }
1403
1404         private void DrawLineIndexes(PaintEventArgs e)
1405         {
1406             int i;
1407             double position;
1408
1409             e.Graphics.SetClip(new Rectangle(this.Width - 34, 21, 17, this.Height-16));
1410
1411             e.Graphics.Clear(Color.White);
1412
1413
1414             for (i = 0; i < HighLightedIndexes.Count; i++)
1415             {
1416                 position = ConvertIndexToScrollBarPosition(HighLightedIndexes[i]);
1417                // e.Graphics.DrawLine(Pens.Blue, this.Width - 32, 25 + Convert.ToSingle(position + AdjustScrollBarLine(HighLightedIndexes[i])), this.Width-16, 25 + Convert.ToSingle(position + AdjustScrollBarLine(HighLightedIndexes[i])));
1418                // e.Graphics.DrawLine(Pens.Blue, this.Width-32, 25 + Convert.ToSingle(position + 1 + AdjustScrollBarLine(HighLightedIndexes[i])), this.Width-16, 25 + Convert.ToSingle(position + 1 + AdjustScrollBarLine(HighLightedIndexes[i])));
1419
344044 1420                 e.Graphics.DrawLine(Pens.Blue, this.Width - 32,   Convert.ToSingle(position + AdjustScrollBarLine(HighLightedIndexes[i])), this.Width - 15,  Convert.ToSingle(position + AdjustScrollBarLine(HighLightedIndexes[i])));
RD 1421                 e.Graphics.DrawLine(Pens.Blue, this.Width - 32,   Convert.ToSingle(position + 1 + AdjustScrollBarLine(HighLightedIndexes[i])), this.Width - 15,  Convert.ToSingle(position + 1 + AdjustScrollBarLine(HighLightedIndexes[i])));
d7103d 1422             }
R 1423
1424             e.Graphics.DrawLine(Pens.Gray, new Point(this.Width - 33, 21), new Point(this.Width - 33, this.Height));
1425             e.Graphics.DrawLine(Pens.LightGray, new Point(this.Width - 32, 21), new Point(this.Width - 32, this.Height));
1426
1427
1428         }
1429
1430         private double AdjustScrollBarLine(double position)
1431         {
1432             double percentage_position_half;
1433
1434             // get the percentage of the position in relation to half the number of total items
1435             percentage_position_half = position / (DrawStartIndex.Data.GroupDuplicateTotal / 2);
1436
1437             return 18 - (18 * percentage_position_half);
1438         }
1439
1440         public double ConvertIndexToScrollBarPosition(int index)
1441         {
1442             double percent_of_items = (double)100 / DrawStartIndex.Data.GroupDuplicateTotal * index;
1443             double percent_of_scrollbar = GetPercentOfScrollBar(percent_of_items);
1444
1445             return percent_of_scrollbar;
1446         }
1447
1448         public double GetPercentOfScrollBar(double percent)
1449         {
344044 1450             int height = Height - 25;
d7103d 1451             return height * ((double)percent) / ((double)100);
R 1452         }
1453
1454         private void verticalScrollbar_ValueChanged(object sender, EventArgs e)
1455         {
1456             if (EnsureVisibleEvent == false)
1457             {
1458                 if (verticalScrollbar.Value == 0)
1459                 {
1460                     DrawStartIndex.Group = 0;
1461                     DrawStartIndex.Duplicate = -1;
1462                 }
1463
1464                 if (DataRemoved == true)
1465                     DataRemoved = false;
1466                 else
1467                 {
1468                     if (verticalScrollbar.Value < OldVerticalScrollBarValue)
1469                         DrawStartIndex.Decrement(OldVerticalScrollBarValue - verticalScrollbar.Value);
1470                     else
1471                         DrawStartIndex.Increment(verticalScrollbar.Value - OldVerticalScrollBarValue);
1472                 }
1473
1474                 Invalidate();
1475             }
1476
1477             OldVerticalScrollBarValue = verticalScrollbar.Value;
1478             EnsureVisibleEvent = false;
344044 1479
RD 1480             if (ListChanged != null)
1481                 ListChanged(new EventArgs());
d7103d 1482         }
R 1483
1484         private void DuplicateListView_KeyDown(object sender, KeyEventArgs e)
1485         {
1486             if (SelectedItem.InBoundsIncremented(1) == DrawIndex.IndexReturnStatus.Exists && e.KeyCode == Keys.Down)
1487                 SelectedItem.Increment();
1488             if (SelectedItem.InBoundsDecremented(1) == DrawIndex.IndexReturnStatus.Exists && e.KeyCode == Keys.Up)
1489                 SelectedItem.Decrement();
1490
1491             if (e.KeyCode == Keys.Down && DrawStartIndex.Group + DrawStartIndex.Duplicate + (DrawStartIndex.Duplicate == -1 ? 1 : 0) + MaximumVisibleItems() > SelectedItem.Group + SelectedItem.Duplicate + (SelectedItem.Duplicate == -1 ? 1 : 0))
1492             {
1493                 EnsureVisibleEvent = true;
1494                 DrawStartIndex = new DrawIndex(SelectedItem.Group, SelectedItem.Duplicate, SelectedItem.Data);
1495                 DrawStartIndex.Decrement(MaximumVisibleItems() - 1);
344044 1496                 if (verticalScrollbar.Value < verticalScrollbar.Maximum)
RD 1497                     verticalScrollbar.Value += 1;
d7103d 1498                 EnsureVisibleEvent = false;
R 1499             }
1500             if (e.KeyCode == Keys.Up && DrawStartIndex.Group + DrawStartIndex.Duplicate + (DrawStartIndex.Duplicate == -1 ? 1 : 0) >= SelectedItem.Group + SelectedItem.Duplicate + (SelectedItem.Duplicate == -1 ? 1 : 0))
1501             {
1502                 EnsureVisibleEvent = true;
1503                 DrawStartIndex = new DrawIndex(SelectedItem.Group, SelectedItem.Duplicate, SelectedItem.Data);
344044 1504                 if(verticalScrollbar.Value > 0)
RD 1505                     verticalScrollbar.Value -= 1;
d7103d 1506                 EnsureVisibleEvent = false;
R 1507             }
1508
1509             verticalScrollbar.Invalidate();
1510             Invalidate();
1511         }
1512
1513         protected override bool IsInputKey(System.Windows.Forms.Keys keyData)
1514         {
1515             if (keyData == Keys.Down || keyData == Keys.Up)
1516                 return true;
1517
1518                 return base.IsInputKey(keyData);
1519         }
1520
1521
1522     }
1523
1524    
1525
1526 }