Author Topic: Block Count in a ToolTip  (Read 1453 times)

0 Members and 1 Guest are viewing this topic.

Offline (gile)

  • C#
  • *
  • Posts: 87
  • Karma: +8/-0
  • Gender: Male
    • prefered language: F
    • Prog expertise: Good
    • View Profile
Block Count in a ToolTip
« on: November 08, 2013, 04:15:07 PM »
Hi,

Here's an example of Editor.PointMonitor event handling.
A toolTip displays the number of inserts in the current space of the block reference which the pickbox is hovering over.

C#
Code: [Select]
// (C) Copyright 2012 by Gilles Chanteau
//
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: ExtensionApplication(typeof(Gile.BlockCountExtensionApplication.BlockCountToolTip))]

namespace Gile.BlockCountExtensionApplication
{
    public class BlockCountToolTip : IExtensionApplication
    {
        private static DocumentCollection docs;
        private static RXClass blockRefClass;

        public void Initialize()
        {
            docs = AcAp.DocumentManager;
            blockRefClass = RXClass.GetClass(typeof(BlockReference));
            docs.DocumentCreated += onDocumentCreated;
            foreach (Document doc in docs)
            {
                doc.Editor.PointMonitor += onPointMonitor;
            }
        }

        public void Terminate() { }

        void onDocumentCreated(object sender, DocumentCollectionEventArgs e)
        {
            if (e.Document != null)
                e.Document.Editor.PointMonitor += onPointMonitor;
        }

        void onPointMonitor(object sender, PointMonitorEventArgs e)
        {
            if ((e.Context.History & PointHistoryBits.FromKeyboard) == PointHistoryBits.FromKeyboard)
                return;

            FullSubentityPath[] paths = e.Context.GetPickedEntities();

            if (paths == null || paths.Length == 0)
                return;

            ObjectId[] ids = paths[0].GetObjectIds();

            if (ids == null || ids.Length == 0)
                return;

            ObjectId id = ids[0];

            if (id.IsValid && id.ObjectClass == blockRefClass)
            {
                Database db = id.Database;
                int cnt = 0;
                using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
                {
                    BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                    bool isDyn = br.IsDynamicBlock;
                    BlockTableRecord btr = isDyn ?
                        (BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead) :
                        (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
                    string name = btr.Name;
                    ObjectId cSpaceId = db.CurrentSpaceId;
                    foreach (ObjectId brId in btr.GetBlockReferenceIds(true, false))
                    {
                        DBObject bRef = tr.GetObject(brId, OpenMode.ForRead);
                        if (bRef.OwnerId == cSpaceId)
                            cnt++;
                    }
                    if (isDyn)
                    {
                        foreach (ObjectId anonId in btr.GetAnonymousBlockIds())
                        {
                            BlockTableRecord anonBtr = (BlockTableRecord)tr.GetObject(anonId, OpenMode.ForRead);
                            foreach (ObjectId brId in anonBtr.GetBlockReferenceIds(true, false))
                            {
                                DBObject bRef = tr.GetObject(brId, OpenMode.ForRead);
                                if (bRef.OwnerId == cSpaceId)
                                    cnt++;
                            }
                        }
                    }
                    e.AppendToolTipText(String.Format("'{0}' {1}\n{2} insert{3}\n",
                        btr.Name,
                        isDyn ? "(dynamic)" : "",
                        cnt,
                        cnt > 1 ? "s" : ""));
                    tr.Commit();
                }
            }
        }
    }
}

F#
Code: [Select]
// (C) Copyright 2012 by Gilles Chanteau
//
module Gile.BlockCount

open System
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Runtime

let docMan = Application.DocumentManager
let blkRefClass = RXClass.GetClass(typeof<BlockReference>)

type BCountToolTip() =
    let pointMonitor (e: PointMonitorEventArgs) =
        if (e.Context.History &&& PointHistoryBits.FromKeyboard) <> PointHistoryBits.FromKeyboard then
            let paths = e.Context.GetPickedEntities()
            if paths <> null && paths.Length > 0 then
                let ids = paths.[0].GetObjectIds()
                if ids <> null && ids.Length > 0 then
                    let id  = ids.[0]
                    if id.IsValid && id.ObjectClass = blkRefClass then
                        let db = id.Database
                        let spaceId = db.CurrentSpaceId
                        use tr = db.TransactionManager.StartOpenCloseTransaction()

                        let countRefs (btr: BlockTableRecord) =
                            btr.GetBlockReferenceIds(true, false)
                            |> Seq.cast
                            |> Seq.filter(fun id -> tr.GetObject(id, OpenMode.ForRead).OwnerId = spaceId)
                            |> Seq.length

                        let br = tr.GetObject(id, OpenMode.ForRead) :?> BlockReference
                        let isDyn = br.IsDynamicBlock
                        let btrId = if isDyn then br.DynamicBlockTableRecord else br.BlockTableRecord
                        let btr = tr.GetObject(btrId, OpenMode.ForRead) :?> BlockTableRecord
                        let cnt =
                            countRefs btr +
                            if isDyn then
                                seq { for id in btr.GetAnonymousBlockIds() ->
                                        tr.GetObject(id, OpenMode.ForRead) :?> BlockTableRecord |> countRefs }
                                |> Seq.sum
                            else 0
                        e.AppendToolTipText(String.Format("'{0}' {1}\n{2} insert{3}\n",
                                                            btr.Name,
                                                            (if isDyn then "(dynamic)" else ""),
                                                            cnt,
                                                            if cnt > 1 then "s" else ""))
                        tr.Commit()

    interface IExtensionApplication with
        member x.Initialize() =
            docMan.DocumentCreated.AddHandler(fun o e ->
                if e.Document <> null then
                    e.Document.Editor.PointMonitor.AddHandler(fun o e -> pointMonitor e))
            docMan.DocumentToBeDestroyed.AddHandler(fun o e ->
                if e.Document <> null then
                    e.Document.Editor.PointMonitor.RemoveHandler(fun o e -> pointMonitor e))
            docMan
            |> Seq.cast<Document>
            |> Seq.iter(fun doc -> doc.Editor.PointMonitor.AddHandler(fun o e -> pointMonitor e))
        member x.Terminate() = ()
« Last Edit: November 08, 2013, 04:31:46 PM by (gile) »

Offline Patriiick

  • Administrator
  • *****
  • Posts: 130
  • Karma: +1/-0
  • Gender: Male
    • prefered language: VB
    • Prog expertise: Good
    • View Profile
  • Twitter: @Patriiick
Re: Block Count in a ToolTip
« Reply #1 on: November 08, 2013, 04:16:48 PM »
Thanks, very useful!  :clin_oeil_rapide: