1#ifndef SETTINGS_HANDLER_H
2#define SETTINGS_HANDLER_H
3
4
5#include <stdarg.h>
6#include <stdlib.h>
7#include <stdio.h>
8#include <string.h>
9
10#include <SupportDefs.h>
11
12
13class BFile;
14class BDirectory;
15class BRect;
16class Settings;
17
18
19typedef const char* (*ArgvHandler)(int argc, const char *const *argv, void *params);
20	// return 0 or error string if parsing failed
21
22
23const int32 kBufferSize = 1024;
24
25
26class ArgvParser {
27	public:
28		static status_t EachArgv(const char* name,
29			ArgvHandler argvHandlerFunc, void* passThru);
30
31	private:
32		ArgvParser(const char* name);
33		~ArgvParser();
34
35		status_t EachArgvPrivate(const char* name,
36			ArgvHandler argvHandlerFunc, void* passThru);
37		char GetCh();
38
39		status_t SendArgv(ArgvHandler argvHandlerFunc, void* passThru);
40			// done with a whole line of argv, send it off and get ready
41			// to build a new one
42
43		void NextArgv();
44			// done with current string, get ready to start building next
45		void NextArgvIfNotEmpty();
46			// as above, don't commint current string if empty
47
48		void MakeArgvEmpty();
49
50		FILE*	fFile;
51		char*	fBuffer;
52		int32	fPos;
53		int32	fNumAvail;
54
55		int		fArgc;
56		char**	fCurrentArgv;
57
58		int32	fCurrentArgsPos;
59		char	fCurrentArgs[1024];
60
61		bool	fSawBackslash;
62		bool	fEatComment;
63		bool	fInDoubleQuote;
64		bool	fInSingleQuote;
65
66		int32	fLineNo;
67		const char* fFileName;
68};
69
70
71class SettingsArgvDispatcher {
72		// base class for a single setting item
73	public:
74		SettingsArgvDispatcher(const char* name);
75		virtual ~SettingsArgvDispatcher() {};
76
77		void SaveSettings(Settings* settings, bool onlyIfNonDefault);
78
79		const char* Name() const
80		{
81			return fName;
82		}
83
84		virtual const char* Handle(const char* const *argv) = 0;
85			// override this adding an argv parser that reads in the
86			// values in argv format for this setting
87			// return a pointer to an error message or null if parsed OK
88
89		bool HandleRectValue(BRect&, const char* const *argv,
90			bool printError = true);
91
92		// static bool HandleColorValue(rgb_color &, const char *const *argv, bool printError = true);
93		void WriteRectValue(Settings*, BRect);
94		// void WriteColorValue(BRect);
95
96	protected:
97		virtual void SaveSettingValue(Settings* settings) = 0;
98			// override this to save the current value of this setting in a
99			// text format
100
101		virtual bool NeedsSaving() const
102		{
103			return true;
104		}
105		// override to return false if current value is equal to the default
106		// and does not need saving
107	private:
108		const char* fName;
109};
110
111
112class Settings {
113	public:
114		Settings(const char* filename, const char* settingsDirName);
115		~Settings();
116		void TryReadingSettings();
117		void SaveSettings(bool onlyIfNonDefault = true);
118
119#ifdef SINGLE_SETTING_FILE
120		static Settings* SettingsHandler()
121		{
122			return settingsHandler;
123		}
124#else
125		Settings* SettingsHandler()
126		{
127			return this;
128		}
129#endif
130
131		bool Add(SettingsArgvDispatcher *);
132
133		void Write(const char* format, ...);
134		void VSWrite(const char*, va_list);
135
136#ifdef SINGLE_SETTING_FILE
137		static Settings* settingsHandler;
138#endif
139
140	private:
141		void _MakeSettingsDirectory(BDirectory*);
142
143		SettingsArgvDispatcher* _Find(const char*);
144		static const char* _ParseUserSettings(int, const char *const *argv, void*);
145		void _SaveCurrentSettings(bool onlyIfNonDefault);
146
147		const char* fFileName;
148		const char* fSettingsDir;
149		SettingsArgvDispatcher** fList;
150		int32 fCount;
151		int32 fListSize;
152		BFile* fCurrentSettings;
153};
154
155#endif	// SETTINGS_HANDLER_H
156