public static SupportingFileReferenceList CalculateReferencesForPublish(IBlogPostEditingContext editingContext) { SupportingFileReferenceList list = new SupportingFileReferenceList(editingContext); list.CalculateReferencesForPublish(); return(list); }
public ContentEditorProxy(ContentEditorFactory factory, IContentEditorSite contentEditorSite, IInternetSecurityManager internetSecurityManager, IHTMLDocument2 htmlDocument, HtmlInsertOptions options, int dlControlFlags, string color, string wpost) { string content = htmlDocument.body.innerHTML; htmlDocument.body.innerHTML = "{post-body}"; string wysiwygHTML = HTMLDocumentHelper.HTMLDocToString(htmlDocument); BlogPost documentToBeLoaded = null; IBlogPostEditingContext editingContext = null; if (string.IsNullOrEmpty(wpost) || !File.Exists(wpost)) { documentToBeLoaded = new BlogPost(); editingContext = new BlogPostEditingContext(ContentEditorAccountAdapter.AccountId, documentToBeLoaded); } else { PostEditorFile wpostxFile = PostEditorFile.GetExisting(new FileInfo(wpost)); editingContext = wpostxFile.Load(false); editingContext.BlogPost.Contents = ""; } if (!string.IsNullOrEmpty(content)) { delayedInsertOperations.Enqueue(new DelayedInsert(content, options)); } ContentEditorProxyCore(factory, contentEditorSite, internetSecurityManager, wysiwygHTML, null, editingContext, new ContentEditorTemplateStrategy(), dlControlFlags, color); }
public PostEditorForm(IBlogPostEditingContext editingContext, bool synchronizePost, IDisposable splashScreen) { CommonInit(); _initialEditingContext = editingContext; _synchronizePost = synchronizePost; _splashScreen = splashScreen; }
/// <summary> /// Initializes the IContentEditor. /// </summary> /// <param name="factory"></param> /// <param name="contentEditorSite"></param> /// <param name="internetSecurityManager"></param> /// <param name="wysiwygHTML"></param> /// <param name="previewHTML"></param> /// <param name="newEditingContext"></param> /// <param name="templateStrategy"></param> /// <param name="dlControlFlags"> /// For Mail, these flags should always include DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS so that local /// images, videos and sounds are loaded. To block external content, it should also include /// DLCTL_PRAGMA_NO_CACHE | DLCTL_FORCEOFFLINE | DLCTL_NO_CLIENTPULL so that external images are not loaded /// and are displayed as a red X instead. /// </param> /// <param name="color"></param> private void ContentEditorProxyCore(ContentEditorFactory factory, IContentEditorSite contentEditorSite, IInternetSecurityManager internetSecurityManager, string wysiwygHTML, string previewHTML, IBlogPostEditingContext newEditingContext, BlogPostHtmlEditorControl.TemplateStrategy templateStrategy, int dlControlFlags, string color) { try { Debug.Assert(contentEditorSite is IUIFramework, "IContentEditorSite must also implement IUIFramework"); Debug.Assert(contentEditorSite is IDropTarget, "IContentEditorSite must also implement IDropTarget"); ApplyInstalledCulture(); this.factory = factory; _wysiwygHTML = wysiwygHTML; _previewHTML = previewHTML; _contentEditorSite = contentEditorSite; IntPtr p = _contentEditorSite.GetWindowHandle(); WINDOWINFO info = new WINDOWINFO(); User32.GetWindowInfo(p, ref info); panel = new Panel(); panel.Top = 0; panel.Left = 0; panel.Width = Math.Max(info.rcWindow.Width, 200); panel.Height = Math.Max(info.rcWindow.Height, 200); panel.CreateControl(); User32.SetParent(panel.Handle, p); accountAdapter = new ContentEditorAccountAdapter(); mainFrame = new MainFrameWindowAdapter(p, panel, _contentEditorSite, accountAdapter.Id); context = newEditingContext; contentEditor = new ContentEditor(mainFrame, panel, mainFrame, internetSecurityManager, templateStrategy, dlControlFlags); // Prevents asserts contentEditor.DisableSpelling(); contentEditor.OnEditorAccountChanged(accountAdapter); contentEditor.DocumentComplete += new EventHandler(blogPostHtmlEditor_DocumentComplete); contentEditor.GotFocus += new EventHandler(contentEditor_GotFocus); contentEditor.LostFocus += new EventHandler(contentEditor_LostFocus); contentEditor.Initialize(context, accountAdapter, wysiwygHTML, previewHTML, false); if (!string.IsNullOrEmpty(color)) { contentEditor.IndentColor = color; } this.factory.GlobalSpellingOptionsChanged += GlobalSpellingOptionsChangedHandler; } catch (Exception ex) { // Something went wrong, make sure we don't reuse a cached editor HtmlEditorControl.DisposeCachedEditor(); Trace.Fail(ex.ToString()); Trace.Flush(); throw; } }
public void Initialize(IBlogPostEditingContext editorContext, IBlogClientOptions clientOptions) { _editorContext = editorContext; _clientOptions = clientOptions; controller.Initialize(editorContext, clientOptions); ((IBlogPostEditor)postPropertiesForm).Initialize(editorContext, clientOptions); ManageLayout(); }
public void Initialize(IBlogPostEditingContext editingContext, IBlogClientOptions options) { PropertyType requiredType = editingContext.BlogPost.IsPage ? PropertyType.Page : PropertyType.Post; bool isCorrectType = (propertyType & requiredType) == requiredType; if (isCorrectType && populate != null) { populate(editingContext, options); } }
private static void ExecuteOpenPost() { using (OpenPostForm openPostForm = new OpenPostForm()) { if (openPostForm.ShowDialog(Win32WindowImpl.DesktopWin32Window) == DialogResult.OK) { IBlogPostEditingContext editingContext = openPostForm.BlogPostEditingContext; PostEditorForm.Launch(editingContext, true); } } }
public void Initialize(IBlogPostEditingContext editingContext, IBlogClientOptions clientOptions) { // this needs to happen before an editor is loaded, it is needed to know if // if the blog this band should show or not. bool firstTimeInitialization = _currentEditor == null; InitDefaultEditorForBlog(); base.Initialize(editingContext, clientOptions, GetStyledHtml(), GetPreviewHtml(), true); commandSemanticHtml.SetAccountId(_currentBlog.Id, IsRTLTemplate, false); _postPropertyEditor.Initialize(editingContext, clientOptions); }
public void UpdateControlVisibility(IBlogPostEditingContext editingContext, IBlogClientOptions options) { PropertyType requiredType = editingContext.BlogPost.IsPage ? PropertyType.Page : PropertyType.Post; bool isCorrectType = (propertyType & requiredType) == requiredType; bool visible = isCorrectType && shouldShow(options); foreach (Control c in controls) { if (c != null) { c.Visible = visible; } } }
private static void ConvertImageReferencesToLocal(IBlogPostEditingContext editingContext) { ImageReferenceFixer refFixer = new ImageReferenceFixer(editingContext.ImageDataList, editingContext.BlogId); // Create a text writer that the new html will be written to TextWriter htmlWriter = new StringWriter(CultureInfo.InvariantCulture); // Check an html image fixer that will find references and rewrite them to new paths HtmlReferenceFixer referenceFixer = new HtmlReferenceFixer(editingContext.BlogPost.Contents); // We need to update the editing context when we change an image ContextImageReferenceFixer contextFixer = new ContextImageReferenceFixer(editingContext); // Do the fixing referenceFixer.FixReferences(htmlWriter, new ReferenceFixer(refFixer.FixImageReferences), contextFixer.ReferenceFixedCallback); // Write back the new html editingContext.BlogPost.Contents = htmlWriter.ToString(); }
void IBlogPostEditor.Initialize(IBlogPostEditingContext editingContext, IBlogClientOptions clientOptions) { // categories from blog CategoryContext.SetBlogCategories(_targetBlog.Categories); // pickup new categories from the blog-post CategoryContext.SetNewCategories(editingContext.BlogPost.NewCategories); // combine all post categories before settting ArrayList selectedCategories = new ArrayList(); selectedCategories.AddRange(editingContext.BlogPost.NewCategories); selectedCategories.AddRange(editingContext.BlogPost.Categories); _lastSelectedCategories = new BlogPostCategory[0]; CategoryContext.SelectedCategories = selectedCategories.ToArray(typeof(BlogPostCategory)) as BlogPostCategory[]; toolTipCategories.SetToolTip(this, CategoryContext.FormattedCategoryList); _isDirty = false; }
public void Dispose() { contentEditor.DocumentComplete -= new EventHandler(blogPostHtmlEditor_DocumentComplete); contentEditor.GotFocus -= new EventHandler(contentEditor_GotFocus); contentEditor.LostFocus -= new EventHandler(contentEditor_LostFocus); contentEditor.Dispose(); panel.Dispose(); accountAdapter.Dispose(); mainFrame.Dispose(); Marshal.ReleaseComObject(_contentEditorSite); _contentEditorSite = null; accountAdapter = null; contentEditor = null; panel = null; context = null; }
private static void ExecutePostEditorFile(string filename, IDisposable splashScreen) { if (VerifyPostEditorFileIsEditable(filename)) { // load the contents of the file PostEditorFile postEditorFile = PostEditorFile.GetExisting(new FileInfo(filename)); IBlogPostEditingContext editingContext = postEditorFile.Load(); // launch the editing form (request post synchronization) PostEditorForm.Launch(editingContext, true, splashScreen); } else { if (splashScreen != null) { splashScreen.Dispose(); } } }
private void AcceptSelectedPost() { // see if there is anyone listening to the validate event (to veto the selection) if (ValidateSelectedPost()) { // get the post from the list box try { // get the post using (new WaitCursor()) _selectedPost = listBoxPosts.RetrieveSelectedPost(); // if that succeeded then allow the dialog to be dismissed DialogResult = DialogResult.OK; } catch (Exception ex) { DisplayableExceptionDisplayForm.Show(this, ex); } } }
public void Initialize(IBlogPostEditingContext context, IBlogClientOptions clientOptions) { Debug.Assert(_blogId == context.BlogId); using (SuspendLogic()) { editorContext = context; using (Blog blog = new Blog(context.BlogId)) UpdateFieldsForBlog(blog); ((IBlogPostEditor)categoryDropDown).Initialize(context, clientOptions); foreach (PropertyField field in fields) { field.Initialize(context, clientOptions); } } isDirty = false; }
/// <summary> /// Synchronize the local and remote copies of the recent post to create an /// edit context that combines the latest HTML content, etc. from the web /// with the local image editing context /// </summary> /// <param name="editingContext"></param> /// <returns></returns> public static IBlogPostEditingContext Synchronize(IWin32Window mainFrameWindow, IBlogPostEditingContext editingContext) { // reloading a local draft does not require synchronization if (editingContext.LocalFile.IsDraft && editingContext.LocalFile.IsSaved) { return(editingContext); } else if (editingContext.LocalFile.IsRecentPost) { // search for a draft of this post which has already been initialized for offline editing of the post // (we don't want to allow opening multiple local "drafts" of edits to the same remote post PostEditorFile postEditorFile = PostEditorFile.FindPost(PostEditorFile.DraftsFolder, editingContext.BlogId, editingContext.BlogPost.Id); if (postEditorFile != null) { // return the draft return(postEditorFile.Load()); } //verify synchronization is supported for this blog service if (!SynchronizationSupportedForBlog(editingContext.BlogId)) { Debug.WriteLine("Post synchronization is not supported"); return(editingContext); } // opening local copy, try to marry with up to date post content on the server // (will return the existing post if an error occurs or the user cancels) BlogPost serverBlogPost = SafeGetPostFromServer(mainFrameWindow, editingContext.BlogId, editingContext.BlogPost); if (serverBlogPost != null) { // if the server didn't return a post-id then replace it with the // known post id if (serverBlogPost.Id == String.Empty) { serverBlogPost.Id = editingContext.BlogPost.Id; } // merge trackbacks MergeTrackbacksFromClient(serverBlogPost, editingContext.BlogPost); // create new init params IBlogPostEditingContext newEditingContext = new BlogPostEditingContext( editingContext.BlogId, serverBlogPost, // swap-in blog post from server editingContext.LocalFile, null, editingContext.ServerSupportingFileDirectory, editingContext.SupportingFileStorage, editingContext.ImageDataList, editingContext.ExtensionDataList, editingContext.SupportingFileService); SynchronizeLocalContentsWithEditingContext(editingContext.BlogPost.Contents, editingContext.BlogPost.ContentsVersionSignature, newEditingContext); // return new init params return(newEditingContext); } else { return(editingContext); } } else if (editingContext.LocalFile.IsSaved) { // Opening draft from somewhere other than the official drafts directory return(editingContext); } else { // opening from the server, first see if the user already has a draft // "checked out" for this post PostEditorFile postEditorFile = PostEditorFile.FindPost(PostEditorFile.DraftsFolder, editingContext.BlogId, editingContext.BlogPost.Id); if (postEditorFile != null) { return(postEditorFile.Load()); } // no draft, try to marry with local copy of recent post PostEditorFile recentPost = PostEditorFile.FindPost( PostEditorFile.RecentPostsFolder, editingContext.BlogId, editingContext.BlogPost.Id); if (recentPost != null) { // load the recent post IBlogPostEditingContext newEditingContext = recentPost.Load(); string localContents = newEditingContext.BlogPost.Contents; string localContentsSignature = newEditingContext.BlogPost.ContentsVersionSignature; // merge trackbacks from client MergeTrackbacksFromClient(editingContext.BlogPost, newEditingContext.BlogPost); // copy the BlogPost properties from the server (including merged trackbacks) newEditingContext.BlogPost.CopyFrom(editingContext.BlogPost); SynchronizeLocalContentsWithEditingContext(localContents, localContentsSignature, newEditingContext); // return the init params return(newEditingContext); } else { return(editingContext); } } }
void IBlogPostEditor.Initialize(IBlogPostEditingContext editingContext, IBlogClientOptions clientOptions) { _isDirty = false; }
public void Initialize(IBlogPostEditingContext editingContext, IBlogClientOptions options) { PropertyType requiredType = editingContext.BlogPost.IsPage ? PropertyType.Page : PropertyType.Post; bool isCorrectType = (propertyType & requiredType) == requiredType; if (isCorrectType && populate != null) populate(editingContext, options); }
void IBlogPostEditor.Initialize(IBlogPostEditingContext editingContext) { CategoryContext.SelectedCategories = editingContext.BlogPost.Categories ; toolTipCategories.SetToolTip(this, CategoryContext.FormattedCategoryList); _isDirty = false ; }
public PostEditorMainControl(IMainFrameWindow mainFrameWindow, IBlogPostEditingContext editingContext) { Init(mainFrameWindow, editingContext); }
/// <summary> /// Dispatches an edit post request to either the current editor window /// or to a new editor form depending upon the user's preferences and /// the current editing state /// </summary> /// <param name="editingContext">editing conext</param> private void DispatchEditPost(IBlogPostEditingContext editingContext, bool isNewPost) { // calcluate whether the user has a "blank" unsaved post bool currentPostIsEmptyAndUnsaved = ((BlogPost != null) && BlogPost.IsNew && (BlogPost.Contents == null || BlogPost.Contents == String.Empty)) && !LocalFile.IsSaved && !PostIsDirty; // edge case: current post is empty and unsaved and this is a new post, // re-using the window in this case will just make the New button appear // to not work at all, therefore we force a new window. We make an exception // for creation of new pages, as firing up a new writer instance and then // switching into "page authoring" mode is a natual thing to do (and shouldn't // result in a new window for no apparent reason). In this case the user will // get "feedback" by seeing the default title change to "Enter Page Title Here" // as well as the contents of the property tray changing. if (currentPostIsEmptyAndUnsaved && isNewPost && !editingContext.BlogPost.IsPage) { PostEditorForm.Launch(editingContext); return; } // Notify all the editors that the post is about to close // This will give them an chance to do any clean up, or in the // case of video publish to hold up the close operation till videos // have finished uploading. CancelEventArgs e = new CancelEventArgs(); foreach (IBlogPostEditor editor in _postEditors) { editor.OnPostClosing(e); if (e.Cancel) break; } if (e.Cancel) { return; } switch (PostEditorSettings.PostWindowBehavior) { case PostWindowBehavior.UseSameWindow: // allow the user a chance to save if necessary if (PostIsDirty) { // cancel aborts the edit post operation DialogResult saveChangesResult = PromptToSaveChanges(); if (saveChangesResult == DialogResult.Cancel) { return; } // special case -- we are actually re-editing the currently active post // in this instance we need to "re-open" it to reflect the saved changes else if (saveChangesResult == DialogResult.Yes && editingContext.LocalFile.Equals(LocalFile)) { EditPostWithPostCloseEvent(LocalFile.Load()); break; ; } } // edit the post using the existing window EditPostWithPostCloseEvent(editingContext); break; case PostWindowBehavior.OpenNewWindow: // special case: if the current frame contains an empty, unsaved // post then replace it (covers the case of the user opening // writer in order to edit an existing post -- in this case they // should never have to deal with managing two windows if (currentPostIsEmptyAndUnsaved) { EditPostWithPostCloseEvent(editingContext); } else { // otherwise open a new window PostEditorForm.Launch(editingContext); } break; case PostWindowBehavior.OpenNewWindowIfDirty: if (PostIsDirty) { PostEditorForm.Launch(editingContext); } else { EditPostWithPostCloseEvent(editingContext); } break; } }
private SupportingFileReferenceList(IBlogPostEditingContext editingContext) { _editingContext = editingContext; }
public void EditPost(IBlogPostEditingContext editingContext) { EditPost(editingContext, false); }
public void EditPost(IBlogPostEditingContext editingContext, bool forceDirty) { // not yet initialized _initialized = false; // note start time of editing session _editStartTime = DateTime.UtcNow; // defend against invalid blog id bool resetPostId = false; string blogId = editingContext.BlogId; if (!BlogSettings.BlogIdIsValid(blogId)) { blogId = BlogSettings.DefaultBlogId; resetPostId = true; } // initialize state SetCurrentBlog(blogId); BlogPost = editingContext.BlogPost; LocalFile = editingContext.LocalFile; _autoSaveLocalFile = editingContext.AutoSaveLocalFile; if (_autoSaveLocalFile != null) forceDirty = true; ServerSupportingFileDirectory = editingContext.ServerSupportingFileDirectory; SupportingFileStorage = editingContext.SupportingFileStorage; ImageDataList = editingContext.ImageDataList; ExtensionDataList = editingContext.ExtensionDataList; SupportingFileService = editingContext.SupportingFileService; // can now fire events _initialized = true; // Fix bug 574769: Post ID for a weblog sometimes gets carried over to another weblog so post-publishing fails. if (resetPostId) BlogPost.ResetPostForNewBlog(Blog.ClientOptions); // only fire events after we are fully initialized (event handlers call back into // this object and expect everything to be initialized) OnBlogChanged(); OnBlogPostChanged(); OnEditingStatusChanged(); // force dirty if requested if (forceDirty) ForceDirty(); }
public void OpenPost(IBlogPostEditingContext editingContext) { using (new WaitCursor()) { editingContext = RecentPostSynchronizer.Synchronize(_mainFrameWindow, editingContext); DispatchEditPost(editingContext, false); } }
public void Initialize(IBlogPostEditingContext editingContext, IEditorOptions clientOptions, string wysiwygHTML, string previewHTML, bool containsTitle) { // We suppress he editor reload here while we add the inital template because a bit further down // this function we will reload the editor using the BlogPost from editingContext using (SuppressEditorLoad()) SetTheme(wysiwygHTML, previewHTML, containsTitle); _editingContext = editingContext; // @SharedCanvas - Check to make sure we can get rid of this once we get rid of the sidebar if (_editingContext is BlogPostEditingManager) { // Get an event everytime the user tried to publish, so we refesh smart content that might have been updated during published BlogPostEditingManager editingManager = (BlogPostEditingManager)_editingContext; editingManager.UserPublishedPost += new EventHandler(editingManager_UserPublishedPost); } // save whethere we are editing a page _isPage = editingContext.BlogPost.IsPage; // save a reference to the supporting files _supportingFileStorage = editingContext.SupportingFileStorage; //save a reference to the image data list _imageDataList = editingContext.ImageDataList; //save a reference to the extension data list _extensionDataList = editingContext.ExtensionDataList; // if there is already a RefreshableContentManager, which means that the user // is switching blogs or posts, then we need to dispose of it if (_refreshSmartContentManager != null) _refreshSmartContentManager.Dispose(); // Make a new manager for the extension data for this blog/post _refreshSmartContentManager = new RefreshableContentManager(_extensionDataList, this); _fileService = editingContext.SupportingFileService; // Reset the emoticons manager _emoticonsManager = new EmoticonsManager(this, this); // initialize text-editing command manager // this needs to be called before html is loaded into the editor and before an editor gets // focus because that will cause the html commands to be updated InitializeTextEditingCommands(); bool indent = GlobalEditorOptions.SupportsFeature(ContentEditorFeature.TabAsIndent); CommandManager.Get(CommandId.Indent).On = indent; CommandManager.Get(CommandId.Outdent).On = indent; string postContentsHtml = SmartContentWorker.PerformOperation(editingContext.BlogPost.Contents, GetStructuredEditorHtml, true, this, true); postContentsHtml = StripPluginHeadersAndFooters(postContentsHtml); LoadEditorHtml(editingContext.BlogPost.Title, postContentsHtml, _currentEditorAccount.HomepageBaseUrl, false); // There are a lot of reasons that the post might become dirty, that are not from the users, these usually fall in // a very short time period. This is a catch all case, because there is no way to win against find all the different way. // Often times, it can be a css background loading, or mshtml changing around the html. TimerHelper.CallbackOnDelay(new InvokeInUIThreadDelegate(delegate () { _currentEditor.IsDirty = false; }), 50); // make sure the word count is in sync with the new post that has just been loaded wordCountUpdate(this, EventArgs.Empty); //update editing context of the editors _normalHtmlContentEditor.UpdateEditingContext(); if (_codeHtmlContentEditor != null) _codeHtmlContentEditor.UpdateEditingContext(); }
public static SupportingFileReferenceList CalculateReferencesForPublish(IBlogPostEditingContext editingContext) { SupportingFileReferenceList list = new SupportingFileReferenceList(editingContext); list.CalculateReferencesForPublish(); return list; }
internal ContextImageReferenceFixer(IBlogPostEditingContext editingContext) { _editingContext = editingContext; }
private void EditPostWithPostCloseEvent(IBlogPostEditingContext blogPostEditingContext) { // If the editor has already been initialized once, then we need to tell the editor it is getting its post closed. if (_initialized) { foreach (IBlogPostEditor editor in _postEditors) { editor.OnPostClosed(); } } EditPost(blogPostEditingContext); }
public AttachedFileListWriter(SupportingFilePersister supportingFilePersister, IBlogPostEditingContext editingContext, SupportingFileReferenceList referenceList) { _supportingFilePersister = supportingFilePersister; _editingContext = editingContext; _referenceList = referenceList; }
// implement IBlogPostEditor so we can participating in showing/hiding // the property editor control void IBlogPostEditor.Initialize(IBlogPostEditingContext editingContext, IBlogClientOptions clientOptions) { }
public void SaveBlogPost(IBlogPostEditingContext editingContext) { string filePath = ManagePostFilePath(editingContext.BlogPost.IsPage, editingContext.BlogPost.Title); SaveCore(editingContext, null, filePath); Shell32.SHAddToRecentDocs(SHARD.PATHW, filePath); }
private void Init(IMainFrameWindow mainFrameWindow, IBlogPostEditingContext editingContext) { // save reference to the frame window and workspace border manager _mainFrameWindow = mainFrameWindow; // This call is required by the Windows.Forms Form Designer. Font = Res.DefaultFont; InitializeComponent(); // initialize UI InitializeUI(); // Initialize the editing manager InitializeEditingManager(); // initialize our commands InitializeCommands(); //subscribe to global events BlogSettings.BlogSettingsDeleted += new BlogSettings.BlogSettingsListener(HandleBlogDeleted); // edit the post _editingManager.EditPost(editingContext, false); InitializeRibbon(); }
private void SaveCore(IBlogPostEditingContext editingContext, PostEditorFile autoSaveSourceFile, string filePath) { // did this file exist prior to the attempt to save (if no, we need to delete // it if an exceptoin occurs -- otherwise we leave a "zombie" post file with // no available streams bool isPreviouslyUnsaved = !IsSaved; try { try { // alias blog-post BlogPost blogPost = editingContext.BlogPost; Debug.Assert(!blogPost.IsTemporary, "Saving temporary style detection post!?"); // write out all of the fields using (Storage postStorage = new Storage(filePath, StorageMode.OpenOrCreate, true)) { // file-format clsid postStorage.Clsid = Version2FormatCLSID; // meta-data WriteString(postStorage, DESTINATION_BLOG_ID, editingContext.BlogId); WriteString(postStorage, SERVER_SUPPORTING_FILE_DIR, editingContext.ServerSupportingFileDirectory); // blog post WriteString(postStorage, POST_ID, blogPost.Id); WriteBoolean(postStorage, POST_ISPAGE, blogPost.IsPage); WriteString(postStorage, POST_TITLE, blogPost.Title); WriteXml(postStorage, POST_CATEGORIES, blogPost.Categories, new XmlWriteHandler(WriteCategories)); WriteXml(postStorage, POST_NEW_CATEGORIES, blogPost.NewCategories, new XmlWriteHandler(WriteCategories)); WriteDateTime(postStorage, POST_DATEPUBLISHED, blogPost.DatePublished); WriteDateTime(postStorage, POST_DATEPUBLISHED_OVERRIDE, blogPost.DatePublishedOverride); WriteCommentPolicy(postStorage, blogPost.CommentPolicy); WriteTrackbackPolicy(postStorage, blogPost.TrackbackPolicy); WriteString(postStorage, POST_KEYWORDS, blogPost.Keywords); WriteString(postStorage, POST_EXCERPT, blogPost.Excerpt); WriteString(postStorage, POST_PERMALINK, blogPost.Permalink); WriteString(postStorage, POST_LINK, blogPost.Permalink); // write for legacy compatability with beta 1 WriteXml(postStorage, POST_PINGURLS_PENDING, blogPost.PingUrlsPending, new XmlWriteHandler(WritePingUrls)); WriteXml(postStorage, POST_PINGURLS_SENT, blogPost.PingUrlsSent, new XmlWriteHandler(WritePingUrls)); WriteString(postStorage, POST_SLUG, blogPost.Slug); WriteString(postStorage, POST_PASSWORD, blogPost.Password); WriteString(postStorage, POST_AUTHOR_ID, blogPost.Author.Id); WriteString(postStorage, POST_AUTHOR_NAME, blogPost.Author.Name); WriteString(postStorage, POST_PAGE_PARENT_ID, blogPost.PageParent.Id); WriteString(postStorage, POST_PAGE_PARENT_NAME, blogPost.PageParent.Name); WriteString(postStorage, POST_PAGE_ORDER, blogPost.PageOrder); WriteString(postStorage, POST_ETAG, blogPost.ETag); WriteXml(postStorage, POST_ATOM_REMOTE_POST, blogPost.AtomRemotePost, new XmlWriteHandler(XmlDocWriteHandler)); //save the post info hash WriteString(postStorage, POST_CONTENTS_VERSION_SIGNATURE, blogPost.ContentsVersionSignature); // contents (with fixups for local files) SupportingFilePersister supportingFilePersister = new SupportingFilePersister(postStorage.OpenStorage(POST_SUPPORTING_FILES, StorageMode.Create, true)); //BlogPostReferenceFixedHandler fixedReferenceHandler = new BlogPostReferenceFixedHandler(editingContext.ImageDataList); //string fixedUpPostContents = supportingFilePersister.SaveFilesAndFixupReferences(blogPost.Contents, new ReferenceFixedCallback(fixedReferenceHandler.HandleReferenceFixed)) ; //write the attached file data //supportingFilePersister. SupportingFileReferenceList referenceList = SupportingFileReferenceList.CalculateReferencesForSave(editingContext); WriteXml(postStorage, POST_ATTACHED_FILES, null, new XmlWriteHandler(new AttachedFileListWriter(supportingFilePersister, editingContext, referenceList).WriteAttachedFileList)); WriteXml(postStorage, POST_IMAGE_FILES, editingContext.ImageDataList, new XmlWriteHandler(new AttachedImageListWriter(referenceList).WriteImageFiles)); //write the extension data WriteXml(postStorage, POST_EXTENSION_DATA_LIST, editingContext.ExtensionDataList, new XmlWriteHandler(new ExtensionDataListWriter(supportingFilePersister, blogPost.Contents).WriteExtensionDataList)); //Convert file references in the HTML contents to the new storage path string fixedUpPostContents = supportingFilePersister.FixupHtmlReferences(blogPost.Contents); WriteStringUtf8(postStorage, POST_CONTENTS, fixedUpPostContents); string originalSourcePath = autoSaveSourceFile == null ? "" : autoSaveSourceFile.IsSaved ? autoSaveSourceFile.TargetFile.FullName : autoSaveSourceFile.TargetDirectory.FullName; WriteStringUtf8(postStorage, ORIGINAL_SOURCE_PATH, originalSourcePath); // save to storage postStorage.Commit(); // mark file as saved TargetFile = new FileInfo(filePath); } } catch (Exception ex) { Trace.Fail("Unexpected exception type in PostEditorFile.Save. It is critical that only IO exceptions occur at this level of the system so please check the code which threw the exeption and see if there is a way to behave more robustly!\r\n" + ex.ToString()); throw PostEditorStorageException.Create(ex); } } catch { // if we had no file previously and an exception occurs then // we need to delete the file if (isPreviouslyUnsaved && File.Exists(filePath)) try { File.Delete(filePath); } catch { } throw; } }
/// <summary> /// Synchronizes the editing context contents with the local contents (if the version signatures are equivalent). /// </summary> /// <param name="localContents"></param> /// <param name="localContentsSignature"></param> /// <param name="editingContext"></param> private static void SynchronizeLocalContentsWithEditingContext(string localContents, string localContentsSignature, IBlogPostEditingContext editingContext) { bool contentIsUpToDate = localContentsSignature == editingContext.BlogPost.ContentsVersionSignature; if (contentIsUpToDate) { Debug.WriteLine("RecentPostSynchronizer: Use local contents"); editingContext.BlogPost.Contents = localContents; } else { Debug.WriteLine("RecentPostSynchronizer: Using remote contents"); // convert image references ConvertImageReferencesToLocal(editingContext); } }
public void UpdateControlVisibility(IBlogPostEditingContext editingContext, IBlogClientOptions options) { PropertyType requiredType = editingContext.BlogPost.IsPage ? PropertyType.Page : PropertyType.Post; bool isCorrectType = (propertyType & requiredType) == requiredType; bool visible = isCorrectType && shouldShow(options); foreach (Control c in controls) if (c != null) c.Visible = visible; }
public static void Launch(IBlogPostEditingContext editingContext, bool synchronizePost) { Launch(editingContext, synchronizePost, null); }
void IBlogPostEditor.Initialize(IBlogPostEditingContext editingContext) { CategoryContext.SelectedCategories = editingContext.BlogPost.Categories; toolTipCategories.SetToolTip(this, CategoryContext.FormattedCategoryList); _isDirty = false; }
public static void Launch(IBlogPostEditingContext editingContext, bool synchronizePost, IDisposable splashScreen) { SatelliteApplicationForm.Open(typeof(PostEditorForm), editingContext, synchronizePost, splashScreen); }
public PostEditorForm(IBlogPostEditingContext editingContext, IDisposable splashScreen) : this(editingContext, false, splashScreen) { }
public void Initialize(IBlogPostEditingContext context, IBlogClientOptions clientOptions) { Debug.Assert(_blogId == context.BlogId); using (SuspendLogic()) { editorContext = context; using (Blog blog = new Blog(context.BlogId)) UpdateFieldsForBlog(blog); ((IBlogPostEditor)categoryDropDown).Initialize(context, clientOptions); foreach (PropertyField field in fields) field.Initialize(context, clientOptions); } isDirty = false; }
/// <summary> /// Initializes the IContentEditor. /// </summary> /// <param name="factory"></param> /// <param name="contentEditorSite"></param> /// <param name="internetSecurityManager"></param> /// <param name="wysiwygHTML"></param> /// <param name="previewHTML"></param> /// <param name="newEditingContext"></param> /// <param name="templateStrategy"></param> /// <param name="dlControlFlags"> /// For Mail, these flags should always include DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS so that local /// images, videos and sounds are loaded. To block external content, it should also include /// DLCTL_PRAGMA_NO_CACHE | DLCTL_FORCEOFFLINE | DLCTL_NO_CLIENTPULL so that external images are not loaded /// and are displayed as a red X instead. /// </param> /// <param name="color"></param> private void ContentEditorProxyCore(ContentEditorFactory factory, IContentEditorSite contentEditorSite, IInternetSecurityManager internetSecurityManager, string wysiwygHTML, string previewHTML, IBlogPostEditingContext newEditingContext, BlogPostHtmlEditorControl.TemplateStrategy templateStrategy, int dlControlFlags, string color) { try { Debug.Assert(contentEditorSite is IUIFramework, "IContentEditorSite must also implement IUIFramework"); Debug.Assert(contentEditorSite is IDropTarget, "IContentEditorSite must also implement IDropTarget"); ApplyInstalledCulture(); this.factory = factory; _wysiwygHTML = wysiwygHTML; _previewHTML = previewHTML; _contentEditorSite = contentEditorSite; IntPtr p = _contentEditorSite.GetWindowHandle(); WINDOWINFO info = new WINDOWINFO(); User32.GetWindowInfo(p, ref info); panel = new Panel(); panel.Top = 0; panel.Left = 0; panel.Width = Math.Max(info.rcWindow.Width, 200); panel.Height = Math.Max(info.rcWindow.Height, 200); panel.CreateControl(); User32.SetParent(panel.Handle, p); accountAdapter = new ContentEditorAccountAdapter(); mainFrame = new MainFrameWindowAdapter(p, panel, _contentEditorSite, accountAdapter.Id); context = newEditingContext; contentEditor = new ContentEditor(mainFrame, panel, mainFrame, internetSecurityManager, templateStrategy, dlControlFlags); // Prevents asserts contentEditor.DisableSpelling(); contentEditor.OnEditorAccountChanged(accountAdapter); contentEditor.DocumentComplete += new EventHandler(blogPostHtmlEditor_DocumentComplete); contentEditor.GotFocus += new EventHandler(contentEditor_GotFocus); contentEditor.LostFocus += new EventHandler(contentEditor_LostFocus); contentEditor.Initialize(context, accountAdapter, wysiwygHTML, previewHTML, false); if (!string.IsNullOrEmpty(color)) { contentEditor.IndentColor = color; } } catch (Exception ex) { // Something went wrong, make sure we don't reuse a cached editor HtmlEditorControl.DisposeCachedEditor(); Trace.Fail(ex.ToString()); Trace.Flush(); throw; } }
/// <summary> /// Synchronize the local and remote copies of the recent post to create an /// edit context that combines the latest HTML content, etc. from the web /// with the local image editing context /// </summary> /// <param name="editingContext"></param> /// <returns></returns> public static IBlogPostEditingContext Synchronize(IWin32Window mainFrameWindow, IBlogPostEditingContext editingContext) { // reloading a local draft does not require syncronization if (editingContext.LocalFile.IsDraft && editingContext.LocalFile.IsSaved) { return editingContext; } else if (editingContext.LocalFile.IsRecentPost) { // search for a draft of this post which has already been initialized for offline editing of the post // (we don't want to allow opening multiple local "drafts" of edits to the same remote post PostEditorFile postEditorFile = PostEditorFile.FindPost(PostEditorFile.DraftsFolder, editingContext.BlogId, editingContext.BlogPost.Id); if (postEditorFile != null) { // return the draft return postEditorFile.Load(); } //verify synchronization is supported for this blog service if (!SynchronizationSupportedForBlog(editingContext.BlogId)) { Debug.WriteLine("Post synchronization is not supported"); return editingContext; } // opening local copy, try to marry with up to date post content on the server // (will return the existing post if an error occurs or the user cancels) BlogPost serverBlogPost = SafeGetPostFromServer(mainFrameWindow, editingContext.BlogId, editingContext.BlogPost); if (serverBlogPost != null) { // if the server didn't return a post-id then replace it with the // known post id if (serverBlogPost.Id == String.Empty) serverBlogPost.Id = editingContext.BlogPost.Id; // merge trackbacks MergeTrackbacksFromClient(serverBlogPost, editingContext.BlogPost); // create new init params IBlogPostEditingContext newEditingContext = new BlogPostEditingContext( editingContext.BlogId, serverBlogPost, // swap-in blog post from server editingContext.LocalFile, null, editingContext.ServerSupportingFileDirectory, editingContext.SupportingFileStorage, editingContext.ImageDataList, editingContext.ExtensionDataList, editingContext.SupportingFileService); SynchronizeLocalContentsWithEditingContext(editingContext.BlogPost.Contents, editingContext.BlogPost.ContentsVersionSignature, newEditingContext); // return new init params return newEditingContext; } else { return editingContext; } } else if (editingContext.LocalFile.IsSaved) { // Opening draft from somewhere other than the official drafts directory return editingContext; } else { // opening from the server, first see if the user already has a draft // "checked out" for this post PostEditorFile postEditorFile = PostEditorFile.FindPost(PostEditorFile.DraftsFolder, editingContext.BlogId, editingContext.BlogPost.Id); if (postEditorFile != null) { return postEditorFile.Load(); } // no draft, try to marry with local copy of recent post PostEditorFile recentPost = PostEditorFile.FindPost( PostEditorFile.RecentPostsFolder, editingContext.BlogId, editingContext.BlogPost.Id); if (recentPost != null) { // load the recent post IBlogPostEditingContext newEditingContext = recentPost.Load(); string localContents = newEditingContext.BlogPost.Contents; string localContentsSignature = newEditingContext.BlogPost.ContentsVersionSignature; // merge trackbacks from client MergeTrackbacksFromClient(editingContext.BlogPost, newEditingContext.BlogPost); // copy the BlogPost properties from the server (including merged trackbacks) newEditingContext.BlogPost.CopyFrom(editingContext.BlogPost); SynchronizeLocalContentsWithEditingContext(localContents, localContentsSignature, newEditingContext); // return the init params return newEditingContext; } else { return editingContext; } } }
/// <summary> /// Saves state to this file that includes changes the user has made /// but not saved to autoSaveSourceFile. /// </summary> /// <param name="editingContext"></param> /// <param name="autoSaveSourceFile">The original blog post file that /// this AutoSave operation is storing changes for.</param> public void AutoSave(IBlogPostEditingContext editingContext, PostEditorFile autoSaveSourceFile) { SaveCore(editingContext, autoSaveSourceFile, ManagePostFilePath(editingContext.BlogPost.IsPage, editingContext.BlogPost.Title)); }
public static void Launch(IBlogPostEditingContext editingContext) { Launch(editingContext, null); }
public void SaveContentEditorFile(IBlogPostEditingContext editingContext, string fileNameOverride, bool addToRecentDocs) { SaveCore(editingContext, null, fileNameOverride); }
public static void Launch(IBlogPostEditingContext editingContext, IDisposable splashScreen) { Launch(editingContext, false, splashScreen); }
void IBlogPostEditor.Initialize(IBlogPostEditingContext context, IBlogClientOptions clientOptions) { Text = context.BlogPost.IsPage ? Res.Get(StringId.PageProperties) : Res.Get(StringId.PostProperties); controller.Initialize(context, clientOptions); }