/// <summary> /// Handles the Created event of the PhotoFolderWatcher control. /// In turn, it fires the PhotoAdded event. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="FileSystemEventArgs"/> instance containing the event data.</param> private void PhotoFolderWatcher_Created(object sender, FileSystemEventArgs e) { // First, check if the filename is formatted as a valid Guid. Guid uuid; try { uuid = new Guid(Path.GetFileNameWithoutExtension(e.Name)); } catch (Exception) { return; } // Check the file extension. Now it only supports jpg or jpeg. string ext = Path.GetExtension(e.Name).ToLower(); if (ext != ".jpg" && ext != ".jpeg") { return; } // Second, check if the added file size is greater than zero. // If this is zero-sized, then it is very likely that a subsequent change event is fired very soon. FileInfo finfo = new FileInfo(e.FullPath); if (finfo.Length == 0) { return; } this.StopDeletionTimer(this.PhotoDeletionTimers, uuid); if (this.PhotoAdded != null) { EntryEventArgs eea = new EntryEventArgs(e, ChangeType.PhotoAdded); if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired) { this.SynchronizingObject.Invoke(new Action(delegate() { this.PhotoAdded(this, eea); }), null); } else { this.PhotoAdded(this, eea); } } }
/// <summary> /// Handles the Changed event of the PhotoFolderWatcher control. /// In turn, it fires the PhotoChanged event. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="FileSystemEventArgs"/> instance containing the event data.</param> private void PhotoFolderWatcher_Changed(object sender, FileSystemEventArgs e) { // First, check if the filename is formatted as a valid Guid. Guid uuid; try { uuid = new Guid(Path.GetFileNameWithoutExtension(e.Name)); } catch (Exception) { return; } // Check the file extension. Now it only supports jpg or jpeg. string ext = Path.GetExtension(e.Name).ToLower(); if (ext != ".jpg" && ext != ".jpeg") { return; } this.StopDeletionTimer(this.PhotoDeletionTimers, uuid); if (this.PhotoChanged != null) { EntryEventArgs eea = new EntryEventArgs(e, ChangeType.PhotoChanged); if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired) { this.SynchronizingObject.Invoke(new Action(delegate() { this.PhotoChanged(this, eea); }), null); } else { this.PhotoChanged(this, eea); } } }
/// <summary> /// Handles the Changed event of the EntryFolderWatcher control. /// In turn, it fires the EntryChanged event. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="FileSystemEventArgs"/> instance containing the event data.</param> private void EntryFolderWatcher_Changed(object sender, FileSystemEventArgs e) { // First, check if the filename is formatted as a valid Guid. Guid uuid; try { uuid = new Guid(Path.GetFileNameWithoutExtension(e.Name)); } catch (Exception) { return; } // Second, see if the entry is parsable. Entry entry = null; try { entry = Entry.LoadFromFile(e.FullPath, null, true); } catch (Exception) { return; } this.StopDeletionTimer(this.EntryDeletionTimers, uuid); if (this.EntryChanged != null) { EntryEventArgs eea = new EntryEventArgs(e, ChangeType.EntryChanged); if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired) { this.SynchronizingObject.Invoke(new Action(delegate() { this.EntryChanged(this, eea); }), null); } else { this.EntryChanged(this, eea); } } }
/// <summary> /// Fires the deleted. /// </summary> /// <param name="uuid">The UUID of the entry (or photo).</param> /// <param name="fullPath">The full path of the deleted file.</param> /// <param name="handler">The handler.</param> /// <param name="type">The change type.</param> private void FireDeleted(Guid uuid, string fullPath, EntryEventHandler handler, ChangeType type) { // Fire the event. if (handler != null) { EntryEventArgs e = new EntryEventArgs(uuid, fullPath, type); if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired) { this.SynchronizingObject.Invoke(new Action(delegate() { handler(this, e); }), null); } else { handler(this, e); } } // Delete the timer object from the dictionary. if (this.EntryDeletionTimers.ContainsKey(uuid)) { this.EntryDeletionTimers[uuid].Dispose(); this.EntryDeletionTimers.Remove(uuid); } }
/// <summary> /// Handles the PhotoDeleted event of the Watcher control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EntryEventArgs"/> instance containing the event data.</param> private void Watcher_PhotoDeleted(object sender, EntryEventArgs e) { // Ignore this event, in case the associated entry does not exist in the current database. if (!this.Entries.ContainsKey(e.UUID)) { return; } Entry entry = this.Entries[e.UUID]; entry.PhotoPath = null; // Update the UIs related to photo. if (this.SelectedEntry == entry) { this.UpdatePhotoUIs(); // Reset the auto save timer. if (this.IsEditing) { this.AutoSaveTimer.Stop(); this.AutoSaveTimer.Start(); } } else { this.InvalidateEntryInEntryList(entry); } }
/// <summary> /// Handles the EntryDeleted event of the Watcher control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EntryEventArgs"/> instance containing the event data.</param> private void Watcher_EntryDeleted(object sender, EntryEventArgs e) { // See if the UUID exists in the database at all. if (!this.Entries.ContainsKey(e.UUID)) { // Do nothing. return; } // See if this entry is being edited in the current window. if (this.IsEditing && this.SelectedEntry.UUID == e.UUID) { // Stop the auto save timer here. this.AutoSaveTimer.Stop(); string message = "The current entry has been deleted outside Journaley.\n" + "Would you like to delete the entry?\n" + "(If you do, you will lose your local changes to this entry)"; // Ask if the user wants to delete this entry, or keep it. DialogResult result = MessageBox.Show( message, "Deletion detected", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (result == DialogResult.No) { // Re-enable the auto save timer. this.AutoSaveTimer.Start(); return; } // Here, cancel the edit mode, and remove the entry. this.IsEditing = false; } // Select next entry. if (this.SelectedEntry != null && this.SelectedEntry.UUID == e.UUID) { this.RemoveSelectedAndSelectNext(); } else if (this.Entries.ContainsKey(e.UUID)) { this.Entries.Remove(e.UUID); } else { return; } this.UpdateFromScratch(); }
/// <summary> /// Handles the EntryChanged event of the Watcher control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EntryEventArgs"/> instance containing the event data.</param> private void Watcher_EntryChanged(object sender, EntryEventArgs e) { Entry newEntry = Entry.LoadFromFile(e.FullPath, this.Settings); // See if this entry is being edited in the current window. if (this.IsEditing && this.SelectedEntry.UUID == e.UUID) { // Stop the auto save timer here. this.AutoSaveTimer.Stop(); string message = "The current entry has been changed outside Journaley.\n" + "Would you like to reload the entry?\n" + "(If you do, you will lose your local changes to this entry)"; // Ask if the user wants to reload the entry, or keep the current version. DialogResult result = MessageBox.Show( message, "Change detected", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (result == DialogResult.No) { // Re-enable the auto save timer. this.AutoSaveTimer.Start(); return; } // Here, cancel the edit mode, replace the entry, and replace the selected entry as well. this.IsEditing = false; } // If there was an existing entry with the same ID if (this.Entries.ContainsKey(e.UUID)) { Entry oldEntry = this.Entries[e.UUID]; this.Entries[e.UUID] = newEntry; // If the local time remains unchanged, just invalidate the item in the entry list. // Otherwise, just refresh the entire list. if (oldEntry.LocalTime == newEntry.LocalTime) { foreach (var entryList in this.GetAllEntryLists()) { int oldIndex = entryList.Items.IndexOf(oldEntry); if (oldIndex >= 0) { entryList.Items[oldIndex] = newEntry; } } this.InvalidateEntryInEntryList(newEntry); } else { this.UpdateAllEntryLists(); } } else { int prevTopIndex = this.GetActiveEntryList().TopIndex; this.Entries.Add(e.UUID, newEntry); this.UpdateAllEntryLists(); this.GetActiveEntryList().TopIndex = prevTopIndex; } if (this.SelectedEntry != null && this.SelectedEntry.UUID == e.UUID) { this.SelectedEntry = newEntry; } }