Archicad 28 C++ API
Loading...
Searching...
No Matches
Custom Modul Data

Functions for creating, handling and deleting custom (Add-On specific) Modul Data. Differs from User Data in not being attached to specific elements or element groups. This is a legacy technology, please use Add-On Objects instead. More...

Classes

struct  API_ModulData
 Control information of a custom data section saved into the project file. More...
 

Enumerations

enum  API_MDSetCmd { APIMDSetMerge_TW = 11 , APIMDSetMerge_HLM = 12 , APIMDSetMerge_Merge = 13 }
 ModulData operation code. More...
 

Functions

GSErrCode ACAPI_ModulData_Store (const API_ModulData *info, const GS::UniString &modulName=GS::EmptyUniString)
 Saves a custom data section into the project database.
 
GSErrCode ACAPI_ModulData_GetInfo (API_ModulData *info, const GS::UniString &modulName=GS::EmptyUniString)
 Returns information on the custom data section stored in the project database.
 
GSErrCode ACAPI_ModulData_Get (API_ModulData *info, const GS::UniString &modulName=GS::EmptyUniString)
 Returns the data section stored in the project database.
 
GSErrCode ACAPI_ModulData_GetList (GS::Array< GS::UniString > *modulNameList)
 Returns a list of names of the custom data sections stored in the project database.
 
GSErrCode ACAPI_ModulData_Delete (const GS::UniString &modulName=GS::EmptyUniString)
 Removes the custom data section stored in the project database.
 

Detailed Description

Functions for creating, handling and deleting custom (Add-On specific) Modul Data. Differs from User Data in not being attached to specific elements or element groups. This is a legacy technology, please use Add-On Objects instead.

ModulData Manager

It allows each add-on to own custom data sections in Archicad project files. No limitation is imposed on the structure or content, not even on the amount of saved bytes. Archicad knows nothing about its internal format, it just preserves a number of bytes in the project file and returns them upon requests.

Data sections are identified uniquely by the add-on's modul ID ('MDID') and an optional modul name string. This means the one data per add-on limitation of previous versions has been dissolved.

Functions

All of the ModulData Manager functions begin with the ACAPI_ModulData_ prefix. They are as follows:

Refer to the ModulData Manager example project to see detailed examples on using these functions.

Merging custom data sections

In certain situations modules of the same add-on can conflict with each other. When merging another plan into the project, it might be necessary to keep both the original and the incoming modul data, and to combine them together. Since the host application does not know the content of the modules, the owner add-on is requested to resolve the conflict.

For this purpose the add-on needs to implement an APIModulDataMergeHandlerProc callback handler function, and pass the function pointer to Archicad with the ACAPI_AddOnIntegration_InstallModulDataMergeHandler in the Initialize routine. It is also necessary to inform Archicad that the add-on is prepared for merging module data: this can be done with the ACAPI_AddOnIntegration_RegisterModulDataHandler function called from RegisterInterface.

In Teamwork mode it is also possible that the same module data is modified by the owner and by other team members. In this case the local and the server version of the data is conflicting at synchronization, and the add-on's APIModulDataMergeHandlerProc is called to adjust the proper data.

When Archicad calls the handler function, the API_MDSetCmd moduldata event codes inform you about the type of the actual operation:

Event Code Description
APIMDSetMerge_TW The data sections should be merged because of a Teamwork operation (e.g. Receive changes).
APIMDSetMerge_HLM The data section from a Hotlinked module should be merged into the main database.
APIMDSetMerge_Merge The data section should be merged from a file which was merged into the main project, or from a paste or Drag&Drop operation.

Moduldata versions

The API_ModulData structure contains a version number. If your data structure has to be changed, increase the version number. Upon retrieving the data section, check the version information and provide backward compatibility if possible.

Refer to the API_ModulData structure for more details.

Moduldata platforms

Since Archicad is a multi-platform application, all data written into the project file should be readable on the opposite platform too. As byte ordering is different on the Windows and on the Macintosh, for the correct interpretation the add-on needs to know on which platform the data was created. If the platform code differs from the actual platform, perform the necessary byte swapping operations using the GSRoot module, or use Memory Channel to read and write the custom data.

Refer to the API_ModulData structure for more details.

Saving data into old format project

If the structure of the custom data has changed since the previous version, you need to implement an APIModulDataSaveOldFormatHandlerProc callback function to be able to convert your modules when saving into an older format project. In order to be called this handler, the function pointer must be passed with ACAPI_AddOnIntegration_InstallModulDataSaveOldFormatHandler, and the modul data handling feature must be registered with ACAPI_AddOnIntegration_RegisterModulDataHandler.

When Archicad calls this function, the add-on should create the converted data according to the given plan file format, and pass it back to the application. The old format data should not be stored with ACAPI_ModulData_Store, nor the current data needs to be deleted or modified during the project save operation.

If the add-on does not install this converter callback routine, the available current format module data is saved into the old version project as well.

Other comments

Notice that it is not recommended to store unique ID-type references to Archicad elements in the module data; for this purpose try to use the Element Set Manager service instead.

The Modul Data - Saving Custom Data as a Section of the Archicad Project File

Every add-on can save custom data into an Archicad single project, teamwork project, or hotlink module. This lets the add-on programmers have a custom - unlimited length - data section in the project. The benefit of this feature is that it spares the Archicad users from having to care about many separate files that belong to a project and are needed by add-ons, when the project file changes its location (by copy, paste, email, ftp, etc).

The custom section of the project file can be anything the add-on programmer desires to save for his/her add-on, but special attention is needed for the issues of maintaining this data when the add-on is active, and also, the correct byte order, if the add-on was developed for multiplatform usage.


Trick: You can delete add-on data from a project file following these steps:

  1. Quit Archicad if it's running.
  2. Delete or remove the add-on from its location.
    (Usually the Add-Ons folder of your Archicad installation directory.)
  3. Start up Archicad, and open the Project file in Archicad that you want to erase the add-on data from.
  4. Locate the "Archicad Temporary Folder"
    (It is on the Temporary Volume, which can be set through the Options/Preferences/Data Safety menu, Temporary Folder Location button (or the applying localized version of it.) Usually it's on the C: drive on Windows, or in the System Folder of the System Drive on the Macintosh.)
  5. Switch into the APIData subfolder.
  6. Locate the tmp file that belongs to your add-on.
    (The corresponding file should contain the filename of your add-on at its 64th byte.)
  7. Delete the located file.
  8. Save the project in Archicad.

At the next opening of the project, your add-on data will not be present. This way you can decrease the load time of Archicad, test the initialization of an add-on with no add-on data present, or get rid of add-on data for add-ons you don't use any more.

Warning: The data deleted following this method will be lost and cannot be recovered!

Enumeration Type Documentation

◆ API_MDSetCmd

ModulData operation code.

Remarks
This value is passed as a parameter to the APIModulDataMergeHandlerProc callback function. When the ModulData Manager notifies your add-on, this code tells you the type of operation your add-on is called for. The APIMDSetMerge_Merge code means that the notification is posted because of the database must be updated; invoked by the Merge or Copy commands. The APIMDSetMerge_HLM and APIMDSetMerge_TW means the notification is posted because of the databases must be merged; invoked by Teamwork (Send Changes, Receive Changes), or Place Hotlink Module commands, respectively.

Function Documentation

◆ ACAPI_ModulData_Delete()

GSErrCode ACAPI_ModulData_Delete ( const GS::UniString &  modulName = GS::EmptyUniString)

Removes the custom data section stored in the project database.

Parameters
modulName[in] Identifier name of the modul data (optional).
Returns
  • NoError - The information was returned successfully.
  • APIERR_NOMODULEDATA - No custom data section is saved into the project file identified by the add-on's unique modul ID and the modulName parameter.
Remarks
This function is used to delete the custom data section embedded in the project database. Calling ACAPI_ModulData_Delete is equivalent to ACAPI_ModulData_Store (nullptr). This function is a non-undoable data structure modifier function. See more details on this topic at Command Overview.

◆ ACAPI_ModulData_Get()

GSErrCode ACAPI_ModulData_Get ( API_ModulData info,
const GS::UniString &  modulName = GS::EmptyUniString 
)

Returns the data section stored in the project database.

Parameters
info[out] Contains the the custom data stored in the project file on return.
modulName[in] Identifier name of the modul data (optional).
Returns
  • NoError - The function has completed successfully.
  • APIERR_BADPARS - The info parameter is nullptr.
  • APIERR_NOMODULEDATA - No custom data section is saved into the project file identified by the add-on's unique modul ID and the modulName parameter.
Remarks
This function is used to retrieve the data bytes of the custom data section embedded into the project database, identified with the given modulName.
  • Always check the platformSign returned in the API_ModulData structure. Call the necessary byte swapping methods to ensure correct data format. Refer to the GSRoot documentation to have further details on the byte swapping methods.
  • Always check the dataVersion returned in the API_ModulData structure. Old data formats should be handled to keep backward compatibility (see also APIModulDataSaveOldFormatHandlerProc). Archicad allocates the target buffer in the dataHdl field of info ; the caller add-on is responsible to dispose it with BMKillHandle. In order to check whether there is moduldata with the specified identifier stored into the current project, it is recommended to use the ACAPI_ModulData_GetInfo function, which does not retrieves the data itself but the version and platform information.
Example
GSErrCode MyDataClass::LoadFromModulData (void)
{
GSErrCode err;
BNZeroMemory (&info, sizeof (API_ModulData));
err = ACAPI_ModulData_GetInfo (&info, "MyFirstDataBlock");
if (err != NoError) {
if (err == APIERR_NOMODULEDATA)
err = NoError;
return err;
}
err = ACAPI_ModulData_Get (&info, "MyFirstDataBlock");
if (err == NoError && info.dataVersion == 1) {
myDataClassIntMember = *(reinterpret_cast<Int32*> (*info.dataHdl));
if (info.platformSign != GS::Act_Platform_Sign) { // swap data bytes
IVLong ((GS::PlatformSign) info.platformSign, &myDataClassIntMember);
}
}
BMKillHandle (&info.dataHdl);
return err;
}
GSErrCode ACAPI_ModulData_GetInfo(API_ModulData *info, const GS::UniString &modulName=GS::EmptyUniString)
Returns information on the custom data section stored in the project database.
GSErrCode ACAPI_ModulData_Get(API_ModulData *info, const GS::UniString &modulName=GS::EmptyUniString)
Returns the data section stored in the project database.
Control information of a custom data section saved into the project file.
Definition: APIdefs_ModulData.h:62
unsigned short platformSign
Byte ordering in data storage (can be either GS::Win_Platform_Sign, GS::Mac_Platform_Sign or GS::Mact...
Definition: APIdefs_ModulData.h:74
Int32 dataVersion
Data version; use this for backward compatibility.
Definition: APIdefs_ModulData.h:68
GSHandle dataHdl
User specified data (cannot be nullptr).
Definition: APIdefs_ModulData.h:81

◆ ACAPI_ModulData_GetInfo()

GSErrCode ACAPI_ModulData_GetInfo ( API_ModulData info,
const GS::UniString &  modulName = GS::EmptyUniString 
)

Returns information on the custom data section stored in the project database.

Parameters
info[out] The version and platform information of the stored moduldata.
modulName[in] Identifier name of the modul data (optional).
Returns
  • NoError - The information was returned successfully.
  • APIERR_BADPARS - The info parameter is nullptr.
  • APIERR_NOMODULEDATA - No custom data section is saved into the project file identified by the add-on's unique modul ID and the modulName parameter.
Remarks
This function is used to retrieve version and platform information on the custom data section embedded in the project database, identified with the given modulName. In order to get the stored data itself, use the ACAPI_ModulData_Get function.

◆ ACAPI_ModulData_GetList()

GSErrCode ACAPI_ModulData_GetList ( GS::Array< GS::UniString > *  modulNameList)

Returns a list of names of the custom data sections stored in the project database.

Parameters
modulNameList[out] List of moduldata names stored by the add-on into the current project.
Returns
  • NoError - The information was returned successfully.
  • APIERR_BADPARS - The modulNameList parameter is nullptr.
Remarks
This function is used to retrieve a list of names of the custom data sections embedded by the add-on in the project database. In order to get the stored data itself, use the ACAPI_ModulData_Get function using the names retrieved in the list. Empty list means no custom data section is stored in the project. If the project was saved in earlier format than Archicad 13, the modul name of the stored custom data is empty string ("").
Example
GS::Array<GS::UniString> modulNameList;
ACAPI_ModulData_GetList (&modulNameList);
for (GS::Array<GS::UniString>::ConstIterator it = modulNameList.Enumerate (); it != nullptr; ++it) {
API_ModulData modulData;
BNZeroMemory (&modulData, sizeof (API_ModulData));
if (ACAPI_ModulData_Get (&modulData, *it) == NoError) {
// do something with the moduldata
}
BMKillHandle (&modulData.dataHdl);
}
GSErrCode ACAPI_ModulData_GetList(GS::Array< GS::UniString > *modulNameList)
Returns a list of names of the custom data sections stored in the project database.

◆ ACAPI_ModulData_Store()

GSErrCode ACAPI_ModulData_Store ( const API_ModulData info,
const GS::UniString &  modulName = GS::EmptyUniString 
)

Saves a custom data section into the project database.

Parameters
info[in] The module data to store. It also includes platform and version information.
modulName[in] Identifier name of the modul data (optional).
Returns
  • NoError - the function completed successfully
  • APIERR_BADPARS - the passed dataHdl parameter is nullptr
  • APIERR_BADPLATFORMSIGN - the platformSign passed in info is not valid
  • APIERR_NOMODULEDATA - no custom data section is saved into the project file to be deleted
  • APIERR_MEMFULL - failed memory allocation
  • APIERR_GENERAL - a general error
Remarks
This function is used to embed a custom data section into the project database. The data section in the project is identified uniquely using the 'MDID' of the caller add-on and the passed modulName identifier. The dataHdl handle has to be allocated and released using the c%20Memory%20Manager"> BM memory manager functions of the GSRoot module. The data content can be copied into the handle directly, or you can use the allocated memory block as a memory channel (see IO::MemoryOChannel). In order to remove the saved module data from the project, you can simply pass nullptr pointer in the info parameter. The same effect can be achieved with the ACAPI_ModulData_Delete function. To retrieve the stored section use the ACAPI_ModulData_GetInfo and ACAPI_ModulData_Get functions. You can also get a list of names of all modules stored by the add-on with the ACAPI_ModulData_GetList function. If you need to save different format moduldata back into previous version project file, you should implement an APIModulDataSaveOldFormatHandlerProc callback function, which prepares the necessary data in the format corresponding to the project version. You might also need to merge data of the modules conflicting due to a merge or Teamwork receive operation. In order to properly resolve the conflicts you can implement an APIModulDataMergeHandlerProc callback function. For further details refer to the ModulData Manager overview. This function is a non-undoable data structure modifier function. See more details on this topic at Command Overview.
Example
GSErrCode MyDataClass::SaveIntoModulData (void)
{
GSErrCode err = NoError;
BNZeroMemory (&info, sizeof (API_ModulData));
info.dataVersion = 1;
info.platformSign = GS::Act_Platform_Sign;
info.dataHdl = BMAllocateHandle (sizeof (myDataClassIntMember), 0, 0);
if (info.dataHdl != nullptr) {
*(reinterpret_cast<Int32*> (*info.dataHdl)) = myDataClassIntMember;
err = ACAPI_ModulData_Store (&info, "MyFirstDataBlock");
BMKillHandle (&info.dataHdl);
} else {
err = APIERR_MEMFULL;
}
return err;
}
GSErrCode ACAPI_ModulData_Store(const API_ModulData *info, const GS::UniString &modulName=GS::EmptyUniString)
Saves a custom data section into the project database.