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 "controlfeatureinterception.hxx"
21 : #include "urltransformer.hxx"
22 :
23 :
24 : namespace frm
25 : {
26 :
27 :
28 : using namespace ::com::sun::star::uno;
29 : using namespace ::com::sun::star::frame;
30 : using namespace ::com::sun::star::util;
31 : using namespace ::com::sun::star::lang;
32 :
33 :
34 : //= ControlFeatureInterception
35 :
36 :
37 0 : ControlFeatureInterception::ControlFeatureInterception( const Reference< XComponentContext >& _rxORB )
38 0 : :m_pUrlTransformer( new UrlTransformer( _rxORB ) )
39 : {
40 0 : }
41 :
42 :
43 0 : void SAL_CALL ControlFeatureInterception::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException )
44 : {
45 0 : if ( !_rxInterceptor.is() )
46 : {
47 : OSL_FAIL( "ControlFeatureInterception::registerDispatchProviderInterceptor: invalid interceptor!" );
48 0 : return;
49 : }
50 :
51 0 : if ( m_xFirstDispatchInterceptor.is() )
52 : {
53 : // there is already an interceptor; the new one will become its master
54 0 : Reference< XDispatchProvider > xFirstProvider( m_xFirstDispatchInterceptor, UNO_QUERY );
55 0 : _rxInterceptor->setSlaveDispatchProvider( xFirstProvider );
56 0 : m_xFirstDispatchInterceptor->setMasterDispatchProvider( xFirstProvider );
57 : }
58 :
59 : // we are the master of the chain's first interceptor
60 0 : m_xFirstDispatchInterceptor = _rxInterceptor;
61 0 : m_xFirstDispatchInterceptor->setMasterDispatchProvider( NULL );
62 : // it's the first of the interceptor chain
63 : }
64 :
65 :
66 0 : void SAL_CALL ControlFeatureInterception::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException )
67 : {
68 0 : if ( !_rxInterceptor.is() )
69 : {
70 : OSL_FAIL( "ControlFeatureInterception::releaseDispatchProviderInterceptor: invalid interceptor!" );
71 0 : return;
72 : }
73 :
74 0 : Reference< XDispatchProviderInterceptor > xChainWalk( m_xFirstDispatchInterceptor );
75 :
76 0 : if ( m_xFirstDispatchInterceptor == _rxInterceptor )
77 : { // our chain will have a new first element
78 0 : Reference< XDispatchProviderInterceptor > xSlave( m_xFirstDispatchInterceptor->getSlaveDispatchProvider(), UNO_QUERY );
79 0 : m_xFirstDispatchInterceptor = xSlave;
80 : }
81 : // do this before removing the interceptor from the chain as we won't know it's slave afterwards)
82 :
83 0 : while ( xChainWalk.is() )
84 : {
85 : // walk along the chain of interceptors and look for the interceptor that has to be removed
86 0 : Reference< XDispatchProviderInterceptor > xSlave( xChainWalk->getSlaveDispatchProvider(), UNO_QUERY );
87 :
88 0 : if ( xChainWalk == _rxInterceptor )
89 : {
90 : // old master may be an interceptor too
91 0 : Reference< XDispatchProviderInterceptor > xMaster( xChainWalk->getMasterDispatchProvider(), UNO_QUERY );
92 :
93 : // unchain the interceptor that has to be removed
94 0 : xChainWalk->setSlaveDispatchProvider( NULL );
95 0 : xChainWalk->setMasterDispatchProvider( NULL );
96 :
97 : // reconnect the chain
98 0 : if ( xMaster.is() )
99 : {
100 0 : xMaster->setSlaveDispatchProvider( Reference< XDispatchProvider >::query( xSlave ) );
101 : }
102 :
103 : // if somebody has registered the same interceptor twice, then we will remove
104 : // it once per call ...
105 0 : break;
106 : }
107 :
108 0 : xChainWalk = xSlave;
109 0 : }
110 : }
111 :
112 :
113 0 : void ControlFeatureInterception::dispose()
114 : {
115 : // release all interceptors
116 0 : Reference< XDispatchProviderInterceptor > xInterceptor( m_xFirstDispatchInterceptor );
117 0 : m_xFirstDispatchInterceptor.clear();
118 0 : while ( xInterceptor.is() )
119 : {
120 : // tell the interceptor it has a new (means no) predecessor
121 0 : xInterceptor->setMasterDispatchProvider( NULL );
122 :
123 : // ask for it's successor
124 0 : Reference< XDispatchProvider > xSlave = xInterceptor->getSlaveDispatchProvider();
125 : // and give it the new (means no) successoert
126 0 : xInterceptor->setSlaveDispatchProvider( NULL );
127 :
128 : // start over with the next chain element
129 0 : xInterceptor = xInterceptor.query( xSlave );
130 0 : }
131 0 : }
132 :
133 0 : Reference< XDispatch > ControlFeatureInterception::queryDispatch( const URL& _rURL, const OUString& _rTargetFrameName, ::sal_Int32 _nSearchFlags ) SAL_THROW((RuntimeException))
134 : {
135 0 : Reference< XDispatch > xDispatcher;
136 0 : if ( m_xFirstDispatchInterceptor.is() )
137 0 : xDispatcher = m_xFirstDispatchInterceptor->queryDispatch( _rURL, _rTargetFrameName, _nSearchFlags );
138 0 : return xDispatcher;
139 : }
140 :
141 :
142 0 : Reference< XDispatch > ControlFeatureInterception::queryDispatch( const URL& _rURL ) SAL_THROW((RuntimeException))
143 : {
144 0 : return queryDispatch( _rURL, OUString(), 0 );
145 : }
146 :
147 :
148 0 : Reference< XDispatch > ControlFeatureInterception::queryDispatch( const sal_Char* _pAsciiURL ) SAL_THROW((RuntimeException))
149 : {
150 0 : return queryDispatch( m_pUrlTransformer->getStrictURLFromAscii( _pAsciiURL ) );
151 : }
152 :
153 :
154 : } // namespace frm
155 :
156 :
157 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|