Generalize protocol settings' GUI templating

A nice templating system is used for account settings dialogues― the
required slots are specified by the protocol, and are reflected in the
settings dialogue.

To generalize this templating system (and eventually use elsewhere),
ProtocolSettings was split into two classes― ProtocolSettings and
ProtocolTemplate.

The CayaProtocol::SettingsTemplate() call was also edited to require a
string parameter, naming the specific template that should be returned.

"account" is used for the account settings dialogue, and other values
are TBA.
This commit is contained in:
Jaidyn Ann 2021-06-17 16:51:37 -05:00
parent 9eaeac24e6
commit 3fbe072d42
13 changed files with 398 additions and 322 deletions

View File

@ -38,8 +38,10 @@ public:
//! Change settings
virtual status_t UpdateSettings(BMessage*) = 0;
//! Settings menu template
virtual BMessage SettingsTemplate() = 0;
//! Return a settings template
// Currently there are two: "account" (used when creating/editing
// the user's account) and "room" (used when creating a room).
virtual BMessage SettingsTemplate(const char* name) = 0;
//! Protocol signature
virtual const char* Signature() const = 0;

View File

@ -47,6 +47,7 @@ SRCS = \
application/ProtocolLooper.cpp \
application/ProtocolManager.cpp \
application/ProtocolSettings.cpp \
application/ProtocolTemplate.cpp \
application/Server.cpp \
application/TheApp.cpp \
application/User.cpp \

View File

@ -1,58 +1,31 @@
/*
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Copyright 2003-2009, IM Kit Team. All rights reserved.
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Davidson, slaad@bong.com.au
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
* Jaidyn Levesque, jadedctrl@teknik.io
*/
#include <stdio.h>
#include <stdlib.h>
#include "ProtocolSettings.h"
#include <CheckBox.h>
#include <Directory.h>
#include <File.h>
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <Menu.h>
#include <MenuItem.h>
#include <MenuField.h>
#include <Message.h>
#include <ObjectList.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <Resources.h>
#include <ScrollView.h>
#include <StringView.h>
#include <TextControl.h>
#include <TextView.h>
#include <TypeConstants.h>
#include <libinterface/NotifyingTextView.h>
#include "CayaProtocolAddOn.h"
#include "CayaResources.h"
#include "CayaUtils.h"
#include "ProtocolManager.h"
#include "ProtocolSettings.h"
const float kDividerWidth = 1.0f;
ProtocolSettings::ProtocolSettings(CayaProtocolAddOn* addOn)
:
fAddOn(addOn),
fTemplate(new BMessage())
fTemplate(addOn, "account")
{
_Init();
}
ProtocolSettings::~ProtocolSettings()
{
delete fTemplate;
}
@ -66,7 +39,7 @@ ProtocolSettings::InitCheck() const
CayaProtocolAddOn*
ProtocolSettings::AddOn() const
{
return fAddOn;
return fTemplate.AddOn();
}
@ -75,7 +48,9 @@ ProtocolSettings::Accounts() const
{
BObjectList<BString> list(true);
BPath path(CayaAccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
BPath path(CayaAccountPath(AddOn()->Signature(),
AddOn()->ProtoSignature()));
if (path.InitCheck() != B_OK)
return list;
@ -91,24 +66,13 @@ ProtocolSettings::Accounts() const
list.AddItem(new BString(buffer));
}
}
return list;
}
status_t
ProtocolSettings::LoadTemplate(BView* parent)
{
return Load(NULL, parent);
}
status_t
ProtocolSettings::Load(const char* account, BView* parent)
{
if (!parent)
debugger("Couldn't build protocol's settings GUI on a NULL parent!");
BMessage* settings = NULL;
if (account) {
@ -116,169 +80,7 @@ ProtocolSettings::Load(const char* account, BView* parent)
if (ret != B_OK)
return ret;
}
BMessage curr;
float inset = ceilf(be_plain_font->Size() * 0.7f);
// Setup layout
parent->SetLayout(new BGroupLayout(B_VERTICAL));
BGroupLayoutBuilder layout(B_VERTICAL, inset);
for (int32 i = 0; fTemplate->FindMessage("setting", i, &curr) == B_OK; i++) {
char temp[512];
// Get stuff from settings template
const char* name = curr.FindString("name");
const char* desc = curr.FindString("description");
const char* value = NULL;
int32 type = -1;
bool secret = false;
bool freeText = true;
bool multiLine = false;
BView* control = NULL;
BMenu* menu = NULL;
// Ignore settings with errors
if (curr.FindInt32("type", &type) != B_OK)
continue;
switch (type) {
case B_STRING_TYPE: {
if (curr.FindString("valid_value")) {
// It's a "select one of these" setting
freeText = false;
menu = new BPopUpMenu(name);
for (int j = 0; curr.FindString("valid_value", j); j++) {
BMenuItem* item
= new BMenuItem(curr.FindString("valid_value", j),
NULL);
menu->AddItem(item);
}
if (settings)
value = settings->FindString(name);
if (value)
menu->FindItem(value)->SetMarked(true);
} else {
// It's a free-text setting
if (curr.FindBool("multi_line", &multiLine) != B_OK)
multiLine = false;
if (settings)
value = settings->FindString(name);
if (!value)
value = curr.FindString("default");
if (curr.FindBool("is_secret",&secret) != B_OK)
secret = false;
}
break;
}
case B_INT32_TYPE: {
if (curr.FindInt32("valid_value")) {
// It's a "select one of these" setting
freeText = false;
menu = new BPopUpMenu(name);
int32 def = 0;
status_t hasValue = B_ERROR;
if (settings)
settings->FindInt32(name, 0, &def);
if (hasValue != B_OK)
hasValue = curr.FindInt32("default", 0, &def);
int32 v = 0;
for (int32 j = 0; curr.FindInt32("valid_value", j, &v) == B_OK; j++) {
sprintf(temp, "%ld", v);
BMenuItem* item = new BMenuItem(temp, NULL);
if (hasValue != B_OK && j == 0)
item->SetMarked(true);
else if ((hasValue == B_OK) && (def == v))
item->SetMarked(true);
menu->AddItem(item);
}
} else {
// It's a free-text (but number) setting
int32 v = 0;
if (settings && settings->FindInt32(name, &v) == B_OK) {
sprintf(temp,"%ld", v);
value = temp;
} else if (curr.FindInt32("default", &v) == B_OK) {
sprintf(temp,"%ld", v);
value = temp;
}
if (curr.FindBool("is_secret",&secret) != B_OK)
secret = false;
}
break;
}
case B_BOOL_TYPE: {
bool active;
if (settings && settings->FindBool(name, &active) != B_OK) {
if (curr.FindBool("default", &active) != B_OK)
active = false;
}
control = new BCheckBox(name, desc, NULL);
if (active)
dynamic_cast<BCheckBox*>(control)->SetValue(B_CONTROL_ON);
break;
}
default:
continue;
}
if (!value)
value = "";
if (!control) {
if (freeText) {
if (!multiLine) {
control = new BTextControl(name, desc, value, NULL);
if (secret) {
dynamic_cast<BTextControl*>(control)->TextView()->HideTyping(true);
dynamic_cast<BTextControl*>(control)->SetText(value);
}
dynamic_cast<BTextControl*>(control)->SetDivider(
kDividerWidth);
} else {
BStringView* label = new BStringView("NA", desc,
B_WILL_DRAW);
layout.Add(label);
NotifyingTextView* textView
= new NotifyingTextView(name);
control = new BScrollView("NA", textView, 0, false, true);
textView->SetText(value);
}
} else {
control = new BMenuField(name, desc, menu);
dynamic_cast<BMenuField*>(control)->SetDivider(kDividerWidth);
}
}
#if 0
if (curr.FindString("help"))
gHelper.SetHelp(control, strdup(curr.FindString("help")));
#endif
layout.Add(control);
}
layout.AddGlue();
parent->AddChild(layout);
return B_OK;
return fTemplate.Load(parent, settings);
}
@ -288,70 +90,24 @@ ProtocolSettings::Save(const char* account, BView* parent)
if (!parent)
debugger("Couldn't save protocol's settings GUI on a NULL parent!");
BMessage* settings = new BMessage();
BMessage* settings = fTemplate.Save(parent);
BMessage cur;
for (int32 i = 0; fTemplate->FindMessage("setting", i, &cur) == B_OK; i++) {
const char* name = cur.FindString("name");
if (!account || !settings)
return B_BAD_VALUE;
// Skip NULL names
if (!name)
continue;
status_t ret = B_ERROR;
int32 type = -1;
if (cur.FindInt32("type", &type) != B_OK)
continue;
// Find user's settings path
BPath path(CayaAccountPath(AddOn()->Signature(),
AddOn()->ProtoSignature()));
BView* view = parent->FindView(name);
if (!view)
continue;
if ((ret = path.InitCheck()) != B_OK)
return ret;
BTextControl* textControl
= dynamic_cast<BTextControl*>(view);
if (textControl) {
switch (type) {
case B_STRING_TYPE:
settings->AddString(name, textControl->Text());
break;
case B_INT32_TYPE:
settings->AddInt32(name, atoi(textControl->Text()));
break;
default:
return B_ERROR;
}
}
BMenuField* menuField
= dynamic_cast<BMenuField*>(view);
if (menuField) {
BMenuItem* item = menuField->Menu()->FindMarked();
if (!item)
return B_ERROR;
switch (type) {
case B_STRING_TYPE:
settings->AddString(name, item->Label());
break;
case B_INT32_TYPE:
settings->AddInt32(name, atoi(item->Label()));
break;
default:
return B_ERROR;
}
}
BCheckBox* checkBox
= dynamic_cast<BCheckBox*>(view);
if (checkBox)
settings->AddBool(name, (checkBox->Value() == B_CONTROL_ON));
NotifyingTextView* textView
= dynamic_cast<NotifyingTextView*>(view);
if (textView)
settings->AddString(name, textView->Text());
}
return _Save(account, settings);
// Load settings file
path.Append(account);
BFile file(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
return settings->Flatten(&file);
}
@ -361,7 +117,9 @@ ProtocolSettings::Rename(const char* from, const char* to)
status_t ret = B_ERROR;
// Find user's settings path
BPath path(CayaAccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
BPath path(CayaAccountPath(AddOn()->Signature(),
AddOn()->ProtoSignature()));
if ((ret = path.InitCheck()) != B_OK)
return ret;
@ -382,7 +140,9 @@ ProtocolSettings::Delete(const char* account)
status_t ret = B_ERROR;
// Find user's settings path
BPath path(CayaAccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
BPath path(CayaAccountPath(AddOn()->Signature(),
AddOn()->ProtoSignature()));
if ((ret = path.InitCheck()) != B_OK)
return ret;
@ -397,15 +157,6 @@ ProtocolSettings::Delete(const char* account)
}
void
ProtocolSettings::_Init()
{
// Load protocol's settings template
BMessage settingsTemplate = fAddOn->Protocol()->SettingsTemplate();
*fTemplate = settingsTemplate;
}
status_t
ProtocolSettings::_Load(const char* account, BMessage** settings)
{
@ -417,7 +168,9 @@ ProtocolSettings::_Load(const char* account, BMessage** settings)
status_t ret = B_ERROR;
// Find user's settings path
BPath path(CayaAccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
BPath path(CayaAccountPath(AddOn()->Signature(),
AddOn()->ProtoSignature()));
if ((ret = path.InitCheck()) != B_OK)
return ret;
@ -429,23 +182,3 @@ ProtocolSettings::_Load(const char* account, BMessage** settings)
*settings = msg;
return ret;
}
status_t
ProtocolSettings::_Save(const char* account, BMessage* settings)
{
if (!account || !settings)
return B_BAD_VALUE;
status_t ret = B_ERROR;
// Find user's settings path
BPath path(CayaAccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
if ((ret = path.InitCheck()) != B_OK)
return ret;
// Load settings file
path.Append(account);
BFile file(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
return settings->Flatten(&file);
}

View File

@ -1,12 +1,16 @@
/*
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Copyright 2003-2009, IM Kit Team. All rights reserved.
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _PROTOCOL_SETTINGS_H
#define _PROTOCOL_SETTINGS_H
#include <ObjectList.h>
#include <String.h>
#include "ProtocolTemplate.h"
class BMessage;
class CayaProtocolAddOn;
@ -14,14 +18,12 @@ class CayaProtocolAddOn;
class ProtocolSettings {
public:
ProtocolSettings(CayaProtocolAddOn* addOn);
~ProtocolSettings();
status_t InitCheck() const;
CayaProtocolAddOn* AddOn() const;
BObjectList<BString> Accounts() const;
status_t LoadTemplate(BView* parent);
status_t Load(const char* account, BView* parent);
status_t Save(const char* account, BView* parent);
@ -29,14 +31,10 @@ public:
status_t Delete(const char* account);
private:
status_t fStatus;
CayaProtocolAddOn* fAddOn;
BString fAccount;
BMessage* fTemplate;
void _Init();
status_t _Load(const char* account, BMessage** settings);
status_t _Save(const char* account, BMessage* settings);
ProtocolTemplate fTemplate;
status_t fStatus;
};
#endif // _PROTOCOL_SETTINGS_H

View File

@ -0,0 +1,300 @@
/*
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Copyright 2003-2009, IM Kit Team. All rights reserved.
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Davidson, slaad@bong.com.au
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
* Jaidyn Levesque, jadedctrl@teknik.io
*/
#include "ProtocolTemplate.h"
#include <cstdio>
#include <CheckBox.h>
#include <GroupLayoutBuilder.h>
#include <MenuItem.h>
#include <MenuField.h>
#include <PopUpMenu.h>
#include <ScrollView.h>
#include <StringView.h>
#include <TextControl.h>
#include <libinterface/NotifyingTextView.h>
#include "CayaProtocol.h"
#include "CayaProtocolAddOn.h"
const float kDividerWidth = 1.0f;
ProtocolTemplate::ProtocolTemplate(CayaProtocolAddOn* addOn, const char* type)
:
fAddOn(addOn),
fTemplate(new BMessage())
{
// Load protocol's settings template
BMessage settingsTemplate = fAddOn->Protocol()->SettingsTemplate(type);
*fTemplate = settingsTemplate;
}
ProtocolTemplate::~ProtocolTemplate()
{
delete fTemplate;
}
CayaProtocolAddOn*
ProtocolTemplate::AddOn() const
{
return fAddOn;
}
status_t
ProtocolTemplate::Load(BView* parent, BMessage* settings)
{
if (!parent)
debugger("Couldn't build protocol's settings GUI on a NULL parent!");
BMessage curr;
float inset = ceilf(be_plain_font->Size() * 0.7f);
// Setup layout
parent->SetLayout(new BGroupLayout(B_VERTICAL));
BGroupLayoutBuilder layout(B_VERTICAL, inset);
for (int32 i = 0; fTemplate->FindMessage("setting", i, &curr) == B_OK; i++) {
char temp[512];
// Get stuff from settings template
const char* name = curr.FindString("name");
const char* desc = curr.FindString("description");
const char* value = NULL;
int32 type = -1;
bool secret = false;
bool freeText = true;
bool multiLine = false;
BView* control = NULL;
BMenu* menu = NULL;
// Ignore settings with errors
if (curr.FindInt32("type", &type) != B_OK)
continue;
switch (type) {
case B_STRING_TYPE: {
if (curr.FindString("valid_value")) {
// It's a "select one of these" setting
freeText = false;
menu = new BPopUpMenu(name);
for (int j = 0; curr.FindString("valid_value", j); j++) {
BMenuItem* item
= new BMenuItem(curr.FindString("valid_value", j),
NULL);
menu->AddItem(item);
}
if (settings)
value = settings->FindString(name);
if (value)
menu->FindItem(value)->SetMarked(true);
} else {
// It's a free-text setting
if (curr.FindBool("multi_line", &multiLine) != B_OK)
multiLine = false;
if (settings)
value = settings->FindString(name);
if (!value)
value = curr.FindString("default");
if (curr.FindBool("is_secret",&secret) != B_OK)
secret = false;
}
break;
}
case B_INT32_TYPE: {
if (curr.FindInt32("valid_value")) {
// It's a "select one of these" setting
freeText = false;
menu = new BPopUpMenu(name);
int32 def = 0;
status_t hasValue = B_ERROR;
if (settings)
settings->FindInt32(name, 0, &def);
if (hasValue != B_OK)
hasValue = curr.FindInt32("default", 0, &def);
int32 v = 0;
for (int32 j = 0; curr.FindInt32("valid_value", j, &v) == B_OK; j++) {
sprintf(temp, "%ld", v);
BMenuItem* item = new BMenuItem(temp, NULL);
if (hasValue != B_OK && j == 0)
item->SetMarked(true);
else if ((hasValue == B_OK) && (def == v))
item->SetMarked(true);
menu->AddItem(item);
}
} else {
// It's a free-text (but number) setting
int32 v = 0;
if (settings && settings->FindInt32(name, &v) == B_OK) {
sprintf(temp,"%ld", v);
value = temp;
} else if (curr.FindInt32("default", &v) == B_OK) {
sprintf(temp,"%ld", v);
value = temp;
}
if (curr.FindBool("is_secret",&secret) != B_OK)
secret = false;
}
break;
}
case B_BOOL_TYPE: {
bool active;
if (settings && settings->FindBool(name, &active) != B_OK) {
if (curr.FindBool("default", &active) != B_OK)
active = false;
}
control = new BCheckBox(name, desc, NULL);
if (active)
dynamic_cast<BCheckBox*>(control)->SetValue(B_CONTROL_ON);
break;
}
default:
continue;
}
if (!value)
value = "";
if (!control) {
if (freeText) {
if (!multiLine) {
control = new BTextControl(name, desc, value, NULL);
if (secret) {
dynamic_cast<BTextControl*>(control)->TextView()->HideTyping(true);
dynamic_cast<BTextControl*>(control)->SetText(value);
}
dynamic_cast<BTextControl*>(control)->SetDivider(
kDividerWidth);
} else {
BStringView* label = new BStringView("NA", desc,
B_WILL_DRAW);
layout.Add(label);
NotifyingTextView* textView
= new NotifyingTextView(name);
control = new BScrollView("NA", textView, 0, false, true);
textView->SetText(value);
}
} else {
control = new BMenuField(name, desc, menu);
dynamic_cast<BMenuField*>(control)->SetDivider(kDividerWidth);
}
}
#if 0
if (curr.FindString("help"))
gHelper.SetHelp(control, strdup(curr.FindString("help")));
#endif
layout.Add(control);
}
layout.AddGlue();
parent->AddChild(layout);
return B_OK;
}
BMessage*
ProtocolTemplate::Save(BView* parent)
{
if (!parent)
debugger("Couldn't save protocol's settings GUI on a NULL parent!");
BMessage* settings = new BMessage();
BMessage cur;
for (int32 i = 0; fTemplate->FindMessage("setting", i, &cur) == B_OK; i++) {
const char* name = cur.FindString("name");
// Skip NULL names
if (!name)
continue;
int32 type = -1;
if (cur.FindInt32("type", &type) != B_OK)
continue;
BView* view = parent->FindView(name);
if (!view)
continue;
BTextControl* textControl
= dynamic_cast<BTextControl*>(view);
if (textControl) {
switch (type) {
case B_STRING_TYPE:
settings->AddString(name, textControl->Text());
break;
case B_INT32_TYPE:
settings->AddInt32(name, atoi(textControl->Text()));
break;
default:
return NULL;
}
}
BMenuField* menuField
= dynamic_cast<BMenuField*>(view);
if (menuField) {
BMenuItem* item = menuField->Menu()->FindMarked();
if (!item)
return NULL;
switch (type) {
case B_STRING_TYPE:
settings->AddString(name, item->Label());
break;
case B_INT32_TYPE:
settings->AddInt32(name, atoi(item->Label()));
break;
default:
return NULL;
}
}
BCheckBox* checkBox
= dynamic_cast<BCheckBox*>(view);
if (checkBox)
settings->AddBool(name, (checkBox->Value() == B_CONTROL_ON));
NotifyingTextView* textView
= dynamic_cast<NotifyingTextView*>(view);
if (textView)
settings->AddString(name, textView->Text());
}
return settings;
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Copyright 2003-2009, IM Kit Team. All rights reserved.
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _PROTOCOL_TEMPLATE_H
#define _PROTOCOL_TEMPLATE_H
#include <SupportDefs.h>
class BMessage;
class BView;
class CayaProtocolAddOn;
class ProtocolTemplate {
public:
ProtocolTemplate(CayaProtocolAddOn* addOn,
const char* type);
~ProtocolTemplate();
status_t InitCheck() const;
CayaProtocolAddOn* AddOn() const;
status_t Load(BView* parent, BMessage* settings = NULL);
BMessage* Save(BView* parent);
private:
CayaProtocolAddOn* fAddOn;
BMessage* fTemplate;
};
#endif // _PROTOCOL_TEMPLATE_H

View File

@ -44,7 +44,7 @@ AccountDialog::AccountDialog(const char* title, ProtocolSettings* settings,
if (fAccount.Length() > 0)
fSettings->Load(fAccount.String(), fTop);
else
fSettings->LoadTemplate(fTop);
fSettings->Load(NULL, fTop);
BButton* cancel = new BButton("Cancel", new BMessage(kCancel));
BButton* ok = new BButton("OK", new BMessage(kOK));

View File

@ -47,9 +47,12 @@ FacebookProtocol::Icon() const
BMessage
FacebookProtocol::SettingsTemplate()
FacebookProtocol::SettingsTemplate(const char* name)
{
return JabberHandler::_SettingsTemplate("Username", false);
if (name == BString("account"))
return JabberHandler::_SettingsTemplate("Username", false);
else
return BMessage();
}

View File

@ -17,7 +17,7 @@ public:
virtual BBitmap* Icon() const;
virtual BMessage SettingsTemplate();
virtual BMessage SettingsTemplate(const char*);
virtual void OverrideSettings();
virtual BString ComposeJID() const;

View File

@ -47,17 +47,19 @@ GoogleTalkProtocol::Icon() const
BMessage
GoogleTalkProtocol::SettingsTemplate()
GoogleTalkProtocol::SettingsTemplate(const char* name)
{
return JabberHandler::_SettingsTemplate("Identifier", false);
if (name == BString("account"))
return JabberHandler::_SettingsTemplate("Identifier", false);
else
return BMessage();
}
void
GoogleTalkProtocol::OverrideSettings()
{
fServer = "talk.google.com";
fPort = 0;
fServer = "dismail.de";
}
@ -66,7 +68,7 @@ GoogleTalkProtocol::ComposeJID() const
{
BString jid(fUsername);
if (jid.FindLast("@") < 0)
jid << "@gmail.com";
jid << "@dismail.de";
jid << "/" << fResource;
return jid;
}

View File

@ -17,7 +17,7 @@ public:
virtual BBitmap* Icon() const;
virtual BMessage SettingsTemplate();
virtual BMessage SettingsTemplate(const char* name);
virtual void OverrideSettings();
virtual BString ComposeJID() const;

View File

@ -46,9 +46,12 @@ JabberProtocol::Icon() const
BMessage
JabberProtocol::SettingsTemplate()
JabberProtocol::SettingsTemplate(const char* name)
{
return JabberHandler::_SettingsTemplate("Jabber identifier", true);
if (name == BString("account"))
return JabberHandler::_SettingsTemplate("Jabber identifier", true);
else
return BMessage();
}

View File

@ -17,7 +17,7 @@ public:
virtual BBitmap* Icon() const;
virtual BMessage SettingsTemplate();
virtual BMessage SettingsTemplate(const char* name);
virtual void OverrideSettings();
virtual BString ComposeJID() const;