DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2246
Version: 1.3-current
Hi, I'm using fltk-1.3.x and fluid with gettext i18n. If I add Fl_Choice
widget to some window in fluid, and then add predefined dropdown menu to
that choice widget, then fluid will generate menu as static class member
array.
Then this array is used in constructor of window to construct choice
widget with it.
This array itself is created before main function executed, therefore
before proper locale is set. Thus gettext returns original messages, not
translated ones, and all menus in choices left untranslated.
Solution is to add it not like a static class member but local static
object in window constructor, just before it gets used. It still be
created once, as a static object, but not before main function. I tried to
modify generated code this way, it works.
I have fixed this issue as proposed, see attached patch. Please review it
and let me know if everything is ok. I have tested it with several fltk
applications that uses menus, everything works ok.
Link: http://www.fltk.org/str.php?L2246
Version: 1.3-current
Index: fluid/Fl_Menu_Type.cxx
===================================================================
--- fluid/Fl_Menu_Type.cxx (revision 6847)
+++ fluid/Fl_Menu_Type.cxx (working copy)
@@ -169,6 +169,44 @@
#include "Fluid_Image.h"
+// if menu item array belongs to class, add it as static local array to `"_" +
class_name(1)'
+// function instead of static class member because if we are using
internationalization, setting
+// locale (in main() func) happens after static and global objects
initialization, and menus created
+// as global objects or static class members left untranslated
+void Fl_Menu_Item_Type::write_arr_definition()
+{
+ const char* k = class_name(1);
+ if (k) {
+ int i; write_c("\nstatic Fl_Menu_Item %s[] = {\n", menu_name(i));
+ } else {
+ int i; write_c("\nFl_Menu_Item %s[] = {\n", menu_name(i));
+ }
+ for (Fl_Type* q = this; q && q->is_menu_item(); q = q->next)
+ {
+ ((Fl_Menu_Item_Type*)q)->write_item();
+ int thislevel = q->level; if (q->is_parent()) thislevel++;
+ int nextlevel =
+ (q->next && q->next->is_menu_item()) ? q->next->level : this->level;
+ while (thislevel > nextlevel) {write_c(" {0,0,0,0,0,0,0,0,0},\n");
thislevel--;}
+ }
+ write_c(" {0,0,0,0,0,0,0,0,0}\n};\n");
+ if (k) {
+ // Write menu item variables...
+ for (Fl_Type* q = this; q && q->is_menu_item(); q = q->next) {
+ Fl_Menu_Item_Type *m = (Fl_Menu_Item_Type*)q;
+ const char *c = array_name(m);
+ if (c) {
+ if (c==m->name()) {
+ // assign a menu item address directly to a variable
+ int i;
+ const char* n = ((Fl_Menu_Item_Type *)q)->menu_name(i);
+ write_c("%s = %s + %d;\n", c, n, i);
+ }
+ }
+ }
+ }
+}
+
void Fl_Menu_Item_Type::write_static() {
if (callback() && is_name(callback()) && !user_defined(callback()))
write_declare("extern void %s(Fl_Menu_*, %s);", callback(),
@@ -223,45 +261,9 @@
image->written = write_number;
}
}
- if (next && next->is_menu_item()) return;
- // okay, when we hit last item in the menu we have to write the
- // entire array out:
- const char* k = class_name(1);
- if (k) {
- int i; write_c("\nFl_Menu_Item %s::%s[] = {\n", k, menu_name(i));
- } else {
- int i; write_c("\nFl_Menu_Item %s[] = {\n", menu_name(i));
- }
- Fl_Type* t = prev; while (t && t->is_menu_item()) t = t->prev;
- for (Fl_Type* q = t->next; q && q->is_menu_item(); q = q->next) {
- ((Fl_Menu_Item_Type*)q)->write_item();
- int thislevel = q->level; if (q->is_parent()) thislevel++;
- int nextlevel =
- (q->next && q->next->is_menu_item()) ? q->next->level : t->level+1;
- while (thislevel > nextlevel) {write_c(" {0,0,0,0,0,0,0,0,0},\n");
thislevel--;}
- }
- write_c(" {0,0,0,0,0,0,0,0,0}\n};\n");
-
- if (k) {
- // Write menu item variables...
- t = prev; while (t && t->is_menu_item()) t = t->prev;
- for (Fl_Type* q = t->next; q && q->is_menu_item(); q = q->next) {
- Fl_Menu_Item_Type *m = (Fl_Menu_Item_Type*)q;
- const char *c = array_name(m);
- if (c) {
- if (c==m->name()) {
- // assign a menu item address directly to a variable
- int i;
- const char* n = ((Fl_Menu_Item_Type *)q)->menu_name(i);
- write_c("Fl_Menu_Item* %s::%s = %s::%s + %d;\n", k, c, k, n, i);
- } else {
- // if the name is an array, only define the array.
- // The actual assignment is in write_code1()
- write_c("Fl_Menu_Item* %s::%s;\n", k, c);
- }
- }
- }
- }
+ // if we are on first menu entry and global definition needed, add it
+ if((!prev || !prev->is_menu_item()) && !class_name(1))
+ write_arr_definition();
}
int Fl_Menu_Item_Type::flags() {
@@ -341,17 +343,18 @@
int i; const char* mname = menu_name(i);
if (!prev->is_menu_item()) {
// for first menu item, declare the array
- if (class_name(1))
- write_h(" static Fl_Menu_Item %s[];\n", mname);
- else
- write_h("extern Fl_Menu_Item %s[];\n", mname);
+ if (class_name(1)){
+ // write menu item array definition as local static if we are in class
+ write_arr_definition();
+ } else {
+ write_h("extern Fl_Menu_Item %s[];\n", mname); }
}
const char *c = array_name(this);
if (c) {
if (class_name(1)) {
write_public(public_);
- write_h(" static Fl_Menu_Item *%s;\n", c);
+ write_h(" Fl_Menu_Item *%s;\n", c);
} else {
if (c==name())
write_h("#define %s (%s+%d)\n", c, mname, i);
Index: fluid/Fl_Type.h
===================================================================
--- fluid/Fl_Type.h (revision 6847)
+++ fluid/Fl_Type.h (working copy)
@@ -577,6 +577,7 @@
const char* menu_name(int& i);
int flags();
void write_static();
+ void write_arr_definition();
void write_item();
void write_code1();
void write_code2();
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs