+private:
+ wxString m_strLine; // line contents
+ wxFileConfigLineList *m_pNext, // next node
+ *m_pPrev; // previous one
+};
+
+// ----------------------------------------------------------------------------
+// wxFileConfigEntry: a name/value pair
+// ----------------------------------------------------------------------------
+
+class wxFileConfigEntry
+{
+private:
+ wxFileConfigGroup *m_pParent; // group that contains us
+
+ wxString m_strName, // entry name
+ m_strValue; // value
+ bool m_bDirty:1, // changed since last read?
+ m_bImmutable:1, // can be overriden locally?
+ m_bHasValue:1; // set after first call to SetValue()
+
+ int m_nLine; // used if m_pLine == NULL only
+
+ // pointer to our line in the linked list or NULL if it was found in global
+ // file (which we don't modify)
+ wxFileConfigLineList *m_pLine;
+
+public:
+ wxFileConfigEntry(wxFileConfigGroup *pParent,
+ const wxString& strName, int nLine);
+
+ // simple accessors
+ const wxString& Name() const { return m_strName; }
+ const wxString& Value() const { return m_strValue; }
+ wxFileConfigGroup *Group() const { return m_pParent; }
+ bool IsDirty() const { return m_bDirty; }
+ bool IsImmutable() const { return m_bImmutable; }
+ bool IsLocal() const { return m_pLine != 0; }
+ int Line() const { return m_nLine; }
+ wxFileConfigLineList *
+ GetLine() const { return m_pLine; }
+
+ // modify entry attributes
+ void SetValue(const wxString& strValue, bool bUser = TRUE);
+ void SetDirty();
+ void SetLine(wxFileConfigLineList *pLine);
+};
+
+// ----------------------------------------------------------------------------
+// wxFileConfigGroup: container of entries and other groups
+// ----------------------------------------------------------------------------
+
+class wxFileConfigGroup
+{
+private:
+ wxFileConfig *m_pConfig; // config object we belong to
+ wxFileConfigGroup *m_pParent; // parent group (NULL for root group)
+ ArrayEntries m_aEntries; // entries in this group
+ ArrayGroups m_aSubgroups; // subgroups
+ wxString m_strName; // group's name
+ bool m_bDirty; // if FALSE => all subgroups are not dirty
+ wxFileConfigLineList *m_pLine; // pointer to our line in the linked list
+ wxFileConfigEntry *m_pLastEntry; // last entry/subgroup of this group in the
+ wxFileConfigGroup *m_pLastGroup; // local file (we insert new ones after it)
+
+ // DeleteSubgroupByName helper
+ bool DeleteSubgroup(wxFileConfigGroup *pGroup);
+
+public:
+ // ctor
+ wxFileConfigGroup(wxFileConfigGroup *pParent, const wxString& strName, wxFileConfig *);
+
+ // dtor deletes all entries and subgroups also
+ ~wxFileConfigGroup();
+
+ // simple accessors
+ const wxString& Name() const { return m_strName; }
+ wxFileConfigGroup *Parent() const { return m_pParent; }
+ wxFileConfig *Config() const { return m_pConfig; }
+ bool IsDirty() const { return m_bDirty; }
+
+ const ArrayEntries& Entries() const { return m_aEntries; }
+ const ArrayGroups& Groups() const { return m_aSubgroups; }
+ bool IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); }
+
+ // find entry/subgroup (NULL if not found)
+ wxFileConfigGroup *FindSubgroup(const wxChar *szName) const;
+ wxFileConfigEntry *FindEntry (const wxChar *szName) const;
+
+ // delete entry/subgroup, return FALSE if doesn't exist
+ bool DeleteSubgroupByName(const wxChar *szName);
+ bool DeleteEntry(const wxChar *szName);
+
+ // create new entry/subgroup returning pointer to newly created element
+ wxFileConfigGroup *AddSubgroup(const wxString& strName);
+ wxFileConfigEntry *AddEntry (const wxString& strName, int nLine = wxNOT_FOUND);
+
+ // will also recursively set parent's dirty flag
+ void SetDirty();
+ void SetLine(wxFileConfigLineList *pLine);
+
+ // rename: no checks are done to ensure that the name is unique!
+ void Rename(const wxString& newName);
+
+ //
+ wxString GetFullName() const;
+
+ // get the last line belonging to an entry/subgroup of this group
+ wxFileConfigLineList *GetGroupLine(); // line which contains [group]
+ wxFileConfigLineList *GetLastEntryLine(); // after which our subgroups start
+ wxFileConfigLineList *GetLastGroupLine(); // after which the next group starts
+
+ // called by entries/subgroups when they're created/deleted
+ void SetLastEntry(wxFileConfigEntry *pEntry) { m_pLastEntry = pEntry; }
+ void SetLastGroup(wxFileConfigGroup *pGroup) { m_pLastGroup = pGroup; }
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// static functions
+// ----------------------------------------------------------------------------
+wxString wxFileConfig::GetGlobalDir()
+{
+ wxString strDir;
+
+ #ifdef __VMS__ // Note if __VMS is defined __UNIX is also defined
+ strDir = wxT("sys$manager:");
+ #elif defined( __UNIX__ )
+ strDir = wxT("/etc/");
+ #elif defined(__WXPM__)
+ ULONG aulSysInfo[QSV_MAX] = {0};
+ UINT drive;
+ APIRET rc;
+
+ rc = DosQuerySysInfo( 1L, QSV_MAX, (PVOID)aulSysInfo, sizeof(ULONG)*QSV_MAX);
+ if (rc == 0)
+ {
+ drive = aulSysInfo[QSV_BOOT_DRIVE - 1];
+ switch(drive)
+ {
+ case 1:
+ strDir = "A:\\OS2\\";
+ break;
+ case 2:
+ strDir = "B:\\OS2\\";
+ break;
+ case 3:
+ strDir = "C:\\OS2\\";
+ break;
+ case 4:
+ strDir = "D:\\OS2\\";
+ break;
+ case 5:
+ strDir = "E:\\OS2\\";
+ break;
+ case 6:
+ strDir = "F:\\OS2\\";
+ break;
+ case 7:
+ strDir = "G:\\OS2\\";
+ break;
+ case 8:
+ strDir = "H:\\OS2\\";
+ break;
+ case 9:
+ strDir = "I:\\OS2\\";
+ break;
+ case 10:
+ strDir = "J:\\OS2\\";
+ break;
+ case 11:
+ strDir = "K:\\OS2\\";
+ break;
+ case 12:
+ strDir = "L:\\OS2\\";
+ break;
+ case 13:
+ strDir = "M:\\OS2\\";
+ break;
+ case 14:
+ strDir = "N:\\OS2\\";
+ break;
+ case 15:
+ strDir = "O:\\OS2\\";
+ break;
+ case 16:
+ strDir = "P:\\OS2\\";
+ break;
+ case 17:
+ strDir = "Q:\\OS2\\";
+ break;
+ case 18:
+ strDir = "R:\\OS2\\";
+ break;
+ case 19:
+ strDir = "S:\\OS2\\";
+ break;
+ case 20:
+ strDir = "T:\\OS2\\";
+ break;
+ case 21:
+ strDir = "U:\\OS2\\";
+ break;
+ case 22:
+ strDir = "V:\\OS2\\";
+ break;
+ case 23:
+ strDir = "W:\\OS2\\";
+ break;
+ case 24:
+ strDir = "X:\\OS2\\";
+ break;
+ case 25:
+ strDir = "Y:\\OS2\\";
+ break;
+ case 26:
+ strDir = "Z:\\OS2\\";
+ break;
+ }
+ }
+ #elif defined(__WXSTUBS__)
+ wxASSERT_MSG( FALSE, wxT("TODO") ) ;
+ #elif defined(__WXMAC__)
+ strDir = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder ) ;
+ #else // Windows
+ wxChar szWinDir[MAX_PATH];
+ ::GetWindowsDirectory(szWinDir, MAX_PATH);
+
+ strDir = szWinDir;
+ strDir << wxT('\\');
+ #endif // Unix/Windows
+
+ return strDir;