* Changed BLocaleRoster::GetLanguage() to a signature that makes more sense,
and looks more like the rest of the API. * Also, it will now return an appropriate error code if the language couldn't be allocated (anything else than B_OK is an improvement :-)). * Several changes in BLanguage: - GetName() now gets a BString reference, also - it now returns the name in its own language, ie. for German this would always be "deutsch", no matter the current language settings, and finally, - it now empties the string it gets before adding the name. - added GetTranslatedName() that behaves like the previous version. - added const where it made sense (ie. almost everywhere). - Code() now returns the code of the language only. - ID() now returns the full ID of this language, ie. including country, variant, and keywords if any. - added Country(), and Variant(). - renamed IsCountry() to IsCountrySpecific(). - added IsVariant(). * Cleaned up Language.h, minor cleanup in LocaleRoster.cpp. * Removed the whole move item logic from LanguageListView; while this was not only spaghetti code, it doesn't make much sense in the first place. * Instead of removing stuff from the left, and even worse, moving all countries for a language even if only one had been dragged, we now only mark the items that are already in the preferred list, and only those. * Fixed various mixups of FullList*() vs. *() methods that could lead to things like bug #5896. * Pressing the delete key in the preferred list view will now remove the language. * Moved LocaleWindow specific message constants to LocaleWindow.cpp; Locale.h is supposed to contain application wide constants. * The drop logic is now in LocaleWindow. * We now make sure that each base language can only be in the list once. * Lots of cleanup, even though I mostly replaced spaghettie code with different looking spaghettie code - still, I think things have slightly improved. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36727 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8da96bede1
commit
96eaa02e8f
@ -1,16 +1,14 @@
|
||||
/*
|
||||
** Copyright 2003, Haiku, Inc.
|
||||
** Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
* Copyright 2003-2010, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _LANGUAGE_H_
|
||||
#define _LANGUAGE_H_
|
||||
|
||||
|
||||
#include <LocaleStrings.h>
|
||||
#include <String.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <LocaleStrings.h>
|
||||
|
||||
|
||||
// We must not include the icu headers in there as it could mess up binary
|
||||
@ -28,29 +26,37 @@ enum script_direction {
|
||||
|
||||
|
||||
class BLanguage {
|
||||
public:
|
||||
~BLanguage();
|
||||
public:
|
||||
~BLanguage();
|
||||
|
||||
// language name, e.g. "english", "deutsch"
|
||||
status_t GetName(BString* name);
|
||||
// ISO-639 language code, e.g. "en", "de"
|
||||
const char* Code();
|
||||
bool IsCountry();
|
||||
status_t GetName(BString& name) const;
|
||||
status_t GetTranslatedName(BString& name) const;
|
||||
|
||||
uint8 Direction() const;
|
||||
// ISO-639 language code, e.g. "en", "de"
|
||||
const char* Code() const;
|
||||
const char* Country() const;
|
||||
const char* Variant() const;
|
||||
const char* ID() const;
|
||||
|
||||
// see definitions below
|
||||
const char *GetString(uint32 id) const;
|
||||
bool IsCountrySpecific() const;
|
||||
bool IsVariant() const;
|
||||
|
||||
private:
|
||||
friend class BLocaleRoster;
|
||||
uint8 Direction() const;
|
||||
|
||||
BLanguage(const char *language);
|
||||
void Default();
|
||||
// see definitions below
|
||||
const char* GetString(uint32 id) const;
|
||||
|
||||
char *fStrings[B_NUM_LANGUAGE_STRINGS];
|
||||
uint8 fDirection;
|
||||
icu_4_2::Locale* fICULocale;
|
||||
private:
|
||||
friend class BLocaleRoster;
|
||||
|
||||
BLanguage(const char *language);
|
||||
void Default();
|
||||
|
||||
private:
|
||||
char* fStrings[B_NUM_LANGUAGE_STRINGS];
|
||||
uint8 fDirection;
|
||||
icu_4_2::Locale* fICULocale;
|
||||
};
|
||||
|
||||
#endif /* _LANGUAGE_H_ */
|
||||
|
||||
#endif // _LANGUAGE_H_
|
||||
|
@ -1,3 +1,7 @@
|
||||
/*
|
||||
* Copyright 2003-2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef _LOCALE_ROSTER_H_
|
||||
#define _LOCALE_ROSTER_H_
|
||||
|
||||
@ -17,7 +21,7 @@ struct entry_ref;
|
||||
|
||||
namespace BPrivate {
|
||||
class EditableCatalog;
|
||||
};
|
||||
}
|
||||
|
||||
enum {
|
||||
B_LOCALE_CHANGED = '_LCC',
|
||||
@ -25,7 +29,6 @@ enum {
|
||||
|
||||
|
||||
class BLocaleRoster {
|
||||
|
||||
public:
|
||||
BLocaleRoster();
|
||||
~BLocaleRoster();
|
||||
@ -42,7 +45,8 @@ class BLocaleRoster {
|
||||
status_t GetDefaultCountry(BCountry **) const;
|
||||
void SetDefaultCountry(BCountry *) const;
|
||||
|
||||
status_t GetLanguage(BLanguage** language, BString languageCode) const;
|
||||
status_t GetLanguage(const char* languageCode,
|
||||
BLanguage** _language) const;
|
||||
|
||||
status_t GetPreferredLanguages(BMessage *) const;
|
||||
status_t SetPreferredLanguages(BMessage *);
|
||||
|
@ -80,10 +80,7 @@ static const char *gBuiltInStrings[] = {
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
BLanguage::BLanguage(const char *language)
|
||||
BLanguage::BLanguage(const char* language)
|
||||
:
|
||||
fDirection(B_LEFT_TO_RIGHT)
|
||||
{
|
||||
@ -123,10 +120,11 @@ BLanguage::Direction() const
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
const char*
|
||||
BLanguage::GetString(uint32 id) const
|
||||
{
|
||||
if (id < B_LANGUAGE_STRINGS_BASE || id > B_LANGUAGE_STRINGS_BASE + B_NUM_LANGUAGE_STRINGS)
|
||||
if (id < B_LANGUAGE_STRINGS_BASE
|
||||
|| id > B_LANGUAGE_STRINGS_BASE + B_NUM_LANGUAGE_STRINGS)
|
||||
return NULL;
|
||||
|
||||
return fStrings[id - B_LANGUAGE_STRINGS_BASE];
|
||||
@ -134,30 +132,84 @@ BLanguage::GetString(uint32 id) const
|
||||
|
||||
|
||||
status_t
|
||||
BLanguage::GetName(BString* name)
|
||||
BLanguage::GetName(BString& name) const
|
||||
{
|
||||
BMessage preferredLanguage;
|
||||
be_locale_roster->GetPreferredLanguages(&preferredLanguage);
|
||||
BString appLanguage;
|
||||
|
||||
preferredLanguage.FindString("language", 0, &appLanguage);
|
||||
|
||||
UnicodeString s;
|
||||
fICULocale->getDisplayName(Locale(appLanguage), s);
|
||||
BStringByteSink converter(name);
|
||||
s.toUTF8(converter);
|
||||
UnicodeString string;
|
||||
fICULocale->getDisplayName(*fICULocale, string);
|
||||
|
||||
name.Truncate(0);
|
||||
BStringByteSink converter(&name);
|
||||
string.toUTF8(converter);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BLanguage::GetTranslatedName(BString& name) const
|
||||
{
|
||||
BMessage preferredLanguage;
|
||||
be_locale_roster->GetPreferredLanguages(&preferredLanguage);
|
||||
|
||||
BString appLanguage;
|
||||
preferredLanguage.FindString("language", 0, &appLanguage);
|
||||
|
||||
UnicodeString string;
|
||||
fICULocale->getDisplayName(Locale(appLanguage), string);
|
||||
|
||||
name.Truncate(0);
|
||||
BStringByteSink converter(&name);
|
||||
string.toUTF8(converter);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BLanguage::Code()
|
||||
BLanguage::Code() const
|
||||
{
|
||||
return fICULocale->getLanguage();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BLanguage::IsCountry()
|
||||
const char*
|
||||
BLanguage::Country() const
|
||||
{
|
||||
return *(fICULocale->getCountry()) != '\0';
|
||||
const char* country = fICULocale->getCountry();
|
||||
if (country == NULL || country[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
return country;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BLanguage::Variant() const
|
||||
{
|
||||
const char* variant = fICULocale->getVariant();
|
||||
if (variant == NULL || variant[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BLanguage::ID() const
|
||||
{
|
||||
return fICULocale->getName();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BLanguage::IsCountrySpecific() const
|
||||
{
|
||||
return Country() != NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BLanguage::IsVariant() const
|
||||
{
|
||||
return Variant() != NULL;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2004, Haiku. All rights reserved.
|
||||
* Copyright 2003-2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -37,8 +37,35 @@
|
||||
#include <unicode/locid.h>
|
||||
|
||||
|
||||
/*
|
||||
* several attributes/resource-IDs used within the Locale Kit:
|
||||
*/
|
||||
static const char *kPriorityAttr = "ADDON:priority";
|
||||
|
||||
const char *BLocaleRoster::kCatLangAttr = "BEOS:LOCALE_LANGUAGE";
|
||||
// name of catalog language, lives in every catalog file
|
||||
const char *BLocaleRoster::kCatSigAttr = "BEOS:LOCALE_SIGNATURE";
|
||||
// catalog signature, lives in every catalog file
|
||||
const char *BLocaleRoster::kCatFingerprintAttr = "BEOS:LOCALE_FINGERPRINT";
|
||||
// catalog fingerprint, may live in catalog file
|
||||
|
||||
const char *BLocaleRoster::kCatManagerMimeType
|
||||
= "application/x-vnd.Be.locale.catalog-manager";
|
||||
// signature of catalog managing app
|
||||
const char *BLocaleRoster::kCatEditorMimeType
|
||||
= "application/x-vnd.Be.locale.catalog-editor";
|
||||
// signature of catalog editor app
|
||||
|
||||
const char *BLocaleRoster::kEmbeddedCatAttr = "BEOS:LOCALE_EMBEDDED_CATALOG";
|
||||
// attribute which contains flattened data of embedded catalog
|
||||
// this may live in an app- or add-on-file
|
||||
int32 BLocaleRoster::kEmbeddedCatResId = 0xCADA;
|
||||
// a unique value used to identify the resource (=> embedded CAtalog DAta)
|
||||
// which contains flattened data of embedded catalog.
|
||||
// this may live in an app- or add-on-file
|
||||
|
||||
|
||||
|
||||
typedef BCatalogAddOn *(*InstantiateCatalogFunc)(const char *name,
|
||||
const char *language, uint32 fingerprint);
|
||||
|
||||
@ -47,7 +74,7 @@ typedef BCatalogAddOn *(*CreateCatalogFunc)(const char *name,
|
||||
|
||||
typedef BCatalogAddOn *(*InstantiateEmbeddedCatalogFunc)(
|
||||
entry_ref *appOrAddOnRef);
|
||||
|
||||
|
||||
typedef status_t (*GetAvailableLanguagesFunc)(BMessage*, const char*,
|
||||
const char*, int32);
|
||||
|
||||
@ -211,7 +238,7 @@ RosterData::RosterData()
|
||||
Locale::setDefault(icuLocale,icuError);
|
||||
assert(icuError == U_ZERO_ERROR);
|
||||
fPreferredLanguages.RemoveName("language");
|
||||
for (int i = 0; settingsMessage.FindString("language", i,
|
||||
for (int i = 0; settingsMessage.FindString("language", i,
|
||||
&langName) == B_OK; i++) {
|
||||
fPreferredLanguages.AddString("language", langName);
|
||||
}
|
||||
@ -310,7 +337,7 @@ RosterData::InitializeCatalogAddOns()
|
||||
priority = -1;
|
||||
if (node.ReadAttr(kPriorityAttr, B_INT8_TYPE, 0,
|
||||
&priority, sizeof(int8)) <= 0) {
|
||||
// add-on has no priority-attribute yet, so we load it
|
||||
// add-on has no priority-attribute yet, so we load it
|
||||
// to fetch the priority from the corresponding
|
||||
// symbol...
|
||||
BString fullAddOnPath(addOnFolderName);
|
||||
@ -385,34 +412,9 @@ RosterData::CleanupCatalogAddOns()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* several attributes/resource-IDs used within the Locale Kit:
|
||||
*/
|
||||
const char *BLocaleRoster::kCatLangAttr = "BEOS:LOCALE_LANGUAGE";
|
||||
// name of catalog language, lives in every catalog file
|
||||
const char *BLocaleRoster::kCatSigAttr = "BEOS:LOCALE_SIGNATURE";
|
||||
// catalog signature, lives in every catalog file
|
||||
const char *BLocaleRoster::kCatFingerprintAttr = "BEOS:LOCALE_FINGERPRINT";
|
||||
// catalog fingerprint, may live in catalog file
|
||||
// #pragma mark - BLocaleRoster
|
||||
|
||||
const char *BLocaleRoster::kCatManagerMimeType
|
||||
= "application/x-vnd.Be.locale.catalog-manager";
|
||||
// signature of catalog managing app
|
||||
const char *BLocaleRoster::kCatEditorMimeType
|
||||
= "application/x-vnd.Be.locale.catalog-editor";
|
||||
// signature of catalog editor app
|
||||
|
||||
const char *BLocaleRoster::kEmbeddedCatAttr = "BEOS:LOCALE_EMBEDDED_CATALOG";
|
||||
// attribute which contains flattened data of embedded catalog
|
||||
// this may live in an app- or add-on-file
|
||||
int32 BLocaleRoster::kEmbeddedCatResId = 0xCADA;
|
||||
// a unique value used to identify the resource (=> embedded CAtalog DAta)
|
||||
// which contains flattened data of embedded catalog.
|
||||
// this may live in an app- or add-on-file
|
||||
|
||||
/*
|
||||
* BLocaleRoster, the exported interface to the locale roster data:
|
||||
*/
|
||||
BLocaleRoster::BLocaleRoster()
|
||||
{
|
||||
}
|
||||
@ -473,17 +475,23 @@ BLocaleRoster::GetDefaultCountry(BCountry **country) const
|
||||
|
||||
|
||||
status_t
|
||||
BLocaleRoster::GetLanguage(BLanguage **language, BString languageCode) const
|
||||
BLocaleRoster::GetLanguage(const char* languageCode,
|
||||
BLanguage** _language) const
|
||||
{
|
||||
if (!language)
|
||||
if (_language == NULL || languageCode == NULL || languageCode[0] == '\0')
|
||||
return B_BAD_VALUE;
|
||||
*language = new(std::nothrow) BLanguage(languageCode);
|
||||
|
||||
BLanguage* language = new(std::nothrow) BLanguage(languageCode);
|
||||
if (language == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
*_language = language;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BLocaleRoster::SetDefaultCountry(BCountry * newDefault) const
|
||||
BLocaleRoster::SetDefaultCountry(BCountry* newDefault) const
|
||||
{
|
||||
gRosterData.fCountryCodeName = newDefault->Code();
|
||||
newDefault->DateFormat(gRosterData.fCountryDateFormat, true);
|
||||
@ -491,7 +499,7 @@ BLocaleRoster::SetDefaultCountry(BCountry * newDefault) const
|
||||
|
||||
|
||||
status_t
|
||||
BLocaleRoster::GetPreferredLanguages(BMessage *languages) const
|
||||
BLocaleRoster::GetPreferredLanguages(BMessage* languages) const
|
||||
{
|
||||
if (!languages)
|
||||
return B_BAD_VALUE;
|
||||
@ -548,7 +556,7 @@ BLocaleRoster::GetInstalledCatalogs(BMessage * languageList, const char* sigPatt
|
||||
{
|
||||
if (languageList == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
||||
int32 count = gRosterData.fCatalogAddOnInfos.CountItems();
|
||||
for (int32 i = 0; i < count; ++i) {
|
||||
BCatalogAddOnInfo *info
|
||||
@ -556,11 +564,11 @@ BLocaleRoster::GetInstalledCatalogs(BMessage * languageList, const char* sigPatt
|
||||
|
||||
if (!info->MakeSureItsLoaded() || !info->fLanguagesFunc)
|
||||
continue;
|
||||
|
||||
|
||||
info->fLanguagesFunc(languageList, sigPattern, langPattern,
|
||||
fingerprint);
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -9,16 +9,15 @@ Preference Locale :
|
||||
Locale.cpp
|
||||
LocaleWindow.cpp
|
||||
TimeFormatSettingsView.cpp
|
||||
|
||||
: be liblocale.so $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) libicu-common.so
|
||||
libicu-data.so libshared.a
|
||||
: Locale.rdef
|
||||
;
|
||||
;
|
||||
|
||||
DoCatalogs Locale # application name
|
||||
: x-vnd.Haiku-Locale # app MIME signature
|
||||
: # sources to extract the keys from
|
||||
DoCatalogs Locale : x-vnd.Haiku-Locale :
|
||||
LanguageListView.cpp
|
||||
Locale.cpp
|
||||
LocaleWindow.cpp
|
||||
TimeFormatSettingsView.cpp
|
||||
;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
* Adrien Destugues <pulkomandy@gmail.com>
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
@ -17,31 +18,46 @@
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Country.h>
|
||||
|
||||
#include "Locale.h"
|
||||
#include <Catalog.h>
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
#define MAX_DRAG_HEIGHT 200.0
|
||||
#define ALPHA 170
|
||||
#define TEXT_OFFSET 5.0
|
||||
|
||||
#define TR_CONTEXT "LanguageListView"
|
||||
|
||||
|
||||
LanguageListItem::LanguageListItem(const char* text, const char* code)
|
||||
LanguageListItem::LanguageListItem(const char* text, const char* id,
|
||||
const char* code)
|
||||
:
|
||||
BStringItem(text),
|
||||
fLanguageCode(code)
|
||||
fID(id),
|
||||
fCode(code)
|
||||
{
|
||||
// TODO: should probably keep the BCountry as a member of the class
|
||||
BCountry myCountry(code);
|
||||
BRect bounds(0, 0, 15, 15);
|
||||
fIcon = new(std::nothrow) BBitmap(bounds, B_RGBA32);
|
||||
if (fIcon && myCountry.GetIcon(fIcon) != B_OK) {
|
||||
BCountry country(id);
|
||||
|
||||
fIcon = new(std::nothrow) BBitmap(BRect(0, 0, 15, 15), B_RGBA32);
|
||||
if (fIcon != NULL && country.GetIcon(fIcon) != B_OK) {
|
||||
delete fIcon;
|
||||
fIcon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LanguageListItem::LanguageListItem(const LanguageListItem& other)
|
||||
:
|
||||
BStringItem(other.Text()),
|
||||
fID(other.ID()),
|
||||
fCode(other.Code()),
|
||||
fIcon(NULL)
|
||||
{
|
||||
if (other.fIcon != NULL)
|
||||
fIcon = new BBitmap(*other.fIcon);
|
||||
}
|
||||
|
||||
|
||||
LanguageListItem::~LanguageListItem()
|
||||
{
|
||||
delete fIcon;
|
||||
@ -51,10 +67,8 @@ LanguageListItem::~LanguageListItem()
|
||||
void
|
||||
LanguageListItem::DrawItem(BView* owner, BRect frame, bool complete)
|
||||
{
|
||||
rgb_color kHighlight = { 140,140,140,0 };
|
||||
rgb_color kBlack = { 0,0,0,0 };
|
||||
|
||||
BRect r(frame);
|
||||
rgb_color kHighlight = {140, 140, 140, 0};
|
||||
rgb_color kBlack = {0, 0, 0, 0};
|
||||
|
||||
if (IsSelected() || complete) {
|
||||
rgb_color color;
|
||||
@ -64,33 +78,43 @@ LanguageListItem::DrawItem(BView* owner, BRect frame, bool complete)
|
||||
color = owner->ViewColor();
|
||||
owner->SetHighColor(color);
|
||||
owner->SetLowColor(color);
|
||||
owner->FillRect(r);
|
||||
owner->FillRect(frame);
|
||||
owner->SetHighColor(kBlack);
|
||||
} else
|
||||
owner->SetLowColor(owner->ViewColor());
|
||||
|
||||
frame.left += 4;
|
||||
BRect iconFrame(frame);
|
||||
iconFrame.Set(iconFrame.left, iconFrame.top+1, iconFrame.left+15,
|
||||
iconFrame.top+16);
|
||||
iconFrame.Set(iconFrame.left, iconFrame.top + 1, iconFrame.left + 15,
|
||||
iconFrame.top + 16);
|
||||
|
||||
if (fIcon && fIcon->IsValid()) {
|
||||
if (fIcon != NULL && fIcon->IsValid()) {
|
||||
owner->SetDrawingMode(B_OP_OVER);
|
||||
owner->DrawBitmap(fIcon, iconFrame);
|
||||
owner->SetDrawingMode(B_OP_COPY);
|
||||
}
|
||||
|
||||
frame.left += 16 * (OutlineLevel() + 1);
|
||||
owner->SetHighColor(kBlack);
|
||||
|
||||
BString text = Text();
|
||||
if (IsEnabled())
|
||||
owner->SetHighColor(kBlack);
|
||||
else {
|
||||
owner->SetHighColor(tint_color(owner->LowColor(), B_DARKEN_3_TINT));
|
||||
text += " (";
|
||||
text += B_TRANSLATE("already chosen");
|
||||
text += ")";
|
||||
}
|
||||
|
||||
BFont font = be_plain_font;
|
||||
font_height finfo;
|
||||
font.GetHeight(&finfo);
|
||||
owner->SetFont(&font);
|
||||
owner->MovePenTo(frame.left+8, frame.top + ((frame.Height() - (finfo.ascent
|
||||
+ finfo.descent + finfo.leading)) / 2) + (finfo.ascent
|
||||
+ finfo.descent) - 1);
|
||||
owner->DrawString(Text());
|
||||
// TODO: the position is unnecessarily complicated, and not correct either
|
||||
owner->MovePenTo(frame.left + 8, frame.top
|
||||
+ (frame.Height() - (finfo.ascent + finfo.descent + finfo.leading)) / 2
|
||||
+ (finfo.ascent + finfo.descent) - 1);
|
||||
owner->DrawString(text.String());
|
||||
}
|
||||
|
||||
|
||||
@ -100,14 +124,66 @@ LanguageListItem::DrawItem(BView* owner, BRect frame, bool complete)
|
||||
LanguageListView::LanguageListView(const char* name, list_view_type type)
|
||||
:
|
||||
BOutlineListView(name, type),
|
||||
fMsgPrefLanguagesChanged(new BMessage(kMsgPrefLanguagesChanged))
|
||||
fDeleteMessage(NULL),
|
||||
fDragMessage(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LanguageListView::~LanguageListView()
|
||||
{
|
||||
delete fMsgPrefLanguagesChanged;
|
||||
}
|
||||
|
||||
|
||||
LanguageListItem*
|
||||
LanguageListView::ItemForLanguageID(const char* id, int32* _index) const
|
||||
{
|
||||
for (int32 index = 0; index < FullListCountItems(); index++) {
|
||||
LanguageListItem* item
|
||||
= static_cast<LanguageListItem*>(FullListItemAt(index));
|
||||
|
||||
if (item->ID() == id) {
|
||||
if (_index != NULL)
|
||||
*_index = index;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
LanguageListItem*
|
||||
LanguageListView::ItemForLanguageCode(const char* code, int32* _index) const
|
||||
{
|
||||
for (int32 index = 0; index < FullListCountItems(); index++) {
|
||||
LanguageListItem* item
|
||||
= static_cast<LanguageListItem*>(FullListItemAt(index));
|
||||
|
||||
if (item->Code() == code) {
|
||||
if (_index != NULL)
|
||||
*_index = index;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LanguageListView::SetDeleteMessage(BMessage* message)
|
||||
{
|
||||
delete fDeleteMessage;
|
||||
fDeleteMessage = message;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LanguageListView::SetDragMessage(BMessage* message)
|
||||
{
|
||||
delete fDragMessage;
|
||||
fDragMessage = message;
|
||||
}
|
||||
|
||||
|
||||
@ -119,302 +195,141 @@ LanguageListView::AttachedToWindow()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LanguageListView::MoveItems(BList& items, int32 index)
|
||||
{
|
||||
// TODO : only allow moving top level item around other top level
|
||||
// or sublevels within the same top level
|
||||
|
||||
DeselectAll();
|
||||
|
||||
// collect all items that must be moved (adding subitems as necessary)
|
||||
int32 count = items.CountItems();
|
||||
BList itemsToBeMoved;
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BListItem* item = (BListItem*)items.ItemAt(i);
|
||||
itemsToBeMoved.AddItem(item);
|
||||
if (item->OutlineLevel() == 0) {
|
||||
// add all subitems, as they need to be moved, too
|
||||
int32 subItemCount = CountItemsUnder(item, true);
|
||||
for (int subIndex = 0; subIndex < subItemCount ; subIndex++)
|
||||
itemsToBeMoved.AddItem(ItemUnderAt(item, true, subIndex));
|
||||
}
|
||||
}
|
||||
|
||||
// now remove all the items backwards (in order to remove children before
|
||||
// their parent), decreasing target index if we are removing items before
|
||||
// it
|
||||
count = itemsToBeMoved.CountItems();
|
||||
for (int32 i = count - 1; i >= 0; i--) {
|
||||
BListItem* item = (BListItem*)itemsToBeMoved.ItemAt(i);
|
||||
int32 removeIndex = FullListIndexOf(item);
|
||||
if (RemoveItem(item)) {
|
||||
if (removeIndex < index)
|
||||
index--;
|
||||
}
|
||||
}
|
||||
|
||||
// finally add all the items at the given index
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BListItem* item = (BListItem*)itemsToBeMoved.ItemAt(i);
|
||||
if (AddItem(item, index))
|
||||
index++;
|
||||
else
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LanguageListView::MessageReceived(BMessage* message)
|
||||
{
|
||||
if (message->what == 'DRAG') {
|
||||
if (message->WasDropped() && _AcceptsDragMessage(message)) {
|
||||
// Someone just dropped something on us
|
||||
LanguageListView* list = NULL;
|
||||
if (message->FindPointer("list", (void**)&list) == B_OK) {
|
||||
// It comes from a list
|
||||
int32 count = CountItems();
|
||||
if (fDropIndex < 0 || fDropIndex > count)
|
||||
fDropIndex = count;
|
||||
BMessage dragMessage(*message);
|
||||
dragMessage.AddInt32("drop_index", fDropIndex);
|
||||
dragMessage.AddPointer("drop_target", this);
|
||||
|
||||
if (list == this) {
|
||||
// It comes from ourselves : move the item around in the list
|
||||
BList items;
|
||||
int32 index;
|
||||
for (int32 i = 0;
|
||||
message->FindInt32("index", i, &index) == B_OK; i++) {
|
||||
if (BListItem* item = FullListItemAt(index))
|
||||
items.AddItem((void*)item);
|
||||
}
|
||||
|
||||
if (items.CountItems() > 0) {
|
||||
// There is something to move
|
||||
LanguageListItem* parent = static_cast<LanguageListItem*>(
|
||||
Superitem(static_cast<LanguageListItem*>(
|
||||
items.FirstItem())));
|
||||
if (parent) {
|
||||
// item has a parent - it should then stay
|
||||
// below it
|
||||
if (Superitem(FullListItemAt(fDropIndex - 1)) == parent
|
||||
|| FullListItemAt(fDropIndex - 1) == parent)
|
||||
MoveItems(items, fDropIndex);
|
||||
} else {
|
||||
// item is top level and should stay so.
|
||||
if (Superitem(FullListItemAt(fDropIndex - 1)) == NULL)
|
||||
MoveItems(items, fDropIndex);
|
||||
else {
|
||||
int itemCount = CountItemsUnder(
|
||||
FullListItemAt(fDropIndex), true);
|
||||
MoveItems(items, FullListIndexOf(Superitem(
|
||||
FullListItemAt(fDropIndex - 1))
|
||||
+ itemCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
fDropIndex = -1;
|
||||
} else {
|
||||
// It comes from another list : move it here
|
||||
|
||||
// ensure we always drop things at top-level and not
|
||||
// in the middle of another outline
|
||||
if (Superitem(FullListItemAt(fDropIndex))) {
|
||||
// Item has a parent
|
||||
fDropIndex = FullListIndexOf(Superitem(FullListItemAt(
|
||||
fDropIndex)));
|
||||
}
|
||||
|
||||
// Item is now a top level one - we must insert just below its
|
||||
// last child
|
||||
fDropIndex += CountItemsUnder(FullListItemAt(fDropIndex), true)
|
||||
+ 1;
|
||||
|
||||
int32 indexCount;
|
||||
type_code dummy;
|
||||
if (message->GetInfo("index", &dummy, &indexCount) == B_OK) {
|
||||
for (int32 i = indexCount - 1; i >= 0; i--) {
|
||||
int32 index;
|
||||
if (message->FindInt32("index", i, &index) == B_OK)
|
||||
MoveItemFrom(list, index, fDropIndex);
|
||||
}
|
||||
}
|
||||
|
||||
fDropIndex = -1;
|
||||
}
|
||||
Invoke(fMsgPrefLanguagesChanged);
|
||||
}
|
||||
Invoke(&dragMessage);
|
||||
} else
|
||||
BOutlineListView::MessageReceived(message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LanguageListView::MoveItemFrom(BOutlineListView* origin, int32 index,
|
||||
int32 dropSpot)
|
||||
{
|
||||
// Check that the node we are going to move is a top-level one.
|
||||
// If not, we want its parent instead
|
||||
LanguageListItem* itemToMove = static_cast<LanguageListItem*>(
|
||||
origin->Superitem(origin->FullListItemAt(index)));
|
||||
if (itemToMove == NULL) {
|
||||
itemToMove = static_cast<LanguageListItem*>(
|
||||
origin->FullListItemAt(index));
|
||||
if (itemToMove == NULL)
|
||||
return;
|
||||
} else
|
||||
index = origin->FullListIndexOf(itemToMove);
|
||||
|
||||
// collect all items that must be moved (adding subitems as necessary)
|
||||
BList itemsToBeMoved;
|
||||
itemsToBeMoved.AddItem(itemToMove);
|
||||
// add all subitems, as they need to be moved, too
|
||||
int32 subItemCount = origin->CountItemsUnder(itemToMove, true);
|
||||
for (int32 subIndex = 0; subIndex < subItemCount; subIndex++) {
|
||||
itemsToBeMoved.AddItem(origin->ItemUnderAt(itemToMove, true,
|
||||
subIndex));
|
||||
}
|
||||
|
||||
// now remove all items from origin in reverse order (to remove the children
|
||||
// before the parent) ...
|
||||
// TODO: using RemoveItem() on the parent will delete the subitems, which
|
||||
// may be a bug, actually.
|
||||
int32 itemCount = itemsToBeMoved.CountItems();
|
||||
for (int32 i = itemCount - 1; i >= 0; i--)
|
||||
origin->RemoveItem(index + i);
|
||||
// ... and add all the items to this list
|
||||
AddList(&itemsToBeMoved, dropSpot);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LanguageListView::InitiateDrag(BPoint point, int32 index, bool)
|
||||
LanguageListView::InitiateDrag(BPoint point, int32 dragIndex,
|
||||
bool /*wasSelected*/)
|
||||
{
|
||||
bool success = false;
|
||||
if (fDragMessage == NULL)
|
||||
return false;
|
||||
|
||||
BListItem* item = FullListItemAt(CurrentSelection(0));
|
||||
if (!item) {
|
||||
if (item == NULL) {
|
||||
// workaround for a timing problem
|
||||
Select(index);
|
||||
item = FullListItemAt(index);
|
||||
// TODO: this should support extending the selection
|
||||
item = ItemAt(dragIndex);
|
||||
Select(dragIndex);
|
||||
}
|
||||
if (item) {
|
||||
// create drag message
|
||||
BMessage msg('DRAG');
|
||||
msg.AddPointer("list", (void*)(this));
|
||||
// first selection round, consider only superitems
|
||||
int32 index;
|
||||
for (int32 i = 0; (index = FullListCurrentSelection(i)) >= 0; i++) {
|
||||
BListItem* item = FullListItemAt(index);
|
||||
if (item == NULL)
|
||||
return false;
|
||||
if (item->OutlineLevel() == 0)
|
||||
msg.AddInt32("index", index);
|
||||
}
|
||||
if (!msg.HasInt32("index")) {
|
||||
// second selection round, consider only subitems of the same
|
||||
// (i.e. the first) parent
|
||||
BListItem* seenSuperItem = NULL;
|
||||
for (int32 i = 0; (index = FullListCurrentSelection(i)) >= 0; i++) {
|
||||
BListItem* item = FullListItemAt(index);
|
||||
if (item == NULL)
|
||||
return false;
|
||||
if (item->OutlineLevel() != 0) {
|
||||
BListItem* superItem = Superitem(item);
|
||||
if (seenSuperItem == NULL)
|
||||
seenSuperItem = superItem;
|
||||
if (superItem == seenSuperItem)
|
||||
msg.AddInt32("index", index);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item == NULL)
|
||||
return false;
|
||||
|
||||
// figure out drag rect
|
||||
float width = Bounds().Width();
|
||||
BRect dragRect(0.0, 0.0, width, -1.0);
|
||||
// figure out, how many items fit into our bitmap
|
||||
bool fade = false;
|
||||
int32 numItems;
|
||||
int32 currIndex;
|
||||
BListItem* item;
|
||||
for (numItems = 0;
|
||||
msg.FindInt32("index", numItems, &currIndex) == B_OK
|
||||
&& (item = FullListItemAt(currIndex)) != NULL; numItems++) {
|
||||
dragRect.bottom += ceilf(item->Height()) + 1.0;
|
||||
if (dragRect.Height() > MAX_DRAG_HEIGHT) {
|
||||
fade = true;
|
||||
dragRect.bottom = MAX_DRAG_HEIGHT;
|
||||
numItems++;
|
||||
break;
|
||||
}
|
||||
// create drag message
|
||||
BMessage message = *fDragMessage;
|
||||
message.AddPointer("listview", this);
|
||||
|
||||
for (int32 i = 0;; i++) {
|
||||
int32 index = FullListCurrentSelection(i);
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
message.AddInt32("index", index);
|
||||
}
|
||||
|
||||
// figure out drag rect
|
||||
|
||||
BRect dragRect(0.0, 0.0, Bounds().Width(), -1.0);
|
||||
int32 numItems = 0;
|
||||
bool fade = false;
|
||||
|
||||
// figure out, how many items fit into our bitmap
|
||||
for (int32 i = 0, index; message.FindInt32("index", i, &index) == B_OK;
|
||||
i++) {
|
||||
BListItem* item = FullListItemAt(index);
|
||||
if (item == NULL)
|
||||
break;
|
||||
|
||||
dragRect.bottom += ceilf(item->Height()) + 1.0;
|
||||
numItems++;
|
||||
|
||||
if (dragRect.Height() > MAX_DRAG_HEIGHT) {
|
||||
dragRect.bottom = MAX_DRAG_HEIGHT;
|
||||
fade = true;
|
||||
break;
|
||||
}
|
||||
BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true);
|
||||
if (dragBitmap && dragBitmap->IsValid()) {
|
||||
BView* v = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE,
|
||||
B_WILL_DRAW);
|
||||
dragBitmap->AddChild(v);
|
||||
dragBitmap->Lock();
|
||||
BRect itemBounds(dragRect) ;
|
||||
itemBounds.bottom = 0.0;
|
||||
// let all selected items, that fit into our drag_bitmap, draw
|
||||
for (int32 i = 0; i < numItems; i++) {
|
||||
int32 index = msg.FindInt32("index", i);
|
||||
LanguageListItem* item
|
||||
= static_cast<LanguageListItem*>(FullListItemAt(index));
|
||||
itemBounds.bottom = itemBounds.top + ceilf(item->Height());
|
||||
if (itemBounds.bottom > dragRect.bottom)
|
||||
itemBounds.bottom = dragRect.bottom;
|
||||
item->DrawItem(v, itemBounds);
|
||||
itemBounds.top = itemBounds.bottom + 1.0;
|
||||
}
|
||||
// make a black frame arround the edge
|
||||
v->SetHighColor(0, 0, 0, 255);
|
||||
v->StrokeRect(v->Bounds());
|
||||
v->Sync();
|
||||
}
|
||||
|
||||
uint8* bits = (uint8*)dragBitmap->Bits();
|
||||
int32 height = (int32)dragBitmap->Bounds().Height() + 1;
|
||||
int32 width = (int32)dragBitmap->Bounds().Width() + 1;
|
||||
int32 bpr = dragBitmap->BytesPerRow();
|
||||
BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true);
|
||||
if (dragBitmap->IsValid()) {
|
||||
BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE,
|
||||
B_WILL_DRAW);
|
||||
dragBitmap->AddChild(view);
|
||||
dragBitmap->Lock();
|
||||
BRect itemBounds(dragRect) ;
|
||||
itemBounds.bottom = 0.0;
|
||||
// let all selected items, that fit into our drag_bitmap, draw
|
||||
for (int32 i = 0; i < numItems; i++) {
|
||||
int32 index = message.FindInt32("index", i);
|
||||
LanguageListItem* item
|
||||
= static_cast<LanguageListItem*>(FullListItemAt(index));
|
||||
itemBounds.bottom = itemBounds.top + ceilf(item->Height());
|
||||
if (itemBounds.bottom > dragRect.bottom)
|
||||
itemBounds.bottom = dragRect.bottom;
|
||||
item->DrawItem(view, itemBounds);
|
||||
itemBounds.top = itemBounds.bottom + 1.0;
|
||||
}
|
||||
// make a black frame arround the edge
|
||||
view->SetHighColor(0, 0, 0, 255);
|
||||
view->StrokeRect(view->Bounds());
|
||||
view->Sync();
|
||||
|
||||
if (fade) {
|
||||
for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) {
|
||||
uint8* line = bits + 3;
|
||||
for (uint8* end = line + 4 * width; line < end; line += 4)
|
||||
*line = ALPHA;
|
||||
}
|
||||
for (int32 y = height - ALPHA / 2; y < height;
|
||||
y++, bits += bpr) {
|
||||
uint8* line = bits + 3;
|
||||
for (uint8* end = line + 4 * width; line < end; line += 4)
|
||||
*line = (height - y) << 1;
|
||||
}
|
||||
} else {
|
||||
for (int32 y = 0; y < height; y++, bits += bpr) {
|
||||
uint8* line = bits + 3;
|
||||
for (uint8* end = line + 4 * width; line < end; line += 4)
|
||||
*line = ALPHA;
|
||||
}
|
||||
uint8* bits = (uint8*)dragBitmap->Bits();
|
||||
int32 height = (int32)dragBitmap->Bounds().Height() + 1;
|
||||
int32 width = (int32)dragBitmap->Bounds().Width() + 1;
|
||||
int32 bpr = dragBitmap->BytesPerRow();
|
||||
|
||||
if (fade) {
|
||||
for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) {
|
||||
uint8* line = bits + 3;
|
||||
for (uint8* end = line + 4 * width; line < end; line += 4)
|
||||
*line = ALPHA;
|
||||
}
|
||||
for (int32 y = height - ALPHA / 2; y < height;
|
||||
y++, bits += bpr) {
|
||||
uint8* line = bits + 3;
|
||||
for (uint8* end = line + 4 * width; line < end; line += 4)
|
||||
*line = (height - y) << 1;
|
||||
}
|
||||
dragBitmap->Unlock();
|
||||
} else {
|
||||
delete dragBitmap;
|
||||
dragBitmap = NULL;
|
||||
for (int32 y = 0; y < height; y++, bits += bpr) {
|
||||
uint8* line = bits + 3;
|
||||
for (uint8* end = line + 4 * width; line < end; line += 4)
|
||||
*line = ALPHA;
|
||||
}
|
||||
}
|
||||
if (dragBitmap)
|
||||
DragMessage(&msg, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0));
|
||||
else
|
||||
DragMessage(&msg, dragRect.OffsetToCopy(point), this);
|
||||
|
||||
success = true;
|
||||
dragBitmap->Unlock();
|
||||
} else {
|
||||
delete dragBitmap;
|
||||
dragBitmap = NULL;
|
||||
}
|
||||
return success;
|
||||
|
||||
if (dragBitmap != NULL)
|
||||
DragMessage(&message, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0));
|
||||
else
|
||||
DragMessage(&message, dragRect.OffsetToCopy(point), this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LanguageListView::MouseMoved(BPoint where, uint32 transit, const BMessage* msg)
|
||||
LanguageListView::MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage)
|
||||
{
|
||||
if (msg && msg->what == 'DRAG') {
|
||||
if (dragMessage != NULL && _AcceptsDragMessage(dragMessage)) {
|
||||
switch (transit) {
|
||||
case B_ENTERED_VIEW:
|
||||
case B_INSIDE_VIEW:
|
||||
@ -455,5 +370,26 @@ LanguageListView::MouseMoved(BPoint where, uint32 transit, const BMessage* msg)
|
||||
}
|
||||
}
|
||||
} else
|
||||
BOutlineListView::MouseMoved(where, transit, msg);
|
||||
BOutlineListView::MouseMoved(where, transit, dragMessage);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LanguageListView::KeyDown(const char* bytes, int32 numBytes)
|
||||
{
|
||||
if (bytes[0] == B_DELETE && fDeleteMessage != NULL) {
|
||||
Invoke(fDeleteMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
BOutlineListView::KeyDown(bytes, numBytes);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LanguageListView::_AcceptsDragMessage(const BMessage* message) const
|
||||
{
|
||||
LanguageListView* sourceView = NULL;
|
||||
return message != NULL
|
||||
&& message->FindPointer("listview", (void**)&sourceView) == B_OK;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
* Adrien Destugues <pulkomandy@gmail.com>
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
#ifndef LANGUAGE_LIST_VIEW_H
|
||||
@ -19,15 +20,19 @@
|
||||
class LanguageListItem : public BStringItem {
|
||||
public:
|
||||
LanguageListItem(const char* text,
|
||||
const char* code);
|
||||
const char* id, const char* code);
|
||||
LanguageListItem(const LanguageListItem& other);
|
||||
virtual ~LanguageListItem();
|
||||
|
||||
const BString& LanguageCode() { return fLanguageCode; }
|
||||
void DrawItem(BView* owner, BRect frame,
|
||||
const BString& ID() const { return fID; }
|
||||
const BString& Code() const { return fCode; }
|
||||
|
||||
virtual void DrawItem(BView* owner, BRect frame,
|
||||
bool complete = false);
|
||||
|
||||
private:
|
||||
BString fLanguageCode;
|
||||
BString fID;
|
||||
BString fCode;
|
||||
BBitmap* fIcon;
|
||||
};
|
||||
|
||||
@ -38,18 +43,29 @@ public:
|
||||
list_view_type type);
|
||||
virtual ~LanguageListView();
|
||||
|
||||
bool InitiateDrag(BPoint point, int32 index,
|
||||
LanguageListItem* ItemForLanguageID(const char* code,
|
||||
int32* _index = NULL) const;
|
||||
LanguageListItem* ItemForLanguageCode(const char* code,
|
||||
int32* _index = NULL) const;
|
||||
|
||||
void SetDeleteMessage(BMessage* message);
|
||||
void SetDragMessage(BMessage* message);
|
||||
|
||||
virtual bool InitiateDrag(BPoint point, int32 index,
|
||||
bool wasSelected);
|
||||
void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* msg);
|
||||
void MoveItems(BList& items, int32 index);
|
||||
void MoveItemFrom(BOutlineListView* origin, int32 index,
|
||||
int32 dropSpot = 0);
|
||||
void AttachedToWindow();
|
||||
void MessageReceived (BMessage* message);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage);
|
||||
virtual void AttachedToWindow();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||
|
||||
private:
|
||||
bool _AcceptsDragMessage(const BMessage* message) const;
|
||||
|
||||
private:
|
||||
int32 fDropIndex;
|
||||
BMessage* fMsgPrefLanguagesChanged;
|
||||
BMessage* fDeleteMessage;
|
||||
BMessage* fDragMessage;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2005-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef LOCALE_H
|
||||
@ -11,13 +11,7 @@
|
||||
|
||||
extern const char* kSignature;
|
||||
|
||||
static const uint32 kMsgCountrySelection = 'csel';
|
||||
static const uint32 kMsgSettingsChanged = 'SeCh';
|
||||
static const uint32 kMsgPrefLanguagesChanged = 'lang';
|
||||
static const uint32 kMsgLangInvoked = 'laiv';
|
||||
static const uint32 kMsgPrefLangInvoked = 'pliv';
|
||||
static const uint32 kMsgDefaults = 'dflt';
|
||||
static const uint32 kMsgRevert = 'revt';
|
||||
|
||||
|
||||
#endif /* LOCALE_H */
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <Application.h>
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <ControlLook.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <Locale.h>
|
||||
@ -23,6 +24,7 @@
|
||||
#include <ScrollView.h>
|
||||
#include <StringView.h>
|
||||
#include <TabView.h>
|
||||
#include <UnicodeChar.h>
|
||||
|
||||
#include <ICUWrapper.h>
|
||||
|
||||
@ -35,6 +37,18 @@
|
||||
#define TR_CONTEXT "Locale Preflet Window"
|
||||
|
||||
|
||||
static const uint32 kMsgLanguageInvoked = 'LaIv';
|
||||
static const uint32 kMsgLanguageDragged = 'LaDr';
|
||||
static const uint32 kMsgPreferredLanguageInvoked = 'PLIv';
|
||||
static const uint32 kMsgPreferredLanguageDragged = 'PLDr';
|
||||
static const uint32 kMsgPreferredLanguageDeleted = 'PLDl';
|
||||
static const uint32 kMsgCountrySelection = 'csel';
|
||||
static const uint32 kMsgDefaults = 'dflt';
|
||||
static const uint32 kMsgRevert = 'revt';
|
||||
|
||||
static const uint32 kMsgPreferredLanguagesChanged = 'lang';
|
||||
|
||||
|
||||
static int
|
||||
compare_typed_list_items(const BListItem* _a, const BListItem* _b)
|
||||
{
|
||||
@ -50,26 +64,19 @@ compare_typed_list_items(const BListItem* _a, const BListItem* _b)
|
||||
|
||||
LocaleWindow::LocaleWindow()
|
||||
:
|
||||
BWindow(BRect(0, 0, 0, 0), "Locale", B_TITLED_WINDOW, B_NOT_RESIZABLE
|
||||
| B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS
|
||||
| B_QUIT_ON_WINDOW_CLOSE),
|
||||
fMsgPrefLanguagesChanged(new BMessage(kMsgPrefLanguagesChanged))
|
||||
BWindow(BRect(0, 0, 0, 0), "Locale", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE
|
||||
| B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS)
|
||||
{
|
||||
BCountry* defaultCountry;
|
||||
be_locale_roster->GetDefaultCountry(&defaultCountry);
|
||||
|
||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
|
||||
BButton* button = new BButton(B_TRANSLATE("Defaults"),
|
||||
new BMessage(kMsgDefaults));
|
||||
fRevertButton = new BButton(B_TRANSLATE("Revert"),
|
||||
new BMessage(kMsgRevert));
|
||||
fRevertButton->SetEnabled(false);
|
||||
float spacing = be_control_look->DefaultItemSpacing();
|
||||
|
||||
BTabView* tabView = new BTabView("tabview");
|
||||
|
||||
BView* languageTab = new BView(B_TRANSLATE("Language"), B_WILL_DRAW);
|
||||
languageTab->SetLayout(new BGroupLayout(B_VERTICAL, 0));
|
||||
BGroupView* languageTab = new BGroupView(B_TRANSLATE("Language"),
|
||||
B_HORIZONTAL, spacing);
|
||||
|
||||
// first list: available languages
|
||||
fLanguageListView = new LanguageListView("available",
|
||||
@ -77,34 +84,48 @@ LocaleWindow::LocaleWindow()
|
||||
BScrollView* scrollView = new BScrollView("scroller", fLanguageListView,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS, false, true);
|
||||
|
||||
fLanguageListView->SetInvocationMessage(new BMessage(kMsgLangInvoked));
|
||||
fLanguageListView->SetInvocationMessage(new BMessage(kMsgLanguageInvoked));
|
||||
fLanguageListView->SetDragMessage(new BMessage(kMsgLanguageDragged));
|
||||
|
||||
// Fill the language list from the LocaleRoster data
|
||||
BMessage installedLanguages;
|
||||
if (be_locale_roster->GetInstalledLanguages(&installedLanguages) == B_OK) {
|
||||
BString currentLanguageCode;
|
||||
BString currentLanguageName;
|
||||
BString currentID;
|
||||
LanguageListItem* lastAddedCountryItem = NULL;
|
||||
|
||||
for (int i = 0; installedLanguages.FindString("langs",
|
||||
i, ¤tLanguageCode) == B_OK; i++) {
|
||||
for (int i = 0; installedLanguages.FindString("langs", i, ¤tID)
|
||||
== B_OK; i++) {
|
||||
// Now get an human-readable, localized name for each language
|
||||
BLanguage* currentLanguage;
|
||||
be_locale_roster->GetLanguage(¤tLanguage,
|
||||
currentLanguageCode.String());
|
||||
be_locale_roster->GetLanguage(currentID.String(),
|
||||
¤tLanguage);
|
||||
|
||||
currentLanguageName.Truncate(0);
|
||||
currentLanguage->GetName(¤tLanguageName);
|
||||
BString name;
|
||||
currentLanguage->GetName(name);
|
||||
|
||||
LanguageListItem* item = new LanguageListItem(currentLanguageName,
|
||||
currentLanguageCode.String());
|
||||
if (currentLanguage->IsCountry()) {
|
||||
// TODO: as long as the app_server doesn't support font overlays,
|
||||
// use the translated name if problematic characters are used...
|
||||
const char* string = name.String();
|
||||
while (uint32 code = BUnicodeChar::FromUTF8(&string)) {
|
||||
if (code > 1424) {
|
||||
currentLanguage->GetTranslatedName(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LanguageListItem* item = new LanguageListItem(name,
|
||||
currentID.String(), currentLanguage->Code());
|
||||
if (currentLanguage->IsCountrySpecific()
|
||||
&& lastAddedCountryItem != NULL
|
||||
&& lastAddedCountryItem->Code() == item->Code()) {
|
||||
fLanguageListView->AddUnder(item, lastAddedCountryItem);
|
||||
} else {
|
||||
// This is a language without country, add it at top-level
|
||||
// This is a language variant, add it at top-level
|
||||
fLanguageListView->AddItem(item);
|
||||
item->SetExpanded(false);
|
||||
lastAddedCountryItem = item;
|
||||
if (!currentLanguage->IsCountrySpecific()) {
|
||||
item->SetExpanded(false);
|
||||
lastAddedCountryItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
delete currentLanguage;
|
||||
@ -112,12 +133,12 @@ LocaleWindow::LocaleWindow()
|
||||
|
||||
fLanguageListView->FullListSortItems(compare_typed_list_items);
|
||||
} else {
|
||||
BAlert* myAlert = new BAlert("Error",
|
||||
BAlert* alert = new BAlert("Error",
|
||||
B_TRANSLATE("Unable to find the available languages! You can't "
|
||||
"use this preflet!"),
|
||||
B_TRANSLATE("OK"), NULL, NULL,
|
||||
B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_STOP_ALERT);
|
||||
myAlert->Go();
|
||||
alert->Go();
|
||||
}
|
||||
|
||||
// Second list: active languages
|
||||
@ -126,40 +147,23 @@ LocaleWindow::LocaleWindow()
|
||||
BScrollView* scrollViewEnabled = new BScrollView("scroller",
|
||||
fPreferredListView, B_WILL_DRAW | B_FRAME_EVENTS, false, true);
|
||||
|
||||
fPreferredListView->SetInvocationMessage(new BMessage(kMsgPrefLangInvoked));
|
||||
fPreferredListView->SetInvocationMessage(
|
||||
new BMessage(kMsgPreferredLanguageInvoked));
|
||||
fPreferredListView->SetDeleteMessage(
|
||||
new BMessage(kMsgPreferredLanguageDeleted));
|
||||
fPreferredListView->SetDragMessage(
|
||||
new BMessage(kMsgPreferredLanguageDragged));
|
||||
|
||||
// get the preferred languages from the Settings. Move them here from
|
||||
// the other list.
|
||||
BMessage msg;
|
||||
be_locale_roster->GetPreferredLanguages(&msg);
|
||||
BString langCode;
|
||||
for (int index = 0; msg.FindString("language", index, &langCode) == B_OK;
|
||||
index++) {
|
||||
for (int listPos = 0; LanguageListItem* item
|
||||
= static_cast<LanguageListItem*>
|
||||
(fLanguageListView->FullListItemAt(listPos));
|
||||
listPos++) {
|
||||
if (langCode == item->LanguageCode()) {
|
||||
// We found the item we were looking for, now move it to
|
||||
// the other list along with all its children
|
||||
static_cast<LanguageListView*>(fPreferredListView)
|
||||
->MoveItemFrom(fLanguageListView,
|
||||
fLanguageListView->FullListIndexOf(item),
|
||||
fLanguageListView->CountItems());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
languageTab->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL, 10)
|
||||
.AddGroup(B_VERTICAL, 10)
|
||||
BLayoutBuilder::Group<>(languageTab)
|
||||
.AddGroup(B_VERTICAL, spacing)
|
||||
.Add(new BStringView("", B_TRANSLATE("Available languages")))
|
||||
.Add(scrollView)
|
||||
.End()
|
||||
.AddGroup(B_VERTICAL, 10)
|
||||
.AddGroup(B_VERTICAL, spacing)
|
||||
.Add(new BStringView("", B_TRANSLATE("Preferred languages")))
|
||||
.Add(scrollViewEnabled)
|
||||
.End()
|
||||
.View());
|
||||
.SetInsets(spacing, spacing, spacing, spacing);
|
||||
|
||||
BView* countryTab = new BView(B_TRANSLATE("Country"), B_WILL_DRAW);
|
||||
countryTab->SetLayout(new BGroupLayout(B_VERTICAL, 0));
|
||||
@ -183,48 +187,56 @@ LocaleWindow::LocaleWindow()
|
||||
countryFullName.toUTF8(sink);
|
||||
|
||||
LanguageListItem* item
|
||||
= new LanguageListItem(string, currentLocale[index].getName());
|
||||
= new LanguageListItem(string, currentLocale[index].getName(),
|
||||
NULL);
|
||||
listView->AddItem(item);
|
||||
if (!strcmp(currentLocale[index].getName(), defaultCountry->Code()))
|
||||
listView->Select(listView->CountItems() - 1);
|
||||
}
|
||||
|
||||
// TODO: find a real solution intead of this hack
|
||||
listView->SetExplicitMinSize(BSize(300, B_SIZE_UNSET));
|
||||
listView->SetExplicitMinSize(
|
||||
BSize(25 * be_plain_font->Size(), B_SIZE_UNSET));
|
||||
|
||||
fFormatView = new FormatView(defaultCountry);
|
||||
|
||||
countryTab->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL, 5)
|
||||
countryTab->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL, spacing)
|
||||
.AddGroup(B_VERTICAL, 3)
|
||||
.Add(scrollView)
|
||||
.End()
|
||||
.Add(fFormatView)
|
||||
.View()
|
||||
);
|
||||
.SetInsets(spacing, spacing, spacing, spacing));
|
||||
|
||||
listView->ScrollToSelection();
|
||||
|
||||
tabView->AddTab(languageTab);
|
||||
tabView->AddTab(countryTab);
|
||||
|
||||
BLayoutBuilder::Group<>(this)
|
||||
.AddGroup(B_VERTICAL, 3)
|
||||
.Add(tabView)
|
||||
.AddGroup(B_HORIZONTAL, 3)
|
||||
.Add(button)
|
||||
.Add(fRevertButton)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.SetInsets(5, 5, 5, 5)
|
||||
.End();
|
||||
BButton* button = new BButton(B_TRANSLATE("Defaults"),
|
||||
new BMessage(kMsgDefaults));
|
||||
#if 0
|
||||
fRevertButton = new BButton(B_TRANSLATE("Revert"),
|
||||
new BMessage(kMsgRevert));
|
||||
fRevertButton->SetEnabled(false);
|
||||
#endif
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL, spacing)
|
||||
.Add(tabView)
|
||||
.AddGroup(B_HORIZONTAL, spacing)
|
||||
.Add(button)
|
||||
// .Add(fRevertButton)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.SetInsets(spacing, spacing, spacing, spacing)
|
||||
.End();
|
||||
|
||||
_UpdatePreferredFromLocaleRoster();
|
||||
CenterOnScreen();
|
||||
}
|
||||
|
||||
|
||||
LocaleWindow::~LocaleWindow()
|
||||
{
|
||||
delete fMsgPrefLanguagesChanged;
|
||||
}
|
||||
|
||||
|
||||
@ -233,30 +245,86 @@ LocaleWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgDefaults:
|
||||
// TODO
|
||||
_Defaults();
|
||||
break;
|
||||
|
||||
case kMsgRevert:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case kMsgPrefLanguagesChanged:
|
||||
case kMsgLanguageDragged:
|
||||
{
|
||||
BMessage update(kMsgSettingsChanged);
|
||||
int index = 0;
|
||||
while (index < fPreferredListView->FullListCountItems()) {
|
||||
// only include subitems : we can guess the superitem
|
||||
// from them anyway
|
||||
if (fPreferredListView->Superitem(
|
||||
fPreferredListView->FullListItemAt(index)) != NULL) {
|
||||
LanguageListItem* item = static_cast<LanguageListItem*>(
|
||||
fPreferredListView->FullListItemAt(index));
|
||||
update.AddString("language", item->LanguageCode());
|
||||
}
|
||||
index++;
|
||||
void* target = NULL;
|
||||
if (message->FindPointer("drop_target", &target) != B_OK
|
||||
|| target != fPreferredListView)
|
||||
break;
|
||||
|
||||
// Add from available languages to preferred languages
|
||||
int32 dropIndex;
|
||||
if (message->FindInt32("drop_index", &dropIndex) != B_OK)
|
||||
dropIndex = fPreferredListView->CountItems();
|
||||
|
||||
int32 index = 0;
|
||||
for (int32 i = 0; message->FindInt32("index", i, &index) == B_OK;
|
||||
i++) {
|
||||
LanguageListItem* item = static_cast<LanguageListItem*>(
|
||||
fLanguageListView->FullListItemAt(index));
|
||||
_InsertPreferredLanguage(item, dropIndex++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMsgLanguageInvoked:
|
||||
{
|
||||
int32 index = 0;
|
||||
for (int32 i = 0; message->FindInt32("index", i, &index) == B_OK;
|
||||
i++) {
|
||||
LanguageListItem* item = static_cast<LanguageListItem*>(
|
||||
fLanguageListView->ItemAt(index));
|
||||
_InsertPreferredLanguage(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgPreferredLanguageDragged:
|
||||
{
|
||||
void* target = NULL;
|
||||
if (fPreferredListView->CountItems() == 1
|
||||
|| message->FindPointer("drop_target", &target) != B_OK)
|
||||
break;
|
||||
|
||||
if (target == fPreferredListView) {
|
||||
// change ordering
|
||||
int32 dropIndex = message->FindInt32("drop_index");
|
||||
int32 index = 0;
|
||||
if (message->FindInt32("index", &index) == B_OK
|
||||
&& dropIndex != index) {
|
||||
BListItem* item = fPreferredListView->RemoveItem(index);
|
||||
if (dropIndex > index)
|
||||
index--;
|
||||
fPreferredListView->AddItem(item, dropIndex);
|
||||
|
||||
_PreferredLanguagesChanged();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// supposed to fall through - remove item
|
||||
}
|
||||
case kMsgPreferredLanguageDeleted:
|
||||
case kMsgPreferredLanguageInvoked:
|
||||
{
|
||||
if (fPreferredListView->CountItems() == 1)
|
||||
break;
|
||||
|
||||
// Remove from preferred languages
|
||||
int32 index = 0;
|
||||
if (message->FindInt32("index", &index) == B_OK) {
|
||||
delete fPreferredListView->RemoveItem(index);
|
||||
_PreferredLanguagesChanged();
|
||||
|
||||
if (message->what == kMsgPreferredLanguageDeleted)
|
||||
fPreferredListView->Select(index);
|
||||
}
|
||||
fLanguageListView->FullListSortItems(compare_typed_list_items);
|
||||
be_app_messenger.SendMessage(&update);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -274,42 +342,14 @@ LocaleWindow::MessageReceived(BMessage* message)
|
||||
LanguageListItem* item = static_cast<LanguageListItem*>
|
||||
(countryList->ItemAt(countryList->CurrentSelection()));
|
||||
BMessage newMessage(kMsgSettingsChanged);
|
||||
newMessage.AddString("country", item->LanguageCode());
|
||||
newMessage.AddString("country", item->ID());
|
||||
be_app_messenger.SendMessage(&newMessage);
|
||||
|
||||
BCountry* country = new BCountry(item->LanguageCode());
|
||||
BCountry* country = new BCountry(item->ID());
|
||||
fFormatView->SetCountry(country);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgLangInvoked:
|
||||
{
|
||||
int32 index = 0;
|
||||
if (message->FindInt32("index", &index) == B_OK) {
|
||||
LanguageListItem* listItem = static_cast<LanguageListItem*>
|
||||
(fLanguageListView->RemoveItem(index));
|
||||
fPreferredListView->AddItem(listItem);
|
||||
fPreferredListView->Invoke(fMsgPrefLanguagesChanged);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgPrefLangInvoked:
|
||||
{
|
||||
if (fPreferredListView->CountItems() == 1)
|
||||
break;
|
||||
|
||||
int32 index = 0;
|
||||
if (message->FindInt32("index", &index) == B_OK) {
|
||||
LanguageListItem* listItem = static_cast<LanguageListItem*>
|
||||
(fPreferredListView->RemoveItem(index));
|
||||
fLanguageListView->AddItem(listItem);
|
||||
fLanguageListView->FullListSortItems(compare_typed_list_items);
|
||||
fPreferredListView->Invoke(fMsgPrefLanguagesChanged);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
@ -317,11 +357,142 @@ LocaleWindow::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocaleWindow::FrameMoved(BPoint newPosition)
|
||||
bool
|
||||
LocaleWindow::QuitRequested()
|
||||
{
|
||||
BMessage update(kMsgSettingsChanged);
|
||||
update.AddPoint("window_location", newPosition);
|
||||
update.AddPoint("window_location", Frame().LeftTop());
|
||||
be_app_messenger.SendMessage(&update);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocaleWindow::_PreferredLanguagesChanged()
|
||||
{
|
||||
BMessage update(kMsgSettingsChanged);
|
||||
int index = 0;
|
||||
while (index < fPreferredListView->FullListCountItems()) {
|
||||
// only include subitems: we can guess the superitem
|
||||
// from them anyway
|
||||
LanguageListItem* item = static_cast<LanguageListItem*>(
|
||||
fPreferredListView->FullListItemAt(index));
|
||||
if (item != NULL)
|
||||
update.AddString("language", item->ID());
|
||||
|
||||
index++;
|
||||
}
|
||||
be_app_messenger.SendMessage(&update);
|
||||
|
||||
_EnableDisableLanguages();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocaleWindow::_EnableDisableLanguages()
|
||||
{
|
||||
DisableUpdates();
|
||||
|
||||
for (int32 i = 0; i < fLanguageListView->FullListCountItems(); i++) {
|
||||
LanguageListItem* item = static_cast<LanguageListItem*>(
|
||||
fLanguageListView->FullListItemAt(i));
|
||||
|
||||
bool enable = fPreferredListView->ItemForLanguageID(item->ID()) == NULL;
|
||||
if (item->IsEnabled() != enable) {
|
||||
item->SetEnabled(enable);
|
||||
|
||||
int32 visibleIndex = fLanguageListView->IndexOf(item);
|
||||
if (visibleIndex >= 0) {
|
||||
if (!enable)
|
||||
fLanguageListView->Deselect(visibleIndex);
|
||||
fLanguageListView->InvalidateItem(visibleIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EnableUpdates();
|
||||
}
|
||||
|
||||
|
||||
//! Get the preferred languages from the settings.
|
||||
void
|
||||
LocaleWindow::_UpdatePreferredFromLocaleRoster()
|
||||
{
|
||||
DisableUpdates();
|
||||
|
||||
// Delete all existing items
|
||||
for (int32 index = fPreferredListView->CountItems(); index-- > 0; ) {
|
||||
delete fPreferredListView->ItemAt(index);
|
||||
}
|
||||
fPreferredListView->MakeEmpty();
|
||||
|
||||
// Add new ones from the locale roster
|
||||
BMessage preferredLanguages;
|
||||
be_locale_roster->GetPreferredLanguages(&preferredLanguages);
|
||||
|
||||
BString languageID;
|
||||
for (int32 index = 0; preferredLanguages.FindString("language", index,
|
||||
&languageID) == B_OK; index++) {
|
||||
int32 listIndex;
|
||||
LanguageListItem* item
|
||||
= fLanguageListView->ItemForLanguageID(languageID.String(),
|
||||
&listIndex);
|
||||
if (item != NULL) {
|
||||
// We found the item we were looking for, now copy it to
|
||||
// the other list
|
||||
fPreferredListView->AddItem(new LanguageListItem(*item));
|
||||
}
|
||||
}
|
||||
|
||||
_EnableDisableLanguages();
|
||||
EnableUpdates();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocaleWindow::_InsertPreferredLanguage(LanguageListItem* item, int32 atIndex)
|
||||
{
|
||||
if (item == NULL || fPreferredListView->ItemForLanguageID(
|
||||
item->ID().String()) != NULL)
|
||||
return;
|
||||
|
||||
if (atIndex == -1)
|
||||
atIndex = fPreferredListView->CountItems();
|
||||
|
||||
BLanguage* language = NULL;
|
||||
be_locale_roster->GetLanguage(item->Code(), &language);
|
||||
|
||||
LanguageListItem* baseItem = NULL;
|
||||
if (language != NULL) {
|
||||
baseItem = fPreferredListView->ItemForLanguageCode(language->Code(),
|
||||
&atIndex);
|
||||
delete language;
|
||||
}
|
||||
|
||||
DisableUpdates();
|
||||
|
||||
fPreferredListView->AddItem(new LanguageListItem(*item), atIndex);
|
||||
|
||||
// Replace other languages with the same base
|
||||
|
||||
if (baseItem != NULL) {
|
||||
fPreferredListView->RemoveItem(baseItem);
|
||||
delete baseItem;
|
||||
}
|
||||
|
||||
_PreferredLanguagesChanged();
|
||||
|
||||
EnableUpdates();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocaleWindow::_Defaults()
|
||||
{
|
||||
BMessage update(kMsgSettingsChanged);
|
||||
update.AddString("language", "en");
|
||||
|
||||
be_app_messenger.SendMessage(&update);
|
||||
_UpdatePreferredFromLocaleRoster();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2005-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef LOCALE_WINDOW_H
|
||||
@ -8,27 +8,37 @@
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
class BButton;
|
||||
class BListView;
|
||||
class BOutlineListView;
|
||||
class FormatView;
|
||||
class LanguageListItem;
|
||||
class LanguageListView;
|
||||
|
||||
|
||||
class LocaleWindow : public BWindow {
|
||||
public:
|
||||
LocaleWindow();
|
||||
~LocaleWindow();
|
||||
virtual ~LocaleWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void FrameMoved(BPoint newPosition);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
void _PreferredLanguagesChanged();
|
||||
void _EnableDisableLanguages();
|
||||
void _UpdatePreferredFromLocaleRoster();
|
||||
void _InsertPreferredLanguage(LanguageListItem* item,
|
||||
int32 atIndex = -1);
|
||||
void _Defaults();
|
||||
|
||||
private:
|
||||
BButton* fRevertButton;
|
||||
BOutlineListView* fLanguageListView;
|
||||
BOutlineListView* fPreferredListView;
|
||||
LanguageListView* fLanguageListView;
|
||||
LanguageListView* fPreferredListView;
|
||||
FormatView* fFormatView;
|
||||
BMessage* fMsgPrefLanguagesChanged;
|
||||
};
|
||||
|
||||
|
||||
#endif // LOCALE_WINDOW_H
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user