QuickImage – Diff between revs 7 and 8
?pathlinks?
Rev 7 | Rev 8 | |||
---|---|---|---|---|
Line 50... | Line 50... | |||
50 | private readonly SemaphoreSlim _imageListViewLock; |
50 | private readonly SemaphoreSlim _imageListViewLock; |
|
51 | private readonly ImageTool _imageTool; |
51 | private readonly ImageTool _imageTool; |
|
52 | private readonly Progress<ImageListViewItemProgress<ListViewItem>> _listViewItemProgress; |
52 | private readonly Progress<ImageListViewItemProgress<ListViewItem>> _listViewItemProgress; |
|
53 | private readonly MagicMime _magicMime; |
53 | private readonly MagicMime _magicMime; |
|
54 | private readonly MD5 _md5; |
54 | private readonly MD5 _md5; |
|
55 | private readonly LogMemorySink _memorySink; |
55 | private readonly LogMemorySink _memorySink = new LogMemorySink(); |
|
56 | private readonly QuickImageDatabase _quickImageDatabase; |
56 | private readonly QuickImageDatabase _quickImageDatabase; |
|
Line 57... | Line 57... | |||
57 | |
57 | |
|
58 | private readonly Progress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>> |
58 | private readonly Progress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>> |
|
Line 91... | Line 91... | |||
91 | public enum MenuItemsToggleOperation |
91 | public enum MenuItemsToggleOperation |
|
92 | { |
92 | { |
|
93 | NONE, |
93 | NONE, |
|
94 | ENABLE, |
94 | ENABLE, |
|
95 | DISABLE |
95 | DISABLE |
|
96 | } |
96 | } |
|
- | 97 | |
||
- | 98 | private Configuration.Configuration Configuration { get; set; } |
||
- | 99 | |
||
- | 100 | public bool MemorySinkEnabled { get; set; } = true; |
||
Line 97... | Line 101... | |||
97 | |
101 | |
|
98 | private Form1() |
102 | private Form1() |
|
99 | { |
103 | { |
|
Line 123... | Line 127... | |||
123 | _quickImageListViewProgress = |
127 | _quickImageListViewProgress = |
|
124 | new Progress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>>(); |
128 | new Progress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>>(); |
|
Line 125... | Line 129... | |||
125 | |
129 | |
|
126 | _tagAutoCompleteStringCollection = new AutoCompleteStringCollection(); |
130 | _tagAutoCompleteStringCollection = new AutoCompleteStringCollection(); |
|
127 | textBox1.AutoCompleteCustomSource = _tagAutoCompleteStringCollection; |
131 | textBox1.AutoCompleteCustomSource = _tagAutoCompleteStringCollection; |
|
128 | tagTextBox.AutoCompleteCustomSource = _tagAutoCompleteStringCollection; |
132 | tagTextBox.AutoCompleteCustomSource = _tagAutoCompleteStringCollection; |
|
- | 133 | |
||
- | 134 | _quickImageDatabase = new QuickImageDatabase(_cancellationToken); |
||
129 | |
135 | _tagManager = new TagManager(_fileMutex); |
|
Line 130... | Line 136... | |||
130 | _memorySink = new LogMemorySink(); |
136 | _imageTool = new ImageTool(); |
|
131 | |
137 | |
|
132 | Log.Logger = new LoggerConfiguration() |
138 | Log.Logger = new LoggerConfiguration() |
|
133 | .MinimumLevel.Debug() |
139 | .MinimumLevel.Debug() |
|
Line 142... | Line 148... | |||
142 | |
148 | |
|
143 | _sparkle = new SparkleUpdater("https://quickimage.grimore.org/update/appcast.xml", |
149 | _sparkle = new SparkleUpdater("https://quickimage.grimore.org/update/appcast.xml", |
|
144 | new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY=")) |
150 | new Ed25519Checker(SecurityMode.Strict, "LonrgxVjSF0GnY4hzwlRJnLkaxnDn2ikdmOifILzLJY=")) |
|
145 | { |
151 | { |
|
146 | UIFactory = new UIFactory(icon), |
152 | UIFactory = new UIFactory(icon), |
|
147 | RelaunchAfterUpdate = true, |
- | ||
148 | //SecurityProtocolType = SecurityProtocolType.Tls12, |
- | ||
149 | //ShowsUIOnMainThread = false, |
- | ||
150 | LogWriter = new LogWriter(LogWriterOutputMode.None) |
153 | RelaunchAfterUpdate = true |
|
151 | }; |
- | ||
Line 152... | Line -... | |||
152 | _sparkle.StartLoop(true, true); |
- | ||
153 | |
- | ||
154 | _quickImageDatabase = new QuickImageDatabase(_cancellationToken); |
154 | }; |
|
155 | _tagManager = new TagManager(_fileMutex); |
155 | |
|
Line 156... | Line 156... | |||
156 | _imageTool = new ImageTool(); |
156 | _sparkle.StartLoop(true, true); |
|
157 | } |
157 | } |
|
158 | |
158 | |
|
Line 159... | Line -... | |||
159 | public Form1(Mutex mutex) : this() |
- | ||
160 | { |
- | ||
161 | } |
- | ||
162 | |
159 | public Form1(Mutex mutex) : this() |
|
163 | private Configuration.Configuration Configuration { get; set; } |
160 | { |
|
164 | public bool MemorySinkEnabled { get; set; } |
- | ||
165 | |
161 | } |
|
Line 166... | Line 162... | |||
166 | private async Task SortImageListView(IComparer<ListViewItem> comparer) |
162 | |
|
167 | { |
163 | private async Task SortImageListView(IComparer<ListViewItem> comparer) |
|
168 | var taskCompletionSources = new[] |
164 | { |
|
169 | { new TaskCompletionSource<object>(), new TaskCompletionSource<object>() }; |
165 | var taskCompletionSources = new[] { new TaskCompletionSource<object>(), new TaskCompletionSource<object>() }; |
|
Line 227... | Line 223... | |||
227 | finally |
223 | finally |
|
228 | { |
224 | { |
|
229 | this.InvokeIfRequired(form => |
225 | this.InvokeIfRequired(form => |
|
230 | { |
226 | { |
|
231 | toolStripStatusLabel1.Text = "Sorting complete."; |
227 | toolStripStatusLabel1.Text = "Sorting complete."; |
|
- | 228 | |
||
232 | form.toolStripProgressBar1.MarqueeAnimationSpeed = 0; |
229 | form.toolStripProgressBar1.MarqueeAnimationSpeed = 0; |
|
233 | }); |
230 | }); |
|
- | 231 | |
||
234 | _imageListViewLock.Release(); |
232 | _imageListViewLock.Release(); |
|
235 | } |
233 | } |
|
236 | } |
234 | } |
|
Line 237... | Line 235... | |||
237 | |
235 | |
|
238 | private async Task BalanceTags(IEnumerable<ListViewItem> items) |
236 | private async Task BalanceTags(IEnumerable<ListViewItem> items) |
|
239 | { |
237 | { |
|
240 | var enumerable = items as ListViewItem[] ?? items.ToArray(); |
238 | var enumerable = items as ListViewItem[] ?? items.ToArray(); |
|
Line 241... | Line 239... | |||
241 | var count = enumerable.Length; |
239 | var count = enumerable.Length; |
|
242 | |
- | ||
243 | var bufferBlock = new BufferBlock<(string Name, ConcurrentBag<string> Tags)>(new DataflowBlockOptions |
240 | |
|
244 | { CancellationToken = _cancellationToken }); |
- | ||
245 | var broadcastBlock = new BroadcastBlock<(string Name, ConcurrentBag<string> Tags)>(x => x, |
241 | var bufferBlock = new BufferBlock<(string Name, ConcurrentBag<string> Tags)>(new DataflowBlockOptions{ CancellationToken = _cancellationToken }); |
|
246 | new DataflowBlockOptions { CancellationToken = _cancellationToken }); |
242 | var broadcastBlock = new BroadcastBlock<(string Name, ConcurrentBag<string> Tags)>(x => x, new DataflowBlockOptions { CancellationToken = _cancellationToken }); |
|
247 | var databaseActionBlock = new ActionBlock<(string Name, ConcurrentBag<string> Tags)>( |
243 | var databaseActionBlock = new ActionBlock<(string Name, ConcurrentBag<string> Tags)>( |
|
248 | async file => |
244 | async file => |
|
249 | { |
- | ||
250 | await Task.WhenAll(_quickImageDatabase.AddTagsAsync(file.Name, file.Tags, _cancellationToken), |
245 | { |
|
251 | _tagManager.AddIptcKeywords(file.Name, file.Tags, _cancellationToken)); |
246 | await Task.WhenAll(_quickImageDatabase.AddTagsAsync(file.Name, file.Tags, _cancellationToken), _tagManager.AddIptcKeywords(file.Name, file.Tags, _cancellationToken)); |
|
252 | }, new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken }); |
247 | }, new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken }); |
|
253 | var taggingActionBlock = new ActionBlock<(string Name, ConcurrentBag<string> Tags)>(file => |
248 | var taggingActionBlock = new ActionBlock<(string Name, ConcurrentBag<string> Tags)>(file => |
|
254 | { |
249 | { |
|
Line 283... | Line 278... | |||
283 | try |
278 | try |
|
284 | { |
279 | { |
|
285 | this.InvokeIfRequired(form => { form.toolStripStatusLabel1.Text = "Balancing tags..."; }); |
280 | this.InvokeIfRequired(form => { form.toolStripStatusLabel1.Text = "Balancing tags..."; }); |
|
Line 286... | Line 281... | |||
286 | |
281 | |
|
287 | var tags = new ConcurrentBag<string>(); |
282 | var tags = new ConcurrentBag<string>(); |
|
288 | foreach (var item in enumerable) |
283 | foreach (var item in enumerable) |
|
289 | await foreach (var tag in |
284 | { |
|
290 | _quickImageDatabase.GetTags(item.Name, _cancellationToken) |
285 | await foreach (var tag in _quickImageDatabase.GetTags(item.Name, _cancellationToken).WithCancellation(_cancellationToken)) |
|
291 | .WithCancellation(_cancellationToken)) |
286 | { |
|
- | 287 | tags.Add(tag); |
||
- | 288 | } |
||
Line 292... | Line 289... | |||
292 | tags.Add(tag); |
289 | } |
|
293 | |
290 | |
|
- | 291 | var tasks = new List<Task>(); |
||
294 | var tasks = new List<Task>(); |
292 | foreach (var item in enumerable) |
|
- | 293 | { |
||
Line 295... | Line 294... | |||
295 | foreach (var item in enumerable) |
294 | tasks.Add(bufferBlock.SendAsync((item.Name, Tags: tags), _cancellationToken)); |
|
Line 296... | Line 295... | |||
296 | tasks.Add(bufferBlock.SendAsync((item.Name, Tags: tags), _cancellationToken)); |
295 | } |
|
- | 296 | |
||
297 | |
297 | await Task.WhenAll(tasks); |
|
298 | await Task.WhenAll(tasks); |
298 | |
|
299 | |
299 | bufferBlock.Complete(); |
|
300 | bufferBlock.Complete(); |
300 | |
|
301 | await bufferBlock.Completion; |
301 | await bufferBlock.Completion; |
|
Line 368... | Line 368... | |||
368 | } |
368 | } |
|
369 | } |
369 | } |
|
Line 370... | Line 370... | |||
370 | |
370 | |
|
371 | if (count == 0) |
371 | if (count == 0) |
|
- | 372 | { |
||
- | 373 | if (_selectionCancellationTokenSource != null) |
||
372 | { |
374 | { |
|
- | 375 | _selectionCancellationTokenSource.Cancel(); |
||
Line 373... | Line 376... | |||
373 | if (_selectionCancellationTokenSource != null) _selectionCancellationTokenSource.Cancel(); |
376 | } |
|
374 | |
377 | |
|
375 | tagListView.BeginUpdate(); |
378 | tagListView.BeginUpdate(); |
|
376 | foreach (var item in tagListView.CheckedItems.OfType<ListViewItem>()) |
379 | foreach (var item in tagListView.CheckedItems.OfType<ListViewItem>()) |
|
Line 380... | Line 383... | |||
380 | |
383 | |
|
381 | tagListView.EndUpdate(); |
384 | tagListView.EndUpdate(); |
|
382 | return; |
385 | return; |
|
Line -... | Line 386... | |||
- | 386 | } |
||
- | 387 | |
||
383 | } |
388 | if (_selectionCancellationTokenSource != null) |
|
- | 389 | { |
||
Line 384... | Line 390... | |||
384 | |
390 | _selectionCancellationTokenSource.Cancel(); |
|
385 | if (_selectionCancellationTokenSource != null) _selectionCancellationTokenSource.Cancel(); |
391 | } |
|
386 | |
392 | |
|
387 | _selectionCancellationTokenSource = new CancellationTokenSource(); |
393 | _selectionCancellationTokenSource = new CancellationTokenSource(); |
|
Line 396... | Line 402... | |||
396 | try |
402 | try |
|
397 | { |
403 | { |
|
398 | tagListView.InvokeIfRequired(view => |
404 | tagListView.InvokeIfRequired(view => |
|
399 | { |
405 | { |
|
400 | view.BeginUpdate(); |
406 | view.BeginUpdate(); |
|
- | 407 | |
||
401 | foreach (var item in view.CheckedItems.OfType<ListViewItem>()) |
408 | foreach (var item in view.CheckedItems.OfType<ListViewItem>()) |
|
402 | { |
409 | { |
|
403 | item.Checked = false; |
410 | item.Checked = false; |
|
404 | } |
411 | } |
|
Line 410... | Line 417... | |||
410 | { |
417 | { |
|
411 | form.toolStripStatusLabel1.Text = "Selecting items..."; |
418 | form.toolStripStatusLabel1.Text = "Selecting items..."; |
|
412 | Application.Idle += IdleHandler; |
419 | Application.Idle += IdleHandler; |
|
413 | }); |
420 | }); |
|
Line 414... | Line 421... | |||
414 | |
421 | |
|
415 | var tasks = new List<Task>(); |
422 | var tasks = new ConcurrentBag<Task>(); |
|
416 | foreach (var item in enumerable) |
423 | foreach (var item in enumerable) |
|
417 | { |
424 | { |
|
418 | await foreach (var tag in _quickImageDatabase.GetTags(item.Name, _combinedSelectionCancellationToken).WithCancellation(_combinedSelectionCancellationToken)) |
425 | await foreach (var tag in _quickImageDatabase.GetTags(item.Name, _combinedSelectionCancellationToken).WithCancellation(_combinedSelectionCancellationToken)) |
|
419 | { |
426 | { |
|
Line 435... | Line 442... | |||
435 | Log.Warning(exception, "Could not select items."); |
442 | Log.Warning(exception, "Could not select items."); |
|
436 | } |
443 | } |
|
437 | }, _combinedSelectionCancellationToken); |
444 | }, _combinedSelectionCancellationToken); |
|
438 | } |
445 | } |
|
Line 439... | Line 446... | |||
439 | |
446 | |
|
440 | private async Task RelocateToAsync(IEnumerable<ListViewItem> items, string destinationDirectory, |
447 | private void RelocateTo(IEnumerable<ListViewItem> items, string destinationDirectory, |
|
441 | CancellationToken cancellationToken) |
448 | CancellationToken cancellationToken) |
|
442 | { |
449 | { |
|
Line 443... | Line 450... | |||
443 | var enumerable = items as ListViewItem[] ?? items.ToArray(); |
450 | var enumerable = items as ListViewItem[] ?? items.ToArray(); |
|
Line 537... | Line 544... | |||
537 | return; |
544 | return; |
|
538 | } |
545 | } |
|
Line 539... | Line 546... | |||
539 | |
546 | |
|
540 | try |
547 | try |
|
541 | { |
- | ||
542 | using var _1 = transformBlock.LinkTo(actionBlock, |
548 | { |
|
Line -... | Line 549... | |||
- | 549 | using var _1 = transformBlock.LinkTo(actionBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
||
543 | new DataflowLinkOptions { PropagateCompletion = true }); |
550 | |
|
544 | |
551 | var tasks = new ConcurrentBag<Task>(); |
|
545 | foreach (var item in enumerable) |
552 | foreach (var item in enumerable) |
|
- | 553 | { |
||
- | 554 | if (cancellationToken.IsCancellationRequested) |
||
- | 555 | { |
||
Line 546... | Line 556... | |||
546 | { |
556 | return; |
|
- | 557 | } |
||
547 | if (cancellationToken.IsCancellationRequested) return; |
558 | |
|
Line -... | Line 559... | |||
- | 559 | var task = transformBlock.SendAsync((Item: item, File: destinationDirectory), cancellationToken); |
||
548 | |
560 | tasks.Add(task); |
|
549 | await transformBlock.SendAsync((Item: item, File: destinationDirectory), cancellationToken); |
561 | } |
|
550 | } |
562 | |
|
551 | |
563 | await Task.WhenAll(tasks); |
|
552 | transformBlock.Complete(); |
564 | transformBlock.Complete(); |
|
553 | await actionBlock.Completion; |
565 | await actionBlock.Completion; |
|
554 | } |
566 | } |
|
555 | finally |
567 | finally |
|
556 | { |
568 | { |
|
Line 557... | Line 569... | |||
557 | _imageListViewLock.Release(); |
569 | _imageListViewLock.Release(); |
|
558 | } |
570 | } |
|
559 | }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); |
571 | }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); |
|
Line 560... | Line 572... | |||
560 | } |
572 | } |
|
561 | |
573 | |
|
562 | private async Task RemoveImagesAsync(IEnumerable<ListViewItem> items, CancellationToken cancellationToken) |
574 | private void RemoveImages(IEnumerable<ListViewItem> items, CancellationToken cancellationToken) |
|
563 | { |
575 | { |
|
Line 564... | Line 576... | |||
564 | var enumerable = items as ListViewItem[] ?? items.ToArray(); |
576 | var enumerable = items as ListViewItem[] ?? items.ToArray(); |
|
565 | |
- | ||
- | 577 | |
||
566 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
578 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
|
567 | toolStripProgressBar1.Minimum = 0; |
579 | toolStripProgressBar1.Minimum = 0; |
|
568 | toolStripProgressBar1.Maximum = enumerable.Length; |
580 | toolStripProgressBar1.Maximum = enumerable.Length; |
|
569 | toolStripProgressBar1.Value = 0; |
581 | toolStripProgressBar1.Value = 0; |
|
570 | |
582 | |
|
571 | var bufferBlock = new BufferBlock<ListViewItem>(new DataflowBlockOptions |
583 | var bufferBlock = new BufferBlock<ListViewItem>(new DataflowBlockOptions { CancellationToken = cancellationToken }); |
|
572 | { CancellationToken = cancellationToken }); |
- | ||
573 | var actionBlock = new ActionBlock<ListViewItem>(listViewItem => |
584 | |
|
Line 574... | Line 585... | |||
574 | { |
585 | var actionBlock = new ActionBlock<ListViewItem>(listViewItem => |
|
Line 575... | Line 586... | |||
575 | toolStripStatusLabel1.Text = $"Unloading image {listViewItem.Name}"; |
586 | { |
|
576 | imageListView.Items.Remove(listViewItem); |
587 | toolStripStatusLabel1.Text = $"Unloading image {listViewItem.Name}"; |
|
Line 594... | Line 605... | |||
594 | return; |
605 | return; |
|
595 | } |
606 | } |
|
Line 596... | Line 607... | |||
596 | |
607 | |
|
597 | try |
608 | try |
|
598 | { |
- | ||
599 | using var _ = bufferBlock.LinkTo(actionBlock, |
609 | { |
|
Line 600... | Line 610... | |||
600 | new DataflowLinkOptions { PropagateCompletion = true }); |
610 | using var _ = bufferBlock.LinkTo(actionBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
|
601 | |
611 | |
|
602 | foreach (var item in enumerable) |
612 | foreach (var item in enumerable) |
|
Line 603... | Line 613... | |||
603 | { |
613 | { |
|
604 | if (cancellationToken.IsCancellationRequested) return; |
614 | if (cancellationToken.IsCancellationRequested) return; |
|
605 | |
615 | |
|
- | 616 | try |
||
- | 617 | { |
||
- | 618 | if (!await _quickImageDatabase.RemoveImageAsync(item.Name, cancellationToken)) |
||
Line 606... | Line 619... | |||
606 | try |
619 | { |
|
607 | { |
620 | continue; |
|
608 | if (!await _quickImageDatabase.RemoveImageAsync(item.Name, cancellationToken)) continue; |
621 | } |
|
609 | |
622 | |
|
Line 648... | Line 661... | |||
648 | new ExecutionDataflowBlockOptions |
661 | new ExecutionDataflowBlockOptions |
|
649 | { CancellationToken = cancellationToken, TaskScheduler = _formTaskScheduler }); |
662 | { CancellationToken = cancellationToken, TaskScheduler = _formTaskScheduler }); |
|
Line 650... | Line 663... | |||
650 | |
663 | |
|
651 | var actionBlock = new ActionBlock<ListViewItem>(async item => |
664 | var actionBlock = new ActionBlock<ListViewItem>(async item => |
|
652 | { |
665 | { |
|
- | 666 | if (item == null) |
||
- | 667 | { |
||
- | 668 | return; |
||
Line 653... | Line 669... | |||
653 | if (item == null) return; |
669 | } |
|
654 | |
670 | |
|
655 | try |
671 | try |
|
656 | { |
672 | { |
|
Line 679... | Line 695... | |||
679 | toolStripProgressBar1.Style = ProgressBarStyle.Marquee; |
695 | toolStripProgressBar1.Style = ProgressBarStyle.Marquee; |
|
680 | toolStripProgressBar1.MarqueeAnimationSpeed = 30; |
696 | toolStripProgressBar1.MarqueeAnimationSpeed = 30; |
|
Line 681... | Line 697... | |||
681 | |
697 | |
|
682 | try |
698 | try |
|
683 | { |
699 | { |
|
684 | var tasks = new List<Task>(); |
700 | var tasks = new ConcurrentBag<Task>(); |
|
- | 701 | foreach (var group in enumerable) |
||
685 | foreach (var group in enumerable) |
702 | { |
|
- | 703 | foreach (var item in imageListView.Items.OfType<ListViewItem>()) |
||
686 | foreach (var item in imageListView.Items.OfType<ListViewItem>()) |
704 | { |
|
- | 705 | if (string.Equals(item.Group.Name, group, StringComparison.OrdinalIgnoreCase)) |
||
687 | if (string.Equals(item.Group.Name, group, StringComparison.OrdinalIgnoreCase)) |
706 | { |
|
- | 707 | tasks.Add(bufferBlock.SendAsync(item, cancellationToken)); |
||
- | 708 | } |
||
- | 709 | } |
||
Line 688... | Line 710... | |||
688 | tasks.Add(bufferBlock.SendAsync(item, cancellationToken)); |
710 | } |
|
Line 689... | Line 711... | |||
689 | |
711 | |
|
Line 719... | Line 741... | |||
719 | { |
741 | { |
|
720 | toolStripStatusLabel1.Text = $"File {file} already exits."; |
742 | toolStripStatusLabel1.Text = $"File {file} already exits."; |
|
721 | return; |
743 | return; |
|
722 | } |
744 | } |
|
Line -... | Line 745... | |||
- | 745 | |
||
- | 746 | if (!largeImageList.Images.ContainsKey(file)) |
||
723 | |
747 | { |
|
- | 748 | largeImageList.Images.Add(file, thumbnail); |
||
Line 724... | Line 749... | |||
724 | if (!largeImageList.Images.ContainsKey(file)) largeImageList.Images.Add(file, thumbnail); |
749 | } |
|
725 | |
750 | |
|
726 | var fileInfo = new FileInfo(file); |
751 | var fileInfo = new FileInfo(file); |
|
727 | if (!_imageListViewGroupDictionary.TryGetValue(fileInfo.DirectoryName, out var group)) |
752 | if (!_imageListViewGroupDictionary.TryGetValue(fileInfo.DirectoryName, out var group)) |
|
728 | { |
- | ||
729 | group = new ListViewGroup(fileInfo.DirectoryName, HorizontalAlignment.Left) |
753 | { |
|
730 | { Name = fileInfo.DirectoryName }; |
754 | group = new ListViewGroup(fileInfo.DirectoryName, HorizontalAlignment.Left) { Name = fileInfo.DirectoryName }; |
|
731 | _imageListViewGroupDictionary.TryAdd(fileInfo.DirectoryName, group); |
755 | _imageListViewGroupDictionary.TryAdd(fileInfo.DirectoryName, group); |
|
Line 732... | Line -... | |||
732 | imageListView.Groups.Add(group); |
- | ||
733 | } |
756 | imageListView.Groups.Add(group); |
|
734 | |
757 | } |
|
735 | var imageListViewItem = new ListViewItem(file) |
758 | |
|
Line 736... | Line 759... | |||
736 | { Name = file, ImageKey = file, Text = fileInfo.Name, Group = group }; |
759 | var imageListViewItem = new ListViewItem(file) { Name = file, ImageKey = file, Text = fileInfo.Name, Group = group }; |
|
Line 759... | Line 782... | |||
759 | catch (Exception exception) |
782 | catch (Exception exception) |
|
760 | { |
783 | { |
|
761 | Log.Warning(exception, "Could not update image list view."); |
784 | Log.Warning(exception, "Could not update image list view."); |
|
762 | } |
785 | } |
|
763 | }, |
786 | }, |
|
764 | new ExecutionDataflowBlockOptions |
- | ||
765 | { CancellationToken = cancellationToken, TaskScheduler = _formTaskScheduler }); |
787 | new ExecutionDataflowBlockOptions { CancellationToken = cancellationToken, TaskScheduler = _formTaskScheduler }); |
|
Line 766... | Line 788... | |||
766 | |
788 | |
|
767 | var fileInputBlock = new BufferBlock<string>(new ExecutionDataflowBlockOptions |
- | ||
Line 768... | Line 789... | |||
768 | { CancellationToken = cancellationToken }); |
789 | var fileInputBlock = new BufferBlock<string>(new ExecutionDataflowBlockOptions { CancellationToken = cancellationToken }); |
|
769 | |
790 | |
|
770 | var updateImageTagsTransformBlock = new TransformBlock<string, Database.QuickImage>(async file => |
791 | var updateImageTagsTransformBlock = new TransformBlock<string, Database.QuickImage>(async file => |
|
771 | { |
792 | { |
|
772 | try |
793 | try |
|
Line 773... | Line 794... | |||
773 | { |
794 | { |
|
774 | var tags = new HashSet<string>(); |
- | ||
Line 775... | Line 795... | |||
775 | |
795 | var tags = new HashSet<string>(); |
|
Line 776... | Line 796... | |||
776 | var databaseTags = await _quickImageDatabase.GetTags(file, cancellationToken) |
796 | |
|
Line 813... | Line 833... | |||
813 | var mime = await magicMime.GetMimeType(file, cancellationToken); |
833 | var mime = await magicMime.GetMimeType(file, cancellationToken); |
|
Line 814... | Line 834... | |||
814 | |
834 | |
|
815 | if (Configuration.SupportedFormats.IsSupportedImage(mime)) |
835 | if (Configuration.SupportedFormats.IsSupportedImage(mime)) |
|
816 | { |
836 | { |
|
- | 837 | var iptcTags = _tagManager.GetIptcKeywords(imageFrame); |
||
817 | var iptcTags = _tagManager.GetIptcKeywords(imageFrame); |
838 | |
|
818 | tags = iptcTags.ToArray(); |
839 | tags = iptcTags.ToArray(); |
|
Line 819... | Line 840... | |||
819 | } |
840 | } |
|
820 | |
841 | |
|
Line 857... | Line 878... | |||
857 | using var _4 = updateImageTagsTransformBlock.LinkTo(updateImageListViewActionBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
878 | using var _4 = updateImageTagsTransformBlock.LinkTo(updateImageListViewActionBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
|
858 | using var _5 = |
879 | using var _5 = |
|
859 | updateImageTagsTransformBlock.LinkTo(DataflowBlock.NullTarget<Database.QuickImage>(), image => |
880 | updateImageTagsTransformBlock.LinkTo(DataflowBlock.NullTarget<Database.QuickImage>(), image => |
|
860 | { |
881 | { |
|
861 | var r = image == null; |
882 | var r = image == null; |
|
- | 883 | |
||
862 | return r; |
884 | return r; |
|
863 | }); |
885 | }); |
|
Line 864... | Line 886... | |||
864 | |
886 | |
|
865 | using var _3 = fileInputBlock.LinkTo(createImageTransformBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
887 | using var _3 = fileInputBlock.LinkTo(createImageTransformBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
|
866 | using var _6 = createImageTransformBlock.LinkTo(updateImageListViewActionBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
888 | using var _6 = createImageTransformBlock.LinkTo(updateImageListViewActionBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
|
867 | using var _7 = |
889 | using var _7 = |
|
868 | createImageTransformBlock.LinkTo(DataflowBlock.NullTarget<Database.QuickImage>(), image => |
890 | createImageTransformBlock.LinkTo(DataflowBlock.NullTarget<Database.QuickImage>(), image => |
|
869 | { |
891 | { |
|
- | 892 | var r = image == null; |
||
870 | var r = image == null; |
893 | |
|
871 | return r; |
894 | return r; |
|
Line 872... | Line 895... | |||
872 | }); |
895 | }); |
|
873 | |
896 | |
|
Line 884... | Line 907... | |||
884 | try |
907 | try |
|
885 | { |
908 | { |
|
886 | toolStripProgressBar1.Style = ProgressBarStyle.Marquee; |
909 | toolStripProgressBar1.Style = ProgressBarStyle.Marquee; |
|
887 | toolStripProgressBar1.MarqueeAnimationSpeed = 30; |
910 | toolStripProgressBar1.MarqueeAnimationSpeed = 30; |
|
Line 888... | Line 911... | |||
888 | |
911 | |
|
889 | var tasks = new List<Task>(); |
912 | var tasks = new ConcurrentBag<Task>(); |
|
890 | foreach (var item in enumerable) |
913 | foreach (var item in enumerable) |
|
891 | { |
914 | { |
|
892 | await foreach (var entry in GetFilesAsync(item, Configuration, magicMime, cancellationToken).WithCancellation(cancellationToken)) |
915 | await foreach (var entry in GetFilesAsync(item, Configuration, magicMime, cancellationToken).WithCancellation(cancellationToken)) |
|
893 | { |
916 | { |
|
Line 903... | Line 926... | |||
903 | } |
926 | } |
|
904 | finally |
927 | finally |
|
905 | { |
928 | { |
|
906 | toolStripProgressBar1.MarqueeAnimationSpeed = 0; |
929 | toolStripProgressBar1.MarqueeAnimationSpeed = 0; |
|
907 | _imageListViewLock.Release(); |
930 | _imageListViewLock.Release(); |
|
- | 931 | |
||
908 | toolStripStatusLabel1.Text = "Done loading images."; |
932 | toolStripStatusLabel1.Text = "Done loading images."; |
|
909 | } |
933 | } |
|
910 | } |
934 | } |
|
Line 911... | Line 935... | |||
911 | |
935 | |
|
Line 985... | Line 1009... | |||
985 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
1009 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
|
986 | toolStripProgressBar1.Minimum = 0; |
1010 | toolStripProgressBar1.Minimum = 0; |
|
987 | toolStripProgressBar1.Maximum = enumerable.Length; |
1011 | toolStripProgressBar1.Maximum = enumerable.Length; |
|
988 | toolStripProgressBar1.Value = 0; |
1012 | toolStripProgressBar1.Value = 0; |
|
Line 989... | Line -... | |||
989 | |
- | ||
990 | void QuickImageListViewItemProgress(object sender, |
1013 | |
|
991 | ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)> e) |
1014 | void QuickImageListViewItemProgress(object sender, ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)> e) |
|
992 | { |
1015 | { |
|
993 | switch (e) |
1016 | switch (e) |
|
994 | { |
1017 | { |
|
995 | case ImageListViewItemProgressSuccess<(ListViewItem Item, Database.QuickImage Image)> |
- | ||
996 | imageListViewItemProgressSuccess: |
1018 | case ImageListViewItemProgressSuccess<(ListViewItem Item, Database.QuickImage Image)> imageListViewItemProgressSuccess: |
|
997 | if (imageListViewItemProgressSuccess.Item is { } tuple) |
1019 | if (imageListViewItemProgressSuccess.Item is { } tuple) |
|
998 | { |
1020 | { |
|
Line 999... | Line 1021... | |||
999 | var (item, image) = tuple; |
1021 | var (item, image) = tuple; |
|
Line 1012... | Line 1034... | |||
1012 | _imageListViewGroupDictionary.TryAdd(fileInfo.DirectoryName, group); |
1034 | _imageListViewGroupDictionary.TryAdd(fileInfo.DirectoryName, group); |
|
1013 | imageListView.Groups.Add(group); |
1035 | imageListView.Groups.Add(group); |
|
1014 | } |
1036 | } |
|
Line 1015... | Line 1037... | |||
1015 | |
1037 | |
|
- | 1038 | largeImageList.Images.RemoveByKey(item.Name); |
||
1016 | largeImageList.Images.RemoveByKey(item.Name); |
1039 | |
|
Line 1017... | Line 1040... | |||
1017 | largeImageList.Images.Add(image.File, image.Thumbnail); |
1040 | largeImageList.Images.Add(image.File, image.Thumbnail); |
|
1018 | |
1041 | |
|
1019 | imageListView.Items.Add(new ListViewItem(fileInfo.DirectoryName) |
1042 | imageListView.Items.Add(new ListViewItem(fileInfo.DirectoryName) |
|
Line 1074... | Line 1097... | |||
1074 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
1097 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
|
1075 | toolStripProgressBar1.Minimum = 0; |
1098 | toolStripProgressBar1.Minimum = 0; |
|
1076 | toolStripProgressBar1.Maximum = 1; |
1099 | toolStripProgressBar1.Maximum = 1; |
|
1077 | toolStripProgressBar1.Value = 0; |
1100 | toolStripProgressBar1.Value = 0; |
|
Line 1078... | Line -... | |||
1078 | |
- | ||
1079 | void QuickImageListViewItemProgress(object sender, |
1101 | |
|
1080 | ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)> e) |
1102 | void QuickImageListViewItemProgress(object sender, ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)> e) |
|
1081 | { |
1103 | { |
|
1082 | switch (e) |
1104 | switch (e) |
|
1083 | { |
1105 | { |
|
1084 | case ImageListViewItemProgressSuccess<(ListViewItem Item, Database.QuickImage Image)> |
1106 | case ImageListViewItemProgressSuccess<(ListViewItem Item, Database.QuickImage Image)> |
|
1085 | imageListViewItemProgressSuccess: |
1107 | imageListViewItemProgressSuccess: |
|
1086 | if (imageListViewItemProgressSuccess.Item is { } tuple) |
1108 | if (imageListViewItemProgressSuccess.Item is { } tuple) |
|
1087 | { |
1109 | { |
|
Line 1088... | Line 1110... | |||
1088 | var (item, image) = tuple; |
1110 | var (item, image) = tuple; |
|
- | 1111 | |
||
1089 | |
1112 | imageListView.BeginUpdate(); |
|
1090 | imageListView.BeginUpdate(); |
1113 | |
|
1091 | try |
1114 | try |
|
Line 1092... | Line 1115... | |||
1092 | { |
1115 | { |
|
Line 1093... | Line 1116... | |||
1093 | imageListView.Items.Remove(item); |
1116 | imageListView.Items.Remove(item); |
|
1094 | |
1117 | |
|
1095 | var fileInfo = new FileInfo(image.File); |
1118 | var fileInfo = new FileInfo(image.File); |
|
1096 | |
- | ||
1097 | if (!_imageListViewGroupDictionary.TryGetValue(fileInfo.DirectoryName, out var group)) |
1119 | |
|
1098 | { |
1120 | if (!_imageListViewGroupDictionary.TryGetValue(fileInfo.DirectoryName, out var group)) |
|
1099 | group = new ListViewGroup(fileInfo.DirectoryName, HorizontalAlignment.Left) |
1121 | { |
|
Line 1100... | Line 1122... | |||
1100 | { Name = fileInfo.DirectoryName }; |
1122 | group = new ListViewGroup(fileInfo.DirectoryName, HorizontalAlignment.Left) { Name = fileInfo.DirectoryName }; |
|
Line 1147... | Line 1169... | |||
1147 | _quickImageListViewProgress.ProgressChanged += QuickImageListViewItemProgress; |
1169 | _quickImageListViewProgress.ProgressChanged += QuickImageListViewItemProgress; |
|
1148 | try |
1170 | try |
|
1149 | { |
1171 | { |
|
1150 | var directoryName = Path.GetDirectoryName(item.Name); |
1172 | var directoryName = Path.GetDirectoryName(item.Name); |
|
Line 1151... | Line 1173... | |||
1151 | |
1173 | |
|
1152 | await RenameImage(item, Path.Combine(directoryName, destinationFileName), _quickImageListViewProgress, |
- | ||
1153 | cancellationToken); |
1174 | await RenameImage(item, Path.Combine(directoryName, destinationFileName), _quickImageListViewProgress, cancellationToken); |
|
1154 | } |
1175 | } |
|
1155 | catch (Exception exception) |
1176 | catch (Exception exception) |
|
1156 | { |
1177 | { |
|
Line 1169... | Line 1190... | |||
1169 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
1190 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
|
1170 | toolStripProgressBar1.Minimum = 0; |
1191 | toolStripProgressBar1.Minimum = 0; |
|
1171 | toolStripProgressBar1.Maximum = enumerable.Length; |
1192 | toolStripProgressBar1.Maximum = enumerable.Length; |
|
1172 | toolStripProgressBar1.Value = 0; |
1193 | toolStripProgressBar1.Value = 0; |
|
Line 1173... | Line -... | |||
1173 | |
- | ||
1174 | void QuickImageListViewItemProgress(object sender, |
1194 | |
|
1175 | ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)> e) |
1195 | void QuickImageListViewItemProgress(object sender, ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)> e) |
|
1176 | { |
1196 | { |
|
1177 | switch (e) |
1197 | switch (e) |
|
1178 | { |
1198 | { |
|
1179 | case ImageListViewItemProgressSuccess<(ListViewItem Item, Database.QuickImage Image)> |
- | ||
1180 | imageListViewItemProgressSuccess: |
1199 | case ImageListViewItemProgressSuccess<(ListViewItem Item, Database.QuickImage Image)> imageListViewItemProgressSuccess: |
|
1181 | if (imageListViewItemProgressSuccess.Item is { } tuple) |
1200 | if (imageListViewItemProgressSuccess.Item is { } tuple) |
|
1182 | { |
1201 | { |
|
Line 1183... | Line 1202... | |||
1183 | var (item, image) = tuple; |
1202 | var (item, image) = tuple; |
|
Line 1205... | Line 1224... | |||
1205 | Name = image.File, |
1224 | Name = image.File, |
|
1206 | ImageKey = image.File, |
1225 | ImageKey = image.File, |
|
1207 | Text = fileInfo.Name, |
1226 | Text = fileInfo.Name, |
|
1208 | Group = group |
1227 | Group = group |
|
1209 | }); |
1228 | }); |
|
- | 1229 | |
||
1210 | imageListView.EnsureVisible(listViewItem.Index); |
1230 | imageListView.EnsureVisible(listViewItem.Index); |
|
1211 | } |
1231 | } |
|
1212 | finally |
1232 | finally |
|
1213 | { |
1233 | { |
|
1214 | imageListView.EndUpdate(); |
1234 | imageListView.EndUpdate(); |
|
Line 1285... | Line 1305... | |||
1285 | return; |
1305 | return; |
|
1286 | } |
1306 | } |
|
Line 1287... | Line 1307... | |||
1287 | |
1307 | |
|
1288 | try |
1308 | try |
|
1289 | { |
- | ||
1290 | using var _ = bufferBlock.LinkTo(actionBlock, |
1309 | { |
|
Line 1291... | Line 1310... | |||
1291 | new DataflowLinkOptions { PropagateCompletion = true }); |
1310 | using var _ = bufferBlock.LinkTo(actionBlock, new DataflowLinkOptions { PropagateCompletion = true }); |
|
1292 | |
1311 | |
|
1293 | foreach (var item in enumerable) |
1312 | foreach (var item in enumerable) |
|
- | 1313 | { |
||
- | 1314 | if (cancellationToken.IsCancellationRequested) |
||
- | 1315 | { |
||
Line 1294... | Line 1316... | |||
1294 | { |
1316 | return; |
|
1295 | if (cancellationToken.IsCancellationRequested) return; |
1317 | } |
|
1296 | |
1318 | |
|
Line 1297... | Line 1319... | |||
1297 | try |
1319 | try |
|
- | 1320 | { |
||
- | 1321 | File.Delete(item.Name); |
||
- | 1322 | |
||
Line 1298... | Line 1323... | |||
1298 | { |
1323 | if (!await _quickImageDatabase.RemoveImageAsync(item.Name, cancellationToken)) |
|
1299 | File.Delete(item.Name); |
1324 | { |
|
1300 | |
1325 | continue; |
|
1301 | if (!await _quickImageDatabase.RemoveImageAsync(item.Name, cancellationToken)) continue; |
1326 | } |
|
Line 1329... | Line 1354... | |||
1329 | catch |
1354 | catch |
|
1330 | { |
1355 | { |
|
1331 | return; |
1356 | return; |
|
1332 | } |
1357 | } |
|
Line -... | Line 1358... | |||
- | 1358 | |
||
- | 1359 | if (_selectionCancellationTokenSource != null) |
||
1333 | |
1360 | { |
|
- | 1361 | _selectionCancellationTokenSource.Cancel(); |
||
Line 1334... | Line 1362... | |||
1334 | if (_selectionCancellationTokenSource != null) _selectionCancellationTokenSource.Cancel(); |
1362 | } |
|
- | 1363 | |
||
1335 | |
1364 | imageListView.InvokeIfRequired(view => { imageListView.BeginUpdate(); }); |
|
1336 | imageListView.InvokeIfRequired(view => { imageListView.BeginUpdate(); }); |
1365 | |
|
1337 | try |
1366 | try |
|
1338 | { |
1367 | { |
|
1339 | var taskCompletionSource = new TaskCompletionSource<object>(); |
1368 | var taskCompletionSource = new TaskCompletionSource<object>(); |
|
1340 | imageListView.InvokeIfRequired(view => |
1369 | imageListView.InvokeIfRequired(view => |
|
- | 1370 | { |
||
- | 1371 | foreach (var item in view.Items.OfType<ListViewItem>()) |
||
- | 1372 | { |
||
Line 1341... | Line 1373... | |||
1341 | { |
1373 | _searchStore.TryAdd(item.Name, item); |
|
- | 1374 | } |
||
1342 | foreach (var item in view.Items.OfType<ListViewItem>()) _searchStore.TryAdd(item.Name, item); |
1375 | |
|
1343 | |
1376 | view.Items.Clear(); |
|
Line 1344... | Line 1377... | |||
1344 | view.Items.Clear(); |
1377 | |
|
Line 1345... | Line -... | |||
1345 | taskCompletionSource.TrySetResult(new { }); |
- | ||
1346 | }); |
1378 | taskCompletionSource.TrySetResult(new { }); |
|
1347 | |
- | ||
1348 | await taskCompletionSource.Task; |
- | ||
1349 | |
1379 | }); |
|
1350 | await foreach (var quickImage in _quickImageDatabase |
1380 | |
|
- | 1381 | await taskCompletionSource.Task; |
||
- | 1382 | |
||
- | 1383 | await foreach (var quickImage in _quickImageDatabase.Search(keywords, _quickImageSearchType, _quickImageSearchParameters, _combinedSearchSelectionCancellationToken).WithCancellation(_combinedSearchSelectionCancellationToken)) |
||
Line 1351... | Line 1384... | |||
1351 | .Search(keywords, _quickImageSearchType, _quickImageSearchParameters, |
1384 | { |
|
1352 | _combinedSearchSelectionCancellationToken) |
1385 | if (!_searchStore.TryGetValue(quickImage.File, out var item)) |
|
- | 1386 | { |
||
- | 1387 | continue; |
||
- | 1388 | } |
||
Line 1353... | Line 1389... | |||
1353 | .WithCancellation(_combinedSearchSelectionCancellationToken)) |
1389 | |
|
1354 | { |
1390 | var directoryName = Path.GetDirectoryName(item.Name); |
|
1355 | if (!_searchStore.TryGetValue(quickImage.File, out var item)) continue; |
1391 | if (_imageListViewGroupDictionary.TryGetValue(directoryName, out var group)) |
|
1356 | |
1392 | { |
|
Line 1380... | Line 1416... | |||
1380 | catch |
1416 | catch |
|
1381 | { |
1417 | { |
|
1382 | return; |
1418 | return; |
|
1383 | } |
1419 | } |
|
Line -... | Line 1420... | |||
- | 1420 | |
||
- | 1421 | if (_selectionCancellationTokenSource != null) |
||
1384 | |
1422 | { |
|
- | 1423 | _selectionCancellationTokenSource.Cancel(); |
||
Line 1385... | Line 1424... | |||
1385 | if (_selectionCancellationTokenSource != null) _selectionCancellationTokenSource.Cancel(); |
1424 | } |
|
1386 | |
1425 | |
|
1387 | imageListView.InvokeIfRequired(view => { imageListView.BeginUpdate(); }); |
1426 | imageListView.InvokeIfRequired(view => { imageListView.BeginUpdate(); }); |
|
1388 | try |
1427 | try |
|
Line 1389... | Line 1428... | |||
1389 | { |
1428 | { |
|
- | 1429 | toolStripStatusLabel1.Text = "Restoring items."; |
||
1390 | toolStripStatusLabel1.Text = "Restoring items."; |
1430 | |
|
1391 | |
1431 | var taskCompletionSource = new TaskCompletionSource<object>(); |
|
1392 | var taskCompletionSource = new TaskCompletionSource<object>(); |
1432 | |
|
1393 | imageListView.InvokeIfRequired(view => |
1433 | imageListView.InvokeIfRequired(view => |
|
1394 | { |
1434 | { |
|
Line 1429... | Line 1469... | |||
1429 | |
1469 | |
|
1430 | private async Task OcrImages(IEnumerable<ListViewItem> items, |
1470 | private async Task OcrImages(IEnumerable<ListViewItem> items, |
|
1431 | IProgress<ImageListViewItemProgress<ListViewItem>> progress, |
1471 | IProgress<ImageListViewItemProgress<ListViewItem>> progress, |
|
1432 | CancellationToken cancellationToken) |
1472 | CancellationToken cancellationToken) |
|
1433 | { |
1473 | { |
|
1434 | using var engine = new TesseractEngine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tessdata"), |
- | ||
1435 | "eng", EngineMode.Default); |
1474 | using var engine = new TesseractEngine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tessdata"), "eng", EngineMode.Default); |
|
1436 | foreach (var item in items) |
1475 | foreach (var item in items) |
|
1437 | { |
1476 | { |
|
Line 1438... | Line 1477... | |||
1438 | if (cancellationToken.IsCancellationRequested) return; |
1477 | if (cancellationToken.IsCancellationRequested) return; |
|
Line 1462... | Line 1501... | |||
1462 | continue; |
1501 | continue; |
|
1463 | } |
1502 | } |
|
Line 1464... | Line 1503... | |||
1464 | |
1503 | |
|
1465 | if (!await _quickImageDatabase.AddTagsAsync(item.Name, tags, cancellationToken)) |
1504 | if (!await _quickImageDatabase.AddTagsAsync(item.Name, tags, cancellationToken)) |
|
1466 | { |
1505 | { |
|
1467 | progress.Report(new ImageListViewItemProgressFailure<ListViewItem>(item, |
- | ||
1468 | new ArgumentException(MethodBase.GetCurrentMethod()?.Name))); |
1506 | progress.Report(new ImageListViewItemProgressFailure<ListViewItem>(item, new ArgumentException(MethodBase.GetCurrentMethod()?.Name))); |
|
1469 | continue; |
1507 | continue; |
|
Line 1470... | Line 1508... | |||
1470 | } |
1508 | } |
|
1471 | |
1509 | |
|
Line 1482... | Line 1520... | |||
1482 | IProgress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>> progress, |
1520 | IProgress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>> progress, |
|
1483 | CancellationToken cancellationToken) |
1521 | CancellationToken cancellationToken) |
|
1484 | { |
1522 | { |
|
1485 | foreach (var item in items) |
1523 | foreach (var item in items) |
|
1486 | { |
1524 | { |
|
1487 | if (cancellationToken.IsCancellationRequested) return; |
1525 | if (cancellationToken.IsCancellationRequested) |
|
- | 1526 | { |
||
- | 1527 | return; |
||
- | 1528 | } |
||
Line 1488... | Line 1529... | |||
1488 | |
1529 | |
|
1489 | try |
1530 | try |
|
1490 | { |
1531 | { |
|
Line 1564... | Line 1605... | |||
1564 | CancellationToken cancellationToken) |
1605 | CancellationToken cancellationToken) |
|
1565 | { |
1606 | { |
|
1566 | try |
1607 | try |
|
1567 | { |
1608 | { |
|
1568 | await Miscellaneous.CopyFileAsync(item.Name, destinationFileName, cancellationToken); |
1609 | await Miscellaneous.CopyFileAsync(item.Name, destinationFileName, cancellationToken); |
|
- | 1610 | |
||
1569 | File.Delete(item.Name); |
1611 | File.Delete(item.Name); |
|
Line 1570... | Line 1612... | |||
1570 | |
1612 | |
|
Line 1571... | Line 1613... | |||
1571 | var image = await _quickImageDatabase.GetImageAsync(item.Name, cancellationToken); |
1613 | var image = await _quickImageDatabase.GetImageAsync(item.Name, cancellationToken); |
|
Line 1606... | Line 1648... | |||
1606 | IProgress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>> progress, |
1648 | IProgress<ImageListViewItemProgress<(ListViewItem Item, Database.QuickImage Image)>> progress, |
|
1607 | CancellationToken cancellationToken) |
1649 | CancellationToken cancellationToken) |
|
1608 | { |
1650 | { |
|
1609 | foreach (var item in items) |
1651 | foreach (var item in items) |
|
1610 | { |
1652 | { |
|
1611 | if (cancellationToken.IsCancellationRequested) return; |
1653 | if (cancellationToken.IsCancellationRequested) |
|
- | 1654 | { |
||
- | 1655 | return; |
||
- | 1656 | } |
||
Line 1612... | Line 1657... | |||
1612 | |
1657 | |
|
1613 | try |
1658 | try |
|
1614 | { |
1659 | { |
|
1615 | var fileName = Path.GetFileName(item.Name); |
1660 | var fileName = Path.GetFileName(item.Name); |
|
Line 1655... | Line 1700... | |||
1655 | private async Task GetTags(IReadOnlyList<ListViewItem> items, |
1700 | private async Task GetTags(IReadOnlyList<ListViewItem> items, |
|
1656 | IProgress<ImageListViewItemProgress<ListViewItem>> progress, CancellationToken cancellationToken) |
1701 | IProgress<ImageListViewItemProgress<ListViewItem>> progress, CancellationToken cancellationToken) |
|
1657 | { |
1702 | { |
|
1658 | foreach (var item in items) |
1703 | foreach (var item in items) |
|
1659 | { |
1704 | { |
|
1660 | if (cancellationToken.IsCancellationRequested) return; |
1705 | if (cancellationToken.IsCancellationRequested) |
|
- | 1706 | { |
||
- | 1707 | return; |
||
- | 1708 | } |
||
Line 1661... | Line 1709... | |||
1661 | |
1709 | |
|
1662 | try |
1710 | try |
|
1663 | { |
1711 | { |
|
1664 | var tags = await _quickImageDatabase.GetTags(item.Name, cancellationToken) |
1712 | var tags = await _quickImageDatabase.GetTags(item.Name, cancellationToken) |
|
Line 1770... | Line 1818... | |||
1770 | |
1818 | |
|
1771 | try |
1819 | try |
|
1772 | { |
1820 | { |
|
Line 1773... | Line 1821... | |||
1773 | var mime = await magicMime.GetMimeType(item.Name, cancellationToken); |
1821 | var mime = await magicMime.GetMimeType(item.Name, cancellationToken); |
|
- | 1822 | |
||
1774 | |
1823 | if (Configuration.SupportedFormats.IsSupportedImage(mime)) |
|
1775 | if (Configuration.SupportedFormats.IsSupportedImage(mime)) |
1824 | { |
|
1776 | if (!await _tagManager.StripIptcProfile(item.Name, cancellationToken)) |
1825 | if (!await _tagManager.StripIptcProfile(item.Name, cancellationToken)) |
|
1777 | { |
1826 | { |
|
1778 | progress.Report(new ImageListViewItemProgressFailure<ListViewItem>(item, |
1827 | progress.Report(new ImageListViewItemProgressFailure<ListViewItem>(item, |
|
1779 | new ArgumentException(MethodBase.GetCurrentMethod()?.Name))); |
1828 | new ArgumentException(MethodBase.GetCurrentMethod()?.Name))); |
|
- | 1829 | continue; |
||
Line 1780... | Line 1830... | |||
1780 | continue; |
1830 | } |
|
1781 | } |
- | ||
Line 1782... | Line 1831... | |||
1782 | |
1831 | } |
|
1783 | var tags = await _quickImageDatabase.GetTags(item.Name, cancellationToken) |
1832 | |
|
1784 | .ToArrayAsync(cancellationToken); |
1833 | var tags = await _quickImageDatabase.GetTags(item.Name, cancellationToken).ToArrayAsync(cancellationToken); |
|
1785 | |
1834 | |
|
Line 1813... | Line 1862... | |||
1813 | |
1862 | |
|
1814 | try |
1863 | try |
|
1815 | { |
1864 | { |
|
Line 1816... | Line 1865... | |||
1816 | var mime = await magicMime.GetMimeType(item.Name, cancellationToken); |
1865 | var mime = await magicMime.GetMimeType(item.Name, cancellationToken); |
|
- | 1866 | |
||
1817 | |
1867 | if (Configuration.SupportedFormats.IsSupportedImage(mime)) |
|
1818 | if (Configuration.SupportedFormats.IsSupportedImage(mime)) |
1868 | { |
|
1819 | if (!await _tagManager.RemoveIptcKeywords(item.Name, keywords, cancellationToken)) |
1869 | if (!await _tagManager.RemoveIptcKeywords(item.Name, keywords, cancellationToken)) |
|
1820 | { |
1870 | { |
|
1821 | progress.Report(new ImageListViewItemProgressFailure<ListViewItem>(item, |
1871 | progress.Report(new ImageListViewItemProgressFailure<ListViewItem>(item, |
|
1822 | new ArgumentException(MethodBase.GetCurrentMethod()?.Name))); |
1872 | new ArgumentException(MethodBase.GetCurrentMethod()?.Name))); |
|
- | 1873 | continue; |
||
Line 1823... | Line 1874... | |||
1823 | continue; |
1874 | } |
|
1824 | } |
1875 | } |
|
1825 | |
1876 | |
|
1826 | if (!await _quickImageDatabase.RemoveTagsAsync(item.Name, keywords, cancellationToken)) |
1877 | if (!await _quickImageDatabase.RemoveTagsAsync(item.Name, keywords, cancellationToken)) |
|
Line 1901... | Line 1952... | |||
1901 | DateImageListViewSorterType.Modification)); |
1952 | DateImageListViewSorterType.Modification)); |
|
1902 | } |
1953 | } |
|
Line 1903... | Line 1954... | |||
1903 | |
1954 | |
|
1904 | private void renameToolStripMenuItem_Click(object sender, EventArgs e) |
1955 | private void renameToolStripMenuItem_Click(object sender, EventArgs e) |
|
1905 | { |
1956 | { |
|
- | 1957 | if (_renameForm != null) |
||
- | 1958 | { |
||
- | 1959 | return; |
||
Line 1906... | Line 1960... | |||
1906 | if (_renameForm != null) return; |
1960 | } |
|
Line 1907... | Line 1961... | |||
1907 | |
1961 | |
|
- | 1962 | var item = imageListView.SelectedItems.OfType<ListViewItem>().FirstOrDefault(); |
||
- | 1963 | |
||
- | 1964 | if (item == null) |
||
Line 1908... | Line 1965... | |||
1908 | var item = imageListView.SelectedItems.OfType<ListViewItem>().FirstOrDefault(); |
1965 | { |
|
1909 | |
1966 | return; |
|
1910 | if (item == null) return; |
1967 | } |
|
1911 | |
1968 | |
|
Line 1920... | Line 1977... | |||
1920 | await RenameImageAsync(e.ListViewItem, e.FileName, _cancellationToken); |
1977 | await RenameImageAsync(e.ListViewItem, e.FileName, _cancellationToken); |
|
1921 | } |
1978 | } |
|
Line 1922... | Line 1979... | |||
1922 | |
1979 | |
|
1923 | private void RenameForm_Closing(object sender, CancelEventArgs e) |
1980 | private void RenameForm_Closing(object sender, CancelEventArgs e) |
|
1924 | { |
1981 | { |
|
- | 1982 | if (_renameForm == null) |
||
- | 1983 | { |
||
- | 1984 | return; |
||
Line 1925... | Line 1985... | |||
1925 | if (_renameForm == null) return; |
1985 | } |
|
1926 | |
1986 | |
|
1927 | _renameForm.Closing -= RenameForm_Closing; |
1987 | _renameForm.Closing -= RenameForm_Closing; |
|
1928 | _renameForm.Dispose(); |
1988 | _renameForm.Dispose(); |
|
Line 1938... | Line 1998... | |||
1938 | IsFolderPicker = true |
1998 | IsFolderPicker = true |
|
1939 | }; |
1999 | }; |
|
Line 1940... | Line 2000... | |||
1940 | |
2000 | |
|
Line 1941... | Line 2001... | |||
1941 | var groupItems = new List<ListViewItem>(); |
2001 | var groupItems = new List<ListViewItem>(); |
|
- | 2002 | |
||
1942 | |
2003 | if (dialog.ShowDialog() == CommonFileDialogResult.Ok) |
|
- | 2004 | { |
||
1943 | if (dialog.ShowDialog() == CommonFileDialogResult.Ok) |
2005 | foreach (var item in imageListView.SelectedItems.OfType<ListViewItem>()) |
|
- | 2006 | { |
||
1944 | foreach (var item in imageListView.SelectedItems.OfType<ListViewItem>()) |
2007 | foreach (var groupItem in item.Group.Items.OfType<ListViewItem>()) |
|
- | 2008 | { |
||
- | 2009 | groupItems.Add(groupItem); |
||
- | 2010 | } |
||
Line 1945... | Line 2011... | |||
1945 | foreach (var groupItem in item.Group.Items.OfType<ListViewItem>()) |
2011 | } |
|
1946 | groupItems.Add(groupItem); |
2012 | } |
|
Line 1947... | Line 2013... | |||
1947 | |
2013 | |
|
1948 | await RelocateToAsync(groupItems, dialog.FileName, _cancellationToken); |
2014 | RelocateTo(groupItems, dialog.FileName, _cancellationToken); |
|
1949 | } |
2015 | } |
|
Line 1983... | Line 2049... | |||
1983 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
2049 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
|
1984 | _linkedSearchCancellationTokenSource = |
2050 | _linkedSearchCancellationTokenSource = |
|
1985 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
2051 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
|
1986 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
2052 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
|
Line 1987... | Line 2053... | |||
1987 | |
2053 | |
|
1988 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, |
- | ||
1989 | async text => { await BeginSearch(text); }, _formTaskScheduler, |
- | ||
1990 | _combinedSearchSelectionCancellationToken); |
2054 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, async text => { await BeginSearch(text); }, _formTaskScheduler, _combinedSearchSelectionCancellationToken); |
|
Line 1991... | Line 2055... | |||
1991 | } |
2055 | } |
|
1992 | |
2056 | |
|
1993 | private void checkBox3_CheckedChanged(object sender, EventArgs e) |
2057 | private void checkBox3_CheckedChanged(object sender, EventArgs e) |
|
Line 2005... | Line 2069... | |||
2005 | _quickImageSearchParameters & ~QuickImageSearchParameters.Split; |
2069 | _quickImageSearchParameters & ~QuickImageSearchParameters.Split; |
|
2006 | break; |
2070 | break; |
|
2007 | } |
2071 | } |
|
Line 2008... | Line 2072... | |||
2008 | |
2072 | |
|
2009 | var text = textBox1.Text; |
2073 | var text = textBox1.Text; |
|
- | 2074 | if (string.IsNullOrEmpty(text)) |
||
- | 2075 | { |
||
- | 2076 | return; |
||
Line -... | Line 2077... | |||
- | 2077 | } |
||
- | 2078 | |
||
2010 | if (string.IsNullOrEmpty(text)) return; |
2079 | if (_searchCancellationTokenSource != null) |
|
- | 2080 | { |
||
Line 2011... | Line 2081... | |||
2011 | |
2081 | _searchCancellationTokenSource.Cancel(); |
|
2012 | if (_searchCancellationTokenSource != null) _searchCancellationTokenSource.Cancel(); |
2082 | } |
|
2013 | |
2083 | |
|
2014 | _searchCancellationTokenSource = new CancellationTokenSource(); |
2084 | _searchCancellationTokenSource = new CancellationTokenSource(); |
|
2015 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
2085 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
|
Line 2016... | Line 2086... | |||
2016 | _linkedSearchCancellationTokenSource = |
2086 | _linkedSearchCancellationTokenSource = |
|
2017 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
- | ||
2018 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
- | ||
2019 | |
2087 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
|
Line 2020... | Line 2088... | |||
2020 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, |
2088 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
|
2021 | async text => { await BeginSearch(text); }, _formTaskScheduler, |
2089 | |
|
2022 | _combinedSearchSelectionCancellationToken); |
2090 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, async text => { await BeginSearch(text); }, _formTaskScheduler, _combinedSearchSelectionCancellationToken); |
|
Line 2059... | Line 2127... | |||
2059 | |
2127 | |
|
2060 | private async Task PerformUpgrade() |
2128 | private async Task PerformUpgrade() |
|
2061 | { |
2129 | { |
|
2062 | // Manually check for updates, this will not show a ui |
2130 | // Manually check for updates, this will not show a ui |
|
- | 2131 | var updateCheck = await _sparkle.CheckForUpdatesQuietly(); |
||
2063 | var updateCheck = await _sparkle.CheckForUpdatesQuietly(); |
2132 | |
|
2064 | switch (updateCheck.Status) |
2133 | switch (updateCheck.Status) |
|
2065 | { |
2134 | { |
|
2066 | case UpdateStatus.UserSkipped: |
2135 | case UpdateStatus.UserSkipped: |
|
- | 2136 | var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version; |
||
2067 | var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version; |
2137 | |
|
2068 | updateCheck.Updates.Sort(UpdateComparer); |
2138 | updateCheck.Updates.Sort(UpdateComparer); |
|
2069 | var latestVersion = updateCheck.Updates.FirstOrDefault(); |
2139 | var latestVersion = updateCheck.Updates.FirstOrDefault(); |
|
2070 | if (latestVersion != null) |
2140 | if (latestVersion != null) |
|
2071 | { |
2141 | { |
|
Line 2143... | Line 2213... | |||
2143 | if (fileAttributes.HasFlag(FileAttributes.Directory)) |
2213 | if (fileAttributes.HasFlag(FileAttributes.Directory)) |
|
2144 | { |
2214 | { |
|
2145 | continue; |
2215 | continue; |
|
2146 | } |
2216 | } |
|
Line -... | Line 2217... | |||
- | 2217 | |
||
2147 | |
2218 | using var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); |
|
- | 2219 | var memoryStream = new MemoryStream(); |
||
2148 | var memoryStream = new MemoryStream(File.ReadAllBytes(file)); |
2220 | await fileStream.CopyToAsync(memoryStream); |
|
Line 2149... | Line 2221... | |||
2149 | memoryStream.Position = 0L; |
2221 | memoryStream.Position = 0L; |
|
2150 | |
2222 | |
|
2151 | var mime = await magicMime.Identify(file, cancellationToken); |
2223 | var mime = await magicMime.Identify(file, cancellationToken); |
|
Line 2163... | Line 2235... | |||
2163 | var fileNames = data.GetFileContentNames(); |
2235 | var fileNames = data.GetFileContentNames(); |
|
2164 | for (var i = 0; i < fileNames.Length; ++i) |
2236 | for (var i = 0; i < fileNames.Length; ++i) |
|
2165 | { |
2237 | { |
|
2166 | var memoryStream = data.GetFileContent(i); |
2238 | var memoryStream = data.GetFileContent(i); |
|
2167 | memoryStream.Position = 0L; |
2239 | memoryStream.Position = 0L; |
|
- | 2240 | |
||
2168 | var mime = magicMime.Identify(fileNames[i], memoryStream, cancellationToken); |
2241 | var mime = magicMime.Identify(fileNames[i], memoryStream, cancellationToken); |
|
- | 2242 | |
||
2169 | if (mime == null) continue; |
2243 | if (mime == null) |
|
- | 2244 | { |
||
- | 2245 | continue; |
||
- | 2246 | } |
||
- | 2247 | |
||
2170 | yield return (File: fileNames[0], Data: memoryStream, Mime: mime.Definition); |
2248 | yield return (File: fileNames[0], Data: memoryStream, Mime: mime.Definition); |
|
2171 | } |
2249 | } |
|
2172 | } |
2250 | } |
|
Line 2173... | Line 2251... | |||
2173 | |
2251 | |
|
2174 | private static async IAsyncEnumerable<string> GetFilesAsync(string entry, |
2252 | private static async IAsyncEnumerable<string> GetFilesAsync(string entry, |
|
2175 | Configuration.Configuration configuration, MagicMime magicMime, |
2253 | Configuration.Configuration configuration, MagicMime magicMime, |
|
2176 | [EnumeratorCancellation] CancellationToken cancellationToken) |
2254 | [EnumeratorCancellation] CancellationToken cancellationToken) |
|
2177 | { |
2255 | { |
|
2178 | var bufferBlock = new BufferBlock<string>(new DataflowBlockOptions |
- | ||
Line 2179... | Line 2256... | |||
2179 | { CancellationToken = cancellationToken }); |
2256 | var bufferBlock = new BufferBlock<string>(new DataflowBlockOptions { CancellationToken = cancellationToken }); |
|
2180 | |
2257 | |
|
2181 | #pragma warning disable CS4014 |
2258 | #pragma warning disable CS4014 |
|
2182 | Task.Run(async () => |
2259 | Task.Run(async () => |
|
Line 2222... | Line 2299... | |||
2222 | } |
2299 | } |
|
2223 | }, cancellationToken); |
2300 | }, cancellationToken); |
|
Line 2224... | Line 2301... | |||
2224 | |
2301 | |
|
2225 | while (await bufferBlock.OutputAvailableAsync(cancellationToken)) |
2302 | while (await bufferBlock.OutputAvailableAsync(cancellationToken)) |
|
2226 | { |
2303 | { |
|
- | 2304 | if (!bufferBlock.TryReceiveAll(out var files)) |
||
- | 2305 | { |
||
- | 2306 | continue; |
||
Line 2227... | Line 2307... | |||
2227 | if (!bufferBlock.TryReceiveAll(out var files)) continue; |
2307 | } |
|
- | 2308 | |
||
- | 2309 | foreach (var file in files) |
||
- | 2310 | { |
||
2228 | |
2311 | yield return file; |
|
2229 | foreach (var file in files) yield return file; |
2312 | } |
|
Line 2230... | Line 2313... | |||
2230 | } |
2313 | } |
|
2231 | } |
2314 | } |
|
Line 2331... | Line 2414... | |||
2331 | |
2414 | |
|
Line 2332... | Line 2415... | |||
2332 | #region Event Handlers |
2415 | #region Event Handlers |
|
2333 | |
2416 | |
|
2334 | private void toolStripTextBox1_KeyUp(object sender, KeyEventArgs e) |
2417 | private void toolStripTextBox1_KeyUp(object sender, KeyEventArgs e) |
|
- | 2418 | { |
||
- | 2419 | if (e.KeyCode != Keys.Return) |
||
- | 2420 | { |
||
Line 2335... | Line 2421... | |||
2335 | { |
2421 | return; |
|
2336 | if (e.KeyCode != Keys.Return) return; |
2422 | } |
|
Line 2337... | Line 2423... | |||
2337 | |
2423 | |
|
2338 | // Skip the beep. |
2424 | // Skip the beep. |
|
2339 | e.Handled = true; |
2425 | e.Handled = true; |
|
Line 2340... | Line 2426... | |||
2340 | |
2426 | |
|
- | 2427 | var toolStripTextBox = (ToolStripTextBox)sender; |
||
- | 2428 | var tagText = toolStripTextBox.Text; |
||
- | 2429 | toolStripTextBox.Clear(); |
||
Line 2341... | Line 2430... | |||
2341 | var toolStripTextBox = (ToolStripTextBox)sender; |
2430 | |
|
Line 2342... | Line 2431... | |||
2342 | var tagText = toolStripTextBox.Text; |
2431 | if (string.IsNullOrEmpty(tagText)) |
|
Line 2397... | Line 2486... | |||
2397 | } |
2486 | } |
|
Line 2398... | Line 2487... | |||
2398 | |
2487 | |
|
2399 | toolStripStatusLabel1.Text = "Adding tags..."; |
2488 | toolStripStatusLabel1.Text = "Adding tags..."; |
|
Line 2400... | Line 2489... | |||
2400 | toolStripProgressBar1.Increment(1); |
2489 | toolStripProgressBar1.Increment(1); |
|
- | 2490 | |
||
2401 | |
2491 | if (toolStripProgressBar1.Value == toolStripProgressBar1.Maximum) |
|
- | 2492 | { |
||
2402 | if (toolStripProgressBar1.Value == toolStripProgressBar1.Maximum) |
2493 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
|
Line 2403... | Line 2494... | |||
2403 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
2494 | } |
|
2404 | } |
2495 | } |
|
2405 | |
2496 | |
|
Line 2474... | Line 2565... | |||
2474 | form.toolStripProgressBar1.MarqueeAnimationSpeed = 30; |
2565 | form.toolStripProgressBar1.MarqueeAnimationSpeed = 30; |
|
2475 | }); |
2566 | }); |
|
Line 2476... | Line 2567... | |||
2476 | |
2567 | |
|
2477 | try |
2568 | try |
|
2478 | { |
- | ||
2479 | var images = await _quickImageDatabase.GetAll(_cancellationToken).ToArrayAsync(_cancellationToken); |
2569 | { |
|
2480 | var imageListViewItems = new List<ListViewItem>(); |
2570 | var imageListViewItems = new ConcurrentBag<ListViewItem>(); |
|
2481 | var tags = new HashSet<string>(StringComparer.Ordinal); |
2571 | var tags = new HashSet<string>(StringComparer.Ordinal); |
|
2482 | foreach (var image in images) |
2572 | await foreach (var image in _quickImageDatabase.GetAll(_cancellationToken)) |
|
2483 | { |
2573 | { |
|
- | 2574 | if (!largeImageList.Images.ContainsKey(image.File)) |
||
2484 | if (!largeImageList.Images.ContainsKey(image.File)) |
2575 | { |
|
- | 2576 | largeImageList.Images.Add(image.File, image.Thumbnail); |
||
Line 2485... | Line 2577... | |||
2485 | largeImageList.Images.Add(image.File, image.Thumbnail); |
2577 | } |
|
Line 2486... | Line 2578... | |||
2486 | |
2578 | |
|
2487 | var fileInfo = new FileInfo(image.File); |
2579 | var fileInfo = new FileInfo(image.File); |
|
2488 | |
2580 | |
|
2489 | if (!_imageListViewGroupDictionary.TryGetValue(fileInfo.DirectoryName, out var group)) |
- | ||
2490 | { |
- | ||
Line -... | Line 2581... | |||
- | 2581 | if (!_imageListViewGroupDictionary.TryGetValue(fileInfo.DirectoryName, out var group)) |
||
- | 2582 | { |
||
2491 | group = new ListViewGroup(fileInfo.DirectoryName, HorizontalAlignment.Left) |
2583 | group = new ListViewGroup(fileInfo.DirectoryName, HorizontalAlignment.Left) { Name = fileInfo.DirectoryName }; |
|
2492 | { Name = fileInfo.DirectoryName }; |
2584 | |
|
- | 2585 | _imageListViewGroupDictionary.TryAdd(fileInfo.DirectoryName, group); |
||
2493 | _imageListViewGroupDictionary.TryAdd(fileInfo.DirectoryName, group); |
2586 | |
|
2494 | |
- | ||
- | 2587 | imageListView.InvokeIfRequired(view => |
||
2495 | imageListView.InvokeIfRequired(view => |
2588 | { |
|
2496 | { |
2589 | view.BeginUpdate(); |
|
Line 2497... | Line 2590... | |||
2497 | view.Groups.Add(group); |
2590 | view.Groups.Add(group); |
|
Line 2498... | Line 2591... | |||
2498 | |
2591 | view.EndUpdate(); |
|
2499 | }); |
2592 | }); |
|
2500 | } |
2593 | } |
|
2501 | |
2594 | |
|
2502 | tags.UnionWith(image.Tags); |
2595 | tags.UnionWith(image.Tags); |
|
2503 | |
2596 | |
|
2504 | imageListViewItems.Add(new ListViewItem(image.File) |
2597 | var imageListViewItem = new ListViewItem(image.File) |
|
- | 2598 | { |
||
- | 2599 | Name = image.File, |
||
- | 2600 | ImageKey = image.File, |
||
2505 | { |
2601 | Text = fileInfo.Name, |
|
Line 2506... | Line 2602... | |||
2506 | Name = image.File, |
2602 | Group = group |
|
Line 2507... | Line 2603... | |||
2507 | ImageKey = image.File, |
2603 | }; |
|
2508 | Text = fileInfo.Name, |
2604 | |
|
Line 2522... | Line 2618... | |||
2522 | tagListView.InvokeIfRequired(view => |
2618 | tagListView.InvokeIfRequired(view => |
|
2523 | { |
2619 | { |
|
2524 | view.BeginUpdate(); |
2620 | view.BeginUpdate(); |
|
2525 | view.Items.AddRange(tags.Select(tag => new ListViewItem(tag) { Name = tag }).ToArray()); |
2621 | view.Items.AddRange(tags.Select(tag => new ListViewItem(tag) { Name = tag }).ToArray()); |
|
2526 | view.EndUpdate(); |
2622 | view.EndUpdate(); |
|
2527 | }); |
2623 | }); |
|
2528 | } |
2624 | } |
|
2529 | catch (Exception exception) |
2625 | catch (Exception exception) |
|
2530 | { |
2626 | { |
|
2531 | Log.Error(exception, "Unable to load images."); |
2627 | Log.Error(exception, "Unable to load images."); |
|
2532 | } |
2628 | } |
|
Line 2544... | Line 2640... | |||
2544 | } |
2640 | } |
|
Line 2545... | Line 2641... | |||
2545 | |
2641 | |
|
2546 | private async void tagListView_MouseDown(object sender, MouseEventArgs e) |
2642 | private async void tagListView_MouseDown(object sender, MouseEventArgs e) |
|
2547 | { |
2643 | { |
|
2548 | var listView = (ListView)sender; |
2644 | var listView = (ListView)sender; |
|
- | 2645 | if (!listView.CheckBoxes) |
||
- | 2646 | { |
||
- | 2647 | return; |
||
Line 2549... | Line 2648... | |||
2549 | if (!listView.CheckBoxes) return; |
2648 | } |
|
2550 | |
2649 | |
|
2551 | // Allow clicking anywhere on tag. |
2650 | // Allow clicking anywhere on tag. |
|
- | 2651 | var hitTest = listView.HitTest(e.Location); |
||
- | 2652 | if (hitTest.Item == null) |
||
- | 2653 | { |
||
Line 2552... | Line 2654... | |||
2552 | var hitTest = listView.HitTest(e.Location); |
2654 | return; |
|
Line 2553... | Line 2655... | |||
2553 | if (hitTest.Item == null) return; |
2655 | } |
|
Line 2588... | Line 2690... | |||
2588 | case ImageListViewItemProgressFailure<ListViewItem> imageListViewItemProgressFailure: |
2690 | case ImageListViewItemProgressFailure<ListViewItem> imageListViewItemProgressFailure: |
|
2589 | break; |
2691 | break; |
|
2590 | } |
2692 | } |
|
Line 2591... | Line 2693... | |||
2591 | |
2693 | |
|
2592 | toolStripProgressBar1.Increment(1); |
2694 | toolStripProgressBar1.Increment(1); |
|
- | 2695 | if (toolStripProgressBar1.Value == toolStripProgressBar1.Maximum) |
||
2593 | if (toolStripProgressBar1.Value == toolStripProgressBar1.Maximum) |
2696 | { |
|
- | 2697 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
||
2594 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
2698 | } |
|
Line 2595... | Line 2699... | |||
2595 | } |
2699 | } |
|
2596 | |
2700 | |
|
Line 2597... | Line 2701... | |||
2597 | if (item.Checked) |
2701 | if (item.Checked) |
|
- | 2702 | { |
||
2598 | { |
2703 | |
|
2599 | |
2704 | toolStripStatusLabel1.Text = "Removing tags..."; |
|
2600 | toolStripStatusLabel1.Text = "Removing tags..."; |
2705 | |
|
2601 | _listViewItemProgress.ProgressChanged += ImageListViewItemProgress; |
2706 | _listViewItemProgress.ProgressChanged += ImageListViewItemProgress; |
|
2602 | try |
2707 | try |
|
2603 | { |
2708 | { |
|
2604 | await RemoveTags(items, keywords, _magicMime, _listViewItemProgress, _cancellationToken); |
2709 | await RemoveTags(items, keywords, _magicMime, _listViewItemProgress, _cancellationToken); |
|
2605 | } |
2710 | } |
|
2606 | finally |
2711 | finally |
|
Line -... | Line 2712... | |||
- | 2712 | { |
||
- | 2713 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
||
- | 2714 | } |
||
2607 | { |
2715 | |
|
- | 2716 | switch(hitTest.Location) |
||
- | 2717 | { |
||
Line 2608... | Line 2718... | |||
2608 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
2718 | case ListViewHitTestLocations.Label: |
|
2609 | } |
2719 | hitTest.Item.Checked = !hitTest.Item.Checked; |
|
Line 2610... | Line 2720... | |||
2610 | |
2720 | break; |
|
Line 2622... | Line 2732... | |||
2622 | finally |
2732 | finally |
|
2623 | { |
2733 | { |
|
2624 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
2734 | _listViewItemProgress.ProgressChanged -= ImageListViewItemProgress; |
|
2625 | } |
2735 | } |
|
Line -... | Line 2736... | |||
- | 2736 | |
||
- | 2737 | switch(hitTest.Location) |
||
- | 2738 | { |
||
2626 | |
2739 | case ListViewHitTestLocations.Label: |
|
- | 2740 | hitTest.Item.Checked = !hitTest.Item.Checked; |
||
- | 2741 | break; |
||
2627 | if (hitTest.Location == ListViewHitTestLocations.Label) hitTest.Item.Checked = !hitTest.Item.Checked; |
2742 | } |
|
Line 2628... | Line 2743... | |||
2628 | } |
2743 | } |
|
2629 | |
2744 | |
|
2630 | private void aboutToolStripMenuItem_Click(object sender, EventArgs e) |
2745 | private void aboutToolStripMenuItem_Click(object sender, EventArgs e) |
|
- | 2746 | { |
||
- | 2747 | if (_aboutForm != null) |
||
- | 2748 | { |
||
Line 2631... | Line 2749... | |||
2631 | { |
2749 | return; |
|
2632 | if (_aboutForm != null) return; |
2750 | } |
|
2633 | |
2751 | |
|
2634 | _aboutForm = new AboutForm(); |
2752 | _aboutForm = new AboutForm(); |
|
Line 2635... | Line 2753... | |||
2635 | _aboutForm.Closing += AboutForm_Closing; |
2753 | _aboutForm.Closing += AboutForm_Closing; |
|
2636 | _aboutForm.Show(); |
2754 | _aboutForm.Show(); |
|
2637 | } |
2755 | } |
|
- | 2756 | |
||
- | 2757 | private void AboutForm_Closing(object sender, CancelEventArgs e) |
||
- | 2758 | { |
||
Line 2638... | Line 2759... | |||
2638 | |
2759 | if (_aboutForm == null) |
|
2639 | private void AboutForm_Closing(object sender, CancelEventArgs e) |
2760 | { |
|
2640 | { |
2761 | return; |
|
2641 | if (_aboutForm == null) return; |
2762 | } |
|
Line 2650... | Line 2771... | |||
2650 | await PerformUpgrade(); |
2771 | await PerformUpgrade(); |
|
2651 | } |
2772 | } |
|
Line 2652... | Line 2773... | |||
2652 | |
2773 | |
|
2653 | private void viewLogsToolStripMenuItem_Click(object sender, EventArgs e) |
2774 | private void viewLogsToolStripMenuItem_Click(object sender, EventArgs e) |
|
2654 | { |
2775 | { |
|
- | 2776 | if (_viewLogsForm != null) |
||
- | 2777 | { |
||
- | 2778 | return; |
||
Line 2655... | Line 2779... | |||
2655 | if (_viewLogsForm != null) return; |
2779 | } |
|
2656 | |
2780 | |
|
2657 | _viewLogsForm = new ViewLogsForm(this, _memorySink, _cancellationToken); |
2781 | _viewLogsForm = new ViewLogsForm(this, _memorySink, _cancellationToken); |
|
2658 | _viewLogsForm.Closing += ViewLogsForm_Closing; |
2782 | _viewLogsForm.Closing += ViewLogsForm_Closing; |
|
Line 2659... | Line 2783... | |||
2659 | _viewLogsForm.Show(); |
2783 | _viewLogsForm.Show(); |
|
2660 | } |
2784 | } |
|
2661 | |
2785 | |
|
- | 2786 | private void ViewLogsForm_Closing(object sender, CancelEventArgs e) |
||
- | 2787 | { |
||
- | 2788 | if (_viewLogsForm == null) |
||
Line 2662... | Line 2789... | |||
2662 | private void ViewLogsForm_Closing(object sender, CancelEventArgs e) |
2789 | { |
|
2663 | { |
2790 | return; |
|
2664 | if (_viewLogsForm == null) return; |
2791 | } |
|
2665 | |
2792 | |
|
Line 2676... | Line 2803... | |||
2676 | |
2803 | |
|
2677 | private async void removeToolStripMenuItem_Click(object sender, EventArgs e) |
2804 | private async void removeToolStripMenuItem_Click(object sender, EventArgs e) |
|
2678 | { |
2805 | { |
|
Line 2679... | Line 2806... | |||
2679 | var items = imageListView.SelectedItems.OfType<ListViewItem>().ToArray(); |
2806 | var items = imageListView.SelectedItems.OfType<ListViewItem>().ToArray(); |
|
2680 | |
2807 | |
|
Line 2681... | Line 2808... | |||
2681 | await RemoveImagesAsync(items, _cancellationToken); |
2808 | RemoveImages(items, _cancellationToken); |
|
2682 | } |
2809 | } |
|
2683 | |
2810 | |
|
Line 2750... | Line 2877... | |||
2750 | private void textBox1_KeyDown(object sender, KeyEventArgs e) |
2877 | private void textBox1_KeyDown(object sender, KeyEventArgs e) |
|
2751 | { |
2878 | { |
|
2752 | if (e.Control && e.KeyCode == Keys.A) |
2879 | if (e.Control && e.KeyCode == Keys.A) |
|
2753 | { |
2880 | { |
|
2754 | var textBox = (TextBox)sender; |
2881 | var textBox = (TextBox)sender; |
|
- | 2882 | |
||
2755 | textBox.SelectAll(); |
2883 | textBox.SelectAll(); |
|
2756 | } |
2884 | } |
|
2757 | } |
2885 | } |
|
Line 2758... | Line 2886... | |||
2758 | |
2886 | |
|
2759 | private void radioButton2_CheckedChanged(object sender, EventArgs e) |
2887 | private void radioButton2_CheckedChanged(object sender, EventArgs e) |
|
2760 | { |
2888 | { |
|
Line 2761... | Line 2889... | |||
2761 | _quickImageSearchType = QuickImageSearchType.Any; |
2889 | _quickImageSearchType = QuickImageSearchType.Any; |
|
2762 | |
2890 | |
|
- | 2891 | var text = textBox1.Text; |
||
- | 2892 | if (string.IsNullOrEmpty(text)) |
||
- | 2893 | { |
||
Line -... | Line 2894... | |||
- | 2894 | return; |
||
- | 2895 | } |
||
2763 | var text = textBox1.Text; |
2896 | |
|
- | 2897 | if (_searchCancellationTokenSource != null) |
||
Line 2764... | Line 2898... | |||
2764 | if (string.IsNullOrEmpty(text)) return; |
2898 | { |
|
2765 | |
2899 | _searchCancellationTokenSource.Cancel(); |
|
2766 | if (_searchCancellationTokenSource != null) _searchCancellationTokenSource.Cancel(); |
2900 | } |
|
2767 | |
2901 | |
|
2768 | _searchCancellationTokenSource = new CancellationTokenSource(); |
2902 | _searchCancellationTokenSource = new CancellationTokenSource(); |
|
Line 2769... | Line 2903... | |||
2769 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
2903 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
|
2770 | _linkedSearchCancellationTokenSource = |
- | ||
2771 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
- | ||
2772 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
2904 | _linkedSearchCancellationTokenSource = |
|
Line 2773... | Line 2905... | |||
2773 | |
2905 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
|
2774 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, |
2906 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
|
2775 | async text => { await BeginSearch(text); }, _formTaskScheduler, |
2907 | |
|
Line 2776... | Line 2908... | |||
2776 | _combinedSearchSelectionCancellationToken); |
2908 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, async text => { await BeginSearch(text); }, _formTaskScheduler, _combinedSearchSelectionCancellationToken); |
|
2777 | } |
2909 | } |
|
- | 2910 | |
||
- | 2911 | private void radiobutton1_CheckedChanged(object sender, EventArgs e) |
||
- | 2912 | { |
||
Line 2778... | Line 2913... | |||
2778 | |
2913 | _quickImageSearchType = QuickImageSearchType.All; |
|
Line 2779... | Line 2914... | |||
2779 | private void radiobutton1_CheckedChanged(object sender, EventArgs e) |
2914 | |
|
2780 | { |
2915 | var text = textBox1.Text; |
|
2781 | _quickImageSearchType = QuickImageSearchType.All; |
2916 | if (string.IsNullOrEmpty(text)) |
|
2782 | |
2917 | { |
|
2783 | var text = textBox1.Text; |
2918 | return; |
|
Line 2784... | Line 2919... | |||
2784 | if (string.IsNullOrEmpty(text)) return; |
2919 | } |
|
2785 | |
- | ||
2786 | if (_searchCancellationTokenSource != null) _searchCancellationTokenSource.Cancel(); |
- | ||
2787 | |
2920 | |
|
Line 2788... | Line 2921... | |||
2788 | _searchCancellationTokenSource = new CancellationTokenSource(); |
2921 | if (_searchCancellationTokenSource != null) _searchCancellationTokenSource.Cancel(); |
|
2789 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
2922 | |
|
2790 | _linkedSearchCancellationTokenSource = |
2923 | _searchCancellationTokenSource = new CancellationTokenSource(); |
|
2791 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
2924 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
|
2792 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
- | ||
2793 | |
- | ||
2794 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, |
- | ||
2795 | async text => { await BeginSearch(text); }, _formTaskScheduler, |
- | ||
2796 | _combinedSearchSelectionCancellationToken); |
- | ||
2797 | } |
2925 | _linkedSearchCancellationTokenSource = |
|
2798 | |
2926 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
|
2799 | private async void editToolStripMenuItem1_Click(object sender, EventArgs e) |
2927 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
|
2800 | { |
- | ||
2801 | var item = imageListView.SelectedItems.OfType<ListViewItem>().FirstOrDefault(); |
- | ||
2802 | if (item == null) return; |
- | ||
Line -... | Line 2928... | |||
- | 2928 | |
||
- | 2929 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, async text => { await BeginSearch(text); }, _formTaskScheduler, _combinedSearchSelectionCancellationToken); |
||
2803 | |
2930 | } |
|
2804 | if (_editorForm != null) return; |
2931 | |
|
Line -... | Line 2932... | |||
- | 2932 | private async void editToolStripMenuItem1_Click(object sender, EventArgs e) |
||
2805 | |
2933 | { |
|
2806 | string mime; |
2934 | var item = imageListView.SelectedItems.OfType<ListViewItem>().FirstOrDefault(); |
|
2807 | try |
2935 | if (item == null) |
|
2808 | { |
2936 | { |
|
2809 | mime = await _magicMime.GetMimeType(item.Name, _cancellationToken); |
2937 | return; |
|
2810 | } |
2938 | } |
|
2811 | catch (Exception exception) |
2939 | |
|
2812 | { |
2940 | if (_editorForm != null) |
|
2813 | Log.Error(exception, "Unable to identify file."); |
2941 | { |
|
2814 | |
2942 | return; |
|
Line 2866... | Line 2994... | |||
2866 | var thumbnail = new Bitmap(thumbnailBitmap); |
2994 | var thumbnail = new Bitmap(thumbnailBitmap); |
|
2867 | thumbnailBitmap.Dispose(); |
2995 | thumbnailBitmap.Dispose(); |
|
Line 2868... | Line 2996... | |||
2868 | |
2996 | |
|
2869 | try |
2997 | try |
|
2870 | { |
2998 | { |
|
- | 2999 | if (!await _quickImageDatabase.RemoveImageAsync(e.FileName, _cancellationToken)) |
||
2871 | var keywords = await _quickImageDatabase.GetTags(e.FileName, _cancellationToken) |
3000 | { |
|
- | 3001 | throw new ArgumentException($"Could not remove image {e.FileName} from database."); |
||
Line 2872... | Line 3002... | |||
2872 | .ToArrayAsync(_cancellationToken); |
3002 | } |
|
2873 | |
- | ||
Line 2874... | Line 3003... | |||
2874 | if (!await _quickImageDatabase.RemoveImageAsync(e.FileName, _cancellationToken)) |
3003 | |
|
- | 3004 | var keywords = await _quickImageDatabase.GetTags(e.FileName, _cancellationToken).ToArrayAsync(_cancellationToken); |
||
2875 | throw new ArgumentException($"Could not remove image {e.FileName} from database."); |
3005 | |
|
- | 3006 | if (!await _quickImageDatabase.AddImageAsync(e.FileName, hash, keywords, thumbnail, _cancellationToken)) |
||
Line 2876... | Line 3007... | |||
2876 | |
3007 | { |
|
2877 | if (!await _quickImageDatabase.AddImageAsync(e.FileName, hash, keywords, thumbnail, _cancellationToken)) |
3008 | throw new ArgumentException($"Could not add image {e.FileName} to database."); |
|
2878 | throw new ArgumentException($"Could not add image {e.FileName} to database."); |
3009 | } |
|
2879 | |
3010 | |
|
Line 2889... | Line 3020... | |||
2889 | } |
3020 | } |
|
2890 | } |
3021 | } |
|
Line 2891... | Line 3022... | |||
2891 | |
3022 | |
|
2892 | private void _editorForm_Closing(object sender, CancelEventArgs e) |
3023 | private void _editorForm_Closing(object sender, CancelEventArgs e) |
|
2893 | { |
3024 | { |
|
- | 3025 | if (_editorForm == null) |
||
- | 3026 | { |
||
- | 3027 | return; |
||
Line 2894... | Line 3028... | |||
2894 | if (_editorForm == null) return; |
3028 | } |
|
2895 | |
3029 | |
|
2896 | _editorForm.ImageSave -= _editorForm_ImageSave; |
3030 | _editorForm.ImageSave -= _editorForm_ImageSave; |
|
2897 | _editorForm.ImageSaveAs -= _editorForm_ImageSaveAs; |
3031 | _editorForm.ImageSaveAs -= _editorForm_ImageSaveAs; |
|
Line 2912... | Line 3046... | |||
2912 | void ImageListViewItemProgress(object sender, ImageListViewItemProgress<ListViewItem> e) |
3046 | void ImageListViewItemProgress(object sender, ImageListViewItemProgress<ListViewItem> e) |
|
2913 | { |
3047 | { |
|
2914 | switch (e) |
3048 | switch (e) |
|
2915 | { |
3049 | { |
|
2916 | case ImageListViewItemProgressSuccess<ListViewItem> imageListViewItemProgressSuccess: |
3050 | case ImageListViewItemProgressSuccess<ListViewItem> imageListViewItemProgressSuccess: |
|
2917 | if (!(imageListViewItemProgressSuccess.Item is { } listViewItem)) break; |
3051 | if (!(imageListViewItemProgressSuccess.Item is { } listViewItem)) |
|
- | 3052 | { |
||
- | 3053 | break; |
||
- | 3054 | } |
||
Line 2918... | Line 3055... | |||
2918 | |
3055 | |
|
Line 2919... | Line 3056... | |||
2919 | toolStripStatusLabel1.Text = $"Synchronizing tags for {listViewItem.Name}"; |
3056 | toolStripStatusLabel1.Text = $"Synchronizing tags for {listViewItem.Name}"; |
|
2920 | |
3057 | |
|
Line 2981... | Line 3118... | |||
2981 | _quickImageSearchParameters & ~QuickImageSearchParameters.CaseSensitive; |
3118 | _quickImageSearchParameters & ~QuickImageSearchParameters.CaseSensitive; |
|
2982 | break; |
3119 | break; |
|
2983 | } |
3120 | } |
|
Line 2984... | Line 3121... | |||
2984 | |
3121 | |
|
2985 | var text = textBox1.Text; |
3122 | var text = textBox1.Text; |
|
- | 3123 | if (string.IsNullOrEmpty(text)) |
||
- | 3124 | { |
||
- | 3125 | return; |
||
Line -... | Line 3126... | |||
- | 3126 | } |
||
- | 3127 | |
||
2986 | if (string.IsNullOrEmpty(text)) return; |
3128 | if (_searchCancellationTokenSource != null) |
|
- | 3129 | { |
||
Line 2987... | Line 3130... | |||
2987 | |
3130 | _searchCancellationTokenSource.Cancel(); |
|
2988 | if (_searchCancellationTokenSource != null) _searchCancellationTokenSource.Cancel(); |
3131 | } |
|
2989 | |
3132 | |
|
2990 | _searchCancellationTokenSource = new CancellationTokenSource(); |
3133 | _searchCancellationTokenSource = new CancellationTokenSource(); |
|
2991 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
3134 | _searchCancellationToken = _searchCancellationTokenSource.Token; |
|
Line 2992... | Line 3135... | |||
2992 | _linkedSearchCancellationTokenSource = |
3135 | _linkedSearchCancellationTokenSource = |
|
2993 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
- | ||
2994 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
- | ||
2995 | |
3136 | CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken, _searchCancellationToken); |
|
Line 2996... | Line 3137... | |||
2996 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, |
3137 | _combinedSearchSelectionCancellationToken = _linkedSearchCancellationTokenSource.Token; |
|
2997 | async text => { await BeginSearch(text); }, _formTaskScheduler, |
3138 | |
|
2998 | _combinedSearchSelectionCancellationToken); |
3139 | _searchScheduledContinuation.Schedule(TimeSpan.FromMilliseconds(250), text, async text => { await BeginSearch(text); }, _formTaskScheduler, _combinedSearchSelectionCancellationToken); |
|
- | 3140 | } |
||
- | 3141 | |
||
- | 3142 | private void PreviewFormClosing(object sender, CancelEventArgs e) |
||
Line 2999... | Line 3143... | |||
2999 | } |
3143 | { |
|
3000 | |
3144 | if (_previewForm == null) |
|
3001 | private void PreviewFormClosing(object sender, CancelEventArgs e) |
3145 | { |
|
3002 | { |
3146 | return; |
|
Line 3018... | Line 3162... | |||
3018 | private void openDirectoryToolStripMenuItem_Click(object sender, EventArgs e) |
3162 | private void openDirectoryToolStripMenuItem_Click(object sender, EventArgs e) |
|
3019 | { |
3163 | { |
|
3020 | var items = imageListView.SelectedItems.OfType<ListViewItem>().ToArray(); |
3164 | var items = imageListView.SelectedItems.OfType<ListViewItem>().ToArray(); |
|
Line 3021... | Line 3165... | |||
3021 | |
3165 | |
|
3022 | var item = items.FirstOrDefault(); |
3166 | var item = items.FirstOrDefault(); |
|
- | 3167 | if (item == null) |
||
- | 3168 | { |
||
- | 3169 | return; |
||
Line 3023... | Line 3170... | |||
3023 | if (item == null) return; |
3170 | } |
|
3024 | |
3171 | |
|
Line 3025... | Line 3172... | |||
3025 | Process.Start("explorer.exe", $"/select, \"{item.Name}\""); |
3172 | Process.Start("explorer.exe", $"/select, \"{item.Name}\""); |
|
3026 | } |
3173 | } |
|
3027 | |
3174 | |
|
- | 3175 | private void aboutToolStripMenuItem1_Click(object sender, EventArgs e) |
||
- | 3176 | { |
||
- | 3177 | if (_aboutForm != null) |
||
Line 3028... | Line 3178... | |||
3028 | private void aboutToolStripMenuItem1_Click(object sender, EventArgs e) |
3178 | { |
|
3029 | { |
3179 | return; |
|
3030 | if (_aboutForm != null) return; |
3180 | } |
|
3031 | |
3181 | |
|
Line 3213... | Line 3363... | |||
3213 | return; |
3363 | return; |
|
3214 | } |
3364 | } |
|
Line 3215... | Line 3365... | |||
3215 | |
3365 | |
|
Line 3216... | Line 3366... | |||
3216 | var item = info.Item; |
3366 | var item = info.Item; |
|
- | 3367 | |
||
- | 3368 | if (item == null) |
||
- | 3369 | { |
||
Line 3217... | Line 3370... | |||
3217 | |
3370 | return; |
|
- | 3371 | } |
||
3218 | if (item == null) return; |
3372 | |
|
3219 | |
3373 | if (_previewForm != null) |
|
3220 | if (_previewForm != null) |
3374 | { |
|
3221 | _previewForm.InvokeIfRequired(form => |
3375 | _previewForm.InvokeIfRequired(form => |
|
3222 | { |
3376 | { |
|
- | 3377 | form.Close(); |
||
Line 3223... | Line 3378... | |||
3223 | form.Close(); |
3378 | form = null; |
|
3224 | form = null; |
3379 | }); |
|
3225 | }); |
3380 | } |
|
3226 | |
3381 | |
|
Line 3244... | Line 3399... | |||
3244 | var items = imageListView.SelectedItems.OfType<ListViewItem>(); |
3399 | var items = imageListView.SelectedItems.OfType<ListViewItem>(); |
|
Line 3245... | Line 3400... | |||
3245 | |
3400 | |
|
3246 | SelectTags(items); |
3401 | SelectTags(items); |
|
Line 3247... | Line 3402... | |||
3247 | } |
3402 | } |
|
3248 | |
3403 | |
|
3249 | private async void imageListView_KeyUp(object sender, KeyEventArgs e) |
3404 | private void imageListView_KeyUp(object sender, KeyEventArgs e) |
|
3250 | { |
3405 | { |
|
3251 | var items = imageListView.SelectedItems.OfType<ListViewItem>().ToArray(); |
3406 | var items = imageListView.SelectedItems.OfType<ListViewItem>().ToArray(); |
|
3252 | if (e.KeyCode == Keys.Delete) |
3407 | if (e.KeyCode == Keys.Delete) |
|
3253 | { |
3408 | { |
|
3254 | await RemoveImagesAsync(items, _cancellationToken); |
3409 | RemoveImages(items, _cancellationToken); |
|
Line 3255... | Line 3410... | |||
3255 | return; |
3410 | return; |
|
3256 | } |
3411 | } |
|
Line 3263... | Line 3418... | |||
3263 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
3418 | toolStripProgressBar1.Style = ProgressBarStyle.Continuous; |
|
3264 | toolStripProgressBar1.Minimum = 0; |
3419 | toolStripProgressBar1.Minimum = 0; |
|
3265 | toolStripProgressBar1.Value = 0; |
3420 | toolStripProgressBar1.Value = 0; |
|
3266 | toolStripProgressBar1.Maximum = 3; |
3421 | toolStripProgressBar1.Maximum = 3; |
|
Line 3267... | Line 3422... | |||
3267 | |
3422 | |
|
3268 | var inputBlock = new BufferBlock<ListViewItem>(new DataflowBlockOptions |
- | ||
3269 | { CancellationToken = _cancellationToken }); |
3423 | var inputBlock = new BufferBlock<ListViewItem>(new DataflowBlockOptions { CancellationToken = _cancellationToken }); |
|
3270 | var fileTransformBlock = |
3424 | var fileTransformBlock = |
|
3271 | new TransformBlock<ListViewItem, (string Source, string Path, string Name, string Mime, string Extension |
- | ||
3272 | )>(async item => |
3425 | new TransformBlock<ListViewItem, (string Source, string Path, string Name, string Mime, string Extension)>(async item => |
|
3273 | { |
3426 | { |
|
Line 3274... | Line 3427... | |||
3274 | var mime = await _magicMime.GetMimeType(item.Name, _cancellationToken); |
3427 | var mime = await _magicMime.GetMimeType(item.Name, _cancellationToken); |
|
3275 | |
3428 | |
|
Line 3279... | Line 3432... | |||
3279 | if (Configuration.OutboundDragDrop.RenameOnDragDrop) |
3432 | if (Configuration.OutboundDragDrop.RenameOnDragDrop) |
|
3280 | { |
3433 | { |
|
3281 | switch (Configuration.OutboundDragDrop.DragDropRenameMethod) |
3434 | switch (Configuration.OutboundDragDrop.DragDropRenameMethod) |
|
3282 | { |
3435 | { |
|
3283 | case DragDropRenameMethod.Random: |
3436 | case DragDropRenameMethod.Random: |
|
3284 | file = string.Join("", |
- | ||
3285 | Enumerable.Repeat(0, 5).Select(n => (char)_random.Next('a', 'z' + 1))); |
3437 | file = string.Join("", Enumerable.Repeat(0, 5).Select(n => (char)_random.Next('a', 'z' + 1))); |
|
3286 | break; |
3438 | break; |
|
3287 | case DragDropRenameMethod.Timestamp: |
3439 | case DragDropRenameMethod.Timestamp: |
|
3288 | file = $"{DateTimeOffset.Now.ToUnixTimeSeconds()}"; |
3440 | file = $"{DateTimeOffset.Now.ToUnixTimeSeconds()}"; |
|
3289 | break; |
3441 | break; |
|
3290 | } |
3442 | } |
|
Line 3305... | Line 3457... | |||
3305 | toolStripStatusLabel1.Text = "All files scanned for drag and drop."; |
3457 | toolStripStatusLabel1.Text = "All files scanned for drag and drop."; |
|
3306 | toolStripProgressBar1.Increment(1); |
3458 | toolStripProgressBar1.Increment(1); |
|
3307 | }, _formTaskScheduler); |
3459 | }, _formTaskScheduler); |
|
Line 3308... | Line 3460... | |||
3308 | |
3460 | |
|
3309 | var noConvertTransformBlock = |
3461 | var noConvertTransformBlock = |
|
3310 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>( |
- | ||
3311 | async item => |
3462 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>(async item => |
|
3312 | { |
3463 | { |
|
- | 3464 | var destination = Path.Combine(item.Path, $"{item.Name}{item.Extension}"); |
||
3313 | var destination = Path.Combine(item.Path, $"{item.Name}{item.Extension}"); |
3465 | |
|
Line 3314... | Line 3466... | |||
3314 | await Miscellaneous.CopyFileAsync(item.Source, destination, _cancellationToken); |
3466 | await Miscellaneous.CopyFileAsync(item.Source, destination, _cancellationToken); |
|
3315 | |
3467 | |
|
3316 | this.InvokeIfRequired(form => |
3468 | this.InvokeIfRequired(form => |
|
Line 3328... | Line 3480... | |||
3328 | toolStripStatusLabel1.Text = "Conversion complete for drag and drop."; |
3480 | toolStripStatusLabel1.Text = "Conversion complete for drag and drop."; |
|
3329 | toolStripProgressBar1.Increment(1); |
3481 | toolStripProgressBar1.Increment(1); |
|
3330 | }, _formTaskScheduler); |
3482 | }, _formTaskScheduler); |
|
Line 3331... | Line 3483... | |||
3331 | |
3483 | |
|
3332 | var jpegTransformBlock = |
3484 | var jpegTransformBlock = |
|
3333 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>( |
- | ||
3334 | async file => |
3485 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>(async file => |
|
3335 | { |
3486 | { |
|
3336 | using var imageStream = |
3487 | using var imageStream = |
|
Line 3337... | Line 3488... | |||
3337 | await _imageTool.ConvertTo(file.Source, MagickFormat.Jpeg, _cancellationToken); |
3488 | await _imageTool.ConvertTo(file.Source, MagickFormat.Jpeg, _cancellationToken); |
|
3338 | |
3489 | |
|
3339 | var jpegDestination = Path.Combine(file.Path, $"{file.Name}.jpg"); |
- | ||
Line 3340... | Line 3490... | |||
3340 | await Miscellaneous.CopyFileAsync(imageStream, jpegDestination, |
3490 | var jpegDestination = Path.Combine(file.Path, $"{file.Name}.jpg"); |
|
3341 | _cancellationToken); |
3491 | await Miscellaneous.CopyFileAsync(imageStream, jpegDestination, _cancellationToken); |
|
3342 | |
3492 | |
|
3343 | this.InvokeIfRequired(form => |
3493 | this.InvokeIfRequired(form => |
|
Line 3356... | Line 3506... | |||
3356 | toolStripStatusLabel1.Text = "Conversion complete for drag and drop."; |
3506 | toolStripStatusLabel1.Text = "Conversion complete for drag and drop."; |
|
3357 | toolStripProgressBar1.Increment(1); |
3507 | toolStripProgressBar1.Increment(1); |
|
3358 | }, _formTaskScheduler); |
3508 | }, _formTaskScheduler); |
|
Line 3359... | Line 3509... | |||
3359 | |
3509 | |
|
3360 | var pngTransformBlock = |
3510 | var pngTransformBlock = |
|
3361 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>( |
- | ||
3362 | async file => |
3511 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>(async file => |
|
3363 | { |
- | ||
3364 | using var imageStream = |
3512 | { |
|
Line 3365... | Line 3513... | |||
3365 | await _imageTool.ConvertTo(file.Source, MagickFormat.Png, _cancellationToken); |
3513 | using var imageStream = await _imageTool.ConvertTo(file.Source, MagickFormat.Png, _cancellationToken); |
|
3366 | |
3514 | |
|
Line 3367... | Line 3515... | |||
3367 | var pngDestination = Path.Combine(file.Path, $"{file.Name}.png"); |
3515 | var pngDestination = Path.Combine(file.Path, $"{file.Name}.png"); |
|
Line 3383... | Line 3531... | |||
3383 | toolStripStatusLabel1.Text = "Conversion complete for drag and drop."; |
3531 | toolStripStatusLabel1.Text = "Conversion complete for drag and drop."; |
|
3384 | toolStripProgressBar1.Increment(1); |
3532 | toolStripProgressBar1.Increment(1); |
|
3385 | }, _formTaskScheduler); |
3533 | }, _formTaskScheduler); |
|
Line 3386... | Line 3534... | |||
3386 | |
3534 | |
|
3387 | var bmpTransformBlock = |
3535 | var bmpTransformBlock = |
|
3388 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>( |
- | ||
3389 | async file => |
3536 | new TransformBlock<(string Source, string Path, string Name, string Mime, string Extension), string>( async file => |
|
3390 | { |
- | ||
3391 | using var imageStream = |
3537 | { |
|
Line 3392... | Line 3538... | |||
3392 | await _imageTool.ConvertTo(file.Source, MagickFormat.Jpeg, _cancellationToken); |
3538 | using var imageStream = await _imageTool.ConvertTo(file.Source, MagickFormat.Jpeg, _cancellationToken); |
|
3393 | |
3539 | |
|
Line 3394... | Line 3540... | |||
3394 | var bmpDestination = Path.Combine(file.Path, $"{file.Name}.bmp"); |
3540 | var bmpDestination = Path.Combine(file.Path, $"{file.Name}.bmp"); |
|
Line 3414... | Line 3560... | |||
3414 | var iptcStripTransformBlock = new TransformBlock<string, string>(async file => |
3560 | var iptcStripTransformBlock = new TransformBlock<string, string>(async file => |
|
3415 | { |
3561 | { |
|
3416 | try |
3562 | try |
|
3417 | { |
3563 | { |
|
3418 | var mime = await _magicMime.GetMimeType(file, _cancellationToken); |
3564 | var mime = await _magicMime.GetMimeType(file, _cancellationToken); |
|
3419 | |
- | ||
3420 | if (Configuration.SupportedFormats.IsSupportedVideo(mime)) |
3565 | if (Configuration.SupportedFormats.IsSupportedVideo(mime)) |
|
3421 | { |
3566 | { |
|
3422 | return file; |
3567 | return file; |
|
3423 | } |
3568 | } |
|
Line 3537... | Line 3682... | |||
3537 | await Task.WhenAll( |
3682 | await Task.WhenAll( |
|
3538 | jpegTransformBlock.Completion, |
3683 | jpegTransformBlock.Completion, |
|
3539 | pngTransformBlock.Completion, |
3684 | pngTransformBlock.Completion, |
|
3540 | bmpTransformBlock.Completion, |
3685 | bmpTransformBlock.Completion, |
|
3541 | iptcStripTransformBlock.Completion, |
3686 | iptcStripTransformBlock.Completion, |
|
3542 | noConvertTransformBlock.Completion).ContinueWith(_ => { |
3687 | noConvertTransformBlock.Completion).ContinueWith(_ => |
|
- | 3688 | { |
||
3543 | outputBlock.Complete(); |
3689 | outputBlock.Complete(); |
|
3544 | }, _cancellationToken); |
3690 | }, _cancellationToken); |
|
Line 3545... | Line 3691... | |||
3545 | |
3691 | |
|
3546 | var files = new HashSet<string>(); |
3692 | var files = new HashSet<string>(); |
|
Line 3565... | Line 3711... | |||
3565 | { |
3711 | { |
|
3566 | return; |
3712 | return; |
|
3567 | } |
3713 | } |
|
Line 3568... | Line 3714... | |||
3568 | |
3714 | |
|
3569 | var data = new DataObject(DataFormats.FileDrop, files.ToArray()); |
3715 | var data = new DataObject(DataFormats.FileDrop, files.ToArray()); |
|
- | 3716 | this.InvokeIfRequired(_ => |
||
3570 | this.InvokeIfRequired(_ => { |
3717 | { |
|
3571 | DoDragDrop(data, DragDropEffects.Copy); |
3718 | DoDragDrop(data, DragDropEffects.Copy); |
|
3572 | }); |
3719 | }); |
|
Line 3573... | Line 3720... | |||
3573 | } |
3720 | } |
|
Line 3603... | Line 3750... | |||
3603 | AddToMostRecentlyUsedList = true, |
3750 | AddToMostRecentlyUsedList = true, |
|
3604 | Multiselect = true, |
3751 | Multiselect = true, |
|
3605 | IsFolderPicker = false |
3752 | IsFolderPicker = false |
|
3606 | }; |
3753 | }; |
|
Line -... | Line 3754... | |||
- | 3754 | |
||
- | 3755 | switch (dialog.ShowDialog()) |
||
3607 | |
3756 | { |
|
3608 | if (dialog.ShowDialog() == CommonFileDialogResult.Ok) |
3757 | case CommonFileDialogResult.Ok: |
|
- | 3758 | await LoadFilesAsync(dialog.FileNames, _magicMime, _cancellationToken); |
||
- | 3759 | break; |
||
3609 | await LoadFilesAsync(dialog.FileNames, _magicMime, _cancellationToken); |
3760 | } |
|
Line 3610... | Line 3761... | |||
3610 | } |
3761 | } |
|
3611 | |
3762 | |
|
3612 | private async void importDirectoryToolStripMenuItem_Click(object sender, EventArgs e) |
3763 | private async void importDirectoryToolStripMenuItem_Click(object sender, EventArgs e) |
|
Line 3616... | Line 3767... | |||
3616 | AddToMostRecentlyUsedList = true, |
3767 | AddToMostRecentlyUsedList = true, |
|
3617 | Multiselect = true, |
3768 | Multiselect = true, |
|
3618 | IsFolderPicker = true |
3769 | IsFolderPicker = true |
|
3619 | }; |
3770 | }; |
|
Line -... | Line 3771... | |||
- | 3771 | |
||
- | 3772 | switch (dialog.ShowDialog()) |
||
3620 | |
3773 | { |
|
3621 | if (dialog.ShowDialog() == CommonFileDialogResult.Ok) |
3774 | case CommonFileDialogResult.Ok: |
|
- | 3775 | await LoadFilesAsync(dialog.FileNames, _magicMime, _cancellationToken); |
||
- | 3776 | break; |
||
3622 | await LoadFilesAsync(dialog.FileNames, _magicMime, _cancellationToken); |
3777 | } |
|
Line 3623... | Line 3778... | |||
3623 | } |
3778 | } |
|
3624 | |
3779 | |
|
3625 | private void settingsToolStripMenuItem_Click(object sender, EventArgs e) |
3780 | private void settingsToolStripMenuItem_Click(object sender, EventArgs e) |
|
- | 3781 | { |
||
- | 3782 | if (_settingsForm != null) |
||
- | 3783 | { |
||
Line 3626... | Line 3784... | |||
3626 | { |
3784 | return; |
|
3627 | if (_settingsForm != null) return; |
3785 | } |
|
3628 | |
3786 | |
|
3629 | _settingsForm = new SettingsForm(Configuration, _cancellationToken); |
3787 | _settingsForm = new SettingsForm(Configuration, _cancellationToken); |
|
Line 3630... | Line 3788... | |||
3630 | _settingsForm.Closing += SettingsForm_Closing; |
3788 | _settingsForm.Closing += SettingsForm_Closing; |
|
3631 | _settingsForm.Show(); |
3789 | _settingsForm.Show(); |
|
3632 | } |
3790 | } |
|
- | 3791 | |
||
- | 3792 | private void SettingsForm_Closing(object sender, CancelEventArgs e) |
||
- | 3793 | { |
||
Line 3633... | Line 3794... | |||
3633 | |
3794 | if (_settingsForm == null) |
|
- | 3795 | { |
||
3634 | private void SettingsForm_Closing(object sender, CancelEventArgs e) |
3796 | return; |
|
3635 | { |
3797 | } |
|
3636 | if (_settingsForm == null) return; |
3798 | |
|
- | 3799 | if (_settingsForm.SaveOnClose) |
||
Line 3637... | Line 3800... | |||
3637 | |
3800 | { |
|
3638 | if (_settingsForm.SaveOnClose) |
3801 | // Commit the configuration. |
|
3639 | // Commit the configuration. |
3802 | _changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1), |
|
3640 | _changedConfigurationContinuation.Schedule(TimeSpan.FromSeconds(1), |
3803 | async () => { await SaveConfiguration(Configuration); }, _cancellationToken); |
|
Line 3705... | Line 3868... | |||
3705 | private async void balanceTagsToolStripMenuItem_Click(object sender, EventArgs e) |
3868 | private async void balanceTagsToolStripMenuItem_Click(object sender, EventArgs e) |
|
3706 | { |
3869 | { |
|
3707 | var items = imageListView.SelectedItems.OfType<ListViewItem>(); |
3870 | var items = imageListView.SelectedItems.OfType<ListViewItem>(); |
|
Line 3708... | Line 3871... | |||
3708 | |
3871 | |
|
3709 | var listViewItems = items as ListViewItem[] ?? items.ToArray(); |
3872 | var listViewItems = items as ListViewItem[] ?? items.ToArray(); |
|
- | 3873 | if (listViewItems.Length < 2) |
||
- | 3874 | { |
||
- | 3875 | return; |
||
Line 3710... | Line 3876... | |||
3710 | if (listViewItems.Length < 2) return; |
3876 | } |
|
3711 | |
3877 | |
|
Line 3712... | Line 3878... | |||
3712 | await BalanceTags(listViewItems); |
3878 | await BalanceTags(listViewItems); |
|
Line 3725... | Line 3891... | |||
3725 | { |
3891 | { |
|
3726 | var menuItem = (ToolStripMenuItem)sender; |
3892 | var menuItem = (ToolStripMenuItem)sender; |
|
Line 3727... | Line 3893... | |||
3727 | |
3893 | |
|
3728 | foreach (var group in _imageListViewGroupDictionary.Keys) |
3894 | foreach (var group in _imageListViewGroupDictionary.Keys) |
|
3729 | { |
3895 | { |
|
- | 3896 | if (menuItem.DropDownItems.ContainsKey(group)) |
||
- | 3897 | { |
||
- | 3898 | continue; |
||
Line 3730... | Line 3899... | |||
3730 | if (menuItem.DropDownItems.ContainsKey(group)) continue; |
3899 | } |
|
3731 | |
3900 | |
|
3732 | var toolStripMenuSubItem = new ToolStripButton(group) { Name = group }; |
3901 | var toolStripMenuSubItem = new ToolStripButton(group) { Name = group }; |
|
3733 | toolStripMenuSubItem.Click += moveTargetToolStripMenuItem_Click; |
3902 | toolStripMenuSubItem.Click += moveTargetToolStripMenuItem_Click; |
|
- | 3903 | menuItem.DropDownItems.Add(toolStripMenuSubItem); |
||
- | 3904 | } |
||
- | 3905 | } |
||
- | 3906 | |
||
- | 3907 | private void moveToolStripMenuItem_DropDownClosed(object sender, EventArgs e) |
||
- | 3908 | { |
||
- | 3909 | var menuItem = (ToolStripMenuItem)sender; |
||
- | 3910 | |
||
- | 3911 | var items = new ConcurrentBag<ToolStripButton>(); |
||
- | 3912 | foreach(var toolStripMenuSubItem in menuItem.DropDownItems.OfType<ToolStripButton>()) |
||
- | 3913 | { |
||
- | 3914 | toolStripMenuSubItem.Click -= moveTargetToolStripMenuItem_Click; |
||
- | 3915 | |
||
- | 3916 | items.Add(toolStripMenuSubItem); |
||
- | 3917 | } |
||
- | 3918 | |
||
- | 3919 | foreach(var toolStripMenuSubItem in items) |
||
- | 3920 | { |
||
3734 | menuItem.DropDownItems.Add(toolStripMenuSubItem); |
3921 | menuItem.DropDownItems.Remove(toolStripMenuSubItem); |
|
Line 3735... | Line 3922... | |||
3735 | } |
3922 | } |
|
3736 | } |
3923 | } |
|
3737 | |
3924 | |
|
Line 3769... | Line 3956... | |||
3769 | { "png", "image/png" }, |
3956 | { "png", "image/png" }, |
|
3770 | { "bmp", "image/bmp" }, |
3957 | { "bmp", "image/bmp" }, |
|
3771 | { "gif", "image/gif" } |
3958 | { "gif", "image/gif" } |
|
3772 | }; |
3959 | }; |
|
Line 3773... | Line 3960... | |||
3773 | |
3960 | |
|
- | 3961 | if (!Configuration.SupportedFormats.Images.Image.Contains(extensionToMime[extension])) |
||
- | 3962 | { |
||
- | 3963 | return; |
||
Line 3774... | Line 3964... | |||
3774 | if (!Configuration.SupportedFormats.Images.Image.Contains(extensionToMime[extension])) return; |
3964 | } |
|
Line 3775... | Line 3965... | |||
3775 | |
3965 | |
|
3776 | var items = imageListView.SelectedItems.OfType<ListViewItem>(); |
3966 | var items = imageListView.SelectedItems.OfType<ListViewItem>(); |