mirror of https://github.com/fltk/fltk
311 lines
11 KiB
C++
311 lines
11 KiB
C++
//
|
|
// Preferences implementation for the Fast Light Tool Kit (FLTK).
|
|
//
|
|
// Copyright 2002-2010 by Matthias Melcher.
|
|
//
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
// file is missing or damaged, see the license at:
|
|
//
|
|
// https://www.fltk.org/COPYING.php
|
|
//
|
|
// Please see the following page on how to report bugs and issues:
|
|
//
|
|
// https://www.fltk.org/bugs.php
|
|
//
|
|
|
|
/* \file
|
|
Fl_Preferences class . */
|
|
|
|
#ifndef Fl_Preferences_H
|
|
# define Fl_Preferences_H
|
|
|
|
# include <stdio.h>
|
|
# include "Fl_Export.H"
|
|
|
|
/**
|
|
\brief Fl_Preferences provides methods to store user
|
|
settings between application starts.
|
|
|
|
It is similar to the
|
|
Registry on Windows and Preferences on MacOS, and provides a
|
|
simple configuration mechanism for UNIX.
|
|
|
|
Fl_Preferences uses a hierarchy to store data. It
|
|
bundles similar data into groups and manages entries in these
|
|
groups as name/value pairs.
|
|
|
|
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.
|
|
|
|
Entries can be of any length. However, the size of each
|
|
preferences file should be kept small for performance
|
|
reasons. One application can have multiple preferences files.
|
|
Extensive binary data however should be stored in separate
|
|
files: see \a Fl_Preferences::getUserdataPath() .
|
|
|
|
\note Starting with FLTK 1.3, preference databases are expected to
|
|
be in UTF-8 encoding. Previous databases were stored in the
|
|
current character set or code page which renders them incompatible
|
|
for text entries using international characters.
|
|
|
|
\note Starting with FLTK 1.4, searching a valid path to store
|
|
the preferences files has changed slightly. Please see
|
|
Fl_Preferences::Fl_Preferences(Root, const char*, const char*)
|
|
for details.
|
|
*/
|
|
class FL_EXPORT Fl_Preferences {
|
|
|
|
public:
|
|
/**
|
|
Define the scope of the preferences.
|
|
*/
|
|
enum Root {
|
|
SYSTEM = 0, ///< Preferences are used system-wide
|
|
USER, ///< Preferences apply only to the current user
|
|
ROOT_MASK = 0xFF, ///< masks for the values above
|
|
CORE = 0x100, ///< OR'd by FLTK to read and write core library preferences and options
|
|
CORE_SYSTEM = CORE|SYSTEM,
|
|
CORE_USER = CORE|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
|
|
database remains open.
|
|
*/
|
|
typedef void *ID;
|
|
|
|
static const char *newUUID();
|
|
|
|
/** Set this, if no call to Fl_Preferences shall access the file sytem
|
|
@see Fl_Preferences::file_access(unsigned int)
|
|
@see Fl_Preferences::file_access()
|
|
*/
|
|
static const unsigned int NONE = 0x0000;
|
|
/** set this if it is ok for applications to read user preference files */
|
|
static const unsigned int USER_READ_OK = 0x0001;
|
|
/** set this if it is ok for applications to create and write user preference files */
|
|
static const unsigned int USER_WRITE_OK = 0x0002;
|
|
/** set this if it is ok for applications to read, create, and write user preference files */
|
|
static const unsigned int USER_OK = USER_READ_OK | USER_WRITE_OK;
|
|
/** set this if it is ok for applications to read system wide preference files */
|
|
static const unsigned int SYSTEM_READ_OK = 0x0004;
|
|
/** set this if it is ok for applications to create and write system wide preference files */
|
|
static const unsigned int SYSTEM_WRITE_OK = 0x0008;
|
|
/** set this if it is ok for applications to read, create, and write system wide preference files */
|
|
static const unsigned int SYSTEM_OK = SYSTEM_READ_OK | SYSTEM_WRITE_OK;
|
|
/** set this if it is ok for applications to read, create, and write any kind of preference files */
|
|
static const unsigned int APP_OK = SYSTEM_OK | USER_OK;
|
|
/** Set this if it is ok for FLTK to read preference files. USER_READ_OK and/or SYSTEM_READ_OK must also be set. */
|
|
static const unsigned int CORE_READ_OK = 0x0010;
|
|
/** Set this if it is ok for FLTK to create or write preference files. USER_WRITE_OK and/or SYSTEM_WRITE_OK must also be set. */
|
|
static const unsigned int CORE_WRITE_OK = 0x0020;
|
|
/** set this if it is ok for FLTK to read, create, or write preference files */
|
|
static const unsigned int CORE_OK = CORE_READ_OK | CORE_WRITE_OK;
|
|
/** set this to allow FLTK and applications to read preference files */
|
|
static const unsigned int ALL_READ_OK = USER_READ_OK | SYSTEM_READ_OK | CORE_READ_OK;
|
|
/** set this to allow FLTK and applications to create and write preference files */
|
|
static const unsigned int ALL_WRITE_OK = USER_WRITE_OK | SYSTEM_WRITE_OK | CORE_WRITE_OK;
|
|
/** set this to give FLTK and applications permission to read, write, and create preference files */
|
|
static const unsigned int ALL = ALL_READ_OK | ALL_WRITE_OK;
|
|
|
|
static void file_access(unsigned int flags);
|
|
static unsigned int file_access();
|
|
|
|
Fl_Preferences( Root root, const char *vendor, const char *application );
|
|
Fl_Preferences( const char *path, const char *vendor, const char *application );
|
|
Fl_Preferences( Fl_Preferences &parent, const char *group );
|
|
Fl_Preferences( Fl_Preferences *parent, const char *group );
|
|
Fl_Preferences( Fl_Preferences &parent, int groupIndex );
|
|
Fl_Preferences( Fl_Preferences *parent, int groupIndex );
|
|
Fl_Preferences(const Fl_Preferences&);
|
|
Fl_Preferences( ID id );
|
|
virtual ~Fl_Preferences();
|
|
|
|
/** Return an ID that can later be reused to open more references to this dataset.
|
|
*/
|
|
ID id() { return (ID)node; }
|
|
|
|
/** Remove the group with this ID from a database.
|
|
*/
|
|
static char remove(ID id_) { return ((Node*)id_)->remove(); }
|
|
|
|
/** Return the name of this entry.
|
|
*/
|
|
const char *name() { return node->name(); }
|
|
|
|
/** Return the full path to this entry.
|
|
*/
|
|
const char *path() { return node->path(); }
|
|
|
|
int groups();
|
|
const char *group( int num_group );
|
|
char groupExists( const char *key );
|
|
char deleteGroup( const char *group );
|
|
char deleteAllGroups();
|
|
|
|
int entries();
|
|
const char *entry( int index );
|
|
char entryExists( const char *key );
|
|
char deleteEntry( const char *entry );
|
|
char deleteAllEntries();
|
|
|
|
char clear();
|
|
|
|
char set( const char *entry, int value );
|
|
char set( const char *entry, float value );
|
|
char set( const char *entry, float value, int precision );
|
|
char set( const char *entry, double value );
|
|
char set( const char *entry, double value, int precision );
|
|
char set( const char *entry, const char *value );
|
|
char set( const char *entry, const void *value, int size );
|
|
|
|
char get( const char *entry, int &value, int defaultValue );
|
|
char get( const char *entry, float &value, float defaultValue );
|
|
char get( const char *entry, double &value, double defaultValue );
|
|
char get( const char *entry, char *&value, const char *defaultValue );
|
|
char get( const char *entry, char *value, const char *defaultValue, int maxSize );
|
|
char get( const char *entry, void *&value, const void *defaultValue, int defaultSize );
|
|
char get( const char *entry, void *value, const void *defaultValue, int defaultSize, int maxSize );
|
|
|
|
int size( const char *entry );
|
|
|
|
char getUserdataPath( char *path, int pathlen );
|
|
|
|
void flush();
|
|
|
|
// char export( const char *filename, Type fileFormat );
|
|
// char import( const char *filename );
|
|
|
|
/**
|
|
'Name' provides a simple method to create numerical or more complex
|
|
procedural names for entries and groups on the fly.
|
|
|
|
Example: prefs.set(Fl_Preferences::Name("File%d",i),file[i]);.
|
|
|
|
See test/preferences.cxx as a sample for writing arrays into preferences.
|
|
|
|
'Name' is actually implemented as a class inside Fl_Preferences. It casts
|
|
into const char* and gets automatically destroyed after the enclosing call
|
|
ends.
|
|
*/
|
|
class FL_EXPORT Name {
|
|
|
|
char *data_;
|
|
|
|
public:
|
|
Name( unsigned int n );
|
|
Name( const char *format, ... );
|
|
|
|
/**
|
|
Return the Name as a "C" string.
|
|
\internal
|
|
*/
|
|
operator const char *() { return data_; }
|
|
~Name();
|
|
};
|
|
|
|
/** \internal An entry associates a preference name to its corresponding value */
|
|
struct Entry {
|
|
char *name, *value;
|
|
};
|
|
|
|
private:
|
|
Fl_Preferences() : node(0), rootNode(0) { }
|
|
Fl_Preferences &operator=(const Fl_Preferences&);
|
|
|
|
static char nameBuffer[128];
|
|
static char uuidBuffer[40];
|
|
static Fl_Preferences *runtimePrefs;
|
|
static unsigned int fileAccess_;
|
|
|
|
public: // older Sun compilers need this (public definition of the following classes)
|
|
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_;
|
|
union { // these two are mutually exclusive
|
|
Node *parent_; // top_ bit clear
|
|
RootNode *root_; // top_ bit set
|
|
};
|
|
char *path_;
|
|
Entry *entry_;
|
|
int nEntry_, NEntry_;
|
|
unsigned char dirty_:1;
|
|
unsigned char top_:1;
|
|
unsigned char indexed_:1;
|
|
// indexing routines
|
|
Node **index_;
|
|
int nIndex_, NIndex_;
|
|
void createIndex();
|
|
void updateIndex();
|
|
void deleteIndex();
|
|
public:
|
|
static int lastEntrySet;
|
|
public:
|
|
Node( const char *path );
|
|
~Node();
|
|
// node methods
|
|
int write( FILE *f );
|
|
const char *name();
|
|
const char *path() { return path_; }
|
|
Node *find( const char *path );
|
|
Node *search( const char *path, int offset=0 );
|
|
Node *childNode( int ix );
|
|
Node *addChild( const char *path );
|
|
void setParent( Node *parent );
|
|
Node *parent() { return top_?0L:parent_; }
|
|
void setRoot(RootNode *r) { root_ = r; top_ = 1; }
|
|
RootNode *findRoot();
|
|
char remove();
|
|
char dirty();
|
|
void clearDirtyFlags();
|
|
void deleteAllChildren();
|
|
// entry methods
|
|
int nChildren();
|
|
const char *child( int ix );
|
|
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 );
|
|
char deleteEntry( const char *name );
|
|
void deleteAllEntries();
|
|
int nEntry() { return nEntry_; }
|
|
Entry &entry(int i) { return entry_[i]; }
|
|
};
|
|
friend class Node;
|
|
|
|
class FL_EXPORT RootNode { // the root node manages file paths and basic reading and writing
|
|
Fl_Preferences *prefs_;
|
|
char *filename_;
|
|
char *vendor_, *application_;
|
|
Root root_;
|
|
public:
|
|
RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application );
|
|
RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application );
|
|
RootNode( Fl_Preferences * );
|
|
~RootNode();
|
|
int read();
|
|
int write();
|
|
char getPath( char *path, int pathlen );
|
|
};
|
|
friend class RootNode;
|
|
|
|
protected:
|
|
Node *node;
|
|
RootNode *rootNode;
|
|
};
|
|
|
|
#endif // !Fl_Preferences_H
|