Karsten Hopp 0d32bf
To: vim-dev@vim.org
Karsten Hopp 0d32bf
Subject: patch 7.0.232 (extra)
Karsten Hopp 0d32bf
Fcc: outbox
Karsten Hopp 0d32bf
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 0d32bf
Mime-Version: 1.0
Karsten Hopp 0d32bf
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp 0d32bf
Content-Transfer-Encoding: 8bit
Karsten Hopp 0d32bf
------------
Karsten Hopp 0d32bf
Karsten Hopp 0d32bf
Patch 7.0.232 (extra)
Karsten Hopp 0d32bf
Problem:    Mac: doesn't support GUI tab page labels.
Karsten Hopp 0d32bf
Solution:   Add GUI tab page labels. (Nicolas Weber)
Karsten Hopp 0d32bf
Files:	    src/feature.h, src/gui.c, src/gui.h, src/gui_mac.c,
Karsten Hopp 0d32bf
	    src/proto/gui_mac.pro
Karsten Hopp 0d32bf
Karsten Hopp 0d32bf
Karsten Hopp 0d32bf
*** ../vim-7.0.231/src/feature.h	Wed Nov  1 18:10:36 2006
Karsten Hopp 0d32bf
--- src/feature.h	Thu Mar 15 19:02:15 2007
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 756,761 ****
Karsten Hopp 0d32bf
--- 756,762 ----
Karsten Hopp 0d32bf
  #if defined(FEAT_WINDOWS) && defined(FEAT_NORMAL) \
Karsten Hopp 0d32bf
      && (defined(FEAT_GUI_GTK) \
Karsten Hopp 0d32bf
  	|| (defined(FEAT_GUI_MOTIF) && defined(HAVE_XM_NOTEBOOK_H)) \
Karsten Hopp 0d32bf
+ 	|| defined(FEAT_GUI_MAC) \
Karsten Hopp 0d32bf
  	|| (defined(FEAT_GUI_MSWIN) && (!defined(_MSC_VER) || _MSC_VER > 1020)))
Karsten Hopp 0d32bf
  # define FEAT_GUI_TABLINE
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
*** ../vim-7.0.231/src/gui.c	Tue Oct 10 17:36:50 2006
Karsten Hopp 0d32bf
--- src/gui.c	Thu Mar 15 19:02:15 2007
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 1159,1165 ****
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
  # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
Karsten Hopp 0d32bf
! 	|| defined(FEAT_GUI_MOTIF))
Karsten Hopp 0d32bf
      if (gui_has_tabline())
Karsten Hopp 0d32bf
  	text_area_y += gui.tabline_height;
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
--- 1159,1165 ----
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
  # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
Karsten Hopp 0d32bf
!  	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
Karsten Hopp 0d32bf
      if (gui_has_tabline())
Karsten Hopp 0d32bf
  	text_area_y += gui.tabline_height;
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
*** ../vim-7.0.231/src/gui.h	Thu Apr 27 01:52:33 2006
Karsten Hopp 0d32bf
--- src/gui.h	Thu Mar 15 19:02:15 2007
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 421,427 ****
Karsten Hopp 0d32bf
  #endif	/* FEAT_GUI_GTK */
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
  #if defined(FEAT_GUI_TABLINE) \
Karsten Hopp 0d32bf
! 	&& (defined(FEAT_GUI_W32) || defined(FEAT_GUI_MOTIF))
Karsten Hopp 0d32bf
      int		tabline_height;
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
--- 425,432 ----
Karsten Hopp 0d32bf
  #endif	/* FEAT_GUI_GTK */
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
  #if defined(FEAT_GUI_TABLINE) \
Karsten Hopp 0d32bf
!  	&& (defined(FEAT_GUI_W32) || defined(FEAT_GUI_MOTIF) \
Karsten Hopp 0d32bf
!                  || defined(FEAT_GUI_MAC))
Karsten Hopp 0d32bf
      int		tabline_height;
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
*** ../vim-7.0.231/src/gui_mac.c	Thu Mar  8 20:39:02 2007
Karsten Hopp 0d32bf
--- src/gui_mac.c	Fri Mar 16 11:26:05 2007
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 4,10 ****
Karsten Hopp 0d32bf
   *				GUI/Motif support by Robert Webb
Karsten Hopp 0d32bf
   *				Macintosh port by Dany St-Amant
Karsten Hopp 0d32bf
   *					      and Axel Kielhorn
Karsten Hopp 0d32bf
!  *				Port to MPW by Bernhard PrŸmmer
Karsten Hopp 0d32bf
   *				Initial Carbon port by Ammon Skidmore
Karsten Hopp 0d32bf
   *
Karsten Hopp 0d32bf
   * Do ":help uganda"  in Vim to read copying and usage conditions.
Karsten Hopp 0d32bf
--- 4,10 ----
Karsten Hopp 0d32bf
   *				GUI/Motif support by Robert Webb
Karsten Hopp 0d32bf
   *				Macintosh port by Dany St-Amant
Karsten Hopp 0d32bf
   *					      and Axel Kielhorn
Karsten Hopp 0d32bf
!  *				Port to MPW by Bernhard Pruemmer
Karsten Hopp 0d32bf
   *				Initial Carbon port by Ammon Skidmore
Karsten Hopp 0d32bf
   *
Karsten Hopp 0d32bf
   * Do ":help uganda"  in Vim to read copying and usage conditions.
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 260,265 ****
Karsten Hopp 0d32bf
--- 260,270 ----
Karsten Hopp 0d32bf
  OSErr HandleUnusedParms(const AppleEvent *theAEvent);
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
+ #ifdef FEAT_GUI_TABLINE
Karsten Hopp 0d32bf
+ static void initialise_tabline(void);
Karsten Hopp 0d32bf
+ static WindowRef drawer = NULL; // TODO: put into gui.h
Karsten Hopp 0d32bf
+ #endif
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
  /*
Karsten Hopp 0d32bf
   * ------------------------------------------------------------
Karsten Hopp 0d32bf
   * Conversion Utility
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 2357,2362 ****
Karsten Hopp 0d32bf
--- 2323,2335 ----
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
      thePart = FindWindow(theEvent->where, &whichWindow);
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
+ #ifdef FEAT_GUI_TABLINE
Karsten Hopp 0d32bf
+     /* prevent that the vim window size changes if it's activated by a
Karsten Hopp 0d32bf
+        click into the tab pane */
Karsten Hopp 0d32bf
+     if (whichWindow == drawer)
Karsten Hopp 0d32bf
+         return;
Karsten Hopp 0d32bf
+ #endif
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
      switch (thePart)
Karsten Hopp 0d32bf
      {
Karsten Hopp 0d32bf
  	case (inDesk):
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 3097,3102 ****
Karsten Hopp 0d32bf
--- 3070,3082 ----
Karsten Hopp 0d32bf
  #endif
Karsten Hopp 0d32bf
  */
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
+ #ifdef FEAT_GUI_TABLINE
Karsten Hopp 0d32bf
+     /*
Karsten Hopp 0d32bf
+      * Create the tabline
Karsten Hopp 0d32bf
+      */
Karsten Hopp 0d32bf
+     initialise_tabline();
Karsten Hopp 0d32bf
+ #endif
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
      /* TODO: Load bitmap if using TOOLBAR */
Karsten Hopp 0d32bf
      return OK;
Karsten Hopp 0d32bf
  }
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 5895,5901 ****
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioFDirIndex = 0;
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioNamePtr   = file.name;
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioVRefNum   = file.vRefNum;
Karsten Hopp 0d32bf
!   /*theCPB.hFileInfo.ioDirID   = 0;*/
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioDrDirID   = file.parID;
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
      /* As ioFDirIndex = 0, get the info of ioNamePtr,
Karsten Hopp 0d32bf
--- 5875,5881 ----
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioFDirIndex = 0;
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioNamePtr   = file.name;
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioVRefNum   = file.vRefNum;
Karsten Hopp 0d32bf
!     /*theCPB.hFileInfo.ioDirID   = 0;*/
Karsten Hopp 0d32bf
      theCPB.dirInfo.ioDrDirID   = file.parID;
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
      /* As ioFDirIndex = 0, get the info of ioNamePtr,
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 6093,6096 ****
Karsten Hopp 0d32bf
--- 6073,6479 ----
Karsten Hopp 0d32bf
      return (script != smRoman
Karsten Hopp 0d32bf
  	    && script == GetScriptManagerVariable(smSysScript)) ? 1 : 0;
Karsten Hopp 0d32bf
  }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
  #endif /* defined(USE_IM_CONTROL) || defined(PROTO) */
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
Karsten Hopp 0d32bf
+ // drawer implementation
Karsten Hopp 0d32bf
+ static MenuRef contextMenu = NULL;
Karsten Hopp 0d32bf
+ enum
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     kTabContextMenuId = 42,
Karsten Hopp 0d32bf
+ };
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // the caller has to CFRelease() the returned string
Karsten Hopp 0d32bf
+     static CFStringRef
Karsten Hopp 0d32bf
+ getTabLabel(tabpage_T *page)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     get_tabline_label(page, FALSE);
Karsten Hopp 0d32bf
+ #ifdef MACOS_CONVERT
Karsten Hopp 0d32bf
+     return mac_enc_to_cfstring(NameBuff, STRLEN(NameBuff));
Karsten Hopp 0d32bf
+ #else
Karsten Hopp 0d32bf
+     // TODO: check internal encoding?
Karsten Hopp 0d32bf
+     return CFStringCreateWithCString(kCFAllocatorDefault, (char *)NameBuff,
Karsten Hopp 0d32bf
+ 						   kCFStringEncodingMacRoman);
Karsten Hopp 0d32bf
+ #endif
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ #define DRAWER_SIZE 150
Karsten Hopp 0d32bf
+ #define DRAWER_INSET 16
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ static ControlRef dataBrowser = NULL;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // when the tabline is hidden, vim doesn't call update_tabline(). When
Karsten Hopp 0d32bf
+ // the tabline is shown again, show_tabline() is called before upate_tabline(),
Karsten Hopp 0d32bf
+ // and because of this, the tab labels and vims internal tabs are out of sync
Karsten Hopp 0d32bf
+ // for a very short time. to prevent inconsistent state, we store the labels
Karsten Hopp 0d32bf
+ // of the tabs, not pointers to the tabs (which are invalid for a short time).
Karsten Hopp 0d32bf
+ static CFStringRef *tabLabels = NULL;
Karsten Hopp 0d32bf
+ static int tabLabelsSize = 0;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ enum
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     kTabsColumn = 'Tabs'
Karsten Hopp 0d32bf
+ };
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     static int
Karsten Hopp 0d32bf
+ getTabCount(void)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     tabpage_T	*tp;
Karsten Hopp 0d32bf
+     int		numTabs = 0;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
Karsten Hopp 0d32bf
+         ++numTabs;
Karsten Hopp 0d32bf
+     return numTabs;
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // data browser item display callback
Karsten Hopp 0d32bf
+     static OSStatus
Karsten Hopp 0d32bf
+ dbItemDataCallback(ControlRef browser,
Karsten Hopp 0d32bf
+ 	DataBrowserItemID itemID,
Karsten Hopp 0d32bf
+         DataBrowserPropertyID property /* column id */,
Karsten Hopp 0d32bf
+         DataBrowserItemDataRef itemData,
Karsten Hopp 0d32bf
+ 	Boolean changeValue)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     OSStatus status = noErr;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // assert(property == kTabsColumn); // why is this violated??
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // changeValue is true if we have a modifieable list and data was changed.
Karsten Hopp 0d32bf
+     // In our case, it's always false.
Karsten Hopp 0d32bf
+     // (that is: if (changeValue) updateInternalData(); else return
Karsten Hopp 0d32bf
+     // internalData();
Karsten Hopp 0d32bf
+     if (!changeValue)
Karsten Hopp 0d32bf
+     {
Karsten Hopp 0d32bf
+ 	CFStringRef str;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 	assert(itemID - 1 >= 0 && itemID - 1 < tabLabelsSize);
Karsten Hopp 0d32bf
+ 	str = tabLabels[itemID - 1];
Karsten Hopp 0d32bf
+ 	status = SetDataBrowserItemDataText(itemData, str);
Karsten Hopp 0d32bf
+     }
Karsten Hopp 0d32bf
+     else
Karsten Hopp 0d32bf
+ 	status = errDataBrowserPropertyNotSupported;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     return status;
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // data browser action callback
Karsten Hopp 0d32bf
+     static void
Karsten Hopp 0d32bf
+ dbItemNotificationCallback(ControlRef browser,
Karsten Hopp 0d32bf
+ 	DataBrowserItemID item,
Karsten Hopp 0d32bf
+ 	DataBrowserItemNotification message)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     switch (message)
Karsten Hopp 0d32bf
+     {
Karsten Hopp 0d32bf
+ 	case kDataBrowserItemSelected:
Karsten Hopp 0d32bf
+ 	    send_tabline_event(item);
Karsten Hopp 0d32bf
+ 	    break;
Karsten Hopp 0d32bf
+     }
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // callbacks needed for contextual menu:
Karsten Hopp 0d32bf
+     static void
Karsten Hopp 0d32bf
+ dbGetContextualMenuCallback(ControlRef browser,
Karsten Hopp 0d32bf
+ 	MenuRef *menu,
Karsten Hopp 0d32bf
+         UInt32 *helpType,
Karsten Hopp 0d32bf
+ 	CFStringRef *helpItemString,
Karsten Hopp 0d32bf
+         AEDesc *selection)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     // on mac os 9: kCMHelpItemNoHelp, but it's not the same
Karsten Hopp 0d32bf
+     *helpType = kCMHelpItemRemoveHelp; // OS X only ;-)
Karsten Hopp 0d32bf
+     *helpItemString = NULL;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     *menu = contextMenu;
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     static void
Karsten Hopp 0d32bf
+ dbSelectContextualMenuCallback(ControlRef browser,
Karsten Hopp 0d32bf
+ 	MenuRef menu,
Karsten Hopp 0d32bf
+ 	UInt32 selectionType,
Karsten Hopp 0d32bf
+ 	SInt16 menuID,
Karsten Hopp 0d32bf
+ 	MenuItemIndex menuItem)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     if (selectionType == kCMMenuItemSelected)
Karsten Hopp 0d32bf
+     {
Karsten Hopp 0d32bf
+ 	MenuCommand command;
Karsten Hopp 0d32bf
+ 	GetMenuItemCommandID(menu, menuItem, &command);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 	// get tab that was selected when the context menu appeared
Karsten Hopp 0d32bf
+ 	// (there is always one tab selected). TODO: check if the context menu
Karsten Hopp 0d32bf
+ 	// isn't opened on an item but on empty space (has to be possible some
Karsten Hopp 0d32bf
+ 	// way, the finder does it too ;-) )
Karsten Hopp 0d32bf
+ 	Handle items = NewHandle(0);
Karsten Hopp 0d32bf
+ 	if (items != NULL)
Karsten Hopp 0d32bf
+ 	{
Karsten Hopp 0d32bf
+ 	    int numItems;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 	    GetDataBrowserItems(browser, kDataBrowserNoItem, false,
Karsten Hopp 0d32bf
+ 					   kDataBrowserItemIsSelected, items);
Karsten Hopp 0d32bf
+ 	    numItems = GetHandleSize(items) / sizeof(DataBrowserItemID);
Karsten Hopp 0d32bf
+ 	    if (numItems > 0)
Karsten Hopp 0d32bf
+ 	    {
Karsten Hopp 0d32bf
+ 		int idx;
Karsten Hopp 0d32bf
+ 		DataBrowserItemID *itemsPtr;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 		HLock(items);
Karsten Hopp 0d32bf
+ 		itemsPtr = (DataBrowserItemID *)*items;
Karsten Hopp 0d32bf
+ 		idx = itemsPtr[0];
Karsten Hopp 0d32bf
+ 		HUnlock(items);
Karsten Hopp 0d32bf
+ 		send_tabline_menu_event(idx, command);
Karsten Hopp 0d32bf
+ 	    }
Karsten Hopp 0d32bf
+ 	    DisposeHandle(items);
Karsten Hopp 0d32bf
+ 	}
Karsten Hopp 0d32bf
+     }
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // focus callback of the data browser to always leave focus in vim
Karsten Hopp 0d32bf
+     static OSStatus
Karsten Hopp 0d32bf
+ dbFocusCallback(EventHandlerCallRef handler, EventRef event, void *data)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     assert(GetEventClass(event) == kEventClassControl
Karsten Hopp 0d32bf
+ 	    && GetEventKind(event) == kEventControlSetFocusPart);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     return paramErr;
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // drawer callback to resize data browser to drawer size
Karsten Hopp 0d32bf
+     static OSStatus
Karsten Hopp 0d32bf
+ drawerCallback(EventHandlerCallRef handler, EventRef event, void *data)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     switch (GetEventKind(event))
Karsten Hopp 0d32bf
+     {
Karsten Hopp 0d32bf
+ 	case kEventWindowBoundsChanged: // move or resize
Karsten Hopp 0d32bf
+ 	    {
Karsten Hopp 0d32bf
+ 		UInt32 attribs;
Karsten Hopp 0d32bf
+ 		GetEventParameter(event, kEventParamAttributes, typeUInt32,
Karsten Hopp 0d32bf
+ 				       NULL, sizeof(attribs), NULL, &attribs);
Karsten Hopp 0d32bf
+ 		if (attribs & kWindowBoundsChangeSizeChanged) // resize
Karsten Hopp 0d32bf
+ 		{
Karsten Hopp 0d32bf
+ 		    Rect r;
Karsten Hopp 0d32bf
+ 		    GetWindowBounds(drawer, kWindowContentRgn, &r);
Karsten Hopp 0d32bf
+ 		    SetRect(&r, 0, 0, r.right - r.left, r.bottom - r.top);
Karsten Hopp 0d32bf
+ 		    SetControlBounds(dataBrowser, &r);
Karsten Hopp 0d32bf
+ 		    SetDataBrowserTableViewNamedColumnWidth(dataBrowser,
Karsten Hopp 0d32bf
+ 							kTabsColumn, r.right);
Karsten Hopp 0d32bf
+ 		}
Karsten Hopp 0d32bf
+ 	    }
Karsten Hopp 0d32bf
+ 	    break;
Karsten Hopp 0d32bf
+     }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     return eventNotHandledErr;
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ // Load DataBrowserChangeAttributes() dynamically on tiger (and better).
Karsten Hopp 0d32bf
+ // This way the code works on 10.2 and 10.3 as well (it doesn't have the
Karsten Hopp 0d32bf
+ // blue highlights in the list view on these systems, though. Oh well.)
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ #import <mach-o/dyld.h>
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ enum { kMyDataBrowserAttributeListViewAlternatingRowColors = (1 << 1) };
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     static OSStatus
Karsten Hopp 0d32bf
+ myDataBrowserChangeAttributes(ControlRef inDataBrowser,
Karsten Hopp 0d32bf
+ 	OptionBits inAttributesToSet,
Karsten Hopp 0d32bf
+ 	OptionBits inAttributesToClear)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     long osVersion;
Karsten Hopp 0d32bf
+     char *symbolName;
Karsten Hopp 0d32bf
+     NSSymbol symbol = NULL;
Karsten Hopp 0d32bf
+     OSStatus (*dataBrowserChangeAttributes)(ControlRef inDataBrowser,
Karsten Hopp 0d32bf
+ 	      OptionBits   inAttributesToSet, OptionBits inAttributesToClear);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     Gestalt(gestaltSystemVersion, &osVersion);
Karsten Hopp 0d32bf
+     if (osVersion < 0x1040) // only supported for 10.4 (and up)
Karsten Hopp 0d32bf
+ 	return noErr;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // C name mangling...
Karsten Hopp 0d32bf
+     symbolName = "_DataBrowserChangeAttributes";
Karsten Hopp 0d32bf
+     if (!NSIsSymbolNameDefined(symbolName)
Karsten Hopp 0d32bf
+ 	    || (symbol = NSLookupAndBindSymbol(symbolName)) == NULL)
Karsten Hopp 0d32bf
+ 	return noErr;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     dataBrowserChangeAttributes = NSAddressOfSymbol(symbol);
Karsten Hopp 0d32bf
+     if (dataBrowserChangeAttributes == NULL)
Karsten Hopp 0d32bf
+ 	return noErr; // well...
Karsten Hopp 0d32bf
+     return dataBrowserChangeAttributes(inDataBrowser,
Karsten Hopp 0d32bf
+ 				      inAttributesToSet, inAttributesToClear);
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     static void
Karsten Hopp 0d32bf
+ initialise_tabline(void)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     Rect drawerRect = { 0, 0, 0, DRAWER_SIZE };
Karsten Hopp 0d32bf
+     DataBrowserCallbacks dbCallbacks;
Karsten Hopp 0d32bf
+     EventTypeSpec focusEvent = {kEventClassControl, kEventControlSetFocusPart};
Karsten Hopp 0d32bf
+     EventTypeSpec resizeEvent = {kEventClassWindow, kEventWindowBoundsChanged};
Karsten Hopp 0d32bf
+     DataBrowserListViewColumnDesc colDesc;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // drawers have to have compositing enabled
Karsten Hopp 0d32bf
+     CreateNewWindow(kDrawerWindowClass,
Karsten Hopp 0d32bf
+ 	    kWindowStandardHandlerAttribute
Karsten Hopp 0d32bf
+ 		    | kWindowCompositingAttribute
Karsten Hopp 0d32bf
+ 		    | kWindowResizableAttribute
Karsten Hopp 0d32bf
+ 		    | kWindowLiveResizeAttribute,
Karsten Hopp 0d32bf
+ 	    &drawerRect, &drawer);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     SetThemeWindowBackground(drawer, kThemeBrushDrawerBackground, true);
Karsten Hopp 0d32bf
+     SetDrawerParent(drawer, gui.VimWindow);
Karsten Hopp 0d32bf
+     SetDrawerOffsets(drawer, kWindowOffsetUnchanged, DRAWER_INSET);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // create list view embedded in drawer
Karsten Hopp 0d32bf
+     CreateDataBrowserControl(drawer, &drawerRect, kDataBrowserListView,
Karsten Hopp 0d32bf
+ 								&dataBrowser);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     dbCallbacks.version = kDataBrowserLatestCallbacks;
Karsten Hopp 0d32bf
+     InitDataBrowserCallbacks(&dbCallbacks);
Karsten Hopp 0d32bf
+     dbCallbacks.u.v1.itemDataCallback =
Karsten Hopp 0d32bf
+ 				NewDataBrowserItemDataUPP(dbItemDataCallback);
Karsten Hopp 0d32bf
+     dbCallbacks.u.v1.itemNotificationCallback =
Karsten Hopp 0d32bf
+ 		NewDataBrowserItemNotificationUPP(dbItemNotificationCallback);
Karsten Hopp 0d32bf
+     dbCallbacks.u.v1.getContextualMenuCallback =
Karsten Hopp 0d32bf
+ 	      NewDataBrowserGetContextualMenuUPP(dbGetContextualMenuCallback);
Karsten Hopp 0d32bf
+     dbCallbacks.u.v1.selectContextualMenuCallback =
Karsten Hopp 0d32bf
+ 	NewDataBrowserSelectContextualMenuUPP(dbSelectContextualMenuCallback);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     SetDataBrowserCallbacks(dataBrowser, &dbCallbacks);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     SetDataBrowserListViewHeaderBtnHeight(dataBrowser, 0); // no header
Karsten Hopp 0d32bf
+     SetDataBrowserHasScrollBars(dataBrowser, false, true); // only vertical
Karsten Hopp 0d32bf
+     SetDataBrowserSelectionFlags(dataBrowser,
Karsten Hopp 0d32bf
+ 	      kDataBrowserSelectOnlyOne | kDataBrowserNeverEmptySelectionSet);
Karsten Hopp 0d32bf
+     SetDataBrowserTableViewHiliteStyle(dataBrowser,
Karsten Hopp 0d32bf
+ 					     kDataBrowserTableViewFillHilite);
Karsten Hopp 0d32bf
+     Boolean b = false;
Karsten Hopp 0d32bf
+     SetControlData(dataBrowser, kControlEntireControl,
Karsten Hopp 0d32bf
+ 		  kControlDataBrowserIncludesFrameAndFocusTag, sizeof(b), &b);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // enable blue background in data browser (this is only in 10.4 and vim
Karsten Hopp 0d32bf
+     // has to support older osx versions as well, so we have to load this
Karsten Hopp 0d32bf
+     // function dynamically)
Karsten Hopp 0d32bf
+     myDataBrowserChangeAttributes(dataBrowser,
Karsten Hopp 0d32bf
+ 		      kMyDataBrowserAttributeListViewAlternatingRowColors, 0);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // install callback that keeps focus in vim and away from the data browser
Karsten Hopp 0d32bf
+     InstallControlEventHandler(dataBrowser, dbFocusCallback, 1, &focusEvent,
Karsten Hopp 0d32bf
+ 								  NULL, NULL);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // install callback that keeps data browser at the size of the drawer
Karsten Hopp 0d32bf
+     InstallWindowEventHandler(drawer, drawerCallback, 1, &resizeEvent,
Karsten Hopp 0d32bf
+ 								  NULL, NULL);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // add "tabs" column to data browser
Karsten Hopp 0d32bf
+     colDesc.propertyDesc.propertyID = kTabsColumn;
Karsten Hopp 0d32bf
+     colDesc.propertyDesc.propertyType = kDataBrowserTextType;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // add if items can be selected (?): kDataBrowserListViewSelectionColumn
Karsten Hopp 0d32bf
+     colDesc.propertyDesc.propertyFlags = kDataBrowserDefaultPropertyFlags;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.minimumWidth = 100;
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.maximumWidth = 150;
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.titleOffset = 0;
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.titleString = CFSTR("Tabs");
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.btnFontStyle.flags = 0; // use default font
Karsten Hopp 0d32bf
+     colDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     AddDataBrowserListViewColumn(dataBrowser, &colDesc, 0);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // create tabline popup menu required by vim docs (see :he tabline-menu)
Karsten Hopp 0d32bf
+     CreateNewMenu(kTabContextMenuId, 0, &contextMenu);
Karsten Hopp 0d32bf
+     AppendMenuItemTextWithCFString(contextMenu, CFSTR("Close"), 0,
Karsten Hopp 0d32bf
+ 						    TABLINE_MENU_CLOSE, NULL);
Karsten Hopp 0d32bf
+     AppendMenuItemTextWithCFString(contextMenu, CFSTR("New Tab"), 0,
Karsten Hopp 0d32bf
+ 						      TABLINE_MENU_NEW, NULL);
Karsten Hopp 0d32bf
+     AppendMenuItemTextWithCFString(contextMenu, CFSTR("Open Tab..."), 0,
Karsten Hopp 0d32bf
+ 						     TABLINE_MENU_OPEN, NULL);
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ /*
Karsten Hopp 0d32bf
+  * Show or hide the tabline.
Karsten Hopp 0d32bf
+  */
Karsten Hopp 0d32bf
+     void
Karsten Hopp 0d32bf
+ gui_mch_show_tabline(int showit)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     if (showit == 0)
Karsten Hopp 0d32bf
+         CloseDrawer(drawer, true);
Karsten Hopp 0d32bf
+     else
Karsten Hopp 0d32bf
+         OpenDrawer(drawer, kWindowEdgeRight, true);
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ /*
Karsten Hopp 0d32bf
+  * Return TRUE when tabline is displayed.
Karsten Hopp 0d32bf
+  */
Karsten Hopp 0d32bf
+     int
Karsten Hopp 0d32bf
+ gui_mch_showing_tabline(void)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     WindowDrawerState state = GetDrawerState(drawer);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     return state == kWindowDrawerOpen || state == kWindowDrawerOpening;
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ /*
Karsten Hopp 0d32bf
+  * Update the labels of the tabline.
Karsten Hopp 0d32bf
+  */
Karsten Hopp 0d32bf
+     void
Karsten Hopp 0d32bf
+ gui_mch_update_tabline(void)
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     tabpage_T	*tp;
Karsten Hopp 0d32bf
+     int		numTabs = getTabCount();
Karsten Hopp 0d32bf
+     int		nr = 1;
Karsten Hopp 0d32bf
+     int		curtabidx = 1;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // adjust data browser
Karsten Hopp 0d32bf
+     if (tabLabels != NULL)
Karsten Hopp 0d32bf
+     {
Karsten Hopp 0d32bf
+         int i;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+         for (i = 0; i < tabLabelsSize; ++i)
Karsten Hopp 0d32bf
+             CFRelease(tabLabels[i]);
Karsten Hopp 0d32bf
+         free(tabLabels);
Karsten Hopp 0d32bf
+     }
Karsten Hopp 0d32bf
+     tabLabels = (CFStringRef *)malloc(numTabs * sizeof(CFStringRef));
Karsten Hopp 0d32bf
+     tabLabelsSize = numTabs;
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr)
Karsten Hopp 0d32bf
+     {
Karsten Hopp 0d32bf
+ 	if (tp == curtab)
Karsten Hopp 0d32bf
+ 	    curtabidx = nr;
Karsten Hopp 0d32bf
+         tabLabels[nr-1] = getTabLabel(tp);
Karsten Hopp 0d32bf
+     }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     RemoveDataBrowserItems(dataBrowser, kDataBrowserNoItem, 0, NULL,
Karsten Hopp 0d32bf
+ 						  kDataBrowserItemNoProperty);
Karsten Hopp 0d32bf
+     // data browser uses ids 1, 2, 3, ... numTabs per default, so we
Karsten Hopp 0d32bf
+     // can pass NULL for the id array
Karsten Hopp 0d32bf
+     AddDataBrowserItems(dataBrowser, kDataBrowserNoItem, numTabs, NULL,
Karsten Hopp 0d32bf
+ 						  kDataBrowserItemNoProperty);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     DataBrowserItemID item = curtabidx;
Karsten Hopp 0d32bf
+     SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign);
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ /*
Karsten Hopp 0d32bf
+  * Set the current tab to "nr".  First tab is 1.
Karsten Hopp 0d32bf
+  */
Karsten Hopp 0d32bf
+     void
Karsten Hopp 0d32bf
+ gui_mch_set_curtab(nr)
Karsten Hopp 0d32bf
+     int		nr;
Karsten Hopp 0d32bf
+ {
Karsten Hopp 0d32bf
+     DataBrowserItemID item = nr;
Karsten Hopp 0d32bf
+     SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign);
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+     // TODO: call something like this?: (or restore scroll position, or...)
Karsten Hopp 0d32bf
+     RevealDataBrowserItem(dataBrowser, item, kTabsColumn,
Karsten Hopp 0d32bf
+ 						      kDataBrowserRevealOnly);
Karsten Hopp 0d32bf
+ }
Karsten Hopp 0d32bf
+ 
Karsten Hopp 0d32bf
+ #endif // FEAT_GUI_TABLINE
Karsten Hopp 0d32bf
*** ../vim-7.0.231/src/proto/gui_mac.pro	Tue Mar 28 23:01:02 2006
Karsten Hopp 0d32bf
--- src/proto/gui_mac.pro	Thu Mar 15 20:23:42 2007
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 84,89 ****
Karsten Hopp 0d32bf
--- 84,93 ----
Karsten Hopp 0d32bf
  int gui_mch_dialog __ARGS((int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, char_u *textfield));
Karsten Hopp 0d32bf
  char_u *gui_mch_browse __ARGS((int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter));
Karsten Hopp 0d32bf
  void gui_mch_set_foreground __ARGS((void));
Karsten Hopp 0d32bf
+ void gui_mch_show_tabline __ARGS((int showit));
Karsten Hopp 0d32bf
+ int gui_mch_showing_tabline __ARGS((void));
Karsten Hopp 0d32bf
+ void gui_mch_update_tabline __ARGS((void));
Karsten Hopp 0d32bf
+ void gui_mch_set_curtab __ARGS((int nr));
Karsten Hopp 0d32bf
  
Karsten Hopp 0d32bf
  char_u *C2Pascal_save __ARGS((char_u *Cstring));
Karsten Hopp 0d32bf
  char_u *C2Pascal_save_and_remove_backslash __ARGS((char_u *Cstring));
Karsten Hopp 0d32bf
*** ../vim-7.0.231/src/version.c	Thu Apr 26 17:23:28 2007
Karsten Hopp 0d32bf
--- src/version.c	Thu Apr 26 18:17:42 2007
Karsten Hopp 0d32bf
***************
Karsten Hopp 0d32bf
*** 668,669 ****
Karsten Hopp 0d32bf
--- 668,671 ----
Karsten Hopp 0d32bf
  {   /* Add new patch number below this line */
Karsten Hopp 0d32bf
+ /**/
Karsten Hopp 0d32bf
+     232,
Karsten Hopp 0d32bf
  /**/
Karsten Hopp 0d32bf
Karsten Hopp 0d32bf
-- 
Karsten Hopp 0d32bf
hundred-and-one symptoms of being an internet addict:
Karsten Hopp 0d32bf
24. You realize there is not a sound in the house and you have no idea where
Karsten Hopp 0d32bf
    your children are.
Karsten Hopp 0d32bf
Karsten Hopp 0d32bf
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 0d32bf
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 0d32bf
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp 0d32bf
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///