/* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */ /* AbiSource Application Framework * Copyright (C) 2004 Francis James Franklin * Copyright (C) 2007 Hubert Figuiere * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include "config.h" #include "ut_string_class.h" #include "ut_xml.h" #include "xap_CocoaApp.h" #include "xap_CocoaAppController.h" #include "xap_CocoaPlugin.h" #include "ap_CocoaPlugin.h" class s_SimpleXML_Listener : public UT_XML::Listener { private: id m_callback; NSString * m_error; UT_XML m_parser; public: s_SimpleXML_Listener (id callback) : m_callback(callback), m_error(0) { m_parser.setListener(this); } virtual ~s_SimpleXML_Listener () { if (m_error) { [m_error release]; m_error = 0; } } NSString * parse (NSString * path) { if (m_parser.parse ([path UTF8String]) != UT_OK) { if (!m_error) { m_error = [NSString stringWithFormat:@"Error while parsing \"%@\"", path]; [m_error retain]; } } return m_error; } virtual void startElement (const gchar * element_name, const gchar ** atts) { NSMutableDictionary * dictionary = [NSMutableDictionary dictionaryWithCapacity:4]; NSString * name = [NSString stringWithUTF8String:element_name]; const gchar ** attr = atts; while (*attr) { const gchar * key = *attr++; const gchar * value = *attr++; if (*key && value) { [dictionary setObject:[NSString stringWithUTF8String:value] forKey:[NSString stringWithUTF8String:key]]; } } if (![m_callback startElement:name attributes:dictionary]) { m_parser.stop(); m_error = @"Simple XML parser stopped by callback method \"startElement:attributes:\"."; [m_error retain]; } } virtual void endElement (const gchar * element_name) { NSString * name = [NSString stringWithUTF8String:element_name]; if (![m_callback endElement:name]) { m_parser.stop(); m_error = @"Simple XML parser stopped by callback method \"endElement:\"."; [m_error retain]; } } virtual void charData (const gchar * buffer, int length) { UT_UTF8String data(buffer,length); // FIXME: remove the UT_UTF8String from here if (![m_callback characterData:[NSString stringWithUTF8String:(data.utf8_str())]]) { m_parser.stop(); m_error = @"Simple XML parser stopped by callback method \"characterData:\"."; [m_error retain]; } } }; @implementation XAP_CocoaPlugin - (id)init { if (![super init]) { return nil; } m_delegate = nil; return self; } - (void)dealloc { // [super dealloc]; } - (BOOL)loadBundleWithPath:(NSString *)path { BOOL bLoaded = NO; if (NSBundle * bundle = [NSBundle bundleWithPath:path]) { if (![bundle isLoaded]) { if ([bundle load]) { if (Class bundleClass = [bundle principalClass]) { if (id instance = [[bundleClass alloc] init]) { if ([instance respondsToSelector:@selector(pluginCanRegisterForAbiWord:version:interface:)]) { [self setDelegate:instance]; unsigned long interface = XAP_COCOAPLUGIN_INTERFACE; NSString * version = [NSString stringWithUTF8String:VERSION]; bLoaded = [instance pluginCanRegisterForAbiWord:self version:version interface:interface]; } if (!bLoaded) { [instance release]; } } } } } } return bLoaded; } - (void)setDelegate:(id )delegate { m_delegate = delegate; } - (id )delegate { return m_delegate; } - (void)appendMenuItem:(NSMenuItem *)menuItem { XAP_CocoaAppController * pController = (XAP_CocoaAppController *) [NSApp delegate]; [pController appendPluginMenuItem:menuItem]; } - (void)removeMenuItem:(NSMenuItem *)menuItem { XAP_CocoaAppController * pController = (XAP_CocoaAppController *) [NSApp delegate]; [pController removePluginMenuItem:menuItem]; } - (id )currentDocument // may return nil; { return [AP_CocoaPlugin_Document currentDocument]; } - (NSArray *)documents { return [AP_CocoaPlugin_Document documents]; } - (NSString *)selectMailMergeSource // may return nil { return [AP_CocoaPlugin_Document selectMailMergeSource]; } /* Returns an NSMutableArray whose objects are NSMutableArray of NSString, the first row holding the * field names, the rest being records; returns nil on failure. */ - (NSMutableArray *)importMailMergeSource:(NSString *)path { return [AP_CocoaPlugin_Document importMailMergeSource:path]; } - (id )importDocumentFromFile:(NSString *)path importOptions:(NSDictionary *)options { return [AP_CocoaPlugin_FramelessDocument documentFromFile:path importOptions:options]; } - (id )contextMenuItemWithLabel:(NSString *)label { return [AP_CocoaPlugin_ContextMenuItem itemWithLabel:label]; } - (NSArray *)toolProviders { XAP_CocoaAppController * pController = (XAP_CocoaAppController *) [NSApp delegate]; return [pController toolProviders]; } - (id )toolProvider:(NSString *)name { XAP_CocoaAppController * pController = (XAP_CocoaAppController *) [NSApp delegate]; return [pController toolProvider:name]; } - (NSString *)findResourcePath:(NSString *)relativePath { XAP_CocoaApp * pApp = static_cast(XAP_App::getApp()); NSString * resource_path = 0; if (relativePath) { if ([relativePath length]) { UT_String path; if (pApp->findAbiSuiteLibFile(path, [relativePath UTF8String])) { resource_path = [NSString stringWithUTF8String:(path.c_str())]; } } } return resource_path; } - (NSString *)userResourcePath:(NSString *)relativePath { XAP_CocoaApp * pApp = static_cast(XAP_App::getApp()); NSString * resource_path = [NSString stringWithUTF8String:(pApp->getUserPrivateDirectory())]; if (relativePath) { if ([relativePath length]) { resource_path = [resource_path stringByAppendingPathComponent:relativePath]; } } return resource_path; } - (NSString *)parseFile:(NSString *)path simpleXML:(id )callback { NSString * error = 0; if (path && callback) { s_SimpleXML_Listener parser(callback); error = parser.parse(path); } else { error = @"Method \"parseFile:simpleXML:\" requires path and callback!"; } return error; } @end