LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/framework/source/services - taskcreatorsrv.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 116 131 88.5 %
Date: 2013-07-09 Functions: 21 27 77.8 %
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/Frame.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/helper/vclunohelper.hxx>
      44             : #include <vcl/window.hxx>
      45             : 
      46             : //_______________________________________________
      47             : // namespaces
      48             : 
      49             : namespace framework
      50             : {
      51             : //-----------------------------------------------
      52        8327 : 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         686 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE_2(TaskCreatorService                ,
      66             :                                        ::cppu::OWeakObject               ,
      67             :                                        "com.sun.star.frame.TaskCreator",
      68             :                                        IMPLEMENTATIONNAME_FWK_TASKCREATOR)
      69             : 
      70             : //-----------------------------------------------
      71          61 : 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 information!
      78             :                         */
      79             :                     }
      80             :                    )
      81             : 
      82             : //-----------------------------------------------
      83          61 : TaskCreatorService::TaskCreatorService(const css::uno::Reference< css::uno::XComponentContext >& xContext)
      84          61 :     : ThreadHelpBase     (&Application::GetSolarMutex())
      85             :     , ::cppu::OWeakObject(                             )
      86         122 :     , m_xContext         (xContext                     )
      87             : {
      88          61 : }
      89             : 
      90             : //-----------------------------------------------
      91         120 : TaskCreatorService::~TaskCreatorService()
      92             : {
      93         120 : }
      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        1103 : 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        1103 :     ::comphelper::SequenceAsHashMap lArgs(lArguments);
     109             : 
     110        2206 :     css::uno::Reference< css::frame::XFrame > xParentFrame                  = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_PARENTFRAME)                  , css::uno::Reference< css::frame::XFrame >());
     111        2206 :     OUString                           sFrameName                    = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_FRAMENAME)                    , OUString()                          );
     112        1103 :     sal_Bool                                  bVisible                      = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_MAKEVISIBLE)                  , sal_False                                  );
     113        1103 :     sal_Bool                                  bCreateTopWindow              = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_CREATETOPWINDOW)              , sal_True                                   );
     114             :     // only possize=[0,0,0,0] triggers default handling of vcl !
     115        1103 :     css::awt::Rectangle                       aPosSize                      = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_POSSIZE)                      , css::awt::Rectangle(0, 0, 0, 0)            );
     116        2206 :     css::uno::Reference< css::awt::XWindow >  xContainerWindow              = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_CONTAINERWINDOW)              , css::uno::Reference< css::awt::XWindow >() );
     117        1103 :     sal_Bool                                  bSupportPersistentWindowState = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE) , sal_False                                  );
     118        1103 :     sal_Bool                                  bEnableTitleBarUpdate         = lArgs.getUnpackedValueOrDefault(OUString(ARGUMENT_ENABLE_TITLEBARUPDATE)        , sal_True                                   );
     119             : 
     120             :     // We use FrameName property to set it as API name of the new created frame later.
     121             :     // But those frame names must be different from the set of special target names as e.g. _blank, _self etcpp !
     122        2206 :     OUString sRightName = impl_filterNames(sFrameName);
     123             : 
     124             :     // if no external frame window was given ... create a new one.
     125        1103 :     if ( ! xContainerWindow.is())
     126             :     {
     127        1102 :         css::uno::Reference< css::awt::XWindow > xParentWindow;
     128        1102 :         if (xParentFrame.is())
     129        1102 :             xParentWindow = xParentFrame->getContainerWindow();
     130             : 
     131             :         // Parent has no own window ...
     132             :         // So we have to create a top level window always !
     133        1102 :         if ( ! xParentWindow.is())
     134        1102 :             bCreateTopWindow = sal_True;
     135             : 
     136        1102 :         xContainerWindow = implts_createContainerWindow(xParentWindow, aPosSize, bCreateTopWindow);
     137             :     }
     138             : 
     139             :     // #i53630#
     140             :     // Mark all document windows as "special ones", so VCL can bind
     141             :     // special features to it. Because VCL doesnt know anything about documents ...
     142             :     // Note: Doing so it's no longer supported, that e.g. our wizards can use findFrame(_blank)
     143             :     // to create it's previes frames. They must do it manually by using WindowDescriptor+Toolkit!
     144        2206 :     css::uno::Reference< css::frame::XDesktop > xDesktop(xParentFrame, css::uno::UNO_QUERY);
     145             :     ::sal_Bool bTopLevelDocumentWindow = (
     146        3300 :                                             sRightName.isEmpty() &&
     147             :                                             (
     148        2198 :                                                 (! xParentFrame.is() )    ||
     149        1099 :                                                 (  xDesktop.is()     )
     150             :                                             )
     151        1103 :                                          );
     152        1103 :     if (bTopLevelDocumentWindow)
     153        1098 :         implts_applyDocStyleToWindow(xContainerWindow);
     154             :     //------------------->
     155             : 
     156             :     // create the new frame
     157        2206 :     css::uno::Reference< css::frame::XFrame2 > xFrame = implts_createFrame(xParentFrame, xContainerWindow, sRightName);
     158             : 
     159             :     // special freature:
     160             :     // A special listener will restore pos/size states in case
     161             :     // a component was loaded into the frame first time.
     162        1103 :     if (bSupportPersistentWindowState)
     163        1102 :         implts_establishWindowStateListener(xFrame);
     164             : 
     165             :     // special feature: On Mac we need tagging the window in case
     166             :     // the underlying model was modified.
     167             :     // VCL will ignore our calls in case different platform then Mac
     168             :     // is used ...
     169        1103 :     if (bTopLevelDocumentWindow)
     170        1098 :         implts_establishDocModifyListener (xFrame);
     171             : 
     172             :     // special freature:
     173             :     // A special listener will update title bar (text and icon)
     174             :     // if component of frame will be changed.
     175        1103 :     if (bEnableTitleBarUpdate)
     176        1103 :         implts_establishTitleBarUpdate(xFrame);
     177             : 
     178             :     // Make it visible directly here ...
     179             :     // if its required from outside.
     180        1103 :     if (bVisible)
     181           0 :         xContainerWindow->setVisible(bVisible);
     182             : 
     183        2206 :     return css::uno::Reference< css::uno::XInterface >(xFrame, css::uno::UNO_QUERY_THROW);
     184             : }
     185             : 
     186             : //-----------------------------------------------
     187        1098 : void TaskCreatorService::implts_applyDocStyleToWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) const
     188             : {
     189             :     // SYNCHRONIZED ->
     190        1098 :     SolarMutexGuard aSolarGuard;
     191        1098 :     Window* pVCLWindow = VCLUnoHelper::GetWindow(xWindow);
     192        1098 :     if (pVCLWindow)
     193        1098 :         pVCLWindow->SetExtendedStyle(WB_EXT_DOCUMENT);
     194             :     // <- SYNCHRONIZED
     195        1098 : }
     196             : 
     197             : //-----------------------------------------------
     198        1102 : css::uno::Reference< css::awt::XWindow > TaskCreatorService::implts_createContainerWindow( const css::uno::Reference< css::awt::XWindow >& xParentWindow ,
     199             :                                                                                            const css::awt::Rectangle&                      aPosSize      ,
     200             :                                                                                                  sal_Bool                                  bTopWindow    )
     201             : {
     202             :     // SAFE  ->
     203        1102 :     ReadGuard aReadLock( m_aLock );
     204        2204 :     css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
     205        1102 :     aReadLock.unlock();
     206             :     // <- SAFE
     207             : 
     208             :     // get toolkit to create task container window
     209        2204 :     css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( xContext );
     210             : 
     211             :     // Check if child frames can be created realy. We need at least a valid window at the parent frame ...
     212        2204 :     css::uno::Reference< css::awt::XWindowPeer > xParentWindowPeer;
     213        1102 :     if ( ! bTopWindow)
     214             :     {
     215           0 :         if ( ! xParentWindow.is())
     216           0 :             bTopWindow = sal_False;
     217             :         else
     218           0 :             xParentWindowPeer = css::uno::Reference< css::awt::XWindowPeer >(xParentWindow, css::uno::UNO_QUERY_THROW);
     219             :     }
     220             : 
     221             :     // describe window properties.
     222        2204 :     css::awt::WindowDescriptor aDescriptor;
     223        1102 :     if (bTopWindow)
     224             :     {
     225        1102 :         aDescriptor.Type                =   css::awt::WindowClass_TOP                       ;
     226        1102 :         aDescriptor.WindowServiceName   =   OUString("window");
     227        1102 :         aDescriptor.ParentIndex         =   -1                                              ;
     228        1102 :         aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >()  ;
     229        1102 :         aDescriptor.Bounds              =   aPosSize                                        ;
     230             :         aDescriptor.WindowAttributes    =   css::awt::WindowAttribute::BORDER               |
     231             :                                             css::awt::WindowAttribute::MOVEABLE             |
     232             :                                             css::awt::WindowAttribute::SIZEABLE             |
     233             :                                             css::awt::WindowAttribute::CLOSEABLE            |
     234        1102 :                                             css::awt::VclWindowPeerAttribute::CLIPCHILDREN  ;
     235             :     }
     236             :     else
     237             :     {
     238           0 :         aDescriptor.Type                =   css::awt::WindowClass_TOP                       ;
     239           0 :         aDescriptor.WindowServiceName   =   OUString("dockingwindow");
     240           0 :         aDescriptor.ParentIndex         =   1                                               ;
     241           0 :         aDescriptor.Parent              =   xParentWindowPeer                               ;
     242           0 :         aDescriptor.Bounds              =   aPosSize                                        ;
     243           0 :         aDescriptor.WindowAttributes    =   css::awt::VclWindowPeerAttribute::CLIPCHILDREN  ;
     244             :     }
     245             : 
     246             :     // create a new blank container window and get access to parent container to append new created task.
     247        2204 :     css::uno::Reference< css::awt::XWindowPeer > xPeer      = xToolkit->createWindow( aDescriptor );
     248        1102 :     css::uno::Reference< css::awt::XWindow >     xWindow    ( xPeer, css::uno::UNO_QUERY );
     249        1102 :     if ( ! xWindow.is())
     250             :         throw css::uno::Exception("TaskCreator service was not able to create suitable frame window.",
     251           0 :                                   static_cast< ::cppu::OWeakObject* >(this));
     252        1102 :     if (bTopWindow)
     253        1102 :         xPeer->setBackground(::svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor);
     254             :     else
     255           0 :         xPeer->setBackground(0xffffffff);
     256             : 
     257        2204 :     return xWindow;
     258             : }
     259             : 
     260             : //-----------------------------------------------
     261        1103 : css::uno::Reference< css::frame::XFrame2 > TaskCreatorService::implts_createFrame( const css::uno::Reference< css::frame::XFrame >& xParentFrame    ,
     262             :                                                                                   const css::uno::Reference< css::awt::XWindow >&  xContainerWindow,
     263             :                                                                                   const OUString&                           sName           )
     264             : {
     265             :     // SAFE  ->
     266        1103 :     ReadGuard aReadLock( m_aLock );
     267        2206 :     css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
     268        1103 :     aReadLock.unlock();
     269             :     // <- SAFE
     270             : 
     271             :     // create new frame.
     272        1103 :     css::uno::Reference< css::frame::XFrame2 > xNewFrame = css::frame::Frame::create( xContext );
     273             : 
     274             :     // Set window on frame.
     275             :     // Do it before calling any other interface methods ...
     276             :     // The new created frame must be initialized before you can do anything else there.
     277        1103 :     xNewFrame->initialize( xContainerWindow );
     278             : 
     279             :     // Put frame to the frame tree.
     280             :     // Note: The property creator/parent will be set on the new putted frame automaticly ... by the parent container.
     281        1103 :     if (xParentFrame.is())
     282             :     {
     283        1103 :         css::uno::Reference< css::frame::XFramesSupplier > xSupplier  (xParentFrame, css::uno::UNO_QUERY_THROW);
     284        2206 :         css::uno::Reference< css::frame::XFrames >         xContainer = xSupplier->getFrames();
     285        2206 :         xContainer->append( css::uno::Reference<css::frame::XFrame>(xNewFrame, css::uno::UNO_QUERY_THROW) );
     286             :     }
     287             : 
     288             :     // Set it's API name (if there is one from outside)
     289        1103 :     if (!sName.isEmpty())
     290           4 :         xNewFrame->setName( sName );
     291             : 
     292        2206 :     return xNewFrame;
     293             : }
     294             : 
     295             : //-----------------------------------------------
     296        1102 : void TaskCreatorService::implts_establishWindowStateListener( const css::uno::Reference< css::frame::XFrame2 >& xFrame )
     297             : {
     298             :     // SAFE  ->
     299        1102 :     ReadGuard aReadLock( m_aLock );
     300        2204 :     css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
     301        1102 :     aReadLock.unlock();
     302             :     // <- SAFE
     303             : 
     304             :     // Special feature: It's allowed for frames using a top level window only!
     305             :     // We must create a special listener service and couple it with the new created task frame.
     306             :     // He will restore or save the window state of it ...
     307             :     // See used classes for further information too.
     308        1102 :     PersistentWindowState* pPersistentStateHandler = new PersistentWindowState( xContext );
     309        2204 :     css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pPersistentStateHandler), css::uno::UNO_QUERY_THROW);
     310             : 
     311        2204 :     css::uno::Sequence< css::uno::Any > lInitData(1);
     312        1102 :     lInitData[0] <<= xFrame;
     313        2204 :     xInit->initialize(lInitData);
     314        1102 : }
     315             : 
     316             : //-----------------------------------------------
     317        1098 : void TaskCreatorService::implts_establishDocModifyListener( const css::uno::Reference< css::frame::XFrame2 >& xFrame )
     318             : {
     319             :     // Special feature: It's allowed for frames using a top level window only!
     320             :     // We must create a special listener service and couple it with the new created task frame.
     321             :     // It will tag the window as modified if the underlying model was modified ...
     322        1098 :     TagWindowAsModified* pTag = new TagWindowAsModified();
     323        1098 :     css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pTag), css::uno::UNO_QUERY_THROW);
     324             : 
     325        2196 :     css::uno::Sequence< css::uno::Any > lInitData(1);
     326        1098 :     lInitData[0] <<= xFrame;
     327        2196 :     xInit->initialize(lInitData);
     328        1098 : }
     329             : 
     330             : //-----------------------------------------------
     331        1103 : void TaskCreatorService::implts_establishTitleBarUpdate( const css::uno::Reference< css::frame::XFrame2 >& xFrame )
     332             : {
     333             :     // SAFE  ->
     334        1103 :     ReadGuard aReadLock( m_aLock );
     335        2206 :     css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
     336        1103 :     aReadLock.unlock();
     337             :     // <- SAFE
     338             : 
     339        1103 :     TitleBarUpdate* pHelper = new TitleBarUpdate (xContext);
     340        2206 :     css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
     341             : 
     342        2206 :     css::uno::Sequence< css::uno::Any > lInitData(1);
     343        1103 :     lInitData[0] <<= xFrame;
     344        2206 :     xInit->initialize(lInitData);
     345        1103 : }
     346             : 
     347             : //-----------------------------------------------
     348        1103 : OUString TaskCreatorService::impl_filterNames( const OUString& sName )
     349             : {
     350        1103 :     OUString sFiltered;
     351        1103 :     if (TargetHelper::isValidNameForFrame(sName))
     352           5 :         sFiltered = sName;
     353        1103 :     return sFiltered;
     354             : }
     355             : 
     356         402 : } // namespace framework
     357             : 
     358             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10