Coding conventions
Layout of the source tree
Path |
Contents |
|---|---|
|
Portable base library: strings, logging, exceptions, reference counting, threads, XML / JSON / zip, disk utilities. No UI. |
|
Document model, repositories (GigaBase), presentations, document types. |
|
The application and its ~40 feature modules ( |
|
DEP2 archive protocol, TCIOL transport, import / export tools. |
|
Pluggable components (BasicExport, PhotoFilter, SapLink, ShellFiles). |
|
Host-application integration: MsWord, MsExcel, MsOutlook, LotusNotes, WebExtension, ChromeExt. |
|
Standalone executables: TahitiServer, StiHandler, RunTpkg, Send2Damis. |
|
Image processing routines. |
|
Vendored third-party sources (FreeImage, libxml2, podofo, gigabase, cppunit, …). |
|
Installer (WiX) and build / release scripts. |
|
Fixtures for the test executables. |
Tests use cppunit with mfcTestRunner, one test executable per layer:
Tahiti/TahitiTest, TahitiBase/TahitiBaseTest, TahitiCore/TahitiCoreTest,
Communication/tciolTest.
Errors, logging, ownership
Errors are accumulated, not thrown. The convention is a
boolreturn plus a trailingTahitiException &tahitiExceptionout-parameter. Add context withTAHITI_EXCEPTION("msg")(it references the local namedtahitiException),TAHITI_EXCEPTION_OBJECT(obj, "msg")orTAHITI_EXCEPTION_LOCAL("msg"). For COM failures useTAHITI_COM_EXCEPTION(msg, pUnk, piid, hr)fromTahitiBase/ComUtils.h.Logging (
TahitiBase/logger.h):_LOG_SYS_DEBUG(x),_LOG_SYS_INFO(x),_LOG_SYS(level, x)with_LOG_LEVEL_CRITICAL | MEDIUM | INFO | DEBUG. Pass au8stringor aU8StringBuilder. Never log secrets, see Handling of secrets in memory.Reference counting (
TahitiBase/ReferenceCounter.h):lcbase::Reference<T>is the smart pointer,lcbase::ReferencedImpl<T>the instantiable wrapper:lcbase::Reference<Foo> f(new lcbase::ReferencedImpl<Foo>());
COM uses
CComPtr,_variant_t,_bstr_tandvtMissingfor optional arguments.
Architecture
A TahitiDomain owns a TahitiDomainComponentManager. Features are
TahitiDomainComponent instances registered under a name and resolved at
runtime:
TahitiDomainComponent *pComponent =
getDomain()->getComponentManager()->get(TU8(COMPONENT_DOCUMENTMANAGER_NAME));
DocumentManagerComponentBase *pDocMgr =
dynamic_cast<DocumentManagerComponentBase *>(pComponent);
Cross-module access goes through pure-virtual interface headers (...I.h,
...Base.h), so modules depend on interfaces rather than on each other’s
implementations. When a module needs to expose something new, extend its
interface header; do not reach into the concrete class.
The main window is MainFrame : CMDSIFrameWnd (Tahiti/Tahiti/MainFrame.cpp).
The ribbon is BCGControlBar Pro (CBCGPRibbonBar / CBCGPRibbonPanel /
CBCGPRibbonButton).
Recipe: adding a UI command
Resource id - add
#define ID_MY_CMD <n>toTahiti/TahitiCommon/resource.h.in(CMake copies it toresource.h). Add icon PNG entries with their own ids toTahiti/Tahiti/res/Tahiti.rc2.Command class - subclass
TahitiCommon::MenuCommandBaseandTahitiCommon::CommandHandler; useTahiti/Tahiti/ViewHistoryCmd.{h,cpp}as the template. ImplementgetMenuItemId(),getMenuItem(),onCommand(),onUpdateCommand().Register in
MainFrame::registerViewCommands(). EitherregisterCommandHandler(ID_MY_CMD, cmd->getHandler())binds the handler to a fixed resource id (ribbon and classic menu referenceID_MY_CMD), orregisterViewCommand(cmd)binds it to the string id from the id manager and appends it to the dynamic view-command list. Pick one.String id (only for
registerViewCommand) - addids.push_back(TahitiIdManagerId(TU8("My.Command"), 0));inTahiti/Tahiti/MainApp.cpp(addPredefinedMainIds/addPredefinedViewIds/addPredefinedToolbarIds).Menus - ribbon button in the relevant
Create*Panel()ofMainFrame.cpp; classic menu entry inTahiti/TahitiCommon/TahitiDocTemplate.cpp.Labels - add the key to
Tahiti/locale/{cs,en}/<Bundle>.properties.Build - add the new files to the module’s
CMakeLists.txt.
Localization
.properties bundles per module live under Tahiti/locale/<lang>/.
Translations exist for cs and en; add every new key to both. Lookup
macros (TahitiBase/localize.h, Tahiti/TahitiCommon/LocalizedStrings.h):
_TR_UI_TU8("Key") (default bundle), _TRB_UI_TU8("Bundle", "Key")
(explicit bundle), LS_TAHITICOMMON_UI("Key") (the TahitiCommon bundle).
Since 7.7 the application language follows the system language unless the user
overrides it in Options; a language is available when its locale
subdirectory contains the Common bundle.
Style
Indentation is inconsistent by file age: older files use tabs, newer or rewritten ones use 4 spaces. Follow the file you are editing; do not reflow surrounding code.
Doxygen comments:
/*! \brief ... */or/** ... */.Members are
m_-prefixed with a type hint:m_str...string,m_b...bool,m_i...int,m_sp...smart / COM pointer. Parameters usep...pointer,i...int,str...string,b...bool.Commit messages are written in Czech, usually
#<ticket> - <description>; release commits contain only the version number.