1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 #include <dispatch/dispatchinformationprovider.hxx>
35 #include <dispatch/closedispatcher.hxx>
36 #include <threadhelp/readguard.hxx>
37 #include <threadhelp/writeguard.hxx>
38 #include <stdtypes.h>
39 #include <services.h>
40 
41 //_________________________________________________________________________________________________________________
42 //	interface includes
43 //_________________________________________________________________________________________________________________
44 #include <com/sun/star/frame/CommandGroup.hpp>
45 
46 //_________________________________________________________________________________________________________________
47 //	includes of other projects
48 //_________________________________________________________________________________________________________________
49 #include <comphelper/sequenceasvector.hxx>
50 
51 //_________________________________________________________________________________________________________________
52 //	namespace
53 //_________________________________________________________________________________________________________________
54 
55 namespace framework{
56 
57 namespace css = ::com::sun::star;
58 
59 //_________________________________________________________________________________________________________________
60 //	declarations
61 //_________________________________________________________________________________________________________________
62 DEFINE_XINTERFACE_1(DispatchInformationProvider                               ,
63                     OWeakObject                                               ,
64                     DIRECT_INTERFACE(css::frame::XDispatchInformationProvider))
65 
66 //_________________________________________________________________________________________________________________
67 DispatchInformationProvider::DispatchInformationProvider(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
68                                                          const css::uno::Reference< css::frame::XFrame >&              xFrame)
69     : ThreadHelpBase(&Application::GetSolarMutex())
70     , m_xSMGR       (xSMGR                        )
71     , m_xFrame      (xFrame                       )
72 {
73 }
74 
75 //_________________________________________________________________________________________________________________
76 DispatchInformationProvider::~DispatchInformationProvider()
77 {
78 }
79 
80 //_________________________________________________________________________________________________________________
81 css::uno::Sequence< sal_Int16 > SAL_CALL DispatchInformationProvider::getSupportedCommandGroups()
82     throw (css::uno::RuntimeException)
83 {
84     css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > lProvider = implts_getAllSubProvider();
85     sal_Int32                                                                             c1        = lProvider.getLength();
86     sal_Int32                                                                             i1        = 0;
87 
88     ::comphelper::SequenceAsVector< sal_Int16 > lGroups;
89 
90     for (i1=0; i1<c1; ++i1)
91     {
92         // ignore controller, which doesnt implement the right interface
93         css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider = lProvider[i1];
94         if (!xProvider.is())
95             continue;
96 
97         const css::uno::Sequence< sal_Int16 > lProviderGroups = xProvider->getSupportedCommandGroups();
98               sal_Int32                       c2              = lProviderGroups.getLength();
99               sal_Int32                       i2              = 0;
100         for (i2=0; i2<c2; ++i2)
101         {
102             const sal_Int16&                                                  rGroup = lProviderGroups[i2];
103                   ::comphelper::SequenceAsVector< sal_Int16 >::const_iterator pGroup = ::std::find(lGroups.begin(), lGroups.end(), rGroup);
104             if (pGroup == lGroups.end())
105                 lGroups.push_back(rGroup);
106         }
107     }
108 
109     return lGroups.getAsConstList();
110 }
111 
112 //_________________________________________________________________________________________________________________
113 css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL DispatchInformationProvider::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
114     throw (css::uno::RuntimeException)
115 {
116     css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > lProvider = implts_getAllSubProvider();
117     sal_Int32                                                                             c1        = lProvider.getLength();
118     sal_Int32                                                                             i1        = 0;
119 
120     BaseHash< css::frame::DispatchInformation > lInfos;
121 
122     for (i1=0; i1<c1; ++i1)
123     {
124         try
125         {
126             // ignore controller, which doesnt implement the right interface
127             css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider = lProvider[i1];
128             if (!xProvider.is())
129                 continue;
130 
131             const css::uno::Sequence< css::frame::DispatchInformation > lProviderInfos = xProvider->getConfigurableDispatchInformation(nCommandGroup);
132                   sal_Int32                                             c2             = lProviderInfos.getLength();
133                   sal_Int32                                             i2             = 0;
134             for (i2=0; i2<c2; ++i2)
135             {
136                 const css::frame::DispatchInformation&                            rInfo = lProviderInfos[i2];
137                       BaseHash< css::frame::DispatchInformation >::const_iterator pInfo = lInfos.find(rInfo.Command);
138                 if (pInfo == lInfos.end())
139                     lInfos[rInfo.Command] = rInfo;
140             }
141         }
142         catch(const css::uno::RuntimeException& exRun)
143             { throw exRun; }
144         catch(const css::uno::Exception&)
145             { continue; }
146     }
147 
148     c1 = (sal_Int32)lInfos.size();
149     i1 = 0;
150 
151     css::uno::Sequence< css::frame::DispatchInformation >       lReturn(c1);
152     BaseHash< css::frame::DispatchInformation >::const_iterator pStepp ;
153     for (  pStepp  = lInfos.begin()          ;
154            pStepp != lInfos.end  () && i1<c1 ;
155          ++pStepp, ++i1                      )
156     {
157         lReturn[i1] = pStepp->second;
158     }
159     return lReturn;
160 }
161 
162 //_________________________________________________________________________________________________________________
163 css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > DispatchInformationProvider::implts_getAllSubProvider()
164 {
165     // SAFE -> ----------------------------------
166     ReadGuard aReadLock(m_aLock);
167     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
168     css::uno::Reference< css::frame::XFrame >              xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
169     aReadLock.unlock();
170     // <- SAFE ----------------------------------
171 
172     if (!xFrame.is())
173         return css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > >();
174 
175     CloseDispatcher* pCloser = new CloseDispatcher(xSMGR, xFrame, ::rtl::OUString::createFromAscii("_self")); // explicit "_self" ... not "" ... see implementation of close dispatcher itself!
176     css::uno::Reference< css::uno::XInterface > xCloser(static_cast< css::frame::XDispatch* >(pCloser), css::uno::UNO_QUERY);
177 
178     css::uno::Reference< css::frame::XDispatchInformationProvider > xCloseDispatch(xCloser                                                      , css::uno::UNO_QUERY);
179     css::uno::Reference< css::frame::XDispatchInformationProvider > xController   (xFrame->getController()                                      , css::uno::UNO_QUERY);
180     css::uno::Reference< css::frame::XDispatchInformationProvider > xAppDispatcher(xSMGR->createInstance(IMPLEMENTATIONNAME_APPDISPATCHPROVIDER), css::uno::UNO_QUERY);
181 
182     css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > lProvider(3);
183     lProvider[0] = xController   ;
184     lProvider[1] = xCloseDispatch;
185     lProvider[2] = xAppDispatcher;
186 
187     return lProvider;
188 }
189 
190 } // namespace framework
191