private void BgWorkerSaveNoc_Completed(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { Trace.WriteLine(DateTime.Now + " - BgWorkerSaveNoc_Completed: error while saving: " + e.Error.Message); // check if token was expired var error = e.Error.Message.ToLower(); if (error.Contains("token expired") || error.Contains("authorization")) { // let's resume the synchronizer _synchronizer.Start(); // let's also start up the sync timer if not already started // (this might be the first time saving) if (!_addToSyncQueueTimer.Enabled) { _addToSyncQueueTimer.Start(); } if (Settings.Default.AutoSave) { _autoSaveTimer.Start(); } TokenExpired(); return; } // else just show the error to user Status(StatusType.Error, e.Error.Message); } else { // let's get our saved document from the result and update current tab with it var newDoc = e.Result as Document; if (newDoc != null) { // let's reset the sync situation (unless this document wasn't saved because of Etag mismatch) if (newDoc.Summary != "unchanged") { // TxtNocContentAtLastSave works mainly only as a helper to remember the previously saved content // TxtNocContentAtLastSync is used when merging incoming Google Docs content with those previous changes Debug.WriteLine("SaveCompleted > TxtNocContentAtLastSync = " + TxtNocContentAtLastSuccessfulSave); TxtNocContentAtLastSync = TxtNocContentAtLastSuccessfulSave; Debug.WriteLine("SaveCompleted > TxtNocContentAtLastSuccessfulSave = " + Document.Content); TxtNocContentAtLastSuccessfulSave = Document.Content; } Document.Summary = null; ContentHasChanged = false; _tabTitleModifiedBecauseContentHasChanged = false; // need to check for InvokeRequired because we can only make changes to WinForm controls from the master thread if (InvokeRequired) { NocEventHandler setTabTitle = SetTabTitleText; Invoke(setTabTitle, newDoc.Title); NocUpdateContentAndTitle updateNocContentAndTitle = UpdateTxtNocContentNowAndTabTitle; Invoke(updateNocContentAndTitle, new object[] { null }); } else { Text = newDoc.Title; UpdateTxtNocContentNowAndTabTitle(null); } } else { // couldn't create document / save, possibly because of "could not convert document" if (InvokeRequired) { NocUpdateContentAndTitle updateNocContentAndTitle = UpdateTxtNocContentNowAndTabTitle; Invoke(updateNocContentAndTitle, new object[] { null }); } else { UpdateTxtNocContentNowAndTabTitle(null); } Debug.WriteLine(DateTime.Now + " - BgWorkerSaveNoc_Completed: e.Result is null"); } // item saved, let's notify the Main-form (unless auto-saving) // if InvokeRequired, it means that we're running through auto-save and a separate thread -> no need to update status if (!InvokeRequired) { Status(StatusType.Reset, null); } // newDoc is null when there's a problem with saving or creating a new document. // usually it's when creating a new document and gdata api couldn't convert the document if (newDoc == null) { return; } // let's resume the synchronizer _synchronizer.Start(); // let's also start up the sync timer if not already started // (this might be the first time saving) if (!_addToSyncQueueTimer.Enabled) { _addToSyncQueueTimer.Start(); } if (Settings.Default.AutoSave) { _autoSaveTimer.Start(); } } }
private void SynchronizerContentUpdated(SyncResult result) { // no need to continue checking if this is an Untitled-document if (!Document.IsDraft && result.Job.SyncDocument.ResourceId == Document.ResourceId && result.ContentUpdated) { // in case for some reason the content gets "updated" on google's side // and the content hasn't actually changed, let's just stop here if (result.Document.Content == TxtNocContentNow && result.Document.Title == Document.Title) { Debug.WriteLine("SynchronizerContentUpdated and incoming document is identical"); Document.ETag = result.Document.ETag; return; } // also, if we're currently writing something (Content has changed), // let's not merge changes yet to avoid deletion of our own work if (ContentHasChanged) { return; } // let's update the fields for this document Document = result.Document; // let's get the merged text based on text at last sync //Debug.WriteLine("SyncContentUpdated > From: TxtNocContentAtLastSync:\t" + TxtNocContentAtLastSync); Debug.WriteLine("SyncContentUpdated > From: TxtNocContentAtLastSuccessfulSave:\t" + TxtNocContentAtLastSuccessfulSave); Debug.WriteLine("SyncContentUpdated > To: Incoming:\t\t\t\t\t" + Document.Content); Debug.WriteLine("SyncContentUpdated > TxtNocContentAtLastSave:\t" + TxtNocContentAtLastSuccessfulSave); Debug.WriteLine("SyncContentUpdated > TxtNocContentNow:\t\t\t" + TxtNocContentNow); Document.Content = Tools.MergeText(TxtNocContentAtLastSuccessfulSave, TxtNocContentNow, Document.Content); Debug.WriteLine("SyncContentUpdated > Merged:\t\t\t\t\t" + Document.Content); // let's find out if we've changed the editor text since last sync var editorContentChangedSinceLastSync = TxtNocContentAtLastSync != TxtNocContentNow; // let's reset the sync situation Debug.WriteLine("SyncContentUpdated > TxtNocContentAtLastSync/Save = " + Document.Content); TxtNocContentAtLastSync = Document.Content; TxtNocContentAtLastSuccessfulSave = Document.Content; ContentHasChanged = false; _tabTitleModifiedBecauseContentHasChanged = false; // this event will always be called from a separate thread so we'll have to use Invoke to modify Noc's properties // (can only make changes to WinForm controls from the master thread) if (IsHandleCreated) { // let's update the tab's title and the RichTextBox content NocEventHandler setTabTitle = SetTabTitleText; Invoke(setTabTitle, result.Document.Title); NocEventHandler setEditorContent = SetEditorContent; Invoke(setEditorContent, Document.Content); } else { Trace.WriteLine(DateTime.Now + " - Noc: Handle not created while trying to invoke content changes for: " + result.Document.Title); return; } // in case we've change the text since last sync (while syncing for example), // let's save this document again if (editorContentChangedSinceLastSync && !NocsService.Working && !_bgWorkerSaveNoc.IsBusy) { Debug.WriteLine("ContentUpdated: editor content changed since last sync, saving current content"); // let's run the backgroundWorker for saving this document var folderId = string.Empty; if (Document.ParentFolders.Count > 0) { folderId = Document.ParentFolders[0]; } var args = new object[] { folderId, Document.Title, false, false }; _bgWorkerSaveNoc.RunWorkerAsync(args); } } }