AcEdSSGetFilter Remove item from selection - Not Working

AcEdSSGetFilter Remove item from selection - Not Working

Kyudos
Advisor Advisor
1,123 Views
6 Replies
Message 1 of 7

AcEdSSGetFilter Remove item from selection - Not Working

Kyudos
Advisor
Advisor

During one of my commands I need to limit what the user is allowed to select, so I'm using AcEdSSGetFilter::endSSGet. However, even though my remove call comes back OK, the things I don't want to be selected are still selected. What am I doing wrong?

 

Code:

 

//------------------------------------------------------------------------------
void MySelectionReactor::endSSGet(Acad::PromptStatus returnStatus, int ssgetFlags, AcEdSelectionSetService& service, const AcDbObjectIdArray& selectionSet)
//------------------------------------------------------------------------------
{
    Acad::ErrorStatus es = Acad::eOk;
    if (pApp->VetoActive())
    {
        CADManager.StartTransaction(__FUNCTION__);

        for (int i = 0; i < selectionSet.length(); i++)
        {
            AcDbObjectId id = selectionSet.at(i);
            AcDbObject* pObject = CADManager.GetAcDbObject(id, AcDb::kForRead);
            AcDbBlockReference* pBlockReference = dynamic_cast<AcDbBlockReference*>(pObject);
            MyClass* pMine = dynamic_cast<MyClass*>(pObject);
            if (pBlockReference == NULL)
            {
                es = service.remove(i);
            }
            else if (pMine != NULL)
            {
                es = service.remove(i);
            }
        }

        CADManager.EndTransaction(__FUNCTION__);
    }
}

(I only want to allow the user to click on block reference objects, except a specific type of block reference object - MyClass)

0 Likes
Accepted solutions (1)
1,124 Views
6 Replies
Replies (6)
Message 2 of 7

BerndCuder8196
Advocate
Advocate

This code i have tested with my custom blockreference and it will work fine:

 

void MySelectionReactor::endSSGet(Acad::PromptStatus returnStatus, int ssgetFlags, AcEdSelectionSetService &service, const AcDbObjectIdArray& selectionSet)
{
	if (returnStatus != Acad::eNormal)
	{
		return;
	}

	for (int i = 0; i < selectionSet.length(); i++)
	{
		AcDbObjectId id = selectionSet.at(i);

		AcDbObject* pObject;

		if (acdbOpenObject(pObject, id, AcDb::kForRead) == Acad::eOk)
		{
			AcDbBlockReference* pBlockReference = dynamic_cast<AcDbBlockReference*>(pObject);

			MyClass* pMine = dynamic_cast<MyClass*>(pObject);

			if (pBlockReference == NULL)
			{
				service.remove(i);
			}
			else if (pMine != NULL)
			{
				service.remove(i);
			}

			pObject->close();
		}
	}
}
0 Likes
Message 3 of 7

Kyudos
Advisor
Advisor

Even without the transaction stuff, it still doesn't work for me.

0 Likes
Message 4 of 7

BerndCuder8196
Advocate
Advocate
Are you sure your reactor is loaded and endSSGet is called? What happens in debug mode when you set an stop mark at the loop with selectionSet?
0 Likes
Message 5 of 7

Kyudos
Advisor
Advisor

That is basically the problem - it is definitely active, I get to the "service.remove" lines at the correct times (after clicking a MyClass object for instance), and the debugger shows that those calls return eOk. It just doesn't actually remove that thing from the selection - it is still highlighted in the interface and in still in the array when I get to my other selection handlers (e.g. in AcEdInputContextReactor::endSSGet).

0 Likes
Message 6 of 7

BerndCuder8196
Advocate
Advocate
Have you tested turn off the other reactors? Maybe there is an problem. As I posted before, the code works fine in AutoCAD 2017 on my computer.
Info: service.remove doesn't work synchronized, it removes the indicies at end of endSSGet.
0 Likes
Message 7 of 7

Kyudos
Advisor
Advisor
Accepted solution

I got it to work! I took my code and moved it from endSSGet to ssgetAddFilter and analysed the subSelectionSet for the remove.

 

Not sure why one works and the other doesn't, but it works so I don't care 🙂

0 Likes