Dynamically Populate NSMenuItem Submenu With System Files?

Discussion in 'Mac Programming' started by Darkroom, Dec 1, 2008.

  1. Darkroom Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #1
    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. :)
     
  2. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
  3. Darkroom thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #3
    sorry, i meant just files in a specific location on the computer... for example, i would like to dynamically populate an NSMenuItem submenu with a list of all the files and folders in ~/Documents.
     
  4. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #4
    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.
     
  5. Darkroom thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #5
    *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.
     
  6. Darkroom thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #6
    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?
     
  7. Darkroom thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #7
    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?
     
  8. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #8
    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".
     
  9. Darkroom thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #9
    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?
     

    Attached Files:

Share This Page