| File: MS\Internal\Documents\Application\PackageController.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationUI\PresentationUI.csproj (PresentationUI) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // Description: // Responsible for the lifecycle of the PackageDocument and the actions that can // be performed on it. using System; using System.Windows.TrustUI; namespace MS.Internal.Documents.Application { /// <summary> /// Responsible for the lifecycle of the PackageDocument and the actions that can /// be performed on it. /// <see cref="MS.Internal.Documents.Application.IDocumentController"/> /// </summary> internal class PackageController : IDocumentController { #region IDocumentController Members //-------------------------------------------------------------------------- // IDocumentController Members //-------------------------------------------------------------------------- /// <summary> /// <see cref="MS.Internal.Documents.Application.IDocumentController"/> /// </summary> bool IDocumentController.EnableEdit(Document document) { PackageDocument doc = (PackageDocument)document; if (doc.Workspace != null) { doc.Package.EnableEditMode(doc.Workspace); } return true; } /// <summary> /// <see cref="MS.Internal.Documents.Application.IDocumentController"/> /// </summary> bool IDocumentController.Open(Document document) { PackageDocument doc = (PackageDocument)document; TransactionalPackage package = new RestrictedTransactionalPackage( doc.Source); doc.Package = package; DocumentProperties.Current.SetXpsProperties(package.PackageProperties); DocumentSignatureManager.Initialize(new DigitalSignatureProvider(package)); // when signatures change (are added or removed) we can no longer simply copy bits on disk DocumentSignatureManager.Current.SignaturesChanged += new EventHandler( delegate ( object sender, EventArgs args) { if (doc.IsFileCopySafe) { Trace.SafeWrite( Trace.Signatures, "Disabling file copy for current document."); doc.IsFileCopySafe = false; } }); return true; } /// <summary> /// <see cref="MS.Internal.Documents.Application.IDocumentController"/> /// </summary> bool IDocumentController.Rebind(Document document) { PackageDocument doc = (PackageDocument)document; if (doc.IsRebindNeeded) { doc.Package.Rebind(doc.Source); // no rebinds are needed above us for documents as package doc.IsRebindNeeded = false; } return true; } /// <summary> /// <see cref="MS.Internal.Documents.Application.IDocumentController"/> /// </summary> bool IDocumentController.SaveAsPreperation(Document document) { return ((IDocumentController)this).SavePreperation(document); } /// <summary> /// <see cref="MS.Internal.Documents.Application.IDocumentController"/> /// <exception cref="System.InvalidOperationException"/> /// </summary> bool IDocumentController.SaveCommit(Document document) { PackageDocument doc = (PackageDocument)document; if (doc.Destination == null) { return false; } if (doc.Package.IsDirty || !doc.IsDestinationIdenticalToSource) { StreamProxy source = doc.Source as StreamProxy; StreamProxy destination = doc.Destination as StreamProxy; // this will catch the case where our source stream is our destination // stream, which would cause corruption of the package if (source.GetHashCode() == destination.GetHashCode()) { throw new InvalidOperationException( SR.PackageControllerStreamCorruption); } // this will catch the case where no one was able to copy the stream // thus the lengths will not match if (doc.Source.Length != doc.Destination.Length) { throw new InvalidOperationException( SR.PackageControllerStreamCorruption); } // Flush the package to ensure that the relationship parts are // written out before changes are merged doc.Package.Flush(); doc.Package.MergeChanges(doc.Destination); Trace.SafeWrite(Trace.File, "Destination Merged."); } else { Trace.SafeWrite(Trace.File, "Destination Merge Skipped (nothing to do)."); } return true; } /// <summary> /// <see cref="MS.Internal.Documents.Application.IDocumentController"/> /// </summary> /// <remarks> /// This method severely breaks encapsulating the chain, however it does /// so because the requirement breaks encapsulation and the original design /// of the class only consider streams not properties. The requirement is /// that as we transition to/from a protected document we copy properties /// between the layers. It was least risk to compromise the design here /// then extend it. /// </remarks> bool IDocumentController.SavePreperation(Document document) { // we don't have to check packageDoc for because we are only responsible // for PackageDocuments PackageDocument packageDoc = (PackageDocument)document; RightsDocument rightsDoc = document.Dependency as RightsDocument; if (rightsDoc != null) { bool isDestinationProtected = rightsDoc.IsDestinationProtected(); bool isSourceProtected = rightsDoc.IsSourceProtected(); // the only time we don't need to copy properties is when // neither source nor destination is protected as OPC properties // are copied as parts // if the source was protected and the destination is not // then we need to copy properties to the package if (isSourceProtected && !isDestinationProtected) { DocumentProperties.Copy( new SuppressedProperties(rightsDoc.SourcePackage), packageDoc.Package.PackageProperties); } // if the source was not protected and the destination is // then we need to copy properties from the package to the envelope if (!isSourceProtected && isDestinationProtected) { DocumentProperties.Copy( packageDoc.Package.PackageProperties, new SuppressedProperties(rightsDoc.DestinationPackage)); } // if they were both protected we need to copy properties // from the old envelope to the new if (isDestinationProtected && isSourceProtected) { DocumentProperties.Copy( new SuppressedProperties(rightsDoc.SourcePackage), new SuppressedProperties(rightsDoc.DestinationPackage)); } } return true; } #endregion IDocumentController Members #region IChainOfResponsibiltyNode<Document> Members //-------------------------------------------------------------------------- // IChainOfResponsibiltyNode<Document> Members //-------------------------------------------------------------------------- /// <summary> /// <see cref="MS.Internal.Documents.Application.IChainOfResponsibiltyNode<T>"/> /// </summary> bool IChainOfResponsibiltyNode<Document>.IsResponsible(Document subject) { return subject is PackageDocument; } #endregion IChainOfResponsibiltyNode<Document> Members } }