summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>2002-04-28 16:41:17 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>2002-04-28 16:41:17 +0000
commit44bb5f60de2bd7162a6de2d0cb73377ce1a55bc1 (patch)
tree7c361e263dd10f6ab636b85f241a6c3d421d9024
parent081d369c114780af58b5be639ff3d431a8602705 (diff)
Add Fl_Preferences class to base library.
Add FLTK_DATADIR definition to config.h for system-wide configuration data. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@2126 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--CHANGES3
-rw-r--r--FL/Fl_Preferences.H148
-rw-r--r--configh.in7
-rw-r--r--configure.in11
-rw-r--r--documentation/Fl_Preferences.html184
-rw-r--r--documentation/Makefile263
-rw-r--r--makefiles/config.mingw7
-rw-r--r--makefiles/config.os2x7
-rw-r--r--src/Fl_Preferences.cxx828
-rw-r--r--src/Fl_Window.cxx5
-rw-r--r--src/Makefile5
-rw-r--r--visualc/config.h7
-rw-r--r--visualc/fltk.lib.dsp4
-rw-r--r--visualc/fltkdll.dsp5
14 files changed, 1365 insertions, 119 deletions
diff --git a/CHANGES b/CHANGES
index cba1a6f51..e1e7a30f1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
CHANGES IN FLTK 1.1.0rc1
+ - Added Fl_Preferences class from Matthias Melcher.
+ - FLUID now recognizes the "using" keyword in
+ declarations.
- fl_file_chooser() didn't highlight the requested file
the second time the file chooser dialog was shown.
- Fixed rendering of Fl_Light_Button with the plastic
diff --git a/FL/Fl_Preferences.H b/FL/Fl_Preferences.H
new file mode 100644
index 000000000..cf9ca2d21
--- /dev/null
+++ b/FL/Fl_Preferences.H
@@ -0,0 +1,148 @@
+//
+// "$Id: Fl_Preferences.H,v 1.1.2.1 2002/04/28 16:41:16 easysw Exp $"
+//
+// Preferences header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2002 by Matthias Melcher.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@matthiasm.com".
+//
+
+#ifndef Fl_Preferences_H
+#define Fl_Preferences_H
+
+# include <stdio.h>
+
+/* missing functions:
+
+ Fl_Preferences should return functions to create and access User Data directories
+ Fl_Preferences could offer functions that return the value instead off an error code to write directly into widgets
+*/
+
+/**
+ * Preferences are a data tree containing a root, branches and leafs
+ */
+class Fl_Preferences
+{
+
+public:
+
+ typedef enum { SYSTEM=0, USER } Root;
+ // typedef enum { win32, macos, fltk } Type;
+
+ FL_EXPORT Fl_Preferences( enum Root root, const char *vendor, const char *application );
+ FL_EXPORT Fl_Preferences( Fl_Preferences&, const char *group );
+ FL_EXPORT Fl_Preferences( Fl_Preferences*, const char *group );
+ FL_EXPORT ~Fl_Preferences();
+
+ FL_EXPORT int groups();
+ FL_EXPORT const char *group( int );
+ FL_EXPORT int groupExists( const char *group );
+ FL_EXPORT int deleteGroup( const char *group );
+
+ FL_EXPORT int entries();
+ FL_EXPORT const char *entry( int );
+ FL_EXPORT int entryExists( const char *entry );
+ FL_EXPORT int deleteEntry( const char *entry );
+
+ FL_EXPORT int set( const char *entry, int value );
+ FL_EXPORT int set( const char *entry, float value );
+ FL_EXPORT int set( const char *entry, double value );
+ FL_EXPORT int set( const char *entry, const char *value );
+ // FL_EXPORT int set( const char *entry, const void *value, int size );
+
+ FL_EXPORT int get( const char *entry, int &value, int defaultValue );
+ FL_EXPORT int get( const char *entry, float &value, float defaultValue );
+ FL_EXPORT int get( const char *entry, double &value, double defaultValue );
+ FL_EXPORT int get( const char *entry, char *&value, const char *defaultValue );
+ FL_EXPORT int get( const char *entry, char *value, const char *defaultValue, int maxSize );
+ // FL_EXPORT int get( const char *entry, void *&value, const char *defaultValue );
+ // FL_EXPORT int get( const char *entry, void *value, const char *defaultValue, int maxSize );
+ FL_EXPORT int size( const char *entry );
+
+ FL_EXPORT int getUserdataPath( char *path );
+
+ FL_EXPORT void flush();
+
+ // FL_EXPORT int export( const char *filename, enum Type fileFormat );
+ // FL_EXPORT int import( const char *filename );
+
+ // FL_EXPORT const char *namef( const char *, ... );
+
+private:
+
+ static char nameBuffer[128];
+
+ struct Entry
+ {
+ char *name, *value;
+ };
+
+ class Node
+ {
+ Node *child_, *next_, *parent_;
+ char *path_;
+ int dirty_;
+ public:
+ Node( const char *path );
+ ~Node();
+ Node *find( const char *path );
+ Node *search( const char *path );
+ int write( FILE *f );
+ void setParent( Node *parent );
+ Node *addChild( const char *path );
+ void set( const char *name, const char *value );
+ void set( const char *line );
+ void add( const char *line );
+ const char *get( const char *name );
+ int getEntry( const char *name );
+ int deleteEntry( const char *name );
+ int remove();
+ int dirty();
+ int nChildren();
+ const char *child( int ix );
+ Entry *entry;
+ int nEntry, NEntry;
+ static int lastEntrySet;
+ };
+ friend class Node;
+
+ class RootNode
+ {
+ Fl_Preferences *prefs_; //++ maybe we should hold a reference to the first node
+ char *filename_;
+ char *vendor_, *application_;
+ public:
+ RootNode( Fl_Preferences *, enum Root root, const char *vendor, const char *application );
+ ~RootNode();
+ int read();
+ int write();
+ int getPath( char *path );
+ };
+ friend class RootNode;
+
+ Node *node;
+ RootNode *rootNode;
+};
+
+
+#endif
+
+//
+// End of "$Id: Fl_Preferences.H,v 1.1.2.1 2002/04/28 16:41:16 easysw Exp $".
+//
diff --git a/configh.in b/configh.in
index 59911f471..fc5d8194d 100644
--- a/configh.in
+++ b/configh.in
@@ -1,5 +1,5 @@
/*
- * "$Id: configh.in,v 1.11.2.11.2.10 2002/04/24 18:29:05 easysw Exp $"
+ * "$Id: configh.in,v 1.11.2.11.2.11 2002/04/28 16:41:15 easysw Exp $"
*
* Configuration file for the Fast Light Tool Kit (FLTK).
* @configure_input@
@@ -25,9 +25,10 @@
*/
/*
- * Where to find the documentation files...
+ * Where to find files...
*/
+#define FLTK_DATADIR ""
#define FLTK_DOCDIR ""
/*
@@ -219,5 +220,5 @@
/*
- * End of "$Id: configh.in,v 1.11.2.11.2.10 2002/04/24 18:29:05 easysw Exp $".
+ * End of "$Id: configh.in,v 1.11.2.11.2.11 2002/04/28 16:41:15 easysw Exp $".
*/
diff --git a/configure.in b/configure.in
index 8d9168b83..89c40cb77 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
dnl -*- sh -*-
dnl the "configure" script is made from this by running GNU "autoconf"
dnl
-dnl "$Id: configure.in,v 1.33.2.31.2.63 2002/04/26 12:39:32 easysw Exp $"
+dnl "$Id: configure.in,v 1.33.2.31.2.64 2002/04/28 16:41:15 easysw Exp $"
dnl
dnl Configuration script for the Fast Light Tool Kit (FLTK).
dnl
@@ -720,6 +720,13 @@ else
AC_DEFINE_UNQUOTED(FLTK_DOCDIR, "$prefix/share/doc/fltk")
fi
+dnl Define the FLTK data directory...
+if test x$prefix = xNONE; then
+ AC_DEFINE_UNQUOTED(FLTK_DATADIR, "/usr/local/share/fltk")
+else
+ AC_DEFINE_UNQUOTED(FLTK_DATADIR, "$prefix/share/fltk")
+fi
+
dnl Write all of the files...
AC_CONFIG_HEADER(config.h:configh.in)
AC_OUTPUT(makeinclude fltk.list fltk-config FL/Makefile)
@@ -728,5 +735,5 @@ dnl Make sure the fltk-config script is executable...
chmod +x fltk-config
dnl
-dnl End of "$Id: configure.in,v 1.33.2.31.2.63 2002/04/26 12:39:32 easysw Exp $".
+dnl End of "$Id: configure.in,v 1.33.2.31.2.64 2002/04/28 16:41:15 easysw Exp $".
dnl
diff --git a/documentation/Fl_Preferences.html b/documentation/Fl_Preferences.html
new file mode 100644
index 000000000..966cf08e2
--- /dev/null
+++ b/documentation/Fl_Preferences.html
@@ -0,0 +1,184 @@
+<html>
+<body>
+
+<!-- NEW PAGE -->
+
+<h2>class Fl_Preferences</h2>
+
+<hr>
+
+<h3>Class Hierarchy</h3>
+
+<ul><pre>
+<b>Fl_Preferences</a></H4>&nbsp;
+</pre></ul>
+
+<h3>Include Files</h3>
+
+<ul><pre>
+#include &lt;FL/Fl_Preferences.H&gt;
+</pre></ul>
+
+<h3>Description</h3>
+
+<P><tt>Fl_Preferences </tt>provides methods to store user
+setting between application starts. It is similar to the
+Registry on WIN32 and Preferences on MacOS, and provides a
+simple configuration mechanism for UNIX.
+
+<P><tt>Fl_Preferences </tt>uses a hierarchy to store data. It
+bundles similar data into groups and manages entries into those
+groups as name/value pairs.
+
+<P>Preferences are stored in text files that can be edited
+manually. The file format is easy to read and relatively
+forgiving. Preferences files are the same on all platforms. User
+comments in preference files are preserved. Filenames are unique
+for each application by using a vendor/application naming
+scheme. The user must provide default values for all entries to
+ensure proper operation should preferences be corrupted or not
+yet exist.
+
+<P>Entries can be of any length. However, the size of each
+preferences file should be kept under 100k for performance
+reasons. One application can have multiple preferences files.
+Extensive binary data however should be stored in seperate
+files; see the <A
+href="#Fl_Preferences.getUserdataPath"><tt>getUserdataPath()</tt></A>
+method.
+
+<h3>Methods</h3>
+
+<ul>
+
+ <li><a href="#Fl_Preferences.Fl_Preferences">Fl_Preferences</a></li>
+ <li><a href="#Fl_Preferences.~Fl_Preferences">~Fl_Preferences</a></li>
+ <li><a href="#Fl_Preferences.deleteEntry">deleteEntry</a></li>
+ <li><a href="#Fl_Preferences.deleteGroup">deleteGroup</a></li>
+ <li><a href="#Fl_Preferences.entries">entries</a></li>
+ <li><a href="#Fl_Preferences.entry">entry</a></li>
+ <li><a href="#Fl_Preferences.entryExists">entryExists</a></li>
+ <li><a href="#Fl_Preferences.get">get</a></li>
+ <li><a href="#Fl_Preferences.getUserdataPath">getUserdataPath</a></li>
+ <li><a href="#Fl_Preferences.group">group</a></li>
+ <li><a href="#Fl_Preferences.groupExists">groupExists</a></li>
+ <li><a href="#Fl_Preferences.groups">groups</a></li>
+ <li><a href="#Fl_Preferences.set">set</a></li>
+ <li><a href="#Fl_Preferences.size">size</a></li>
+
+</ul>
+
+<H4><a name="Fl_Preferences.Fl_Preferences">Fl_Preferences(enum Root root,
+const char *vendor, const char *application)<BR>
+Fl_Preferences(Fl_Preferences &amp;p, const char *groupname)</a></H4>
+
+<P>The constructor creates a group that manages name/value pairs and
+child groups. Groups are ready for reading and writing at any time.
+The <tt>root</tt> argument is either <tt>Fl_Preferences::USER</tt>
+or <tt>Fl_Preferences::SYSTEM</tt>.
+
+<P>The first format creates the <i>base</i> instance for all
+following entries and reads existing databases into memory. The
+<tt>vendor</tt> argument is a unique text string identifying the
+development team or vendor of an application. A domain name or
+an EMail address are great unique names, e.g.
+"researchATmatthiasm.com" or "fltk.org". The
+<tt>application</tt> argument can be the working title or final
+name of your application. Both <tt>vendor</tt> and
+<tt>application</tt> must be valid relative UNIX pathnames and
+may contain '/'s to create deeper file structures.
+
+<P>The <tt>groupname</tt> argument identifies a group of
+entries. It can contain '/'s to get quick access to individual
+elements inside the hierarchy.
+
+<H4><a name="Fl_Preferences.~Fl_Preferences">~Fl_Preferences()</a></H4>
+
+<P>The destructor removes allocated resources. When used on the
+<i>base</i> preferences group, the destructor flushes all
+changes to the preferences file and deletes all internal
+databases.
+
+<H4><a name="Fl_Preferences.deleteEntry">int Fl_Preferences::deleteEntry(const char *entry)</a></H4>
+
+<P>Removes a single entry (name/value pair).
+
+<H4><a name="Fl_Preferences.deleteGroup">int Fl_Preferences::deleteGroup(const char *groupname)</a></H4>
+
+<P>Deletes a group.
+
+<H4><a name="Fl_Preferences.entries">int Fl_Preferences::entries()</a></H4>
+
+<P>Returns the number of entries (name/value) pairs in a group.
+
+<H4><a name="Fl_Preferences.entry">const char *Fl_Preferences::entry(int ix)</a></H4>
+
+<P>Returns the name of an entry. There is no guaranteed order of
+entry names. The index must be within the range given by
+<tt>entries()</tt>.
+
+<H4><a name="Fl_Preferences.entryExists">int Fl_Preferences::entryExists(const char *entry)</a></H4>
+
+<P>Returns non-zero if an entry with this name exists.
+
+<H4><a name="Fl_Preferences.flush">void Fl_Preferences::flush()</a></H4>
+
+<P>Write all preferences to disk. This function works only with
+the base preference group. This function is rarely used as
+deleting the base preferences flushes automatically.
+
+<H4><a name="Fl_Preferences.getUserdataPath">int Fl_Preferences::getUserdataPath(char *path)</a></H4>
+
+<P>Creates a path that is related to the preferences file and
+that is usable for application data beyond what is covered by
+<tt>Fl_Preferences</tt>.
+
+<H4><a name="Fl_Preferences.get">int get(const char *entry, int &amp;value,&nbsp;&nbsp; int defaultValue)<BR>
+int get(const char *entry, int &amp;value,&nbsp;&nbsp;&nbsp; int defaultValue)<BR>
+int get(const char *entry, float &amp;value,&nbsp; float defaultValue)<BR>
+int get(const char *entry, double &amp;value, double defaultValue )
+int get(const char *entry, char *&amp;value,&nbsp; const char *defaultValue)<BR>
+int get(const char *entry, char *value,&nbsp;&nbsp; const char *defaultValue,
+int maxSize)</a></H4>
+
+<P>Reads an entry from the group. A default value must be
+supplied. The return value indicates if the value was available
+(non-zero) or the default was used (0). If the '<tt>char
+*&amp;value</tt>' form is used, the resulting text must be freed
+with '<tt>free(value)</tt>'.
+
+<H4><a name="Fl_Preferences.group">const char
+*Fl_Preferences::group(int ix)</a></H4>
+
+<P>Returns the name of the Nth group. There is no guaranteed
+order of group names. The index must be within the range given
+by <tt>groups()</tt>.
+
+<H4><a name="Fl_Preferences.groupExists">int Fl_Preferences::groupExists(const char *groupname)</a></H4>
+
+<P>Returns non-zero if a group with this name exists.
+
+<H4><a name="Fl_Preferences.groups">int Fl_Preferences::groups()</a></H4>
+
+<P>Returns the number of groups that are contained within a
+group.
+
+<H4><a name="Fl_Preferences.set">int set(const char *entry, int value)<BR>
+int set(const char *entry, int value)<BR>
+int set(const char *entry, float value)<BR>
+int set(const char *entry, double value)<BR>
+int set(const char *entry, const char *value)</a></H4>
+
+<P>Sets an entry (name/value pair). Text data must not contain
+any '\n' or '\r' characters. The return value indicates if there
+was a problem storing the data in memory. However it does not
+reflect if the value was actually stored in the preferences
+file.
+
+<H4><a name="Fl_Preferences.size">int Fl_Preferences::size(const char *key)</a></H4>
+
+<P>Returns the size of the value part of an entry.
+
+
+</body>
+</html>
diff --git a/documentation/Makefile b/documentation/Makefile
index f90e821b1..7d8074145 100644
--- a/documentation/Makefile
+++ b/documentation/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile,v 1.9.2.10.2.13 2002/04/20 21:07:18 easysw Exp $"
+# "$Id: Makefile,v 1.9.2.10.2.14 2002/04/28 16:41:16 easysw Exp $"
#
# Documentation makefile for the Fast Light Tool Kit (FLTK).
#
@@ -42,102 +42,163 @@ MEDIA = --size universal
# These are the HTML "source" files...
HTMLFILES = \
- basics.html \
- common.html \
- drawing.html \
- editor.html \
- enumerations.html \
- events.html \
- Fl.html \
- Fl_Adjuster.html \
- Fl_Bitmap.html \
- Fl_BMP_Image.html \
- Fl_Box.html \
- Fl_Browser_.html \
- Fl_Browser.html \
- Fl_Button.html \
- Fl_Chart.html \
- Fl_Check_Button.html \
- Fl_Choice.html \
- Fl_Clock.html \
- Fl_Color_Chooser.html \
- Fl_Counter.html \
- Fl_Dial.html \
- Fl_Double_Window.html \
- Fl_End.html \
- Fl_File_Browser.html \
- Fl_File_Chooser.html \
- Fl_File_Icon.html \
- Fl_Float_Input.html \
- Fl_Free.html \
- Fl_GIF_Image.html \
- Fl_Gl_Window.html \
- Fl_Group.html \
- Fl_Help_Dialog.html \
- Fl_Help_View.html \
- Fl_Hold_Browser.html \
- Fl_Image.html \
- Fl_Input_.html \
- Fl_Input.html \
- Fl_Int_Input.html \
- Fl_JPEG_Image.html \
- Fl_Light_Button.html \
- Fl_Menu_Bar.html \
- Fl_Menu_Button.html \
- Fl_Menu_.html \
- Fl_Menu_Item.html \
- Fl_Menu_Window.html \
- Fl_Multi_Browser.html \
- Fl_Multiline_Input.html \
- Fl_Multiline_Output.html \
- Fl_Output.html \
- Fl_Overlay_Window.html \
- Fl_Pack.html \
- Fl_Pixmap.html \
- Fl_PNG_Image.html \
- Fl_PNM_Image.html \
- Fl_Positioner.html \
- Fl_Repeat_Button.html \
- Fl_Return_Button.html \
- Fl_RGB_Image.html \
- Fl_Roller.html \
- Fl_Round_Button.html \
- Fl_Scrollbar.html \
- Fl_Scroll.html \
- Fl_Secret_Input.html \
- Fl_Select_Browser.html \
- Fl_Shared_Image.html \
- Fl_Single_Window.html \
- Fl_Slider.html \
- Fl_Tabs.html \
- Fl_Text_Buffer.html \
- Fl_Text_Display.html \
- Fl_Text_Editor.html \
- Fl_Tiled_Image.html \
- Fl_Tile.html \
- Fl_Timer.html \
- Fl_Tooltip.html \
- fluid.html \
- Fl_Valuator.html \
- Fl_Value_Input.html \
- Fl_Value_Output.html \
- Fl_Value_Slider.html \
- Fl_Widget.html \
- Fl_Window.html \
- Fl_Wizard.html \
- Fl_XBM_Image.html \
- Fl_XPM_Image.html \
- forms.html \
- functions.html \
- glut.html \
- intro.html \
- license.html \
- migration.html \
- opengl.html \
- osissues.html \
- preface.html \
- subclassing.html \
- widgets.html
+ preface.html \
+ intro.html \
+ basics.html \
+ common.html \
+ editor.html \
+ drawing.html \
+ events.html \
+ subclassing.html \
+ opengl.html \
+ fluid.html \
+ widgets.html \
+ Fl.html \
+ Fl_Adjuster.html \
+ Fl_Bitmap.html \
+ Fl_BMP_Image.html \
+ Fl_Box.html \
+ Fl_Browser_.html \
+ Fl_Browser.html \
+ Fl_Button.html \
+ Fl_Chart.html \
+ Fl_Check_Button.html \
+ Fl_Choice.html \
+ Fl_Clock.html \
+ Fl_Color_Chooser.html \
+ Fl_Counter.html \
+ Fl_Dial.html \
+ Fl_Double_Window.html \
+ Fl_End.html \
+ Fl_File_Browser.html \
+ Fl_File_Chooser.html \
+ Fl_File_Icon.html \
+ Fl_Float_Input.html \
+ Fl_Free.html \
+ Fl_GIF_Image.html \
+ Fl_Gl_Window.html \
+ Fl_Group.html \
+ Fl_Help_Dialog.html \
+ Fl_Help_View.html \
+ Fl_Hold_Browser.html \
+ Fl_Image.html \
+ Fl_Input.html \
+ Fl_Input_.html \
+ Fl_Int_Input.html \
+ Fl_JPEG_Image.html \
+ Fl_Light_Button.html \
+ Fl_Menu_.html \
+ Fl_Menu_Bar.html \
+ Fl_Menu_Button.html \
+ Fl_Menu_Item.html \
+ Fl_Menu_Window.html \
+ Fl_Multi_Browser.html \
+ Fl_Multiline_Input.html \
+ Fl_Multiline_Output.html \
+ Fl_Output.html \
+ Fl_Overlay_Window.html \
+ Fl_Pack.html \
+ Fl_Pixmap.html \
+ Fl_PNG_Image.html \
+ Fl_PNM_Image.html \
+ Fl_Positioner.html \
+ Fl_Progress.html \
+ Fl_Repeat_Button.html \
+ Fl_RGB_Image.html \
+ Fl_Return_Button.html \
+ Fl_Roller.html \
+ Fl_Round_Button.html \
+ Fl_Scroll.html \
+ Fl_Scrollbar.html \
+ Fl_Secret_Input.html \
+ Fl_Select_Browser.html \
+ Fl_Single_Window.html \
+ Fl_Slider.html \
+ Fl_Tabs.html \
+ Fl_Text_Buffer.html \
+ Fl_Text_Display.html \
+ Fl_Text_Editor.html \
+ Fl_Tile.html \
+ Fl_Tiled_Image.html \
+ Fl_Timer.html \
+ Fl_Tooltip.html \
+ Fl_Valuator.html \
+ Fl_Value_Input.html \
+ Fl_Value_Output.html \
+ Fl_Value_Slider.html \
+ Fl_Widget.html \
+ Fl_Window.html \
+ Fl_Wizard.html \
+ Fl_XBM_Image.html \
+ Fl_XPM_Image.html \
+ functions.html \
+ enumerations.html \
+ glut.html \
+ forms.html \
+ osissues.html \
+ migration.html \
+ license.html
+
+IMAGEFILES = \
+ adjuster1.gif \
+ boxtypes.gif \
+ buttons.gif \
+ charts.gif \
+ choice.gif \
+ clock.gif \
+ counter.gif \
+ cubeview.gif \
+ dial.gif \
+ editor.gif \
+ editor-replace.gif \
+ filechooser.gif \
+ fl_alert.gif \
+ fl_ask.gif \
+ Fl_Check_Button.gif \
+ fl_choice.gif \
+ fl_color_chooser.jpg \
+ FL.gif \
+ Fl_Help_Dialog.gif \
+ fl_input.gif \
+ Fl_Light_Button.gif \
+ fl_message.gif \
+ fl_password.gif \
+ Fl_Return_Button.gif \
+ Fl_Roller.gif \
+ Fl_Round_Button.gif \
+ Fl_Scroll.gif \
+ fl_show_colormap.gif \
+ Fl_Tile.gif \
+ fluid1.gif \
+ fluid2.gif \
+ fluid3-cxx.gif \
+ fluid3-gui.gif \
+ fluid3-style.gif \
+ fluid4.gif \
+ fluid-catgets.gif \
+ fluid-gettext.gif \
+ fluid-org.gif \
+ fluid_prefs.gif \
+ fluid_widget_cxx.gif \
+ fluid_widget_gui.gif \
+ fluid_widget_style.gif \
+ Fl_Value_Input.gif \
+ Fl_Value_Output.gif \
+ hello.C.gif \
+ menubar.gif \
+ menu_button.gif \
+ menu.gif \
+ positioner.gif \
+ resizebox1.gif \
+ resizebox2.gif \
+ round_clock.gif \
+ scrollbar.gif \
+ slider.gif \
+ symbols.gif \
+ tabs.gif \
+ text.gif \
+ valuators.gif \
+ value_slider.gif
MANPAGES = fltk.$(CAT3EXT) fltk-config.$(CAT1EXT) fluid.$(CAT1EXT)
@@ -192,22 +253,22 @@ uninstall:
# Base html files are now the readable ones, so this target is not make by
# default...
-fltk.d/index.html: $(HTMLFILES)
+fltk.d/index.html: $(HTMLFILES) $(IMAGEFILES)
echo "Generating HTML documentation..."
-mkdir fltk.d
-rm -f fltk.d/*
$(HTMLDOC) --verbose --batch fltk.book -d fltk.d -t html
-fltk.ps: $(HTMLFILES)
+fltk.ps: $(HTMLFILES) $(IMAGEFILES)
echo "Generating PostScript documentation..."
rm -f fltk.ps
$(HTMLDOC) --verbose --batch fltk.book $(MEDIA) -f fltk.ps
-fltk.pdf: $(HTMLFILES)
+fltk.pdf: $(HTMLFILES) $(IMAGEFILES)
echo "Generating PDF documentation..."
rm -f fltk.pdf
$(HTMLDOC) --verbose --batch fltk.book $(MEDIA) -f fltk.pdf
#
-# End of "$Id: Makefile,v 1.9.2.10.2.13 2002/04/20 21:07:18 easysw Exp $".
+# End of "$Id: Makefile,v 1.9.2.10.2.14 2002/04/28 16:41:16 easysw Exp $".
#
diff --git a/makefiles/config.mingw b/makefiles/config.mingw
index 100951d19..203799eeb 100644
--- a/makefiles/config.mingw
+++ b/makefiles/config.mingw
@@ -1,5 +1,5 @@
/*
- * "$Id: config.mingw,v 1.1.2.3.2.3 2002/04/24 18:29:05 easysw Exp $"
+ * "$Id: config.mingw,v 1.1.2.3.2.4 2002/04/28 16:41:16 easysw Exp $"
*
* Configuration file for the Fast Light Tool Kit (FLTK).
*
@@ -24,9 +24,10 @@
*/
/*
- * Where to find the documentation files...
+ * Where to find files...
*/
+#define FLTK_DATADIR "C:/FLTK"
#define FLTK_DOCDIR "C:/FLTK/DOC"
/*
@@ -189,5 +190,5 @@
/*
- * End of "$Id: config.mingw,v 1.1.2.3.2.3 2002/04/24 18:29:05 easysw Exp $".
+ * End of "$Id: config.mingw,v 1.1.2.3.2.4 2002/04/28 16:41:16 easysw Exp $".
*/
diff --git a/makefiles/config.os2x b/makefiles/config.os2x
index aa3574d62..cd89c9b38 100644
--- a/makefiles/config.os2x
+++ b/makefiles/config.os2x
@@ -1,6 +1,6 @@
/* config.h. Generated automatically by configure. */
/*
- * "$Id: config.os2x,v 1.1.2.4.2.5 2002/04/24 18:29:05 easysw Exp $"
+ * "$Id: config.os2x,v 1.1.2.4.2.6 2002/04/28 16:41:16 easysw Exp $"
*
* Configuration file for the Fast Light Tool Kit (FLTK).
* @configure_input@
@@ -26,9 +26,10 @@
*/
/*
- * Where to find the documentation files...
+ * Where to find files...
*/
+#define FLTK_DATADIR "/usr/local/share/fltk"
#define FLTK_DOCDIR "/usr/local/share/doc/fltk"
/*
@@ -220,5 +221,5 @@
/*
- * End of "$Id: config.os2x,v 1.1.2.4.2.5 2002/04/24 18:29:05 easysw Exp $".
+ * End of "$Id: config.os2x,v 1.1.2.4.2.6 2002/04/28 16:41:16 easysw Exp $".
*/
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
new file mode 100644
index 000000000..526222d85
--- /dev/null
+++ b/src/Fl_Preferences.cxx
@@ -0,0 +1,828 @@
+//
+// "$Id: Fl_Preferences.cxx,v 1.1.2.1 2002/04/28 16:41:16 easysw Exp $"
+//
+// Preferences file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2002 by Matthias Melcher.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org".
+//
+
+
+#include <FL/Fl.H>
+#include <FL/Fl_Preferences.H>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "flstring.h"
+
+#include <sys/stat.h>
+
+
+char Fl_Preferences::nameBuffer[];
+
+
+/**
+ * create the initial preferences base
+ * i root: machine or user preferences
+ * i vendor: unique identification of author or vendor of application
+ * Must be a valid directory name.
+ * i application: vendor unique application name, i.e. "PreferencesTest"
+ * multiple preferences files can be created per application.
+ * Must be a valid file name.
+ * example: Fl_Preferences base( Fl_Preferences::USER, "matthiasm.com", "test01");
+ */
+Fl_Preferences::Fl_Preferences( enum Root root, const char *vendor, const char *application )
+{
+ node = new Node( "." );
+ rootNode = new RootNode( this, root, vendor, application );
+}
+
+
+/**
+ * create a Preferences node in relation to a parent node for reading and writing
+ * i parent: base name for group
+ * i group: group name (can contain '/' seperated group names)
+ * example: Fl_Preferences colors( base, "setup/colors" );
+ */
+Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *key )
+{
+ rootNode = 0;
+ node = parent.node->addChild( key );
+}
+
+
+/**
+ * create a Preferences node in relation to a parent node for reading and writing
+ * i parent: base name for group
+ * i group: group name (can contain '/' seperated group names)
+ * example: Fl_Preferences colors( base, "setup/colors" );
+ */
+Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *key )
+{
+ rootNode = 0;
+ node = parent->node->addChild( key );
+}
+
+
+/**
+ * destroy individual keys
+ * - destroying the base preferences will flush changes to the prefs file
+ * - after destroying the base, none of the depending preferences must be read or written
+ */
+Fl_Preferences::~Fl_Preferences()
+{
+ delete rootNode;
+ // DO NOT delete nodes! The root node will do that after writing the preferences
+}
+
+
+/**
+ * return the number of groups that are contained within a group
+ * example: int n = base.groups();
+ */
+int Fl_Preferences::groups()
+{
+ return node->nChildren();
+}
+
+
+/**
+ * return the group name of the n'th group
+ * - there is no guaranteed order of group names
+ * - the index must be within the range given by groups()
+ * example: printf( "Group(%d)='%s'\n", ix, base.group(ix) );
+ */
+const char *Fl_Preferences::group( int ix )
+{
+ return node->child( ix );
+}
+
+
+/**
+ * return 1, if a group with this name exists
+ * example: if ( base.groupExists( "setup/colors" ) ) ...
+ */
+int Fl_Preferences::groupExists( const char *key )
+{
+ return node->search( key ) ? 1 : 0 ;
+}
+
+
+/**
+ * delete a group
+ * example: setup.deleteGroup( "colors/buttons" );
+ */
+int Fl_Preferences::deleteGroup( const char *key )
+{
+ Node *nd = node->search( key );
+ if ( nd ) return nd->remove();
+ return 0;
+}
+
+
+/**
+ * return the number of entries (name/value) pairs for a group
+ * example: int n = buttonColor.entries();
+ */
+int Fl_Preferences::entries()
+{
+ return node->nEntry;
+}
+
+
+/**
+ * return the name of an entry
+ * - there is no guaranteed order of entry names
+ * - the index must be within the range given by entries()
+ * example: printf( "Entry(%d)='%s'\n", ix, buttonColor.entry(ix) );
+ */
+const char *Fl_Preferences::entry( int ix )
+{
+ return node->entry[ix].name;
+}
+
+
+/**
+ * return 1, if a group with this name exists
+ * example: if ( buttonColor.entryExists( "red" ) ) ...
+ */
+int Fl_Preferences::entryExists( const char *key )
+{
+ return node->getEntry( key ) ? 1 : 0 ;
+}
+
+
+/**
+ * remove a single entry (name/value pair)
+ * example: buttonColor.deleteEntry( "red" );
+ */
+int Fl_Preferences::deleteEntry( const char *key )
+{
+ return node->deleteEntry( key );
+}
+
+
+
+/**
+ * read an entry from the group
+ * - a default value must be supplied
+ * - the return value indicates, if the value was not available and the default was used (0)
+ * example: button.get( "visible", b.visible, 1 );
+ */
+int Fl_Preferences::get( const char *key, int &value, int defaultValue )
+{
+ const char *v = node->get( key );
+ value = v ? atoi( v ) : defaultValue;
+ return 0;
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+int Fl_Preferences::set( const char *key, int value )
+{
+ sprintf( nameBuffer, "%d", value );
+ node->set( key, nameBuffer );
+ return 1;
+}
+
+
+/**
+ * read an entry from the group
+ */
+int Fl_Preferences::get( const char *key, float &value, float defaultValue )
+{
+ const char *v = node->get( key );
+ value = v ? (float)atof( v ) : defaultValue;
+ return 0;
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+int Fl_Preferences::set( const char *key, float value )
+{
+ sprintf( nameBuffer, "%g", value );
+ node->set( key, nameBuffer );
+ return 1;
+}
+
+
+/**
+ * read an entry from the group
+ */
+int Fl_Preferences::get( const char *key, double &value, double defaultValue )
+{
+ const char *v = node->get( key );
+ value = v ? atof( v ) : defaultValue;
+ return 0;
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+int Fl_Preferences::set( const char *key, double value )
+{
+ sprintf( nameBuffer, "%g", value );
+ node->set( key, nameBuffer );
+ return 1;
+}
+
+
+/**
+ * read a text entry from the group
+ * - the maximum size for text plus entry name is 2046 bytes plus the trailling 0
+ * - the text must not contain special characters
+ * the text will be movet into the given text buffer
+ */
+int Fl_Preferences::get( const char *key, char *text, const char *defaultValue, int maxSize )
+{
+ maxSize --;
+ const char *v = node->get( key );
+ if ( !v ) v = defaultValue;
+ strncpy( text, v, maxSize );
+ if ( (int)strlen(v) >= maxSize ) text[maxSize] = 0;
+ return 0;
+}
+
+
+/**
+ * read a text entry from the group
+ * - the maximum size for text plus entry name is 2046 bytes plus the trailling 0
+ * - the text must not contain special characters (no \n or \r, "quotes" are OK)
+ * 'text' will be changed to point to a new text buffer
+ * the text buffer must be deleted with 'free(text)' by the user.
+ */
+int Fl_Preferences::get( const char *key, char *&text, const char *defaultValue )
+{
+ const char *v = node->get( key );
+ if ( !v ) v = defaultValue;
+ text = strdup( v );
+ return 0;
+}
+
+
+/**
+ * set an entry (name/value pair)
+ */
+int Fl_Preferences::set( const char *key, const char *text )
+{
+ node->set( key, text );
+ return 1;
+}
+
+
+/**
+ * return the size of the value part of an entry
+ */
+int Fl_Preferences::size( const char *key )
+{
+ const char *v = node->get( key );
+ return v ? strlen( v ) : 0 ;
+}
+
+/**
+ * creates a path that is related to the preferences file
+ * and that is usable for application data beyond what is covered
+ * by Fl_Preferences.
+ * - 'getUserdataPath' actually creates the directory
+ * - 'path' must be large enough to receive a complete file path
+ * example:
+ * Fl_Preferences prefs( USER, "matthiasm.com", "test" );
+ * char path[MAX_PATH];
+ * prefs.getUserdataPath( path );
+ * sample returns:
+ * Win32: c:/Documents and Settings/matt/Application Data/matthiasm.com/test/
+ * prefs: c:/Documents and Settings/matt/Application Data/matthiasm.com/test.prefs
+ */
+int Fl_Preferences::getUserdataPath( char *path )
+{
+ if ( rootNode )
+ return rootNode->getPath( path );
+ return 0;
+}
+
+/**
+ * write all preferences to disk
+ * - this function works only with the base preference group
+ * - this function is rarely used as deleting the base preferences does that automatically
+ */
+void Fl_Preferences::flush()
+{
+ if ( rootNode && node->dirty() )
+ rootNode->write();
+}
+
+/*
+int Fl_Preferences::export( const char *filename, enum Type type )
+{
+//#pragma message ( "TODO: implement Fl_Preferences::export(filepath)" )
+ switch ( type )
+ {
+ case win32:
+ break;
+ case macos:
+ break;
+ case fltk:
+ break;
+ }
+ return 0;
+}
+
+
+int Fl_Preferences::import( const char *filename )
+{
+//#pragma message ( "TODO: implement Fl_Preferences::import(filepath)" )
+ return 0;
+}
+*/
+
+//-----------------------------------------------------------------------------
+// internal methods, do not change or use as they will change without notice
+//
+
+int Fl_Preferences::Node::lastEntrySet = -1;
+
+static int makePath( const char *path )
+{
+ struct stat stats;
+ int ret = stat( path, &stats );
+ if ( ret )
+ {
+ char *s = strrchr( path, '/' );
+ if ( !s ) return 0;
+ int len = s-path;
+ char *p = (char*)malloc( len+1 );
+ memcpy( p, path, len );
+ p[len] = 0;
+ makePath( p );
+ free( p );
+ return ( mkdir( path, 0777 ) == 0 );
+ }
+ return 1;
+}
+
+static void makePathForFile( const char *path )
+{
+ char *s = strrchr( path, '/' );
+ if ( !s ) return;
+ int len = s-path;
+ char *p = (char*)malloc( len+1 );
+ memcpy( p, path, len );
+ p[len] = 0;
+ makePath( p );
+ free( p );
+}
+
+// create the root node
+// - construct the name of the file that will hold our preferences
+Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, enum Root root, const char *vendor, const char *application )
+{
+ const char *home; // Home directory
+ char filename[1024]; // Filename
+#ifdef WIN32
+ HKEY key; // Registry key
+ DWORD size; // Size of string
+ char data[1024]; // Home (profile) directory
+#endif // WIN32
+
+ // Find the home directory...
+#ifdef WIN32
+ // Open the registry...
+ if (RegOpenKeyEx(HKEY_CURRENT_USER,
+ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0,
+ KEY_READ, &key)) {
+ data[0] = '\0';
+ } else {
+ // Grab the current user's AppData directory...
+ size = sizeof(data);
+ if (RegQueryValueEx(key, "AppData", NULL, NULL, (unsigned char *)data, &size))
+ data[0] = '\0';
+
+ RegCloseKey(key);
+ }
+
+ if (data[0])
+ home = data;
+ else
+ home = NULL;
+#else
+ home = getenv("HOME");
+#endif // WIN32
+
+ // Choose the appropriate path...
+ if (root == SYSTEM || !home) {
+ // Locate the preferences in the system data directory...
+ snprintf(filename, sizeof(filename),
+ FLTK_DATADIR "/%s/%s.prefs", vendor, application);
+ } else {
+ // Locate the preferences in the user data directory...
+ snprintf(filename, sizeof(filename),
+ "%s/.fltk/%s/%s.prefs", home, vendor, application);
+ }
+
+ makePathForFile( filename );
+ prefs_ = prefs;
+ filename_ = strdup( filename );
+ vendor_ = strdup( vendor );
+ application_ = strdup( application );
+ read();
+}
+
+// destroy the root node and all depending nodes
+Fl_Preferences::RootNode::~RootNode()
+{
+ if ( prefs_->node->dirty() )
+ write();
+ if ( filename_ )
+ free( filename_ );
+ delete vendor_;
+ delete application_;
+ delete prefs_->node;
+}
+
+// read a preferences file and construct the group tree and with all entry leafs
+int Fl_Preferences::RootNode::read()
+{
+ char buf[1024];
+ FILE *f = fopen( filename_, "rb" );
+ if ( !f ) return 0;
+ fgets( buf, 1024, f );
+ fgets( buf, 1024, f );
+ fgets( buf, 1024, f );
+ Node *nd = prefs_->node;
+ for (;;)
+ {
+ if ( !fgets( buf, 1024, f ) ) break; // EOF or Error
+ if ( buf[0]=='[' ) // read a new group
+ {
+ int end = strcspn( buf+1, "]\n\r" );
+ buf[ end+1 ] = 0;
+ nd = prefs_->node->find( buf+1 );
+ }
+ else if ( buf[0]=='+' ) //
+ { // value of previous name/value pair spans multiple lines
+ int end = strcspn( buf+1, "\n\r" );
+ if ( end != 0 ) // if entry is not empty
+ {
+ buf[ end+1 ] = 0;
+ nd->add( buf+1 );
+ }
+ }
+ else // read a name/value pair
+ {
+ int end = strcspn( buf, "\n\r" );
+ if ( end != 0 ) // if entry is not empty
+ {
+ buf[ end ] = 0;
+ nd->set( buf );
+ }
+ }
+ }
+ fclose( f );
+ return 0;
+}
+
+// write the group tree and all entry leafs
+int Fl_Preferences::RootNode::write()
+{
+ FILE *f = fopen( filename_, "wb" );
+ if ( !f ) return 1;
+ fprintf( f, "; FLTK preferences file format 1.0\n" );
+ fprintf( f, "; vendor: %s\n", vendor_ );
+ fprintf( f, "; application: %s\n", application_ );
+ prefs_->node->write( f );
+ fclose( f );
+ return 0;
+}
+
+// get the path to the preferences directory
+int Fl_Preferences::RootNode::getPath( char *path )
+{
+ char *s;
+
+ strcpy( path, filename_ );
+ for ( s = path; *s; s++ ) if ( *s == '\\' ) *s = '/';
+ s = strrchr( path, '.' );
+ if ( !s ) return 0;
+ *s = 0;
+ int ret = makePath( path );
+ strcpy( s, "/" );
+ return ret;
+}
+
+// create a node that represents a group
+// - path must be a single word, prferable alnum(), dot and underscore only. Space is ok.
+Fl_Preferences::Node::Node( const char *path )
+{
+ if ( path ) path_ = strdup( path ); else path_ = 0;
+ child_ = 0; next_ = 0; parent_ = 0;
+ entry = 0;
+ nEntry = NEntry = 0;
+ dirty_ = 0;
+}
+
+// delete this and all depending nodes
+Fl_Preferences::Node::~Node()
+{
+ Node *nx;
+ for ( Node *nd = child_; nd; nd = nx )
+ {
+ nx = nd->next_;
+ delete nd;
+ }
+ for ( int i = 0; i < nEntry; i++ )
+ {
+ delete entry[i].name;
+ delete entry[i].value;
+ }
+ delete[] entry;
+ if ( path_ ) free( path_ );
+}
+
+// recursively check if any entry is dirty (was changed after loading a fresh prefs file)
+int Fl_Preferences::Node::dirty()
+{
+ if ( dirty_ ) return 1;
+ if ( next_ && next_->dirty() ) return 1;
+ if ( child_ && child_->dirty() ) return 1;
+ return 0;
+}
+
+// write this node (recursively from the last neighbor back to this)
+// write all entries
+// write all children
+int Fl_Preferences::Node::write( FILE *f )
+{
+ if ( next_ ) next_->write( f );
+ fprintf( f, "\n[%s]\n\n", path_ );
+ for ( int i = 0; i < nEntry; i++ )
+ {
+ char *src = entry[i].value;
+ if ( src )
+ { // hack it into smaller pieces if needed
+ fprintf( f, "%s:", entry[i].name );
+ int cnt;
+ for ( cnt = 0; cnt < 60; cnt++ )
+ if ( src[cnt]==0 ) break;
+ fwrite( src, cnt, 1, f );
+ fprintf( f, "\n" );
+ src += cnt;
+ for (;*src;)
+ {
+ for ( cnt = 0; cnt < 80; cnt++ )
+ if ( src[cnt]==0 ) break;
+ fputc( '+', f );
+ fwrite( src, cnt, 1, f );
+ fputc( '\n', f );
+ src += cnt;
+ }
+ }
+ else
+ fprintf( f, "%s\n", entry[i].name );
+ }
+ if ( child_ ) child_->write( f );
+ dirty_ = 0;
+ return 0;
+}
+
+// set the parent node and create the full path
+void Fl_Preferences::Node::setParent( Node *pn )
+{
+ parent_ = pn;
+ next_ = pn->child_;
+ pn->child_ = this;
+ sprintf( nameBuffer, "%s/%s", pn->path_, path_ );
+ free( path_ );
+ path_ = strdup( nameBuffer );
+}
+
+// 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 )
+{
+ sprintf( nameBuffer, "%s/%s", path_, path );
+ char *name = strdup( nameBuffer );
+ Node *nd = find( nameBuffer );
+ free( name );
+ return nd;
+}
+
+// create and set, or change an entry within this node
+void Fl_Preferences::Node::set( const char *name, const char *value )
+{
+ for ( int i=0; i<nEntry; i++ )
+ {
+ if ( strcmp( name, entry[i].name ) == 0 )
+ {
+ if ( !value ) return; // annotation
+ if ( strcmp( value, entry[i].value ) != 0 )
+ {
+ delete entry[i].value;
+ entry[i].value = strdup( value );
+ dirty_ = 1;
+ }
+ lastEntrySet = i;
+ return;
+ }
+ }
+ if ( NEntry==nEntry )
+ {
+ NEntry = NEntry ? NEntry*2 : 10;
+ entry = (Entry*)realloc( entry, NEntry * sizeof(Entry) );
+ }
+ entry[ nEntry ].name = strdup( name );
+ entry[ nEntry ].value = value?strdup( value ):0;
+ lastEntrySet = nEntry;
+ nEntry++;
+ dirty_ = 1;
+}
+
+// create or set a value (or annotation) from a single line in the file buffer
+void Fl_Preferences::Node::set( const char *line )
+{
+ int dirty = dirty_; // hmm. If we assume that we always read yhis file in the beginning, we can handle the dirty flag 'quick and dirty'
+ if ( line[0]==';' || line[0]==0 || line[0]=='#' )
+ {
+ set( line, 0 );
+ }
+ else
+ {
+ char *c = strchr( line, ':' );
+ if ( c )
+ {
+ strncpy( nameBuffer, line, c-line );
+ nameBuffer[ c-line ] = 0;
+ set( nameBuffer, c+1 );
+ }
+ else
+ set( line, "" );
+ }
+ dirty_ = dirty;
+}
+
+// add more data to an existing entry
+void Fl_Preferences::Node::add( const char *line )
+{
+ if ( lastEntrySet<0 || lastEntrySet>=nEntry ) return;
+ char *&dst = entry[ lastEntrySet ].value;
+ int a = strlen( dst );
+ int b = strlen( line );
+ dst = (char*)realloc( dst, a+b+1 );
+ memcpy( dst+a, line, b+1 );
+ dirty_ = 1;
+}
+
+// get the value for a name, returns 0 if no such name
+const char *Fl_Preferences::Node::get( const char *name )
+{
+ int i = getEntry( name );
+ return i>=0 ? entry[i].value : 0 ;
+}
+
+// find the index of an entry, returns -1 if no such entry
+int Fl_Preferences::Node::getEntry( const char *name )
+{
+ for ( int i=0; i<nEntry; i++ )
+ {
+ if ( strcmp( name, entry[i].name ) == 0 )
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+// remove one entry form this group
+int Fl_Preferences::Node::deleteEntry( const char *name )
+{
+ int ix = getEntry( name );
+ if ( ix == -1 ) return 0;
+ memmove( entry+ix, entry+ix+1, (nEntry-ix-1) * sizeof(Entry) );
+ nEntry--;
+ return 1;
+}
+
+// find a group somewhere in the tree starting here
+// - this method will always return a valid node (except for memory allocation problems)
+// - if the node was not found, 'find' will create the required branch
+Fl_Preferences::Node *Fl_Preferences::Node::find( const char *path )
+{
+ int len = strlen( path_ );
+ if ( strncmp( path, path_, len ) == 0 )
+ {
+ if ( path[ len ] == 0 )
+ return this;
+ if ( path[ len ] == '/' )
+ {
+ Node *nd;
+ for ( nd = child_; nd; nd = nd->next_ )
+ {
+ Node *nn = nd->find( path );
+ if ( nn ) return nn;
+ }
+ const char *s = path+len+1;
+ const char *e = strchr( s, '/' );
+ if ( e ) { strncpy( nameBuffer, s, e-s ); nameBuffer[ e-s ] = 0; } else strcpy( nameBuffer, s );
+ nd = new Node( nameBuffer );
+ nd->setParent( this );
+ return nd->find( path );
+ }
+ }
+ return 0;
+}
+
+// find a group somewhere in the tree starting here
+// - if the node does not exist, 'search' returns NULL
+Fl_Preferences::Node *Fl_Preferences::Node::search( const char *path )
+{
+ int len = strlen( path_ );
+ if ( strncmp( path, path_, len ) == 0 )
+ {
+ if ( path[ len ] == 0 )
+ return this;
+ if ( path[ len ] == '/' )
+ {
+ Node *nd;
+
+ for ( nd = child_; nd; nd = nd->next_ )
+ {
+ Node *nn = nd->find( path );
+ if ( nn ) return nn;
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+
+// return the number of child nodes (groups)
+int Fl_Preferences::Node::nChildren()
+{
+ int cnt = 0;
+ for ( Node *nd = child_; nd; nd = nd->next_ )
+ cnt++;
+ return cnt;
+}
+
+// return the n'th child node
+const char *Fl_Preferences::Node::child( int ix )
+{
+ Node *nd;
+ for ( nd = child_; nd; nd = nd->next_ )
+ {
+ if ( !ix-- ) break;
+ }
+ if ( nd && nd->path_ )
+ {
+ char *r = strrchr( nd->path_, '/' );
+ return r ? r+1 : nd->path_ ;
+ }
+ return 0L ;
+}
+
+// remove myself from the list and delete me (and all children)
+int Fl_Preferences::Node::remove()
+{
+ Node *nd, *np;
+ if ( parent_ )
+ {
+ nd = parent_->child_; np = 0L;
+ for ( ; nd; nd = nd->next_ )
+ {
+ if ( nd == this )
+ {
+ if ( np )
+ np->next_ = nd->next_;
+ else
+ parent_->child_ = nd->next_;
+ break;
+ }
+ }
+ }
+ delete this;
+ return ( nd != 0 );
+}
+
+
+//
+// End of "$Id: Fl_Preferences.cxx,v 1.1.2.1 2002/04/28 16:41:16 easysw Exp $".
+//
diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx
index 2c2f417c8..355850ac1 100644
--- a/src/Fl_Window.cxx
+++ b/src/Fl_Window.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Window.cxx,v 1.6.2.3.2.3 2002/01/01 15:11:31 easysw Exp $"
+// "$Id: Fl_Window.cxx,v 1.6.2.3.2.4 2002/04/28 16:41:16 easysw Exp $"
//
// Window widget class for the Fast Light Tool Kit (FLTK).
//
@@ -84,6 +84,7 @@ int Fl_Window::y_root() const {
void Fl_Window::draw() {
int savex = x(); x(0);
int savey = y(); y(0);
+ Fl_Widget::label(0);
Fl_Group::draw();
y(savey);
x(savex);
@@ -108,5 +109,5 @@ void Fl_Window::default_callback(Fl_Window* window, void* v) {
}
//
-// End of "$Id: Fl_Window.cxx,v 1.6.2.3.2.3 2002/01/01 15:11:31 easysw Exp $".
+// End of "$Id: Fl_Window.cxx,v 1.6.2.3.2.4 2002/04/28 16:41:16 easysw Exp $".
//
diff --git a/src/Makefile b/src/Makefile
index b8c4f0a6c..e903a563d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile,v 1.18.2.14.2.39 2002/04/11 11:52:42 easysw Exp $"
+# "$Id: Makefile,v 1.18.2.14.2.40 2002/04/28 16:41:16 easysw Exp $"
#
# Library makefile for the Fast Light Tool Kit (FLTK).
#
@@ -70,6 +70,7 @@ CPPFILES = \
Fl_PNG_Image.cxx \
Fl_PNM_Image.cxx \
Fl_Positioner.cxx \
+ Fl_Preferences.cxx \
Fl_Progress.cxx \
Fl_Repeat_Button.cxx \
Fl_Return_Button.cxx \
@@ -427,5 +428,5 @@ uninstall:
#
-# End of "$Id: Makefile,v 1.18.2.14.2.39 2002/04/11 11:52:42 easysw Exp $".
+# End of "$Id: Makefile,v 1.18.2.14.2.40 2002/04/28 16:41:16 easysw Exp $".
#
diff --git a/visualc/config.h b/visualc/config.h
index ba54bef4f..841184ab9 100644
--- a/visualc/config.h
+++ b/visualc/config.h
@@ -1,5 +1,5 @@
/*
- * "$Id: config.h,v 1.5.2.5.2.6 2002/04/24 18:29:06 easysw Exp $"
+ * "$Id: config.h,v 1.5.2.5.2.7 2002/04/28 16:41:17 easysw Exp $"
*
* Configuration file for the Fast Light Tool Kit (FLTK) for Visual C++.
*
@@ -24,9 +24,10 @@
*/
/*
- * Where to find the documentation files...
+ * Where to find files...
*/
+#define FLTK_DATADIR "C:/FLTK"
#define FLTK_DOCDIR "C:/FLTK/DOC"
/*
@@ -182,5 +183,5 @@
/*
- * End of "$Id: config.h,v 1.5.2.5.2.6 2002/04/24 18:29:06 easysw Exp $".
+ * End of "$Id: config.h,v 1.5.2.5.2.7 2002/04/28 16:41:17 easysw Exp $".
*/
diff --git a/visualc/fltk.lib.dsp b/visualc/fltk.lib.dsp
index ffff2c47c..fcb097a1d 100644
--- a/visualc/fltk.lib.dsp
+++ b/visualc/fltk.lib.dsp
@@ -601,5 +601,9 @@ SOURCE=..\src\scandir.c
SOURCE=..\src\vsnprintf.c
# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Preferences.cxx
+# End Source File
# End Target
# End Project
diff --git a/visualc/fltkdll.dsp b/visualc/fltkdll.dsp
index db7030b0a..8b231bfa7 100644
--- a/visualc/fltkdll.dsp
+++ b/visualc/fltkdll.dsp
@@ -2407,5 +2407,10 @@ DEP_CPP_VSNPR=\
".\config.h"\
# End Source File
+# Begin Source File
+
+SOURCE=..\src\Fl_Preferences.cxx
+
+# End Source File
# End Target
# End Project