QString MacUtils::getOpenFileName(QWidget *parent, const QString &title, const QString &dirName, const QString &filter, MacUtils::OpenType openType) | |
{ | |
qDebug() << Q_FUNC_INFO << "dirName:" << dirName; | |
NSOpenPanel *panel = [NSOpenPanel openPanel]; | |
QWidget *window = parent->window(); | |
Q_ASSERT_X(window != 0, Q_FUNC_INFO, "Expected non-nil window"); | |
Q_ASSERT_X(window->isWindow(), Q_FUNC_INFO, "Expected window"); | |
NSView *v = reinterpret_cast<NSView *>(window->winId()); | |
NSWindow *macWindow = [v window]; | |
__block QEventLoop *loop = new QEventLoop; | |
__block NSURL *result = nil; | |
NSURL *promptUrl = [NSURL fileURLWithPath:dirName.toNSString() isDirectory:YES]; | |
[panel setTitle:title.toNSString()]; | |
[panel setCanChooseFiles:YES]; | |
if (openType == DirectoriesOnly) | |
{ | |
// On Mac you cannot choose bundles if this is set | |
[panel setCanChooseFiles:NO]; | |
[panel setCanChooseDirectories:YES]; | |
[panel setShowsHiddenFiles:YES]; | |
// allow bundles | |
[panel setTreatsFilePackagesAsDirectories:YES]; | |
[panel setMessage:@"Choose a directory for the Navigator Pane"]; | |
} | |
else | |
{ | |
[panel setAllowsOtherFileTypes:YES]; | |
[panel setAllowedFileTypes:@[ filter.toNSString() ]]; | |
[panel setCanChooseFiles:YES]; | |
[panel setCanChooseDirectories:NO]; | |
[panel setMessage:@"Choose a file"]; | |
} | |
[panel setAllowsMultipleSelection:NO]; | |
[panel setDirectoryURL:promptUrl]; | |
[panel beginSheetModalForWindow:macWindow completionHandler:^(NSInteger returnCode) | |
{ | |
NSLog(@"Return completion handler: %ld", (long)returnCode); | |
if (returnCode == NSOKButton) | |
{ | |
result = [[panel URLs] objectAtIndex:0]; | |
NSLog(@"NSOpenPanel completion handler block - URL is: %@", result); | |
} | |
loop->quit(); | |
NSLog(@"Sent quit to loop"); | |
}]; | |
loop->exec(); | |
QString answer; | |
NSLog(@"Exited loop: %@", result); | |
if (result != nil) | |
{ | |
NSLog(@"Got URL as %@ - is a file url: %s", result, ([result isFileURL] ? "YES" : "NO")); | |
if ([result isFileURL]) | |
{ | |
answer = QString::fromNSString([result path]); | |
if (instance()->isSandboxed()) | |
{ | |
QScopedPointer<SecurityBookmarkManager> smgr(new SecurityBookmarkManager); | |
smgr->storeSecurityScope(result); | |
} | |
} | |
else | |
{ | |
NSLog(@"### LOGIC ERROR: panel returned a non-file URL: %@!!!!!!!", result); | |
} | |
} | |
delete loop; | |
return answer; | |
} | |
// Cannot create a security scoped book-mark for a file that doesn't exist, so | |
// instead we create a small placeholder file just to allow book-mark creation. | |
static bool writePlaceHolderFile(const QUrl &url) | |
{ | |
QString filePath = url.toLocalFile(); | |
QFile placeHolder(filePath); | |
bool success = placeHolder.open(QIODevice::WriteOnly); | |
if (!success) | |
{ | |
qDebug() << Q_FUNC_INFO << "Could not open for writing" << placeHolder.fileName() << placeHolder.errorString(); | |
return false; | |
} | |
qint64 r = placeHolder.write(QByteArray("Hello World!")); | |
if (r <= 0) | |
{ | |
qDebug() << Q_FUNC_INFO << "Could not write bytes" << url << placeHolder.errorString(); | |
return false; | |
} | |
qDebug() << Q_FUNC_INFO << "Wrote placeholder" << url; | |
placeHolder.close(); | |
return true; | |
} | |
QString MacUtils::getSaveFileName(QWidget *parent, const QString &title, const QString &dirName, const QString &filter) | |
{ | |
qDebug() << Q_FUNC_INFO << "dirName:" << dirName; | |
NSSavePanel *panel = [NSSavePanel savePanel]; | |
QWidget *window = parent->window(); | |
Q_ASSERT_X(window != 0, Q_FUNC_INFO, "Expected non-nil window"); | |
Q_ASSERT_X(window->isWindow(), Q_FUNC_INFO, "Expected window"); | |
NSView *v = reinterpret_cast<NSView *>(window->winId()); | |
NSWindow *macWindow = [v window]; | |
__block QEventLoop *loop = new QEventLoop; | |
__block NSURL *result = nil; | |
NSURL *promptUrl = [NSURL fileURLWithPath:dirName.toNSString() isDirectory:YES]; | |
[panel setTitle:title.toNSString()]; | |
[panel setDirectoryURL:promptUrl]; | |
[panel setAllowsOtherFileTypes:YES]; | |
[panel setAllowedFileTypes:@[ filter.toNSString() ]]; | |
[panel beginSheetModalForWindow:macWindow completionHandler:^(NSInteger returnCode) | |
{ | |
NSLog(@"Return completion handler: %ld", (long)returnCode); | |
if (returnCode == NSOKButton) | |
{ | |
result = [panel URL]; | |
[result retain]; | |
NSLog(@"NSOpenPanel completion handler block - URL is: %@", result); | |
} | |
loop->quit(); | |
NSLog(@"Sent quit to loop"); | |
}]; | |
loop->exec(); | |
qDebug() << Q_FUNC_INFO << "Loop quit"; | |
QString answer; | |
if (result != nil) | |
{ | |
NSLog(@"Got URL as %@ - is a file url: %s", result, ([result isFileURL] ? "YES" : "NO")); | |
if ([result isFileURL]) | |
{ | |
answer = QString::fromNSString([result path]); | |
if (instance()->isSandboxed()) | |
{ | |
QUrl url = QUrl::fromLocalFile(answer); | |
NSLog(@"Got Qt URL from NSURL - %s", qPrintable(url.toLocalFile())); | |
writePlaceHolderFile(url); | |
QScopedPointer<SecurityBookmarkManager> smgr(new SecurityBookmarkManager); | |
smgr->storeSecurityScope(result); | |
} | |
} | |
else | |
{ | |
NSLog(@"### LOGIC ERROR: panel returned a non-file URL!!!!!!!"); | |
} | |
[result release]; | |
} | |
delete loop; | |
return answer; | |
} | |
void MacUtils::macLog(const QString &message) | |
{ | |
NSLog(@"%s", qPrintable(message)); | |
} | |
bool MacUtils::isSandboxed() const | |
{ | |
NSLog(@"MacUtils::isSandboxed()"); | |
if (!pvt->isInitialized) | |
{ | |
NSDictionary* env = [[NSProcessInfo processInfo] environment]; | |
BOOL freedom = ([env objectForKey:@"APP_SANDBOX_CONTAINER_ID"] == nil); | |
NSLog(@"APP_SANDBOX_CONTAINER_ID: %@", [env objectForKey:@"APP_SANDBOX_CONTAINER_ID"] ); | |
pvt->isSandboxed = !freedom; | |
} | |
return pvt->isSandboxed; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment