1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "precompiled_sd.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include "ConfigurationClassifier.hxx"
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include "framework/FrameworkHelper.hxx"
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir using namespace ::com::sun::star;
35*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
36*cdf0e10cSrcweir using namespace ::com::sun::star::drawing::framework;
37*cdf0e10cSrcweir using ::rtl::OUString;
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #undef VERBOSE
40*cdf0e10cSrcweir //#define VERBOSE 2
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir namespace sd { namespace framework {
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir ConfigurationClassifier::ConfigurationClassifier (
46*cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration1,
47*cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration2)
48*cdf0e10cSrcweir     : mxConfiguration1(rxConfiguration1),
49*cdf0e10cSrcweir       mxConfiguration2(rxConfiguration2),
50*cdf0e10cSrcweir       maC1minusC2(),
51*cdf0e10cSrcweir       maC2minusC1(),
52*cdf0e10cSrcweir       maC1andC2()
53*cdf0e10cSrcweir {
54*cdf0e10cSrcweir }
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir bool ConfigurationClassifier::Partition (void)
60*cdf0e10cSrcweir {
61*cdf0e10cSrcweir     maC1minusC2.clear();
62*cdf0e10cSrcweir     maC2minusC1.clear();
63*cdf0e10cSrcweir     maC1andC2.clear();
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir     PartitionResources(
66*cdf0e10cSrcweir         mxConfiguration1->getResources(NULL, OUString(), AnchorBindingMode_DIRECT),
67*cdf0e10cSrcweir         mxConfiguration2->getResources(NULL, OUString(), AnchorBindingMode_DIRECT));
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir     return !maC1minusC2.empty() || !maC2minusC1.empty();
70*cdf0e10cSrcweir }
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1minusC2 (void) const
76*cdf0e10cSrcweir {
77*cdf0e10cSrcweir     return maC1minusC2;
78*cdf0e10cSrcweir }
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC2minusC1 (void) const
84*cdf0e10cSrcweir {
85*cdf0e10cSrcweir     return maC2minusC1;
86*cdf0e10cSrcweir }
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1andC2 (void) const
91*cdf0e10cSrcweir {
92*cdf0e10cSrcweir     return maC1andC2;
93*cdf0e10cSrcweir }
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir void ConfigurationClassifier::PartitionResources (
97*cdf0e10cSrcweir     const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1,
98*cdf0e10cSrcweir     const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2)
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir     ResourceIdVector aC1minusC2;
101*cdf0e10cSrcweir     ResourceIdVector aC2minusC1;
102*cdf0e10cSrcweir     ResourceIdVector aC1andC2;
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir     // Classify the resources in the configurations that are not bound to
105*cdf0e10cSrcweir     // other resources.
106*cdf0e10cSrcweir     ClassifyResources(
107*cdf0e10cSrcweir         rS1,
108*cdf0e10cSrcweir         rS2,
109*cdf0e10cSrcweir         aC1minusC2,
110*cdf0e10cSrcweir         aC2minusC1,
111*cdf0e10cSrcweir         aC1andC2);
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir #if defined VERBOSE && VERBOSE >= 2
114*cdf0e10cSrcweir     OSL_TRACE("copying resource ids to C1-C2\r");
115*cdf0e10cSrcweir #endif
116*cdf0e10cSrcweir     CopyResources(aC1minusC2, mxConfiguration1, maC1minusC2);
117*cdf0e10cSrcweir #if defined VERBOSE && VERBOSE >= 2
118*cdf0e10cSrcweir     OSL_TRACE("copying resource ids to C2-C1\r");
119*cdf0e10cSrcweir #endif
120*cdf0e10cSrcweir     CopyResources(aC2minusC1, mxConfiguration2, maC2minusC1);
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir     // Process the unique resources that belong to both configurations.
123*cdf0e10cSrcweir     ResourceIdVector::const_iterator iResource;
124*cdf0e10cSrcweir     for (iResource=aC1andC2.begin(); iResource!=aC1andC2.end(); ++iResource)
125*cdf0e10cSrcweir     {
126*cdf0e10cSrcweir         maC1andC2.push_back(*iResource);
127*cdf0e10cSrcweir         PartitionResources(
128*cdf0e10cSrcweir             mxConfiguration1->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT),
129*cdf0e10cSrcweir             mxConfiguration2->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT));
130*cdf0e10cSrcweir     }
131*cdf0e10cSrcweir }
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir void ConfigurationClassifier::ClassifyResources (
137*cdf0e10cSrcweir     const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1,
138*cdf0e10cSrcweir     const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2,
139*cdf0e10cSrcweir     ResourceIdVector& rS1minusS2,
140*cdf0e10cSrcweir     ResourceIdVector& rS2minusS1,
141*cdf0e10cSrcweir     ResourceIdVector& rS1andS2)
142*cdf0e10cSrcweir {
143*cdf0e10cSrcweir     // Get arrays from the sequences for faster iteration.
144*cdf0e10cSrcweir     const Reference<XResourceId>* aA1 = rS1.getConstArray();
145*cdf0e10cSrcweir     const Reference<XResourceId>* aA2 = rS2.getConstArray();
146*cdf0e10cSrcweir     sal_Int32 nL1 (rS1.getLength());
147*cdf0e10cSrcweir     sal_Int32 nL2 (rS2.getLength());
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir     // Find all elements in rS1 and place them in rS1minusS2 or rS1andS2
150*cdf0e10cSrcweir     // depending on whether they are in rS2 or not.
151*cdf0e10cSrcweir     for (sal_Int32 i=0; i<nL1; ++i)
152*cdf0e10cSrcweir     {
153*cdf0e10cSrcweir         bool bFound (false);
154*cdf0e10cSrcweir         for (sal_Int32 j=0; j<nL2 && !bFound; ++j)
155*cdf0e10cSrcweir             if (aA1[i]->getResourceURL().equals(aA2[j]->getResourceURL()))
156*cdf0e10cSrcweir                 bFound = true;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir         if (bFound)
159*cdf0e10cSrcweir             rS1andS2.push_back(aA1[i]);
160*cdf0e10cSrcweir         else
161*cdf0e10cSrcweir             rS1minusS2.push_back(aA1[i]);
162*cdf0e10cSrcweir     }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir     // Find all elements in rS2 that are not in rS1.  The elements that are
165*cdf0e10cSrcweir     // in both rS1 and rS2 have been handled above and are therefore ignored
166*cdf0e10cSrcweir     // here.
167*cdf0e10cSrcweir     for (sal_Int32 j=0; j<nL2; ++j)
168*cdf0e10cSrcweir     {
169*cdf0e10cSrcweir         bool bFound (false);
170*cdf0e10cSrcweir         for (sal_Int32 i=0; i<nL1 && !bFound; ++i)
171*cdf0e10cSrcweir             if (aA2[j]->getResourceURL().equals(aA1[i]->getResourceURL()))
172*cdf0e10cSrcweir                 bFound = true;
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir         if ( ! bFound)
175*cdf0e10cSrcweir             rS2minusS1.push_back(aA2[j]);
176*cdf0e10cSrcweir     }
177*cdf0e10cSrcweir }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir void ConfigurationClassifier::CopyResources (
183*cdf0e10cSrcweir     const ResourceIdVector& rSource,
184*cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration,
185*cdf0e10cSrcweir     ResourceIdVector& rTarget)
186*cdf0e10cSrcweir {
187*cdf0e10cSrcweir     // Copy all resources bound to the ones in aC1minusC2Unique to rC1minusC2.
188*cdf0e10cSrcweir     ResourceIdVector::const_iterator iResource (rSource.begin());
189*cdf0e10cSrcweir     ResourceIdVector::const_iterator iEnd(rSource.end());
190*cdf0e10cSrcweir     for ( ; iResource!=iEnd; ++iResource)
191*cdf0e10cSrcweir     {
192*cdf0e10cSrcweir         const Sequence<Reference<XResourceId> > aBoundResources (
193*cdf0e10cSrcweir             rxConfiguration->getResources(
194*cdf0e10cSrcweir                 *iResource,
195*cdf0e10cSrcweir                 OUString(),
196*cdf0e10cSrcweir                 AnchorBindingMode_INDIRECT));
197*cdf0e10cSrcweir         const sal_Int32 nL (aBoundResources.getLength());
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir         rTarget.reserve(rTarget.size() + 1 + nL);
200*cdf0e10cSrcweir         rTarget.push_back(*iResource);
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir #if defined VERBOSE && VERBOSE >= 2
203*cdf0e10cSrcweir         OSL_TRACE("    copying %s\r",
204*cdf0e10cSrcweir             OUStringToOString(FrameworkHelper::ResourceIdToString(*iResource),
205*cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8).getStr());
206*cdf0e10cSrcweir #endif
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir         const Reference<XResourceId>* aA = aBoundResources.getConstArray();
209*cdf0e10cSrcweir         for (sal_Int32 i=0; i<nL; ++i)
210*cdf0e10cSrcweir         {
211*cdf0e10cSrcweir             rTarget.push_back(aA[i]);
212*cdf0e10cSrcweir #if defined VERBOSE && VERBOSE >= 2
213*cdf0e10cSrcweir             OSL_TRACE("    copying %s\r",
214*cdf0e10cSrcweir                 OUStringToOString(FrameworkHelper::ResourceIdToString(aA[i]),
215*cdf0e10cSrcweir                     RTL_TEXTENCODING_UTF8).getStr());
216*cdf0e10cSrcweir #endif
217*cdf0e10cSrcweir         }
218*cdf0e10cSrcweir     }
219*cdf0e10cSrcweir }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir void ConfigurationClassifier::TraceResourceIdVector (
223*cdf0e10cSrcweir     const sal_Char* pMessage,
224*cdf0e10cSrcweir     const ResourceIdVector& rResources) const
225*cdf0e10cSrcweir {
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir     OSL_TRACE(pMessage);
228*cdf0e10cSrcweir     ResourceIdVector::const_iterator iResource;
229*cdf0e10cSrcweir     for (iResource=rResources.begin(); iResource!=rResources.end(); ++iResource)
230*cdf0e10cSrcweir     {
231*cdf0e10cSrcweir         OUString sResource (FrameworkHelper::ResourceIdToString(*iResource));
232*cdf0e10cSrcweir         OSL_TRACE("    %s\r",
233*cdf0e10cSrcweir             OUStringToOString(sResource, RTL_TEXTENCODING_UTF8).getStr());
234*cdf0e10cSrcweir     }
235*cdf0e10cSrcweir }
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir } } // end of namespace sd::framework
239