Last active
September 15, 2017 23:22
-
-
Save sarah-j-smith/9801615 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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