1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "precompiled_sd.hxx" 25 26 #include "ConfigurationClassifier.hxx" 27 28 #include "framework/FrameworkHelper.hxx" 29 30 using namespace ::com::sun::star; 31 using namespace ::com::sun::star::uno; 32 using namespace ::com::sun::star::drawing::framework; 33 using ::rtl::OUString; 34 35 #undef VERBOSE 36 //#define VERBOSE 2 37 38 39 namespace sd { namespace framework { 40 41 ConfigurationClassifier::ConfigurationClassifier ( 42 const Reference<XConfiguration>& rxConfiguration1, 43 const Reference<XConfiguration>& rxConfiguration2) 44 : mxConfiguration1(rxConfiguration1), 45 mxConfiguration2(rxConfiguration2), 46 maC1minusC2(), 47 maC2minusC1(), 48 maC1andC2() 49 { 50 } 51 52 53 54 55 bool ConfigurationClassifier::Partition (void) 56 { 57 maC1minusC2.clear(); 58 maC2minusC1.clear(); 59 maC1andC2.clear(); 60 61 PartitionResources( 62 mxConfiguration1->getResources(NULL, OUString(), AnchorBindingMode_DIRECT), 63 mxConfiguration2->getResources(NULL, OUString(), AnchorBindingMode_DIRECT)); 64 65 return !maC1minusC2.empty() || !maC2minusC1.empty(); 66 } 67 68 69 70 71 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1minusC2 (void) const 72 { 73 return maC1minusC2; 74 } 75 76 77 78 79 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC2minusC1 (void) const 80 { 81 return maC2minusC1; 82 } 83 84 85 86 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1andC2 (void) const 87 { 88 return maC1andC2; 89 } 90 91 92 void ConfigurationClassifier::PartitionResources ( 93 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1, 94 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2) 95 { 96 ResourceIdVector aC1minusC2; 97 ResourceIdVector aC2minusC1; 98 ResourceIdVector aC1andC2; 99 100 // Classify the resources in the configurations that are not bound to 101 // other resources. 102 ClassifyResources( 103 rS1, 104 rS2, 105 aC1minusC2, 106 aC2minusC1, 107 aC1andC2); 108 109 #if defined VERBOSE && VERBOSE >= 2 110 OSL_TRACE("copying resource ids to C1-C2\r"); 111 #endif 112 CopyResources(aC1minusC2, mxConfiguration1, maC1minusC2); 113 #if defined VERBOSE && VERBOSE >= 2 114 OSL_TRACE("copying resource ids to C2-C1\r"); 115 #endif 116 CopyResources(aC2minusC1, mxConfiguration2, maC2minusC1); 117 118 // Process the unique resources that belong to both configurations. 119 ResourceIdVector::const_iterator iResource; 120 for (iResource=aC1andC2.begin(); iResource!=aC1andC2.end(); ++iResource) 121 { 122 maC1andC2.push_back(*iResource); 123 PartitionResources( 124 mxConfiguration1->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT), 125 mxConfiguration2->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT)); 126 } 127 } 128 129 130 131 132 void ConfigurationClassifier::ClassifyResources ( 133 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1, 134 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2, 135 ResourceIdVector& rS1minusS2, 136 ResourceIdVector& rS2minusS1, 137 ResourceIdVector& rS1andS2) 138 { 139 // Get arrays from the sequences for faster iteration. 140 const Reference<XResourceId>* aA1 = rS1.getConstArray(); 141 const Reference<XResourceId>* aA2 = rS2.getConstArray(); 142 sal_Int32 nL1 (rS1.getLength()); 143 sal_Int32 nL2 (rS2.getLength()); 144 145 // Find all elements in rS1 and place them in rS1minusS2 or rS1andS2 146 // depending on whether they are in rS2 or not. 147 for (sal_Int32 i=0; i<nL1; ++i) 148 { 149 bool bFound (false); 150 for (sal_Int32 j=0; j<nL2 && !bFound; ++j) 151 if (aA1[i]->getResourceURL().equals(aA2[j]->getResourceURL())) 152 bFound = true; 153 154 if (bFound) 155 rS1andS2.push_back(aA1[i]); 156 else 157 rS1minusS2.push_back(aA1[i]); 158 } 159 160 // Find all elements in rS2 that are not in rS1. The elements that are 161 // in both rS1 and rS2 have been handled above and are therefore ignored 162 // here. 163 for (sal_Int32 j=0; j<nL2; ++j) 164 { 165 bool bFound (false); 166 for (sal_Int32 i=0; i<nL1 && !bFound; ++i) 167 if (aA2[j]->getResourceURL().equals(aA1[i]->getResourceURL())) 168 bFound = true; 169 170 if ( ! bFound) 171 rS2minusS1.push_back(aA2[j]); 172 } 173 } 174 175 176 177 178 void ConfigurationClassifier::CopyResources ( 179 const ResourceIdVector& rSource, 180 const Reference<XConfiguration>& rxConfiguration, 181 ResourceIdVector& rTarget) 182 { 183 // Copy all resources bound to the ones in aC1minusC2Unique to rC1minusC2. 184 ResourceIdVector::const_iterator iResource (rSource.begin()); 185 ResourceIdVector::const_iterator iEnd(rSource.end()); 186 for ( ; iResource!=iEnd; ++iResource) 187 { 188 const Sequence<Reference<XResourceId> > aBoundResources ( 189 rxConfiguration->getResources( 190 *iResource, 191 OUString(), 192 AnchorBindingMode_INDIRECT)); 193 const sal_Int32 nL (aBoundResources.getLength()); 194 195 rTarget.reserve(rTarget.size() + 1 + nL); 196 rTarget.push_back(*iResource); 197 198 #if defined VERBOSE && VERBOSE >= 2 199 OSL_TRACE(" copying %s\r", 200 OUStringToOString(FrameworkHelper::ResourceIdToString(*iResource), 201 RTL_TEXTENCODING_UTF8).getStr()); 202 #endif 203 204 const Reference<XResourceId>* aA = aBoundResources.getConstArray(); 205 for (sal_Int32 i=0; i<nL; ++i) 206 { 207 rTarget.push_back(aA[i]); 208 #if defined VERBOSE && VERBOSE >= 2 209 OSL_TRACE(" copying %s\r", 210 OUStringToOString(FrameworkHelper::ResourceIdToString(aA[i]), 211 RTL_TEXTENCODING_UTF8).getStr()); 212 #endif 213 } 214 } 215 } 216 217 218 void ConfigurationClassifier::TraceResourceIdVector ( 219 const sal_Char* pMessage, 220 const ResourceIdVector& rResources) const 221 { 222 223 OSL_TRACE(pMessage); 224 ResourceIdVector::const_iterator iResource; 225 for (iResource=rResources.begin(); iResource!=rResources.end(); ++iResource) 226 { 227 OUString sResource (FrameworkHelper::ResourceIdToString(*iResource)); 228 OSL_TRACE(" %s\r", 229 OUStringToOString(sResource, RTL_TEXTENCODING_UTF8).getStr()); 230 } 231 } 232 233 234 } } // end of namespace sd::framework 235