I am new to programming for Mac, so forgive me if my question is too silly.
I am writing a small application, where I need to set a destination folder.
I think, instead of just using a NSButton "Choose folder", the approach that Firefox or Safari with their "Save as..." dialogs take is a very user friendly one.
Using a NSPopUpButton, where one can pick a folder from the user's favorites, or from the last used folders. Additionally I would add a top-most entry "Choose...", what would open a NSOpenPanel.
My question is: How can I get the user's favorite folders, that are shown e.g. in the Finder application, and populate my NSPopUpButton with them?
Here how it looks like in Firefox:
You can find the relevant functions inside the Application Services framework, and you can get the list of items like this:
LSSharedFileListRef favorites = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL);
CFArrayRef snapshot = LSSharedFileListCopySnapshot(favorites, NULL);
CFIndex snapshotCount = CFArrayGetCount(snapshot);
for (CFIndex i = 0; i < snapshotCount; ++i) {
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(snapshot, i);
CFURLRef itemURL = NULL;
LSSharedFileListItemResolve(item, kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes, &itemURL, NULL);
NSLog(#"%#", itemURL);
if (itemURL != NULL) {
CFRelease(itemURL);
}
}
CFRelease(snapshot);
CFRelease(favorites);
When I run this on my computer, I get:
nwnode://domain-AirDrop
file://localhost/Applications/
file://localhost/System/Library/CoreServices/Finder.app/Contents/Resources/MyLibraries/myDocuments.cannedSearch/
file://localhost/Users/dave/
file://localhost/Users/dave/Desktop/
file://localhost/Users/dave/Developer/
file://localhost/Users/dave/Documents/
file://localhost/Users/dave/Downloads/
file://localhost/Users/dave/Dropbox/
Which corresponds to:
Related
I want to use applescript to get the window of an application, but since the app can have several windows, I use objc to get windowId like follow:
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly |
kCGWindowListExcludeDesktopElements,
kCGNullWindowID);
for (CFIndex i = 0; i < windowListCount; i++) {
CFDictionaryRef windowInfo = (CFDictionaryRef)CFArrayGetValueAtIndex(windowList, i);
CGWindowID windowId;
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(windowInfo, kCGWindowNumber), kCGWindowIDCFNumberType, &windowId);
}
but this windowId is different from the windowId I get from the appleScript like follow:
tell application "/Applications/QQBrowser.app"
repeat with theWindow in windows
if visible of theWindow is true then
get id of theWindow
end if
end repeat
end tell
I did not find sth useful, does anybody know why?
my destination is to distinguish the windows of an app, does anybody have some ideas?
Thanks very much~
tell application "Numbers"
get id of every window whose visible is true
end tell
Result: {1462, 1439}
These are unique id's for the open visible windows. You could use this unique id to distinguish windows in an app, and you can also get more information about each window with code like:
get properties of window id 1462
I have this script that finds a paragraph style, puts an item from a library at the very end and applies object style:
myDoc = app.documents[0];
myLib = app.libraries[0];
myObjectStyle = myDoc.objectStyles.item ("marker");
app.findTextPreferences = app.changeTextPreferences = null;
app.findTextPreferences.appliedParagraphStyle = "Custom"
var myFound = app.activeDocument.findText(true);
alert (myFound.length);
try {
for (i = 0; i < myFound.length; i++) {
myIcon = myLib.assets.itemByName("winieta_tr").placeAsset (myFound[i].insertionPoints[-2])[0];
myIcon.appliedObjectStyle = myObjectStyle;
// myFound[i].remove ();
}
}
catch (e) {alert (e.message)}
I don't know how to alter it, so the items are obtained not from library but form pasteboard - any help would be appreciated.
Is it possible to find elements that are in the document by name, as it is with library elements?
Yes, you can find an object by name (you would assign that name in the layers panel) simply by using
myDoc.pageItems.itemByName("myItemName");
If you are looking for the same thing on a specific spread (for example if several items on several spreads have the same name), you can use
myDoc.spreads[0].pageItems.itemByName("myItemName");
Or if you just want to use the currently active spread
app.activeWindow.activeSpread.pageItems.itemByName("myItemName");
Just make sure not to use the page to address a page item on the pasteboard as the pasteboard does not belong to any page.
Is it possible to find elements that are in the document by name, as it is with library elements?
You can apply a script labels to the frame on the pasteboard to give it a name.
I want to open a new Finder window of a specific size in a specific position and displaying a specific folder.
In ScriptingBridge (XCode 6, Mavericks 9.4) I can open a new Finder window and have figured out how to read the URL of the folder it opens. But I am really struggling with how to set the folder to something different.
I have tried to assign the window a 'target' SBObject initialised with a 'URL' property.
but the URL property is readonly although 'target' seems not to be. I've used 'get' to ensure there is a FinderFolder object and a FinderFinderWindow object.
I've tried using a dictionary of properties with a URL key and creating a 'folder'.
FinderFolder *folder = [[[_finder classForScriptingClass:#"folder"] alloc]
initWithProperties:dict];
[[_finder folders] addObject:folder];
I have read the Apple docs and looked for examples all over but cannot find an instance of someone assigning the folder path.
// open folder "Documents" of home folder
FinderFolder *theHomeFolder = [theFinder home];
NSLog(#"theHomeFolder: %#",theHomeFolder);
SBElementArray * theHomeFolderFolders = [theHomeFolder folders];
NSLog(#"theHomeFolderFolders: %#",theHomeFolderFolders);
FinderFolder *theDocsFolder = [theHomeFolderFolders objectWithName:#"Documents"];
NSLog(#"theDocsFolder: %#",theDocsFolder);
[theDocsFolder openUsing:nil withProperties:nil];
FinderFinderWindow * docsFolderWindow = (FinderFinderWindow*) [theDocsFolder containerWindow];
NSLog(#"docsFolderWindow: %#",docsFolderWindow);
docsFolderWindow = [docsFolderWindow get];
NSLog(#"docsFolderWindow: %#",docsFolderWindow);
// change its bounds
docsFolderWindow.bounds = NSMakeRect(64., 64., 800, 600.);
// other fun stuff…
[docsFolderWindow setCurrentView:FinderEcvwListView];
[[docsFolderWindow iconViewOptions] setArrangement:FinderEarrArrangedByName];
[docsFolderWindow cleanUpBy:#selector(name)];
docsFolderWindow.toolbarVisible = NO;
docsFolderWindow.statusbarVisible = NO;
docsFolderWindow.sidebarWidth = 0;
There are a few different ways. The other answer works, or you could explicitly make a new Finder window and set its target property:
NSURL *u = [NSURL fileURLWithPath:#"/tmp"];
FinderFinderWindow *w = [[[theFinder classForScriptingClass:#"Finder window] alloc] init];
[[theFinder finderWindows] addObject:w];
[w setTarget:u];
You could also set it to an SBObject referring to a Finder item, such as theDocsFolder from the other answer.
I have some PDFs containing Hyperlinks both in form of URL and mailto. Now Is there any way or tool(may be 3rd party) to extract the Hyperlink meta information form the PDF like coordinates, link type and destination address. Any help is highly appreciated.
I have already tried with iText and PDFBox but with no major success, even some third party software are not providing me the desired output.
I have tried the following code in Java using iText
PdfReader myReader = new PdfReader("pdf File Path");
PdfDictionary pageDict = myReader.getPageN(1);
PdfArray annots = pageDict.getAsArray(PdfName.ANNOTS);
System.out.println(annots);
ArrayList<String> dests = new ArrayList<String>();
if(annots != null)
{
for(int i=0; i<annots.size(); ++i)
{
PdfDictionary annotDict = annots.getAsDict(i);
PdfName subType = annotDict.getAsName(PdfName.SUBTYPE);
if (subType != null && PdfName.LINK.equals(subType))
{
PdfDictionary action = annotDict.getAsDict(PdfName.A);
if(action != null && PdfName.URI.equals(action.getAsName(PdfName.S)))
{
dests.add(action.getAsString(PdfName.URI).toString());
} // else { its an internal link }
}
}
}
System.out.println(dests);
You can use Docotic.Pdf library for links extraction (disclaimer: I work for the company).
Below is the code that opens specified file, finds all hyperlinks, collects information about position of each link and draws rectangle around each links.
After that the code creates new PDF (with links in rectangles) and a text file with collected information. In the end, both created files are opened in default viewers.
public static void ListAndHighlightLinks(string inputFile, string outputFile, string outputTxt)
{
using (PdfDocument doc = new PdfDocument(inputFile))
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < doc.Pages.Count; i++)
{
PdfPage page = doc.Pages[i];
foreach (PdfWidget widget in page.Widgets)
{
PdfActionArea actionArea = widget as PdfActionArea;
if (actionArea == null)
continue;
PdfUriAction linkAction = actionArea.Action as PdfUriAction;
if (linkAction == null)
continue;
Uri url = linkAction.Uri;
PdfRectangle rect = actionArea.BoundingBox;
// add information about found link into string buffer
sb.Append("Page ");
sb.Append(i.ToString());
sb.Append(" : ");
sb.Append(rect.ToString());
sb.Append(" ");
sb.AppendLine(url.ToString());
// draw rectangle around found link
page.Canvas.DrawRectangle(rect);
}
}
// save document with highlighted links and text information about links to files
doc.Save(outputFile);
System.IO.File.WriteAllText(outputTxt, sb.ToString());
// open created PDF and text file in default viewers
System.Diagnostics.Process.Start(outputTxt);
System.Diagnostics.Process.Start(outputFile);
}
}
You can use the sample code with a call like this:
ListAndHighlightLinks("input.pdf", "output.pdf", "links.txt");
if your pdfs are copy protected, you need to start with step 1, if they're free to copy, you can start with step 2
step 1: convert your pdfs into word .doc: use Adobe Acrobat Pro or an online pdf to word converter:
http://www.pdfonline.com/pdf2word/index.asp
step 2: copy-paste the whole document into the input window here, you can also download the lightweight html tool:
http://www.surf7.net/services/value-added-services/free-web-tools/email-extractor-lite/
select 'url' as 'Type of address to extract', select your separator, hit extract and that's it.
Hope it works cheers.
One possibility would be using a custom JavaScript in Acrobat, which would enumerate the "words" on the page and then read out their Quads. From that you get the coordinates to create a link (or to compare with the links on the page), as well as the actual text (that's the "word(s)".
If it is "only" to set the border of the existing links, you also do another Acrobat JavaScript which enumerates the links of the document, and set their border color property (and you may need to set the width as well).
(if you prefer "buy" over "make" feel free to contact me in private; such things are part of my standard "repertoire").
I have an application which has to be shown on Users list of Finder's sidebar on installation.
So on installation code, I have added one more dictionary object to Library -> Preferences-> com.apple.sidebarlists.plist..
i.e., in useritems -> customListItems of plist.
If I see the plist addition everything looks correct.
On relaunching the Finder.app, it is expected to get that item added in the side bar of Finder. But I am not able to see any change happening instead the plist is overridden with the old items. I tried trashing Finder cache and running the code. still no luck :( Any pointers to what I am missing please.
Thanks in advance!
Use LSSharedFileList.
Add an item to the Finder/Save dialog sidebar
-(void) addPathToSharedItem:(NSString *)path
{
CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:path];
// Create a reference to the shared file list.
LSSharedFileListRef favoriteItems = LSSharedFileListCreate(NULL,
kLSSharedFileListFavoriteItems, NULL);
if (favoriteItems) {
//Insert an item to the list.
LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(favoriteItems,
kLSSharedFileListItemLast, NULL, NULL,
url, NULL, NULL);
if (item){
CFRelease(item);
}
}
CFRelease(favoriteItems);
}