This should get you there. But you are on your own for an xclipped blockref
[CommandMethod("ChangeInsertionpoint")]
public static void NewInsertionPoint()
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptEntityOptions peo = new PromptEntityOptions("Pick a blockreference to change the insertion point:");
peo.SetRejectMessage("Must be a blockreference:");
peo.AddAllowedClass (typeof(BlockReference),true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
PromptPointResult ppo=ed.GetPoint("Pick the new insertion point:");
if (ppo.Status != PromptStatus.OK) return;
Matrix3d ucs=ed.CurrentUserCoordinateSystem;
Point3d insPt = ppo.Value.TransformBy(ucs),newPt;
using(Transaction tr = db.TransactionManager.StartTransaction())
{
BlockReference br = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
ObjectId blockId=br.BlockTableRecord;
BlockTableRecord btr = tr.GetObject(blockId, OpenMode.ForWrite) as BlockTableRecord;
Matrix3d blockmatrix = br.BlockTransform;
insPt= insPt.TransformBy(blockmatrix.Inverse());
Vector3d v=btr.Origin-insPt;
Matrix3d move=Matrix3d.Displacement(v);
foreach (ObjectId id in btr)
{
Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
ent.TransformBy(move);
ent.DowngradeOpen();
}
ObjectIdCollection ids = btr.GetBlockReferenceIds(false, true);
foreach (ObjectId brefId in ids)
{
BlockReference b = tr.GetObject(brefId, OpenMode.ForWrite) as BlockReference;
newPt = insPt.TransformBy(b.BlockTransform);
if (b.BlockTableRecord == blockId)
{
b.TransformBy(Matrix3d.Displacement(newPt - b.Position));
}
else
{
BlockTableRecord nestedBref = tr.GetObject(b.BlockTableRecord, OpenMode.ForWrite) as BlockTableRecord;
foreach (ObjectId id in nestedBref)
{
if (id == brefId)
{
b.TransformBy(Matrix3d.Displacement(newPt - b.Position));
break;
}
}
}
AttributeCollection atts = b.AttributeCollection;
foreach (ObjectId id in atts)
{
AttributeReference at = tr.GetObject(id, OpenMode.ForWrite) as AttributeReference;
at.SetAttributeFromBlock(b.BlockTransform.Inverse());
}
//UpdateClip(db, b, v);
}
tr.Commit();
}
ed.Regen();
} // end NewInsertionPoint