Karsten Hopp caf8a6
To: vim-dev@vim.org
Karsten Hopp caf8a6
Subject: Patch 7.1.285 (extra)
Karsten Hopp caf8a6
Fcc: outbox
Karsten Hopp caf8a6
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp caf8a6
Mime-Version: 1.0
Karsten Hopp caf8a6
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp caf8a6
Content-Transfer-Encoding: 8bit
Karsten Hopp caf8a6
------------
Karsten Hopp caf8a6
Karsten Hopp caf8a6
Patch 7.1.285 (extra)
Karsten Hopp caf8a6
Problem:    Mac: dialog hotkeys don't work.
Karsten Hopp caf8a6
Solution:   Add hotkey support. (Dan Sandler)
Karsten Hopp caf8a6
Files:	    src/gui_mac.c
Karsten Hopp caf8a6
Karsten Hopp caf8a6
Karsten Hopp caf8a6
*** ../vim-7.1.284/src/gui_mac.c	Wed Mar 12 21:47:31 2008
Karsten Hopp caf8a6
--- src/gui_mac.c	Sun Mar 16 15:25:13 2008
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 153,158 ****
Karsten Hopp caf8a6
--- 153,161 ----
Karsten Hopp caf8a6
  /* Keeping track of which scrollbar is being dragged */
Karsten Hopp caf8a6
  static ControlHandle dragged_sb = NULL;
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
+ /* Vector of char_u --> control index for hotkeys in dialogs */
Karsten Hopp caf8a6
+ static short *gDialogHotKeys;
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
  static struct
Karsten Hopp caf8a6
  {
Karsten Hopp caf8a6
      FMFontFamily family;
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5519,5524 ****
Karsten Hopp caf8a6
--- 5522,5570 ----
Karsten Hopp caf8a6
  	SetDialogItemText(itemHandle, itemName);
Karsten Hopp caf8a6
  }
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+ /* ModalDialog() handler for message dialogs that have hotkey accelerators.
Karsten Hopp caf8a6
+  * Expects a mapping of hotkey char to control index in gDialogHotKeys;
Karsten Hopp caf8a6
+  * setting gDialogHotKeys to NULL disables any hotkey handling.
Karsten Hopp caf8a6
+  */
Karsten Hopp caf8a6
+     static pascal Boolean
Karsten Hopp caf8a6
+ DialogHotkeyFilterProc (
Karsten Hopp caf8a6
+     DialogRef	    theDialog,
Karsten Hopp caf8a6
+     EventRecord	    *event,
Karsten Hopp caf8a6
+     DialogItemIndex *itemHit)
Karsten Hopp caf8a6
+ {
Karsten Hopp caf8a6
+     char_u keyHit;
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+     if (event->what == keyDown || event->what == autoKey)
Karsten Hopp caf8a6
+     {
Karsten Hopp caf8a6
+ 	keyHit = (event->message & charCodeMask);
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+ 	if (gDialogHotKeys && gDialogHotKeys[keyHit])
Karsten Hopp caf8a6
+ 	{
Karsten Hopp caf8a6
+ #ifdef DEBUG_MAC_DIALOG_HOTKEYS
Karsten Hopp caf8a6
+ 	    printf("user pressed hotkey '%c' --> item %d\n", keyHit, gDialogHotKeys[keyHit]);
Karsten Hopp caf8a6
+ #endif
Karsten Hopp caf8a6
+ 	    *itemHit = gDialogHotKeys[keyHit];
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+ 	    /* When handing off to StdFilterProc, pretend that the user
Karsten Hopp caf8a6
+ 	     * clicked the control manually. Note that this is also supposed
Karsten Hopp caf8a6
+ 	     * to cause the button to hilite briefly (to give some user
Karsten Hopp caf8a6
+ 	     * feedback), but this seems not to actually work (or it's too
Karsten Hopp caf8a6
+ 	     * fast to be seen).
Karsten Hopp caf8a6
+ 	     */
Karsten Hopp caf8a6
+ 	    event->what = kEventControlSimulateHit;
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+ 	    return true; /* we took care of it */
Karsten Hopp caf8a6
+ 	}
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+ 	/* Defer to the OS's standard behavior for this event.
Karsten Hopp caf8a6
+ 	 * This ensures that Enter will still activate the default button. */
Karsten Hopp caf8a6
+ 	return StdFilterProc(theDialog, event, itemHit);
Karsten Hopp caf8a6
+     }
Karsten Hopp caf8a6
+     return false;      /* Let ModalDialog deal with it */
Karsten Hopp caf8a6
+ }
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
  /* TODO: There have been some crashes with dialogs, check your inbox
Karsten Hopp caf8a6
   * (Jussi)
Karsten Hopp caf8a6
   */
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5544,5549 ****
Karsten Hopp caf8a6
--- 5590,5597 ----
Karsten Hopp caf8a6
      GrafPtr	oldPort;
Karsten Hopp caf8a6
      short	itemHit;
Karsten Hopp caf8a6
      char_u	*buttonChar;
Karsten Hopp caf8a6
+     short	hotKeys[256];		/* map of hotkey -> control ID */
Karsten Hopp caf8a6
+     char_u	aHotKey;
Karsten Hopp caf8a6
      Rect	box;
Karsten Hopp caf8a6
      short	button;
Karsten Hopp caf8a6
      short	lastButton;
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5571,5576 ****
Karsten Hopp caf8a6
--- 5619,5626 ----
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
      WindowRef	theWindow;
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
+     ModalFilterUPP dialogUPP;
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
      /* Check 'v' flag in 'guioptions': vertical button placement. */
Karsten Hopp caf8a6
      vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5610,5615 ****
Karsten Hopp caf8a6
--- 5660,5668 ----
Karsten Hopp caf8a6
      buttonChar = buttons;
Karsten Hopp caf8a6
      button = 0;
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
+     /* initialize the hotkey mapping */
Karsten Hopp caf8a6
+     memset(hotKeys, 0, sizeof(hotKeys));
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
      for (;*buttonChar != 0;)
Karsten Hopp caf8a6
      {
Karsten Hopp caf8a6
  	/* Get the name of the button */
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5619,5625 ****
Karsten Hopp caf8a6
--- 5672,5689 ----
Karsten Hopp caf8a6
  	{
Karsten Hopp caf8a6
  	    if (*buttonChar != DLG_HOTKEY_CHAR)
Karsten Hopp caf8a6
  		name[++len] = *buttonChar;
Karsten Hopp caf8a6
+ 	    else
Karsten Hopp caf8a6
+ 	    {
Karsten Hopp caf8a6
+ 		aHotKey = (char_u)*(buttonChar+1);
Karsten Hopp caf8a6
+ 		if (aHotKey >= 'A' && aHotKey <= 'Z')
Karsten Hopp caf8a6
+ 		    aHotKey = (char_u)((int)aHotKey + (int)'a' - (int)'A');
Karsten Hopp caf8a6
+ 		hotKeys[aHotKey] = button;
Karsten Hopp caf8a6
+ #ifdef DEBUG_MAC_DIALOG_HOTKEYS
Karsten Hopp caf8a6
+ 		printf("### hotKey for button %d is '%c'\n", button, aHotKey);
Karsten Hopp caf8a6
+ #endif
Karsten Hopp caf8a6
+ 	    }
Karsten Hopp caf8a6
  	}
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
  	if (*buttonChar != 0)
Karsten Hopp caf8a6
  	  buttonChar++;
Karsten Hopp caf8a6
  	name[0] = len;
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5688,5694 ****
Karsten Hopp caf8a6
--- 5752,5764 ----
Karsten Hopp caf8a6
  	(void) C2PascalString(textfield, &name);
Karsten Hopp caf8a6
  	SetDialogItemText(itemHandle, name);
Karsten Hopp caf8a6
  	inputItm.width = StringWidth(name);
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
+ 	/* Hotkeys don't make sense if there's a text field */
Karsten Hopp caf8a6
+ 	gDialogHotKeys = NULL;
Karsten Hopp caf8a6
      }
Karsten Hopp caf8a6
+     else
Karsten Hopp caf8a6
+ 	/* Install hotkey table */
Karsten Hopp caf8a6
+ 	gDialogHotKeys = (short *)&hotKeys;
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
      /* Set the <ENTER> and <ESC> button. */
Karsten Hopp caf8a6
      SetDialogDefaultItem(theDialog, dfltbutton);
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5777,5786 ****
Karsten Hopp caf8a6
      dialog_busy = TRUE;
Karsten Hopp caf8a6
  #endif
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
      /* Hang until one of the button is hit */
Karsten Hopp caf8a6
      do
Karsten Hopp caf8a6
      {
Karsten Hopp caf8a6
! 	ModalDialog(nil, &itemHit);
Karsten Hopp caf8a6
      } while ((itemHit < 1) || (itemHit > lastButton));
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
  #ifdef USE_CARBONKEYHANDLER
Karsten Hopp caf8a6
--- 5847,5859 ----
Karsten Hopp caf8a6
      dialog_busy = TRUE;
Karsten Hopp caf8a6
  #endif
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
+     /* Prepare the shortcut-handling filterProc for handing to the dialog */
Karsten Hopp caf8a6
+     dialogUPP = NewModalFilterUPP(DialogHotkeyFilterProc);
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
      /* Hang until one of the button is hit */
Karsten Hopp caf8a6
      do
Karsten Hopp caf8a6
      {
Karsten Hopp caf8a6
! 	ModalDialog(dialogUPP, &itemHit);
Karsten Hopp caf8a6
      } while ((itemHit < 1) || (itemHit > lastButton));
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
  #ifdef USE_CARBONKEYHANDLER
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 5803,5808 ****
Karsten Hopp caf8a6
--- 5876,5884 ----
Karsten Hopp caf8a6
      /* Restore the original graphical port */
Karsten Hopp caf8a6
      SetPort(oldPort);
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
+     /* Free the modal filterProc */
Karsten Hopp caf8a6
+     DisposeRoutineDescriptor(dialogUPP);
Karsten Hopp caf8a6
+ 
Karsten Hopp caf8a6
      /* Get ride of th edialog (free memory) */
Karsten Hopp caf8a6
      DisposeDialog(theDialog);
Karsten Hopp caf8a6
  
Karsten Hopp caf8a6
*** ../vim-7.1.284/src/version.c	Thu Mar 20 13:22:47 2008
Karsten Hopp caf8a6
--- src/version.c	Thu Mar 20 14:38:06 2008
Karsten Hopp caf8a6
***************
Karsten Hopp caf8a6
*** 668,669 ****
Karsten Hopp caf8a6
--- 668,671 ----
Karsten Hopp caf8a6
  {   /* Add new patch number below this line */
Karsten Hopp caf8a6
+ /**/
Karsten Hopp caf8a6
+     285,
Karsten Hopp caf8a6
  /**/
Karsten Hopp caf8a6
Karsten Hopp caf8a6
-- 
Karsten Hopp caf8a6
hundred-and-one symptoms of being an internet addict:
Karsten Hopp caf8a6
163. You go outside for the fresh air (at -30 degrees) but open the
Karsten Hopp caf8a6
     window first to hear new mail arrive.
Karsten Hopp caf8a6
Karsten Hopp caf8a6
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp caf8a6
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp caf8a6
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp caf8a6
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///