haiku/3rdparty/mmu_man/themes/addons/TerminalAddon.cpp
François Revol d2a702e4c6 Also send prefs to running Haiku terminals, but they must be fixed to handle that.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23696 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-21 21:15:22 +00:00

328 lines
8.8 KiB
C++

/*
* BeIDE Color ThemesAddon class
*/
#include <Alert.h>
#include <Directory.h>
#include <Message.h>
#include <Messenger.h>
#include <Font.h>
#include <String.h>
#include <Roster.h>
#include <storage/Path.h>
#include <storage/File.h>
#include <storage/NodeInfo.h>
#include <storage/FindDirectory.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "ThemesAddon.h"
#include "UITheme.h"
#include "Utils.h"
#ifdef SINGLE_BINARY
#define instanciate_themes_addon instanciate_themes_addon_terminal
#endif
#define A_NAME "Terminal"
#define A_MSGNAME Z_THEME_TERMINAL_SETTINGS
#define A_DESCRIPTION "Terminal color, font and size"
#define TP_MAGIC 0xf1f2f3f4
#define TP_VERSION 0x02
#define TP_FONT_NAME_SZ 128
// __PACKED
struct tpref {
uint32 cols;
uint32 rows;
uint32 tab_width;
uint32 font_size;
char font[TP_FONT_NAME_SZ]; // "Family/Style"
uint32 cursor_blink_rate; // blinktime in µs = 1000000
uint32 refresh_rate; // ??? = 0
rgb_color bg;
rgb_color fg;
rgb_color curbg;
rgb_color curfg;
rgb_color selbg;
rgb_color selfg;
char encoding; // index in the menu (0 = UTF-8)
char unknown[3];
}; /* this is what is sent to the Terminal window... actually not ! It's sent by Terminal to itself. */
struct termprefs {
uint32 magic;
uint32 version;
float x;
float y;
struct tpref p;
};
#define TP_COLS "term:cols"
#define TP_ROWS "term:rows"
#define TP_TABWIDTH "term:tab"
#define TP_FONT "term:font"
#define TP_BG "term:c:bg"
#define TP_FG "term:c:fg"
#define TP_CURBG "term:c:curbg"
#define TP_CURFG "term:c:curfg"
#define TP_SELBG "term:c:selbg"
#define TP_SELFG "term:c:selfg"
#define TP_ENCODING "term:encoding"
static const char *kHaikuTerminalAppSig = "application/x-vnd.Haiku-Terminal";
static const char *kBeOSTerminalAppSig = "application/x-vnd.Be-SHEL";
class TerminalThemesAddon : public ThemesAddon {
public:
TerminalThemesAddon();
~TerminalThemesAddon();
const char *Description();
status_t RunPreferencesPanel();
status_t AddNames(BMessage &names);
status_t ApplyTheme(BMessage &theme, uint32 flags=0L);
status_t MakeTheme(BMessage &theme, uint32 flags=0L);
status_t ApplyDefaultTheme(uint32 flags=0L);
/* Theme installation */
status_t InstallFiles(BMessage &theme, BDirectory &folder);
status_t BackupFiles(BMessage &theme, BDirectory &folder);
};
TerminalThemesAddon::TerminalThemesAddon()
: ThemesAddon(A_NAME, A_MSGNAME)
{
}
TerminalThemesAddon::~TerminalThemesAddon()
{
}
const char *TerminalThemesAddon::Description()
{
return A_DESCRIPTION;
}
status_t TerminalThemesAddon::RunPreferencesPanel()
{
BAlert *alert;
alert = new BAlert("info", "Please use the Settings menu in the Terminal application.", "Gotcha");
alert->Go();
return B_OK;
}
status_t TerminalThemesAddon::AddNames(BMessage &names)
{
names.AddString(Z_THEME_TERMINAL_SETTINGS, "Terminal Preferences");
names.AddString(TP_COLS, "Terminal column count");
names.AddString(TP_ROWS, "Terminal row count");
names.AddString(TP_TABWIDTH, "Terminal tab width");
names.AddString(TP_FONT, "Terminal font");
names.AddString(TP_BG, "Terminal background color");
names.AddString(TP_FG, "Terminal foreground color");
names.AddString(TP_CURBG, "Terminal cursor background color");
names.AddString(TP_CURFG, "Terminal cursor foreground color");
names.AddString(TP_SELBG, "Terminal selection background color");
names.AddString(TP_SELFG, "Terminal selection foreground color");
names.AddString(TP_ENCODING, "Terminal text encoding");
return B_OK;
}
status_t TerminalThemesAddon::ApplyTheme(BMessage &theme, uint32 flags)
{
BMessage termpref;
status_t err;
struct termprefs tp;
(void)flags;
err = MyMessage(theme, termpref);
if (err)
return err;
tp.magic = TP_MAGIC;
tp.version = TP_VERSION;
tp.x = 0; // don't open at specific coords
tp.y = 0;
if (termpref.FindInt32(TP_COLS, (int32 *)&tp.p.cols) != B_OK)
tp.p.cols = 80;
if (termpref.FindInt32(TP_ROWS, (int32 *)&tp.p.rows) != B_OK)
tp.p.rows = 25;
if (termpref.FindInt32(TP_TABWIDTH, (int32 *)&tp.p.tab_width) != B_OK)
tp.p.tab_width = 8;
BFont tFont;
tp.p.font_size = 12;
strcpy(tp.p.font, "Courier10 BT/Roman");
if (FindFont(termpref, TP_FONT, 0, &tFont) == B_OK) {
font_family ff;
font_style fs;
tFont.GetFamilyAndStyle(&ff, &fs);
strcpy(tp.p.font, ff);
strcat(tp.p.font, "/");
strcat(tp.p.font, fs);
tp.p.font_size = (uint32)tFont.Size();
}
tp.p.cursor_blink_rate = 1000000;
tp.p.refresh_rate = 0;
if (FindRGBColor(termpref, TP_BG, 0, &tp.p.bg) != B_OK)
tp.p.bg = make_color(255,255,255,255);
if (FindRGBColor(termpref, TP_FG, 0, &tp.p.fg) != B_OK)
tp.p.fg = make_color(0,0,0,255);
if (FindRGBColor(termpref, TP_CURBG, 0, &tp.p.curbg) != B_OK)
tp.p.curbg = make_color(255,255,255,255);
if (FindRGBColor(termpref, TP_CURFG, 0, &tp.p.curfg) != B_OK)
tp.p.curfg = make_color(0,0,0,255);
if (FindRGBColor(termpref, TP_SELBG, 0, &tp.p.selbg) != B_OK)
tp.p.selbg = make_color(0,0,0,255);
if (FindRGBColor(termpref, TP_SELFG, 0, &tp.p.selfg) != B_OK)
tp.p.selfg = make_color(255,255,255,255);
if (termpref.FindInt32(TP_ENCODING, (int32 *)&tp.p.encoding) != B_OK)
tp.p.encoding = 0; // UTF-8
if (true/*flags & UI_THEME_SETTINGS_SAVE*/) {
BPath pTermPref;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &pTermPref) < B_OK)
return EINVAL;
pTermPref.Append("Terminal");
BFile fTermPref(pTermPref.Path(), B_WRITE_ONLY|B_CREATE_FILE|B_ERASE_FILE);
if (fTermPref.InitCheck() != B_OK) {
return fTermPref.InitCheck();
}
fTermPref.Write(&tp, sizeof(struct termprefs));
BNodeInfo ni(&fTermPref);
if (ni.InitCheck() == B_OK)
ni.SetType("application/x-vnd.Be-pref");
}
if (true/*flags & UI_THEME_SETTINGS_APPLY*/) {
BList teamList;
app_info ainfo;
int32 count, i;
be_roster->GetAppList(&teamList);
count = teamList.CountItems();
for (i = 0; i < count; i++) {
if (be_roster->GetRunningAppInfo((team_id)(teamList.ItemAt(i)), &ainfo) == B_OK) {
if (!strcmp(ainfo.signature, kBeOSTerminalAppSig) || !strcmp(ainfo.signature, kHaikuTerminalAppSig)) {
err = B_OK;
BMessage msg('pref');
BMessenger msgr(NULL, ainfo.team);
tp.x = 0;
tp.y = 0;
//msg.AddData("", 'UBYT', &(tp.p), sizeof(struct tpref));
msg.AddData("", 'UBYT', &(tp), sizeof(struct termprefs));
msg.AddSpecifier("Window", 0L);
err = msgr.SendMessage(&msg);
}
}
}
}
return B_OK;
}
status_t TerminalThemesAddon::MakeTheme(BMessage &theme, uint32 flags)
{
BMessage termpref;
status_t err;
struct termprefs tp;
BPath pTermPref;
(void)flags;
err = MyMessage(theme, termpref);
if (err)
termpref.MakeEmpty();
if (find_directory(B_USER_SETTINGS_DIRECTORY, &pTermPref) < B_OK)
return EINVAL;
pTermPref.Append("Terminal");
BFile fTermPref(pTermPref.Path(), B_READ_ONLY);
if (fTermPref.InitCheck() != B_OK)
return fTermPref.InitCheck();
if (fTermPref.Read(&tp, sizeof(struct termprefs)) < (ssize_t)sizeof(struct termprefs))
return EIO;
if ((tp.magic != TP_MAGIC) || (tp.version != TP_VERSION))
return EINVAL;
termpref.AddInt32(TP_COLS, tp.p.cols);
termpref.AddInt32(TP_ROWS, tp.p.rows);
termpref.AddInt32(TP_TABWIDTH, tp.p.tab_width);
BFont tFont;
font_family ff;
font_style fs;
BString str(tp.p.font);
str.Truncate(str.FindFirst('/'));
strncpy(ff, str.String(), sizeof(ff));
str.SetTo(tp.p.font);
str.Remove(0, str.FindFirst('/')+1);
strncpy(fs, str.String(), sizeof(fs));
tFont.SetFamilyAndStyle(ff, fs);
tFont.SetSize(tp.p.font_size);
AddFont(termpref, TP_FONT, &tFont);
AddRGBColor(termpref, TP_BG, tp.p.bg);
AddRGBColor(termpref, TP_FG, tp.p.fg);
AddRGBColor(termpref, TP_CURBG, tp.p.curbg);
AddRGBColor(termpref, TP_CURFG, tp.p.curfg);
AddRGBColor(termpref, TP_SELBG, tp.p.selbg);
AddRGBColor(termpref, TP_SELFG, tp.p.selfg);
termpref.AddInt32(TP_ENCODING, tp.p.encoding);
err = SetMyMessage(theme, termpref);
return B_OK;
}
status_t TerminalThemesAddon::ApplyDefaultTheme(uint32 flags)
{
BMessage theme;
BMessage termpref;
AddRGBColor(termpref, "term:c:bg",make_color(255,255,255,0));
AddRGBColor(termpref, "term:c:fg",make_color(0,0,0,0));
AddRGBColor(termpref, "term:c:curbg",make_color(0,0,0,0));
AddRGBColor(termpref, "term:c:curfg",make_color(255,255,255,0));
AddRGBColor(termpref, "term:c:selbg",make_color(0,0,0,0));
AddRGBColor(termpref, "term:c:selfg",make_color(255,255,255,0));
theme.AddMessage(Z_THEME_TERMINAL_SETTINGS, &termpref);
return ApplyTheme(theme, flags);
}
status_t TerminalThemesAddon::InstallFiles(BMessage &theme, BDirectory &folder)
{
BMessage termpref;
status_t err;
(void)folder;
err = MyMessage(theme, termpref);
if (err)
termpref.MakeEmpty();
return B_OK;
}
status_t TerminalThemesAddon::BackupFiles(BMessage &theme, BDirectory &folder)
{
BMessage termpref;
status_t err;
(void)folder;
err = MyMessage(theme, termpref);
if (err)
termpref.MakeEmpty();
entry_ref ref;
//find_font_file(&ref, ff, fs);
return B_OK;
}
ThemesAddon *instanciate_themes_addon()
{
return (ThemesAddon *) new TerminalThemesAddon;
}