Rework the handling of catalog loading in locale kit :

Instead of computing the mime signature and giving this to the catalog system,
give an entry_ref instead. The default catalog add-on can thus look at the
right place when searching local catalogs (embedded as resources, or stored
as files next to the executable.
  * This allows different versions of the same app to each have their own
catalog set,
  * And also make the embedded/local catalog searching work for add-ons and
libs, instead it only worked for apps because of a getAppInfo call.

Fix cpufrequency to make use of it properly (that wouldhave worked without the
change, but nowit's mandatory, since loading a catlog by mimesignature is not
possible anymore).

Should fix #8037.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43021 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adrien Destugues 2011-10-31 08:57:09 +00:00
parent ef9641e111
commit 54fad654ce
12 changed files with 110 additions and 142 deletions

View File

@ -20,7 +20,7 @@ struct entry_ref;
class BCatalog {
public:
BCatalog();
BCatalog(const char* signature,
BCatalog(const entry_ref& catalogOwner,
const char* language = NULL,
uint32 fingerprint = 0);
virtual ~BCatalog();
@ -42,7 +42,7 @@ public:
status_t GetLanguage(BString* language);
status_t GetFingerprint(uint32* fingerprint);
status_t SetCatalog(const char* signature,
status_t SetCatalog(const entry_ref& catalogOwner,
uint32 fingerprint);
status_t InitCheck() const;

View File

@ -24,7 +24,7 @@ namespace BPrivate {
*/
class DefaultCatalog : public BHashMapCatalog {
public:
DefaultCatalog(const char *signature, const char *language,
DefaultCatalog(const entry_ref &catalogOwner, const char *language,
uint32 fingerprint);
// constructor for normal use
DefaultCatalog(entry_ref *appOrAddOnRef);
@ -45,10 +45,10 @@ class DefaultCatalog : public BHashMapCatalog {
status_t WriteToResource(entry_ref *appOrAddOnRef);
status_t SetRawString(const CatKey& key, const char *translated);
void SetSignature(const entry_ref &catalogOwner);
static BCatalogAddOn *Instantiate(const char *signature,
static BCatalogAddOn *Instantiate(const entry_ref& catalogOwner,
const char *language, uint32 fingerprint);
static BCatalogAddOn *InstantiateEmbedded(entry_ref *appOrAddOnRef);
static BCatalogAddOn *Create(const char *signature,
const char *language);

View File

@ -48,10 +48,9 @@ public:
status_t GetSystemCatalog(BCatalogAddOn** catalog) const;
BCatalogAddOn* LoadCatalog(const char* signature,
BCatalogAddOn* LoadCatalog(const entry_ref& catalogOwner,
const char* language = NULL,
int32 fingerprint = 0) const;
BCatalogAddOn* LoadEmbeddedCatalog(entry_ref* appOrAddOnRef);
status_t UnloadCatalog(BCatalogAddOn* addOn);
BCatalogAddOn* CreateCatalog(const char* type,
@ -60,7 +59,7 @@ public:
};
typedef BCatalogAddOn* (*InstantiateCatalogFunc)(const char* name,
typedef BCatalogAddOn* (*InstantiateCatalogFunc)(const entry_ref& catalogOwner,
const char* language, uint32 fingerprint);
typedef BCatalogAddOn* (*CreateCatalogFunc)(const char* name,
@ -77,7 +76,6 @@ typedef status_t (*GetAvailableLanguagesFunc)(BMessage*, const char*,
*/
struct CatalogAddOnInfo {
InstantiateCatalogFunc fInstantiateFunc;
InstantiateEmbeddedCatalogFunc fInstantiateEmbeddedFunc;
CreateCatalogFunc fCreateFunc;
GetAvailableLanguagesFunc fLanguagesFunc;

View File

@ -10,3 +10,5 @@ resource app_version {
short_info = "Walter",
long_info = "©2001-2011 Haiku Inc."
};
resource app_signature "application/x-vnd.Haiku-libbe" ;

View File

@ -26,10 +26,10 @@ BCatalog::BCatalog()
}
BCatalog::BCatalog(const char *signature, const char *language,
BCatalog::BCatalog(const entry_ref &catalogOwner, const char *language,
uint32 fingerprint)
{
fCatalog = MutableLocaleRoster::Default()->LoadCatalog(signature, language,
fCatalog = MutableLocaleRoster::Default()->LoadCatalog(catalogOwner, language,
fingerprint);
}
@ -98,12 +98,12 @@ BCatalog::GetData(uint32 id, BMessage *msg)
status_t
BCatalog::SetCatalog(const char* signature, uint32 fingerprint)
BCatalog::SetCatalog(const entry_ref &catalogOwner, uint32 fingerprint)
{
// This is not thread safe. It is used only in ReadOnlyBootPrompt and should
// not do harm there, but not sure what to do about it…
MutableLocaleRoster::Default()->UnloadCatalog(fCatalog);
fCatalog = MutableLocaleRoster::Default()->LoadCatalog(signature, NULL,
fCatalog = MutableLocaleRoster::Default()->LoadCatalog(catalogOwner, NULL,
fingerprint);
return B_OK;

View File

@ -12,6 +12,7 @@
#include <new>
#include <syslog.h>
#include <AppFileInfo.h>
#include <Application.h>
#include <DataIO.h>
#include <Directory.h>
@ -55,16 +56,47 @@ const uint8 DefaultCatalog::kDefaultCatalogAddOnPriority = 1;
// give highest priority to our embedded catalog-add-on
void DefaultCatalog::SetSignature(const entry_ref &catalogOwner)
{
// figure out mimetype from image
BFile objectFile(&catalogOwner, B_READ_ONLY);
BAppFileInfo objectInfo(&objectFile);
char objectSignature[B_MIME_TYPE_LENGTH];
if (objectInfo.GetSignature(objectSignature) != B_OK) {
log_team(LOG_ERR, "File %s has no mimesignature, so it can't use"
" localization.", catalogOwner.name);
fSignature = "";
return;
}
// drop supertype from mimetype (should be "application/"):
char* stripSignature = objectSignature;
while (*stripSignature != '/' && *stripSignature != '\0')
stripSignature ++;
if (*stripSignature == '\0')
stripSignature = objectSignature;
else
stripSignature ++;
log_team(LOG_DEBUG, "Image %s requested catalog with mimetype %s",
catalogOwner.name, stripSignature);
fSignature = stripSignature;
}
/*! Constructs a DefaultCatalog with given signature and language and reads
the catalog from disk.
InitCheck() will be B_OK if catalog could be loaded successfully, it will
give an appropriate error-code otherwise.
*/
DefaultCatalog::DefaultCatalog(const char *signature, const char *language,
DefaultCatalog::DefaultCatalog(const entry_ref &catalogOwner, const char *language,
uint32 fingerprint)
:
BHashMapCatalog(signature, language, fingerprint)
BHashMapCatalog("", language, fingerprint)
{
// We created the catalog with an invalid signature, but we fix that now.
SetSignature(catalogOwner);
status_t status;
app_info appInfo;
@ -116,7 +148,7 @@ DefaultCatalog::DefaultCatalog(const char *signature, const char *language,
fInitCheck = status;
log_team(LOG_DEBUG,
"trying to load default-catalog(sig=%s, lang=%s) results in %s",
signature, language, strerror(fInitCheck));
fSignature.String(), language, strerror(fInitCheck));
}
@ -555,23 +587,11 @@ DefaultCatalog::Unflatten(BDataIO *dataIO)
BCatalogAddOn *
DefaultCatalog::Instantiate(const char *signature, const char *language,
DefaultCatalog::Instantiate(const entry_ref &catalogOwner, const char *language,
uint32 fingerprint)
{
DefaultCatalog *catalog
= new(std::nothrow) DefaultCatalog(signature, language, fingerprint);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;
}
return catalog;
}
BCatalogAddOn *
DefaultCatalog::InstantiateEmbedded(entry_ref *appOrAddOnRef)
{
DefaultCatalog *catalog = new(std::nothrow) DefaultCatalog(appOrAddOnRef);
= new(std::nothrow) DefaultCatalog(catalogOwner, language, fingerprint);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;

View File

@ -17,7 +17,6 @@
#include <syslog.h>
#include <Autolock.h>
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <Catalog.h>
#include <Collator.h>
@ -465,7 +464,7 @@ BLocaleRoster::GetLocalizedFileName(BString& localizedFileName,
if (status != B_OK)
return status;
BCatalog catalog(signature);
BCatalog catalog(ref);
const char* temp = catalog.GetString(string, context);
if (temp == NULL)
@ -505,28 +504,11 @@ BLocaleRoster::_GetCatalog(BCatalog* catalog, vint32* catalogInitStatus)
catalog);
return catalog;
}
// figure out mimetype from image
BFile objectFile(info.name, B_READ_ONLY);
BAppFileInfo objectInfo(&objectFile);
char objectSignature[B_MIME_TYPE_LENGTH];
if (objectInfo.GetSignature(objectSignature) != B_OK) {
log_team(LOG_ERR, "File %s has no mimesignature, so it can't use"
" localization.", info.name);
return catalog;
}
// drop supertype from mimetype (should be "application/"):
char* stripSignature = objectSignature;
while (*stripSignature != '/')
stripSignature ++;
stripSignature ++;
log_team(LOG_DEBUG,
"Image %s (address %x) requested catalog with mimetype %s",
info.name, catalog, stripSignature);
// load the catalog for this mimetype and return it to the app
catalog->SetCatalog(stripSignature, 0);
entry_ref ref;
BEntry(info.name).GetRef(&ref);
catalog->SetCatalog(ref, 0);
*catalogInitStatus = true;
return catalog;

View File

@ -51,7 +51,6 @@ CatalogAddOnInfo::CatalogAddOnInfo(const BString& name, const BString& path,
uint8 priority)
:
fInstantiateFunc(NULL),
fInstantiateEmbeddedFunc(NULL),
fCreateFunc(NULL),
fLanguagesFunc(NULL),
fName(name),
@ -87,8 +86,6 @@ CatalogAddOnInfo::MakeSureItsLoaded()
if (fAddOnImage >= B_OK) {
get_image_symbol(fAddOnImage, "instantiate_catalog",
B_SYMBOL_TYPE_TEXT, (void**)&fInstantiateFunc);
get_image_symbol(fAddOnImage, "instantiate_embedded_catalog",
B_SYMBOL_TYPE_TEXT, (void**)&fInstantiateEmbeddedFunc);
get_image_symbol(fAddOnImage, "create_catalog",
B_SYMBOL_TYPE_TEXT, (void**)&fCreateFunc);
get_image_symbol(fAddOnImage, "get_available_languages",
@ -115,7 +112,6 @@ CatalogAddOnInfo::UnloadIfPossible()
unload_add_on(fAddOnImage);
fAddOnImage = B_NO_INIT;
fInstantiateFunc = NULL;
fInstantiateEmbeddedFunc = NULL;
fCreateFunc = NULL;
fLanguagesFunc = NULL;
// log_team(LOG_DEBUG, "catalog-add-on %s has been unloaded",
@ -360,8 +356,6 @@ RosterData::_InitializeCatalogAddOns()
return B_NO_MEMORY;
defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate;
defaultCatalogAddOnInfo->fInstantiateEmbeddedFunc
= DefaultCatalog::InstantiateEmbedded;
defaultCatalogAddOnInfo->fCreateFunc = DefaultCatalog::Create;
fCatalogAddOnInfos.AddItem((void*)defaultCatalogAddOnInfo);
@ -794,7 +788,10 @@ MutableLocaleRoster::GetSystemCatalog(BCatalogAddOn** catalog) const
{
if (!catalog)
return B_BAD_VALUE;
*catalog = LoadCatalog("system");
// get libbe entry_ref
entry_ref ref;
BEntry("/boot/system/lib/libbe.so").GetRef(&ref);
*catalog = LoadCatalog(ref);
return B_OK;
}
@ -849,12 +846,9 @@ MutableLocaleRoster::CreateCatalog(const char* type, const char* signature,
* NULL is returned if no matching catalog could be found.
*/
BCatalogAddOn*
MutableLocaleRoster::LoadCatalog(const char* signature, const char* language,
MutableLocaleRoster::LoadCatalog(const entry_ref& catalogOwner, const char* language,
int32 fingerprint) const
{
if (!signature)
return NULL;
BAutolock lock(RosterData::Default()->fLock);
if (!lock.IsLocked())
return NULL;
@ -877,7 +871,7 @@ MutableLocaleRoster::LoadCatalog(const char* signature, const char* language,
BCatalogAddOn* catalog = NULL;
const char* lang;
for (int32 l=0; languages.FindString("language", l, &lang)==B_OK; ++l) {
catalog = info->fInstantiateFunc(signature, lang, fingerprint);
catalog = info->fInstantiateFunc(catalogOwner, lang, fingerprint);
if (catalog)
info->fLoadedCatalogs.AddItem(catalog);
// Chain-load catalogs for languages that depend on
@ -889,12 +883,12 @@ MutableLocaleRoster::LoadCatalog(const char* signature, const char* language,
int32 pos;
BString langName(lang);
BCatalogAddOn* currCatalog = catalog;
BCatalogAddOn* nextCatalog;
BCatalogAddOn* nextCatalog = NULL;
while ((pos = langName.FindLast('_')) >= 0) {
// language is based on parent, so we load that, too:
// (even if the parent catalog was not found)
langName.Truncate(pos);
nextCatalog = info->fInstantiateFunc(signature,
nextCatalog = info->fInstantiateFunc(catalogOwner,
langName.String(), fingerprint);
if (nextCatalog) {
info->fLoadedCatalogs.AddItem(nextCatalog);
@ -915,43 +909,6 @@ MutableLocaleRoster::LoadCatalog(const char* signature, const char* language,
}
/*
* Loads an embedded catalog from the given entry-ref (which is usually an
* app- or add-on-file. The request to load the catalog is dispatched to all
* add-ons in turn, until an add-on reports success.
* NULL is returned if no embedded catalog could be found.
*/
BCatalogAddOn*
MutableLocaleRoster::LoadEmbeddedCatalog(entry_ref* appOrAddOnRef)
{
if (!appOrAddOnRef)
return NULL;
BAutolock lock(RosterData::Default()->fLock);
if (!lock.IsLocked())
return NULL;
int32 count = RosterData::Default()->fCatalogAddOnInfos.CountItems();
for (int32 i = 0; i < count; ++i) {
CatalogAddOnInfo* info = (CatalogAddOnInfo*)
RosterData::Default()->fCatalogAddOnInfos.ItemAt(i);
if (!info->MakeSureItsLoaded() || !info->fInstantiateEmbeddedFunc)
continue;
BCatalogAddOn* catalog = NULL;
catalog = info->fInstantiateEmbeddedFunc(appOrAddOnRef);
if (catalog) {
info->fLoadedCatalogs.AddItem(catalog);
return catalog;
}
info->UnloadIfPossible();
}
return NULL;
}
/*
* unloads the given catalog (or rather: catalog-chain).
* Every single catalog of the chain will be deleted automatically.

View File

@ -217,22 +217,20 @@ FrequencyMenu::FrequencyMenu(BMenu* menu, BHandler* target,
fStorage(storage),
fInterface(interface)
{
BCatalog catalog("x-vnd.Haiku-CPUFrequencyPref");
fDynamicPerformance = new BMenuItem(
catalog.GetString("Dynamic performance", B_TRANSLATE_CONTEXT),
B_TRANSLATE("Dynamic performance"),
new BMessage(kMsgPolicyDynamic));
fHighPerformance = new BMenuItem(
catalog.GetString("High performance", B_TRANSLATE_CONTEXT),
B_TRANSLATE("High performance"),
new BMessage(kMsgPolicyPerformance));
fLowEnergie = new BMenuItem(catalog.GetString("Low energy",
B_TRANSLATE_CONTEXT), new BMessage(kMsgPolicyLowEnergy));
fLowEnergie = new BMenuItem(B_TRANSLATE("Low energy"),
new BMessage(kMsgPolicyLowEnergy));
menu->AddItem(fDynamicPerformance);
menu->AddItem(fHighPerformance);
menu->AddItem(fLowEnergie);
fCustomStateMenu = new BMenu(catalog.GetString("Set state",
B_TRANSLATE_CONTEXT));
fCustomStateMenu = new BMenu(B_TRANSLATE("Set state"));
StateList* stateList = fInterface->GetCpuFrequencyStates();
for (int i = 0; i < stateList->CountItems(); i++) {
@ -376,8 +374,7 @@ StatusView::StatusView(BRect frame, bool inDeskbar,
B_WILL_DRAW | B_FRAME_EVENTS),
fInDeskbar(inDeskbar),
fCurrentFrequency(NULL),
fDragger(NULL),
fCatalog("x-vnd.Haiku-CPUFrequencyPref")
fDragger(NULL)
{
if (!inDeskbar) {
// we were obviously added to a standard window - let's add a dragger
@ -406,8 +403,7 @@ StatusView::StatusView(BMessage* archive)
: BView(archive),
fInDeskbar(false),
fCurrentFrequency(NULL),
fDragger(NULL),
fCatalog("x-vnd.Haiku-CPUFrequencyPref")
fDragger(NULL)
{
app_info info;
if (be_app->GetAppInfo(&info) == B_OK
@ -431,10 +427,10 @@ StatusView::~StatusView()
void
StatusView::_AboutRequested()
{
BAlert *alert = new BAlert("about", fCatalog.GetString("CPUFrequency\n"
BAlert *alert = new BAlert("about", B_TRANSLATE("CPUFrequency\n"
"\twritten by Clemens Zeidler\n"
"\tCopyright 2009, Haiku, Inc.\n", B_TRANSLATE_CONTEXT),
fCatalog.GetString("Ok", B_TRANSLATE_CONTEXT));
"\tCopyright 2009, Haiku, Inc.\n"),
B_TRANSLATE("Ok"));
BTextView *view = alert->TextView();
BFont font;
@ -514,15 +510,15 @@ StatusView::AttachedToWindow()
fPreferencesMenu->SetFont(be_plain_font);
fPreferencesMenu->AddSeparatorItem();
fOpenPrefItem = new BMenuItem(fCatalog.GetString(
"Open Speedstep preferences" B_UTF8_ELLIPSIS, B_TRANSLATE_CONTEXT),
fOpenPrefItem = new BMenuItem(B_TRANSLATE(
"Open Speedstep preferences" B_UTF8_ELLIPSIS),
new BMessage(kMsgOpenSSPreferences));
fPreferencesMenu->AddItem(fOpenPrefItem);
fOpenPrefItem->SetTarget(this);
if (fInDeskbar) {
fQuitItem= new BMenuItem(fCatalog.GetString("Quit",
B_TRANSLATE_CONTEXT), new BMessage(B_QUIT_REQUESTED));
fQuitItem= new BMenuItem(B_TRANSLATE("Quit"),
new BMessage(B_QUIT_REQUESTED));
fPreferencesMenu->AddItem(fQuitItem);
fQuitItem->SetTarget(this);
}

View File

@ -130,8 +130,6 @@ private:
BString fFreqString;
BDragger* fDragger;
BCatalog fCatalog;
};
#endif // STATUS_VIEW_H

View File

@ -31,10 +31,11 @@ BCatalog::BCatalog()
}
BCatalog::BCatalog(const char *signature, const char *language,
BCatalog::BCatalog(const entry_ref& catalogOwner, const char *language,
uint32 fingerprint)
{
//fCatalog = be_locale_roster->LoadCatalog(signature, language, fingerprint);
// Unsupported - the build tools can't (and don't need to) load anything
// this way.
}

View File

@ -12,6 +12,7 @@
#include <new>
#include <syslog.h>
#include <AppFileInfo.h>
#include <Application.h>
#include <DataIO.h>
#include <Directory.h>
@ -55,20 +56,45 @@ static int16 kCatArchiveVersion = 1;
// version of the catalog archive structure, bump this if you change it!
const char* getCatalogSignature(const entry_ref &catalogOwner)
{
// figure out mimetype from image
BFile objectFile(&catalogOwner, B_READ_ONLY);
BAppFileInfo objectInfo(&objectFile);
char objectSignature[B_MIME_TYPE_LENGTH];
if (objectInfo.GetSignature(objectSignature) != B_OK) {
log_team(LOG_ERR, "File %s has no mimesignature, so it can't use"
" localization.", catalogOwner.name);
return NULL;
}
// drop supertype from mimetype (should be "application/"):
char* stripSignature = objectSignature;
while (*stripSignature != '/')
stripSignature ++;
stripSignature ++;
log_team(LOG_DEBUG, "Image %s requested catalog with mimetype %s",
catalogOwner.name, stripSignature);
return stripSignature;
}
/*! Constructs a DefaultCatalog with given signature and language and reads
the catalog from disk.
InitCheck() will be B_OK if catalog could be loaded successfully, it will
give an appropriate error-code otherwise.
*/
DefaultCatalog::DefaultCatalog(const char *signature, const char *language,
DefaultCatalog::DefaultCatalog(const entry_ref &catalogOwner, const char *language,
uint32 fingerprint)
:
BHashMapCatalog(signature, language, fingerprint)
BHashMapCatalog(getCatalogSignature(catalogOwner), language, fingerprint)
{
fInitCheck = B_NOT_SUPPORTED;
fprintf(stderr,
"trying to load default-catalog(sig=%s, lang=%s) results in %s",
signature, language, strerror(fInitCheck));
getCatalogSignature(catalogOwner), language, strerror(fInitCheck));
}
@ -389,23 +415,11 @@ DefaultCatalog::Unflatten(BDataIO *dataIO)
BCatalogAddOn *
DefaultCatalog::Instantiate(const char *signature, const char *language,
DefaultCatalog::Instantiate(const entry_ref &catalogOwner, const char *language,
uint32 fingerprint)
{
DefaultCatalog *catalog
= new(std::nothrow) DefaultCatalog(signature, language, fingerprint);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;
}
return catalog;
}
BCatalogAddOn *
DefaultCatalog::InstantiateEmbedded(entry_ref *appOrAddOnRef)
{
DefaultCatalog *catalog = new(std::nothrow) DefaultCatalog(appOrAddOnRef);
= new(std::nothrow) DefaultCatalog(catalogOwner, language, fingerprint);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;