private void SetSample(int number = 1) { Enumerable.Range(0, number) .Select(x => (1 < number) ? x.ToString(CultureInfo.InvariantCulture) : string.Empty) .Select(x => new FileItemViewModel($"/DCIM,SAMPLE{x}.JPG,0,0,0,0", "/DCIM")) .ToList() .ForEach(x => FileListCore.Insert(x)); }
private void CheckFileListCoreViewThumbnail() { if (IsChecking) { return; } isFileListCoreViewThumbnailFilled = FileListCore .Where(x => x.IsTarget && (x.Size != 0)) .All(x => x.HasThumbnail || (!(x.IsAliveRemote && x.CanGetThumbnailRemote) && !(x.IsAliveLocal && x.CanLoadDataLocal))); }
public MainWindowViewModel() { // Set samples. FileListCore.Insert(GetSampleFileData(0)); // Add event listeners. if (!Designer.IsInDesignMode) // AddListener source may be null in Design mode. { fileListPropertyChangedListener = new PropertyChangedEventListener(FileListPropertyChanged); PropertyChangedEventManager.AddListener(FileListCore, fileListPropertyChangedListener, String.Empty); settingsPropertyChangedListener = new PropertyChangedEventListener(ReactSettingsPropertyChanged); PropertyChangedEventManager.AddListener(Settings.Current, settingsPropertyChangedListener, String.Empty); operationPropertyChangedListener = new PropertyChangedEventListener(ReactOperationPropertyChanged); PropertyChangedEventManager.AddListener(Op, operationPropertyChangedListener, String.Empty); } // Subscribe event handlers. var currentFrameSizeChangedSubscriber = Observable.FromEvent ( handler => CurrentFrameSizeChanged += handler, handler => CurrentFrameSizeChanged -= handler ) .Throttle(TimeSpan.FromMilliseconds(50)) .ObserveOn(SynchronizationContext.Current) .Subscribe(_ => SetCurrentImage()); var autoCheckIntervalChangedSubscriber = Observable.FromEvent ( handler => AutoCheckChanged += handler, handler => AutoCheckChanged -= handler ) .Throttle(TimeSpan.FromMilliseconds(200)) .ObserveOn(SynchronizationContext.Current) .Subscribe(_ => Op.ResetAutoTimer()); var targetPeriodDatesChangedSubscriber = Observable.FromEvent ( handler => TargetDateChanged += handler, handler => TargetDateChanged -= handler ) .Throttle(TimeSpan.FromMilliseconds(200)) .ObserveOn(SynchronizationContext.Current) .Subscribe(_ => FileListCoreView.Refresh()); }
/// <summary> /// Checks files in FlashAir card. /// </summary> private async Task CheckFileBaseAsync() { OperationStatus = Resources.OperationStatus_Checking; try { using (var manager = new FileManager()) { _tokenSourceWorking = new CancellationTokenSourcePlus(); // Check firmware version. _card.FirmwareVersion = await manager.GetFirmwareVersionAsync(_tokenSourceWorking.Token); // Check CID. if (_card.CanGetCid) { _card.Cid = await manager.GetCidAsync(_tokenSourceWorking.Token); } // Check SSID and check if PC is connected to FlashAir card by a wireless connection. _card.Ssid = await manager.GetSsidAsync(_tokenSourceWorking.Token); _card.IsWirelessConnected = NetworkChecker.IsWirelessNetworkConnected(_card.Ssid); // Get all items. var fileListNew = (await manager.GetFileListRootAsync(_card, _tokenSourceWorking.Token)) .Select(fileItem => new FileItemViewModel(fileItem)) .ToList(); fileListNew.Sort(); // Record time stamp of write event. if (_card.CanGetWriteTimeStamp) { _card.WriteTimeStamp = await manager.GetWriteTimeStampAsync(_tokenSourceWorking.Token); } await Task.Run(() => { // Check if any sample is in old items. var isSample = FileListCore.Any(x => x.Size == 0); // Check if FlashAir card is changed. bool isChanged; if (_card.IsChanged.HasValue) { isChanged = _card.IsChanged.Value; } else { var signaturesOld = new HashSet <string>(FileListCore.Select(x => x.Signature)); isChanged = !fileListNew.Select(x => x.Signature).Any(x => signaturesOld.Contains(x)); } if (isSample || isChanged) { FileListCore.Clear(); } // Check old items. foreach (var itemOld in FileListCore) { var itemSameIndex = fileListNew.IndexOf(x => x.FilePath.Equals(itemOld.FilePath, StringComparison.OrdinalIgnoreCase) && (x.Size == itemOld.Size)); if (itemSameIndex >= 0) { itemOld.IsAliveRemote = true; itemOld.FileItem = fileListNew[itemSameIndex].FileItem; fileListNew.RemoveAt(itemSameIndex); continue; } itemOld.IsAliveRemote = false; } // Add new items (This operation may be heavy). var isLeadOff = true; foreach (var itemNew in fileListNew) { if (isLeadOff) { InvokeSafely(() => FileListCoreViewIndex = FileListCoreView.IndexOf(itemNew)); isLeadOff = false; } itemNew.IsAliveRemote = true; FileListCore.Insert(itemNew); // Customized Insert method } // Check all local files. foreach (var item in FileListCore) { var info = GetFileInfoLocal(item); item.IsAliveLocal = IsAliveLocal(info, item.Size); item.IsAvailableLocal = IsAvailableLocal(info); item.Status = item.IsAliveLocal ? FileStatus.Copied : FileStatus.NotCopied; } // Manage deleted items. var itemDeletedPairs = FileListCore .Select((x, Index) => !x.IsAliveRemote ? new { Item = x, Index } : null) .Where(x => x != null) .OrderByDescending(x => x.Index) .ToArray(); foreach (var itemDeletedPair in itemDeletedPairs) { var item = itemDeletedPair.Item; if (Settings.Current.MovesFileToRecycle && item.IsDescendant && (item.Status == FileStatus.Copied)) { try { Recycle.MoveToRecycle(ComposeLocalPath(item)); item.Status = FileStatus.Recycled; } catch (Exception ex) { Debug.WriteLine($"Failed to move a file to Recycle.\r\n{ex}"); item.Status = FileStatus.NotCopied; } } if (!item.IsDescendant || ((item.Status != FileStatus.Copied) && (item.Status != FileStatus.Recycled))) { FileListCore.RemoveAt(itemDeletedPair.Index); } } }); // Get thumbnails (from local). foreach (var item in FileListCore.Where(x => x.IsTarget && !x.HasThumbnail)) { if (!item.IsAliveLocal || !item.IsAvailableLocal || !item.CanLoadDataLocal) { continue; } _tokenSourceWorking.Token.ThrowIfCancellationRequested(); try { if (item.CanReadExif) { item.Thumbnail = await ImageManager.ReadThumbnailAsync(ComposeLocalPath(item)); } else if (item.CanLoadDataLocal) { item.Thumbnail = await ImageManager.CreateThumbnailAsync(ComposeLocalPath(item)); } } catch (FileNotFoundException) { item.Status = FileStatus.NotCopied; item.IsAliveLocal = false; } catch (IOException) { item.IsAvailableLocal = false; } catch (ImageNotSupportedException) { item.CanLoadDataLocal = false; } } // Get thumbnails (from remote). foreach (var item in FileListCore.Where(x => x.IsTarget && !x.HasThumbnail)) { if (!item.IsAliveRemote || !item.CanGetThumbnailRemote) { continue; } _tokenSourceWorking.Token.ThrowIfCancellationRequested(); try { item.Thumbnail = await manager.GetThumbnailAsync(item.FilePath, _card, _tokenSourceWorking.Token); } catch (RemoteFileThumbnailFailedException) { item.CanGetThumbnailRemote = false; } } } OperationStatus = Resources.OperationStatus_CheckCompleted; } finally { FileListCoreViewIndex = -1; // No selection _tokenSourceWorking?.Dispose(); } }
/// <summary> /// Copies files from FlashAir card. /// </summary> /// <param name="progress">Progress</param> private async Task CopyFileBaseAsync(IProgress <ProgressInfo> progress) { CopyStartTime = DateTime.Now; _copyFileCount = 0; if (!FileListCore.Any(x => x.IsTarget && (x.Status == FileStatus.ToBeCopied))) { OperationStatus = Resources.OperationStatus_NoFileToBeCopied; return; } OperationStatus = Resources.OperationStatus_Copying; try { using (var manager = new FileManager()) { _tokenSourceWorking = new CancellationTokenSourcePlus(); // Check CID. if (_card.CanGetCid) { if (await manager.GetCidAsync(_tokenSourceWorking.Token) != _card.Cid) { throw new CardChangedException(); } } // Check if upload.cgi is disabled. if (Settings.Current.DeleteOnCopy && _card.CanGetUpload) { _card.Upload = await manager.GetUploadAsync(_tokenSourceWorking.Token); if (_card.IsUploadDisabled) { throw new CardUploadDisabledException(); } } while (true) { var item = FileListCore.FirstOrDefault(x => x.IsTarget && (x.Status == FileStatus.ToBeCopied)); if (item == null) { break; // Copy completed. } _tokenSourceWorking.Token.ThrowIfCancellationRequested(); try { item.Status = FileStatus.Copying; FileListCoreViewIndex = FileListCoreView.IndexOf(item); var localPath = ComposeLocalPath(item); var localDirectory = Path.GetDirectoryName(localPath); if (!string.IsNullOrEmpty(localDirectory) && !Directory.Exists(localDirectory)) { Directory.CreateDirectory(localDirectory); } var data = await manager.GetSaveFileAsync(item.FilePath, localPath, item.Size, item.Date, item.CanReadExif, progress, _card, _tokenSourceWorking.Token); CurrentItem = item; CurrentImageData = data; if (!item.HasThumbnail) { try { if (item.CanReadExif) { item.Thumbnail = await ImageManager.ReadThumbnailAsync(CurrentImageData); } else if (item.CanLoadDataLocal) { item.Thumbnail = await ImageManager.CreateThumbnailAsync(CurrentImageData); } } catch (ImageNotSupportedException) { item.CanLoadDataLocal = false; } } item.CopiedTime = DateTime.Now; item.IsAliveLocal = true; item.IsAvailableLocal = true; item.Status = FileStatus.Copied; _copyFileCount++; } catch (RemoteFileNotFoundException) { item.IsAliveRemote = false; } catch (RemoteFileInvalidException) { item.Status = FileStatus.Weird; } catch { item.Status = FileStatus.ToBeCopied; // Revert to status before copying. throw; } if (Settings.Current.DeleteOnCopy && !item.IsReadOnly && IsAliveLocal(item)) { await manager.DeleteFileAsync(item.FilePath, _tokenSourceWorking.Token); } } } OperationStatus = string.Format(Resources.OperationStatus_CopyCompleted, _copyFileCount, (int)(DateTime.Now - CopyStartTime).TotalSeconds); } finally { FileListCoreViewIndex = -1; // No selection _tokenSourceWorking?.Dispose(); } }
/// <summary> /// Check files in FlashAir card. /// </summary> private async Task CheckFileBaseAsync() { OperationStatus = Resources.OperationStatus_Checking; try { tokenSourceWorking = new CancellationTokenSource(); isTokenSourceWorkingDisposed = false; // Check firmware version. card.FirmwareVersion = await FileManager.GetFirmwareVersionAsync(tokenSourceWorking.Token); // Check CID. if (card.CanGetCid) { card.Cid = await FileManager.GetCidAsync(tokenSourceWorking.Token); } // Check SSID. card.Ssid = await FileManager.GetSsidAsync(tokenSourceWorking.Token); if (!String.IsNullOrWhiteSpace(card.Ssid)) { // Check if PC is connected to FlashAir card by wireless network. var checkTask = Task.Run(async() => card.IsWirelessConnected = await NetworkChecker.IsWirelessNetworkConnectedAsync(card.Ssid)); } // Get all items. var fileListNew = await FileManager.GetFileListRootAsync(tokenSourceWorking.Token, card); fileListNew.Sort(); // Record time stamp of write event. if (card.CanGetWriteTimeStamp) { card.WriteTimeStamp = await FileManager.GetWriteTimeStampAsync(tokenSourceWorking.Token); } // Check if any sample is in old items. var isSample = FileListCore.Any(x => x.Size == 0); // Check if FlashAir card is changed. bool isChanged; if (card.IsChanged.HasValue) { isChanged = card.IsChanged.Value; } else { var signatures = FileListCore.Select(x => x.Signature).ToArray(); isChanged = !fileListNew.Select(x => x.Signature).Any(x => signatures.Contains(x)); } if (isSample || isChanged) { FileListCore.Clear(); } // Check old items. foreach (var itemOld in FileListCore) { var itemBuff = fileListNew.FirstOrDefault(x => x.FilePath == itemOld.FilePath); if ((itemBuff != null) && (itemBuff.Size == itemOld.Size)) { fileListNew.Remove(itemBuff); itemOld.IsAliveRemote = true; itemOld.IsAliveLocal = IsCopiedLocal(itemOld); itemOld.Status = itemOld.IsAliveLocal ? FileStatus.Copied : FileStatus.NotCopied; continue; } itemOld.IsAliveRemote = false; } // Add new items. var isLeadOff = true; foreach (var itemNew in fileListNew) { if (isLeadOff) { FileListCoreViewIndex = FileListCoreView.IndexOf(itemNew); isLeadOff = false; } itemNew.IsAliveRemote = true; itemNew.IsAliveLocal = IsCopiedLocal(itemNew); itemNew.Status = itemNew.IsAliveLocal ? FileStatus.Copied : FileStatus.NotCopied; FileListCore.Insert(itemNew); // Customized Insert method } // Manage deleted items. var itemsDeleted = FileListCore.Where(x => !x.IsAliveRemote && (x.Status != FileStatus.Recycled)).ToArray(); if (itemsDeleted.Any()) { if (Settings.Current.MovesFileToRecycle) { var itemsDeletedCopied = itemsDeleted.Where(x => x.Status == FileStatus.Copied).ToList(); Recycle.MoveToRecycle(itemsDeletedCopied.Select(ComposeLocalPath)); itemsDeletedCopied.ForEach(x => x.Status = FileStatus.Recycled); } for (int i = itemsDeleted.Length - 1; i >= 0; i--) { if ((itemsDeleted[i].Status == FileStatus.Copied) || (itemsDeleted[i].Status == FileStatus.Recycled)) { continue; } FileListCore.Remove(itemsDeleted[i]); } } // Get thumbnails (from local). foreach (var item in FileListCore) { if (!item.IsTarget || item.HasThumbnail || (item.Status != FileStatus.Copied) || !item.IsAliveLocal || !item.CanLoadDataLocal) { continue; } tokenSourceWorking.Token.ThrowIfCancellationRequested(); try { if (item.CanReadExif) { item.Thumbnail = await ImageManager.ReadThumbnailAsync(ComposeLocalPath(item)); } else if (item.CanLoadDataLocal) { item.Thumbnail = await ImageManager.CreateThumbnailAsync(ComposeLocalPath(item)); } } catch (FileNotFoundException) { item.Status = FileStatus.NotCopied; item.IsAliveLocal = false; } catch (IOException) { item.CanLoadDataLocal = false; } catch (ImageNotSupportedException) { item.CanLoadDataLocal = false; } } // Get thumbnails (from remote). foreach (var item in FileListCore) { if (!item.IsTarget || item.HasThumbnail || (item.Status == FileStatus.Copied) || !item.IsAliveRemote || !item.CanGetThumbnailRemote) { continue; } if (!card.CanGetThumbnail) { continue; } tokenSourceWorking.Token.ThrowIfCancellationRequested(); try { item.Thumbnail = await FileManager.GetThumbnailAsync(item.FilePath, tokenSourceWorking.Token, card); } catch (RemoteFileThumbnailFailedException) { item.CanGetThumbnailRemote = false; card.ThumbnailFailedPath = item.FilePath; } } OperationStatus = Resources.OperationStatus_CheckCompleted; } finally { FileListCoreViewIndex = -1; // No selection if (tokenSourceWorking != null) { isTokenSourceWorkingDisposed = true; tokenSourceWorking.Dispose(); } } }