Update of /cvsroot/mahogany/M/src/classes
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10627/src/classes
Modified Files:
Profile.cpp
Log Message:
added wxConfigMultiplexer to allow code using wxConfig and not Profile (as
persistent controls) to still work with multiple config sources
Index: Profile.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/classes/Profile.cpp,v
retrieving revision 1.161
retrieving revision 1.162
diff -b -u -2 -r1.161 -r1.162
--- Profile.cpp 12 Jul 2004 00:25:56 -0000 1.161
+++ Profile.cpp 4 Jul 2005 19:51:40 -0000 1.162
@@ -103,4 +103,6 @@
{
public:
+ enum Type { LD_LONG, LD_STRING };
+
LookupData(const String& key, const String& def)
: m_Key(key), m_Str(def)
@@ -119,5 +121,17 @@
}
- enum Type { LD_LONG, LD_STRING };
+ // default copy ctor, assignment operator and dtor are ok
+
+
+ // don't compare m_Found field here, just the data
+ bool operator==(const LookupData& other)
+ {
+ if ( other.m_Type != m_Type || other.m_Key != m_Key )
+ return false;
+
+ return m_Type == LD_LONG ? other.m_Long == m_Long
+ : other.m_Str == m_Str;
+ }
+
Type GetType(void) const { return m_Type; }
@@ -199,5 +213,4 @@
#endif // OS_UNIX
-
/**
AllConfigSources is a list of all config source the profiles use.
@@ -220,9 +233,16 @@
by their priority values.
+ Side effect: this ctor also changes the global wxConfig object by
+ creating a new wxConfigMultiplexer instance and setting it as global
+ wxConfig using wxConfig::Set().
+
@param filename the file used for the default config, may be empty
*/
AllConfigSources(const String& filename);
- // default dtor is ok
+ /**
+ Destructor destroys wxConfig we had set in ctor.
+ */
+ ~AllConfigSources();
@@ -289,8 +309,14 @@
/// Return true if the given group exists in any config source
- bool HasGroup(const String& path) const;
+ bool HasGroup(const String& path) const
+ {
+ return FindGroup(path) != m_sources.end();
+ }
/// Return true if the given entry exists in any config source
- bool HasEntry(const String& path) const;
+ bool HasEntry(const String& path) const
+ {
+ return FindEntry(path) != m_sources.end();
+ }
//@}
@@ -335,12 +361,28 @@
/**
- Get wxConfig object associated with the local config source.
+ @name Helper methods for wxConfigMultiplexer only.
+
+ Do not use these methods from elsewhere.
+ */
+ //@{
+
+ /// Get the list of all sources
+ List& GetSources() { return m_sources; }
+ const List& GetSources() const { return m_sources; }
+
+ /// Find the config source containing this entry
+ List::iterator FindEntry(const String& path) const;
- This method is deprecated and must not be used, it is there only to
- avoid breaking some existing code.
+ /// Find the config source containing this group
+ List::iterator FindGroup(const String& path) const;
+
+ /**
+ Get wxConfig object associated with the local config source.
@param config pointer (not to be deleted by caller) or NULL
*/
- wxConfigBase *GetConfig() const;
+ wxConfigBase *GetLocalConfig() const;
+
+ //@}
private:
@@ -352,7 +394,6 @@
List m_sources;
- // we can't be coppied
- AllConfigSources(const AllConfigSources&);
- AllConfigSources& operator=(const AllConfigSources&);
+
+ DECLARE_NO_COPY_CLASS(AllConfigSources)
};
@@ -362,4 +403,212 @@
/**
+ wxConfigMultiplexer is a wxConfig façade for AllConfigSources.
+
+ wxConfigMultiplexer presents wxConfig interface for AllConfigSources
+ functionality, i.e. it reads from all config sources and not just from the
+ local config.
+ */
+class wxConfigMultiplexer : public wxConfigBase
+{
+public:
+ wxConfigMultiplexer(AllConfigSources& configSources)
+ : m_configSources(configSources)
+ {
+ }
+
+ virtual void SetPath(const wxString& path)
+ {
+ m_path = path;
+ wxConfigBase * const config = m_configSources.GetLocalConfig();
+ if ( config )
+ config->SetPath(path);
+ }
+
+ virtual const wxString& GetPath() const { return m_path; }
+
+
+ virtual bool GetFirstGroup(wxString& str, long& lIndex) const
+ {
+ wxConfigBase * const config = m_configSources.GetLocalConfig();
+ return config && config->GetFirstGroup(str, lIndex);
+ }
+
+ virtual bool GetNextGroup(wxString& str, long& lIndex) const
+ {
+ wxConfigBase * const config = m_configSources.GetLocalConfig();
+ return config && config->GetNextGroup(str, lIndex);
+ }
+
+ virtual bool GetFirstEntry(wxString& str, long& lIndex) const
+ {
+ wxConfigBase * const config = m_configSources.GetLocalConfig();
+ return config && config->GetFirstEntry(str, lIndex);
+ }
+
+ virtual bool GetNextEntry(wxString& str, long& lIndex) const
+ {
+ wxConfigBase * const config = m_configSources.GetLocalConfig();
+ return config && config->GetNextEntry(str, lIndex);
+ }
+
+
+ virtual size_t GetNumberOfEntries(bool bRecursive = false) const
+ {
+ wxConfigBase * const config = m_configSources.GetLocalConfig();
+ return config ? config->GetNumberOfEntries(bRecursive) : 0;
+ }
+
+ virtual size_t GetNumberOfGroups(bool bRecursive = false) const
+ {
+ wxConfigBase * const config = m_configSources.GetLocalConfig();
+ return config ? config->GetNumberOfGroups(bRecursive) : 0;
+ }
+
+
+ virtual bool HasGroup(const wxString& name) const
+ {
+ return m_configSources.HasGroup(name);
+ }
+
+ virtual bool HasEntry(const wxString& name) const
+ {
+ return m_configSources.HasEntry(name);
+ }
+
+
+ virtual bool Flush(bool /* bCurrentOnly */ = false)
+ {
+ return m_configSources.FlushAll();
+ }
+
+ virtual bool
+ RenameEntry(const wxString& /* oldName */, const wxString& /* newName */)
+ {
+ FAIL_MSG( _T("not implemented") );
+
+ return false;
+ }
+
+ virtual bool
+ RenameGroup(const wxString& /* oldName */, const wxString& /* newName */)
+ {
+ FAIL_MSG( _T("not implemented") );
+
+ return false;
+ }
+
+ virtual bool DeleteEntry(const wxString& key, bool /* groupIfEmpty */ =
true)
+ {
+ wxString path;
+ if ( *key.c_str() == _T('/') )
+ path = key;
+ else
+ path << m_path << _T('/') << key;
+
+ // we need to delete all these entries
+ bool foundAny = false;
+ for ( ;; )
+ {
+ AllConfigSources::List::iterator i = m_configSources.FindEntry(path);
+ if ( i == m_configSources.GetSources().end() )
+ {
+ CHECK( foundAny, false, _T("entry to delete doesn't exist") );
+ break;
+ }
+
+ foundAny = true;
+ if ( !i->DeleteEntry(path) )
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual bool DeleteGroup(const wxString& key)
+ {
+ wxString path;
+ if ( *key.c_str() == _T('/') )
+ path = key;
+ else
+ path << m_path << _T('/') << key;
+
+ bool foundAny = false;
+ for ( ;; )
+ {
+ AllConfigSources::List::iterator i = m_configSources.FindGroup(path);
+ if ( i == m_configSources.GetSources().end() )
+ {
+ CHECK( foundAny, false, _T("group to delete doesn't exist") );
+ break;
+ }
+
+ foundAny = true;
+ if ( !i->DeleteGroup(path) )
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual bool DeleteAll()
+ {
+ // this is too dangerous, we don't provide any way to wipe out all config
+ // information
+ return false;
+ }
+
+protected:
+ bool DoRead(LookupData& ld) const
+ {
+ return m_configSources.Read(m_path, ld);
+ }
+
+ bool DoWrite(LookupData& ld)
+ {
+ return m_configSources.Write(m_path, ld, NULL /* use local config */);
+ }
+
+
+ virtual bool DoReadString(const wxString& key, wxString *pStr) const
+ {
+ LookupData ld(key, _T(""));
+ if ( !DoRead(ld) )
+ return false;
+
+ *pStr = ld.GetString();
+ return true;
+ }
+
+ virtual bool DoReadLong(const wxString& key, long *pl) const
+ {
+ LookupData ld(key, 0l);
+ if ( !DoRead(ld) )
+ return false;
+
+ *pl = ld.GetLong();
+ return true;
+ }
+
+ virtual bool DoWriteString(const wxString& key, const wxString& value)
+ {
+ LookupData ld(key, value);
+ return DoWrite(ld);
+ }
+
+ virtual bool DoWriteLong(const wxString& key, long value)
+ {
+ LookupData ld(key, value);
+ return DoWrite(ld);
+ }
+
+private:
+ AllConfigSources& m_configSources;
+ wxString m_path;
+
+ DECLARE_NO_COPY_CLASS(wxConfigMultiplexer)
+};
+
+
+/**
ProfileEnumDataImpl is used to store state data while iterating over
entries/subgroups of a profile.
@@ -482,6 +731,5 @@
virtual const String& GetName(void) const { return m_ProfileName; }
- virtual wxConfigBase *GetConfig() const
- { return gs_allConfigSources ? gs_allConfigSources->GetConfig() : NULL; }
+ virtual wxConfigBase *GetConfig() const { return wxConfig::Get(); }
virtual void Suspend(void)
@@ -738,4 +986,11 @@
}
+ // also register out special wxConfig for persistent controls use
+ delete wxConfig::Set(new wxConfigMultiplexer(*this));
+
+
+ // now build the list of all config source we use
+ // ----------------------------------------------
+
// local config is always first
m_sources.push_back(configLocal);
@@ -810,4 +1065,10 @@
}
+AllConfigSources::~AllConfigSources()
+{
+ // we can't allow wxConfigMultiplexer to live any longer
+ delete wxConfig::Set(NULL);
+}
+
// ----------------------------------------------------------------------------
// AllConfigSources reading and writing
@@ -847,4 +1108,14 @@
config = *m_sources.begin().operator->();
+
+ // avoid writing to local config source the same data that are already
+ // present in another one with lesser priority: this just results in huge
+ // duplication of data without any gain
+ LookupData dataOld(data);
+ if ( Read(path, dataOld) && dataOld == data )
+ {
+ // the same value already present, don't write it
+ return true;
+ }
}
@@ -935,5 +1206,6 @@
}
-bool AllConfigSources::HasGroup(const String& path) const
+AllConfigSources::List::iterator
+AllConfigSources::FindGroup(const String& path) const
{
const List::iterator end = m_sources.end();
@@ -941,11 +1213,12 @@
{
if ( i->HasGroup(path) )
- return true;
+ return i;
}
- return false;
+ return end;
}
-bool AllConfigSources::HasEntry(const String& path) const
+AllConfigSources::List::iterator
+AllConfigSources::FindEntry(const String& path) const
{
const List::iterator end = m_sources.end();
@@ -953,8 +1226,8 @@
{
if ( i->HasEntry(path) )
- return true;
+ return i;
}
- return false;
+ return end;
}
@@ -1068,5 +1341,5 @@
-wxConfigBase *AllConfigSources::GetConfig() const
+wxConfigBase *AllConfigSources::GetLocalConfig() const
{
if ( m_sources.empty() )
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates