]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/CocoaFileDialog.mm
GUI support for VIA/Discontinuity
[flightgear.git] / src / GUI / CocoaFileDialog.mm
index f802eea06a2f5a6683817cabbdce9ed321e5805e..352fa3c15b66844cf0fc02b31fbad5cb8fbb390f 100644 (file)
@@ -1,27 +1,45 @@
+// CocoaFileDialog.mm - Cocoa implementation of file-dialog interface
+
+// Copyright (C) 2013 James Turner <zakalawe@mac.com>
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
 
 
 #include "CocoaFileDialog.hxx"
 
-// bring it all in!
-#include <Cocoa/Cocoa.h>
+#include <AppKit/NSSavePanel.h>
+#include <AppKit/NSOpenPanel.h>
 
 #include <boost/foreach.hpp>
 
+#include <osgViewer/Viewer>
+#include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/strutils.hxx>
 
+#include <GUI/CocoaHelpers_private.h>
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
+#include <Viewer/renderer.hxx>
 
-static NSString* stdStringToCocoa(const std::string& s)
-{
-    return [NSString stringWithUTF8String:s.c_str()];
-}
-
-static NSURL* pathToNSURL(const SGPath& aPath)
-{
-    return [NSURL fileURLWithPath:stdStringToCocoa(aPath.str())];
-}
+// 10.6 compiler won't accept block-scoped locals in Objective-C++,
+// so making these globals.
+static NSString* completion_path = nil;
+static SGPath completion_sgpath;
 
 class CocoaFileDialog::CocoaFileDialogPrivate
 {
@@ -40,19 +58,22 @@ public:
     NSSavePanel* panel;
 };
 
-CocoaFileDialog::CocoaFileDialog(const std::string& aTitle, FGFileDialog::Usage use) :
-    FGFileDialog(aTitle, use)
+CocoaFileDialog::CocoaFileDialog(FGFileDialog::Usage use) :
+    FGFileDialog(use)
 {
     d.reset(new CocoaFileDialogPrivate);
     if (use == USE_SAVE_FILE) {
         d->panel = [NSSavePanel savePanel];
     } else {
-        d->panel = [NSOpenPanel openPanel];
-    }
+        NSOpenPanel* openPanel = [NSOpenPanel openPanel]; 
+        d->panel = openPanel;
+        
+        if (use == USE_CHOOSE_DIR) {
+            [openPanel setCanChooseDirectories:YES];
+        }
+    } // of USE_OPEN_FILE or USE_CHOOSE_DIR -> building NSOpenPanel
     
-    if (use == USE_CHOOSE_DIR) {
-        [d->panel setCanChooseDirectories:YES];
-    }
+    [d->panel retain];
 }
 
 CocoaFileDialog::~CocoaFileDialog()
@@ -62,20 +83,45 @@ CocoaFileDialog::~CocoaFileDialog()
 
 void CocoaFileDialog::exec()
 {
+// find the native Cocoa NSWindow handle so we can parent the dialog and show
+// it window-modal.
+    NSWindow* cocoaWindow = nil;
+    std::vector<osgViewer::GraphicsWindow*> windows;
+    globals->get_renderer()->getViewer()->getWindows(windows);
+    
+    BOOST_FOREACH(osgViewer::GraphicsWindow* gw, windows) {
+        // OSG doesn't use RTTI, so no dynamic cast. Let's check the class type
+        // using OSG's own system, before we blindly static_cast<> and break
+        // everything.
+        if (strcmp(gw->className(), "GraphicsWindowCocoa")) {
+            continue; 
+        }
+            
+        osgViewer::GraphicsWindowCocoa* gwCocoa = static_cast<osgViewer::GraphicsWindowCocoa*>(gw);
+        cocoaWindow = (NSWindow*) gwCocoa->getWindow();
+        break;
+    }
+    
+// setup the panel fields now we have collected all the data
     if (_usage == USE_SAVE_FILE) {
         [d->panel setNameFieldStringValue:stdStringToCocoa(_placeholder)];
     }
     
-    NSMutableArray* extensions = [NSMutableArray arrayWithCapacity:0];
-    BOOST_FOREACH(std::string ext, _filterPatterns) {
-        if (!simgear::strutils::starts_with(ext, "*.")) {
-            SG_LOG(SG_GENERAL, SG_INFO, "can't use pattern on Cococa:" << ext);
-            continue;
+    if (_filterPatterns.empty()) {
+        [d->panel setAllowedFileTypes:nil];
+    } else {
+        NSMutableArray* extensions = [NSMutableArray arrayWithCapacity:0];
+        BOOST_FOREACH(std::string ext, _filterPatterns) {
+            if (!simgear::strutils::starts_with(ext, "*.")) {
+                SG_LOG(SG_GENERAL, SG_INFO, "can't use pattern on Cococa:" << ext);
+                continue;
+            }
+            [extensions addObject:stdStringToCocoa(ext.substr(2))];
         }
-        [extensions addObject:stdStringToCocoa(ext.substr(2))];
-    }
 
-    [d->panel setAllowedFileTypes:extensions];
+        [d->panel setAllowedFileTypes:extensions];
+    }
+    
     [d->panel setTitle:stdStringToCocoa(_title)];
     if (_showHidden) {
         [d->panel setShowsHiddenFiles:YES];
@@ -83,13 +129,19 @@ void CocoaFileDialog::exec()
     
     [d->panel setDirectoryURL: pathToNSURL(_initialPath)];
     
-    [d->panel beginWithCompletionHandler:^(NSInteger result)
+    [d->panel beginSheetModalForWindow:cocoaWindow completionHandler:^(NSInteger result)
     {
         if (result == NSFileHandlingPanelOKButton) {
-            NSURL*  theDoc = [d->panel URL];
-            NSLog(@"the URL is: %@", theDoc);
-            // Open  the document.
+            completion_path = [[d->panel URL] path];
+            //NSLog(@"the URL is: %@", d->panel URL]);
+            completion_sgpath = ([completion_path UTF8String]);
+            _callback->onFileDialogDone(this, completion_sgpath);
         }
-        
     }];
 }
+
+void CocoaFileDialog::close()
+{
+    [d->panel close];
+}
+