Add to the "Open Recent" menu an item that doesn't point to a file - cocoa

Is there a way to add an item that doesn't point to a file that exists on the file system to the "Open Recent" menu?
In an application not based on NSDocument, I can add an item to the "Open Recent" submenu with the following code:
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL URLWithString:stringToFilePath]];
It works as documented, as long as the URL points to a file that exists on the file system.
If the url doesn't point to a file on the system, such as a web url, or a custom url scheme, nothing happens.
For example, this code has no effect, and produce no log during execution, even if my app handles the scheme used in the URL:
[[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL URLWithString:#"http://www.stackoverflow.com"]];
Update: someone found (a long time ago) a way to tweak this menu to have it show files whether they exist or not: http://lists.apple.com/archives/cocoa-dev/2007/Apr/msg00651.html
I successfully managed to subclass NSDocumentController, but my override of the method - (NSArray *)recentDocumentURLs is never called.
It's not very surprising, as the doc says:
This method is not a good one to
override since the internals of
NSDocumentController do not generally
use it.
But the doc doesn't say what to use instead and the poster didn't give more detail. Any idea?
If there is no solution, on workaround would be to rewrite the entire menu from scratch.
If possible, I would prefer to avoid that, for all the stuff I get for free (like when you have two items with the same name, it displays the parent directory as well to help differentiate them).

It looks like you'll probably have to create your own menu and maintain your own separate list. This menu automatically excludes files that don't exist.
I believe this is also true of files on removable media that is absent (ie, if the media comes back, the I believe the file is once again available in the list if it hasn't been pushed off by more recent items).

Related

How to show a self-defined view as SCIM.app in the System preference - Keyboard - Input Sources

I am trying to intergrate our input method to the 10.10.3
And I found it's not easy to act like SCIM.app as the pic shows
I opened the activity monitor to see what file it opened (the SCIM.app was not running) As you can see in the following images:
The left shows the file list opened by System preference, and the right shows after I click the pinyin-chinese, the file list opened.
So I guess the little view was created by CoreChinese.framework. Since it was in /System/Library/PrivateFramework , It seems impossible for me to show this view as SCIM.app by a normal way.
I turned to nm and hopper disassembler...But I found it a long way to go
I guess you guys may encounter the same question, maybe you can help me.
Yes, I came across the same problems with yours.
1.It's easy to know that the view you saw, is provided by two part, the upper keyboard is a webview, which takes data in /System/Library/Input Methods/SCIM.app/Contents/Resources/*.keylayout, and finally shown by IntlKeyboard.prePane located in resources directory of Keyboard.prePane. and also you can find the actual html and pics, and 2nd part is a self-defined view provided by Preferences.prefPane.
2.Then 2nd part is to show the view you saw under the keyboard. as SCIM.app does, a file named Preferences.prefPane(must in the Resources directory of SCIM.app) was taken by IntlKeyboard.prePane.

Dragging file with Alt+Cmd from Finder does not use NSDragOperationLink flag in draggingSourceOperationMask

I have a simple app that accepts dropping files from Finder.
I want to support 3 different dragging types:
move
copy
link (make alias)
When pressing Alt+Cmd while dragging, Finder usually creates an alias (link). However, in my app in draggingEntered: the flag NSDragOperationLink is not set in that case.
Below are the various flags for the different modifier key combinations:
move (no keys): Private, Delete, Copy, Generic, Link, Move, All_Obsolete, Every
copy (Alt) : Copy, All_Obsolete, Every
link (Alt+Cmd): Copy, Generic, All_Obsolete, Every
Note how in the last case the Link flag is not set. How could I tell in performDragOperation: that I need to create an alias?
Do I really have to check the modifier keys in the current event? I'd much rather have a clean solution via the source dragging operation mask...
Tested on 10.8.5 and 10.9.
You need to register first your dragged types in the code using
registerfordraggedtypes: api
Yes, I know it's a very old thread but it still comes up in search results.
For drag-and-drop operations that span applications you have to hold down Control to filter for the Link flag.
In the online documentation for NSDraggingInfo draggingSourceOperationMask there's a table showing how the modifier keys are handled but it's wrong (it seems to be describing how the Finder works). If you can dig up older documentation on the drag-and-drop API it shows a different filtering algorithm where Option filters for Copy, Command filters for Generic, and Control filters for Link. That's the filtering algorithm that the OS still applies to inter-application drag-and-drop.

NSApplication orderFrontStandardAboutPanel: Making my about panel slightly less standard

What are my options, if any, of adding additional, arbitrary data to the standard Cocoa about dialog that is displayed by an NSApplication when it receives a orderFrontStandardAboutPanel message.
If you add a file named Credits.rtf to Resources the contents will automatically be used in the expanded standard about panel and you can put whatever info you want in the file. It will still pull the standard copyright, version info, etc from the info.plist. It is the easiest way I know of to add arbitrary info, otherwise you pretty much will have to roll your own about panel.
-[NSApplication orderFrontStandardAboutPanelWithOptions:]
Expanding further on the answers from Darrell Root and theMikeSwan above, Apple's documentation for the credits property of NSApplication.AboutPanelOptionKey states:-
The value of this key is an NSAttributedString displayed in the info
area of the panel. If not specified, AppKit then looks for a file
named “Credits.html”, “Credits.rtf”, and “Credits.rtfd”, in that
order, in the bundle returned by the Bundle class method main. The
first file found is used. If none is found, the info area is left
blank.
Expanding on theMikeSwan's answer, by accident I found that if you add a file named Credits.html to the Resources folder, it's contents get used in the expanded standard about panel. In fact Credits.html appears to override a Credits.rtf.
So your choice whether to use html or rtf format, or wire up "About" to a completely different custom window controller.

user interface: what should a file drop target look like?

I have a dialog that includes file selection and it has a "Browse..." button. But it seems like it would be a good idea to provide some kind of drop target so that the user can use his/her favorite file browser to select a file (or files) and drag it onto my application.
Is there any standard practice for what to use as a drop target?
Is it a file icon of some sort? what would that look like?
I tend to think that drop targets should be where the file "should land". That is, if I had a browse button and file path editbox, I'd make the path box the target. If I made a document editing application, I'd make the entire editing area the drop target (unless that would make an embedded object of course ... :-P who said these things are easy?)
So I'd say it depends on the application. But having a dedicated, separate target with no other purpose than to drop things on may not be the best solution, since it unneccessarily clutters the interface even for people who will never be interested in using the feature.
In Safari (on the Mac, at least), a file-chooser form element (Consisting of a "Choose..." button and a field showing the chosen file's name) is also a drag-and-drop target. (Contrast with Firefox, which treats the whole window as a drag-and-drop target, and will replace the current page with the dropped item.)
Other places, I've seen an inset box, sometimes with a centered, grayed-out "Drag items here" text which disappears if anything is dragged in.
As Ruddy said, I don't recall any standard icon for the drop idea. There is one for the no drop as shown in this image
(source: west-wind.com)
Otherwise I tend to like this kind of drop explanation; I find them pretty explicit.
Usually if a window accepts files for drag'n'drop - it just accepts them anywhere in the window.
If you have a list of files (listbox/view) or an just an text box that accepts a single file, those individual control windows could be the drop target rather than the entire window.
Normally there is no visual indication that a window accepts file drops. The only indication would be that you try it and you don't get the no-drop cursor when you drag across the window.
(Note: this is under MS Windows, other os window systems may have different standards)

Disabling/enabling an application menu item

In trying to learn the very fundamentals of menu handling. My test app's menubar has 3 menus -- namely "TestApp", "File" and "Help". I find I can remove these menus entirely, simply by calling say:
NSMenu* rootMenu = [NSApp mainMenu];
[rootMenu removeItemAtIndex:2];
However, I'd only ever want to temporarily disable them (gray them out). Is there an equally simple way to do this, please?
I may be misunderstanding your question, but it seems like you want to be able to gray-out the actual titles of menus that appear with the system's menu bar (Such as graying-out the "File" menu). I'm not sure if it's even possible, but it certainly goes against the Apple Human Interface Guidelines:
A menu’s title is displayed undimmed
even if all of the menu’s commands are
unavailable (dimmed) at the same time.
Users should always be able to view a
menu’s contents, whether or not they
are currently available.
So, the real solution to the problem is to be able to gray-out all of the menu items within a certain menu when your application is in a certain state. To do this, implement the NSUserInterfaceValidations protocol. It only requires implementing the - (BOOL)validateUserInterfaceItem: method. Typically, when implementing this method, you simply check the selector of the user interface item being validated, and return YES if it should be enabled, or NO if it should not (which will gray-out the menu item).

Resources