Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
i just spent a long time searching for information on how to do this and came up short. i'm assuming i have to create an mutable array from a folder or location somehow, like "~/Documents"... and then have the menu display the array... or i could be totally wrong, which is very likely...

if someone can direct me to information about this that would be great. :)
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Well first off you need to enumerate through the files in the folder, which NSFileManager and NSDirectoryEnumerator can do. Then you need to create menu items, which are NSMenuItem objects, and then add each one to your NSMenu.
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
Well first off you need to enumerate through the files in the folder, which NSFileManager and NSDirectoryEnumerator can do. Then you need to create menu items, which are NSMenuItem objects, and then add each one to your NSMenu.

*head blows up*... wow... i haven't done any of that before... if you know of any place off the top of your head where i can see some sample code or more specific instructionto do something like this please let me know... in the meantime, i'm going to continue reading up on some of those class names you just presented.
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
so, i managed to list the files of the documents folder in the log, but i'm not sure how to add them to my NSMenu. this is where i'm at now:

Code:
@interface AppController : NSObject
	{
	IBOutlet NSMenuItem *documentsMenuItem;
	}

@end

#import "AppController.h"


@implementation AppController

- (id)init
	{
	if ([super init])
		{
		NSFileManager *fileManager = [NSFileManager defaultManager];
		NSString *documentsDirectory = [@"~/Documents" stringByExpandingTildeInPath];
		
		NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtPath:documentsDirectory];
		
		NSString *fileName;
		while (fileName = [directoryEnumerator nextObject])
			{
			[directoryEnumerator skipDescendents];
			[documentsMenuItem insertItem:fileName atIndex:index];
			NSLog(fileName);
			}
		}
	return self;
	}
	
@end

any more hints? also, i'm assuming that this will just display the names in each index, but the idea, clearly, is to be able to load the file if selected. will it do that automatically?
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
the only thing i'm not sure of in my code below is "action:mad:selector(fileOrFolder)", and i'm pretty sure that's wrong. but other than that, it's not producing a file list in the NSMenu. i don't really understand why this doesn't work:

Code:
@interface AppController : NSObject
	{
	IBOutlet NSMenu *documentsMenu;
	}

@implementation AppController

- (id)init
	{
	if ([super init])
		{
		NSFileManager *fileManager = [NSFileManager defaultManager];
		NSString *documentsDirectory = [@"~/Documents" stringByExpandingTildeInPath];
		
		NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtPath:documentsDirectory];
		
		NSString *fileName;
		while (fileName = [directoryEnumerator nextObject])
			{
			[directoryEnumerator skipDescendents];
			NSMenuItem *fileOrFolder = [[NSMenuItem alloc] initWithTitle:fileName action:@selector(fileOrFolder) keyEquivalent:@""];
			[documentsMenu addItem:fileOrFolder];
			[fileOrFolder release];
			NSLog(fileName);
			}
		}
	return self;
	}
	
@end

it's hooked up correctly in IB, so what am i missing?
 

autorelease

macrumors regular
Oct 13, 2008
144
0
Achewood, CA
A selector is a method name. The action parameter needs to be the name of a method to be called when the item is selected; there is no method named "fileOrFolder".
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
A selector is a method name. The action parameter needs to be the name of a method to be called when the item is selected; there is no method named "fileOrFolder".

ok... that makes sense...

i've managed to populate my NSMenu with items, but they are all disabled. i've added a selector, but they're still not selectable.

Code:
- (void)awakeFromNib
	{
	NSMenu *documentsMenu = [[NSMenu alloc] initWithTitle:@"Documents"];
	NSMenuItem *documentsItem = [[NSMenuItem alloc] initWithTitle: @"" action: nil keyEquivalent: @""];
	[documentsItem setSubmenu:documentsMenu];
	
	NSFileManager *fileManager = [NSFileManager defaultManager];
	NSString *documentsDirectory = [@"~/Documents" stringByExpandingTildeInPath];
	NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtPath:documentsDirectory];

	NSString *fileOrFolder;
	while ((fileOrFolder = [directoryEnumerator nextObject]))
		{
		NSLog(fileOrFolder);
		[directoryEnumerator skipDescendents];
		NSMenuItem *documentsItem = [[NSMenuItem alloc] initWithTitle:fileOrFolder action:@selector(launchFileOrFolder:) keyEquivalent:@""];

		[documentsMenu addItem:documentsItem];
		[documentsItem release];
		}
	
	//"theMenu" is an IBOutlet to an NSMenu with 2 items already listed.  i place documentsItem between those 2 items at index:1.
	[theMenu insertItem:documentsItem atIndex:1];
	[documentsMenu release];
	[documentsItem release];
	}
	
- (void)launchFileOrFolder
	{
	[NSApp terminate];
	}

by the way, my selector is just for testing purposes here. the real method will tell a file to launch.

additionally, the title of the documentsMenu is not visible when it's added to theMenu. the menu will appear when it's selected but it's just not showing it's title "Documents" as it should. :confused::confused::confused:

i'm not adverse to learning, but this seems to be a fairly common task that developers would want to implement in their applications, but it seems like a very long difficult process... is there nothing that will do this automatically? maybe a feature in interface builder?
 

Attachments

  • Picture 1.png
    Picture 1.png
    46.5 KB · Views: 129
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.