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 #include "precompiled_sd.hxx" 29 30 #include "ConfigurationClassifier.hxx" 31 32 #include "framework/FrameworkHelper.hxx" 33 34 using namespace ::com::sun::star; 35 using namespace ::com::sun::star::uno; 36 using namespace ::com::sun::star::drawing::framework; 37 using ::rtl::OUString; 38 39 #undef VERBOSE 40 //#define VERBOSE 2 41 42 43 namespace sd { namespace framework { 44 45 ConfigurationClassifier::ConfigurationClassifier ( 46 const Reference<XConfiguration>& rxConfiguration1, 47 const Reference<XConfiguration>& rxConfiguration2) 48 : mxConfiguration1(rxConfiguration1), 49 mxConfiguration2(rxConfiguration2), 50 maC1minusC2(), 51 maC2minusC1(), 52 maC1andC2() 53 { 54 } 55 56 57 58 59 bool ConfigurationClassifier::Partition (void) 60 { 61 maC1minusC2.clear(); 62 maC2minusC1.clear(); 63 maC1andC2.clear(); 64 65 PartitionResources( 66 mxConfiguration1->getResources(NULL, OUString(), AnchorBindingMode_DIRECT), 67 mxConfiguration2->getResources(NULL, OUString(), AnchorBindingMode_DIRECT)); 68 69 return !maC1minusC2.empty() || !maC2minusC1.empty(); 70 } 71 72 73 74 75 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1minusC2 (void) const 76 { 77 return maC1minusC2; 78 } 79 80 81 82 83 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC2minusC1 (void) const 84 { 85 return maC2minusC1; 86 } 87 88 89 90 const ConfigurationClassifier::ResourceIdVector& ConfigurationClassifier::GetC1andC2 (void) const 91 { 92 return maC1andC2; 93 } 94 95 96 void ConfigurationClassifier::PartitionResources ( 97 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1, 98 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2) 99 { 100 ResourceIdVector aC1minusC2; 101 ResourceIdVector aC2minusC1; 102 ResourceIdVector aC1andC2; 103 104 // Classify the resources in the configurations that are not bound to 105 // other resources. 106 ClassifyResources( 107 rS1, 108 rS2, 109 aC1minusC2, 110 aC2minusC1, 111 aC1andC2); 112 113 #if defined VERBOSE && VERBOSE >= 2 114 OSL_TRACE("copying resource ids to C1-C2\r"); 115 #endif 116 CopyResources(aC1minusC2, mxConfiguration1, maC1minusC2); 117 #if defined VERBOSE && VERBOSE >= 2 118 OSL_TRACE("copying resource ids to C2-C1\r"); 119 #endif 120 CopyResources(aC2minusC1, mxConfiguration2, maC2minusC1); 121 122 // Process the unique resources that belong to both configurations. 123 ResourceIdVector::const_iterator iResource; 124 for (iResource=aC1andC2.begin(); iResource!=aC1andC2.end(); ++iResource) 125 { 126 maC1andC2.push_back(*iResource); 127 PartitionResources( 128 mxConfiguration1->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT), 129 mxConfiguration2->getResources(*iResource, OUString(), AnchorBindingMode_DIRECT)); 130 } 131 } 132 133 134 135 136 void ConfigurationClassifier::ClassifyResources ( 137 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS1, 138 const ::com::sun::star::uno::Sequence<Reference<XResourceId> >& rS2, 139 ResourceIdVector& rS1minusS2, 140 ResourceIdVector& rS2minusS1, 141 ResourceIdVector& rS1andS2) 142 { 143 // Get arrays from the sequences for faster iteration. 144 const Reference<XResourceId>* aA1 = rS1.getConstArray(); 145 const Reference<XResourceId>* aA2 = rS2.getConstArray(); 146 sal_Int32 nL1 (rS1.getLength()); 147 sal_Int32 nL2 (rS2.getLength()); 148 149 // Find all elements in rS1 and place them in rS1minusS2 or rS1andS2 150 // depending on whether they are in rS2 or not. 151 for (sal_Int32 i=0; i<nL1; ++i) 152 { 153 bool bFound (false); 154 for (sal_Int32 j=0; j<nL2 && !bFound; ++j) 155 if (aA1[i]->getResourceURL().equals(aA2[j]->getResourceURL())) 156 bFound = true; 157 158 if (bFound) 159 rS1andS2.push_back(aA1[i]); 160 else 161 rS1minusS2.push_back(aA1[i]); 162 } 163 164 // Find all elements in rS2 that are not in rS1. The elements that are 165 // in both rS1 and rS2 have been handled above and are therefore ignored 166 // here. 167 for (sal_Int32 j=0; j<nL2; ++j) 168 { 169 bool bFound (false); 170 for (sal_Int32 i=0; i<nL1 && !bFound; ++i) 171 if (aA2[j]->getResourceURL().equals(aA1[i]->getResourceURL())) 172 bFound = true; 173 174 if ( ! bFound) 175 rS2minusS1.push_back(aA2[j]); 176 } 177 } 178 179 180 181 182 void ConfigurationClassifier::CopyResources ( 183 const ResourceIdVector& rSource, 184 const Reference<XConfiguration>& rxConfiguration, 185 ResourceIdVector& rTarget) 186 { 187 // Copy all resources bound to the ones in aC1minusC2Unique to rC1minusC2. 188 ResourceIdVector::const_iterator iResource (rSource.begin()); 189 ResourceIdVector::const_iterator iEnd(rSource.end()); 190 for ( ; iResource!=iEnd; ++iResource) 191 { 192 const Sequence<Reference<XResourceId> > aBoundResources ( 193 rxConfiguration->getResources( 194 *iResource, 195 OUString(), 196 AnchorBindingMode_INDIRECT)); 197 const sal_Int32 nL (aBoundResources.getLength()); 198 199 rTarget.reserve(rTarget.size() + 1 + nL); 200 rTarget.push_back(*iResource); 201 202 #if defined VERBOSE && VERBOSE >= 2 203 OSL_TRACE(" copying %s\r", 204 OUStringToOString(FrameworkHelper::ResourceIdToString(*iResource), 205 RTL_TEXTENCODING_UTF8).getStr()); 206 #endif 207 208 const Reference<XResourceId>* aA = aBoundResources.getConstArray(); 209 for (sal_Int32 i=0; i<nL; ++i) 210 { 211 rTarget.push_back(aA[i]); 212 #if defined VERBOSE && VERBOSE >= 2 213 OSL_TRACE(" copying %s\r", 214 OUStringToOString(FrameworkHelper::ResourceIdToString(aA[i]), 215 RTL_TEXTENCODING_UTF8).getStr()); 216 #endif 217 } 218 } 219 } 220 221 222 void ConfigurationClassifier::TraceResourceIdVector ( 223 const sal_Char* pMessage, 224 const ResourceIdVector& rResources) const 225 { 226 227 OSL_TRACE(pMessage); 228 ResourceIdVector::const_iterator iResource; 229 for (iResource=rResources.begin(); iResource!=rResources.end(); ++iResource) 230 { 231 OUString sResource (FrameworkHelper::ResourceIdToString(*iResource)); 232 OSL_TRACE(" %s\r", 233 OUStringToOString(sResource, RTL_TEXTENCODING_UTF8).getStr()); 234 } 235 } 236 237 238 } } // end of namespace sd::framework 239