-
Notifications
You must be signed in to change notification settings - Fork 0
/
LayoutCount.cs
176 lines (149 loc) · 5.78 KB
/
LayoutCount.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices.LayoutUtils;
using Autodesk.AutoCAD.ApplicationServices.AsyncHelpers;
/// Prerequisites:
///
/// https://github.com/ActivistInvestor/AcMgdUtility/blob/main/DocumentCollectionExtensions.cs
///
/// Coding example showing how to maintain and display the
/// number of paper space layouts in a field or expression.
/// Requires DocumentCollectionExtensions.cs located at the
/// above URL.
/// This attribute tells AutoCAD what type implements the
/// IExtensionApplication interface, allowing it to avoid
/// having to scan every type in the assembly:
[assembly: ExtensionApplication(typeof(LayoutCountApplication))]
namespace Autodesk.AutoCAD.ApplicationServices.LayoutUtils
{
/// <summary>
/// IExtension application (Note: do not create
/// instances of this class from code, AutoCAD
/// will create an instance when the containing
/// assembly loads. Also note that there can be
/// one and only one IExtensionApplication in an
/// assembly).
/// </summary>
public class LayoutCountApplication : IExtensionApplication
{
LayoutCountMonitor layoutCountMonitor;
public async void Initialize()
{
await Application.DocumentManager.WaitForIdle();
layoutCountMonitor = new LayoutCountMonitor();
}
public void Terminate()
{
}
}
/// <summary>
/// A class that monitors the number of paperspace layouts
/// in each document and exposes the count through a USERIx
/// system variable, for use in fields. The default name of
/// the system variable that stores the values is USERI5,
/// which has document-scope. The USSERIx system variable
/// used by this class must not be used for other purposes.
///
/// An alternative to using a USERIx system variable is to
/// define a custom system variable in the registry, that
/// has document scope (e.g., has a distinct value for each
/// document). Doing that, is beyond the scope of this basic
/// example.
/// </summary>
public class LayoutCountMonitor : LazyDocumentManager
{
/// <summary>
/// The system variable that stores the count of
/// layouts for each document. This system variable
/// has document-scope, and can be referenced from
/// fields, DIESEL, LISP, etc.
/// </summary>
public const string SystemVariable = "USERI5";
public LayoutCountMonitor()
{
AutoUpdateFields = true;
}
protected override void Initialize(Document document)
{
LayoutManager manager = LayoutManager.Current;
manager.LayoutCreated += layoutsChanged;
manager.LayoutRemoved += layoutsChanged;
manager.LayoutCopied += layoutCopied;
Update();
}
/// <summary>
/// Gets/sets a value indicating if fields should be
/// updated when the number of layouts changes:
/// </summary>
public bool AutoUpdateFields { get; set; }
void layoutCopied(object sender, LayoutCopiedEventArgs e)
{
Update();
}
void layoutsChanged(object sender, LayoutEventArgs e)
{
Update();
}
/// <summary>
/// Updates the system variable when a layout
/// is added to or removed from the Layouts
/// collection. Calls EvaluateFields() to update
/// fields in the active document if the value
/// has changed and AutoUpdateFields is true.
/// </summary>
void Update()
{
var docmgr = Application.DocumentManager;
Document doc = docmgr.MdiActiveDocument;
if(doc != null)
{
int curval = (int)Application.GetSystemVariable(SystemVariable);
int newval = LayoutManager.Current.LayoutCount - 1;
if(curval != newval)
{
Application.SetSystemVariable(SystemVariable, newval);
if(AutoUpdateFields)
docmgr.InvokeAsCommand(() => doc.Database.EvaluateFields());
}
}
}
}
/// <summary>
/// A variant of DocumentManager that operates in a lazy
/// mode, deferring initialization of each document until
/// the first time it becomes active. This is sometimes
/// necessary when initialization requires a document to
/// be active.
///
/// Unlike DocumentManager, this class does not initialize
/// documents that exist when an instance is created in an
/// 'eager' mode. All documents except the active document
/// are subsequently initialized the first time they are
/// activated after the instance of this class is created.
/// The active document is initialized when the instance is
/// created.
///
/// Derive a class from LazyDocumentManager, and override
/// the Initialize() method to do one-time initialization
/// when the document passed as the argument becomes active.
/// </summary>
public abstract class LazyDocumentManager
{
HashSet<Document> initialized = new HashSet<Document>();
static DocumentCollection docs = Application.DocumentManager;
protected LazyDocumentManager()
{
docs.DocumentActivated += documentActivated;
Document doc = docs.MdiActiveDocument;
if(doc != null && initialized.Add(doc))
Initialize(doc);
}
void documentActivated(object sender, DocumentCollectionEventArgs e)
{
if(initialized.Add(e.Document))
Initialize(e.Document);
}
protected abstract void Initialize(Document document);
}
}