From ae9b3365aa310d90d769576967263bf66bf41b19 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Mon, 28 Dec 2009 22:26:48 +0000 Subject: Added an ID type to preferences which can be retrieved to then re-use the same dataset. IDs can be used in callbacks as user_data(). No need to keep an Fl_Preference around that would later require deleting. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6984 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- FL/Fl_Preferences.H | 27 ++++++++++++++++++++++++--- src/Fl_Preferences.cxx | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/FL/Fl_Preferences.H b/FL/Fl_Preferences.H index 7ad5de756..e734d7d23 100644 --- a/FL/Fl_Preferences.H +++ b/FL/Fl_Preferences.H @@ -80,6 +80,15 @@ public: USER ///< Preferences apply only to the current user }; + /** + Every Fl_Preferences-Group has a uniqe ID. + + ID's can be retrieved from an Fl_Preferences-Group and can then be used + to create more Fl_Preference references to the same data set, as long as the + databse remains open. + */ + typedef void *ID; + static const char *newUUID(); Fl_Preferences( Root root, const char *vendor, const char *application ); @@ -88,7 +97,10 @@ public: Fl_Preferences( Fl_Preferences *parent, const char *group ); Fl_Preferences( Fl_Preferences &parent, int groupIndex ); Fl_Preferences( Fl_Preferences *parent, int groupIndex ); + Fl_Preferences( ID id ); ~Fl_Preferences(); + + ID id(); /** Return the name of this entry. */ @@ -177,11 +189,18 @@ private: static char nameBuffer[128]; static char uuidBuffer[40]; + class RootNode; + class FL_EXPORT Node // a node contains a list to all its entries { // and all means to manage the tree structure - Node *child_, *next_, *parent_; + Node *child_, *next_; + union { // these two are mutually exclusive + Node *parent_; // top_ bit clear + RootNode *root_; // top_ bit set + }; char *path_; - char dirty_; + char dirty_:1; + char top_:1; public: Node( const char *path ); ~Node(); @@ -193,7 +212,9 @@ private: Node *search( const char *path, int offset=0 ); Node *addChild( const char *path ); void setParent( Node *parent ); - Node *parent() { return parent_; } + Node *parent() { return top_?parent_:0L; } + void setRoot(RootNode *r) { root_ = r; top_ = 1; } + RootNode *findRoot(); char remove(); char dirty(); // entry methods diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx index 866c90cae..41dd90c00 100644 --- a/src/Fl_Preferences.cxx +++ b/src/Fl_Preferences.cxx @@ -102,6 +102,7 @@ const char *Fl_Preferences::newUUID() b[10] = (unsigned char)(a>>16); b[11] = (unsigned char)(a>>24); char name[80]; // last four bytes + // BOOL GetComputerName(LPTSTR lpBuffer, LPDWORD nSize); gethostname(name, 79); memcpy(b+12, name, 4); sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", @@ -160,8 +161,9 @@ const char *Fl_Preferences::newUUID() */ Fl_Preferences::Fl_Preferences( Root root, const char *vendor, const char *application ) { - node = new Node( "." ); rootNode = new RootNode( this, root, vendor, application ); + node = new Node( "." ); + node->setRoot(rootNode); } @@ -179,8 +181,9 @@ Fl_Preferences::Fl_Preferences( Root root, const char *vendor, const char *appli */ Fl_Preferences::Fl_Preferences( const char *path, const char *vendor, const char *application ) { - node = new Node( "." ); rootNode = new RootNode( this, path, vendor, application ); + node = new Node( "." ); + node->setRoot(rootNode); } @@ -246,6 +249,24 @@ Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, int groupIndex ) } +/** + Create a new dataset access point using a dataset ID. + + ID's are a great way to remember shortcuts to database entries that are deeply + nested in a preferences database, as long as the databse root is not deleted. + An ID can be retrieved from any Fl_Preferences dataset, and can then be used + to create multiple new references to the same dataset. + + ID's can be put very helpful when put into the user_data() field of + widget callbacks. + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences::ID id ) +{ + node = (Node*)id; + rootNode = node->findRoot(); +} + + /** The destructor removes allocated resources. When used on the \em base preferences group, the destructor flushes all @@ -1166,6 +1187,7 @@ Fl_Preferences::Node::Node( const char *path ) entry = 0; nEntry = NEntry = 0; dirty_ = 0; + top_ = 0; } // delete this and all depending nodes @@ -1260,6 +1282,19 @@ void Fl_Preferences::Node::setParent( Node *pn ) path_ = strdup( nameBuffer ); } +// find the corresponding root node +Fl_Preferences::RootNode *Fl_Preferences::Node::findRoot() +{ + Node *n = this; + do { + if (n->top_) + return n->root_; + n = n->parent_; + + } while (n); + return 0L; +} + // add a child to this node and set its path (try to find it first...) Fl_Preferences::Node *Fl_Preferences::Node::addChild( const char *path ) { -- cgit v1.2.3