<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic How to group items in list view in Archicad C++ API</title>
    <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239936#M5406</link>
    <description>&lt;DIV class="actalk-migrated-content"&gt;Hello,&lt;BR /&gt;&lt;BR /&gt;I would like to know how i can achieve grouping of list items in my list view. I attached an image to show what I want to achieve.&lt;BR /&gt;&lt;BR /&gt;I need to use the code in c++. I know how to make a normal list view:&lt;BR /&gt;
&lt;PRE&gt; // -----------------------------------------------------------------------------
// Set/adjust the dialog items
// -----------------------------------------------------------------------------

static void ListDataDlg_Set (short 	dialId, DGUserData userData)
{
	API_ListData	listdata;
	char			keyStr[NAME_LEN2];
	char			codeStr[NAME_LEN2];
	Int32			count;
	Int32			i;
	bool			filter;

	if (userData == 0L) {
		return;
	}

	 

	listdata = *((API_ListData *) (userData));

	listdata.header.setIndex = (short) DGPopUpGetItemUserData (dialId, DBSetPopupItem,
				(short) DGGetItemValLong (dialId, DBSetPopupItem));

	GS::UniString temp = DGGetItemText (dialId, KeyEditTextItem);
	CHTruncate (UniStringToConstCString (temp), keyStr, NAME_LEN2);
	temp = DGGetItemText (dialId, CodeEditTextItem);
	CHTruncate (UniStringToConstCString (temp), codeStr, NAME_LEN2);

	switch (DGGetItemValLong (dialId, TypeIDPopupItem)) {

		case 1:		listdata.header.typeID = API_ComponentID;
					CHCopyC (keyStr, listdata.component.keycode);
					CHCopyC (codeStr, listdata.component.code);
					DGEnableItem (dialId, KeyEditTextItem);
					break;

		case 2:		listdata.header.typeID = API_DescriptorID;
					CHCopyC (keyStr, listdata.descriptor.keycode);
					CHCopyC (codeStr, listdata.descriptor.code);
					DGEnableItem (dialId, KeyEditTextItem);
					break;

		case 3:		listdata.header.typeID = API_KeyID;
					CHCopyC (codeStr, listdata.key.code);
					DGDisableItem (dialId, KeyEditTextItem);
					break;

		case 4:		listdata.header.typeID = API_UnitID;
					CHCopyC (codeStr, listdata.unit.code);
					DGDisableItem (dialId, KeyEditTextItem);
					break;
	}

	DGListDeleteItem (dialId, SearchListItem, DG_ALL_ITEMS);

	filter = (DGGetCheckedRadio (dialId, 1) == FilterRadioItem);
	Search_ListData (&amp;amp;listdata, &amp;amp;count, filter);

	if (count &amp;lt; 1 || listHdl == NULL)
		return;

	for (i = 1; i &amp;lt;= count; i++)
		DGListInsertItem (dialId, SearchListItem, DG_LIST_BOTTOM);

	SetDGList (dialId, count);
	DGListSelectItem (dialId, SearchListItem, 1);

	return;
}		// ListDataDlg_Set

static void		Search_ListData (API_ListData *param, Int32 *count, bool filter)
{
	API_ListData	listdata;
	Int32			i;
	Int32			beginIndex, endIndex;
	GSErrCode		err;

	listdata	= *param;
	*count		= 0;
	err			= NoError;

	/* ACAPI_ListData_Search fails if keyCode is an empty string */

	/* ------- Search it ------- */
	if (filter &amp;amp;&amp;amp; (param-&amp;gt;header.typeID == API_UnitID || param-&amp;gt;header.typeID == API_KeyID ||
		(param-&amp;gt;header.typeID == API_ComponentID &amp;amp;&amp;amp; strlen (param-&amp;gt;component.code) != 0) ||
		(param-&amp;gt;header.typeID == API_DescriptorID &amp;amp;&amp;amp; strlen (param-&amp;gt;descriptor.code) != 0))) {

		err = ACAPI_ListData_Search (&amp;amp;listdata);

		if (err == NoError)
			err = ACAPI_ListData_Get (&amp;amp;listdata);

		if (err == NoError) {
			err = AppendList (&amp;amp;listdata, count);
			if (listdata.header.typeID == API_DescriptorID)
				BMKillHandle (&amp;amp;listdata.descriptor.name);
		}
	} else {

	/* ------ Search list ------ */
		if (filter) {
			err = ACAPI_ListData_Search (&amp;amp;listdata);
			if (err != NoError)
				return;

			beginIndex = listdata.header.index;
		} else
			beginIndex = 1;

		err = ACAPI_ListData_GetNum (param-&amp;gt;header.setIndex, param-&amp;gt;header.typeID, &amp;amp;endIndex);
		if (err != NoError)
			return;

		BNZeroMemory (&amp;amp;listdata, sizeof (API_ListData));
		listdata.header.typeID	 = param-&amp;gt;header.typeID;
		listdata.header.setIndex = param-&amp;gt;header.setIndex;

		for (i = beginIndex; i &amp;lt;= endIndex; i++) {

			listdata.header.index		= i;
			err = ACAPI_ListData_Get (&amp;amp;listdata);
			if (err != NoError)
				break;

			if (filter) {
				if (listdata.header.typeID == API_ComponentID &amp;amp;&amp;amp;
					!CHEqualCStrings (listdata.component.keycode, param-&amp;gt;component.keycode))
					break;

				if	(listdata.header.typeID == API_DescriptorID &amp;amp;&amp;amp;
					!CHEqualCStrings (listdata.descriptor.keycode, param-&amp;gt;descriptor.keycode)) {

					BMKillHandle (&amp;amp;listdata.descriptor.name);
					break;
				}
			}

			if (err == NoError) {
				err = AppendList (&amp;amp;listdata, count);
				if (listdata.header.typeID == API_DescriptorID)
					BMKillHandle (&amp;amp;listdata.descriptor.name);
			}

			if (err != NoError)
				return;
		}
	}

	return;
}		// Search_ListData

&lt;/PRE&gt;
But how can I group those items under a header like in the example.&lt;BR /&gt;&lt;BR /&gt;Thanks&lt;/DIV&gt;&lt;BR /&gt;&lt;IMG src="http://community.graphisoft.com/t5/image/serverpage/image-id/68488i79E418B83DF561BB/image-size/large?v=v2&amp;amp;px=999" border="0" alt="111.jpeg" title="111.jpeg" /&gt;</description>
    <pubDate>Tue, 01 Aug 2023 11:53:09 GMT</pubDate>
    <dc:creator>Anonymous</dc:creator>
    <dc:date>2023-08-01T11:53:09Z</dc:date>
    <item>
      <title>How to group items in list view</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239936#M5406</link>
      <description>&lt;DIV class="actalk-migrated-content"&gt;Hello,&lt;BR /&gt;&lt;BR /&gt;I would like to know how i can achieve grouping of list items in my list view. I attached an image to show what I want to achieve.&lt;BR /&gt;&lt;BR /&gt;I need to use the code in c++. I know how to make a normal list view:&lt;BR /&gt;
&lt;PRE&gt; // -----------------------------------------------------------------------------
// Set/adjust the dialog items
// -----------------------------------------------------------------------------

static void ListDataDlg_Set (short 	dialId, DGUserData userData)
{
	API_ListData	listdata;
	char			keyStr[NAME_LEN2];
	char			codeStr[NAME_LEN2];
	Int32			count;
	Int32			i;
	bool			filter;

	if (userData == 0L) {
		return;
	}

	 

	listdata = *((API_ListData *) (userData));

	listdata.header.setIndex = (short) DGPopUpGetItemUserData (dialId, DBSetPopupItem,
				(short) DGGetItemValLong (dialId, DBSetPopupItem));

	GS::UniString temp = DGGetItemText (dialId, KeyEditTextItem);
	CHTruncate (UniStringToConstCString (temp), keyStr, NAME_LEN2);
	temp = DGGetItemText (dialId, CodeEditTextItem);
	CHTruncate (UniStringToConstCString (temp), codeStr, NAME_LEN2);

	switch (DGGetItemValLong (dialId, TypeIDPopupItem)) {

		case 1:		listdata.header.typeID = API_ComponentID;
					CHCopyC (keyStr, listdata.component.keycode);
					CHCopyC (codeStr, listdata.component.code);
					DGEnableItem (dialId, KeyEditTextItem);
					break;

		case 2:		listdata.header.typeID = API_DescriptorID;
					CHCopyC (keyStr, listdata.descriptor.keycode);
					CHCopyC (codeStr, listdata.descriptor.code);
					DGEnableItem (dialId, KeyEditTextItem);
					break;

		case 3:		listdata.header.typeID = API_KeyID;
					CHCopyC (codeStr, listdata.key.code);
					DGDisableItem (dialId, KeyEditTextItem);
					break;

		case 4:		listdata.header.typeID = API_UnitID;
					CHCopyC (codeStr, listdata.unit.code);
					DGDisableItem (dialId, KeyEditTextItem);
					break;
	}

	DGListDeleteItem (dialId, SearchListItem, DG_ALL_ITEMS);

	filter = (DGGetCheckedRadio (dialId, 1) == FilterRadioItem);
	Search_ListData (&amp;amp;listdata, &amp;amp;count, filter);

	if (count &amp;lt; 1 || listHdl == NULL)
		return;

	for (i = 1; i &amp;lt;= count; i++)
		DGListInsertItem (dialId, SearchListItem, DG_LIST_BOTTOM);

	SetDGList (dialId, count);
	DGListSelectItem (dialId, SearchListItem, 1);

	return;
}		// ListDataDlg_Set

static void		Search_ListData (API_ListData *param, Int32 *count, bool filter)
{
	API_ListData	listdata;
	Int32			i;
	Int32			beginIndex, endIndex;
	GSErrCode		err;

	listdata	= *param;
	*count		= 0;
	err			= NoError;

	/* ACAPI_ListData_Search fails if keyCode is an empty string */

	/* ------- Search it ------- */
	if (filter &amp;amp;&amp;amp; (param-&amp;gt;header.typeID == API_UnitID || param-&amp;gt;header.typeID == API_KeyID ||
		(param-&amp;gt;header.typeID == API_ComponentID &amp;amp;&amp;amp; strlen (param-&amp;gt;component.code) != 0) ||
		(param-&amp;gt;header.typeID == API_DescriptorID &amp;amp;&amp;amp; strlen (param-&amp;gt;descriptor.code) != 0))) {

		err = ACAPI_ListData_Search (&amp;amp;listdata);

		if (err == NoError)
			err = ACAPI_ListData_Get (&amp;amp;listdata);

		if (err == NoError) {
			err = AppendList (&amp;amp;listdata, count);
			if (listdata.header.typeID == API_DescriptorID)
				BMKillHandle (&amp;amp;listdata.descriptor.name);
		}
	} else {

	/* ------ Search list ------ */
		if (filter) {
			err = ACAPI_ListData_Search (&amp;amp;listdata);
			if (err != NoError)
				return;

			beginIndex = listdata.header.index;
		} else
			beginIndex = 1;

		err = ACAPI_ListData_GetNum (param-&amp;gt;header.setIndex, param-&amp;gt;header.typeID, &amp;amp;endIndex);
		if (err != NoError)
			return;

		BNZeroMemory (&amp;amp;listdata, sizeof (API_ListData));
		listdata.header.typeID	 = param-&amp;gt;header.typeID;
		listdata.header.setIndex = param-&amp;gt;header.setIndex;

		for (i = beginIndex; i &amp;lt;= endIndex; i++) {

			listdata.header.index		= i;
			err = ACAPI_ListData_Get (&amp;amp;listdata);
			if (err != NoError)
				break;

			if (filter) {
				if (listdata.header.typeID == API_ComponentID &amp;amp;&amp;amp;
					!CHEqualCStrings (listdata.component.keycode, param-&amp;gt;component.keycode))
					break;

				if	(listdata.header.typeID == API_DescriptorID &amp;amp;&amp;amp;
					!CHEqualCStrings (listdata.descriptor.keycode, param-&amp;gt;descriptor.keycode)) {

					BMKillHandle (&amp;amp;listdata.descriptor.name);
					break;
				}
			}

			if (err == NoError) {
				err = AppendList (&amp;amp;listdata, count);
				if (listdata.header.typeID == API_DescriptorID)
					BMKillHandle (&amp;amp;listdata.descriptor.name);
			}

			if (err != NoError)
				return;
		}
	}

	return;
}		// Search_ListData

&lt;/PRE&gt;
But how can I group those items under a header like in the example.&lt;BR /&gt;&lt;BR /&gt;Thanks&lt;/DIV&gt;&lt;BR /&gt;&lt;IMG src="http://community.graphisoft.com/t5/image/serverpage/image-id/68488i79E418B83DF561BB/image-size/large?v=v2&amp;amp;px=999" border="0" alt="111.jpeg" title="111.jpeg" /&gt;</description>
      <pubDate>Tue, 01 Aug 2023 11:53:09 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239936#M5406</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2023-08-01T11:53:09Z</dc:date>
    </item>
    <item>
      <title>Re: How to group items in list view</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239937#M5407</link>
      <description>The one in the picture is from GDL though, not the API Dialog Manager. In GDL its merely setting an object's parameter as title type and setting the parameters below it as its children.&lt;BR /&gt;
&lt;BR /&gt;
The closest imitation I could think of is using a ListBox and setting up a column for the "arrow down/right" toggle icon which when click, will populate that listitem's children. And then when clicked again will delete all those children.</description>
      <pubDate>Wed, 28 Jan 2015 03:03:23 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239937#M5407</guid>
      <dc:creator>Erenford</dc:creator>
      <dc:date>2015-01-28T03:03:23Z</dc:date>
    </item>
    <item>
      <title>Re: How to group items in list view</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239938#M5408</link>
      <description>Thank you for your answer...&lt;BR /&gt;
&lt;BR /&gt;
I understand that the upper one is from GDL. I also know how to make these when creating my custom GDL objects. But the lower one (with the IFC properties etc.) seems to be some UI class/element.&lt;BR /&gt;
&lt;BR /&gt;
So as an example, in the DevKit in C++ I can make a list view with: DG::SingleSelListView&lt;BR /&gt;
&lt;BR /&gt;
Like this I would also expect some class to make this kind of list, or is such class not available in the DevKit?&lt;BR /&gt;
&lt;BR /&gt;
Hope you can clear this up.&lt;BR /&gt;
Thanks!</description>
      <pubDate>Wed, 28 Jan 2015 08:14:52 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239938#M5408</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2015-01-28T08:14:52Z</dc:date>
    </item>
    <item>
      <title>Re: How to group items in list view</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239939#M5409</link>
      <description>You can create a class/structure that uses flags the same as the modifier flags of &lt;FONT color="#808080"&gt;API_AddParType&lt;/FONT&gt; (or you can set your own modifier flags). Then modify it whenever you "toggle" an item in the list. Then re-populate the list. Something like (populate list with parameter of a LibPart):&lt;BR /&gt;

&lt;PRE&gt;bool isOpen = false;
//... clear list before loop
for (... i = 0; i &amp;lt; cnt; i++)
{
    if (flags &amp;amp; API_ParFlag_Hidden)
        continue;

    // check if parent or child
    if (flags &amp;amp; API_ParFlag_Child)
    {
        // skip if parent is "close"
        if (!isOpen)
            continue;
    }
    // set isOpen if item is not child
    else
    {
        isOpen = (flags &amp;amp; API_ParFlag_Open) &amp;gt; 0;
    }

    //... populate list here checking if it is disabled, bold, separator, etc.
}&lt;/PRE&gt;</description>
      <pubDate>Thu, 20 Aug 2015 06:54:00 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239939#M5409</guid>
      <dc:creator>ReignBough</dc:creator>
      <dc:date>2015-08-20T06:54:00Z</dc:date>
    </item>
    <item>
      <title>Re: How to group items in list view</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239940#M5410</link>
      <description>I already did listview grouping by this way. Thanks</description>
      <pubDate>Fri, 21 Aug 2015 10:11:48 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-group-items-in-list-view/m-p/239940#M5410</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2015-08-21T10:11:48Z</dc:date>
    </item>
  </channel>
</rss>

