2 * Copyright 2003-2015, Haiku, Inc. All Rights Reserved.
3 * Copyright (c) 2004 Daniel Furrer <assimil8or@users.sourceforge.net>
4 * Copyright (c) 2003-4 Kian Duffy <myob@users.sourceforge.net>
5 * Copyright (c) 1998,99 Kazuho Okui and Takashi Murai.
7 * Distributed unter the terms of the MIT License.
10 * Kian Duffy, myob@users.sourceforge.net
11 * Daniel Furrer, assimil8or@users.sourceforge.net
12 * Siarzhuk Zharski, zharik@gmx.li
16 #include "PrefHandler.h"
24 #include <Directory.h>
27 #include <FindDirectory.h>
29 #include <GraphicsDefs.h>
36 #include "TermConst.h"
41 * Startup preference settings.
43 static const pref_defaults kTermDefaults
[] = {
47 // No need for PREF_HALF_FONT_FAMILY/_STYLE defaults here,
48 // these entries will be filled with corresponding params
49 // of the current system fixed font if they are not
50 // available in the settings file
52 { PREF_HALF_FONT_SIZE
, "12" },
54 { PREF_TEXT_FORE_COLOR
, " 0, 0, 0" },
55 { PREF_TEXT_BACK_COLOR
, "255, 255, 255" },
56 { PREF_CURSOR_FORE_COLOR
, "255, 255, 255" },
57 { PREF_CURSOR_BACK_COLOR
, " 0, 0, 0" },
58 { PREF_SELECT_FORE_COLOR
, "255, 255, 255" },
59 { PREF_SELECT_BACK_COLOR
, " 0, 0, 0" },
61 { PREF_IM_FORE_COLOR
, " 0, 0, 0" },
62 { PREF_IM_BACK_COLOR
, "152, 203, 255" },
63 { PREF_IM_SELECT_COLOR
, "255, 152, 152" },
65 { PREF_ANSI_BLACK_COLOR
, " 40, 40, 40" },
66 { PREF_ANSI_RED_COLOR
, "204, 0, 0" },
67 { PREF_ANSI_GREEN_COLOR
, " 78, 154, 6" },
68 { PREF_ANSI_YELLOW_COLOR
, "218, 168, 0" },
69 { PREF_ANSI_BLUE_COLOR
, " 51, 102, 152" },
70 { PREF_ANSI_MAGENTA_COLOR
, "115, 68, 123" },
71 { PREF_ANSI_CYAN_COLOR
, " 6, 152, 154" },
72 { PREF_ANSI_WHITE_COLOR
, "245, 245, 245" },
74 { PREF_ANSI_BLACK_HCOLOR
, "128, 128, 128" },
75 { PREF_ANSI_RED_HCOLOR
, "255, 0, 0" },
76 { PREF_ANSI_GREEN_HCOLOR
, " 0, 255, 0" },
77 { PREF_ANSI_YELLOW_HCOLOR
, "255, 255, 0" },
78 { PREF_ANSI_BLUE_HCOLOR
, " 0, 0, 255" },
79 { PREF_ANSI_MAGENTA_HCOLOR
, "255, 0, 255" },
80 { PREF_ANSI_CYAN_HCOLOR
, " 0, 255, 255" },
81 { PREF_ANSI_WHITE_HCOLOR
, "255, 255, 255" },
83 { PREF_HISTORY_SIZE
, "10000" },
85 { PREF_TEXT_ENCODING
, "UTF-8" },
87 { PREF_IM_AWARE
, "0"},
89 { PREF_TAB_TITLE
, "%1d: %p%e" },
90 { PREF_WINDOW_TITLE
, "%T% i: %t" },
91 { PREF_BLINK_CURSOR
, PREF_TRUE
},
92 { PREF_WARN_ON_EXIT
, PREF_TRUE
},
93 { PREF_CURSOR_STYLE
, PREF_BLOCK_CURSOR
},
94 { PREF_EMULATE_BOLD
, PREF_FALSE
},
100 PrefHandler
*PrefHandler::sPrefHandler
= NULL
;
103 PrefHandler::PrefHandler(bool loadSettings
)
107 _LoadFromDefault(kTermDefaults
);
111 GetDefaultPath(path
);
112 OpenText(path
.Path());
115 // TODO: If no fixed font is available, be_fixed_font
116 // points to a proportional font.
117 if (IsFontUsable(be_fixed_font
))
118 _ConfirmFont(be_fixed_font
);
120 int32 numFamilies
= count_font_families();
121 for (int32 i
= 0; i
< numFamilies
; i
++) {
124 if (get_font_family(i
, &family
, &flags
) == B_OK
) {
126 int32 numStyles
= count_font_styles(family
);
127 for (int32 j
= 0; j
< numStyles
; j
++) {
128 if (get_font_style(family
, j
, &style
) == B_OK
) {
130 fallBackFont
.SetFamilyAndStyle(family
, style
);
131 if (IsFontUsable(fallBackFont
)) {
132 _ConfirmFont(&fallBackFont
);
143 PrefHandler::PrefHandler(const PrefHandler
* p
)
145 fContainer
= p
->fContainer
;
149 PrefHandler::~PrefHandler()
156 PrefHandler::Default()
158 if (sPrefHandler
== NULL
)
159 sPrefHandler
= new PrefHandler();
166 PrefHandler::DeleteDefault()
175 PrefHandler::SetDefault(PrefHandler
*prefHandler
)
178 sPrefHandler
= prefHandler
;
184 PrefHandler::GetDefaultPath(BPath
& path
)
187 status
= find_directory(B_USER_SETTINGS_DIRECTORY
, &path
, true);
191 status
= path
.Append("Terminal");
195 // Just create the directory. Harmless if already there
196 status
= create_directory(path
.Path(), 0755);
200 return path
.Append("Default");
205 PrefHandler::OpenText(const char *path
)
207 return _LoadFromTextFile(path
);
212 PrefHandler::SaveDefaultAsText()
215 if (GetDefaultPath(path
) == B_OK
)
216 SaveAsText(path
.Path(), PREFFILE_MIMETYPE
);
221 PrefHandler::SaveAsText(const char *path
, const char *mimetype
,
222 const char *signature
)
224 // make sure the target path exists
226 BPath
directoryPath(path
);
227 if (directoryPath
.GetParent(&directoryPath
) == B_OK
)
228 create_directory(directoryPath
.Path(), 0755);
231 BFile
file(path
, B_WRITE_ONLY
| B_CREATE_FILE
| B_ERASE_FILE
);
237 #ifdef B_BEOS_VERSION_DANO
238 fContainer
.GetInfo(B_STRING_TYPE
, i
, &key
, &type
) == B_OK
;
240 fContainer
.GetInfo(B_STRING_TYPE
, i
, (char**)&key
, &type
) == B_OK
;
243 int len
= snprintf(buffer
, sizeof(buffer
), "\"%s\" , \"%s\"\n",
244 key
, getString(key
));
245 file
.Write(buffer
, len
);
248 if (mimetype
!= NULL
) {
249 BNodeInfo
info(&file
);
250 info
.SetType(mimetype
);
251 info
.SetPreferredApp(signature
);
257 PrefHandler::getInt32(const char *key
)
259 const char *value
= fContainer
.FindString(key
);
268 PrefHandler::getFloat(const char *key
)
270 const char *value
= fContainer
.FindString(key
);
278 #undef B_TRANSLATION_CONTEXT
279 #define B_TRANSLATION_CONTEXT "Terminal getString"
282 PrefHandler::getString(const char *key
)
285 if (fContainer
.FindString(key
, &buffer
) != B_OK
)
286 buffer
= B_TRANSLATE("Error!");
288 //printf("%x GET %s: %s\n", this, key, buf);
294 PrefHandler::getBool(const char *key
)
296 const char *value
= fContainer
.FindString(key
);
300 return strcmp(value
, PREF_TRUE
) == 0;
305 PrefHandler::getCursor(const char *key
)
307 const char *value
= fContainer
.FindString(key
);
308 if (value
!= NULL
&& strcmp(value
, PREF_BLOCK_CURSOR
) != 0) {
309 if (strcmp(value
, PREF_UNDERLINE_CURSOR
) == 0)
310 return UNDERLINE_CURSOR
;
311 if (strcmp(value
, PREF_IBEAM_CURSOR
) == 0)
318 #undef B_TRANSLATION_CONTEXT
319 #define B_TRANSLATION_CONTEXT "Terminal getRGB"
321 /** Returns RGB data from given key. */
324 PrefHandler::getRGB(const char *key
)
329 if (const char *s
= fContainer
.FindString(key
)) {
330 sscanf(s
, "%d, %d, %d", &r
, &g
, &b
);
333 "PrefHandler::getRGB(%s) - key not found\n", key
);
345 /** Setting Int32 data with key. */
348 PrefHandler::setInt32(const char *key
, int32 data
)
351 snprintf(buffer
, sizeof(buffer
), "%d", (int)data
);
352 setString(key
, buffer
);
356 /** Setting Float data with key */
359 PrefHandler::setFloat(const char *key
, float data
)
362 snprintf(buffer
, sizeof(buffer
), "%g", data
);
363 setString(key
, buffer
);
367 /** Setting Bool data with key */
370 PrefHandler::setBool(const char *key
, bool data
)
373 setString(key
, PREF_TRUE
);
375 setString(key
, PREF_FALSE
);
379 /** Setting CString data with key */
382 PrefHandler::setString(const char *key
, const char *data
)
384 //printf("%x SET %s: %s\n", this, key, data);
385 fContainer
.RemoveName(key
);
386 fContainer
.AddString(key
, data
);
390 /** Setting RGB data with key */
393 PrefHandler::setRGB(const char *key
, const rgb_color data
)
396 snprintf(buffer
, sizeof(buffer
), "%d, %d, %d", data
.red
, data
.green
, data
.blue
);
397 setString(key
, buffer
);
401 /** Check any peference stored or not. */
404 PrefHandler::IsEmpty() const
406 return fContainer
.IsEmpty();
411 PrefHandler::_ConfirmFont(const BFont
*fallbackFont
)
416 const char *prefFamily
= getString(PREF_HALF_FONT_FAMILY
);
417 int32 familiesCount
= (prefFamily
!= NULL
) ? count_font_families() : 0;
419 for (int32 i
= 0; i
< familiesCount
; i
++) {
420 if (get_font_family(i
, &family
) != B_OK
421 || strcmp(family
, prefFamily
) != 0)
424 const char *prefStyle
= getString(PREF_HALF_FONT_STYLE
);
425 int32 stylesCount
= (prefStyle
!= NULL
) ? count_font_styles(family
) : 0;
427 for (int32 j
= 0; j
< stylesCount
; j
++) {
428 // check style if we can safely use this font
429 if (get_font_style(family
, j
, &style
) == B_OK
430 && strcmp(style
, prefStyle
) == 0)
435 // use fall-back font
436 fallbackFont
->GetFamilyAndStyle(&family
, &style
);
437 setString(PREF_HALF_FONT_FAMILY
, family
);
438 setString(PREF_HALF_FONT_STYLE
, style
);
443 PrefHandler::_LoadFromDefault(const pref_defaults
* defaults
)
445 if (defaults
== NULL
)
448 while (defaults
->key
) {
449 setString(defaults
->key
, defaults
->item
);
457 /** Text is "key","Content"
458 * Comment : Start with '#'
462 PrefHandler::_LoadFromTextFile(const char * path
)
465 char key
[B_FIELD_NAME_LENGTH
], data
[512];
469 file
= fopen(path
, "r");
471 return B_ENTRY_NOT_FOUND
;
473 while (fgets(buffer
, sizeof(buffer
), file
) != NULL
) {
477 n
= sscanf(buffer
, "%*[\"]%[^\"]%*[\"]%*[^\"]%*[\"]%[^\"]", key
, data
);
479 setString(key
, data
);