From 5d1902d6d6efc842c8f488520d3cca40f1ae99f8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 20 Jan 1999 19:54:17 +0000 Subject: [PATCH] RenameEntry/Group() functions added to wxConfig and derivations (not yet implemented for wxIniCnfig and wxRegConfig) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1438 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/config.tex | 33 ++++++ include/wx/confbase.h | 9 ++ include/wx/fileconf.h | 249 +++++++++++++++++++-------------------- include/wx/msw/iniconf.h | 3 + include/wx/msw/regconf.h | 4 + src/common/fileconf.cpp | 64 +++++++++- 6 files changed, 230 insertions(+), 132 deletions(-) diff --git a/docs/latex/wx/config.tex b/docs/latex/wx/config.tex index af679b31a5..8e74b3d429 100644 --- a/docs/latex/wx/config.tex +++ b/docs/latex/wx/config.tex @@ -257,6 +257,17 @@ arbitrary path (either relative or absolute), not just the key name. \helpref{Write}{wxconfigbasewrite}\\ \helpref{Flush}{wxconfigbaseflush} +\membersection{Rename entries/groups} + +The functions in this section allow to rename entries or subgroups of the +current group. They will return FALSE on error. typically because either the +entry/group with the original name doesn't exist, because the entry/group with +the new name already exists or because the function is not supported in this +wxConfig implementation. + +\helpref{RenameEntry}{wxconfigbaserenameentry}\\ +\helpref{RenameGroup}{wxconfigbaserenamegroup} + \membersection{Delete entries/groups} The functions in this section delete entries and/or groups of entries from the @@ -561,6 +572,28 @@ not found, {\it b} is not changed. Reads a bool value, returning TRUE if the value was found. If the value was not found, {\it defaultVal} is used instead. +\membersection{wxConfigBase::RenameEntry}\label{wxconfigbaserenameentry} + +\func{bool}{RenameEntry}{\param{const wxString\& }{ oldName}, \param{const wxString\& }{ newName}} + +Renames an entry in the current group. The entries names (both the old and +the new one) shouldn't contain backslashes, i.e. only simple names and not +arbitrary paths are accepted by this function. + +Returns FALSE if the {\it oldName} doesn't exist or if {\it newName} already +exists. + +\membersection{wxConfigBase::RenameGroup}\label{wxconfigbaserenamegroup} + +\func{bool}{RenameGroup}{\param{const wxString\& }{ oldName}, \param{const wxString\& }{ newName}} + +Renames a subgroup of the current group. The subgroup names (both the old and +the new one) shouldn't contain backslashes, i.e. only simple names and not +arbitrary paths are accepted by this function. + +Returns FALSE if the {\it oldName} doesn't exist or if {\it newName} already +exists. + \membersection{wxConfigBase::Set}\label{wxconfigbaseset} \func{wxConfigBase *}{Set}{\param{wxConfigBase *}{pConfig}} diff --git a/include/wx/confbase.h b/include/wx/confbase.h index 36a9d05efe..b2a4ceb21f 100644 --- a/include/wx/confbase.h +++ b/include/wx/confbase.h @@ -185,6 +185,15 @@ public: // permanently writes all changes virtual bool Flush(bool bCurrentOnly = FALSE) = 0; + // renaming, all functions return FALSE on failure (probably because the new + // name is already taken by an existing entry) + // rename an entry + virtual bool RenameEntry(const wxString& oldName, + const wxString& newName) = 0; + // rename a group + virtual bool RenameGroup(const wxString& oldName, + const wxString& newName) = 0; + // delete entries/groups // deletes the specified entry and the group it belongs to if // it was the last key in it and the second parameter is true diff --git a/include/wx/fileconf.h b/include/wx/fileconf.h index 0e19e07954..3465dc923f 100644 --- a/include/wx/fileconf.h +++ b/include/wx/fileconf.h @@ -98,35 +98,34 @@ (it's on by default, the current status can be retrieved with IsExpandingEnvVars function). */ - class wxFileConfig; //linea nueva - class ConfigGroup; - class ConfigEntry; +class wxFileConfig; +class ConfigGroup; +class ConfigEntry; - // we store all lines of the local config file as a linked list in memory - class LineList - { - public: - void SetNext(LineList *pNext) { m_pNext = pNext; } - void SetPrev(LineList *pPrev) { m_pPrev = pPrev; } - - // ctor - LineList(const wxString& str, LineList *pNext = (LineList *) NULL) : m_strLine(str) - { SetNext(pNext); SetPrev((LineList *) NULL); } +// we store all lines of the local config file as a linked list in memory +class LineList +{ +public: + void SetNext(LineList *pNext) { m_pNext = pNext; } + void SetPrev(LineList *pPrev) { m_pPrev = pPrev; } - // - LineList *Next() const { return m_pNext; } - LineList *Prev() const { return m_pPrev; } + // ctor + LineList(const wxString& str, LineList *pNext = (LineList *) NULL) : m_strLine(str) + { SetNext(pNext); SetPrev((LineList *) NULL); } - // - void SetText(const wxString& str) { m_strLine = str; } - const wxString& Text() const { return m_strLine; } + // + LineList *Next() const { return m_pNext; } + LineList *Prev() const { return m_pPrev; } - private: - wxString m_strLine; // line contents - LineList *m_pNext, // next node - *m_pPrev; // previous one - }; + // + void SetText(const wxString& str) { m_strLine = str; } + const wxString& Text() const { return m_strLine; } +private: + wxString m_strLine; // line contents + LineList *m_pNext, // next node + *m_pPrev; // previous one +}; class wxFileConfig : public wxConfigBase { @@ -190,32 +189,33 @@ public: // The following are necessary to satisfy the compiler wxString Read(const wxString& key, const wxString& defVal) const - { return wxConfigBase::Read(key, defVal); } + { return wxConfigBase::Read(key, defVal); } bool Read(const wxString& key, long *pl, long defVal) const - { return wxConfigBase::Read(key, pl, defVal); } + { return wxConfigBase::Read(key, pl, defVal); } long Read(const wxString& key, long defVal) const - { return wxConfigBase::Read(key, defVal); } + { return wxConfigBase::Read(key, defVal); } bool Read(const wxString& key, int *pi, int defVal) const { return wxConfigBase::Read(key, pi, defVal); } bool Read(const wxString& key, int *pi) const { return wxConfigBase::Read(key, pi); } bool Read(const wxString& key, double* val) const - { return wxConfigBase::Read(key, val); } + { return wxConfigBase::Read(key, val); } bool Read(const wxString& key, double* val, double defVal) const - { return wxConfigBase::Read(key, val, defVal); } + { return wxConfigBase::Read(key, val, defVal); } virtual bool Write(const wxString& key, const wxString& szValue); virtual bool Write(const wxString& key, long lValue); virtual bool Flush(bool bCurrentOnly = FALSE); + virtual bool RenameEntry(const wxString& oldName, const wxString& newName); + virtual bool RenameGroup(const wxString& oldName, const wxString& newName); + virtual bool DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso); virtual bool DeleteGroup(const wxString& szKey); virtual bool DeleteAll(); public: - // fwd decl - // functions to work with this list LineList *LineListAppend(const wxString& str); LineList *LineListInsert(const wxString& str, @@ -224,7 +224,7 @@ public: bool LineListIsEmpty(); private: - // GetXXXFileame helpers: return ('/' terminated) directory names + // GetXXXFileName helpers: return ('/' terminated) directory names static wxString GetGlobalDir(); static wxString GetLocalDir(); @@ -253,111 +253,106 @@ private: ConfigGroup *m_pRootGroup, // the top (unnamed) group *m_pCurrentGroup; // the current group -//protected: --- if wxFileConfig::ConfigEntry is not public, functions in -// ConfigGroup such as Find/AddEntry can't return "ConfigEntry *" public: WX_DEFINE_SORTED_ARRAY(ConfigEntry *, ArrayEntries); WX_DEFINE_SORTED_ARRAY(ConfigGroup *, ArrayGroups); +}; +class ConfigEntry +{ +private: + ConfigGroup *m_pParent; // group that contains us + wxString m_strName, // entry name + m_strValue; // value + bool m_bDirty, // changed since last read? + m_bImmutable; // can be overriden locally? + int m_nLine; // used if m_pLine == NULL only + LineList *m_pLine; // pointer to our line in the linked list + // or NULL if it was found in global file + +public: + ConfigEntry(ConfigGroup *pParent, const wxString& strName, int nLine); + + // simple accessors + const wxString& Name() const { return m_strName; } + const wxString& Value() const { return m_strValue; } + ConfigGroup *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; } + LineList *GetLine() const { return m_pLine; } + + // modify entry attributes + void SetValue(const wxString& strValue, bool bUser = TRUE); + void SetDirty(); + void SetLine(LineList *pLine); }; - class ConfigEntry - { - private: - ConfigGroup *m_pParent; // group that contains us - wxString m_strName, // entry name - m_strValue; // value - bool m_bDirty, // changed since last read? - m_bImmutable; // can be overriden locally? - int m_nLine; // used if m_pLine == NULL only - LineList *m_pLine; // pointer to our line in the linked list - // or NULL if it was found in global file - - public: - ConfigEntry(ConfigGroup *pParent, const wxString& strName, int nLine); - - // simple accessors - const wxString& Name() const { return m_strName; } - const wxString& Value() const { return m_strValue; } - ConfigGroup *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; } - LineList *GetLine() const { return m_pLine; } - - // modify entry attributes - void SetValue(const wxString& strValue, bool bUser = TRUE); - void SetDirty(); - void SetLine(LineList *pLine); - }; - - class ConfigGroup - { - private: - wxFileConfig *m_pConfig; // config object we belong to - ConfigGroup *m_pParent; // parent group (NULL for root group) - wxFileConfig::ArrayEntries m_aEntries; // entries in this group - wxFileConfig::ArrayGroups m_aSubgroups; // subgroups - wxString m_strName; // group's name - bool m_bDirty; // if FALSE => all subgroups are not dirty - LineList *m_pLine; // pointer to our line in the linked list - ConfigEntry *m_pLastEntry; // last entry/subgroup of this group in the - ConfigGroup *m_pLastGroup; // local file (we insert new ones after it) - - // DeleteSubgroupByName helper - bool DeleteSubgroup(ConfigGroup *pGroup); - - public: - // ctor - ConfigGroup(ConfigGroup *pParent, const wxString& strName, wxFileConfig *); - - // dtor deletes all entries and subgroups also - ~ConfigGroup(); - - // simple accessors - const wxString& Name() const { return m_strName; } - ConfigGroup *Parent() const { return m_pParent; } - wxFileConfig *Config() const { return m_pConfig; } - bool IsDirty() const { return m_bDirty; } - - const wxFileConfig::ArrayEntries& Entries() const { return m_aEntries; } - const wxFileConfig::ArrayGroups& Groups() const { return m_aSubgroups; } - bool IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); } - - // find entry/subgroup (NULL if not found) - ConfigGroup *FindSubgroup(const char *szName) const; - ConfigEntry *FindEntry (const char *szName) const; - - // delete entry/subgroup, return FALSE if doesn't exist - bool DeleteSubgroupByName(const char *szName); - bool DeleteEntry(const char *szName); - - // create new entry/subgroup returning pointer to newly created element - ConfigGroup *AddSubgroup(const wxString& strName); - ConfigEntry *AddEntry (const wxString& strName, int nLine = wxNOT_FOUND); - - // will also recursively set parent's dirty flag - void SetDirty(); - void SetLine(LineList *pLine); - - // - wxString GetFullName() const; - - // get the last line belonging to an entry/subgroup of this group - LineList *GetGroupLine(); // line which contains [group] - LineList *GetLastEntryLine(); // after which our subgroups start - LineList *GetLastGroupLine(); // after which the next group starts - - // called by entries/subgroups when they're created/deleted - void SetLastEntry(ConfigEntry *pEntry) { m_pLastEntry = pEntry; } - void SetLastGroup(ConfigGroup *pGroup) { m_pLastGroup = pGroup; } - }; +class ConfigGroup +{ +private: + wxFileConfig *m_pConfig; // config object we belong to + ConfigGroup *m_pParent; // parent group (NULL for root group) + wxFileConfig::ArrayEntries m_aEntries; // entries in this group + wxFileConfig::ArrayGroups m_aSubgroups; // subgroups + wxString m_strName; // group's name + bool m_bDirty; // if FALSE => all subgroups are not dirty + LineList *m_pLine; // pointer to our line in the linked list + ConfigEntry *m_pLastEntry; // last entry/subgroup of this group in the + ConfigGroup *m_pLastGroup; // local file (we insert new ones after it) + + // DeleteSubgroupByName helper + bool DeleteSubgroup(ConfigGroup *pGroup); -#endif //_FILECONF_H +public: + // ctor + ConfigGroup(ConfigGroup *pParent, const wxString& strName, wxFileConfig *); + + // dtor deletes all entries and subgroups also + ~ConfigGroup(); + + // simple accessors + const wxString& Name() const { return m_strName; } + ConfigGroup *Parent() const { return m_pParent; } + wxFileConfig *Config() const { return m_pConfig; } + bool IsDirty() const { return m_bDirty; } + + const wxFileConfig::ArrayEntries& Entries() const { return m_aEntries; } + const wxFileConfig::ArrayGroups& Groups() const { return m_aSubgroups; } + bool IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); } + // find entry/subgroup (NULL if not found) + ConfigGroup *FindSubgroup(const char *szName) const; + ConfigEntry *FindEntry (const char *szName) const; + // delete entry/subgroup, return FALSE if doesn't exist + bool DeleteSubgroupByName(const char *szName); + bool DeleteEntry(const char *szName); + // create new entry/subgroup returning pointer to newly created element + ConfigGroup *AddSubgroup(const wxString& strName); + ConfigEntry *AddEntry (const wxString& strName, int nLine = wxNOT_FOUND); + // will also recursively set parent's dirty flag + void SetDirty(); + void SetLine(LineList *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 + LineList *GetGroupLine(); // line which contains [group] + LineList *GetLastEntryLine(); // after which our subgroups start + LineList *GetLastGroupLine(); // after which the next group starts + + // called by entries/subgroups when they're created/deleted + void SetLastEntry(ConfigEntry *pEntry) { m_pLastEntry = pEntry; } + void SetLastGroup(ConfigGroup *pGroup) { m_pLastGroup = pGroup; } +}; + +#endif //_FILECONF_H diff --git a/include/wx/msw/iniconf.h b/include/wx/msw/iniconf.h index 331ee3f469..a49994978f 100644 --- a/include/wx/msw/iniconf.h +++ b/include/wx/msw/iniconf.h @@ -91,6 +91,9 @@ public: virtual bool Flush(bool bCurrentOnly = FALSE); + virtual bool RenameEntry(const wxString& oldName, const wxString& newName); + virtual bool RenameGroup(const wxString& oldName, const wxString& newName); + virtual bool DeleteEntry(const wxString& Key, bool bGroupIfEmptyAlso); virtual bool DeleteGroup(const wxString& szKey); virtual bool DeleteAll(); diff --git a/include/wx/msw/regconf.h b/include/wx/msw/regconf.h index f9fd74eb90..630bab52d6 100644 --- a/include/wx/msw/regconf.h +++ b/include/wx/msw/regconf.h @@ -85,6 +85,10 @@ public: virtual bool Flush(bool /* bCurrentOnly = FALSE */ ) { return TRUE; } + // rename + virtual bool RenameEntry(const wxString& oldName, const wxString& newName); + virtual bool RenameGroup(const wxString& oldName, const wxString& newName); + // delete virtual bool DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso); virtual bool DeleteGroup(const wxString& key); diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index c887bc6b86..dd99938e9a 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -73,10 +73,8 @@ inline bool IsValid(char c) { return isalnum(c) || strchr("@_/-!.*%", c); } // compare functions for sorting the arrays -static int CompareEntries(ConfigEntry *p1, - ConfigEntry *p2); -static int CompareGroups(ConfigGroup *p1, - ConfigGroup *p2); +static int CompareEntries(ConfigEntry *p1, ConfigEntry *p2); +static int CompareGroups(ConfigGroup *p1, ConfigGroup *p2); // filter strings static wxString FilterIn(const wxString& str); @@ -654,6 +652,50 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */) return file.Commit(); } +// ---------------------------------------------------------------------------- +// renaming groups/entries +// ---------------------------------------------------------------------------- + +bool wxFileConfig::RenameEntry(const wxString& oldName, + const wxString& newName) +{ + // check that the entry exists + ConfigEntry *oldEntry = m_pCurrentGroup->FindEntry(oldName); + if ( !oldEntry ) + return FALSE; + + // check that the new entry doesn't already exist + if ( m_pCurrentGroup->FindEntry(newName) ) + return FALSE; + + // delete the old entry, create the new one + wxString value = oldEntry->Value(); + if ( !m_pCurrentGroup->DeleteEntry(oldName) ) + return FALSE; + + ConfigEntry *newEntry = m_pCurrentGroup->AddEntry(newName); + newEntry->SetValue(value); + + return TRUE; +} + +bool wxFileConfig::RenameGroup(const wxString& oldName, + const wxString& newName) +{ + // check that the group exists + ConfigGroup *group = m_pCurrentGroup->FindSubgroup(oldName); + if ( !group ) + return FALSE; + + // check that the new group doesn't already exist + if ( m_pCurrentGroup->FindSubgroup(newName) ) + return FALSE; + + group->Rename(newName); + + return TRUE; +} + // ---------------------------------------------------------------------------- // delete groups/entries // ---------------------------------------------------------------------------- @@ -852,7 +894,7 @@ void ConfigGroup::SetLine(LineList *pLine) backwards in the config file (OTOH, it's not that important) and as we would still need to do it for the subgroups the code wouldn't have been significantly less complicated. - */ +*/ // Return the line which contains "[our name]". If we're still not in the list, // add our line to it immediately after the last line of our parent group if we @@ -917,6 +959,18 @@ LineList *ConfigGroup::GetLastEntryLine() // group name // ---------------------------------------------------------------------------- +void ConfigGroup::Rename(const wxString& newName) +{ + m_strName = newName; + + LineList *line = GetGroupLine(); + wxString strFullName; + strFullName << "[" << (GetFullName().c_str() + 1) << "]"; // +1: no '/' + line->SetText(strFullName); + + SetDirty(); +} + wxString ConfigGroup::GetFullName() const { if ( Parent() ) -- 2.45.2