예제 #1
0
        //--------------------------------------------------------------------------
        // IDocumentController Members
        //--------------------------------------------------------------------------

        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.EnableEdit(Document document)
        {
            FileDocument doc = (FileDocument)document;

            if (doc.WorkspaceProxy == null)
            {
                // Try to obtain an exclusive lock on the source file. If this
                // fails, we can still create a temporary file and Save As to a
                // different location.
                bool canWriteToSource = doc.SourceProxy.ReOpenWriteable();

                DocumentManager documentManager = DocumentManager.CreateDefault();

                // We can save to the source file if we could reopen it for write
                if (documentManager != null)
                {
                    documentManager.CanSave = canWriteToSource;
                }

                doc.WorkspaceProxy = doc.SourceProxy.CreateTemporary(false);

                if (doc.WorkspaceProxy == null)
                {
                    FilePresentation.ShowNoTemporaryFileAccess();
                }
            }

            return(doc.WorkspaceProxy != null);
        }
예제 #2
0
        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.Rebind(Document document)
        {
            FileDocument doc = (FileDocument)document;

            if (doc.IsRebindNeeded)
            {
                doc.SourceProxy.Close();
                doc.SourceProxy = null;

                try
                {
                    doc.SourceProxy = DocumentStream.Open(doc, false);
                }
                catch (UnauthorizedAccessException uae)
                {
                    FilePresentation.ShowNoAccessToSource();
                    doc.SourceProxy = null;

                    Trace.SafeWrite(
                        Trace.File,
                        "Unable to reopen specified location.\nException: {0}",
                        uae);

                    return(false);
                }
                catch (IOException ioe)
                {
                    FilePresentation.ShowNoAccessToSource();
                    doc.SourceProxy = null;

                    Trace.SafeWrite(
                        Trace.File,
                        "Unable to reopen specified location.\nException: {0}",
                        ioe);

                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.Open(Document document)
        {
            FileDocument doc = (FileDocument)document;

            if (doc.Source == null)
            {
                try
                {
                    doc.SourceProxy = DocumentStream.Open(doc, false);
                }
                catch (UnauthorizedAccessException uae)
                {
                    FilePresentation.ShowNoAccessToSource();
                    doc.SourceProxy = null;

                    Trace.SafeWrite(
                        Trace.File,
                        "Unable to open specified location.\nException: {0}",
                        uae);

                    return(false);
                }
                catch (IOException ioe)
                {
                    FilePresentation.ShowNoAccessToSource();
                    doc.SourceProxy = null;

                    Trace.SafeWrite(
                        Trace.File,
                        "Unable to open specified location.\nException: {0}",
                        ioe);

                    return(false);
                }
            }

            DocumentProperties.InitializeCurrentDocumentProperties(doc.Uri);

            return(true);
        }
예제 #4
0
        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.SaveCommit(Document document)
        {
            bool         success     = true;
            FileDocument doc         = (FileDocument)document;
            bool         haveConsent = (doc.DestinationToken != null);

            // Validate: If we have consent, if not return doing nothing.
            if (!haveConsent)
            {
                Trace.SafeWrite(
                    Trace.File,
                    "{0}.SaveCommit handling but doing nothing we do not have user consent.",
                    this);

                return(true);
            }

            doc.DestinationProxy.Flush();

            //----------------------------------------------------------------------
            // Swap Files if Needed

            if (doc.SwapDestination)
            {
                if (doc.DestinationProxy.SwapWithOriginal())
                {
                    Trace.SafeWrite(
                        Trace.File,
                        "SaveCommit has swapped Destination and Source file.");
                }
                else
                {
                    success = false;
                    FilePresentation.ShowNoAccessToDestination();
                    Trace.SafeWrite(
                        Trace.File,
                        "SaveCommit did not succeed because a needed file swap failed.");
                }

                // we attempted the operation turn off the request
                doc.SwapDestination = false;
            }

            if (success)
            {
                //------------------------------------------------------------------
                // Rebind / Reload the Document

                if (doc.SourceToken == doc.DestinationToken)
                {
                    // we changed the underlying data new keys may be required and
                    // document policy may need re-evaluating or lost our reference
                    doc.IsRebindNeeded = true;

                    Trace.SafeWrite(
                        Trace.File,
                        "SaveCommit declaring a rebind is needed.");
                }
                else
                {
                    Uri originalUri = doc.Uri;

                    // we are a new document and we should be reloaded
                    doc.Uri            = doc.DestinationToken.Location;
                    doc.IsReloadNeeded = true;
                    // we are releasing our lock on the destination
                    doc.DestinationProxy.Close();
                    doc.DestinationProxy = null;

                    Trace.SafeWrite(
                        Trace.File,
                        "SaveCommit declaring a reload to {0} is needed.",
                        doc.Uri);

                    //------------------------------------------------------------------
                    // Add Mark of Web

                    // This only needs to be done when the DestinationToken is in a
                    // different location from the SourceToken, and the equality
                    // operator on CriticalFileToken does properly compare the URI.

                    Trace.SafeWrite(
                        Trace.File,
                        "AttachmentService.SaveWithUI from {0} to {1}.",
                        originalUri,
                        doc.DestinationToken.Location);

                    AttachmentService.SaveWithUI(
                        IntPtr.Zero, originalUri, doc.DestinationToken.Location);
                }
            }

            // rescinding user consent as save is completed
            doc.DestinationToken = null;
            return(success);
        }
예제 #5
0
        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.SaveAsPreperation(Document document)
        {
            FileDocument doc = (FileDocument)document;

            CriticalFileToken sourceToken = doc.SourceToken;
            CriticalFileToken saveToken   = doc.DestinationToken;

            //----------------------------------------------------------------------
            // Get Save Location and Consent (if needed)

            bool haveConsent = false;
            bool cancelSave  = false;

            // Loop until we have consent to save to a file or the user cancels
            while (!haveConsent && !cancelSave)
            {
                // If we have a location, check to see if it is read-only
                if (saveToken != null)
                {
                    if (DocumentStream.IsReadOnly(saveToken))
                    {
                        // If the target file is read-only, we cannot save over it
                        FilePresentation.ShowDestinationIsReadOnly();
                    }
                    else
                    {
                        // If the file isn't read-only, we now have consent to save
                        haveConsent = true;
                    }
                }

                if (!haveConsent)
                {
                    Trace.SafeWrite(
                        Trace.File, "We don't have a save location, prompting user.");

                    // by default set the same file
                    if (saveToken == null)
                    {
                        saveToken = sourceToken;
                    }

                    // A false return value indicates that the user wanted to
                    // cancel the save
                    cancelSave = !FilePresentation.ShowSaveFileDialog(ref saveToken);
                }
                else
                {
                    // Otherwise we do have consent to save to the location stored in
                    // the saveToken
                    doc.DestinationToken = saveToken;
                }
            }

            // Validate: If still don't have consent return without saving
            if (!haveConsent)
            {
                // ensure token is rescinded
                doc.DestinationToken = null;

                Trace.SafeWrite(
                    Trace.File,
                    "{0} not handling we do not have user consent.",
                    this);

                return(false);
            }

            bool isFileCopySafe = doc.IsFileCopySafe;

            //----------------------------------------------------------------------
            // Calculate Save Action
            SaveAction action = SaveAction.Unknown;

            if (doc.Source.CanWrite)
            {
                action |= SaveAction.SourceIsWriteable;
            }
            if (sourceToken == saveToken)
            {
                action |= SaveAction.TargetIsSelf;
            }
            if (isFileCopySafe)
            {
                action |= SaveAction.CanCopyData;
            }

            bool isDestinationIdentical = false;

            // Catch IO Exceptions; will return false and clear token
            try
            {
                //----------------------------------------------------------------------
                // Perform Optimal Save Action (see method remarks)
                switch (action)
                {
                // Example: We were successfully able to open the source package
                // for write and there were no RM changes.
                // I/O Cost: Read & SafeWrite Changes
                case SaveAction.TargetIsSelf
                    | SaveAction.SourceIsWriteable
                    | SaveAction.CanCopyData:

                    Trace.SafeWrite(
                        Trace.File,
                        "SaveAction {0}: Updating comparee to self.",
                        action);

                    doc.DestinationProxy   = doc.SourceProxy;
                    isDestinationIdentical = true;
                    break;

                // Example: Another user / process had a lock on the file, however
                // we would like to save now and there were no RM changes.
                // I/O Cost: Varies (Read & SafeWrite Changes - Read & SafeWrite Sum)
                case SaveAction.TargetIsSelf | SaveAction.CanCopyData:

                    Trace.SafeWrite(
                        Trace.File,
                        "SaveAction {0}: reopening editable, updating comparee to self.",
                        action);

                    // re-open writeable if possible otherwise copy the file
                    if (doc.SourceProxy.ReOpenWriteable())
                    {
                        doc.DestinationProxy   = doc.SourceProxy;
                        isDestinationIdentical = true;
                    }
                    else
                    {
                        Trace.SafeWrite(
                            Trace.File,
                            "SaveAction {0}: creating a temporary document reopen failed.",
                            action);

                        doc.DestinationProxy = doc.SourceProxy.CreateTemporary(true);
                        doc.SwapDestination  = true;
                    }
                    break;

                case SaveAction.TargetIsSelf | SaveAction.SourceIsWriteable:
                case SaveAction.TargetIsSelf:
                    Trace.SafeWrite(
                        Trace.File,
                        "SaveAction {0}: creating a temporary document.",
                        action);
                    doc.DestinationProxy = doc.SourceProxy.CreateTemporary(false);
                    doc.SwapDestination  = true;
                    break;

                // Example: All other cases, like source is web based.
                // I/O Cost: Max (Read Sum & SafeWrite Sum)
                default:
                    Trace.SafeWrite(
                        Trace.File,
                        "SaveAction {0}: Performing defaults.",
                        action);
                    if (isFileCopySafe)
                    {
                        Trace.SafeWrite(
                            Trace.File,
                            "SaveAction {0}: copying original document.",
                            action);
                        doc.DestinationProxy   = doc.SourceProxy.Copy(saveToken);
                        isDestinationIdentical = true;
                    }
                    else
                    {
                        doc.DestinationProxy = DocumentStream.Open(saveToken, true);
                        // ensure we have enough quota to be as large as the sum
                        doc.DestinationProxy.SetLength(
                            doc.SourceProxy.Length +
                            (doc.WorkspaceProxy == null ? 0 : doc.WorkspaceProxy.Length));
                        // set it back as we don't do the copy
                        doc.DestinationProxy.SetLength(0);
                    }
                    doc.SwapDestination = false;
                    break;
                } // switch (action)

                // Set the IsDestinationIdenticalToSource flag on the document
                // depending on what happened above
                doc.IsDestinationIdenticalToSource = isDestinationIdentical;

                return(true);
            }
            catch (UnauthorizedAccessException uae)
            {
                FilePresentation.ShowNoAccessToDestination();
                doc.DestinationProxy = null;
                // ensure token is recinded
                doc.DestinationToken = null;

                Trace.SafeWrite(
                    Trace.File,
                    "SaveAction {0}: unable to open specified location.\nException: {1}",
                    action,
                    uae);

                return(false);
            }
            catch (IOException ioe)
            {
                FilePresentation.ShowNoAccessToDestination();
                doc.DestinationProxy = null;
                // ensure token is recinded
                doc.DestinationToken = null;

                Trace.SafeWrite(
                    Trace.File,
                    "SaveAction {0}: unable to set size at specified location.\nException: {1}",
                    action,
                    ioe);

                return(false);
            }
        }