Ejemplo n.º 1
0
        ///<summary>
        /// Save the buffer as a file, using an asynchronous model
        ///</summary>
        public IAsyncResult BeginSaveAs(string filename, ProgressCallback progressCallback, AsyncCallback ac)
        {
            lock (LockObj) {
                if (!fileOperationsAllowed)
                {
                    return(null);
                }

                saveFinishedEvent.Reset();
                userSaveAsyncCallback = ac;

                SaveAsOperation so = new SaveAsOperation(this, filename, progressCallback, SaveAsAsyncCallback, useGLibIdle);

                // don't allow messing up with the buffer
                // while we are saving
                // ...ReadAllowed is set in SaveOperation
                // this.ReadAllowed = false;
                this.ModifyAllowed         = false;
                this.FileOperationsAllowed = false;
                this.EmitEvents            = false;
                if (fsw != null)
                {
                    fsw.EnableRaisingEvents = false;
                }

                // start save thread
                Thread saveThread = new Thread(so.OperationThread);
                saveThread.IsBackground = true;
                saveThread.Start();

                return(new ThreadedAsyncResult(so, saveFinishedEvent, false));
            }
        }
Ejemplo n.º 2
0
        protected override void DoOperation()
        {
            SaveAsOperation sao = new SaveAsOperation(byteBuffer, tempPath, this.progressCallback, null, false);

            stageReached = SaveStage.BeforeSaveAs;

            // Check for free space for final file
            // free space for temporary file is checked in sao.DoOperation()
            if (!CheckFreeSpace(Path.GetDirectoryName(byteBuffer.Filename), byteBuffer.fileBuf.Size))
            {
                string msg = string.Format(Catalog.GetString("There is not enough free space on the device to save file '{0}'."), byteBuffer.Filename);
                throw new IOException(msg);
            }

            // Save ByteBuffer as a temp file
            sao.OperationThread();

            if (sao.Result == ThreadedAsyncOperation.OperationResult.CaughtException)
            {
                throw sao.ThreadException;
            }
            else if (sao.Result == ThreadedAsyncOperation.OperationResult.Cancelled)
            {
                cancelled = true;
            }

            // if user hasn't cancelled, move temp file to
            // its final location
            if (!cancelled)
            {
                this.ActivateProgressReport(true);
                stageReached = SaveStage.BeforeDelete;

                // Delete here to fail early (before invalidating the byteBuffer)
                // if there are any issues.
                if (System.IO.File.Exists(savePath))
                {
                    System.IO.File.Delete(savePath);
                }

                // close the file, make sure that File Operations
                // are temporarily allowed
                lock (byteBuffer.LockObj) {
                    // CloseFile invalidates the file buffer,
                    // so make sure undo/redo data stays valid
                    byteBuffer.MakePrivateCopyOfUndoRedo();
                    byteBuffer.FileOperationsAllowed = true;
                    byteBuffer.CloseFile();
                    byteBuffer.FileOperationsAllowed = false;
                }

                stageReached = SaveStage.BeforeMove;
                System.IO.File.Move(tempPath, savePath);
            }
        }
Ejemplo n.º 3
0
        ///<summary>
        /// Called when an asynchronous Save As operation finishes
        ///</summary>
        void SaveAsAsyncCallback(IAsyncResult ar)
        {
            lock (LockObj) {
                SaveAsOperation so = (SaveAsOperation)ar.AsyncState;

                // re-allow buffer usage
                this.FileOperationsAllowed = true;


                // make sure Save As went smoothly before doing anything
                if (so.Result == SaveAsOperation.OperationResult.Finished)
                {
                    // make sure data in undo redo are stored safely
                    // because we are going to close the file
                    MakePrivateCopyOfUndoRedo();
                    CloseFile();
                    LoadWithFile(so.SavePath);

                    if (undoDeque.Count > 0)
                    {
                        SaveCheckpoint = undoDeque.PeekFront();
                    }
                    else
                    {
                        SaveCheckpoint = null;
                    }

                    changedBeyondUndo = false;
                }
                else
                {
                    // if cancelled or caught an exception
                    // delete the file only if we have altered it
                    if (so.StageReached != SaveAsOperation.SaveAsStage.BeforeCreate)
                    {
                        try {
                            System.IO.File.Delete(so.SavePath);
                        }
                        catch (Exception e) {
                            System.Console.WriteLine(e.Message);
                        }
                    }
                }

                // re-allow buffer usage
                this.ReadAllowed   = true;
                this.ModifyAllowed = true;

                this.EmitEvents = true;

                if (fsw != null)
                {
                    fsw.EnableRaisingEvents = true;
                }

                // notify the world about the changes
                EmitPermissionsChanged();
                EmitChanged();

                // if user provided a callback, call it now
                if (userSaveAsyncCallback != null)
                {
                    userSaveAsyncCallback(ar);
                }

                // notify that Save As has finished
                saveFinishedEvent.Set();
            }
        }