/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include // Horrible hack static int viewWidth = 1, viewHeight = 1; void AndroidSalInstance::GetWorkArea(tools::Rectangle& rRect) { rRect = tools::Rectangle( Point( 0, 0 ), Size( viewWidth, viewHeight ) ); } AndroidSalInstance *AndroidSalInstance::getInstance() { if (!ImplGetSVData()) return NULL; return static_cast(GetSalInstance()); } AndroidSalInstance::AndroidSalInstance( std::unique_ptr pMutex ) : SvpSalInstance( std::move(pMutex) ) { // FIXME: remove when uniPoll & runLoop is the only Android entry point. int res = (lo_get_javavm())->AttachCurrentThread(&m_pJNIEnv, NULL); LOGI("AttachCurrentThread res=%d env=%p", res, m_pJNIEnv); } // This is never called on Android until app exit. AndroidSalInstance::~AndroidSalInstance() { int res = (lo_get_javavm())->DetachCurrentThread(); LOGI("DetachCurrentThread res=%d", res); LOGI("destroyed Android Sal Instance"); } bool AndroidSalInstance::AnyInput( VclInputFlags nType ) { if( nType & VclInputFlags::TIMER ) return CheckTimeout( false ); // Unfortunately there is no way to check for a specific type of // input being queued. That information is too hidden, sigh. return SvpSalInstance::s_pDefaultInstance->HasUserEvents(); } void AndroidSalInstance::updateMainThread() { int res = (lo_get_javavm())->AttachCurrentThread(&m_pJNIEnv, NULL); LOGI("updateMainThread AttachCurrentThread res=%d env=%p", res, m_pJNIEnv); SvpSalInstance::updateMainThread(); } void AndroidSalInstance::releaseMainThread() { int res = (lo_get_javavm())->DetachCurrentThread(); LOGI("releaseMainThread DetachCurrentThread res=%d", res); SvpSalInstance::releaseMainThread(); } class AndroidSalSystem : public SvpSalSystem { public: AndroidSalSystem() : SvpSalSystem() {} virtual ~AndroidSalSystem() {} virtual int ShowNativeDialog( const OUString& rTitle, const OUString& rMessage, const std::vector< OUString >& rButtons ); }; SalSystem *AndroidSalInstance::CreateSalSystem() { return new AndroidSalSystem(); } class AndroidSalFrame : public SvpSalFrame { public: AndroidSalFrame( AndroidSalInstance *pInstance, SalFrame *pParent, SalFrameStyleFlags nSalFrameStyle ) : SvpSalFrame(pInstance, pParent, nSalFrameStyle) { if (pParent == NULL && viewWidth > 1 && viewHeight > 1) SetPosSize(0, 0, viewWidth, viewHeight, SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT); } virtual void GetWorkArea(tools::Rectangle& rRect) { AndroidSalInstance::getInstance()->GetWorkArea( rRect ); } virtual void UpdateSettings( AllSettings &rSettings ) { // Clobber the UI fonts #if 0 psp::FastPrintFontInfo aInfo; aInfo.m_aFamilyName = "Roboto"; aInfo.m_eItalic = ITALIC_NORMAL; aInfo.m_eWeight = WEIGHT_NORMAL; aInfo.m_eWidth = WIDTH_NORMAL; psp::PrintFontManager::get().matchFont( aInfo, rSettings.GetUILocale() ); #endif // FIXME: is 14 point enough ? vcl::Font aFont( OUString( "Roboto" ), Size( 0, 14 ) ); StyleSettings aStyleSet = rSettings.GetStyleSettings(); aStyleSet.SetAppFont( aFont ); aStyleSet.SetHelpFont( aFont ); aStyleSet.SetMenuFont( aFont ); aStyleSet.SetToolFont( aFont ); aStyleSet.SetLabelFont( aFont ); aStyleSet.SetRadioCheckFont( aFont ); aStyleSet.SetPushButtonFont( aFont ); aStyleSet.SetFieldFont( aFont ); aStyleSet.SetIconFont( aFont ); aStyleSet.SetTabFont( aFont ); aStyleSet.SetGroupFont( aFont ); rSettings.SetStyleSettings( aStyleSet ); } }; SalFrame *AndroidSalInstance::CreateChildFrame( SystemParentData* /*pParent*/, SalFrameStyleFlags nStyle ) { return new AndroidSalFrame( this, NULL, nStyle ); } SalFrame *AndroidSalInstance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) { return new AndroidSalFrame( this, pParent, nStyle ); } // This is our main entry point: extern "C" SalInstance *create_SalInstance() { LOGI("Android: create_SalInstance!"); AndroidSalInstance* pInstance = new AndroidSalInstance( std::make_unique() ); new SvpSalData(); return pInstance; } int AndroidSalSystem::ShowNativeDialog( const OUString& rTitle, const OUString& rMessage, const std::vector< OUString >& rButtons ) { (void)rButtons; LOGI("LibreOffice native dialog '%s': '%s'", OUStringToOString(rTitle, RTL_TEXTENCODING_ASCII_US).getStr(), OUStringToOString(rMessage, RTL_TEXTENCODING_ASCII_US).getStr()); LOGI("Dialog '%s': '%s'", OUStringToOString(rTitle, RTL_TEXTENCODING_ASCII_US).getStr(), OUStringToOString(rMessage, RTL_TEXTENCODING_ASCII_US).getStr()); if (AndroidSalInstance::getInstance() != NULL) { // Does Android have a native dialog ? if not,. we have to do this ... // Of course it has. android.app.AlertDialog seems like a good // choice, it even has one, two or three buttons. Naturally, // it intended to be used from Java, so some verbose JNI // horror would be needed to use it directly here. Probably we // want some easier to use magic wrapper, hmm. std::unique_ptr xBox(Application::CreateMessageDialog(nullptr, VclMessageType::Warning, VclButtonsType::Ok, rMessage)); xBox->set_title(rTitle); xBox->run(); } else LOGE("VCL not initialized"); return 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */