1 /* Copyright Krzysztof Kowalczyk 2006-2007
5 #include "DisplayModel.h"
6 #include "DisplayState.h"
8 #include "FileHistory.h"
15 extern BOOL gShowToolbar
;
17 extern BOOL gPdfAssociateDontAskAgain
;
18 extern BOOL gPdfAssociateShouldAssociate
;
19 extern bool CurrLangNameSet(const char* langName
);
20 extern const char* CurrLangNameGet();
22 #define DEFAULT_WINDOW_X 40
23 #define DEFAULT_WINDOW_Y 20
24 #define DEFAULT_WINDOW_DX 640
25 #define DEFAULT_WINDOW_DY 480
27 static BOOL
FileExists(const char *fileName
)
32 res
= stat(fileName
, &buf
);
38 bool Prefs_Serialize(FileHistoryList
**root
, DString
*strOut
)
40 assert(0 == strOut
->length
);
41 DStringSprintf(strOut
, " %s: %d\n", SHOW_TOOLBAR_STR
, gShowToolbar
);
42 DStringSprintf(strOut
, " %s: %d\n", USE_FITZ_STR
, gUseFitz
);
43 DStringSprintf(strOut
, " %s: %d\n", PDF_ASSOCIATE_DONT_ASK_STR
, gPdfAssociateDontAskAgain
);
44 DStringSprintf(strOut
, " %s: %d\n", PDF_ASSOCIATE_ASSOCIATE_STR
, gPdfAssociateShouldAssociate
);
45 DStringSprintf(strOut
, " %s: %s\n", UI_LANGUAGE_STR
, CurrLangNameGet());
46 return FileHistoryList_Serialize(root
, strOut
);
49 static BOOL
ParseDisplayMode(const char *txt
, DisplayMode
*resOut
)
52 if (!txt
) return FALSE
;
53 return DisplayModeEnumFromName(txt
, resOut
);
56 static BOOL
ParseDouble(const char *txt
, double *resOut
)
61 if (!txt
) return FALSE
;
63 res
= sscanf(txt
, "%lf", resOut
);
69 static BOOL
ParseInt(const char *txt
, int *resOut
)
72 if (!txt
) return FALSE
;
77 static BOOL
ParseBool(const char *txt
, BOOL
*resOut
)
80 if (!txt
) return FALSE
;
89 enum PrefsParsingState
{ PPS_START
, PPS_IN_FILE_HISTORY
};
91 /* Return TRUE if 'str' is a comment line in preferences file.
92 Comment lines start with '#'. */
93 static int Prefs_LineIsComment(const char *str
)
102 static int Prefs_LineIsStructKey(const char *str
)
104 if (strlen(str
) <= 3)
106 if ((' ' == str
[0]) && (' ' == str
[1]))
111 static void ParseKeyValue(char *key
, char *value
, DisplayState
*dsOut
)
118 if (!key
|| !value
|| !dsOut
)
121 if (str_eq(FILE_STR
, key
)) {
124 assert(!dsOut
->filePath
);
125 free((void*)dsOut
->filePath
);
126 dsOut
->filePath
= str_dup(value
);
130 if (str_eq(DISPLAY_MODE_STR
, key
)) {
131 dsOut
->displayMode
= DM_SINGLE_PAGE
;
132 fOk
= ParseDisplayMode(value
, &dsOut
->displayMode
);
137 if (str_eq(PAGE_NO_STR
, key
)) {
138 fOk
= ParseInt(value
, &dsOut
->pageNo
);
140 if (!fOk
|| (dsOut
->pageNo
< 1))
145 if (str_eq(ZOOM_VIRTUAL_STR
, key
)) {
146 fOk
= ParseDouble(value
, &dsOut
->zoomVirtual
);
148 if (!fOk
|| !ValidZoomVirtual(dsOut
->zoomVirtual
))
149 dsOut
->zoomVirtual
= 100.0;
153 if (str_eq(ROTATION_STR
, key
)) {
154 fOk
= ParseInt(value
, &dsOut
->rotation
);
156 if (!fOk
|| !validRotation(dsOut
->rotation
))
161 if (str_eq(VISIBLE_STR
, key
)) {
162 dsOut
->visible
= FALSE
;
163 fOk
= ParseBool(value
, &dsOut
->visible
);
168 if (str_eq(FULLSCREEN_STR
, key
)) {
169 dsOut
->fullScreen
= FALSE
;
170 fOk
= ParseBool(value
, &dsOut
->fullScreen
);
175 if (str_eq(SCROLL_X_STR
, key
)) {
177 fOk
= ParseInt(value
, &dsOut
->scrollX
);
182 if (str_eq(SCROLL_Y_STR
, key
)) {
184 fOk
= ParseInt(value
, &dsOut
->scrollY
);
189 if (str_eq(WINDOW_X_STR
, key
)) {
190 dsOut
->windowX
= DEFAULT_WINDOW_X
;
191 fOk
= ParseInt(value
, &dsOut
->windowX
);
196 if (str_eq(WINDOW_Y_STR
, key
)) {
197 dsOut
->windowY
= DEFAULT_WINDOW_Y
;
198 fOk
= ParseInt(value
, &dsOut
->windowY
);
203 if (str_eq(WINDOW_DX_STR
, key
)) {
204 dsOut
->windowDx
= DEFAULT_WINDOW_DX
;
205 fOk
= ParseInt(value
, &dsOut
->windowDx
);
210 if (str_eq(WINDOW_DY_STR
, key
)) {
211 dsOut
->windowDy
= DEFAULT_WINDOW_DY
;
212 fOk
= ParseInt(value
, &dsOut
->windowDy
);
220 void FileHistory_Add(FileHistoryList
**fileHistoryRoot
, DisplayState
*state
)
222 FileHistoryList
* fileHistoryNode
= NULL
;
223 if (!FileExists(state
->filePath
)) {
224 DBG_OUT("FileHistory_Add() file '%s' doesn't exist anymore\n", state
->filePath
);
228 fileHistoryNode
= FileHistoryList_Node_Create();
229 fileHistoryNode
->state
= *state
;
230 FileHistoryList_Node_Append(fileHistoryRoot
, fileHistoryNode
);
231 fileHistoryNode
= NULL
;
234 /* Deserialize preferences from text. Put state into 'dsOut' and add all history
235 items to file history list 'root'.
236 Return FALSE if there was an error.
237 An ode to a state machine. */
238 bool Prefs_Deserialize(const char *prefsTxt
, FileHistoryList
**fileHistoryRoot
)
240 PrefsParsingState state
= PPS_START
;
241 char * prefsTxtNormalized
= NULL
;
242 char * strTmp
= NULL
;
244 char * key
, *value
, *keyToFree
= NULL
;
246 DisplayState currState
;
248 DisplayState_Init(&currState
);
250 prefsTxtNormalized
= str_normalize_newline(prefsTxt
, UNIX_NEWLINE
);
251 if (!prefsTxtNormalized
)
254 strTmp
= prefsTxtNormalized
;
256 line
= str_split_iter(&strTmp
, UNIX_NEWLINE_C
);
259 str_strip_ws_right(line
);
261 /* skip empty and comment lines*/
264 if (Prefs_LineIsComment(line
))
267 /* each line is key/value pair formatted as: "key: value"
268 value is optional. If value exists, there must
269 be a space after ':' */
271 keyToFree
= str_split_iter(&value
, ':');
276 if (str_empty(value
)) {
277 value
= NULL
; /* there was no value */
279 assert(' ' == *value
);
284 isStructVal
= Prefs_LineIsStructKey(key
);
291 if (str_eq(SHOW_TOOLBAR_STR
, key
)) {
293 ParseBool(value
, &gShowToolbar
);
296 if (str_eq(USE_FITZ_STR
, key
)) {
298 ParseBool(value
, &gUseFitz
);
301 if (str_eq(PDF_ASSOCIATE_DONT_ASK_STR
, key
)) {
302 gPdfAssociateDontAskAgain
= FALSE
;
303 ParseBool(value
, &gPdfAssociateDontAskAgain
);
306 if (str_eq(PDF_ASSOCIATE_ASSOCIATE_STR
, key
)) {
307 gPdfAssociateShouldAssociate
= TRUE
;
308 ParseBool(value
, &gPdfAssociateShouldAssociate
);
311 if (str_eq(UI_LANGUAGE_STR
, key
)) {
312 CurrLangNameSet(value
);
315 if (str_eq(FILE_HISTORY_STR
, key
)) {
316 assert(!isStructVal
);
317 state
= PPS_IN_FILE_HISTORY
;
321 DBG_OUT(" in state PPS_START, line='%s' \n\n", line
);
323 DBG_OUT(" in state PPS_START, line is NULL\n\n");
328 case PPS_IN_FILE_HISTORY
:
330 ParseKeyValue(key
, value
, &currState
);
332 if (currState
.filePath
) {
333 FileHistory_Add(fileHistoryRoot
, &currState
);
334 DisplayState_Init(&currState
);
343 free((void*)keyToFree
);
349 if (PPS_IN_FILE_HISTORY
== state
) {
350 if (currState
.filePath
) {
351 if (FileExists(currState
.filePath
))
352 FileHistory_Add(fileHistoryRoot
, &currState
);
356 free((void*)prefsTxtNormalized
);