Revit二次开发示例:CancelSave

在Revit程序中注册文件操作事件,保存新建或打开文件的信息。当保存时,如果当前文件内容和之前的一致时,则弹出对话框提示并取消保存。对话框中有一个功能链接,点击可打开插件所在目录。

#region Namespaces
using System;
using System.Collections.Generic;
using System.IO;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI;
using Autodesk.RevitAddIns;
#endregion

namespace CancelSave
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.NoCommandData)]
    class App : IExternalApplication
    {
        const string thisAddinFileName = "CancelSave.addin";
        Dictionary<int, string> documentOriginalStatusDic = new Dictionary<int, string>();
        int hashcodeofCurrentClosingDoc;

        public Result OnStartup(UIControlledApplication a)
        {
            a.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(ReserveProjectOriginalStatus);
            a.ControlledApplication.DocumentCreated += new EventHandler<DocumentCreatedEventArgs>(ReserveProjectOriginalStatus);
            a.ControlledApplication.DocumentSaving += new EventHandler<DocumentSavingEventArgs>(CheckProjectStatusUpdate);
            a.ControlledApplication.DocumentSavingAs += new EventHandler<DocumentSavingAsEventArgs>(CheckProjectStatusUpdate);
            a.ControlledApplication.DocumentClosing += new EventHandler<DocumentClosingEventArgs>(MemClosingDocumentHashCode);
            a.ControlledApplication.DocumentClosed += new EventHandler<DocumentClosedEventArgs>(RemoveStatusofClosedDocument);

            return Result.Succeeded;
        }

        public Result OnShutdown(UIControlledApplication a)
        {
            a.ControlledApplication.DocumentOpened -= new EventHandler<DocumentOpenedEventArgs>(ReserveProjectOriginalStatus);
            a.ControlledApplication.DocumentCreated -= new EventHandler<DocumentCreatedEventArgs>(ReserveProjectOriginalStatus);
            a.ControlledApplication.DocumentSaving -= new EventHandler<DocumentSavingEventArgs>(CheckProjectStatusUpdate);
            a.ControlledApplication.DocumentSavingAs -= new EventHandler<DocumentSavingAsEventArgs>(CheckProjectStatusUpdate);
            

            LogManager.LogFinalize();

            return Result.Succeeded;
        }

        private void ReserveProjectOriginalStatus(Object sender, RevitAPIPostDocEventArgs args)
        {
            Document doc = args.Document;

            if (doc.IsFamilyDocument)
            {
                return;
            }

            LogManager.WriteLog(args, doc);

            int docHashCode = doc.GetHashCode();

            string currentProjectStatus = RetrieveProjectCurrentStatus(doc);

            documentOriginalStatusDic.Add(docHashCode, currentProjectStatus);

            LogManager.WriteLog("    Current Project Status: " + currentProjectStatus);

        }


        private void CheckProjectStatusUpdate(Object sender, RevitAPIPreDocEventArgs args)
        {

            Document doc = args.Document;

            if (doc.IsFamilyDocument)
            {
                return;
            }

            LogManager.WriteLog(args, doc);

            string currentProjectStatus = RetrieveProjectCurrentStatus(args.Document);

            string originalProjectStatus = documentOriginalStatusDic[doc.GetHashCode()];

            LogManager.WriteLog("  Current Project Status: " + currentProjectStatus + "; Orignial Project Status: " + originalProjectStatus);

            if ((string.IsNullOrEmpty(currentProjectStatus) && string.IsNullOrEmpty(originalProjectStatus)) ||
                (0 == string.Compare(currentProjectStatus, originalProjectStatus, true)))
            {
                DealNotUpdate(args);
                return;
            }

            documentOriginalStatusDic.Remove(doc.GetHashCode());
            documentOriginalStatusDic.Add(doc.GetHashCode(), currentProjectStatus);

        }

        private void MemClosingDocumentHashCode(Object sender, DocumentClosingEventArgs args)
        {
            hashcodeofCurrentClosingDoc = args.Document.GetHashCode();
        }

        private void RemoveStatusofClosedDocument(Object sender, DocumentClosedEventArgs args)
        {
            if (args.Status.Equals(RevitAPIEventStatus.Succeeded) && (documentOriginalStatusDic.ContainsKey(hashcodeofCurrentClosingDoc)))
            {
                documentOriginalStatusDic.Remove(hashcodeofCurrentClosingDoc);
            }
        }



        private static void DealNotUpdate(RevitAPIPreDocEventArgs args)
        {
            string mainMessage;
            string additionalText;
            TaskDialog taskDialog = new TaskDialog("CancelSave Sample");

            if (args.Cancellable)
            {
                args.Cancel();
                mainMessage = "CancelSave sample detected that the Project Status parameter on Project Info has not been updated. The file will not be saved."; // prompt to user.              

            }
            else
            {
                // will not cancel this event since it isn't cancellable. 
                mainMessage = "The file is about to save. But CancelSave sample detected that the Project Status parameter on Project Info has not been updated."; // prompt to user.              
            }

            if (!LogManager.RegressionTestNow)
            {
                additionalText = "You can disable this permanently by uninstaling the CancelSave sample from Revit. Remove or rename CancelSave.addin from the addins directory.";

                taskDialog.MainInstruction = mainMessage;
                taskDialog.MainContent = additionalText;
                taskDialog.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "Open the addins directory");
                taskDialog.CommonButtons = TaskDialogCommonButtons.Close;
                taskDialog.DefaultButton = TaskDialogResult.Close;
                TaskDialogResult tResult = taskDialog.Show();
                if (TaskDialogResult.CommandLink1 == tResult)
                {
                    System.Diagnostics.Process.Start("explorer.exe", DetectAddinFileLocation(args.Document.Application));
                }

            }


            LogManager.WriteLog("  Project Status is not updated, taskDialog informs user: " + mainMessage);
        }


        private static string RetrieveProjectCurrentStatus(Document doc)
        {
            if (doc.IsFamilyDocument)
            {
                return null;
            }

            return doc.ProjectInformation.Status;
        }

        private static string DetectAddinFileLocation(Autodesk.Revit.ApplicationServices.Application application)
        {
            string addinFileFolderLocation = null;
            IList<RevitProduct> installedRevitList = RevitProductUtility.GetAllInstalledRevitProducts();

            foreach (RevitProduct revit in installedRevitList)
            {
                if (revit.Version.ToString().Contains(application.VersionNumber))
                {
                    string allUsersAddInFolder = revit.AllUsersAddInFolder;
                    string currentUserAddInFolder = revit.CurrentUserAddInFolder;

                    if (File.Exists(Path.Combine(allUsersAddInFolder, thisAddinFileName)))
                    {
                        addinFileFolderLocation = allUsersAddInFolder;
                    }
                    else if (File.Exists(Path.Combine(currentUserAddInFolder, thisAddinFileName)))
                    {
                        addinFileFolderLocation = currentUserAddInFolder;
                    }

                    break;
                }
            }

            return addinFileFolderLocation;
        }
        
    }
}

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Autodesk.Revit.DB;

namespace CancelSave
{
    class LogManager
    {
        private static TextWriterTraceListener TxtListener;
        private static string AssemblyLocation = Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().Location);

        public static bool RegressionTestNow
        {
            get
            {
                string expectedLogFile = Path.Combine(AssemblyLocation, "ExpectedOutput.log");
                if (File.Exists(expectedLogFile))
                {
                    return true;
                }

                return false;
            }
        }

        static LogManager()
        {
            string actullyLogFile = Path.Combine(AssemblyLocation, "CancelSave.log");
            if (File.Exists(actullyLogFile))
            {
                File.Delete(actullyLogFile);
            }

            TxtListener = new TextWriterTraceListener(actullyLogFile);
            Trace.Listeners.Add(TxtListener);
            Trace.AutoFlush = true;
        }

        public static void LogFinalize()
        {
            Trace.Flush();
            TxtListener.Close();
            Trace.Close();
            Trace.Listeners.Remove(TxtListener);
        }

        public static void WriteLog(EventArgs args, Document doc)
        {
            Trace.WriteLine("");
            Trace.WriteLine("[Event] " + GetEventName(args.GetType()) + ": " + TitleNoExt(doc.Title));

        }

        public static void WriteLog(string message)
        {
            Trace.WriteLine(message);
        }

        private static string GetEventName(Type type)
        {
            string argName = type.ToString();
            string tail = "EventArgs";
            string head = "Autodesk.Revit.DB.Events.";
            int firstIndex = head.Length;
            int length = argName.Length - head.Length - tail.Length;
            string eventName = argName.Substring(firstIndex, length);
            return eventName;
        }

        private static string TitleNoExt(string orgTitle)
        {
            if (string.IsNullOrEmpty(orgTitle))
            {
                return "";
            }

            int pos = orgTitle.LastIndexOf('.');
            if (-1 != pos)
            {
                return orgTitle.Remove(pos);
            }
            else
            {
                return orgTitle;
            }
        }


    }
}
posted @ 2014-03-17 11:30  马语者  阅读(1755)  评论(0编辑  收藏  举报