View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0004186 | NoesisGUI | Studio | public | 2025-05-23 10:34 | 2026-01-27 17:34 |
| Reporter | Kamo | Assigned To | maherne | ||
| Priority | normal | Severity | minor | ||
| Status | resolved | Resolution | fixed | ||
| Product Version | Studio_Beta | ||||
| Target Version | Studio_Beta | Fixed in Version | Studio_Beta | ||
| Summary | 0004186: Localization with merged dictionaries doesn't work | ||||
| Description | In case you have merged dictionaries set, the ResourceKey dropwdown won't show any localization keys to select from even though language_jp.xaml has some. The workaround is to select language_jp.xaml directly for Localization source but that will not have all the values I want | ||||
| Platform | Any | ||||
|
As mentioned by the client, it would be good to sort the keys in the dropdown. |
|
|
The attached patch updates the localization key property with sorted keys, and support for merged dictionaries. LocExtensionKey.patch (5,809 bytes)
Index: LocalizationResourceKeyProperty.cpp
===================================================================
--- LocalizationResourceKeyProperty.cpp (revision 16539)
+++ LocalizationResourceKeyProperty.cpp (working copy)
@@ -22,6 +22,69 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
+static void AddResourceKey(const Type* search, HashSet<Symbol>* keys,
+ const char* key, BaseComponent* value)
+{
+ if (value == nullptr)
+ {
+ return;
+ }
+
+ Symbol keySym(key, Symbol::NullIfNotFound());
+ if (keySym.IsNull() || (!keySym.IsNull() && Reflection::GetType(keySym) != nullptr))
+ {
+ return;
+ }
+
+ // Only check if type matches if we're not searching for generic BaseComponent
+ if (search != TypeOf<BaseComponent>())
+ {
+ // Find the actual type of the resource
+ const Type* resType = value->GetClassType();
+ if (Helper::IsType<BoxedValue>(value))
+ {
+ resType = ((BoxedValue*)value)->GetValueType();
+ }
+ else
+ {
+ resType = Helper::ExtractComponentType(resType);
+ }
+ if (resType == nullptr)
+ {
+ resType = value->GetClassType();
+ }
+
+ if (resType && !search->IsAssignableFrom(resType))
+ {
+ return;
+ }
+ }
+
+ keys->Insert(keySym);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+static void ProcessResources(const ResourceDictionary* resources, const Type* searchType,
+ HashSet<Symbol>* keys)
+{
+ if (resources == nullptr)
+ {
+ return;
+ }
+
+ resources->EnumKeyValues([&searchType, &keys](const char* key, BaseComponent* value)
+ {
+ AddResourceKey(searchType, keys, key, value);
+ });
+
+ ResourceDictionaryCollection* collection = resources->GetMergedDictionaries();
+ for (int i = 0; i < collection->Count(); i++)
+ {
+ ProcessResources(collection->Get(i), searchType, keys);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
LocalizationResourceKeyProperty::LocalizationResourceKeyProperty(BasePropertySource* src):
Property(src), mRefreshing(false)
{
@@ -115,56 +178,24 @@
}
}
- // Gather all keys from the dictionary
+ // Gather all keys from this dictionary, and all merged dictionaries
if (resources && searchType)
{
- // TODO: search merged dictionaries?
- struct Params
+ HashSet<Symbol> keys;
+ ProcessResources(resources, searchType, &keys);
+ for (Symbol key : keys)
{
- const Type* search;
- Collection<Boxed<String>>* keys;
- } params = { searchType, &mKeys };
-
- // Go through resources
- resources->EnumKeyValues([¶ms](const char* key, BaseComponent* value)
- {
- if (value == nullptr)
+ int32_t insertIndex = 0;
+ for (; insertIndex < mKeys.Count(); insertIndex++)
{
- return;
- }
-
- // Only check if type matches if we're not searching for generic BaseComponent
- if (params.search != TypeOf<BaseComponent>())
- {
- // Find the actual type of the resource
- const Type* resType = value->GetClassType();
- if (Helper::IsType<BoxedValue>(value))
+ if (StrCaseCompare(Boxing::Unbox<String>(mKeys.Get(insertIndex)).Str(), key.Str())
+ > 0)
{
- resType = ((BoxedValue*)value)->GetValueType();
+ break;
}
- else
- {
- resType = Helper::ExtractComponentType(resType);
- }
- if (resType == nullptr)
- {
- resType = value->GetClassType();
- }
-
- if (resType && !params.search->IsAssignableFrom(resType))
- {
- return;
- }
}
-
- Symbol keySym(key, Symbol::NullIfNotFound());
- if (keySym != Symbol::Null() && Reflection::GetType(keySym) != nullptr)
- {
- return;
- }
-
- params.keys->Add((Boxed<String>*)Boxing::Box<String>(key).GetPtr());
- });
+ mKeys.Insert(insertIndex, (Boxed<String>*)Boxing::Box<String>(key.Str()).GetPtr());
+ }
}
}
@@ -193,7 +224,7 @@
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-const Collection<Boxed<String>>* LocalizationResourceKeyProperty::GetKeys() const
+const ObservableCollection<Boxed<String>>* LocalizationResourceKeyProperty::GetKeys() const
{
return &mKeys;
}
Index: LocalizationResourceKeyProperty.h
===================================================================
--- LocalizationResourceKeyProperty.h (revision 16539)
+++ LocalizationResourceKeyProperty.h (working copy)
@@ -32,10 +32,10 @@
void Refresh() override;
// Get list of keys
- const Noesis::Collection<Noesis::Boxed<Noesis::String>>* GetKeys() const;
+ const Noesis::ObservableCollection<Noesis::Boxed<Noesis::String>>* GetKeys() const;
private:
- Noesis::Collection<Noesis::Boxed<Noesis::String>> mKeys;
+ Noesis::ObservableCollection<Noesis::Boxed<Noesis::String>> mKeys;
bool mRefreshing;
NS_DECLARE_REFLECTION(LocalizationResourceKeyProperty, Property)
|
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2025-05-23 10:34 | Kamo | New Issue | |
| 2025-05-27 19:36 | jsantos | Assigned To | => sfernandez |
| 2025-05-27 19:36 | jsantos | Status | new => assigned |
| 2025-05-27 19:36 | jsantos | Product Version | => Studio_Beta |
| 2025-05-27 19:36 | jsantos | Target Version | => Studio_Beta |
| 2025-05-27 19:37 | jsantos | Product Version | Studio_Beta => 3.2.6 |
| 2025-05-27 19:37 | jsantos | Target Version | Studio_Beta => 3.2.8 |
| 2025-05-27 19:38 | jsantos | Product Version | 3.2.6 => Studio_Beta |
| 2025-05-27 19:38 | jsantos | Target Version | 3.2.8 => Studio_Beta |
| 2026-01-13 11:20 | sfernandez | Assigned To | sfernandez => maherne |
| 2026-01-13 11:20 | sfernandez | Description Updated | |
| 2026-01-13 11:20 | sfernandez | Note Added: 0011689 | |
| 2026-01-27 13:36 | maherne | Note Added: 0011779 | |
| 2026-01-27 13:36 | maherne | File Added: LocExtensionKey.patch | |
| 2026-01-27 17:34 | sfernandez | Status | assigned => resolved |
| 2026-01-27 17:34 | sfernandez | Resolution | open => fixed |
| 2026-01-27 17:34 | sfernandez | Fixed in Version | => Studio_Beta |