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 */


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to