Fix 8172: Time preflet being too slow to start.
* looking at the profile info kindly supplied by diver hinted at getting the timezones for each country individually being part of the problem, using BLocaleRoster::GetAvailableTimeZonesWithRegionInfo() helps considerably * further improve the situation by only requesting the localized display name of a timezone when it is actually needed (i.e. when there are more than a single timezone in the current country) Testing with VMware on my slowest machine, this brings down the start time of the Time preflet from 5 seconds to 1.5 seconds.
This commit is contained in:
parent
635df64352
commit
eb78be9b27
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
@ -301,10 +302,6 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
BLanguage language;
|
BLanguage language;
|
||||||
BLocale::Default()->GetLanguage(&language);
|
BLocale::Default()->GetLanguage(&language);
|
||||||
|
|
||||||
BMessage countryList;
|
|
||||||
BLocaleRoster::Default()->GetAvailableCountries(&countryList);
|
|
||||||
countryList.AddString("country", "");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Group timezones by regions, but filter out unwanted (duplicate) regions
|
* Group timezones by regions, but filter out unwanted (duplicate) regions
|
||||||
* and add an additional region with generic GMT-offset timezones at the end
|
* and add an additional region with generic GMT-offset timezones at the end
|
||||||
@ -335,68 +332,71 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
zoneItemMap[translatedRegion] = regionItem;
|
zoneItemMap[translatedRegion] = regionItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get all time zones
|
||||||
|
BMessage zoneList;
|
||||||
|
BLocaleRoster::Default()->GetAvailableTimeZonesWithRegionInfo(&zoneList);
|
||||||
|
|
||||||
|
typedef std::map<BString, std::vector<const char*> > ZonesByCountyMap;
|
||||||
|
ZonesByCountyMap zonesByCountryMap;
|
||||||
|
const char *zoneID;
|
||||||
BString countryCode;
|
BString countryCode;
|
||||||
for (int c = 0; countryList.FindString("country", c, &countryCode)
|
for (int tz = 0; zoneList.FindString("timeZone", tz, &zoneID) == B_OK
|
||||||
== B_OK; c++) {
|
&& zoneList.FindString("region", tz, &countryCode) == B_OK; tz++) {
|
||||||
BCountry country(countryCode);
|
// From the global ("001") timezones, we only accept the generic GMT
|
||||||
|
// timezones, as all the other world-zones are duplicates of others.
|
||||||
|
if (countryCode == "001" && strncmp(zoneID, "Etc/GMT", 7) != 0)
|
||||||
|
continue;
|
||||||
|
zonesByCountryMap[countryCode].push_back(zoneID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZonesByCountyMap::const_iterator countryIter = zonesByCountryMap.begin();
|
||||||
|
for (; countryIter != zonesByCountryMap.end(); ++countryIter) {
|
||||||
|
BCountry country(countryIter->first.String());
|
||||||
BString countryName;
|
BString countryName;
|
||||||
country.GetName(countryName);
|
country.GetName(countryName);
|
||||||
|
|
||||||
// Now list the timezones for this country
|
size_t zoneCountInCountry = countryIter->second.size();
|
||||||
BMessage zoneList;
|
for (size_t tz = 0; tz < zoneCountInCountry; tz++) {
|
||||||
BLocaleRoster::Default()->GetAvailableTimeZonesForCountry(&zoneList,
|
BString zoneID(countryIter->second[tz]);
|
||||||
countryCode.Length() == 0 ? NULL : countryCode.String());
|
|
||||||
|
|
||||||
int32 count = 0;
|
|
||||||
type_code dummy;
|
|
||||||
zoneList.GetInfo("timeZone", &dummy, &count);
|
|
||||||
|
|
||||||
BString zoneID;
|
|
||||||
for (int tz = 0; zoneList.FindString("timeZone", tz, &zoneID) == B_OK;
|
|
||||||
tz++) {
|
|
||||||
int32 slashPos = zoneID.FindFirst('/');
|
int32 slashPos = zoneID.FindFirst('/');
|
||||||
|
|
||||||
// ignore any "global" timezones, as those are just aliases of
|
|
||||||
// regional ones
|
|
||||||
if (slashPos <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
BString region(zoneID, slashPos);
|
BString region(zoneID, slashPos);
|
||||||
|
|
||||||
if (region == "Etc")
|
if (region == "Etc")
|
||||||
region = kOtherRegion;
|
region = kOtherRegion;
|
||||||
else if (countryName.Length() == 0) {
|
|
||||||
// skip global timezones from other regions, we are just
|
|
||||||
// interested in the generic GMT-based ones under "Etc/"
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// just accept timezones from our supported regions, others are
|
// just accept timezones from our supported regions, others are
|
||||||
// aliases and would just make the list even longer
|
// aliases and would just make the list even longer
|
||||||
TranslatedRegionMap::iterator regionIter = regionMap.find(region);
|
TranslatedRegionMap::iterator regionIter = regionMap.find(region);
|
||||||
if (regionIter == regionMap.end())
|
if (regionIter == regionMap.end())
|
||||||
continue;
|
continue;
|
||||||
const BString& regionName = regionIter->second;
|
|
||||||
|
|
||||||
BString fullCountryID = regionName;
|
BString fullCountryID = regionIter->second;
|
||||||
bool countryIsRegion = countryName == regionName;
|
bool countryIsRegion
|
||||||
|
= countryName == regionIter->second || region == kOtherRegion;
|
||||||
if (!countryIsRegion)
|
if (!countryIsRegion)
|
||||||
fullCountryID << "/" << countryName;
|
fullCountryID << "/" << countryName;
|
||||||
|
|
||||||
BTimeZone* timeZone = new BTimeZone(zoneID, &language);
|
BTimeZone* timeZone = new BTimeZone(zoneID, &language);
|
||||||
BString tzName = timeZone->Name();
|
BString tzName;
|
||||||
if (tzName == "GMT+00:00")
|
|
||||||
tzName = "GMT";
|
|
||||||
|
|
||||||
int32 openParenthesisPos = tzName.FindFirst('(');
|
|
||||||
if (openParenthesisPos >= 0) {
|
|
||||||
tzName.Remove(0, openParenthesisPos + 1);
|
|
||||||
int32 closeParenthesisPos = tzName.FindLast(')');
|
|
||||||
if (closeParenthesisPos >= 0)
|
|
||||||
tzName.Truncate(closeParenthesisPos);
|
|
||||||
}
|
|
||||||
BString fullZoneID = fullCountryID;
|
BString fullZoneID = fullCountryID;
|
||||||
fullZoneID << "/" << tzName;
|
if (zoneCountInCountry > 1)
|
||||||
|
{
|
||||||
|
// we can't use the country name as timezone name, since there
|
||||||
|
// are more than one timezones in this country - fetch the
|
||||||
|
// localized name of the timezone and use that
|
||||||
|
tzName = timeZone->Name();
|
||||||
|
int32 openParenthesisPos = tzName.FindFirst('(');
|
||||||
|
if (openParenthesisPos >= 0) {
|
||||||
|
tzName.Remove(0, openParenthesisPos + 1);
|
||||||
|
int32 closeParenthesisPos = tzName.FindLast(')');
|
||||||
|
if (closeParenthesisPos >= 0)
|
||||||
|
tzName.Truncate(closeParenthesisPos);
|
||||||
|
}
|
||||||
|
fullZoneID << "/" << tzName;
|
||||||
|
} else {
|
||||||
|
tzName = countryName;
|
||||||
|
fullZoneID << "/" << zoneID;
|
||||||
|
}
|
||||||
|
|
||||||
// skip duplicates
|
// skip duplicates
|
||||||
ZoneItemMap::iterator zoneIter = zoneItemMap.find(fullZoneID);
|
ZoneItemMap::iterator zoneIter = zoneItemMap.find(fullZoneID);
|
||||||
@ -407,7 +407,7 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
|
|
||||||
TimeZoneListItem* countryItem = NULL;
|
TimeZoneListItem* countryItem = NULL;
|
||||||
TimeZoneListItem* zoneItem = NULL;
|
TimeZoneListItem* zoneItem = NULL;
|
||||||
if (count > 1 && countryName.Length() > 0) {
|
if (zoneCountInCountry > 1) {
|
||||||
ZoneItemMap::iterator countryIter
|
ZoneItemMap::iterator countryIter
|
||||||
= zoneItemMap.find(fullCountryID);
|
= zoneItemMap.find(fullCountryID);
|
||||||
if (countryIter == zoneItemMap.end()) {
|
if (countryIter == zoneItemMap.end()) {
|
||||||
@ -420,8 +420,7 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
zoneItem = new TimeZoneListItem(tzName, NULL, timeZone);
|
zoneItem = new TimeZoneListItem(tzName, NULL, timeZone);
|
||||||
zoneItem->SetOutlineLevel(countryIsRegion ? 1 : 2);
|
zoneItem->SetOutlineLevel(countryIsRegion ? 1 : 2);
|
||||||
} else {
|
} else {
|
||||||
BString& name = countryName.Length() > 0 ? countryName : tzName;
|
zoneItem = new TimeZoneListItem(tzName, NULL, timeZone);
|
||||||
zoneItem = new TimeZoneListItem(name, NULL, timeZone);
|
|
||||||
zoneItem->SetOutlineLevel(1);
|
zoneItem->SetOutlineLevel(1);
|
||||||
}
|
}
|
||||||
zoneItemMap[fullZoneID] = zoneItem;
|
zoneItemMap[fullZoneID] = zoneItem;
|
||||||
@ -431,7 +430,7 @@ TimeZoneView::_BuildZoneMenu()
|
|||||||
if (countryItem != NULL)
|
if (countryItem != NULL)
|
||||||
countryItem->SetExpanded(true);
|
countryItem->SetExpanded(true);
|
||||||
ZoneItemMap::iterator regionItemIter
|
ZoneItemMap::iterator regionItemIter
|
||||||
= zoneItemMap.find(regionName);
|
= zoneItemMap.find(regionIter->second);
|
||||||
if (regionItemIter != zoneItemMap.end())
|
if (regionItemIter != zoneItemMap.end())
|
||||||
regionItemIter->second->SetExpanded(true);
|
regionItemIter->second->SetExpanded(true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user