// -*- 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/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 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; } 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(); 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_pages(BOOL last){ if(last){ static const OUString PAGE_COUNT = OU("PageCount"); Reference< XPropertySet > set( getXController(), UNO_QUERY ); return getLong(set,PAGE_COUNT); } 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()); }