- re-add todo: descriptions still aren't handled

- MSTheme: map windows system sounds
- MSTheme: fix UTF-8 issue (BString::RemoveSet() is buggy on BeOS) and NTFS path handling (check several capitalizations).
- MSTheme: force Deskbar at the bottom, disable Z-Snake
- add fallbacks for window decors to importers and decor addons
- add 1.0 sound gain from R5


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27805 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2008-10-01 01:18:23 +00:00
parent 9aabd0ab3a
commit 59967bf000
7 changed files with 396 additions and 21 deletions

View File

@ -147,6 +147,40 @@ status_t BeThemeImporter::ImportNextTheme(BMessage **theme)
if (sscanf(token.String(), "DECOR:%ld", &value) >= 1) {
value = (value < 4) ? value : 0;
decor.AddInt32("window:R5:decor", value);
switch (value) {
case R5_DECOR_BEOS:
default:
decor.AddString("window:decor", "R5");
// fallbacks
decor.AddString("window:decor", "Default");
decor.AddString("window:decor", "ClassicBe");
decor.AddString("window:decor", "BeDecorator");
break;
case R5_DECOR_WIN95:
decor.AddString("window:decor", "Win95");
// fallbacks
decor.AddString("window:decor", "Win2k");
decor.AddString("window:decor", "Win");
decor.AddString("window:decor", "Redmond");
decor.AddString("window:decor", "Seattle");
decor.AddString("window:decor", "WinDecorator");
break;
case R5_DECOR_AMIGA:
decor.AddString("window:decor", "Amiga");
// fallbacks
decor.AddString("window:decor", "AmigaOS");
decor.AddString("window:decor", "AmigaOS4");
break;
case R5_DECOR_MAC:
decor.AddString("window:decor", "Mac");
// fallbacks
decor.AddString("window:decor", "MacOS");
decor.AddString("window:decor", "Baqua");
decor.AddString("window:decor", "Cupertino");
decor.AddString("window:decor", "MacDecorator");
break;
}
}
}

View File

@ -40,12 +40,6 @@
#define FENTRY
#endif
static const deskbar_location kDeskbarLocationMap[] = {
//2:top 1:topright 5:bottom
B_DESKBAR_LEFT_TOP, B_DESKBAR_RIGHT_TOP, B_DESKBAR_TOP,
B_DESKBAR_LEFT_BOTTOM, B_DESKBAR_RIGHT_BOTTOM, B_DESKBAR_BOTTOM
};
static struct ui_color_map {
const char *wname;
const char *name1;
@ -115,6 +109,75 @@ static struct screensaver_map {
};
/*
'[' <REGPATH> [|.A|.W] ']'
left to map:
AppEvents\\Schemes\\Apps\\.Default\\AppGPFault\\.Current
AppEvents\\Schemes\\Apps\\.Default\\DeviceConnect\\.Current
AppEvents\\Schemes\\Apps\\.Default\\DeviceDisconnect\\.Current
AppEvents\\Schemes\\Apps\\.Default\\DeviceFail\\.Current
AppEvents\\Schemes\\Apps\\.Default\\LowBatteryAlarm\\.Current
AppEvents\\Schemes\\Apps\\.Default\\MenuCommand\\.Current
AppEvents\\Schemes\\Apps\\.Default\\MenuPopup\\.Current
AppEvents\\Schemes\\Apps\\.Default\\PrintComplete\\.Current
AppEvents\\Schemes\\Apps\\.Default\\RingIn\\.Current
AppEvents\\Schemes\\Apps\\.Default\\Ringout\\.Current
AppEvents\\Schemes\\Apps\\.Default\\SystemHand\\.Current
AppEvents\\Schemes\\Apps\\.Default\\SystemQuestion\\.Current
AppEvents\\Schemes\\Apps\\.Default\\SystemStartMenu\\.Current
AppEvents\\Schemes\\Apps\\.Default\\WindowsLogoff\\.Current
AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current
AppEvents\\Schemes\\Apps\\Explorer\\EmptyRecycleBin\\.Current
AppEvents\\Schemes\\Apps\\Explorer\\Navigating\\.Current
*/
static struct sounds_map {
const char *wname;
const char *name;
} sSoundsMap[] = {
//{ "", "BeShare-DLFinished" },
//{ "", "BeShare-InactivChat" },
//{ "", "BeShare-Name Said" },
//{ "", "BeShare-NoComplete" },
//{ "", "BeShare-Private Msg" },
//{ "", "BeShare-PrivateWndw" },
//{ "", "BeShare-ULFinished" },
//{ "", "BeShare-ULStarted" },
//{ "", "BeShare-WatchedUser" },
{ "AppEvents\\Schemes\\Apps\\.Default\\.Default\\.Current", "Beep" },
//{ "", "Capture" },
//{ "", "IM Connected" },
//{ "", "IM Disconnected" },
//{ "", "IM Message Received" },
//{ "", "IM Status: Available" },
//{ "", "IM Status: Away" },
//{ "", "IM Status: Offline" },
{ "AppEvents\\Schemes\\Apps\\.Default\\SystemExclamation\\.Current", "InfoPopper: Error Message" },
{ "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "InfoPopper: Important Message" },
{ "AppEvents\\Schemes\\Apps\\.Default\\SystemNotification\\.Current", "InfoPopper: Information Message" },
//{ "", "InfoPopper: Progress Message" },
//{ "", "Key Down" },
//{ "", "Key Repeat" },
//{ "", "Key Up" },
//{ "", "Mouse Down" },
//{ "", "Mouse Up" },
{ "AppEvents\\Schemes\\Apps\\.Default\\MailBeep\\.Current", "New E-mail" },
{ "AppEvents\\Schemes\\Apps\\.Default\\SystemStart\\.Current", "Startup" },
//{ "", "Vision Nick Notification" },
//{ "AppEvents\\Schemes\\Apps\\.Default\\RestoreDown\\.Current", "Window Activated" },
// actually *app* close/open...
{ "AppEvents\\Schemes\\Apps\\.Default\\Close\\.Current", "Window Close" },
{ "AppEvents\\Schemes\\Apps\\.Default\\Minimize\\.Current", "Window Minimized" },
{ "AppEvents\\Schemes\\Apps\\.Default\\Open\\.Current", "Window Open" },
// or Activated ?
{ "AppEvents\\Schemes\\Apps\\.Default\\RestoreUp\\.Current", "Window Restored" },
{ "AppEvents\\Schemes\\Apps\\.Default\\Maximize\\.Current", "Window Zoomed" },
//{ "", "Yahoo: Buzz" },
// non official sounds yet
{ "AppEvents\\Schemes\\Apps\\.Default\\SystemExit\\.Current", "Shutdown" },
{ NULL, NULL }
};
MSThemeImporter::MSThemeImporter()
:ThemeImporter("MSTheme")
{
@ -231,9 +294,10 @@ status_t MSThemeImporter::ImportNextTheme(BMessage **theme)
content.UnlockBuffer();
if (err < B_OK)
return err;
//PRINT(("'%s'\n", content.String()));
// strip DOS CR
content.RemoveSet("\r");
//printf("'%s'\n", content.String());
// RemoveSet() seems to be buggy on BeOS (strips UTF-8 chars ???)
content.RemoveAll("\r");
// is it really a theme file ?
if (content.IFindFirst("[Theme]") < 0)
@ -246,6 +310,7 @@ status_t MSThemeImporter::ImportNextTheme(BMessage **theme)
BMessage deskbar;
BMessage ui_settings;
BMessage screensaver;
BMessage sounds;
BString leaf(path.Leaf());
leaf.RemoveLast(".theme");
@ -269,7 +334,7 @@ status_t MSThemeImporter::ImportNextTheme(BMessage **theme)
BString line;
content.MoveInto(line, 0, content.FindFirst('\n'));
content.RemoveFirst("\n");
//printf(":'%s'\n", line.String());
//PRINT((":'%s'\n", line.String()));
if (line.Length() < 1)
continue;
if (line[0] == ';')
@ -380,14 +445,64 @@ status_t MSThemeImporter::ImportNextTheme(BMessage **theme)
if (value == "Metallic" && themeWindowDecor == "Redmond")
themeWindowDecor = "Seattle";
}
} else if (section.IFindFirst("AppEvents\\Schemes\\Apps") > -1) {
if (key != "DefaultValue")
continue;
// system sound...
for (int i = 0; sSoundsMap[i].wname; i++) {
if (section.IFindFirst(sSoundsMap[i].wname) > -1) {
BString encodedPath;
if (section.IFindFirst(".W]") > -1) {
// Wide Char weirdly encoded path...
// skip for now.
break;
// someone knows this +AOk- stuff ??
} else {
// ANSI path (.A or none specified)
// but it's been converted to UTF-8 already
// so we just use that one.
encodedPath = value;
}
PRINT(("Sound: '%s' -> '%s' (%s)\n", section.String(), sSoundsMap[i].name, value.String()));
if (encodedPath.Length() == 0)
break;
BPath soundPath;
if (ParseWinPath(rootDir, encodedPath.String(), soundPath) < B_OK)
break;
BMessage sound('SndI');
sound.AddString("sounds:file", soundPath.Path());
sound.AddFloat("sounds:volume", 1.0);
if (sounds.ReplaceMessage(sSoundsMap[i].name, &sound) < B_OK)
sounds.AddMessage(sSoundsMap[i].name, &sound);
}
}
} else {
;//PRINT(("MSThemeImporter: unknown section '%s', line '%s'\n", section.String(), line.String()));
}
}
// apply settings now we that have everything
// force Deskbar at the bottom... it's Windows, right?
// XXX: I couldn't find a reg key for that in any theme,
// but likely there is one.
deskbar_location loc = B_DESKBAR_BOTTOM;
bool expanded = true;
deskbar.AddInt32("db:location", (int32)loc);
deskbar.AddBool("db:expanded", expanded);
// window decor
decor.AddString("window:decor", themeWindowDecor.String());
// fallbacks
decor.AddString("window:decor", "Win95");
decor.AddString("window:decor", "Win2k");
decor.AddString("window:decor", "Win");
decor.AddString("window:decor", "Redmond");
decor.AddString("window:decor", "Seattle");
decor.AddString("window:decor", "WinDecorator");
decor.AddInt32("window:R5:decor", themeWindowDecorR5);
// wallpaper
if (themeWallpaperPath.InitCheck() == B_OK) {
backgrounds.AddString(B_BACKGROUND_IMAGE, themeWallpaperPath.Path());
backgrounds.AddInt32(B_BACKGROUND_WORKSPACES, 0xffffffff);
@ -408,9 +523,13 @@ status_t MSThemeImporter::ImportNextTheme(BMessage **theme)
}
backgrounds.AddInt32(B_BACKGROUND_MODE, wallpaperMode);
backgrounds.AddPoint(B_BACKGROUND_ORIGIN, themeWallpaperOrigin);
//XXX: there is a reg key for that, is it used ?
//backgrounds.AddBool(B_BACKGROUND_ERASE_TEXT, erasetext);
}
// ui settings: disable Z-Snake
ui_settings.AddBool(B_UI_MENU_ZSNAKE, false);
screensaver.AddString("screensaver:modulename", themeScreensaver.String());
global.AddMessage(Z_THEME_INFO_MESSAGE, &info);
@ -419,6 +538,7 @@ status_t MSThemeImporter::ImportNextTheme(BMessage **theme)
global.AddMessage(Z_THEME_DESKBAR_SETTINGS, &deskbar);
global.AddMessage(Z_THEME_UI_SETTINGS, &ui_settings);
global.AddMessage(Z_THEME_SCREENSAVER_SETTINGS, &screensaver);
global.AddMessage(Z_THEME_SOUNDS_SETTINGS, &sounds);
*theme = new BMessage(global);
//global.PrintToStream();
@ -464,12 +584,14 @@ bool MSThemeImporter::ScanDirectory(BDirectory &dir, int depth)
status_t MSThemeImporter::ParseWinPath(BDirectory &rootDir, const char *from, BPath &to)
{
status_t err;
//FENTRY;
//return ENOENT;
//BDirectory winDir(&rootDir, "WINDOWS");
//BDirectory resourceDir(&winDir, "Resources");
PRINT(("ParseWinPath(, %s, )\n", from));
BString p(from);
p.ReplaceAll('\\', '/');
//p.ReplaceAll('\\', '/');
to.SetTo(&rootDir, ".");
if (p.IFindFirst("%WinDir%") == 0) {
@ -480,10 +602,58 @@ status_t MSThemeImporter::ParseWinPath(BDirectory &rootDir, const char *from, BP
to.Append("WINDOWS/Resources");
p.IReplaceFirst("%ResourceDir%", "");
}
//TODO: %ThemeDir%
//TODO: split and check for correct case
//TODO: %ThemeDir%
to.Append(p.String());
BDirectory dir;
while (p.Length()) {
BString component;
PRINT(("ParseWinPath: p.L %d p '%s'\n", p.Length(), p.String()));
int32 len = p.FindFirst('\\');
if (len < 0)
len = p.Length();
p.MoveInto(component, 0, len);
p.RemoveFirst("\\");
err = dir.SetTo(to.Path());
if (err < B_OK)
return err;
PRINT(("ParseWinPath: at '%s'\n", to.Path()));
PRINT(("ParseWinPath: testing '%s'\n", component.String()));
if (dir.Contains(component.String())) {
to.Append(component.String());
continue;
}
// can't find as is, try various capitalizations
// (caseless fs SUXOR)
component.Capitalize();
PRINT(("ParseWinPath: testing '%s'\n", component.String()));
if (dir.Contains(component.String())) {
to.Append(component.String());
continue;
}
component.CapitalizeEachWord();
PRINT(("ParseWinPath: testing '%s'\n", component.String()));
if (dir.Contains(component.String())) {
to.Append(component.String());
continue;
}
component.ToLower();
PRINT(("ParseWinPath: testing '%s'\n", component.String()));
if (dir.Contains(component.String())) {
to.Append(component.String());
continue;
}
component.ToUpper();
PRINT(("ParseWinPath: testing '%s'\n", component.String()));
if (dir.Contains(component.String())) {
to.Append(component.String());
continue;
}
PRINT(("ParseWinPath: failed\n"));
// TODO: loop on GetNextEntry and ICompare ?
return ENOENT;
}
PRINT(("ParseWinPath(, %s, ) -> %s\n", from, to.Path()));
return B_OK;
}

View File

@ -1,6 +1,7 @@
TODOs for Theme manager:
* check R5 build
* style cleanup (-> Haiku style)
* enable theme descriptions again (tooltip on listitem ?).
* make ParseMessage more robust
* forbid quitting while themes are loading!
* implement BackupFiles() methods to add required files to a zip.

View File

@ -55,6 +55,7 @@
/* compatibility stuff ahead */
/* some field names not always defined */
// ui_colors
#ifndef B_BEOS_VERSION_DANO
#define B_UI_PANEL_BACKGROUND_COLOR "be:c:PanBg"
#define B_UI_PANEL_TEXT_COLOR "be:c:PanTx"
@ -79,6 +80,9 @@
#define B_UI_MENU_SELECTED_BORDER_COLOR "be:c:MenSBr"
#define B_UI_SUCCESS_COLOR "be:c:Success"
#define B_UI_FAILURE_COLOR "be:c:Failure"
// fonts
// other
#define B_UI_MENU_ZSNAKE "be:MenZSnake"
// broadcasted on update
#define B_UI_SETTINGS_CHANGED '_UIC'
#endif

View File

@ -23,6 +23,19 @@
#include "ThemesAddon.h"
#include "UITheme.h"
// for reference:
//
// available decors in Dano:
// (Default R5) Baqua BlueSteel Graphite Origin OriginSimple
//
// available decors in Zeta:
// (Default R5) Cupertino MenloTab Redmond Smoke ZetaDecor Menlo
// R5 Seattle TV_ ZLight blueBeOS yellowTAB
//
// mine:
// Win2k TextMode TextModeBlue
#ifdef SINGLE_BINARY
#define instantiate_themes_addon instantiate_themes_addon_window_decor
#endif
@ -31,6 +44,21 @@
#define A_MSGNAME Z_THEME_WINDOW_DECORATIONS
#define A_DESCRIPTION "Window decorations and scrollbars"
#ifdef B_BEOS_VERSION_DANO
status_t set_window_decor_safe(const char *name, BMessage *globals)
{
// make sure the decor exists (set_window_decor() always returns B_OK)
BPath p("/etc/decors/");
p.Append(name);
BNode n(p.Path());
if (n.InitCheck() < B_OK || !n.IsFile())
return ENOENT;
set_window_decor(name, globals);
return B_OK;
}
#endif
class DecorThemesAddon : public ThemesAddon {
public:
DecorThemesAddon();
@ -95,6 +123,7 @@ status_t DecorThemesAddon::ApplyTheme(BMessage &theme, uint32 flags)
BMessage window_decor;
BMessage globals;
BString decorName;
int32 decorId = R5_DECOR_BEOS;
status_t err;
if (!(flags & UI_THEME_SETTINGS_SET_ALL) || !(AddonFlags() & Z_THEME_ADDON_DO_SET_ALL))
@ -105,14 +134,123 @@ status_t DecorThemesAddon::ApplyTheme(BMessage &theme, uint32 flags)
return err;
#ifdef B_BEOS_VERSION_DANO
if (window_decor.FindString("window:decor", &decorName) == B_OK)
set_window_decor(decorName.String(),
bool decorDone = false;
// try each name until one works
for (int i = 0; window_decor.FindString("window:decor", i, &decorName) == B_OK; i++) {
err = set_window_decor_safe(decorName.String(),
(window_decor.FindMessage("window:decor_globals", &globals) == B_OK)?&globals:NULL);
if (err < B_OK)
continue;
decorDone = true;
break;
}
// none match but we did have one, force the default with the globals
if (!decorDone && decorName.Length()) {
decorDone = true;
set_window_decor_safe(decorName.String(),
(window_decor.FindMessage("window:decor_globals", &globals) == B_OK)?&globals:NULL);
}
// none... maybe R5 number ?
if (!decorDone &&
window_decor.FindInt32("window:R5:decor", &decorId) == B_OK) {
switch (decorId) {
case R5_DECOR_BEOS:
default:
err = set_window_decor_safe("R5", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("BeOS", NULL);
if (err >= B_OK)
break;
set_window_decor("R5", NULL);
break;
case R5_DECOR_WIN95:
err = set_window_decor_safe("Win2k", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("Redmond", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("Seattle", NULL);
if (err >= B_OK)
break;
set_window_decor("R5", NULL);
break;
case R5_DECOR_AMIGA:
err = set_window_decor_safe("Amiga", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("AmigaOS", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("AmigaOS4", NULL);
if (err >= B_OK)
break;
set_window_decor("R5", NULL);
break;
case R5_DECOR_MAC:
err = set_window_decor_safe("Mac", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("MacOS", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("Baqua", NULL);
if (err >= B_OK)
break;
err = set_window_decor_safe("Cupertino", NULL);
if (err >= B_OK)
break;
set_window_decor("R5", NULL);
break;
}
decorDone = true;
}
// it might be intentionally there is none...
//if (!decorDone)
// set_window_decor("Default", NULL);
#else
// best effort with what we have
extern void __set_window_decor(int32 theme);
int32 decorNr = 0;
if (window_decor.FindInt32("window:R5:decor", &decorNr) == B_OK)
__set_window_decor(decorNr);
if (window_decor.FindInt32("window:R5:decor", &decorId) == B_OK)
__set_window_decor(decorId);
else {
BString name;
for (int i = 0; window_decor.FindString("window:decor", i, &decorName) == B_OK; i++) {
if (decorName.IFindFirst("R5") > -1 ||
decorName.IFindFirst("BeOS") > -1 ||
decorName.IFindFirst("Be") > -1 ||
decorName.IFindFirst("yellow") > -1 ||
decorName.IFindFirst("Menlo") > -1 ||
decorName.IFindFirst("Default") > -1 ||
decorName.IFindFirst("Origin") > -1) {
__set_window_decor(R5_DECOR_BEOS);
break;
}
if (decorName.IFindFirst("Microsoft") > -1 ||
decorName.IFindFirst("2k") > -1 ||
decorName.IFindFirst("XP") > -1 ||
decorName.IFindFirst("Redmond") > -1 ||
decorName.IFindFirst("Seattle") > -1 ||
decorName.IFindFirst("Win") > -1) {
__set_window_decor(R5_DECOR_WIN95);
break;
}
if (decorName.IFindFirst("Amiga") > -1 ||
decorName.IFindFirst("OS4") > -1) {
__set_window_decor(R5_DECOR_AMIGA);
break;
}
if (decorName.IFindFirst("Mac") > -1 ||
decorName.IFindFirst("Apple") > -1 ||
decorName.IFindFirst("Aqua") > -1 ||
decorName.IFindFirst("Cupertino") > -1 ||
decorName.IFindFirst("OSX") > -1) {
__set_window_decor(R5_DECOR_MAC);
break;
}
}
}
#endif
// XXX: add colors à la WindowShade ?

View File

@ -122,6 +122,8 @@ status_t DecorThemesAddon::ApplyTheme(BMessage &theme, uint32 flags)
BMessage window_decor;
BMessage globals;
BString decorName;
int32 decorId;
bool decorDone = false;
status_t err;
if (!(flags & UI_THEME_SETTINGS_SET_ALL) || !(AddonFlags() & Z_THEME_ADDON_DO_SET_ALL))
@ -132,8 +134,33 @@ status_t DecorThemesAddon::ApplyTheme(BMessage &theme, uint32 flags)
if (err)
return err;
if (window_decor.FindString("window:decor", &decorName) == B_OK)
set_decorator(decorName.String());
// try each name until one works
for (int i = 0; window_decor.FindString("window:decor", i, &decorName) == B_OK; i++) {
if (set_decorator(decorName.String()) == B_OK) {
decorDone = true;
break;
}
}
// none... maybe R5 number ?
if (!decorDone &&
window_decor.FindInt32("window:R5:decor", &decorId) == B_OK) {
int32 defaultDecor = 0; // XXX ?
switch (decorId) {
case R5_DECOR_BEOS:
default:
set_decorator(defaultDecor);
break;
case R5_DECOR_WIN95:
set_decorator("WinDecorator");
break;
case R5_DECOR_AMIGA:
set_decorator("AmigaDecorator");
break;
case R5_DECOR_MAC:
set_decorator("MacDecorator");
break;
}
}
#if 0
#ifdef B_BEOS_VERSION_DANO
if (window_decor.FindString("window:decor", &decorName) == B_OK)

View File

@ -177,10 +177,11 @@ status_t SoundsThemesAddon::MakeTheme(BMessage &theme, uint32 flags)
//printf("\t%s: %s\n", item.String(), path.Path());
if (path.Path()) {
msg.AddString("sounds:file", path.Path());
gain = 1.0;
#if defined(__HAIKU__) || defined(B_BEOS_VERSION_DANO)
if (bmfs.GetAudioGainFor(BMediaFiles::B_SOUNDS, item.String(), &gain) >= B_OK)
msg.AddFloat("sounds:volume", gain);
bmfs.GetAudioGainFor(BMediaFiles::B_SOUNDS, item.String(), &gain);
#endif
msg.AddFloat("sounds:volume", gain);
}
sounds.AddMessage(item.String(), &msg);
}