Archicad C++ API
About Archicad add-on development using the C++ API.

[SOLVED] APIEnv_SearchNavigatorItemID not working correctly?

Ben Cohen
Advocate
Hi All

I am trying to create an addon that searches through all navigator items and changes various view settings. All is working well but I have found the search is only working for floor plan and perspective view types.

the code below comes directly from the API devkit. It will loop through all the floor plan views. But if you change it to loop through sections - it will not work. (oddly - perspective views seem to work) (also setting db.typeID seems to have no effect)

I am changing this line of code
item.itemType = API_StoryNavItem;
to this
item.itemType = API_SectionNavItem

which will work with floor plans and perspectives - but nothing else??

any help - much appreciated!!



GSErrCode err = NoError;

API_DatabaseInfo db;
BNZeroMemory (&db, sizeof (API_DatabaseInfo));
db.typeID = APIWind_FloorPlanID;

API_NavigatorView   view;
API_NavigatorItem   parent;
API_NavigatorItem   item;
API_NavigatorItem** items = NULL;

BNZeroMemory (&item, sizeof (API_NavigatorItem));
item.itemType = API_StoryNavItem
item.mapId    = API_PublicViewMap;
db.typeID     = APIWind_FloorPlanID;

err = ACAPI_Environment (APIEnv_SearchNavigatorItemID, &item, &items, NULL);
if (err != NoError || items == NULL)
    return;

char    str[256];
Int32   num;
Int32   n = BMhGetSize ((GSHandle) items) / sizeof (API_NavigatorItem);

ACAPI_WriteReport ("Stories of View Map:", false);

for (Int32 i = 0; i < n; i++) {
    sprintf (str, "%s", (*items).name);
    ACAPI_WriteReport (str, false);

    BNZeroMemory (&parent, sizeof (API_NavigatorItem));
    parent.mapId = API_PublicViewMap;
    err = ACAPI_Environment (APIEnv_GetNavigatorParentItemID, (*items).guid, &parent, NULL);
    sprintf (str, " - parent name: %s", parent.name);
    ACAPI_WriteReport (str, false);

    err = ACAPI_Environment (APIEnv_GetNavigatorChildNumID, &parent, &num, NULL);
    sprintf (str, " - number of children of the parent: %d", num);
    ACAPI_WriteReport (str, false);

    BNZeroMemory (&view, sizeof (API_NavigatorView));
    err = ACAPI_Environment (APIEnv_GetNavigatorViewID, &((*items)), &view, NULL);
    if (view.saveLaySet) {
        if (view.layerCombination[0] != 0)
            sprintf (str, " - Layer combination: %s", view.layerCombination);
        else
            sprintf (str, " - Layers individual");
    } else {
        sprintf (str, " - none layers");
    }
    BMhKill ((GSHandle*) &view.layerStats);

    ACAPI_WriteReport (str, false);
}

BMhKill ((GSHandle *) &items);
Ben Cohen
Mac and PC
Archicad (Latest Version) aus
www.4DLibrary.com.au
10 REPLIES 10
Ralph Wessel
Mentor
Ben wrote:
Hi All

I am trying to create an addon that searches through all navigator items and changes various view settings. All is working well but I have found the search is only working for floor plan and perspective view types.

I am changing this line of code
item.itemType = API_StoryNavItem;
to this
item.itemType = API_SectionNavItem

which will work with floor plans and perspectives - but nothing else??
Have you tried varying this line:
db.typeID     = APIWind_FloorPlanID;
That line is directing the search toward the floor plan database.
Ralph Wessel BArch
Software Engineer Speckle Systems
Ben Cohen
Advocate
Hi Ralph

Yes I tried that. Interestingly API_PerspectiveNavItem and API_StoryNavItem both work regardless of how db.typeID is set.

so if I do this

item.itemType = API_SectionNavItem; // API_StoryNavItem;
db.typeID = APIWind_SectionID;

It does not help

Thanks for the reply but still no luck
Ben Cohen
Mac and PC
Archicad (Latest Version) aus
www.4DLibrary.com.au
Akos Somorjai
Graphisoft
Graphisoft
Ben wrote:
Hi Ralph

Yes I tried that. Interestingly API_PerspectiveNavItem and API_StoryNavItem both work regardless of how db.typeID is set.

so if I do this

item.itemType = API_SectionNavItem; // API_StoryNavItem;
db.typeID = APIWind_SectionID;

It does not help

Thanks for the reply but still no luck
Hi Ben,

The solution is to fill the item.db.databaseUnId with the unique ID of the section database you are searching for.
You can get all the available section databases with ACAPI_Database (APIDb_GetSectionDatabasesID, ...).

Best, Akos
Ben Cohen
Advocate
Thanks Ako's. That did the trick!!
Ben Cohen
Mac and PC
Archicad (Latest Version) aus
www.4DLibrary.com.au
Ben Cohen
Advocate
Hi Akos

I have my Addon looping through almost all the views successfully now.
Except for schedule view types.

Something tells me that schedule views are handled very differently.

Any help or hints would be much appreciated
Ben Cohen
Mac and PC
Archicad (Latest Version) aus
www.4DLibrary.com.au
Regina Judak
Graphisoft Alumni
Graphisoft Alumni
Hi Ben,
Yes it is working differently. In this case you don't have to set item.db.databaseUnId.

You have to set the followings:
item.itemType = API_ScheduleNavItem;
item.mapId = API_PublicViewMap;
db.typeID = API_ZombieWindowID;

In addition you also have to set the item.guid2, which is retrived for example if you call APIEnv_GetNavigatorItemID.

Best,
Regina
Ben Cohen
Advocate
Hi Regina

Thanks for the info. But unfortunately I have more issues

I set the following as discussed

item.itemType = API_ScheduleNavItem;
item.mapId = API_PublicViewMap;
db.typeID = API_ZombieWindowID;

but the search function "APIEnv_SearchNavigatorItemID" will not return the number of schedule views. Like it will with the other view types

Any help greatly appreciated
Ben Cohen
Mac and PC
Archicad (Latest Version) aus
www.4DLibrary.com.au
Regina Judak
Graphisoft Alumni
Graphisoft Alumni
Hi Ben,

Here is a modification of the Navigator Test addon’s MakeTree function which handles correctly the Schedules and writes the GUID-s and the name in the report window. Please check this and your code.

Best, Regina
static void MakeTree (short dialogID, short	treeItem, Int32 parent, const API_Guid& guid, GS::PagedArray<Int32>& itemsArray, API_NavigatorMapID mapId)
{
	API_NavigatorItem** items = NULL;
	API_NavigatorItem item;

	BNZeroMemory (&item, sizeof (API_NavigatorItem));
	item.guid = guid;
	item.mapId = NavigatorTestGlobals::Instance ().GetNavigatorMapID ();

	GSErrCode err = ACAPI_Environment (APIEnv_GetNavigatorChildrenItemsID, &item, &items);
	if (err != NoError || items == NULL)
		return;

	Int32 n = BMhGetSize ((GSHandle)items) / Sizeof32 (API_NavigatorItem);
	for (Int32 i = 0; i < n; i++) {
		if ((*items).itemType == API_ScheduleNavItem) {
			API_NavigatorItem** items2 = nullptr;

			char msgStr[256];
			sprintf (msgStr, "GUID: %s, GUID2: %s, name: %s\n",
						 APIGuid2GSGuid ((*items).guid).ToUniString ().ToCStr ().Get (),
						 APIGuid2GSGuid ((*items).guid2).ToUniString ().ToCStr ().Get (),
						 (*items).name);
			ACAPI_WriteReport (msgStr, false);

			(*items).mapId = mapId;
			err = ACAPI_Environment (APIEnv_SearchNavigatorItemID, &(*items), &items2);

			Int32 nn = BMhGetSize ((GSHandle) items2) / Sizeof32 (API_NavigatorItem);
			for (Int32 ii = 0; ii < nn; ii++) { 
				sprintf (msgStr, "GUID: %s, Name: %s, \n",
						 APIGuid2GSGuid ((*items2)[ii].guid).ToUniString ().ToCStr ().Get (), (*items2)[ii].name);
				ACAPI_WriteReport (msgStr, false);
			}

			BMhKill ((GSHandle *) &items2);
		}

		Int32 newItem = InsertTreeItem (dialogID, treeItem, parent, (*items).name, (*items).uiId, (*items).guid, (*items).itemType);
		if (newItem != 0) {
			itemsArray.Push (newItem);
			MakeTree (dialogID, treeItem, newItem, (*items).guid, itemsArray, mapId);
		}
	}

	BMhKill ((GSHandle *) &items);
}
Ben Cohen
Advocate
Thanks Regina

This is fantastic, I now have my addon working perfectly!
Thanks for all your help

Happy Days
Ben Cohen
Mac and PC
Archicad (Latest Version) aus
www.4DLibrary.com.au