// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ // // This file is part of the LibreOffice project. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "mlo_uno.h" #import "MLOCommon.h" //#include #include #import #include #undef TimeValue #include #include "cppuhelper/bootstrap.hxx" #include "com/sun/star/lang/XMultiServiceFactory.hpp" #include "com/sun/star/lang/XComponent.hpp" #include "com/sun/star/frame/Desktop.hpp" #include "com/sun/star/frame/XFrame.hpp" #include "com/sun/star/frame/XDispatchProvider.hpp" #include "com/sun/star/frame/XDispatchHelper.hpp" #include #include "com/sun/star/frame/XComponentLoader.hpp" #include "com/sun/star/frame/XStorable.hpp" #include "com/sun/star/awt/XScrollBar.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star::uno; using namespace com::sun::star::awt; using namespace com::sun::star::view; using namespace com::sun::star::util; using namespace com::sun::star::container; using namespace com::sun::star::document; using namespace com::sun::star::text; using namespace com::sun::star::lang; using namespace com::sun::star::frame; using namespace com::sun::star::beans; using namespace cppu; #define OU(C_STRING) OUString::createFromAscii(C_STRING) #define LOG_EVAL(REF,NS_STRING) REF.get() ? NSLog(@"%@ created",NS_STRING) : NSLog(@"%@ is null",NS_STRING) // singletons Reference openedComponentContext; Reference openedXComponentFactory; Reference openedXDesktop; Reference < XComponentLoader > openedXComponentLoader; // document singletons Reference openedXComponent; Reference openedXModel; Reference openedXTextViewCursorSupplier; Reference openedXController; Reference openedXPageCursor; Reference openedXViewDataSupplier; Reference openedXSearchable; Reference openedXSelectionSupplier; Reference openedXFrame; Reference openedXDispatchProvider; Reference openedXStorable; Reference currentFindAll; rtl::OUString lastSearch; ::sal_Int32 lastSearchIndex =-1; /// functions Reference< XComponentContext > getXComponentContext() { if(!openedComponentContext.get()) { openedComponentContext.set(cppu::defaultBootstrap_InitialComponentContext()); LOG_EVAL(openedComponentContext,@"XComponentContext"); } return openedComponentContext; } Reference getXComponentFactory() { if(!openedXComponentFactory.get()) { openedXComponentFactory.set(getXComponentContext()->getServiceManager()); LOG_EVAL(openedXComponentFactory,@"XMultiComponentContext"); } return openedXComponentFactory; } Reference getXDesktop() { if(!openedXDesktop.get()) { openedXDesktop.set(getXComponentFactory()->createInstanceWithContext ( OU("com.sun.star.frame.Desktop"), getXComponentContext())); LOG_EVAL(openedXDesktop, @"XDesktop"); } return openedXDesktop; } Reference getXComponentLoader() { if(!openedXComponentLoader.get()) { openedXComponentLoader.set(Reference < XComponentLoader >( Desktop::create(getXComponentContext()))); LOG_EVAL(openedXComponentLoader, @"XComponentLoader"); } return openedXComponentLoader; } Reference getXModel() { if(!openedXModel.get()) { Reference model(openedXComponent.get(), UNO_QUERY); openedXModel.set(model); LOG_EVAL(openedXModel, @"XModel"); } return openedXModel; } Reference getXController() { if(!openedXController.get()) { openedXController.set(getXModel()->getCurrentController()); LOG_EVAL(openedXController, @"XController"); } return openedXController; } Reference getXTextViewCursorSupplier() { if(!openedXTextViewCursorSupplier.get()) { Reference supplier(getXController(), UNO_QUERY); openedXTextViewCursorSupplier.set(supplier); LOG_EVAL(openedXTextViewCursorSupplier, @"XTextViewCursorSupplier"); } return openedXTextViewCursorSupplier; } Reference getXPageCursor() { if(!openedXPageCursor.get()) { Reference cursor(getXTextViewCursorSupplier()->getViewCursor(), UNO_QUERY); openedXPageCursor.set(cursor); LOG_EVAL(openedXPageCursor, @"XPageCursor"); } return openedXPageCursor; } Reference getXViewDataSupplier() { //if(!openedXViewDataSupplier.get()) //{ Reference supplier(getXController(),UNO_QUERY); openedXViewDataSupplier.set(supplier); LOG_EVAL(openedXViewDataSupplier,@"XViewDataSupplier"); //} return openedXViewDataSupplier; } Reference getXSearchable() { if(!openedXSearchable.get()) { Reference xSearchable(getXModel(),UNO_QUERY); openedXSearchable.set(xSearchable); LOG_EVAL(openedXSearchable,@"XSearchable"); } return openedXSearchable; } Reference getXSelectionSupplier() { if(!openedXSelectionSupplier.get()) { Reference supplier(getXController(),UNO_QUERY); openedXSelectionSupplier.set(supplier); LOG_EVAL(openedXSelectionSupplier, @"XSelectionSupplier"); } return openedXSelectionSupplier; } Reference getXFrame() { if(!openedXFrame.get()) { openedXFrame.set(getXController()->getFrame()); LOG_EVAL(openedXFrame, @"XFrame"); } return openedXFrame; } Reference getXDispatchProvider() { if(!openedXDispatchProvider.get()) { Reference provider(getXFrame(),UNO_QUERY); openedXDispatchProvider.set(provider); LOG_EVAL(openedXDispatchProvider, @"XDispatchProvider"); } return openedXDispatchProvider; } Reference getXDispatchHelper() { Reference helper = DispatchHelper::create(getXComponentContext()); LOG_EVAL(helper, @"XDispatchHelper"); return helper; } Reference getXStorable() { if(!openedXStorable.get()) { Reference stroable(getXModel(),UNO_QUERY); openedXStorable.set(stroable); LOG_EVAL(openedXStorable, @"XDispatchProvider"); } return openedXStorable; } NSString * createFileUri(NSString * file) { if(file==nil) { NSString * app_root_escaped = [[[NSBundle mainBundle] bundlePath] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; file = [app_root_escaped stringByAppendingPathComponent:@"test1.odt"]; } else { file = [file stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; } static NSString * prefix = @"file://"; if(![file hasPrefix:prefix]) { return [prefix stringByAppendingString:file]; } return file; } void postOpenUnoInitialization() { getXController(); getXSearchable(); } extern "C" BOOL mlo_open_file(NSString* filepath) { static const OUString TARGET = OU("_default"); static const Sequence PROPS (0); filepath = createFileUri(filepath); NSLog(@"LO : Opening the file : %@",filepath ); NSDate * loadStart = [NSDate date]; getXDesktop(); openedXComponent.set(getXComponentLoader()->loadComponentFromURL(OU([filepath UTF8String]),TARGET,0,PROPS)); if(openedXComponent.get()) { NSLog(@"LO : XComponent opened succesffully. Duration: %f",[[NSDate date] timeIntervalSinceDate:loadStart]); postOpenUnoInitialization(); NSLog(@"LO : created document singletons"); return YES; } return NO; } void setLastSearch(OUString string) { lastSearch = string; lastSearchIndex = -1; currentFindAll.clear(); } void resetLastSearch() { setLastSearch(OUString()); } void convert(const OUString & source,NSMutableString * target) { OString asOString = OUStringToOString( source, RTL_TEXTENCODING_ASCII_US ); [target setString:[NSString stringWithUTF8String:asOString.getStr()]]; } BOOL isResetSearch(NSString * toSearch) { if(!toSearch || ([toSearch length] ==0)) { resetLastSearch(); return YES; } return NO; } void markFind(int searchIndex) { Any currentFind= currentFindAll.get()->getByIndex(searchIndex); getXSelectionSupplier()->select(currentFind); } void markDeltaFind(int findCount,int delta) { lastSearchIndex += delta; if(lastSearchIndex == findCount) { lastSearchIndex=0; } else if(lastSearchIndex < 0) { lastSearchIndex = findCount-1; } markFind(lastSearchIndex); } void markAllFinds(int findCount) { for (int i = 0; i descriptor = getXSearchable()->createSearchDescriptor(); descriptor->setSearchString(current); currentFindAll.set(getXSearchable()->findAll(descriptor)); } } extern "C" void mlo_close(void) { if(openedXComponent.get()) { NSLog(@"Disposing of the XComponent for the opened document"); openedXComponent->dispose(); openedXComponent.clear(); openedXModel.clear(); openedXTextViewCursorSupplier.clear(); openedXController.clear(); openedXPageCursor.clear(); openedXViewDataSupplier.clear(); openedXSearchable.clear(); openedXSelectionSupplier.clear(); openedXFrame.clear(); openedXDispatchProvider.clear(); openedXStorable.clear(); resetLastSearch(); NSLog(@"XComponent disposed successfully"); } } long getLong(Reference & set,const OUString & name) { if(set.get()) { return set->getPropertyValue(name).get(); } return -666; } int getInt(Reference & set,const OUString & name) { return getLong(set, name); } extern "C" void mlo_fetch_view_data(NSMutableString * mutableString) { Any any = getXController()->getViewData(); OUString ou = any.get(); convert(ou, mutableString); } extern "C" long mlo_get_page_count() { static const OUString PAGE_COUNT = OU("PageCount"); Reference< XPropertySet > set( getXController(), UNO_QUERY ); return getLong(set,PAGE_COUNT); } extern "C" long mlo_get_current_page() { return getXPageCursor()->getPage(); } extern "C" int mlo_find(NSString * toSearch,MLOFindSelectionType type) { if(!isResetSearch(toSearch)) { setCurrentFindAll(toSearch); if(currentFindAll.get()) { sal_Int32 count =currentFindAll.get()->getCount(); if(count>0) { switch (type) { case MARK_ALL: // mark all returns total count; markAllFinds(count); return count; case MARK_FIRST: // mark first returns total count // index will be zero markDeltaFind(count,1); return count; case MARK_NEXT: // mark next returns the index markDeltaFind(count, 1); return lastSearchIndex; case MARK_PREVIOUS: // mark previous returns the last index markDeltaFind(count, -1); return lastSearchIndex; } } } } return -1; } extern "C" void mlo_get_selection(NSMutableString * mutableString) { OUString asOuString; Reference currentSelection = getXModel()->getCurrentSelection(); if(currentSelection.get()) { Reference< XIndexAccess > xIndexAccess( currentSelection, UNO_QUERY ); if(xIndexAccess.get() && (xIndexAccess->getCount()>0)) { Reference< XTextRange > xTextRange(xIndexAccess->getByIndex(0),UNO_QUERY); if(xTextRange.get()) { asOuString=xTextRange->getString(); } } } convert(asOuString, mutableString); } extern "C" BOOL mlo_is_document_open(void) { return openedXComponent.is() ? YES : NO; } extern "C" void mlo_select_all(void) { getXDispatchHelper()->executeDispatch(getXDispatchProvider(), OUString(".uno:SelectAll"), OUString("_self"), 0, Sequence()); } extern "C" void mlo_save(void) { if(mlo_is_document_open()) { Reference storable =getXStorable(); if(storable->isReadonly()) { NSLog(@"Cannot save changes. File is read only"); } else { storable->store(); NSLog(@"saved changes"); } } }