cancel
Showing results for 
Search instead for 
Did you mean: 
EN
cancel
Showing results for 
Search instead for 
Did you mean: 
Emkave
Enthusiast

Monitor copied-pasted elements

Hello everyone. Does anyone know how can I detected whether or not an element was: "drag a copy"-ed, "rotate a copy"-ed, "mirror a copy"-ed? I need the IFC parameters copied as well, however they don't.

Unfortunately, ACAPI_Element_CatchNewElement does not work. 

 

Thank you for the help!

1 Solution

Accepted Solutions

My answer is similar to my earlier reply to your undo-monitoring question.

 

To detect when an element is copied — whether by standard copy, drag‑copy, rotation, or mirroring — you must first attach an observer to every element that you want to track, by using ACAPI_Element_AttachObserver. This marks the element as observable.

 

Next, install a global element observer with ACAPI_Element_InstallElementObserver, which registers your APIElementEventHandlerProc callback. Whenever an observed element is copied, modified, deleted, or restored, Archicad calls your handler and sends notifications grouped between APINotifyElement_BeginEvents and APINotifyElement_EndEvents.

 

Inside this handler, you can collect GUIDs, detect copy-operations, or react to any other changes. (In my earlier reply about undo-monitoring question, I did not mention copy events because your question there focused specifically on modifications, deletions, and restorations.)

 

// Your APIElementEventHandlerProc callback that should be registered via
// ACAPI_Element_InstallElementObserver, e.g., in your add-on's Initialize function
GSErrCode ElementEventHandler (const API_NotifyElementType* notifyElementType)
{
	GSErrCode err = GS::NoError;

	API_Element parentElement{};

	// Retrieves the parent of the element that triggered the notification.
	// If no parent exists for the action, returns APIERR_REFUSEDCMD.
	// If you pass nullptr values in the memo and userData parameters, the
	// function performs an ACAPI_Element_Get operation, otherwise it behaves
	// like the ACAPI_Element_GetMemo or the ACAPI_Element_GetUserData function
	err = ACAPI_Notification_GetParentElement (&parentElement, nullptr, 0, nullptr);

	// Handle errors as needed...

	switch (notifyElementType->notifID) {
		case API_ElementDBEventID::APINotifyElement_Copy:
		{
			GS::UniString elementTypeName;

			const GS::UniString copiedElementGuidString = APIGuidToString (notifyElementType->elemHead.guid);
			const GS::UniString parentElementGuidString = APIGuidToString (parentElement.header.guid);

			if (parentElement.header.guid != APINULLGuid &&
				(ACAPI_Element_GetElemTypeName (notifyElementType->elemHead.type, elemTypeName) == GS::NoError)) {

				const GS::UniString message = GS::UniString::Printf ( 
					"%T #%T copied from #%T",
					&elementTypeName,
					&copiedElementGuidString,
					&parentElementGuidString);

				// Attach observer to the new clone so it can be tracked in future (copy or other) operations
				err = ACAPI_Element_AttachObserver (notifyElementType->elemHead.guid, 0);

				// Handle errors as needed...

				// Report the event
				DG::InformationAlert ("Copy has been detected", message, "OK");
			}

		// Handle other notification cases...
	}

	return err;
}

 

The attached animation shows exactly how the process unfolds. Since you also obtain the GUID of the parent element, you can access its IFC or other parameters and pass them on to the clone.

 

copy-detection.gif

Go to post

2 Replies 2

My answer is similar to my earlier reply to your undo-monitoring question.

 

To detect when an element is copied — whether by standard copy, drag‑copy, rotation, or mirroring — you must first attach an observer to every element that you want to track, by using ACAPI_Element_AttachObserver. This marks the element as observable.

 

Next, install a global element observer with ACAPI_Element_InstallElementObserver, which registers your APIElementEventHandlerProc callback. Whenever an observed element is copied, modified, deleted, or restored, Archicad calls your handler and sends notifications grouped between APINotifyElement_BeginEvents and APINotifyElement_EndEvents.

 

Inside this handler, you can collect GUIDs, detect copy-operations, or react to any other changes. (In my earlier reply about undo-monitoring question, I did not mention copy events because your question there focused specifically on modifications, deletions, and restorations.)

 

// Your APIElementEventHandlerProc callback that should be registered via
// ACAPI_Element_InstallElementObserver, e.g., in your add-on's Initialize function
GSErrCode ElementEventHandler (const API_NotifyElementType* notifyElementType)
{
	GSErrCode err = GS::NoError;

	API_Element parentElement{};

	// Retrieves the parent of the element that triggered the notification.
	// If no parent exists for the action, returns APIERR_REFUSEDCMD.
	// If you pass nullptr values in the memo and userData parameters, the
	// function performs an ACAPI_Element_Get operation, otherwise it behaves
	// like the ACAPI_Element_GetMemo or the ACAPI_Element_GetUserData function
	err = ACAPI_Notification_GetParentElement (&parentElement, nullptr, 0, nullptr);

	// Handle errors as needed...

	switch (notifyElementType->notifID) {
		case API_ElementDBEventID::APINotifyElement_Copy:
		{
			GS::UniString elementTypeName;

			const GS::UniString copiedElementGuidString = APIGuidToString (notifyElementType->elemHead.guid);
			const GS::UniString parentElementGuidString = APIGuidToString (parentElement.header.guid);

			if (parentElement.header.guid != APINULLGuid &&
				(ACAPI_Element_GetElemTypeName (notifyElementType->elemHead.type, elemTypeName) == GS::NoError)) {

				const GS::UniString message = GS::UniString::Printf ( 
					"%T #%T copied from #%T",
					&elementTypeName,
					&copiedElementGuidString,
					&parentElementGuidString);

				// Attach observer to the new clone so it can be tracked in future (copy or other) operations
				err = ACAPI_Element_AttachObserver (notifyElementType->elemHead.guid, 0);

				// Handle errors as needed...

				// Report the event
				DG::InformationAlert ("Copy has been detected", message, "OK");
			}

		// Handle other notification cases...
	}

	return err;
}

 

The attached animation shows exactly how the process unfolds. Since you also obtain the GUID of the parent element, you can access its IFC or other parameters and pass them on to the clone.

 

copy-detection.gif

Emkave
Enthusiast

Thank you for the responses!!! It all works. However, now I have a little another issue. When I place a wall, then perform operations on it like that: 

 

 

Emkave_0-1776341347702.png

 

 

we are effectively having more walls there. However, when I tried to debug the event, the event was: "APINotifyElement_Edit" and no any other event that would be related to such operation was returned. Sooo I wonder how can I monitor such action as well.

Thank you again for the assistance! 

Didn't find the answer?

Check other topics in this Forum

Back to Forum

Read the latest accepted solutions!

Accepted Solutions

Start a new conversation!