3 #include "CocoaFileDialog.hxx"
6 #include <Cocoa/Cocoa.h>
8 #include <boost/foreach.hpp>
10 #include <osgViewer/Viewer>
11 #include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
13 #include <simgear/debug/logstream.hxx>
14 #include <simgear/misc/strutils.hxx>
16 #include <Main/globals.hxx>
17 #include <Main/fg_props.hxx>
18 #include <Viewer/renderer.hxx>
20 static NSString* stdStringToCocoa(const std::string& s)
22 return [NSString stringWithUTF8String:s.c_str()];
25 static NSURL* pathToNSURL(const SGPath& aPath)
27 return [NSURL fileURLWithPath:stdStringToCocoa(aPath.str())];
30 class CocoaFileDialog::CocoaFileDialogPrivate
33 CocoaFileDialogPrivate() :
39 ~CocoaFileDialogPrivate()
47 CocoaFileDialog::CocoaFileDialog(FGFileDialog::Usage use) :
50 d.reset(new CocoaFileDialogPrivate);
51 if (use == USE_SAVE_FILE) {
52 d->panel = [NSSavePanel savePanel];
54 NSOpenPanel* openPanel = [NSOpenPanel openPanel];
57 if (use == USE_CHOOSE_DIR) {
58 [openPanel setCanChooseDirectories:YES];
60 } // of USE_OPEN_FILE or USE_CHOOSE_DIR -> building NSOpenPanel
65 CocoaFileDialog::~CocoaFileDialog()
70 void CocoaFileDialog::exec()
72 // find the native Cocoa NSWindow handle so we can parent the dialog and show
74 NSWindow* cocoaWindow = nil;
75 std::vector<osgViewer::GraphicsWindow*> windows;
76 globals->get_renderer()->getViewer()->getWindows(windows);
78 BOOST_FOREACH(osgViewer::GraphicsWindow* gw, windows) {
79 // OSG doesn't use RTTI, so no dynamic cast. Let's check the class type
80 // using OSG's own system, before we blindly static_cast<> and break
82 if (strcmp(gw->className(), "GraphicsWindowCocoa")) {
86 osgViewer::GraphicsWindowCocoa* gwCocoa = static_cast<osgViewer::GraphicsWindowCocoa*>(gw);
87 cocoaWindow = (NSWindow*) gwCocoa->getWindow();
91 // setup the panel fields now we have collected all the data
92 if (_usage == USE_SAVE_FILE) {
93 [d->panel setNameFieldStringValue:stdStringToCocoa(_placeholder)];
96 if (_filterPatterns.empty()) {
97 [d->panel setAllowedFileTypes:nil];
99 NSMutableArray* extensions = [NSMutableArray arrayWithCapacity:0];
100 BOOST_FOREACH(std::string ext, _filterPatterns) {
101 if (!simgear::strutils::starts_with(ext, "*.")) {
102 SG_LOG(SG_GENERAL, SG_INFO, "can't use pattern on Cococa:" << ext);
105 [extensions addObject:stdStringToCocoa(ext.substr(2))];
108 [d->panel setAllowedFileTypes:extensions];
111 [d->panel setTitle:stdStringToCocoa(_title)];
113 [d->panel setShowsHiddenFiles:YES];
116 [d->panel setDirectoryURL: pathToNSURL(_initialPath)];
118 [d->panel beginSheetModalForWindow:cocoaWindow completionHandler:^(NSInteger result)
120 NSString* path = nil;
123 if (result == NSFileHandlingPanelOKButton) {
124 path = [[d->panel URL] path];
125 //NSLog(@"the URL is: %@", d->panel URL]);
126 sgpath = ([path UTF8String]);
127 _callback->onFileDialogDone(this, sgpath);
132 void CocoaFileDialog::close()