using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Geometry;
//[assembly: CommandClass(typeof(CivilPiling.PileOverruleCommands))]
namespace CivilPiling
{
public static partial class Tools
{
static Tools()
{
Application.QuitWillStart += quitWillStart;
}
static void quitWillStart( object sender, EventArgs e )
{
Application.QuitWillStart -= quitWillStart;
if( overrule != null )
{
//Application.ShowAlertDialog("Quit start");
overrule.Dispose();
overrule = null;
GC.Collect(2, GCCollectionMode.Default, true);
}
}
public static PileOverrule overrule
= new PileOverrule
(true); }
public class PileOverrule : ObjectOverrule
{
bool enabled = false;
RXClass rxclass
= RXClass
.GetClass(typeof(Line
)); static string AppName = "CADWORX_STEEL";
public static Dictionary<IntPtr, PileRevision> currentPiles;
public static Dictionary<IntPtr, PileRevision> issuedPiles;
public PileOverrule(bool enabled = true)
{
currentPiles
= new Dictionary
<IntPtr, PileRevision
>(); issuedPiles
= new Dictionary
<IntPtr, PileRevision
>(); Application.DocumentManager.DocumentCreated += DocumentManager_DocumentCreated;
Enabled = enabled;
this.SetXDataFilter(AppName);
}
//Add database to watch list if it has the appname we're interested in
void DocumentManager_DocumentCreated(object sender, DocumentCollectionEventArgs e)
{
WatchDatabase(e.Document.Database);
}
public static void WatchDatabase(Database db)
{
if (db.isInteresting())
{
if (!currentPiles.ContainsKey(db.UnmanagedObject))
{
//Application.ShowAlertDialog(
string.Format("Watching {0}", db.Filename).WriteMessage();
db.BeginSave += Database_BeginSave;
db.DatabaseToBeDestroyed += db_DatabaseToBeDestroyed;
currentPiles
.Add(db
.UnmanagedObject,
new PileRevision
(db, Tools
.RevCurrent)); if (db.isInteresting())//if db had invalid data it would no longer be interesting at this point
{
PileRev value = db.GetLastIssuedRevision();
if (!value.IsNull()) issuedPiles
.Add(db
.UnmanagedObject,
new PileRevision
(db,
value)); }
}
}
}
public static void StopWatching(Database db)
{
if (currentPiles.ContainsKey(db.UnmanagedObject))
currentPiles.Remove(db.UnmanagedObject);
if (issuedPiles.ContainsKey(db.UnmanagedObject))
issuedPiles.Remove(db.UnmanagedObject);
db.BeginSave -= Database_BeginSave;
db.DatabaseToBeDestroyed -= db_DatabaseToBeDestroyed;
}
public static void UpdateIssuedRev(Database db, string Revision)
{
//update issued piles
if (issuedPiles
.ContainsKey(db
.UnmanagedObject)) issuedPiles
[db
.UnmanagedObject] = new PileRevision
(db, Revision
); else issuedPiles
.Add(db
.UnmanagedObject,
new PileRevision
(db, Revision
)); //update current piles
currentPiles[db.UnmanagedObject].ClearFlags();
}
static void db_DatabaseToBeDestroyed(object sender, EventArgs e)
{
try
{
string.Format("Database {0} to be destroyed", ((Database)sender).Filename).WriteMessage();
}
finally
{
}
Database db = (Database)sender;
if (currentPiles.ContainsKey(db.UnmanagedObject))
currentPiles.Remove(db.UnmanagedObject);
if (issuedPiles.ContainsKey(db.UnmanagedObject))
issuedPiles.Remove(db.UnmanagedObject);
}
////remove database from our dictionary
//void Database_Disposed(object sender, EventArgs e)
//{
// string.Format("Database {0} disposed", ((Database)sender).Filename).WriteMessage();
// Database db = (Database)sender;
// if (currentPiles.ContainsKey(db.UnmanagedObject))
// currentPiles.Remove(db.UnmanagedObject);
//}
//save our dictionary into the current rev place
static void Database_BeginSave(object sender, DatabaseIOEventArgs e)
{
try
{
Database db = (Database)sender;
if (currentPiles.ContainsKey(db.UnmanagedObject))
using (Transaction tr = db.TransactionManager.StartTransaction())
{
//Don't think this is required
//DBDictionary revDict;
//db.GetCreateRevDict(out revDict);
string.Format("Database {0} begin save", e.FileName).WriteMessage();
currentPiles
[db
.UnmanagedObject].Issue(new PileRev
(Tools
.RevCurrent)); tr.Commit();
}
}
catch (System.Exception ex)
{
ex.Show();
}
}
public virtual bool Enabled
{
get
{
return this.enabled;
}
set
{
if (this.enabled ^ value)
{
this.enabled = value;
if (value)
{
Overrule.AddOverrule(rxclass, this, true);
this.SetXDataFilter(Tools.AppName);
}
else
Overrule.RemoveOverrule(rxclass, this);
OnEnabledChanged(this.enabled);
}
}
}
public override void Erase(DBObject dbObject, bool erasing)
{
Database db = dbObject.Database;
if (currentPiles.ContainsKey(db.UnmanagedObject) && currentPiles[db.UnmanagedObject].LivePiles.ContainsKey(dbObject.ObjectId))
{
if (erasing)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nRemoving {0} from {1}", dbObject.Id, db.Filename);
currentPiles[db.UnmanagedObject].LivePiles[dbObject.Id].Changes |= PileChanges.Deleted;
currentPiles[db.UnmanagedObject].LivePiles[dbObject.Id].Erased = true;
}
else
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nUndoing removing {0} from {1}", dbObject.Id, db.Filename);
currentPiles[db.UnmanagedObject].LivePiles[dbObject.Id].Changes &= PileChanges.NewPile;
currentPiles[db.UnmanagedObject].LivePiles[dbObject.Id].Erased = false;
}
}
base.Erase(dbObject, erasing);
}
public override void Close(DBObject obj)
{
try
{
PileDataSet pds = obj.ReportExData();
if (pds != null)
{
Database db = obj.Database;
if (currentPiles.ContainsKey(db.UnmanagedObject))
{
ObjectId id = obj.ObjectId;
if (obj.IsErased)
{
}
else if (obj.IsNewObject)
{
////////////////////////////////////////////////need to thrash pile tag in xdata
try
{
obj.SetPileTag(" ");
pds.Changes = PileChanges.NewPile;
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nAdding {0} to {1}", id, db.Filename);
currentPiles[db.UnmanagedObject].LivePiles.Add(obj.ObjectId, pds);
}
catch (System.Exception e)
{
Application.ShowAlertDialog(string.Format("Fail: {0}", e));
}
}
else if (obj.IsModified)
{
////////////////////////////////////////////////////////////////////determine modifications, update current rev
if (issuedPiles.ContainsKey(db.UnmanagedObject) && issuedPiles[db.UnmanagedObject].LivePiles.ContainsKey(id))
{
//check all properties against original
PileDataSet issued = issuedPiles[db.UnmanagedObject].LivePiles[pds.Id];
if (pds.PileTag != issued.PileTag) pds.Changes |= PileChanges.PileTag;
if (pds.PileLength != issued.PileLength) pds.Changes |= PileChanges.PileLength;
if (pds.PileSize != issued.PileSize) pds.Changes |= PileChanges.PileSize;
if (pds.Location.X != issued.Location.X) pds.Changes |= PileChanges.XCoordinate;
if (pds.Location.Y != issued.Location.Y) pds.Changes |= PileChanges.YCoordinate;
if (pds.Location.Z != issued.Location.Z) pds.Changes |= PileChanges.ZCoordinate;
string.Format("Changing {0}: {1}", pds.PileTag == null ? "" : pds.PileTag, pds.GetFlags()).WriteMessage();
}
else
{
//must be new object since last issue? we can or the changes of the pds we're looking at with the one in current issue?
pds.Changes |= currentPiles[db.UnmanagedObject].LivePiles[pds.Id].Changes;
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nNew since last rev {0}: {1}", id, pds.GetFlags());
}
currentPiles[db.UnmanagedObject].LivePiles[id] = pds;
}
}
}
}
catch (System.Exception e) { e.Show(); }
base.Close(obj);
}
protected virtual void OnEnabledChanged(bool enabled)
{
}
protected override void Dispose(bool disposing)
{
if (disposing && !base.IsDisposed)
{
Enabled = false;
rxclass.Dispose();
foreach (IntPtr db in currentPiles.Keys)
{
string.Format("Destroying {0} data", db).WriteMessage();
currentPiles.Remove(db);
}
currentPiles = null;
Application.DocumentManager.DocumentCreated -= DocumentManager_DocumentCreated;
}
base.Dispose(disposing);
}
}
}