[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26496] trunk/blender: Cocoa : implement opening .blend file by double-clicking on it in OSX Finder

Damien Plisson damien.plisson at yahoo.fr
Mon Feb 1 10:11:19 CET 2010


Revision: 26496
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26496
Author:   damien78
Date:     2010-02-01 10:11:18 +0100 (Mon, 01 Feb 2010)

Log Message:
-----------
Cocoa : implement opening .blend file by double-clicking on it in OSX Finder

When the user double-clicks on a document file in the Finder, OSX doesn't simply give the filename as a command-line argument when calling Blender, as it is done in other OSes.
Instead, it launches the app if needed, and then sends an "openFile" event.

The user can also open a document file by dropping its icon on the app dock icon. But as this is not real Drag'n'drop, I've renamed the Ghost event to a less confusing "GHOST_kEventOpenMainFile" name.

DND Ghost wiki page updated : http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DragnDrop

Modified Paths:
--------------
    trunk/blender/intern/ghost/GHOST_Types.h
    trunk/blender/intern/ghost/intern/GHOST_EventPrinter.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
    trunk/blender/source/blender/windowmanager/intern/wm_window.c

Added Paths:
-----------
    trunk/blender/intern/ghost/intern/GHOST_EventString.h

Modified: trunk/blender/intern/ghost/GHOST_Types.h
===================================================================
--- trunk/blender/intern/ghost/GHOST_Types.h	2010-02-01 04:07:43 UTC (rev 26495)
+++ trunk/blender/intern/ghost/GHOST_Types.h	2010-02-01 09:11:18 UTC (rev 26496)
@@ -173,7 +173,8 @@
 	GHOST_kEventDraggingUpdated,
 	GHOST_kEventDraggingExited,
 	GHOST_kEventDraggingDropDone,
-	GHOST_kEventDraggingDropOnIcon,
+	
+	GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup
 
 	GHOST_kEventTimer,
 

Modified: trunk/blender/intern/ghost/intern/GHOST_EventPrinter.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_EventPrinter.cpp	2010-02-01 04:07:43 UTC (rev 26495)
+++ trunk/blender/intern/ghost/intern/GHOST_EventPrinter.cpp	2010-02-01 09:11:18 UTC (rev 26496)
@@ -148,26 +148,14 @@
 		}
 		break;
 
-	case GHOST_kEventDraggingDropOnIcon:
+	case GHOST_kEventOpenMainFile:
 		{
-			GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData();
-			std::cout << "GHOST_kEventDraggingDropOnIcon, dragged object type : " << dragnDropData->dataType;
-			switch (dragnDropData->dataType) {
-				case GHOST_kDragnDropTypeString:
-					std::cout << " string received = " << (char*)dragnDropData->data;
-					break;
-				case GHOST_kDragnDropTypeFilenames:
-				{
-					GHOST_TStringArray *strArray = (GHOST_TStringArray*)dragnDropData->data;
-					int i;
-					std::cout << "\nReceived " << strArray->count << " filenames";
-					for (i=0;i<strArray->count;i++)
-						std::cout << " Filename #" << i << ": " << strArray->strings[i];
-				}
-					break;
-				default:
-					break;
-			}
+			GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
+			
+			if (eventData)
+				std::cout << "GHOST_kEventOpenMainFile for path : " << (char*)eventData;
+			else
+				std::cout << "GHOST_kEventOpenMainFile with no path specified!!";
 		}
 		break;
 			

Added: trunk/blender/intern/ghost/intern/GHOST_EventString.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_EventString.h	                        (rev 0)
+++ trunk/blender/intern/ghost/intern/GHOST_EventString.h	2010-02-01 09:11:18 UTC (rev 26496)
@@ -0,0 +1,66 @@
+/**
+ * $Id: GHOST_EventString.h 13161 2008-01-07 19:13:47Z hos $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/**
+ * @file	GHOST_EventString.h
+ * Declaration of GHOST_EventString class.
+ */
+
+#ifndef _GHOST_EVENTSTRING_H_
+#define _GHOST_EVENTSTRING_H_
+
+#include "GHOST_Event.h"
+
+
+/**
+ * Generic class for events with string data
+ * @author	Damien Plisson
+ * @date	Feb 1, 2010
+ */
+class GHOST_EventString : public GHOST_Event
+{
+public:
+	/**
+	 * Constructor.
+	 * @param msec	The time this event was generated.
+	 * @param type	The type of this event.
+	 * @param window The generating window (or NULL if system event).
+	 * @param data_ptr Pointer to the (unformatted) data associated with the event
+	 */
+	GHOST_EventString(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TEventDataPtr data_ptr)
+		: GHOST_Event(msec, type, window)	{
+			m_data = data_ptr;
+	}
+
+	~GHOST_EventString()
+	{
+		if (m_data) free(m_data);
+	}
+};
+
+#endif // _GHOST_EVENTSTRING_H_
+

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2010-02-01 04:07:43 UTC (rev 26495)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2010-02-01 09:11:18 UTC (rev 26496)
@@ -43,6 +43,7 @@
 #include "GHOST_EventNDOF.h"
 #include "GHOST_EventTrackpad.h"
 #include "GHOST_EventDragnDrop.h"
+#include "GHOST_EventString.h"
 
 #include "GHOST_TimerManager.h"
 #include "GHOST_TimerTask.h"
@@ -1025,7 +1026,7 @@
 GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType,
 								   GHOST_WindowCocoa* window, int mouseX, int mouseY, void* data)
 {
-	if (!validWindow(window) && (eventType != GHOST_kEventDraggingDropOnIcon)) {
+	if (!validWindow(window)) {
 		return GHOST_kFailure;
 	}
 	switch(eventType) 
@@ -1037,7 +1038,6 @@
 			break;
 			
 		case GHOST_kEventDraggingDropDone:
-		case GHOST_kEventDraggingDropOnIcon:
 		{
 			GHOST_TUns8 * temp_buff;
 			GHOST_TStringArray *strArray;
@@ -1158,7 +1158,18 @@
 	NSString *filepath = (NSString*)filepathStr;
 	int confirmOpen = NSAlertAlternateReturn;
 	NSArray *windowsList;
+	char * temp_buff;
+	size_t filenameTextSize;	
+	GHOST_Window* window= (GHOST_Window*)m_windowManager->getActiveWindow();
 	
+	if (!window) {
+		return NO;
+	}	
+	
+	//Discard event if we are in cursor grab sequence, it'll lead to "stuck cursor" situation if the alert panel is raised
+	if (window && (window->getCursorGrabMode() != GHOST_kGrabDisable) && (window->getCursorGrabMode() != GHOST_kGrabNormal))
+		return GHOST_kExitCancel;
+
 	//Check open windows if some changes are not saved
 	if (m_windowManager->getAnyModifiedState())
 	{
@@ -1175,7 +1186,20 @@
 
 	if (confirmOpen == NSAlertAlternateReturn)
 	{
-		handleDraggingEvent(GHOST_kEventDraggingDropOnIcon,GHOST_kDragnDropTypeFilenames,NULL,0,0, [NSArray arrayWithObject:filepath]);
+		filenameTextSize = [filepath lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding];
+		
+		temp_buff = (char*) malloc(filenameTextSize+1); 
+		
+		if (temp_buff == NULL) {
+			return GHOST_kFailure;
+		}
+		
+		strncpy(temp_buff, [filepath cStringUsingEncoding:NSISOLatin1StringEncoding], filenameTextSize);
+		
+		temp_buff[filenameTextSize] = '\0';
+
+		pushEvent(new GHOST_EventString(getMilliSeconds(),GHOST_kEventOpenMainFile,window,(GHOST_TEventDataPtr) temp_buff));
+
 		return YES;
 	}
 	else return NO;

Modified: trunk/blender/source/blender/windowmanager/intern/wm_window.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_window.c	2010-02-01 04:07:43 UTC (rev 26495)
+++ trunk/blender/source/blender/windowmanager/intern/wm_window.c	2010-02-01 09:11:18 UTC (rev 26496)
@@ -34,6 +34,7 @@
 #include "DNA_listBase.h"	
 #include "DNA_screen_types.h"
 #include "DNA_windowmanager_types.h"
+#include "RNA_access.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -714,6 +715,28 @@
 				}
 				break;
 			}
+				
+			case GHOST_kEventOpenMainFile:
+			{
+				PointerRNA props_ptr;
+				wmWindow *oldWindow;
+				char *path = GHOST_GetEventData(evt);
+				
+				if (path) {
+					/* operator needs a valid window in context, ensures
+					 it is correctly set */
+					oldWindow = CTX_wm_window(C);
+					CTX_wm_window_set(C, win);
+					
+					WM_operator_properties_create(&props_ptr, "WM_OT_open_mainfile");
+					RNA_string_set(&props_ptr, "path", path);
+					WM_operator_name_call(C, "WM_OT_open_mainfile", WM_OP_EXEC_DEFAULT, &props_ptr);
+					WM_operator_properties_free(&props_ptr);
+					
+					CTX_wm_window_set(C, oldWindow);
+				}
+				break;
+			}
 			case GHOST_kEventDraggingDropDone:
 			{
 				wmEvent event= *(win->eventstate);	/* copy last state, like mouse coords */





More information about the Bf-blender-cvs mailing list