In my Mac OS application, I'm prompting a user to create a new folder. I would like to apply an icon to this folder using Cocoa when it is created. Currently, to create the folder, I'm using the following code:
- (IBAction)browseFiles:(id)sender
{
NSOpenPanel *oPanel = [[NSOpenPanel openPanel] retain];
[oPanel setCanChooseDirectories:YES];
[oPanel setCanChooseFiles:NO];
[oPanel setDelegate:self];
[oPanel setCanCreateDirectories:YES];
[oPanel beginSheetForDirectory:NSHomeDirectory()
file:nil
types:nil
modalForWindow:nil
modalDelegate:self
didEndSelector:#selector(filePanelDidEnd:
returnCode:
contextInfo:)
contextInfo:nil];
}
After choosing a directory, the user clicks a confirm button that calls a function with the following method:
bool set = [[NSWorkspace sharedWorkspace] setIcon:[NSImage imageNamed:#"icon.icns"] forFile:path options:NSExcludeQuickDrawElementsIconCreationOption];
While the piece of code above does return "YES", the icon is not successfully applied to the folder. Am I doing something wrong in my code?
Thanks.
The NSWorkspace method works like a charm here. Maybe your icon is in an invalid format?
I tried setIcon: using the Finder icon:
- (IBAction)setFolderIcon:(id)sender
{
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:NO];
[openPanel setCanChooseDirectories:YES];
switch([openPanel runModal])
{
case NSFileHandlingPanelOKButton:
{
NSURL* directoryURL = [openPanel directoryURL];
NSImage* iconImage = [[NSImage alloc] initWithContentsOfFile:#"/System/Library/CoreServices/Finder.app/Contents/Resources/Finder.icns"];
BOOL didSetIcon = [[NSWorkspace sharedWorkspace] setIcon:iconImage forFile:[directoryURL path] options:0];
NSLog(#"%d", didSetIcon);
[iconImage release];
}
case NSFileHandlingPanelCancelButton:
{
return;
}
}
}
Related
I want a function which just returns the full file path of a file selected in finder.
I am currently have this function:
+ (NSString*)choosePathWindow:(NSString*)title buttonTitle:(NSString*)buttonTitle allowDir:(BOOL)dir allowFile:(BOOL)file{
[NSApp activateIgnoringOtherApps:YES];
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setLevel:NSFloatingWindowLevel];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setCanChooseDirectories:dir];
[openPanel setCanCreateDirectories:dir];
[openPanel setCanChooseFiles:file];
[openPanel setMessage:title];
[openPanel setPrompt:buttonTitle];
NSString* fileName = nil;
if ([openPanel runModal] == NSModalResponseOK)
{
for( NSURL* URL in [openPanel URLs])
{
fileName = [URL path];
}
}
[openPanel close];
return fileName;
}
But this usually behaves awfully and stutters into view and often hangs after choosing a file (I have an i7-7700k and 16GB ddr4) and always hangs when clicking cancel. I also believe that this may be to do with external network mounts I have. But any other software such as PHPStorm or Chrome work fine with the same window.
Is there a better way to do this?
The code looks fine. Try calling your function from main thread; modal dialogs need this and usually don't enforce it themselves. In any case the Powebox (the thing that runs NSOpenPanel in sandbox) is a bit of a beast. Also you might get different results with debug build launched directly from Xcode (not so good) and release build launched from Finder.
To test NSOpenPanel: Try running your App under a guest account to eliminate all stuff that's cluttering the sandbox .
My code:
(actually in production:)
-(void)OpenIt {
NSOpenPanel* panel = [NSOpenPanel openPanel];
// This method displays the panel and returns immediately.
// The completion handler is called when the user selects an
// item or cancels the panel.
[panel setTitle: "title...."];
NSString *title = NSLocalizedString(#"CHOOSE_FILE", #"");
[panel setMessage: title];
[panel beginWithCompletionHandler:^(NSInteger result){
if (result == NSFileHandlingPanelOKButton) {
NSURL* theDoc = [[panel URLs] objectAtIndex:0];
NSLog(#"%#", theDoc);
// Open the document using url
[self openUsingURL: theDoc];
}
}];
}
I've implemented a simple application that basically outputs informations about a given triangle (see image). I've created the triangles programmatically. I would like to improve this example providing a mechanism to open a say .tri file with its sides (e.g. 3 4 5). How can I achieve that ? I've done some research and found out there's a method called openDocument.. How would I use this on my application ? Can someone give me an example of how to achieve that ? Apparently it's not a document-based application.. I've got this code on github: https://github.com/mcand/TableViewMacExample.
I managed to make the panel appear like below.
- (IBAction)openDocument:(id)sender{
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setAllowedFileTypes:[NSArray arrayWithObjects:#"tri", #"qua",nil]];
[openPanel runModal];
}
After opening the file, I cannot change the values of my NSTableView. The code is like that:
- (IBAction)openDocument:(id)sender{
NSOpenPanel* panel = [NSOpenPanel openPanel];
[panel setAllowedFileTypes:[NSArray arrayWithObjects:#"tri", #"qua",nil]];
[panel beginWithCompletionHandler:^(NSInteger result){
if (result == NSFileHandlingPanelOKButton) {
NSURL* file = [[panel URLs] objectAtIndex:0];
[self performSelectorInBackground:#selector(triangle:) withObject:file];
}
}];
}
-(void) triangle:(NSURL *)file{
NSError *error;
NSString *words = [[NSString alloc] initWithContentsOfURL:file encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", words);
NSArray* lines = [words componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableArray *shapes = [[NSMutableArray alloc] init];
while (lines) {
NSArray*info = [words componentsSeparatedByString:#";"];
// Creates triangles to be populated
CGFloat side1 = (CGFloat)[info[0] floatValue];
CGFloat side2 = (CGFloat)[info[1] floatValue];
CGFloat side3 = (CGFloat)[info[2] floatValue];
Triangle *triangle = [[Triangle alloc] initWithSides:side1 side:side2 andSide:side3];
[shapes addObject:triangle];
}
self.formsArray = shapes;
[self performSelectorOnMainThread:#selector(updateTableView) withObject:nil waitUntilDone:YES];
}
-(void)updateTableView{
[self.tableView reloadData];
}
#end
I've got some action in my application on OS X where I have to select file from finder. I want to display window like: "Open file". I know that this let me open url with path:
[[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:NSHomeDirectory() isDirectory:YES]];
But how to show window with "Select" button. This window should let me to get info about selected file.
How can I do this correctly?
Thank you for help.
The code for previous answers :
NSOpenPanel *op = [NSOpenPanel openPanel];
op.canChooseFiles = YES;
op.canChooseDirectories = YES;
[op runModal];
self.txtFilePath.stringValue = [op.URLs firstObject];
in op.URLs you can find paths for all files you just selected.
Building on EderYif's answer, the following doesn't produce a compiler warning and also removes the 'file://' part of the returned filename.
NSOpenPanel *op = [NSOpenPanel openPanel];
[op setCanChooseFiles:true];
[op setCanChooseDirectories:true];
[op runModal];
NSString* file = [[op.URLs firstObject] absoluteString];
NSString* fixedFile = [file stringByReplacingOccurrencesOfString:#"file://"
withString:#""];
[[self textFilePath] setStringValue:fixedFile];
#Perception and #omz gives me good answer. Answer is NSOpenPanel.
OK, this is my issue :
I have an application with one window (an NSPanel actually)
I'm trying to open and NSOpenPanel and get some input
I may have to push the trigger button like 2-3 times, before it opens up...
This is my code :
- (IBAction)doExport:(id)sender
{
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:NO];
[openPanel setCanChooseDirectories:YES];
NSInteger rezult = [openPanel runModal];
if (rezult == NSFileHandlingPanelOKButton)
{
NSString* dir = [[openPanel URL] path];
// do the processing here
}
}
What's going on???
I have a table with the classic + - buttons underneath it. (on mac)
I want to press the + button, and open a little finder to select a file, to add it on the table.
How can I do that?
I searched the developer reference, but didn't find it..
Use NSOpenPanel.
For a guide on dealing with files and using open panels, see the Application File Management guide.
For instance:
- (IBAction)addFile:(id)sender
{
NSInteger result;
NSArray *fileTypes = [NSArray arrayWithObject:#"html"];
NSOpenPanel *oPanel = [NSOpenPanel openPanel];
[oPanel setAllowsMultipleSelection:YES];
[oPanel setDirectory:NSHomeDirectory()];
[oPanel setCanChooseDirectories:NO];
result = [oPanel runModal];
if (result == NSFileHandlingPanelOKButton) {
for (NSURL *fileURL in [oPanel URLs]) {
// do something with fileURL
}
}
}
Another example using a sheet:
- (IBAction)addFile:(id)sender
{
NSArray *fileTypes = [NSArray arrayWithObject:#"html"];
NSOpenPanel *oPanel = [NSOpenPanel openPanel];
[oPanel setAllowsMultipleSelection:YES];
[oPanel setDirectory:NSHomeDirectory()];
[oPanel setCanChooseDirectories:NO];
[oPanel beginSheetModalForWindow:[self window]
completionHandler:^(NSInteger result) {
if (result == NSFileHandlingPanelOKButton) {
for (NSURL *fileURL in [oPanel URLs]) {
// do something with fileURL
}
}
}];
}