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
This commit is contained in:
Vadim Zeitlin
1999-01-20 19:54:17 +00:00
parent e0543d2a70
commit 5d1902d6d6
6 changed files with 219 additions and 121 deletions

View File

@@ -257,6 +257,17 @@ arbitrary path (either relative or absolute), not just the key name.
\helpref{Write}{wxconfigbasewrite}\\ \helpref{Write}{wxconfigbasewrite}\\
\helpref{Flush}{wxconfigbaseflush} \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} \membersection{Delete entries/groups}
The functions in this section delete entries and/or groups of entries from the 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 Reads a bool value, returning TRUE if the value was found. If the value was
not found, {\it defaultVal} is used instead. 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} \membersection{wxConfigBase::Set}\label{wxconfigbaseset}
\func{wxConfigBase *}{Set}{\param{wxConfigBase *}{pConfig}} \func{wxConfigBase *}{Set}{\param{wxConfigBase *}{pConfig}}

View File

@@ -185,6 +185,15 @@ public:
// permanently writes all changes // permanently writes all changes
virtual bool Flush(bool bCurrentOnly = FALSE) = 0; 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 // delete entries/groups
// deletes the specified entry and the group it belongs to if // deletes the specified entry and the group it belongs to if
// it was the last key in it and the second parameter is true // it was the last key in it and the second parameter is true

View File

@@ -98,35 +98,34 @@
(it's on by default, the current status can be retrieved with (it's on by default, the current status can be retrieved with
IsExpandingEnvVars function). IsExpandingEnvVars function).
*/ */
class wxFileConfig; //linea nueva class wxFileConfig;
class ConfigGroup; class ConfigGroup;
class ConfigEntry; class ConfigEntry;
// we store all lines of the local config file as a linked list in memory // we store all lines of the local config file as a linked list in memory
class LineList class LineList
{ {
public: public:
void SetNext(LineList *pNext) { m_pNext = pNext; } void SetNext(LineList *pNext) { m_pNext = pNext; }
void SetPrev(LineList *pPrev) { m_pPrev = pPrev; } void SetPrev(LineList *pPrev) { m_pPrev = pPrev; }
// ctor // ctor
LineList(const wxString& str, LineList *pNext = (LineList *) NULL) : m_strLine(str) LineList(const wxString& str, LineList *pNext = (LineList *) NULL) : m_strLine(str)
{ SetNext(pNext); SetPrev((LineList *) NULL); } { SetNext(pNext); SetPrev((LineList *) NULL); }
// //
LineList *Next() const { return m_pNext; } LineList *Next() const { return m_pNext; }
LineList *Prev() const { return m_pPrev; } LineList *Prev() const { return m_pPrev; }
// //
void SetText(const wxString& str) { m_strLine = str; } void SetText(const wxString& str) { m_strLine = str; }
const wxString& Text() const { return m_strLine; } const wxString& Text() const { return m_strLine; }
private:
wxString m_strLine; // line contents
LineList *m_pNext, // next node
*m_pPrev; // previous one
};
private:
wxString m_strLine; // line contents
LineList *m_pNext, // next node
*m_pPrev; // previous one
};
class wxFileConfig : public wxConfigBase class wxFileConfig : public wxConfigBase
{ {
@@ -190,32 +189,33 @@ public:
// The following are necessary to satisfy the compiler // The following are necessary to satisfy the compiler
wxString Read(const wxString& key, const wxString& defVal) const 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 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 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 bool Read(const wxString& key, int *pi, int defVal) const
{ return wxConfigBase::Read(key, pi, defVal); } { return wxConfigBase::Read(key, pi, defVal); }
bool Read(const wxString& key, int *pi) const bool Read(const wxString& key, int *pi) const
{ return wxConfigBase::Read(key, pi); } { return wxConfigBase::Read(key, pi); }
bool Read(const wxString& key, double* val) const 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 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, const wxString& szValue);
virtual bool Write(const wxString& key, long lValue); virtual bool Write(const wxString& key, long lValue);
virtual bool Flush(bool bCurrentOnly = FALSE); 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 DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso);
virtual bool DeleteGroup(const wxString& szKey); virtual bool DeleteGroup(const wxString& szKey);
virtual bool DeleteAll(); virtual bool DeleteAll();
public: public:
// fwd decl
// functions to work with this list // functions to work with this list
LineList *LineListAppend(const wxString& str); LineList *LineListAppend(const wxString& str);
LineList *LineListInsert(const wxString& str, LineList *LineListInsert(const wxString& str,
@@ -224,7 +224,7 @@ public:
bool LineListIsEmpty(); bool LineListIsEmpty();
private: private:
// GetXXXFileame helpers: return ('/' terminated) directory names // GetXXXFileName helpers: return ('/' terminated) directory names
static wxString GetGlobalDir(); static wxString GetGlobalDir();
static wxString GetLocalDir(); static wxString GetLocalDir();
@@ -253,111 +253,106 @@ private:
ConfigGroup *m_pRootGroup, // the top (unnamed) group ConfigGroup *m_pRootGroup, // the top (unnamed) group
*m_pCurrentGroup; // the current 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: public:
WX_DEFINE_SORTED_ARRAY(ConfigEntry *, ArrayEntries); WX_DEFINE_SORTED_ARRAY(ConfigEntry *, ArrayEntries);
WX_DEFINE_SORTED_ARRAY(ConfigGroup *, ArrayGroups); WX_DEFINE_SORTED_ARRAY(ConfigGroup *, ArrayGroups);
}; };
class ConfigEntry class ConfigEntry
{ {
private: private:
ConfigGroup *m_pParent; // group that contains us ConfigGroup *m_pParent; // group that contains us
wxString m_strName, // entry name wxString m_strName, // entry name
m_strValue; // value m_strValue; // value
bool m_bDirty, // changed since last read? bool m_bDirty, // changed since last read?
m_bImmutable; // can be overriden locally? m_bImmutable; // can be overriden locally?
int m_nLine; // used if m_pLine == NULL only int m_nLine; // used if m_pLine == NULL only
LineList *m_pLine; // pointer to our line in the linked list LineList *m_pLine; // pointer to our line in the linked list
// or NULL if it was found in global file // or NULL if it was found in global file
public: public:
ConfigEntry(ConfigGroup *pParent, const wxString& strName, int nLine); ConfigEntry(ConfigGroup *pParent, const wxString& strName, int nLine);
// simple accessors // simple accessors
const wxString& Name() const { return m_strName; } const wxString& Name() const { return m_strName; }
const wxString& Value() const { return m_strValue; } const wxString& Value() const { return m_strValue; }
ConfigGroup *Group() const { return m_pParent; } ConfigGroup *Group() const { return m_pParent; }
bool IsDirty() const { return m_bDirty; } bool IsDirty() const { return m_bDirty; }
bool IsImmutable() const { return m_bImmutable; } bool IsImmutable() const { return m_bImmutable; }
bool IsLocal() const { return m_pLine != 0; } bool IsLocal() const { return m_pLine != 0; }
int Line() const { return m_nLine; } int Line() const { return m_nLine; }
LineList *GetLine() const { return m_pLine; } LineList *GetLine() const { return m_pLine; }
// modify entry attributes // modify entry attributes
void SetValue(const wxString& strValue, bool bUser = TRUE); void SetValue(const wxString& strValue, bool bUser = TRUE);
void SetDirty(); void SetDirty();
void SetLine(LineList *pLine); void SetLine(LineList *pLine);
}; };
class ConfigGroup class ConfigGroup
{ {
private: private:
wxFileConfig *m_pConfig; // config object we belong to wxFileConfig *m_pConfig; // config object we belong to
ConfigGroup *m_pParent; // parent group (NULL for root group) ConfigGroup *m_pParent; // parent group (NULL for root group)
wxFileConfig::ArrayEntries m_aEntries; // entries in this group wxFileConfig::ArrayEntries m_aEntries; // entries in this group
wxFileConfig::ArrayGroups m_aSubgroups; // subgroups wxFileConfig::ArrayGroups m_aSubgroups; // subgroups
wxString m_strName; // group's name wxString m_strName; // group's name
bool m_bDirty; // if FALSE => all subgroups are not dirty bool m_bDirty; // if FALSE => all subgroups are not dirty
LineList *m_pLine; // pointer to our line in the linked list LineList *m_pLine; // pointer to our line in the linked list
ConfigEntry *m_pLastEntry; // last entry/subgroup of this group in the ConfigEntry *m_pLastEntry; // last entry/subgroup of this group in the
ConfigGroup *m_pLastGroup; // local file (we insert new ones after it) ConfigGroup *m_pLastGroup; // local file (we insert new ones after it)
// DeleteSubgroupByName helper // DeleteSubgroupByName helper
bool DeleteSubgroup(ConfigGroup *pGroup); bool DeleteSubgroup(ConfigGroup *pGroup);
public: public:
// ctor // ctor
ConfigGroup(ConfigGroup *pParent, const wxString& strName, wxFileConfig *); ConfigGroup(ConfigGroup *pParent, const wxString& strName, wxFileConfig *);
// dtor deletes all entries and subgroups also // dtor deletes all entries and subgroups also
~ConfigGroup(); ~ConfigGroup();
// simple accessors // simple accessors
const wxString& Name() const { return m_strName; } const wxString& Name() const { return m_strName; }
ConfigGroup *Parent() const { return m_pParent; } ConfigGroup *Parent() const { return m_pParent; }
wxFileConfig *Config() const { return m_pConfig; } wxFileConfig *Config() const { return m_pConfig; }
bool IsDirty() const { return m_bDirty; } bool IsDirty() const { return m_bDirty; }
const wxFileConfig::ArrayEntries& Entries() const { return m_aEntries; } const wxFileConfig::ArrayEntries& Entries() const { return m_aEntries; }
const wxFileConfig::ArrayGroups& Groups() const { return m_aSubgroups; } const wxFileConfig::ArrayGroups& Groups() const { return m_aSubgroups; }
bool IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); } bool IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); }
// find entry/subgroup (NULL if not found) // find entry/subgroup (NULL if not found)
ConfigGroup *FindSubgroup(const char *szName) const; ConfigGroup *FindSubgroup(const char *szName) const;
ConfigEntry *FindEntry (const char *szName) const; ConfigEntry *FindEntry (const char *szName) const;
// delete entry/subgroup, return FALSE if doesn't exist // delete entry/subgroup, return FALSE if doesn't exist
bool DeleteSubgroupByName(const char *szName); bool DeleteSubgroupByName(const char *szName);
bool DeleteEntry(const char *szName); bool DeleteEntry(const char *szName);
// create new entry/subgroup returning pointer to newly created element // create new entry/subgroup returning pointer to newly created element
ConfigGroup *AddSubgroup(const wxString& strName); ConfigGroup *AddSubgroup(const wxString& strName);
ConfigEntry *AddEntry (const wxString& strName, int nLine = wxNOT_FOUND); ConfigEntry *AddEntry (const wxString& strName, int nLine = wxNOT_FOUND);
// will also recursively set parent's dirty flag // will also recursively set parent's dirty flag
void SetDirty(); void SetDirty();
void SetLine(LineList *pLine); void SetLine(LineList *pLine);
// // rename: no checks are done to ensure that the name is unique!
wxString GetFullName() const; void Rename(const wxString& newName);
// get the last line belonging to an entry/subgroup of this group //
LineList *GetGroupLine(); // line which contains [group] wxString GetFullName() const;
LineList *GetLastEntryLine(); // after which our subgroups start
LineList *GetLastGroupLine(); // after which the next group starts
// called by entries/subgroups when they're created/deleted // get the last line belonging to an entry/subgroup of this group
void SetLastEntry(ConfigEntry *pEntry) { m_pLastEntry = pEntry; } LineList *GetGroupLine(); // line which contains [group]
void SetLastGroup(ConfigGroup *pGroup) { m_pLastGroup = pGroup; } 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 #endif //_FILECONF_H

View File

@@ -91,6 +91,9 @@ public:
virtual bool Flush(bool bCurrentOnly = FALSE); 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 DeleteEntry(const wxString& Key, bool bGroupIfEmptyAlso);
virtual bool DeleteGroup(const wxString& szKey); virtual bool DeleteGroup(const wxString& szKey);
virtual bool DeleteAll(); virtual bool DeleteAll();

View File

@@ -85,6 +85,10 @@ public:
virtual bool Flush(bool /* bCurrentOnly = FALSE */ ) { return TRUE; } 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 // delete
virtual bool DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso); virtual bool DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso);
virtual bool DeleteGroup(const wxString& key); virtual bool DeleteGroup(const wxString& key);

View File

@@ -73,10 +73,8 @@
inline bool IsValid(char c) { return isalnum(c) || strchr("@_/-!.*%", c); } inline bool IsValid(char c) { return isalnum(c) || strchr("@_/-!.*%", c); }
// compare functions for sorting the arrays // compare functions for sorting the arrays
static int CompareEntries(ConfigEntry *p1, static int CompareEntries(ConfigEntry *p1, ConfigEntry *p2);
ConfigEntry *p2); static int CompareGroups(ConfigGroup *p1, ConfigGroup *p2);
static int CompareGroups(ConfigGroup *p1,
ConfigGroup *p2);
// filter strings // filter strings
static wxString FilterIn(const wxString& str); static wxString FilterIn(const wxString& str);
@@ -654,6 +652,50 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */)
return file.Commit(); 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 // 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 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 would still need to do it for the subgroups the code wouldn't have been
significantly less complicated. significantly less complicated.
*/ */
// Return the line which contains "[our name]". If we're still not in the list, // 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 // 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 // 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 wxString ConfigGroup::GetFullName() const
{ {
if ( Parent() ) if ( Parent() )