I try to get a file icon and to set it back to the same file (goal is to have overlay, but I first want to have this one work):
NSImage *img=[[NSWorkspace sharedWorkspace] iconForFile:#"MyFilePath"];
NSLog(#"x=%.f",img.size.width); // Result=32
[[NSWorkspace sharedWorkspace] setIcon:img forFile:#"MyFilePath" options:0];
-> Result is that my file gets a standard Finder icon instead of keeping its own icon. Anything I am doing wrong ?
Try using it like this:
[[NSWorkspace sharedWorkspace]
setIcon: [[NSImage alloc] initWithContentsOfFile:#"MyFilePath"]
forFile: #"MyFilePath"
options: 0];
You need to to load the icon/image into memory first.
EDIT: Answer updated to provide additional information in regards to
the comment below.
"how can I keep the image in memory to "play" with it before reassigning it?"
The NSImage that gets allocated into memory from your specified path can be manipulated in just about any possible way once it's been loaded. You'll want to thoroughly read the NSImage Class Reference to gain a real understanding of what it does and how use it's methods. For this particular scenario you'll want to be able have a named variable assigned from the icon you load.
Only one change needs to happen with the code above to make it work:
NSImage *iconImage = [[NSImage alloc] initWithContentsOfFile:#"MyFilePath"];
[[NSWorkspace sharedWorkspace]
setIcon: iconImage
forFile: #"MyFilePath"
options: 0];
NSLog(#"iconImage: %#",iconImage);
The slight change essentially assigns the variable iconImage from the NSImage icon; everything else stays the same. The NSLog will give you a very quick glimpse at properties associated with iconImage — where you take it from there is really up to your coding ability and creativity.
Related
I have a program with tableview/details of core data object.
One of the attributes is an image (it only appears in the details).
I think it's best to save just the path to the image file, rather than the image itself (it seems to me that core data files with images are much bigger than the images, even if there is little more than that...).
Since it is supposed that the user drags the image to the imagewell, I thought that it would be appropriate to bind the imagewell to the array controller (AC) using "Value path" (AC.selection.image).
However, this doesn't do anything (the imagewell accepts the image dragged there, but it keeps there when we change selection).
It seems likely to me that I must implement some "Value Transformer", but not the ones which are available (NSUnarchiveFromData and NSKeyedUnarchiveFromData), because I tried those already...
Am I right in this supposition? And if so, what value transformer would that be? Is it something that I'll have to define? Or is this altogether impossible?
Maybe I should add that I'm still using OSX 10.6, and thus some hypothesis seem to be ruled out...
Thanks
Yes. It is possible.
select the image view
Bind it to your object controller. In that value path field, you have to set the path value as string property
From my experience, the "value path" and "value URL" bindings only work one-way, as in, you can specify the image view's contents with them, but you can't extract the path/URL from a dragged image. The documentation says that the "binding is read-only", which is more than a little ambiguous, but I believe this is what it refers to.
I ended up just using a text box with a path inside, a "Choose…" button, and the image view as merely a preview. If you really want the "Image Well" functionality, however, I'd recommend something like KSImageView (GitHub gist) that grabs the path out of the NSPasteboard and stores/rebroadcasts it. Here's the main method for that functionality (after inheriting from NSImageView):
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender {
NSPasteboard *pboard = sender.draggingPasteboard;
NSString *plist = [pboard stringForType:NSFilenamesPboardType];
if (!plist) return;
NSArray<NSString*> *files =
[NSPropertyListSerialization propertyListWithData:[plist dataUsingEncoding:NSUTF8StringEncoding]
options:NSPropertyListImmutable
format:NULL
error:NULL];
if (files.count == 0) return;
NSDictionary *userInfo = #{#"imagePath": files[0]};
[[NSNotificationCenter defaultCenter] postNotificationName:#"KSImageDroppedNotification"
object:self
userInfo:userInfo];
}
You know there is a mini progress bar on the file's icon when we copy a file or download file with safari and chrome.
I am wondering how to let it shown in Finder window when I'm copying or download files with my own code.
Could somebody help me?
Thanks a lot.
I got the way by query file/directory attributes myself. It's quit simple.
Get attributes of the file you want to show a progress bar on it's icon
NSDictionary *fileAttr = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
Get extend attributes
NSDictionary *extendAttr = [fileAttr objectForKey:#"NSFileExtendedAttributes"];
Create a Mutable copy of extendAttr and change some value in it
NSMutableDictionary *mutableExtendAttr = [NSMutableDictionary dictionaryWithDictionary:extendAttr];
// create data of progress value
NSData *progressData = [#"0.1" dataUsingEncoding:NSASCIIStringEncoding];
// change it
[mutableExtendAttr setObject:progressData forKey:#"com.apple.progress.fractionCompleted"];
Create a mutable copy of fileAttr
NSMutableDictionary *mutableFileAttr = [NSMutableDictionary dictionaryWithDictionary:fileAttr];
// change extend attr
[mutableFileAttr setObject:[NSDictionary dictionaryWithDictionary:mutableExtendAttr] forKey:extendAttrKey];
// change file/dir create date to the special one
// if not , progress bar will not show
[mutableFileAttr setObject:[NSDate dateWithString:#"1984-01-24 08:00:00 +0000"] forKey:NSFileCreationDate];
// set attribute to file
[[NSFileManager defaultManager] setAttributes:mutableFileAttr ofItemAtPath:filePath error:&error];
Now you'll find it the progress bar showed up.
One starting point would be to use a NSProgressIndicator, then [progressIndicator setIndeterminate:NO];. Your updates/background operation should then not block the main thread. NSProgressIndicator is a bit different for an AppKit widget -- it permits some updates from secondary threads. Of course, updates to the 'current progress' may also be enqueued upon the main thread's run loop.
I've read several questions about this, but no answer seems to fit. If I want to open maps from my app, with an arbitrary location defined by coordinates and an arbitrary name, to use as a title in a pin dropped in that location, how can I do it? With iOS5 I used the openURL with an url scheme built this way:
maps:q=Arbitrary+name#45.000,45.000
This doesn't work anymore (thus all the apps to be updated!), and I don't seem to find a way to achieve the same behaviour: the name I provide is always used as a search parameter, and if nothing is found the pin won't be dropped. On the other side, any found result seems to override coordinates, so several pin are dropped in another part of the globe.
I am trying even formats such:
http://maps.apple.com/?sll=45.000,45.000&q=Arbitrary+name
Any help?
This can be done by the following way:
CLLocationCoordinate2D coOrdinates = //
MKPlacemark *location = [[MKPlacemark alloc] initWithCoordinate:coOrdinates addressDictionary:nil];
MKMapItem *pinItem = [[MKMapItem alloc] initWithPlacemark:endLocation];
pinItem.name =#"Location";
NSMutableDictionary *launchOptions = [[NSMutableDictionary alloc] init];
[pinItem openInMapsWithLaunchOptions:launchOptions];
[location release];
[launchOptions release];
[pinItem release];
I have a custom icon file (MyApp.icns) set up for my Cocoa App. How can I access an NSImage representation of the icon from within my application?
Something like the following would be perfect:
NSImage * iconImage = [MyApplication defaultIconAsImage];
But I'm sure it isn't that easy :)
I can, of course, get a path to the icon file as follows:
NSString * iconPath = [[NSBundle mainBundle]
pathForResource:#"MyApp" ofType:#"icns"];
But it seems to me that there should be some kind of standard way to access the icon file for the application, other than calling it by name, since the name could change.
What is the proper way to do this?
[NSApp applicationIconImage]
Just for completeness - This is how you get the icon for any application or file on your system.
NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:#"path"];
Pass in the path to the application bundle for an application icon or the path to a file for the icon associated with the file.
Note that -[NSApplication applicationIconImage] doesn't return the correct icon when a custom icon is pasted onto the app. Then you need to do:
NSString* appPath = [[NSBundle mainBundle] bundlePath];
NSImage* appIcon = [[NSWorkspace sharedWorkspace] iconForFile:appPath];
(Reference the dock icon code I wrote for Chromium: http://src.chromium.org/svn/trunk/src/chrome/browser/ui/cocoa/dock_icon.mm)
This is probably a n00b question so I apologize in advance. I'm working with NSImage for the first time and basically I need to simply take a picture that is in my Resources folder, and have it display in an NSView/NSImageWell when a button is clicked.
NSImage *image = [[NSImage alloc] initWithContentsOfFile:#"tiles.PNG"];
if ( [image isValid] ) {
NSImageView *view = [[NSImageView alloc] init];
[selection setImage:image];
[selection setImageScaling:NSScaleProportionally];
}
else {
--- This line of code always activates meaning my image isn't valid
}
My only guess is that I am getting the path wrong to the image file and I have looked all over for the right way to access it. Another guess is that I have my code wrong. Anybody familiar with this? Thanks!
I work a lot more with the iPhone, but initWithContentsOfFile seems to require a full/relative path, which I assume tiles.PNG wouldn't fulfill.
I'd use the class method imageNamed:(NSString *)name, which will search your bundle for you.
You should use NSBundleManger to locate the image like so:
NSBundle *mb=[NSBundle mainBundle];
NSString *fp=[mb pathForResource:#"titles" ofType:#"PNG"];
UIImage *img=[UIImage imageWithContentsOfFile:fp];
That way you don't have to mess with internal paths yourself. Otherwise, you have to have the path relative to the final built product which is hard to create and maintain.