public static void SyncNote(NoteMatch match, Syncronizer sync) { Outlook.NoteItem outlookNoteItem = match.OutlookNote; //try //{ if (match.GoogleNote == null && match.OutlookNote != null) { //no google note string googleNotetId = NotePropertiesUtils.GetOutlookGoogleNoteId(sync, outlookNoteItem); if (!string.IsNullOrEmpty(googleNotetId)) { //Redundant check if exist, but in case an error occurred in MatchNotes Document matchingGoogleNote = sync.GetGoogleNoteById(googleNotetId); if (matchingGoogleNote == null) { if (!sync.PromptDelete) { sync.DeleteOutlookResolution = DeleteResolution.DeleteOutlookAlways; } else if (sync.DeleteOutlookResolution != DeleteResolution.DeleteOutlookAlways && sync.DeleteOutlookResolution != DeleteResolution.KeepOutlookAlways) { var r = new ConflictResolver(); sync.DeleteOutlookResolution = r.ResolveDelete(match.OutlookNote); } } switch (sync.DeleteOutlookResolution) { case DeleteResolution.KeepOutlook: case DeleteResolution.KeepOutlookAlways: NotePropertiesUtils.ResetOutlookGoogleNoteId(sync, match.OutlookNote); break; case DeleteResolution.DeleteOutlook: case DeleteResolution.DeleteOutlookAlways: //Avoid recreating a GoogleNote already existing //==> Delete this outlookNote instead if previous match existed but no match exists anymore return; default: throw new ApplicationException("Cancelled"); } } if (sync.SyncOption == SyncOption.GoogleToOutlookOnly) { sync.SkippedCount++; Logger.Log(string.Format("Outlook Note not added to Google, because of SyncOption " + sync.SyncOption.ToString() + ": {0}", match.OutlookNote.Subject), EventType.Information); return; } //create a Google note from Outlook note match.GoogleNote = new Document(); match.GoogleNote.Type = Document.DocumentType.Document; //match.GoogleNote.Categories.Add(new AtomCategory("http://schemas.google.com/docs/2007#document")); //match.GoogleNote.Categories.Add(new AtomCategory("document")); sync.UpdateNote(outlookNoteItem, match.GoogleNote); } else if (match.OutlookNote == null && match.GoogleNote != null) { // no outlook note if (NotePropertiesUtils.NoteFileExists(match.GoogleNote.Id, sync.SyncProfile)) { if (!sync.PromptDelete) { sync.DeleteGoogleResolution = DeleteResolution.DeleteGoogleAlways; } else if (sync.DeleteGoogleResolution != DeleteResolution.DeleteGoogleAlways && sync.DeleteGoogleResolution != DeleteResolution.KeepGoogleAlways) { var r = new ConflictResolver(); sync.DeleteGoogleResolution = r.ResolveDelete(match.GoogleNote, sync); } switch (sync.DeleteGoogleResolution) { case DeleteResolution.KeepGoogle: case DeleteResolution.KeepGoogleAlways: System.IO.File.Delete(NotePropertiesUtils.GetFileName(match.GoogleNote.Id, sync.SyncProfile)); break; case DeleteResolution.DeleteGoogle: case DeleteResolution.DeleteGoogleAlways: //Avoid recreating a OutlookNote already existing //==> Delete this googleNote instead if previous match existed but no match exists anymore return; default: throw new ApplicationException("Cancelled"); } } if (sync.SyncOption == SyncOption.OutlookToGoogleOnly) { sync.SkippedCount++; Logger.Log(string.Format("Google Note not added to Outlook, because of SyncOption " + sync.SyncOption.ToString() + ": {0}", match.GoogleNote.Title), EventType.Information); return; } //create a Outlook note from Google note outlookNoteItem = Syncronizer.CreateOutlookNoteItem(Syncronizer.SyncNotesFolder); sync.UpdateNote(match.GoogleNote, outlookNoteItem); match.OutlookNote = outlookNoteItem; } else if (match.OutlookNote != null && match.GoogleNote != null) { //merge note details //determine if this note pair were syncronized //DateTime? lastUpdated = GetOutlookPropertyValueDateTime(match.OutlookNote, sync.OutlookPropertyNameUpdated); DateTime?lastSynced = NotePropertiesUtils.GetOutlookLastSync(sync, outlookNoteItem); if (lastSynced.HasValue) { //note pair was syncronysed before. //determine if google note was updated since last sync //lastSynced is stored without seconds. take that into account. DateTime lastUpdatedOutlook = match.OutlookNote.LastModificationTime.AddSeconds(-match.OutlookNote.LastModificationTime.Second); DateTime lastUpdatedGoogle = match.GoogleNote.Updated.AddSeconds(-match.GoogleNote.Updated.Second); //check if both outlok and google notes where updated sync last sync if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance && lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance) { //both notes were updated. //options: 1) ignore 2) loose one based on SyncOption //throw new Exception("Both notes were updated!"); switch (sync.SyncOption) { case SyncOption.MergeOutlookWins: case SyncOption.OutlookToGoogleOnly: //overwrite google note Logger.Log("Outlook and Google note have been updated, Outlook note is overwriting Google because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information); sync.UpdateNote(outlookNoteItem, match.GoogleNote); break; case SyncOption.MergeGoogleWins: case SyncOption.GoogleToOutlookOnly: //overwrite outlook note Logger.Log("Outlook and Google note have been updated, Google note is overwriting Outlook because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information); sync.UpdateNote(match.GoogleNote, outlookNoteItem); break; case SyncOption.MergePrompt: //promp for sync option if (sync.ConflictResolution != ConflictResolution.GoogleWinsAlways && sync.ConflictResolution != ConflictResolution.OutlookWinsAlways && sync.ConflictResolution != ConflictResolution.SkipAlways) { var r = new ConflictResolver(); sync.ConflictResolution = r.Resolve(outlookNoteItem, match.GoogleNote, sync, false); } switch (sync.ConflictResolution) { case ConflictResolution.Skip: case ConflictResolution.SkipAlways: Logger.Log(string.Format("User skipped note ({0}).", match.ToString()), EventType.Information); sync.SkippedCount++; break; case ConflictResolution.OutlookWins: case ConflictResolution.OutlookWinsAlways: sync.UpdateNote(outlookNoteItem, match.GoogleNote); break; case ConflictResolution.GoogleWins: case ConflictResolution.GoogleWinsAlways: sync.UpdateNote(match.GoogleNote, outlookNoteItem); break; default: throw new ApplicationException("Canceled"); } break; } return; } //check if outlook note was updated (with X second tolerance) if (sync.SyncOption != SyncOption.GoogleToOutlookOnly && (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance || lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance && sync.SyncOption == SyncOption.OutlookToGoogleOnly ) ) { //outlook note was changed or changed Google note will be overwritten if (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance && sync.SyncOption == SyncOption.OutlookToGoogleOnly) { Logger.Log("Google note has been updated since last sync, but Outlook note is overwriting Google because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information); } sync.UpdateNote(outlookNoteItem, match.GoogleNote); //at the moment use outlook as "master" source of notes - in the event of a conflict google note will be overwritten. //TODO: control conflict resolution by SyncOption return; } //check if google note was updated (with X second tolerance) if (sync.SyncOption != SyncOption.OutlookToGoogleOnly && (lastUpdatedGoogle.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance || lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance && sync.SyncOption == SyncOption.GoogleToOutlookOnly ) ) { //google note was changed or changed Outlook note will be overwritten if (lastUpdatedOutlook.Subtract(lastSynced.Value).TotalSeconds > TimeTolerance && sync.SyncOption == SyncOption.GoogleToOutlookOnly) { Logger.Log("Outlook note has been updated since last sync, but Google note is overwriting Outlook because of SyncOption " + sync.SyncOption + ": " + match.OutlookNote.Subject + ".", EventType.Information); } sync.UpdateNote(match.GoogleNote, outlookNoteItem); } } else { //notes were never synced. //merge notes. switch (sync.SyncOption) { case SyncOption.MergeOutlookWins: case SyncOption.OutlookToGoogleOnly: //overwrite google note sync.UpdateNote(outlookNoteItem, match.GoogleNote); break; case SyncOption.MergeGoogleWins: case SyncOption.GoogleToOutlookOnly: //overwrite outlook note sync.UpdateNote(match.GoogleNote, outlookNoteItem); break; case SyncOption.MergePrompt: //promp for sync option if (sync.ConflictResolution != ConflictResolution.GoogleWinsAlways && sync.ConflictResolution != ConflictResolution.OutlookWinsAlways && sync.ConflictResolution != ConflictResolution.SkipAlways) { var r = new ConflictResolver(); sync.ConflictResolution = r.Resolve(outlookNoteItem, match.GoogleNote, sync, true); } switch (sync.ConflictResolution) { case ConflictResolution.Skip: case ConflictResolution.SkipAlways: //Keep both, Google AND Outlook sync.Notes.Add(new NoteMatch(match.OutlookNote, null)); sync.Notes.Add(new NoteMatch(null, match.GoogleNote)); break; case ConflictResolution.OutlookWins: case ConflictResolution.OutlookWinsAlways: sync.UpdateNote(outlookNoteItem, match.GoogleNote); break; case ConflictResolution.GoogleWins: case ConflictResolution.GoogleWinsAlways: sync.UpdateNote(match.GoogleNote, outlookNoteItem); break; default: throw new ApplicationException("Canceled"); } break; } } } else { throw new ArgumentNullException("NotetMatch has all peers null."); } //} //finally //{ //if (outlookNoteItem != null && // match.OutlookNote != null) //{ // match.OutlookNote.Update(outlookNoteItem, sync); // Marshal.ReleaseComObject(outlookNoteItem); // outlookNoteItem = null; //} //} }