@NotNull private static List<String> processResult(final ID result, final ID panel) { final List<String> resultPaths = new ArrayList<String>(); if (result != null && OK == result.intValue()) { final ID fileNamesArray = invoke(panel, "URLs"); final ID enumerator = invoke(fileNamesArray, "objectEnumerator"); while (true) { final ID url = invoke(enumerator, "nextObject"); if (url == null || 0 == url.intValue()) break; final ID filename = invoke(url, "path"); final String path = Foundation.toStringViaUTF8(filename); if (path != null) { resultPaths.add(path); } } } return resultPaths; }
private static void installAutoUpdateMenu() { ID pool = Foundation.invoke("NSAutoreleasePool", "new"); ID app = Foundation.invoke("NSApplication", "sharedApplication"); ID menu = Foundation.invoke(app, Foundation.createSelector("menu")); ID item = Foundation.invoke(menu, Foundation.createSelector("itemAtIndex:"), 0); ID appMenu = Foundation.invoke(item, Foundation.createSelector("submenu")); final ID checkForUpdatesClass = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSMenuItem"), "NSCheckForUpdates"); Foundation.addMethod(checkForUpdatesClass, Foundation.createSelector("checkForUpdates"), IMPL, "v"); Foundation.registerObjcClassPair(checkForUpdatesClass); ID checkForUpdates = Foundation.invoke("NSCheckForUpdates", "alloc"); Foundation.invoke(checkForUpdates, Foundation.createSelector("initWithTitle:action:keyEquivalent:"), Foundation.nsString("Check for Updates..."), Foundation.createSelector("checkForUpdates"), Foundation.nsString("")); Foundation.invoke(checkForUpdates, Foundation.createSelector("setTarget:"), checkForUpdates); Foundation.invoke(appMenu, Foundation.createSelector("insertItem:atIndex:"), checkForUpdates, 1); Foundation.invoke(checkForUpdates, Foundation.createSelector("release")); Foundation.invoke(pool, Foundation.createSelector("release")); }
private static boolean getMacFormats(DateFormat[] formats) { final int MacFormatterNoStyle = 0; final int MacFormatterShortStyle = 1; final int MacFormatterMediumStyle = 2; final int MacFormatterBehavior_10_4 = 1040; ID autoReleasePool = Foundation.invoke("NSAutoreleasePool", "new"); try { ID dateFormatter = Foundation.invoke("NSDateFormatter", "new"); Foundation.invoke(dateFormatter, Foundation.createSelector("setFormatterBehavior:"), MacFormatterBehavior_10_4); formats[0] = invokeFormatter(dateFormatter, MacFormatterNoStyle, MacFormatterShortStyle); // short date formats[1] = invokeFormatter(dateFormatter, MacFormatterShortStyle, MacFormatterNoStyle); // short time formats[2] = invokeFormatter(dateFormatter, MacFormatterMediumStyle, MacFormatterNoStyle); // medium time formats[3] = invokeFormatter(dateFormatter, MacFormatterShortStyle, MacFormatterShortStyle); // short date/time return true; } finally { Foundation.invoke(autoReleasePool, Foundation.createSelector("release")); } }
private ID getParamsAsID() { LOG.assertTrue(window != null, "Native window must be set first."); params.put(COMMON_DIALOG_PARAM_TYPE.nativeFocusedWindow, window); ID paramsAsID = null; switch (dialogType) { case alert: { paramsAsID = getParamsForAlertDialog(params); break; } case message: { paramsAsID = getParamsForMessageDialog(params); break; } } return paramsAsID; }
@Override public void windowOpened(final WindowEvent e) { if (SystemInfo.isMacOSLion) { Window window = e.getWindow(); if (window instanceof Dialog) { ID _native = MacUtil.findWindowForTitle(((Dialog)window).getTitle()); if (_native != null && _native.intValue() > 0) { // see MacMainFrameDecorator // NSCollectionBehaviorFullScreenAuxiliary = 1 << 8 Foundation.invoke(_native, "setCollectionBehavior:", 1 << 8); } } } SwingUtilities.invokeLater(() -> { myOpened = true; final DialogWrapper activeWrapper = getActiveWrapper(); for (JComponent c : UIUtil.uiTraverser(e.getWindow()).filter(JComponent.class)) { GraphicsUtil.setAntialiasingType(c, AntialiasingType.getAAHintForSwingComponent()); } if (activeWrapper == null) { myFocusedCallback.setRejected(); myTypeAheadDone.setRejected(); } }); }
private static void startModal(final Window w, ID windowId) { long windowPtr = windowId.longValue(); synchronized (lock) { JDK7WindowReorderingWorkaround.disableReordering(); windowFromId.put(windowPtr, w); if (blockedDocumentRoots.keySet().contains(w)) { blockedDocumentRoots.put(w, blockedDocumentRoots.get(w) + 1); } else { blockedDocumentRoots.put(w, 1); } } pumpEventsDocumentExclusively(w); synchronized (lock) { windowFromId.remove(windowPtr); } }
private ID getParamsAsID() { if (window == null) { throw new MacMessageException("Window should be in the list."); } params.put(COMMON_DIALOG_PARAM_TYPE.nativeFocusedWindow, window); ID paramsAsID = null; switch (dialogType) { case alert: paramsAsID = getParamsForAlertDialog(params); break; case message: paramsAsID = getParamsForMessageDialog(params); break; } return paramsAsID; }
private static void installAutoUpdateMenu() { ID pool = Foundation.invoke("NSAutoreleasePool", "new"); ID app = Foundation.invoke("NSApplication", "sharedApplication"); ID menu = Foundation.invoke(app, Foundation.createSelector("menu")); ID item = Foundation.invoke(menu, Foundation.createSelector("itemAtIndex:"), 0); ID appMenu = Foundation.invoke(item, Foundation.createSelector("submenu")); ID checkForUpdatesClass = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSMenuItem"), "NSCheckForUpdates"); Foundation.addMethod(checkForUpdatesClass, Foundation.createSelector("checkForUpdates"), IMPL, "v"); Foundation.registerObjcClassPair(checkForUpdatesClass); ID checkForUpdates = Foundation.invoke("NSCheckForUpdates", "alloc"); Foundation.invoke(checkForUpdates, Foundation.createSelector("initWithTitle:action:keyEquivalent:"), Foundation.nsString("Check for Updates..."), Foundation.createSelector("checkForUpdates"), Foundation.nsString("")); Foundation.invoke(checkForUpdates, Foundation.createSelector("setTarget:"), checkForUpdates); Foundation.invoke(appMenu, Foundation.createSelector("insertItem:atIndex:"), checkForUpdates, 1); Foundation.invoke(checkForUpdates, Foundation.createSelector("release")); Foundation.invoke(pool, Foundation.createSelector("release")); }
private static void updateBehaviorPreferences() { if (!SystemInfo.isMac) return; Foundation.NSAutoreleasePool pool = new Foundation.NSAutoreleasePool(); try { ID defaults = invoke("NSUserDefaults", "standardUserDefaults"); invoke(defaults, "synchronize"); ourClickBehavior = invoke(defaults, "boolForKey:", Foundation.nsString("AppleScrollerPagingBehavior")).intValue() == 1 ? ClickBehavior.JumpToSpot : ClickBehavior.NextPage; } finally { pool.drain(); } }
static boolean invokeHelp(@NonNls @Nullable String id) { if (id == null || "top".equals(id)) id = "startpage"; ID mainBundle = Foundation.invoke("NSBundle", "mainBundle"); ID helpBundle = Foundation.invoke(mainBundle, "objectForInfoDictionaryKey:", Foundation.nsString("CFBundleHelpBookName")); if (helpBundle.equals(ID.NIL)) { return false; } ID helpManager = Foundation.invoke("NSHelpManager", "sharedHelpManager"); Foundation.invoke(helpManager, "openHelpAnchor:inBook:", Foundation.nsString(id), helpBundle); return true; }
@Override public void notify(@NotNull String name, @NotNull String title, @NotNull String description) { final ID notification = invoke(Foundation.getObjcClass("NSUserNotification"), "new"); invoke(notification, "setTitle:", nsString(StringUtil.stripHtml(title, true).replace("%", "%%"))); invoke(notification, "setInformativeText:", nsString(StringUtil.stripHtml(description, true).replace("%", "%%"))); final ID center = invoke(Foundation.getObjcClass("NSUserNotificationCenter"), "defaultUserNotificationCenter"); invoke(center, "deliverNotification:", notification); }
public void register() { final ID autoReleasePool = createAutoReleasePool(); final ID applicationIcon = getApplicationIcon(); final ID defaultNotifications = Foundation.fillArray(myDefaultNotification); final ID allNotifications = Foundation.fillArray(myAllNotifications); final ID userDict = Foundation.createDict( new String[]{GROWL_APP_NAME, GROWL_APP_ICON, GROWL_DEFAULT_NOTIFICATIONS, GROWL_ALL_NOTIFICATIONS}, new Object[]{myProductName, applicationIcon, defaultNotifications, allNotifications}); final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter"); final Object notificationName = Foundation.nsString(GROWL_APPLICATION_REGISTRATION_NOTIFICATION); invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, userDict, true); invoke(autoReleasePool, "release"); }
public void notifyGrowlOf(final String notification, final String title, final String description) { final ID autoReleasePool = createAutoReleasePool(); final ID dict = Foundation.createDict( new String[]{GROWL_NOTIFICATION_NAME, GROWL_NOTIFICATION_TITLE, GROWL_NOTIFICATION_DESCRIPTION, GROWL_APP_NAME}, new Object[]{notification, title, description, myProductName}); final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter"); final Object notificationName = Foundation.nsString(GROWL_NOTIFICATION); invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, dict, true); invoke(autoReleasePool, "release"); }
@SuppressWarnings("UnusedDeclaration") // this is a native up-call public void callback(ID self, ID nsNotification) { if (requestorCount.intValue() == 0) { invoke(self, "oldWindowDidBecomeMain:", nsNotification); } }
@SuppressWarnings("UnusedDeclaration") // this is a native up-call public void callback(ID self) { if (requestorCount.intValue() == 0) { invoke(self, "oldCanBecomeMainWindow"); } }
@SuppressWarnings("UnusedDeclaration") public boolean callback(ID self, String selector, ID panel, ID url) { try { return checkFile(self, url, true); // allow any directory - ability to select nested directories } catch (Exception e) { return false; } }
@SuppressWarnings("UnusedDeclaration") public boolean callback(ID self, String selector, ID panel, ID url, ID outError) { try { return checkFile(self, url, false); } catch (Exception e) { if (!ID.NIL.equals(outError)) { ID domain = Foundation.nsString(ApplicationNamesInfo.getInstance().getProductName()); ID dict = Foundation.createDict(new String[]{"NSLocalizedDescription"}, new Object[]{e.getMessage()}); ID error = Foundation.invoke("NSError", "errorWithDomain:code:userInfo:", domain, 100, dict); new Pointer(outError.longValue()).setLong(0, error.longValue()); } return false; } }
private static boolean checkFile(@NotNull ID self, ID url, boolean quickCheck) throws Exception { MacFileChooserDialogImpl impl = ourImplMap.get(self); if (impl == null) { return true; // already removed from the map: the file is likely to be valid since the user was able to select it } if (url == null || url.intValue() == 0) { return false; } ID filename = Foundation.invoke(url, "path"); String path = Foundation.toStringViaUTF8(filename); if (path == null) { return false; } VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); if (file == null || quickCheck && file.isDirectory()) { return true; } if (!impl.myChooserDescriptor.isFileSelectable(file)) { return false; } if (!quickCheck) { VirtualFile[] files = {file}; impl.myChooserDescriptor.validateSelectedFiles(files); } return true; }
private static void showNativeChooserAsSheet(@NotNull final MacFileChooserDialogImpl impl, @Nullable final String toSelect) { final IdeMenuBar bar = getMenuBar(); if (bar != null) { bar.disableUpdates(); } final ID delegate = invoke(Foundation.getObjcClass("NSOpenPanelDelegate_"), "new"); ourImplMap.put(delegate, impl); final ID select = toSelect == null ? null : Foundation.nsString(toSelect); JDK7WindowReorderingWorkaround.disableReordering(); invoke(delegate, "performSelectorOnMainThread:withObject:waitUntilDone:", Foundation.createSelector("showOpenPanel:"), select, false); }
@Nullable private static BufferedImage captureScreen(@Nullable Window belowWindow, @NotNull Rectangle rect) { ID pool = Foundation.invoke("NSAutoreleasePool", "new"); try { ID windowId = belowWindow != null ? MacUtil.findWindowFromJavaWindow(belowWindow) : null; Foundation.NSRect nsRect = new Foundation.NSRect(rect.x, rect.y, rect.width, rect.height); ID cgWindowId = windowId != null ? Foundation.invoke(windowId, "windowNumber") : ID.NIL; int windowListOptions = cgWindowId != null ? FoundationLibrary.kCGWindowListOptionOnScreenBelowWindow : FoundationLibrary.kCGWindowListOptionAll; int windowImageOptions = FoundationLibrary.kCGWindowImageNominalResolution; ID cgImageRef = Foundation.cgWindowListCreateImage(nsRect, windowListOptions, cgWindowId, windowImageOptions); ID bitmapRep = Foundation.invoke(Foundation.invoke("NSBitmapImageRep", "alloc"), "initWithCGImage:", cgImageRef); ID nsImage = Foundation.invoke(Foundation.invoke("NSImage", "alloc"), "init"); Foundation.invoke(nsImage, "addRepresentation:", bitmapRep); ID data = Foundation.invoke(nsImage, "TIFFRepresentation"); ID bytes = Foundation.invoke(data, "bytes"); ID length = Foundation.invoke(data, "length"); ByteBuffer byteBuffer = Native.getDirectByteBuffer(bytes.longValue(), length.longValue()); Foundation.invoke(nsImage, "release"); byte[] b = new byte[byteBuffer.remaining()]; byteBuffer.get(b); return ImageIO.read(new ByteArrayInputStream(b)); } catch (Throwable t) { LOG.error(t); return null; } finally { Foundation.invoke(pool, "release"); } }
public void callback(ID self, String selector) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { ActionManagerEx am = ActionManagerEx.getInstanceEx(); MouseEvent me = new MouseEvent(JOptionPane.getRootFrame(), MouseEvent.MOUSE_CLICKED, System.currentTimeMillis(), 0, 0, 0, 1, false); am.tryToExecute(am.getAction("CheckForUpdate"), me, null, null, false); } }); }
@Nullable private static Transferable getClipboardContentNatively() { String plainText = "public.utf8-plain-text"; ID pasteboard = Foundation.invoke("NSPasteboard", "generalPasteboard"); ID types = Foundation.invoke(pasteboard, "types"); IntegerType count = Foundation.invoke(types, "count"); ID plainTextType = null; for (int i = 0; i < count.intValue(); i++) { ID each = Foundation.invoke(types, "objectAtIndex:", i); String eachType = Foundation.toStringViaUTF8(each); if (plainText.equals(eachType)) { plainTextType = each; break; } } // will put string value even if we doesn't found java object. this is needed because java caches clipboard value internally and // will reset it ONLY IF we'll put jvm-object into clipboard (see our setContent optimizations which avoids putting jvm-objects // into clipboard) Transferable result = null; if (plainTextType != null) { ID text = Foundation.invoke(pasteboard, "stringForType:", plainTextType); String value = Foundation.toStringViaUTF8(text); if (value == null) { LOG.info(String.format("[Clipboard] Strange string value (null?) for type: %s", plainTextType)); } else { result = new StringSelection(value); } } return result; }
private static DateFormat invokeFormatter(ID dateFormatter, int timeStyle, int dateStyle) { Foundation.invoke(dateFormatter, Foundation.createSelector("setTimeStyle:"), timeStyle); Foundation.invoke(dateFormatter, Foundation.createSelector("setDateStyle:"), dateStyle); String format = Foundation.toStringViaUTF8(Foundation.invoke(dateFormatter, Foundation.createSelector("dateFormat"))); assert format != null; return new SimpleDateFormat(format.trim()); }
private void activateFrame(@Nullable Project openedProject, @NotNull UnityOpenFilePostHandlerRequest body) { if(openedProject == null) { return; } IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(openedProject); if(!((JFrame)ideFrame).isVisible()) { return; } if(SystemInfo.isMac) { RequestFocusHttpRequestHandler.activateFrame(ideFrame); ID id = MacUtil.findWindowFromJavaWindow((Window) ideFrame); if(id != null) { Foundation.invoke(id, "makeKeyAndOrderFront:", ID.NIL); } } else if(SystemInfo.isWindows) { Pointer windowPointer = Native.getWindowPointer((Window) ideFrame); User32.INSTANCE.SetForegroundWindow(new WinDef.HWND(windowPointer)); } else { RequestFocusHttpRequestHandler.activateFrame(ideFrame); } }
static boolean invokeHelp(@NonNls @Nullable String id) { id = id == null || "top".equals(id) ? "startpage" : id; final ID mainBundle = Foundation.invoke("NSBundle", "mainBundle"); final ID helpBundle = Foundation.invoke(mainBundle, "objectForInfoDictionaryKey:", Foundation.nsString("CFBundleHelpBookName")); if (helpBundle.equals(ID.NIL)) { return false; } final ID helpManager = Foundation.invoke("NSHelpManager", "sharedHelpManager"); Foundation.invoke(helpManager, "openHelpAnchor:inBook:", Foundation.nsString(id), helpBundle); return true; }
@Override public void notify(Set<String> allNotifications, @NotNull String notificationName, String title, String description) { final ID notification = invoke(Foundation.getObjcClass("NSUserNotification"), "new"); invoke(notification, "setTitle:", nsString(StringUtil.stripHtml(title == null ? "" : title, true).replace("%", "%%"))); invoke(notification, "setInformativeText:", nsString(StringUtil.stripHtml(description == null ? "" : description, true).replace("%", "%%"))); final ID center = invoke(Foundation.getObjcClass("NSUserNotificationCenter"), "defaultUserNotificationCenter"); invoke(center, "deliverNotification:", notification); }
private static void startModal(final Window w, ID windowId) { synchronized (lock) { windowFromId.put(windowId.longValue(), w); if (blockedDocumentRoots.keySet().contains(w)) { blockedDocumentRoots.put(w, blockedDocumentRoots.get(w) + 1); } else { blockedDocumentRoots.put(w, 1); } } pumpEventsDocumentExclusively(w); }
private static ID getParamsForAlertDialog(HashMap params) { return invoke("NSArray", "arrayWithObjects:", params.get(COMMON_DIALOG_PARAM_TYPE.title), params.get(ALERT_DIALOG_PARAM_TYPE.defaultText), params.get(ALERT_DIALOG_PARAM_TYPE.alternateText), params.get(ALERT_DIALOG_PARAM_TYPE.otherText), params.get(COMMON_DIALOG_PARAM_TYPE.message), params.get(COMMON_DIALOG_PARAM_TYPE.nativeFocusedWindow), nsString(""), params.get(COMMON_DIALOG_PARAM_TYPE.errorStyle), params.get(COMMON_DIALOG_PARAM_TYPE.doNotAskDialogOption1), params.get(COMMON_DIALOG_PARAM_TYPE.doNotAskDialogOption2), null); }
private static ID getParamsForMessageDialog(HashMap params) { return invoke("NSArray", "arrayWithObjects:", params.get(COMMON_DIALOG_PARAM_TYPE.title), params.get(COMMON_DIALOG_PARAM_TYPE.message), params.get(COMMON_DIALOG_PARAM_TYPE.nativeFocusedWindow), nsString(""), params.get(COMMON_DIALOG_PARAM_TYPE.errorStyle), params.get(COMMON_DIALOG_PARAM_TYPE.doNotAskDialogOption1), params.get(MESSAGE_DIALOG_PARAM_TYPE.defaultOptionIndex), params.get(MESSAGE_DIALOG_PARAM_TYPE.focusedOptionIndex), params.get(MESSAGE_DIALOG_PARAM_TYPE.buttonsArray), params.get(COMMON_DIALOG_PARAM_TYPE.doNotAskDialogOption2), null); }
public void callback(ID self, Pointer originalSelector, Pointer selToPerform, ID anObject, ID withObject, boolean waitUntilDone, ID awtMode) { String selectorName = Foundation.stringFromSelector(selToPerform); //LOG.info("selectorName = " + selectorName); if (FIX_ENABLED.get() && "findHeavyweightUnderCursor:".equals(selectorName)) { return; } Foundation.invoke(self, "oldPerformOnMainThread:onObject:withObject:waitUntilDone:awtMode:", selToPerform, anObject, withObject, waitUntilDone, awtMode); }
public void register() { final ID autoReleasePool = createAutoReleasePool(); final ID applicationIcon = getApplicationIcon(); final ID defaultNotifications = fillArray(myDefaultNotification); final ID allNotifications = fillArray(myAllNotifications); final ID userDict = createDict(new String[]{GROWL_APP_NAME, GROWL_APP_ICON, GROWL_DEFAULT_NOTIFICATIONS, GROWL_ALL_NOTIFICATIONS}, new Object[]{myProductName, applicationIcon, defaultNotifications, allNotifications}); final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter"); final Object notificationName = Foundation.nsString(GROWL_APPLICATION_REGISTRATION_NOTIFICATION); invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, userDict, true); invoke(autoReleasePool, "release"); }
public void notifyGrowlOf(final String notification, final String title, final String description) { final ID autoReleasePool = createAutoReleasePool(); final ID dict = createDict(new String[]{ GROWL_NOTIFICATION_NAME, GROWL_NOTIFICATION_TITLE, GROWL_NOTIFICATION_DESCRIPTION, GROWL_APP_NAME}, new Object[]{notification, title, description, myProductName}); final ID center = invoke("NSDistributedNotificationCenter", "defaultCenter"); final Object notificationName = Foundation.nsString(GROWL_NOTIFICATION); invoke(center, "postNotificationName:object:userInfo:deliverImmediately:", notificationName, null, dict, true); invoke(autoReleasePool, "release"); }
private static ID fillArray(final Object[] a) { final ID result = invoke("NSMutableArray", "array"); for (Object s : a) { invoke(result, "addObject:", convertType(s)); } return result; }
private static Object convertType(final Object o) { if (o instanceof Pointer || o instanceof ID) { return o; } else if (o instanceof String) { return Foundation.nsString((String)o); } else { throw new IllegalArgumentException("Unsupported type! " + o.getClass()); } }