From 4674c3e1c55685203a70368b9323ad85a6bbc00f Mon Sep 17 00:00:00 2001 From: Stephan Witt Date: Sun, 19 Aug 2012 22:27:20 +0200 Subject: [PATCH] Patch from Benjamin Piwowar - see ticket #8185: In order to interact with native osx applications, AppleScript support is a plus. Here is a patch that makes LyX respond to a simple command (run) and that allows to communicate with LyX as with the LyX client. Example of use: tell application "LyX" to run "server-get-filename" with argument ""' returns message:/Users/bpiwowar/newfile1.lyx, code:0 with a message and the error code --- development/MacOSX/Info.plist.in | 4 +++ development/MacOSX/LyX.sdef | 54 ++++++++++++++++++++++++++++ development/MacOSX/Makefile.am | 2 +- development/qmake/lyx.pro | 1 + src/frontends/qt4/GuiApplication.cpp | 3 ++ src/support/AppleScript.h | 32 +++++++++++++++++ src/support/AppleScript.m | 46 ++++++++++++++++++++++++ src/support/AppleScriptProxy.cpp | 46 ++++++++++++++++++++++++ src/support/CMakeLists.txt | 1 + src/support/Makefile.am | 3 ++ 10 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 development/MacOSX/LyX.sdef create mode 100644 src/support/AppleScript.h create mode 100644 src/support/AppleScript.m create mode 100644 src/support/AppleScriptProxy.cpp diff --git a/development/MacOSX/Info.plist.in b/development/MacOSX/Info.plist.in index 3145c1a8ca..32accf4c5d 100644 --- a/development/MacOSX/Info.plist.in +++ b/development/MacOSX/Info.plist.in @@ -37,5 +37,9 @@ @VERSION@ CFBundleSignature OLYX + NSAppleScriptEnabled + YES + OSAScriptingDefinition + LyX.sdef diff --git a/development/MacOSX/LyX.sdef b/development/MacOSX/LyX.sdef new file mode 100644 index 0000000000..41f7408ea5 --- /dev/null +++ b/development/MacOSX/LyX.sdef @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/development/MacOSX/Makefile.am b/development/MacOSX/Makefile.am index 4714c7f5c3..89b1a715bb 100644 --- a/development/MacOSX/Makefile.am +++ b/development/MacOSX/Makefile.am @@ -10,7 +10,7 @@ nodist_bundle_DATA = Info.plist dist_bin_SCRIPTS = lyxeditor -dist_pkgdata_DATA = COPYING LyXapp.icns LyX.icns +dist_pkgdata_DATA = COPYING LyXapp.icns LyX.icns LyX.sdef nodist_pkgdata_DATA = lyxrc.dist diff --git a/development/qmake/lyx.pro b/development/qmake/lyx.pro index cef4569653..de5624bcf7 100644 --- a/development/qmake/lyx.pro +++ b/development/qmake/lyx.pro @@ -574,6 +574,7 @@ HEADERS += \ ../../src/support/gzstream.h \ ../../src/support/lassert.h \ ../../src/support/limited_stack.h \ +../../src/support/linkback/AppleScript.h \ ../../src/support/linkback/LinkBack.h \ ../../src/support/linkback/LinkBackProxy.h \ ../../src/support/linkback/LinkBackServer.h \ diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index 701b488eab..0790b46440 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -72,6 +72,7 @@ #include "support/Systemcall.h" #ifdef Q_WS_MACX +#include "support/AppleScript.h" #include "support/linkback/LinkBackProxy.h" #endif @@ -843,6 +844,8 @@ GuiApplication::GuiApplication(int & argc, char ** argv) /// A translator suitable for the entries in the LyX menu. /// Only needed with Qt/Mac. installTranslator(new MenuTranslator(this)); + /// + setupApplescript(); #endif #ifdef Q_WS_X11 diff --git a/src/support/AppleScript.h b/src/support/AppleScript.h new file mode 100644 index 0000000000..6ac23b63bf --- /dev/null +++ b/src/support/AppleScript.h @@ -0,0 +1,32 @@ +// -*- C++ -*- +/** + * \file AppleScript.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Benjamin Piwowarski + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef LYX_SUPPORT_APPLESCRIPT_H +#define LYX_SUPPORT_APPLESCRIPT_H + +#ifdef __cplusplus +extern "C" { +#endif + /// What is returned by applescript_execute_command + typedef struct { + int code; + char *message; + } LyXFunctionResult; + + LyXFunctionResult applescript_execute_command(const char *cmd, const char *args); + + /// Sets up apple script support + void setupApplescript(); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/support/AppleScript.m b/src/support/AppleScript.m new file mode 100644 index 0000000000..bf06b02d42 --- /dev/null +++ b/src/support/AppleScript.m @@ -0,0 +1,46 @@ +/** + * \file AppleScript.m + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Benjamin Piwowarski + * + * Full author contact details are available in file CREDITS. + */ + +#import +#include "AppleScript.h" + + + +@interface LyxCommand : NSScriptCommand { +} +- (id)performDefaultImplementation; +@end + +@implementation LyxCommand +- (id)performDefaultImplementation { + // Get the command and argument + NSDictionary * theArguments = [self evaluatedArguments]; + + NSString * directParameter = [self directParameter]; + NSString *arg = [theArguments objectForKey: @"arg"]; + + + // Execute the command + LyXFunctionResult result = applescript_execute_command([directParameter UTF8String], [arg UTF8String]); + + // Construct the result record + NSString *message = [NSString stringWithCString:result.message encoding:NSUTF8StringEncoding]; + free(result.message); + + NSDictionary *objcResult = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:result.code], @"code", message, @"message", nil]; + return objcResult; +} + +@end + +/// Needed by AppleScript in order to discover LyxCommand +void setupApplescript() { +} + diff --git a/src/support/AppleScriptProxy.cpp b/src/support/AppleScriptProxy.cpp new file mode 100644 index 0000000000..23272e2caf --- /dev/null +++ b/src/support/AppleScriptProxy.cpp @@ -0,0 +1,46 @@ +// -*- C++ -*- +/** + * \file AppleScriptProxy.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Benjamin Piwowarski + * + * Full author contact details are available in file CREDITS. + */ + #include + +#include "AppleScript.h" + +#include "DispatchResult.h" +#include "FuncRequest.h" +#include "LyX.h" +#include "LyXAction.h" + +#include "frontends/Application.h" + +#include "support/docstring.h" +#include "support/debug.h" + +using namespace std; +using namespace lyx; + +extern "C" LyXFunctionResult applescript_execute_command(const char *cmd, const char *arg) { + LYXERR(Debug::ACTION, "Running command [" << cmd << "] with arguments [" << arg << "]"); + FuncRequest fr(lyxaction.lookupFunc(cmd), arg); + fr.setOrigin(FuncRequest::LYXSERVER); + DispatchResult dr; + theApp()->dispatch(fr, dr); + + string const rval = to_utf8(dr.message()); + char *cstr =(char*) malloc((rval.size()+1)*sizeof(rval[0])); + strcpy (cstr, rval.c_str()); + + // Returns the result + LyXFunctionResult result; + result.code = dr.error() ? -1 : 0; + result.message = cstr; + + return result; +} + diff --git a/src/support/CMakeLists.txt b/src/support/CMakeLists.txt index b42f08cf58..521a42a255 100644 --- a/src/support/CMakeLists.txt +++ b/src/support/CMakeLists.txt @@ -11,6 +11,7 @@ file(GLOB moc_files ${TOP_SRC_DIR}/src/support/${LYX_MOC_FILES}) list(REMOVE_ITEM support_sources ${moc_files} .) if(APPLE) list(APPEND dont_merge ${TOP_SRC_DIR}/src/support/AppleSpeller.m) + list(APPEND dont_merge ${TOP_SRC_DIR}/src/support/AppleScript.m) endif() file(GLOB support_headers ${TOP_SRC_DIR}/src/support/${LYX_HPP_FILES}) diff --git a/src/support/Makefile.am b/src/support/Makefile.am index f0819cf146..f7fad7c4cd 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -120,6 +120,9 @@ if INSTALL_MACOSX liblyxsupport_a_SOURCES += \ AppleSpeller.h \ AppleSpeller.m \ + AppleScript.h \ + AppleScript.m \ + AppleScriptProxy.cpp \ linkback/LinkBack.h \ linkback/LinkBack.m \ linkback/LinkBackProxy.h \ -- 2.39.2