Archicad Python API
About automating tasks in Archicad using the Python API.
SOLVED!

PYTHON API - Favorites

dushyant
Enthusiast
Hello!

Is there a way to obtain the list of folders in the Favorites palette? I saw in the xml of a favorite, there is a <Folder Name="sampleFolderName" /> . So I was wondering if there is any accessibility in the new Python API for this folder name.
I am listing the favorites and really need to access them as per folders in 'Favorites'.

Thank you.

Dushyant Basson
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi Dushyant,

The current version of Python API does not able to retrieve the folderhierarchy of the favorites.
Currently it’s available only via C++ API. The code below draws the hierarchy of the favorites to the Report window, simply call DrawFavoritesTree method.
(Note, the code was written by using AC23 API.)
static GS::UniString DrawLevel (USize level)
{
       GS::UniString string;
       for (UIndex ii = 0; ii < level; ++ii)
              string += '\t';
       return string;
}

static GS::UniString DrawItem (const GS::UniString& name, USize level)
{
       return DrawLevel (level) + name + '\n';
}

static GS::UniString DrawFolder (const GS::UniString& folderName,
                                                       const GS::HashTable<GS::UniString, GS::Array<GS::UniString>>& subFoldersInFolder,
                                                       const GS::HashTable<GS::UniString, GS::Array<GS::UniString>>& favoritesInFolder,
                                                       USize level = 0)
{
       GS::UniString string = DrawItem (folderName, level);

       string.Insert (string.GetLength () - 1, " [");
       ++level;
       if (subFoldersInFolder.ContainsKey (folderName)) {
              for (const GS::UniString& subFolder : subFoldersInFolder[folderName]) {
                     string += DrawFolder (subFolder, subFoldersInFolder, favoritesInFolder, level);
              }
       }
       if (favoritesInFolder.ContainsKey (folderName)) {
              for (const GS::UniString& favorite : favoritesInFolder[folderName]) {
                     string += DrawItem (favorite, level);
              }
       }
       string.Insert (string.GetLength () - 1, " ]");

       return string;
}

static GSErrCode DrawFavoritesTree ()
{
       API_ToolBoxInfo      toolboxInfo = {};
       GSErrCode            err = NoError;

       err = ACAPI_Environment (APIEnv_GetToolBoxInfoID, &toolboxInfo, (void*)(GS::IntPtr) true);

       if (err != NoError)
              return err;

       // Get all favorites
       GS::HashTable<GS::UniString, GS::Array<GS::UniString>> favoritesInFolder;
       GS::Array<API_FavoriteFolderHierarchy> folders;
       for (Int32 ii = 0; ii < toolboxInfo.nTools; ++ii) {
              const API_ToolBoxItem& toolBoxItem = (*toolboxInfo.data)[ii];

              GS::Array<API_FavoriteFolderHierarchy> foldersForTool;
              GS::Array<GS::UniString> favoriteNames;
              ACAPI_Favorite_GetNum (toolBoxItem.typeID, toolBoxItem.variationID, nullptr, &foldersForTool, &favoriteNames);
              folders.Append (foldersForTool);

              for (UIndex jj = 0; jj < favoriteNames.GetSize (); ++jj) {
                     favoritesInFolder.Retrieve (foldersForTool[jj].GetLast ()).Push (favoriteNames[jj]);
              }
       }

       BMKillHandle ((GSHandle *)&toolboxInfo.data);

       if (folders.IsEmpty ())
              return APIERR_GENERAL;

       // Build tree from favorites
       GS::HashTable<GS::UniString, GS::Array<GS::UniString>> subFoldersInFolder;
       for (const API_FavoriteFolderHierarchy& folderHierarchy : folders) {
              GS::Optional<GS::UniString> parentFolderName;
              for (const GS::UniString& folderName : folderHierarchy) {
                     if (parentFolderName.HasValue ()) {
                           GS::Array<GS::UniString>& subFolders = subFoldersInFolder.Retrieve (parentFolderName.Get ());
                           if (!subFolders.Contains (folderName))
                                  subFolders.Push (folderName);
                     }
                     subFoldersInFolder.Retrieve (folderName);
                     parentFolderName = folderName;
              }
       }

       // Sort folders and favorites in tree
       for (GS::Array<GS::UniString>& subFolders : subFoldersInFolder.Values ()) {
              GS::Sort (subFolders.Begin (), subFolders.End ());
       }
       for (GS::Array<GS::UniString>& favorites : favoritesInFolder.Values ()) {
              GS::Sort (favorites.Begin (), favorites.End ());
       }

       // Draw tree into the Report Window:
       const GS::UniString rootFolderName = folders.GetFirst ().GetFirst ();
       ACAPI_WriteReport (DrawFolder (rootFolderName, subFoldersInFolder, favoritesInFolder), false);

       return err;
}

View solution in original post

11 REPLIES 11
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi Dushyant,

The current version of Python API does not able to retrieve the folderhierarchy of the favorites.
Currently it’s available only via C++ API. The code below draws the hierarchy of the favorites to the Report window, simply call DrawFavoritesTree method.
(Note, the code was written by using AC23 API.)
static GS::UniString DrawLevel (USize level)
{
       GS::UniString string;
       for (UIndex ii = 0; ii < level; ++ii)
              string += '\t';
       return string;
}

static GS::UniString DrawItem (const GS::UniString& name, USize level)
{
       return DrawLevel (level) + name + '\n';
}

static GS::UniString DrawFolder (const GS::UniString& folderName,
                                                       const GS::HashTable<GS::UniString, GS::Array<GS::UniString>>& subFoldersInFolder,
                                                       const GS::HashTable<GS::UniString, GS::Array<GS::UniString>>& favoritesInFolder,
                                                       USize level = 0)
{
       GS::UniString string = DrawItem (folderName, level);

       string.Insert (string.GetLength () - 1, " [");
       ++level;
       if (subFoldersInFolder.ContainsKey (folderName)) {
              for (const GS::UniString& subFolder : subFoldersInFolder[folderName]) {
                     string += DrawFolder (subFolder, subFoldersInFolder, favoritesInFolder, level);
              }
       }
       if (favoritesInFolder.ContainsKey (folderName)) {
              for (const GS::UniString& favorite : favoritesInFolder[folderName]) {
                     string += DrawItem (favorite, level);
              }
       }
       string.Insert (string.GetLength () - 1, " ]");

       return string;
}

static GSErrCode DrawFavoritesTree ()
{
       API_ToolBoxInfo      toolboxInfo = {};
       GSErrCode            err = NoError;

       err = ACAPI_Environment (APIEnv_GetToolBoxInfoID, &toolboxInfo, (void*)(GS::IntPtr) true);

       if (err != NoError)
              return err;

       // Get all favorites
       GS::HashTable<GS::UniString, GS::Array<GS::UniString>> favoritesInFolder;
       GS::Array<API_FavoriteFolderHierarchy> folders;
       for (Int32 ii = 0; ii < toolboxInfo.nTools; ++ii) {
              const API_ToolBoxItem& toolBoxItem = (*toolboxInfo.data)[ii];

              GS::Array<API_FavoriteFolderHierarchy> foldersForTool;
              GS::Array<GS::UniString> favoriteNames;
              ACAPI_Favorite_GetNum (toolBoxItem.typeID, toolBoxItem.variationID, nullptr, &foldersForTool, &favoriteNames);
              folders.Append (foldersForTool);

              for (UIndex jj = 0; jj < favoriteNames.GetSize (); ++jj) {
                     favoritesInFolder.Retrieve (foldersForTool[jj].GetLast ()).Push (favoriteNames[jj]);
              }
       }

       BMKillHandle ((GSHandle *)&toolboxInfo.data);

       if (folders.IsEmpty ())
              return APIERR_GENERAL;

       // Build tree from favorites
       GS::HashTable<GS::UniString, GS::Array<GS::UniString>> subFoldersInFolder;
       for (const API_FavoriteFolderHierarchy& folderHierarchy : folders) {
              GS::Optional<GS::UniString> parentFolderName;
              for (const GS::UniString& folderName : folderHierarchy) {
                     if (parentFolderName.HasValue ()) {
                           GS::Array<GS::UniString>& subFolders = subFoldersInFolder.Retrieve (parentFolderName.Get ());
                           if (!subFolders.Contains (folderName))
                                  subFolders.Push (folderName);
                     }
                     subFoldersInFolder.Retrieve (folderName);
                     parentFolderName = folderName;
              }
       }

       // Sort folders and favorites in tree
       for (GS::Array<GS::UniString>& subFolders : subFoldersInFolder.Values ()) {
              GS::Sort (subFolders.Begin (), subFolders.End ());
       }
       for (GS::Array<GS::UniString>& favorites : favoritesInFolder.Values ()) {
              GS::Sort (favorites.Begin (), favorites.End ());
       }

       // Draw tree into the Report Window:
       const GS::UniString rootFolderName = folders.GetFirst ().GetFirst ();
       ACAPI_WriteReport (DrawFolder (rootFolderName, subFoldersInFolder, favoritesInFolder), false);

       return err;
}
poco2013
Mentor
In the same vane as above :

I tried compiling the Favorites_Test example and got a huge number of errors -- 973 errors -- basically could not find the standard header files such as: error.h, float.h, correct.h, stdef.h, stdin.h --- etc. etc.

All other examples that I tried compile fine without modification. Obviously something was missed in Favorites_Test. Using Download API Development Kit 23 3006 on Windows 10 with VS 2017

What do I need to fix?
Gerry

Windows 11 - Visual Studio 2022; ArchiCAD 27
MOREH Tamas
Graphisoft
Graphisoft
poco2013 wrote:
In the same vane as above :

I tried compiling the Favorites_Test example and got a huge number of errors -- 973 errors -- basically could not find the standard header files such as: error.h, float.h, correct.h, stdef.h, stdin.h --- etc. etc.

All other examples that I tried compile fine without modification. Obviously something was missed in Favorites_Test. Using Download API Development Kit 23 3006 on Windows 10 with VS 2017

What do I need to fix?
Hi,
Have you installed well the Windows SDK? If yes, you should check the Project properties. Check the VC++ Directories page and the Include Directories row. If you open the edit dialogue of the Include directories you see the paths and you can check them if they are correct.

But please pay attention to the Subject from now on. This is not a Python related question.
poco2013
Mentor
Thanks for the non-response
Gerry

Windows 11 - Visual Studio 2022; ArchiCAD 27
Ralph Wessel
Mentor
poco2013 wrote:
Thanks for the non-response
Bit harsh – Tamas gave you some good leads to check out.
Ralph Wessel BArch
Software Engineer Speckle Systems
Akos Somorjai
Graphisoft
Graphisoft
poco2013 wrote:
In the same vane as above :

I tried compiling the Favorites_Test example and got a huge number of errors -- 973 errors -- basically could not find the standard header files such as: error.h, float.h, correct.h, stdef.h, stdin.h --- etc. etc.

All other examples that I tried compile fine without modification. Obviously something was missed in Favorites_Test. Using Download API Development Kit 23 3006 on Windows 10 with VS 2017

What do I need to fix?
Which edition of VS 2017 did you install? The Community Edition usually requires an additional download of the Windows SDK.

Best, Akos
poco2013
Mentor
Thanks AKOS

I am using the Community 2017 version.
The real problem is that Graphisoft does not advise of the SDK issue. and apparently ?? different examples require different SDKs. -- Almost all other Examples will compile normally out of the box which threw me the "curve"

I finally figured that out. Thanks for the very Professional answer.
Gerry

Windows 11 - Visual Studio 2022; ArchiCAD 27
dushyant
Enthusiast
Hi
Does the current Python API release (with AC-24) include anything to access the 'Favorites'?
Tibor wrote:
Hi Dushyant,

The current version of Python API does not able to retrieve the folderhierarchy of the favorites.
Currently it’s available only via C++ API. The code below draws the hierarchy of the favorites to the Report window, simply call DrawFavoritesTree method.
(Note, the code was written by using AC23 API.)
static GS::UniString DrawLevel (USize level)
{
       GS::UniString string;
       for (UIndex ii = 0; ii < level; ++ii)
              string += '\t';
       return string;
}

static GS::UniString DrawItem (const GS::UniString& name, USize level)
{
       return DrawLevel (level) + name + '\n';
}

static GS::UniString DrawFolder (const GS::UniString& folderName,
                                                       const GS::HashTable<GS::UniString, GS::Array<GS::UniString>>& subFoldersInFolder,
                                                       const GS::HashTable<GS::UniString, GS::Array<GS::UniString>>& favoritesInFolder,
                                                       USize level = 0)
{
       GS::UniString string = DrawItem (folderName, level);

       string.Insert (string.GetLength () - 1, " [");
       ++level;
       if (subFoldersInFolder.ContainsKey (folderName)) {
              for (const GS::UniString& subFolder : subFoldersInFolder[folderName]) {
                     string += DrawFolder (subFolder, subFoldersInFolder, favoritesInFolder, level);
              }
       }
       if (favoritesInFolder.ContainsKey (folderName)) {
              for (const GS::UniString& favorite : favoritesInFolder[folderName]) {
                     string += DrawItem (favorite, level);
              }
       }
       string.Insert (string.GetLength () - 1, " ]");

       return string;
}

static GSErrCode DrawFavoritesTree ()
{
       API_ToolBoxInfo      toolboxInfo = {};
       GSErrCode            err = NoError;

       err = ACAPI_Environment (APIEnv_GetToolBoxInfoID, &toolboxInfo, (void*)(GS::IntPtr) true);

       if (err != NoError)
              return err;

       // Get all favorites
       GS::HashTable<GS::UniString, GS::Array<GS::UniString>> favoritesInFolder;
       GS::Array<API_FavoriteFolderHierarchy> folders;
       for (Int32 ii = 0; ii < toolboxInfo.nTools; ++ii) {
              const API_ToolBoxItem& toolBoxItem = (*toolboxInfo.data)[ii];

              GS::Array<API_FavoriteFolderHierarchy> foldersForTool;
              GS::Array<GS::UniString> favoriteNames;
              ACAPI_Favorite_GetNum (toolBoxItem.typeID, toolBoxItem.variationID, nullptr, &foldersForTool, &favoriteNames);
              folders.Append (foldersForTool);

              for (UIndex jj = 0; jj < favoriteNames.GetSize (); ++jj) {
                     favoritesInFolder.Retrieve (foldersForTool[jj].GetLast ()).Push (favoriteNames[jj]);
              }
       }

       BMKillHandle ((GSHandle *)&toolboxInfo.data);

       if (folders.IsEmpty ())
              return APIERR_GENERAL;

       // Build tree from favorites
       GS::HashTable<GS::UniString, GS::Array<GS::UniString>> subFoldersInFolder;
       for (const API_FavoriteFolderHierarchy& folderHierarchy : folders) {
              GS::Optional<GS::UniString> parentFolderName;
              for (const GS::UniString& folderName : folderHierarchy) {
                     if (parentFolderName.HasValue ()) {
                           GS::Array<GS::UniString>& subFolders = subFoldersInFolder.Retrieve (parentFolderName.Get ());
                           if (!subFolders.Contains (folderName))
                                  subFolders.Push (folderName);
                     }
                     subFoldersInFolder.Retrieve (folderName);
                     parentFolderName = folderName;
              }
       }

       // Sort folders and favorites in tree
       for (GS::Array<GS::UniString>& subFolders : subFoldersInFolder.Values ()) {
              GS::Sort (subFolders.Begin (), subFolders.End ());
       }
       for (GS::Array<GS::UniString>& favorites : favoritesInFolder.Values ()) {
              GS::Sort (favorites.Begin (), favorites.End ());
       }

       // Draw tree into the Report Window:
       const GS::UniString rootFolderName = folders.GetFirst ().GetFirst ();
       ACAPI_WriteReport (DrawFolder (rootFolderName, subFoldersInFolder, favoritesInFolder), false);

       return err;
}
FavoritesTreeInReportWindow.png
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
dushyant wrote:
Does the current Python API release (with AC-24) include anything to access the 'Favorites'?
Unfortunately my answer is no. Currently (AC24.3010) the Python API is not able to access any information related to the Favorites.
It's in our backlog, but we haven't started to implement it.