//
// (C) Copyright 2003-2021 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB.Events;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using Autodesk.RevitAddIns;
using Autodesk.Revit.UI.Events;
using System.Linq;
namespace Revit.SDK.Samples.SelectionChanged.CS
{
///
/// This class is an external application which monitors when the selection is changed.
///
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
public class SelectionChanged : IExternalApplication
{
#region Class Member Variables
///
/// A controlled application used to register the events. Because all trigger points
/// in this sample come from UI, all events in application level must be registered
/// to ControlledApplication. If the trigger point is from API, user can register it
/// to Application or Document according to what level it is in. But then,
/// the syntax is the same in these three cases.
///
private static UIControlledApplication m_ctrlApp;
///
/// The window is used to show SelectionChanged event information.
///
private static InfoWindow m_infoWindow;
static string AddInPath = typeof(SelectionChanged).Assembly.Location;
#endregion
#region Class Static Property
///
/// Property to get and set private member variable of InfoWindows
///
public static InfoWindow InfoWindow
{
get;
set;
}
#endregion
#region IExternalApplication Members
///
/// Implement OnStartup method of IExternalApplication interface.
/// This method subscribes to SelectionChanged event.
///
/// Controlled application to be loaded to Revit process.
/// The status of the external application
public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
m_ctrlApp = application;
RibbonPanel ribbonPanel = m_ctrlApp.CreateRibbonPanel("SelectionChanged Event");
PushButtonData showInfoWindowButton = new PushButtonData("showInfoWindow", "Show Event Info", AddInPath, "Revit.SDK.Samples.SelectionChanged.CS.Command");
showInfoWindowButton.ToolTip = "Show Event Monitor window";
ribbonPanel.AddItem(showInfoWindowButton);
// subscribe to SelectionChanged event
application.SelectionChanged += new EventHandler(SelectionChangedHandler);
return Autodesk.Revit.UI.Result.Succeeded;
}
///
/// Implement OnShutdown method of IExternalApplication interface.
/// This method unsubscribes from SelectionChanged event
///
/// Controlled application to be shutdown.
/// The status of the external application.
public Autodesk.Revit.UI.Result OnShutdown(UIControlledApplication application)
{
// unsubscribe to SelectionChanged event
application.SelectionChanged -= new EventHandler(SelectionChangedHandler);
// finalize the log file.
LogManager.LogFinalize();
if (m_infoWindow != null)
{
m_infoWindow.Close();
m_infoWindow = null;
}
return Autodesk.Revit.UI.Result.Succeeded;
}
#endregion
#region EventHandler
///
/// Event handler method for SelectionChanged event.
/// This method will check that the selection reported by event is the same with the actual Revit selection
/// and print the current selection in the log file.
///
/// The source of the event.
/// Event arguments that contains the event data.
private void SelectionChangedHandler(Object sender, SelectionChangedEventArgs args)
{
// The document associated with the event.
Document doc = args.GetDocument();
//Check if Revit selection matches the selection reported by the event
UIDocument uidoc = new UIDocument(doc);
IList currentSelection = uidoc.Selection.GetReferences();
IList reportedSelection = args.GetReferences();
if (!currentSelection.All(i => null != reportedSelection.FirstOrDefault(r => r.EqualTo(i))))
{
LogManager.WriteLog("Error: Current selection is different from the selection reported by the selectionchanged event");
}
var currentSelectedElementIds = uidoc.Selection.GetElementIds();
var reportedSelectedElementIds = args.GetSelectedElements();
if (!currentSelectedElementIds.All(i => null != reportedSelectedElementIds.FirstOrDefault(r => r == i)))
{
LogManager.WriteLog("Error: Current selected ElementIds is different from the one reported by the selectionchanged event");
}
// write to log file.
LogManager.WriteLog(args.GetInfo());
if(InfoWindow != null)
{
InfoWindow.RevitUIApp_SelectionChanged(sender, args);
}
}
#endregion
}
}