LCOV - code coverage report
Current view: top level - libreoffice/framework/source/services - taskcreatorsrv.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 119 136 87.5 %
Date: 2012-12-27 Functions: 19 25 76.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "services/taskcreatorsrv.hxx"
      21             : 
      22             : #include <helper/persistentwindowstate.hxx>
      23             : #include <helper/tagwindowasmodified.hxx>
      24             : #include <helper/titlebarupdate.hxx>
      25             : #include <threadhelp/readguard.hxx>
      26             : #include <threadhelp/writeguard.hxx>
      27             : #include <loadenv/targethelper.hxx>
      28             : #include <services.h>
      29             : 
      30             : #include <com/sun/star/frame/XFrame.hpp>
      31             : #include <com/sun/star/frame/XController.hpp>
      32             : #include <com/sun/star/frame/XModel.hpp>
      33             : #include <com/sun/star/frame/XDesktop.hpp>
      34             : #include <com/sun/star/awt/Toolkit.hpp>
      35             : #include <com/sun/star/awt/XTopWindow.hpp>
      36             : #include <com/sun/star/awt/WindowDescriptor.hpp>
      37             : #include <com/sun/star/awt/WindowAttribute.hpp>
      38             : #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
      39             : 
      40             : #include <svtools/colorcfg.hxx>
      41             : #include <vcl/svapp.hxx>
      42             : 
      43             : #include <toolkit/unohlp.hxx>
      44             : #include <vcl/window.hxx>
      45             : 
      46             : //_______________________________________________
      47             : // namespaces
      48             : 
      49             : namespace framework
      50             : {
      51             : //-----------------------------------------------
      52        1770 : DEFINE_XINTERFACE_3(TaskCreatorService                                ,
      53             :                     OWeakObject                                       ,
      54             :                     DIRECT_INTERFACE(css::lang::XTypeProvider        ),
      55             :                     DIRECT_INTERFACE(css::lang::XServiceInfo         ),
      56             :                     DIRECT_INTERFACE(css::lang::XSingleServiceFactory))
      57             : 
      58             : //-----------------------------------------------
      59           0 : DEFINE_XTYPEPROVIDER_3(TaskCreatorService              ,
      60             :                        css::lang::XTypeProvider        ,
      61             :                        css::lang::XServiceInfo         ,
      62             :                        css::lang::XSingleServiceFactory)
      63             : 
      64             : //-----------------------------------------------
      65          83 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(TaskCreatorService                ,
      66             :                                        ::cppu::OWeakObject               ,
      67             :                                        SERVICENAME_TASKCREATOR           ,
      68             :                                        IMPLEMENTATIONNAME_FWK_TASKCREATOR)
      69             : 
      70             : //-----------------------------------------------
      71           9 : DEFINE_INIT_SERVICE(
      72             :                     TaskCreatorService,
      73             :                     {
      74             :                         /*Attention
      75             :                             I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
      76             :                             to create a new instance of this class by our own supported service factory.
      77             :                             see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
      78             :                         */
      79             :                     }
      80             :                    )
      81             : 
      82             : //-----------------------------------------------
      83           9 : TaskCreatorService::TaskCreatorService(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
      84           9 :     : ThreadHelpBase     (&Application::GetSolarMutex())
      85             :     , ::cppu::OWeakObject(                             )
      86          18 :     , m_xSMGR            (xSMGR                        )
      87             : {
      88           9 : }
      89             : 
      90             : //-----------------------------------------------
      91          18 : TaskCreatorService::~TaskCreatorService()
      92             : {
      93          18 : }
      94             : 
      95             : //-----------------------------------------------
      96           0 : css::uno::Reference< css::uno::XInterface > SAL_CALL TaskCreatorService::createInstance()
      97             :     throw(css::uno::Exception       ,
      98             :           css::uno::RuntimeException)
      99             : {
     100           0 :     return createInstanceWithArguments(css::uno::Sequence< css::uno::Any >());
     101             : }
     102             : 
     103             : //-----------------------------------------------
     104         240 : css::uno::Reference< css::uno::XInterface > SAL_CALL TaskCreatorService::createInstanceWithArguments(const css::uno::Sequence< css::uno::Any >& lArguments)
     105             :     throw(css::uno::Exception       ,
     106             :           css::uno::RuntimeException)
     107             : {
     108         240 :     ::comphelper::SequenceAsHashMap lArgs(lArguments);
     109             : 
     110         240 :     css::uno::Reference< css::frame::XFrame > xParentFrame                  = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_PARENTFRAME)                  , css::uno::Reference< css::frame::XFrame >());
     111         240 :     ::rtl::OUString                           sFrameName                    = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_FRAMENAME)                    , ::rtl::OUString()                          );
     112         240 :     sal_Bool                                  bVisible                      = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_MAKEVISIBLE)                  , sal_False                                  );
     113         240 :     sal_Bool                                  bCreateTopWindow              = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_CREATETOPWINDOW)              , sal_True                                   );
     114             :     // only possize=[0,0,0,0] triggers default handling of vcl !
     115         240 :     css::awt::Rectangle                       aPosSize                      = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_POSSIZE)                      , css::awt::Rectangle(0, 0, 0, 0)            );
     116         240 :     css::uno::Reference< css::awt::XWindow >  xContainerWindow              = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_CONTAINERWINDOW)              , css::uno::Reference< css::awt::XWindow >() );
     117         240 :     sal_Bool                                  bSupportPersistentWindowState = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE) , sal_False                                  );
     118         240 :     sal_Bool                                  bEnableTitleBarUpdate         = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_ENABLE_TITLEBARUPDATE)        , sal_True                                   );
     119             : 
     120             :     /* SAFE { */
     121         240 :     ReadGuard aReadLock( m_aLock );
     122         240 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     123         240 :     aReadLock.unlock();
     124             :     /* } SAFE */
     125             : 
     126             :     // We use FrameName property to set it as API name of the new created frame later.
     127             :     // But those frame names must be different from the set of special target names as e.g. _blank, _self etcpp !
     128         240 :     ::rtl::OUString sRightName = impl_filterNames(sFrameName);
     129             : 
     130             :     // if no external frame window was given ... create a new one.
     131         240 :     if ( ! xContainerWindow.is())
     132             :     {
     133         240 :         css::uno::Reference< css::awt::XWindow > xParentWindow;
     134         240 :         if (xParentFrame.is())
     135         240 :             xParentWindow = xParentFrame->getContainerWindow();
     136             : 
     137             :         // Parent has no own window ...
     138             :         // So we have to create a top level window always !
     139         240 :         if ( ! xParentWindow.is())
     140         240 :             bCreateTopWindow = sal_True;
     141             : 
     142         240 :         xContainerWindow = implts_createContainerWindow(xParentWindow, aPosSize, bCreateTopWindow);
     143             :     }
     144             : 
     145             :     // #i53630#
     146             :     // Mark all document windows as "special ones", so VCL can bind
     147             :     // special features to it. Because VCL doesnt know anything about documents ...
     148             :     // Note: Doing so it's no longer supported, that e.g. our wizards can use findFrame(_blank)
     149             :     // to create it's previes frames. They must do it manually by using WindowDescriptor+Toolkit!
     150         240 :     css::uno::Reference< css::frame::XDesktop > xDesktop(xParentFrame, css::uno::UNO_QUERY);
     151             :     ::sal_Bool bTopLevelDocumentWindow = (
     152         240 :                                             sRightName.isEmpty() &&
     153             :                                             (
     154         240 :                                                 (! xParentFrame.is() )    ||
     155         240 :                                                 (  xDesktop.is()     )
     156             :                                             )
     157         720 :                                          );
     158         240 :     if (bTopLevelDocumentWindow)
     159         240 :         implts_applyDocStyleToWindow(xContainerWindow);
     160             :     //------------------->
     161             : 
     162             :     // create the new frame
     163         240 :     css::uno::Reference< css::frame::XFrame > xFrame = implts_createFrame(xParentFrame, xContainerWindow, sRightName);
     164             : 
     165             :     // special freature:
     166             :     // A special listener will restore pos/size states in case
     167             :     // a component was loaded into the frame first time.
     168         240 :     if (bSupportPersistentWindowState)
     169         240 :         implts_establishWindowStateListener(xFrame);
     170             : 
     171             :     // special feature: On Mac we need tagging the window in case
     172             :     // the underlying model was modified.
     173             :     // VCL will ignore our calls in case different platform then Mac
     174             :     // is used ...
     175         240 :     if (bTopLevelDocumentWindow)
     176         240 :         implts_establishDocModifyListener (xFrame);
     177             : 
     178             :     // special freature:
     179             :     // A special listener will update title bar (text and icon)
     180             :     // if component of frame will be changed.
     181         240 :     if (bEnableTitleBarUpdate)
     182         240 :         implts_establishTitleBarUpdate(xFrame);
     183             : 
     184             :     // Make it visible directly here ...
     185             :     // if its required from outside.
     186         240 :     if (bVisible)
     187           0 :         xContainerWindow->setVisible(bVisible);
     188             : 
     189         240 :     return css::uno::Reference< css::uno::XInterface >(xFrame, css::uno::UNO_QUERY_THROW);
     190             : }
     191             : 
     192             : //-----------------------------------------------
     193         240 : void TaskCreatorService::implts_applyDocStyleToWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) const
     194             : {
     195             :     // SYNCHRONIZED ->
     196         240 :     SolarMutexGuard aSolarGuard;
     197         240 :     Window* pVCLWindow = VCLUnoHelper::GetWindow(xWindow);
     198         240 :     if (pVCLWindow)
     199         240 :         pVCLWindow->SetExtendedStyle(WB_EXT_DOCUMENT);
     200             :     // <- SYNCHRONIZED
     201         240 : }
     202             : 
     203             : //-----------------------------------------------
     204         240 : css::uno::Reference< css::awt::XWindow > TaskCreatorService::implts_createContainerWindow( const css::uno::Reference< css::awt::XWindow >& xParentWindow ,
     205             :                                                                                            const css::awt::Rectangle&                      aPosSize      ,
     206             :                                                                                                  sal_Bool                                  bTopWindow    )
     207             : {
     208             :     // SAFE  ->
     209         240 :     ReadGuard aReadLock( m_aLock );
     210         240 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     211         240 :     aReadLock.unlock();
     212             :     // <- SAFE
     213             : 
     214             :     // get toolkit to create task container window
     215         240 :     css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( comphelper::getComponentContext(xSMGR) );
     216             : 
     217             :     // Check if child frames can be created realy. We need at least a valid window at the parent frame ...
     218         240 :     css::uno::Reference< css::awt::XWindowPeer > xParentWindowPeer;
     219         240 :     if ( ! bTopWindow)
     220             :     {
     221           0 :         if ( ! xParentWindow.is())
     222           0 :             bTopWindow = sal_False;
     223             :         else
     224           0 :             xParentWindowPeer = css::uno::Reference< css::awt::XWindowPeer >(xParentWindow, css::uno::UNO_QUERY_THROW);
     225             :     }
     226             : 
     227             :     // describe window properties.
     228         240 :     css::awt::WindowDescriptor aDescriptor;
     229         240 :     if (bTopWindow)
     230             :     {
     231         240 :         aDescriptor.Type                =   css::awt::WindowClass_TOP                       ;
     232         240 :         aDescriptor.WindowServiceName   =   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("window"));
     233         240 :         aDescriptor.ParentIndex         =   -1                                              ;
     234         240 :         aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >()  ;
     235         240 :         aDescriptor.Bounds              =   aPosSize                                        ;
     236             :         aDescriptor.WindowAttributes    =   css::awt::WindowAttribute::BORDER               |
     237             :                                             css::awt::WindowAttribute::MOVEABLE             |
     238             :                                             css::awt::WindowAttribute::SIZEABLE             |
     239             :                                             css::awt::WindowAttribute::CLOSEABLE            |
     240         240 :                                             css::awt::VclWindowPeerAttribute::CLIPCHILDREN  ;
     241             :     }
     242             :     else
     243             :     {
     244           0 :         aDescriptor.Type                =   css::awt::WindowClass_TOP                       ;
     245           0 :         aDescriptor.WindowServiceName   =   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dockingwindow"));
     246           0 :         aDescriptor.ParentIndex         =   1                                               ;
     247           0 :         aDescriptor.Parent              =   xParentWindowPeer                               ;
     248           0 :         aDescriptor.Bounds              =   aPosSize                                        ;
     249           0 :         aDescriptor.WindowAttributes    =   css::awt::VclWindowPeerAttribute::CLIPCHILDREN  ;
     250             :     }
     251             : 
     252             :     // create a new blank container window and get access to parent container to append new created task.
     253         240 :     css::uno::Reference< css::awt::XWindowPeer > xPeer      = xToolkit->createWindow( aDescriptor );
     254         240 :     css::uno::Reference< css::awt::XWindow >     xWindow    ( xPeer, css::uno::UNO_QUERY );
     255         240 :     if ( ! xWindow.is())
     256             :         throw css::uno::Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TaskCreator service was not able to create suitable frame window.")),
     257           0 :                                   static_cast< ::cppu::OWeakObject* >(this));
     258         240 :     if (bTopWindow)
     259         240 :         xPeer->setBackground(::svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor);
     260             :     else
     261           0 :         xPeer->setBackground(0xffffffff);
     262             : 
     263         240 :     return xWindow;
     264             : }
     265             : 
     266             : //-----------------------------------------------
     267         240 : css::uno::Reference< css::frame::XFrame > TaskCreatorService::implts_createFrame( const css::uno::Reference< css::frame::XFrame >& xParentFrame    ,
     268             :                                                                                   const css::uno::Reference< css::awt::XWindow >&  xContainerWindow,
     269             :                                                                                   const ::rtl::OUString&                           sName           )
     270             : {
     271             :     // SAFE  ->
     272         240 :     ReadGuard aReadLock( m_aLock );
     273         240 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     274         240 :     aReadLock.unlock();
     275             :     // <- SAFE
     276             : 
     277             :     // create new frame.
     278         240 :     css::uno::Reference< css::frame::XFrame > xNewFrame( xSMGR->createInstance( SERVICENAME_FRAME ), css::uno::UNO_QUERY_THROW );
     279             : 
     280             :     // Set window on frame.
     281             :     // Do it before calling any other interface methods ...
     282             :     // The new created frame must be initialized before you can do anything else there.
     283         240 :     xNewFrame->initialize( xContainerWindow );
     284             : 
     285             :     // Put frame to the frame tree.
     286             :     // Note: The property creator/parent will be set on the new putted frame automaticly ... by the parent container.
     287         240 :     if (xParentFrame.is())
     288             :     {
     289         240 :         css::uno::Reference< css::frame::XFramesSupplier > xSupplier  (xParentFrame, css::uno::UNO_QUERY_THROW);
     290         240 :         css::uno::Reference< css::frame::XFrames >         xContainer = xSupplier->getFrames();
     291         240 :         xContainer->append( xNewFrame );
     292             :     }
     293             : 
     294             :     // Set it's API name (if there is one from outside)
     295         240 :     if (!sName.isEmpty())
     296           0 :         xNewFrame->setName( sName );
     297             : 
     298         240 :     return xNewFrame;
     299             : }
     300             : 
     301             : //-----------------------------------------------
     302         240 : void TaskCreatorService::implts_establishWindowStateListener( const css::uno::Reference< css::frame::XFrame >& xFrame )
     303             : {
     304             :     // SAFE  ->
     305         240 :     ReadGuard aReadLock( m_aLock );
     306         240 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     307         240 :     aReadLock.unlock();
     308             :     // <- SAFE
     309             : 
     310             :     // Special feature: It's allowed for frames using a top level window only!
     311             :     // We must create a special listener service and couple it with the new created task frame.
     312             :     // He will restore or save the window state of it ...
     313             :     // See used classes for further informations too.
     314         240 :     PersistentWindowState* pPersistentStateHandler = new PersistentWindowState(xSMGR);
     315         240 :     css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pPersistentStateHandler), css::uno::UNO_QUERY_THROW);
     316             : 
     317         240 :     css::uno::Sequence< css::uno::Any > lInitData(1);
     318         240 :     lInitData[0] <<= xFrame;
     319         240 :     xInit->initialize(lInitData);
     320         240 : }
     321             : 
     322             : //-----------------------------------------------
     323         240 : void TaskCreatorService::implts_establishDocModifyListener( const css::uno::Reference< css::frame::XFrame >& xFrame )
     324             : {
     325             :     // SAFE  ->
     326         240 :     ReadGuard aReadLock( m_aLock );
     327         240 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     328         240 :     aReadLock.unlock();
     329             :     // <- SAFE
     330             : 
     331             :     // Special feature: It's allowed for frames using a top level window only!
     332             :     // We must create a special listener service and couple it with the new created task frame.
     333             :     // It will tag the window as modified if the underlying model was modified ...
     334         240 :     TagWindowAsModified* pTag = new TagWindowAsModified(xSMGR);
     335         240 :     css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pTag), css::uno::UNO_QUERY_THROW);
     336             : 
     337         240 :     css::uno::Sequence< css::uno::Any > lInitData(1);
     338         240 :     lInitData[0] <<= xFrame;
     339         240 :     xInit->initialize(lInitData);
     340         240 : }
     341             : 
     342             : //-----------------------------------------------
     343         240 : void TaskCreatorService::implts_establishTitleBarUpdate( const css::uno::Reference< css::frame::XFrame >& xFrame )
     344             : {
     345             :     // SAFE  ->
     346         240 :     ReadGuard aReadLock( m_aLock );
     347         240 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     348         240 :     aReadLock.unlock();
     349             :     // <- SAFE
     350             : 
     351         240 :     TitleBarUpdate* pHelper = new TitleBarUpdate (xSMGR);
     352         240 :     css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
     353             : 
     354         240 :     css::uno::Sequence< css::uno::Any > lInitData(1);
     355         240 :     lInitData[0] <<= xFrame;
     356         240 :     xInit->initialize(lInitData);
     357         240 : }
     358             : 
     359             : //-----------------------------------------------
     360         240 : ::rtl::OUString TaskCreatorService::impl_filterNames( const ::rtl::OUString& sName )
     361             : {
     362         240 :     ::rtl::OUString sFiltered;
     363         240 :     if (TargetHelper::isValidNameForFrame(sName))
     364           0 :         sFiltered = sName;
     365         240 :     return sFiltered;
     366             : }
     367             : 
     368             : } // namespace framework
     369             : 
     370             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10