Author: manolo
Date: 2013-02-05 07:40:17 -0800 (Tue, 05 Feb 2013)
New Revision: 9813
Log:
Mac OS: internationalization support for application menu, and more text input.

Modified:
   branches/branch-3.0/documentation/src/osissues.dox
   branches/branch-3.0/include/fltk3/osx.h
   branches/branch-3.0/src/fltk3/cocoa.mm
   branches/branch-3.0/src/fltk3/run.cxx

Modified: branches/branch-3.0/documentation/src/osissues.dox
===================================================================
--- branches/branch-3.0/documentation/src/osissues.dox  2013-02-02 15:46:00 UTC 
(rev 9812)
+++ branches/branch-3.0/documentation/src/osissues.dox  2013-02-05 15:40:17 UTC 
(rev 9813)
@@ -716,10 +716,6 @@
 Attaches the callback \c cb to the "About myprog" item of the system 
application menu.
 \c cb will be called with NULL first argument and \c user_data second argument.
 
-Fl_Mac_App_Menu class
-\par 
-The Fl_Mac_App_Menu class allows to localize the application menu.
-
 Fl_Sys_Menu_Bar class
 
 \par
@@ -727,8 +723,8 @@
 placed in the system menu bar (at top-left of display), and, on other 
platforms,
 at a user-chosen location of a user-chosen window.
 
+
 \subsection osissues_quartz Drawing Things Using Quartz
-
 All code inside Fl_Widget::draw()
 is expected to call Quartz drawing functions. The Quartz coordinate system 
 is flipped to match
@@ -737,6 +733,27 @@
 \c fl_gc is the appropriate Quartz 2D drawing environment.
 Include FL/x.H to declare the \c fl_gc variable.
 
+\subsection osissues_localize Internationalization
+All FLTK programs contain an application menu with, e.g., the About xxx, Hide 
xxx, and Quit xxx items.
+This menu can be internationalized/localized by any of two means.
+\li using the Fl_Mac_App_Menu class.
+\li using the standard Mac OS X localization procedure. Create a 
language-specific .lproj directory 
+(e.g., <tt>German.lproj</tt>) in the Resources subdirectory of the application 
bundle. 
+Create therein a <tt>Localizable.strings</tt> file that translates all menu 
items to this language. 
+The German <tt>Localizable.strings</tt> file, for example, contains:
+\verbatim
+"About %@" = "Über %@";
+"Print Front Window"="Frontfenster drucken";
+"Services" = "Dienste";
+"Hide %@"="%@ ausblenden";
+"Hide Others"="Andere ausblenden";
+"Show All"="Alle einblenden";
+"Quit %@"="%@ beenden";
+\endverbatim
+Set <tt>"Print Front Window" = "";</tt> therein so the application menu 
doesn't show a "Print Front Window" item.
+To localize the application name itself, create a file 
<tt>InfoPlist.strings</tt> in each .lproj directory
+and put <tt>CFBundleName = "localized name";</tt> in each such file.
+
 Fl_Double_Window
 
 OS X double-buffers all windows automatically. On OS X,

Modified: branches/branch-3.0/include/fltk3/osx.h
===================================================================
--- branches/branch-3.0/include/fltk3/osx.h     2013-02-02 15:46:00 UTC (rev 
9812)
+++ branches/branch-3.0/include/fltk3/osx.h     2013-02-05 15:40:17 UTC (rev 
9813)
@@ -200,6 +200,7 @@
 
 /** \defgroup group_macosx Mac OS X-specific symbols
  Mac OS X-specific symbols declared in <fltk3/x.h> or <fltk3/gl.h>
+ \sa \ref osissues_macos
  @{ */
 
 /** @brief Register a function called for each file dropped onto an 
application icon.

Modified: branches/branch-3.0/src/fltk3/cocoa.mm
===================================================================
--- branches/branch-3.0/src/fltk3/cocoa.mm      2013-02-02 15:46:00 UTC (rev 
9812)
+++ branches/branch-3.0/src/fltk3/cocoa.mm      2013-02-05 15:40:17 UTC (rev 
9813)
@@ -1608,6 +1608,13 @@
  When the character palette is used to enter text, the system sends an 
insertText: message to myview. The code processes it 
  as an fltk3::PASTE event. The in_key_event field of the FLView class allows 
to differentiate keyboard from palette inputs.
  
+ During processing of the handleEvent message, inserted and marked strings are 
concatenated in a single string
+ inserted in a single fltk3::KEYBOARD event after return from handleEvent. The 
need_handle member variable of FLView allows 
+ to determine when setMarkedText or insertText strings have been sent during 
handleEvent processing, and therefore 
+ an fltk3::KEYBOARD event is needed. Concatenating two insertText operations 
or an insertText followed by a setMarkedText is possible. 
+ In contrast, setMarkedText followed by insertText or by another setMarkedText 
isn't correct if concatenated in a single 
+ string. Thus, in such case, the setMarkedText and the next operation produce 
each an fltk3::KEYBOARD event.  
+ 
  OS >= 10.7 contains a feature where pressing and holding certain keys opens a 
menu window that shows a list 
  of possible accented variants of this key. The selectedRange field of the 
FLView class and the selectedRange, insertText:
  and setMarkedText: methods of the NSTextInputClient protocol are used to 
support this feature.
@@ -1705,11 +1712,13 @@
 #endif
 > {
   @private
-  BOOL in_key_event;
+  BOOL in_key_event; // YES means keypress is being processed by handleEvent
+  BOOL need_handle; // YES means fltk3::handle(fltk3::KEYBOARD,) is needed 
after handleEvent processing
   NSInteger identifier;
   NSRange selectedRange;
 }
 + (void)prepareEtext:(NSString*)aString;
++ (void)concatEtext:(NSString*)aString;
 - (id)init;
 - (void)drawRect:(NSRect)rect;
 - (BOOL)acceptsFirstResponder;
@@ -1785,7 +1794,9 @@
   }
   else {
     in_key_event = YES;
+    need_handle = NO;
     handled = [[self performSelector:inputContextSEL] handleEvent:theEvent];
+    if (need_handle) handled = fltk3::handle(fltk3::KEYBOARD, 
[(FLWindow*)[theEvent window] getFl_Window]);
     in_key_event = NO;
   }
   fl_unlock_function();
@@ -1837,7 +1848,9 @@
   fltk3::first_window(window);
   cocoaKeyboardHandler(theEvent);
   in_key_event = YES;
+  need_handle = NO;
   [[self performSelector:inputContextSEL] handleEvent:theEvent];
+  if (need_handle) fltk3::handle(fltk3::KEYBOARD, window);
   in_key_event = NO;
   fl_unlock_function();
 }
@@ -1995,6 +2008,12 @@
   fltk3::e_length = l;
 }
 
++ (void)concatEtext:(NSString*)aString {
+  // extends fltk3::e_text with aString
+  NSString *newstring = [[NSString stringWithUTF8String:fltk3::e_text] 
stringByAppendingString:aString];
+  [FLView prepareEtext:newstring];
+}
+
 - (void)doCommandBySelector:(SEL)aSelector {
   //NSLog(@"doCommandBySelector:%s",sel_getName(aSelector));
   [FLView prepareEtext:[[NSApp currentEvent] characters]];
@@ -2023,12 +2042,19 @@
     fltk3::handle(fltk3::KEYBOARD, target);
     fltk3::e_keysym = saved_keysym;
   }
-  [FLView prepareEtext:received];
+  if (in_key_event && Fl_X::next_marked_length && fltk3::e_length) {
+    // if setMarkedText + insertText is sent during handleEvent, text cannot 
be concatenated in single fltk3::KEYBOARD event
+    fltk3::handle(fltk3::KEYBOARD, target);
+    fltk3::e_length = 0;
+  }
+  if (in_key_event && fltk3::e_length) [FLView concatEtext:received];
+  else [FLView prepareEtext:received];
   // We can get called outside of key events (e.g., from the character 
palette, from CJK text input). 
   // Transform character palette actions to fltk3::PASTE events.
   Fl_X::next_marked_length = 0;
   int flevent = (in_key_event || fltk3::marked_text_length()) ? 
fltk3::KEYBOARD : fltk3::PASTE;
-  fltk3::handle( flevent, target);
+  if (!in_key_event) fltk3::handle( flevent, target);
+  else need_handle = YES;
   selectedRange = NSMakeRange(100, 0); // 100 is an arbitrary value
   // for some reason, with the palette, the window does not redraw until the 
next mouse move or button push
   // sending a 'redraw()' or 'awake()' does not solve the issue!
@@ -2060,9 +2086,16 @@
     fltk3::handle(fltk3::KEYBOARD, target);
     fltk3::e_keysym = 'a'; // pretend a letter key was hit
   }
-  [FLView prepareEtext:received];
-  Fl_X::next_marked_length = fltk3::e_length;
-  fltk3::handle(fltk3::KEYBOARD, target);
+  if (in_key_event && Fl_X::next_marked_length && fltk3::e_length) {
+    // if setMarkedText + setMarkedText is sent during handleEvent, text 
cannot be concatenated in single fltk3::KEYBOARD event
+    fltk3::handle(fltk3::KEYBOARD, target);
+    fltk3::e_length = 0;
+  }
+  if (in_key_event && fltk3::e_length) [FLView concatEtext:received];
+  else [FLView prepareEtext:received];
+  Fl_X::next_marked_length = strlen([received UTF8String]);
+  if (!in_key_event) fltk3::handle( fltk3::KEYBOARD, target);
+  else need_handle = YES;
   selectedRange = NSMakeRange(100, newSelection.length);
   fl_unlock_function();
 }
@@ -3039,20 +3072,22 @@
   NSMenuItem *menuItem;
   NSString *title;
 
-  NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] 
objectForKey:@"CFBundleName"];
+  SEL infodictSEL = (fl_mac_os_version >= 100200 ? 
@selector(localizedInfoDictionary) : @selector(infoDictionary));
+  NSString *nsappname = [[[NSBundle mainBundle] performSelector:infodictSEL] 
objectForKey:@"CFBundleName"];  
   if (nsappname == nil)
     nsappname = [[NSProcessInfo processInfo] processName];
   appleMenu = [[NSMenu alloc] initWithTitle:@""];
   /* Add menu items */
-  title = [[NSString stringWithUTF8String:Fl_Mac_App_Menu::about] 
stringByAppendingString:nsappname];
+  title = [NSString stringWithFormat:NSLocalizedString([NSString 
stringWithUTF8String:Fl_Mac_App_Menu::about],nil), nsappname];
   menuItem = [appleMenu addItemWithTitle:title action:@selector(showPanel) 
keyEquivalent:@""];
   FLaboutItemTarget *about = [[FLaboutItemTarget alloc] init];
   [menuItem setTarget:about];
   [appleMenu addItem:[NSMenuItem separatorItem]];
   // Print front window
-  if (strlen(Fl_Mac_App_Menu::print) > 0) {
+  title = NSLocalizedString([NSString 
stringWithUTF8String:Fl_Mac_App_Menu::print], nil);
+  if ([title length] > 0) {
     menuItem = [appleMenu 
-               addItemWithTitle:[NSString 
stringWithUTF8String:Fl_Mac_App_Menu::print] 
+               addItemWithTitle:title 
                action:@selector(printPanel) 
                keyEquivalent:@""];
     [menuItem setTarget:about];
@@ -3064,29 +3099,29 @@
     // Services Menu
     services = [[NSMenu alloc] init];
     menuItem = [appleMenu 
-               addItemWithTitle:[NSString 
stringWithUTF8String:Fl_Mac_App_Menu::services] 
+               addItemWithTitle:NSLocalizedString([NSString 
stringWithUTF8String:Fl_Mac_App_Menu::services], nil)
                action:nil 
                keyEquivalent:@""];
     [appleMenu setSubmenu:services forItem:menuItem];
     [appleMenu addItem:[NSMenuItem separatorItem]];
     // Hide AppName
-    title = [[NSString stringWithUTF8String:Fl_Mac_App_Menu::hide] 
stringByAppendingString:nsappname];
+    title = [NSString stringWithFormat:NSLocalizedString([NSString 
stringWithUTF8String:Fl_Mac_App_Menu::hide],nil), nsappname];
     [appleMenu addItemWithTitle:title 
                         action:@selector(hide:) 
                  keyEquivalent:@"h"];
     // Hide Others
     menuItem = [appleMenu 
-               addItemWithTitle:[NSString 
stringWithUTF8String:Fl_Mac_App_Menu::hide_others] 
+               addItemWithTitle:NSLocalizedString([NSString 
stringWithUTF8String:Fl_Mac_App_Menu::hide_others] , nil)
                action:@selector(hideOtherApplications:) 
                keyEquivalent:@"h"];
     [menuItem 
setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
     // Show All
-    [appleMenu addItemWithTitle:[NSString 
stringWithUTF8String:Fl_Mac_App_Menu::show] 
+    [appleMenu addItemWithTitle:NSLocalizedString([NSString 
stringWithUTF8String:Fl_Mac_App_Menu::show] , nil)
                         action:@selector(unhideAllApplications:) 
keyEquivalent:@""];
     [appleMenu addItem:[NSMenuItem separatorItem]];
     // Quit AppName
-    title = [[NSString stringWithUTF8String:Fl_Mac_App_Menu::quit] 
-            stringByAppendingString:nsappname];
+    title = [NSString stringWithFormat:NSLocalizedString([NSString 
stringWithUTF8String:Fl_Mac_App_Menu::quit] , nil),
+            nsappname];
     [appleMenu addItemWithTitle:title 
                         action:@selector(terminate:) 
                  keyEquivalent:@"q"];

Modified: branches/branch-3.0/src/fltk3/run.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/run.cxx       2013-02-02 15:46:00 UTC (rev 
9812)
+++ branches/branch-3.0/src/fltk3/run.cxx       2013-02-05 15:40:17 UTC (rev 
9813)
@@ -84,13 +84,13 @@
 // Globals...
 //
 #if defined(__APPLE__) || defined(FLTK3_DOXYGEN)
-const char *Fl_Mac_App_Menu::about = "About ";
+const char *Fl_Mac_App_Menu::about = "About %@";
 const char *Fl_Mac_App_Menu::print = "Print Front Window";
 const char *Fl_Mac_App_Menu::services = "Services";
-const char *Fl_Mac_App_Menu::hide = "Hide ";
+const char *Fl_Mac_App_Menu::hide = "Hide %@";
 const char *Fl_Mac_App_Menu::hide_others = "Hide Others";
 const char *Fl_Mac_App_Menu::show = "Show All";
-const char *Fl_Mac_App_Menu::quit = "Quit ";
+const char *Fl_Mac_App_Menu::quit = "Quit %@";
 #endif // __APPLE__
 #ifndef FLTK3_DOXYGEN
 fltk3::Widget  *fltk3::belowmouse_,

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to