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_sd.hxx"
30 
31 #include "MasterPageDescriptor.hxx"
32 
33 #include "DocumentHelper.hxx"
34 #include "sdpage.hxx"
35 #include <tools/urlobj.hxx>
36 
37 namespace sd { namespace toolpanel { namespace controls {
38 
39 
40 //===== MasterPageDescriptor ==================================================
41 
42 MasterPageDescriptor::MasterPageDescriptor (
43     MasterPageContainer::Origin eOrigin,
44     const sal_Int32 nTemplateIndex,
45     const String& rsURL,
46     const String& rsPageName,
47     const String& rsStyleName,
48     const bool bIsPrecious,
49     const ::boost::shared_ptr<PageObjectProvider>& rpPageObjectProvider,
50     const ::boost::shared_ptr<PreviewProvider>& rpPreviewProvider)
51     : maToken(MasterPageContainer::NIL_TOKEN),
52       meOrigin(eOrigin),
53       msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS)),
54       msPageName(rsPageName),
55       msStyleName(rsStyleName),
56       mbIsPrecious(bIsPrecious),
57       mpMasterPage(NULL),
58       mpSlide(NULL),
59       maSmallPreview(),
60       maLargePreview(),
61       mpPreviewProvider(rpPreviewProvider),
62       mpPageObjectProvider(rpPageObjectProvider),
63       mnTemplateIndex(nTemplateIndex),
64       meURLClassification(URLCLASS_UNDETERMINED),
65       mnUseCount(0)
66 {
67 }
68 
69 
70 
71 
72 MasterPageDescriptor::MasterPageDescriptor (const MasterPageDescriptor& rDescriptor)
73     : maToken(rDescriptor.maToken),
74       meOrigin(rDescriptor.meOrigin),
75       msURL(rDescriptor.msURL),
76       msPageName(rDescriptor.msPageName),
77       msStyleName(rDescriptor.msStyleName),
78       mbIsPrecious(rDescriptor.mbIsPrecious),
79       mpMasterPage(rDescriptor.mpMasterPage),
80       mpSlide(rDescriptor.mpSlide),
81       maSmallPreview(rDescriptor.maSmallPreview),
82       maLargePreview(rDescriptor.maLargePreview),
83       mpPreviewProvider(rDescriptor.mpPreviewProvider),
84       mpPageObjectProvider(rDescriptor.mpPageObjectProvider),
85       mnTemplateIndex(rDescriptor.mnTemplateIndex),
86       meURLClassification(rDescriptor.meURLClassification),
87       mnUseCount(rDescriptor.mnUseCount)
88 {
89 }
90 
91 
92 
93 
94 MasterPageDescriptor::~MasterPageDescriptor (void)
95 {
96 }
97 
98 
99 
100 
101 void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken)
102 {
103     maToken = aToken;
104 }
105 
106 
107 
108 
109 Image MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize)
110 {
111     if (eSize == MasterPageContainer::SMALL)
112         return maSmallPreview;
113     else
114         return maLargePreview;
115 }
116 
117 
118 
119 
120 ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
121     MasterPageDescriptor::Update (
122         const MasterPageDescriptor& rDescriptor)
123 {
124     bool bDataChanged (false);
125     bool bIndexChanged (false);
126     bool bPreviewChanged (false);
127 
128     if (meOrigin==MasterPageContainer::UNKNOWN
129         && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN)
130     {
131         meOrigin = rDescriptor.meOrigin;
132         bIndexChanged = true;
133     }
134 
135     if (msURL.getLength()==0 && rDescriptor.msURL.getLength()!=0)
136     {
137         msURL = rDescriptor.msURL;
138         bDataChanged = true;
139     }
140 
141     if (msPageName.getLength()==0 && rDescriptor.msPageName.getLength()!=0)
142     {
143         msPageName = rDescriptor.msPageName;
144         bDataChanged = true;
145     }
146 
147     if (msStyleName.getLength()==0 && rDescriptor.msStyleName.getLength()!=0)
148     {
149         msStyleName = rDescriptor.msStyleName;
150         bDataChanged = true;
151     }
152 
153     if (mpPageObjectProvider.get()==NULL && rDescriptor.mpPageObjectProvider.get()!=NULL)
154     {
155         mpPageObjectProvider = rDescriptor.mpPageObjectProvider;
156         bDataChanged = true;
157     }
158 
159      if (mpPreviewProvider.get()==NULL && rDescriptor.mpPreviewProvider.get()!=NULL)
160      {
161          mpPreviewProvider = rDescriptor.mpPreviewProvider;
162          bPreviewChanged = true;
163      }
164 
165      if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0)
166      {
167          mnTemplateIndex = rDescriptor.mnTemplateIndex;
168          bIndexChanged = true;
169      }
170 
171      // Prepare the list of event types that will be returned.
172      ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult;
173      if (bDataChanged || bIndexChanged || bPreviewChanged)
174      {
175          pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>());
176          if (bDataChanged)
177              pResult->push_back(MasterPageContainerChangeEvent::DATA_CHANGED);
178          if (bIndexChanged)
179              pResult->push_back(MasterPageContainerChangeEvent::INDEX_CHANGED);
180          if (bPreviewChanged)
181              pResult->push_back(MasterPageContainerChangeEvent::PREVIEW_CHANGED);
182      }
183 
184      return pResult;
185 }
186 
187 
188 
189 
190 bool MasterPageDescriptor::UpdatePageObject (
191     sal_Int32 nCostThreshold,
192     SdDrawDocument* pDocument)
193 {
194     bool bModified (false);
195 
196     // Update the page object when that is not yet known.
197     if (mpMasterPage == NULL
198         && mpPageObjectProvider.get()!=NULL
199         && (nCostThreshold<0 || mpPageObjectProvider->GetCostIndex()<=nCostThreshold))
200     {
201         // Note that pDocument may be NULL.
202 
203         SdPage* pPage = (*mpPageObjectProvider)(pDocument);
204         if (meOrigin == MasterPageContainer::MASTERPAGE)
205         {
206             mpMasterPage = pPage;
207             if (mpMasterPage != NULL)
208                 mpMasterPage->SetPrecious(mbIsPrecious);
209         }
210         else
211         {
212             // Master pages from templates are copied into the local document.
213             if (pDocument != NULL)
214                 mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage);
215             mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage);
216         }
217 
218         if (mpMasterPage != NULL)
219         {
220             // Update page name and style name.
221             if (msPageName.getLength() == 0)
222                 msPageName = mpMasterPage->GetName();
223             msStyleName = mpMasterPage->GetName();
224 
225             // Delete an existing substitution. The next request for a preview
226             // will create the real one.
227             maSmallPreview = Image();
228             maLargePreview = Image();
229             mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(new PagePreviewProvider());
230         }
231         else
232         {
233             DBG_ASSERT(false, "UpdatePageObject: master page is NULL");
234         }
235 
236         bModified = true;
237     }
238 
239     return bModified;
240 }
241 
242 
243 
244 
245 bool MasterPageDescriptor::UpdatePreview (
246     sal_Int32 nCostThreshold,
247     const Size& rSmallSize,
248     const Size& rLargeSize,
249     ::sd::PreviewRenderer& rRenderer)
250 {
251     bool bModified (false);
252 
253     // Update the preview when that is not yet known.
254     if (maLargePreview.GetSizePixel().Width()==0
255         && mpPreviewProvider.get()!=NULL
256         && (nCostThreshold<0 || mpPreviewProvider->GetCostIndex()<=nCostThreshold))
257     {
258         SdPage* pPage = mpSlide;
259         if (pPage == NULL)
260         {
261             pPage = mpMasterPage;
262         }
263         maLargePreview = (*mpPreviewProvider)(
264             rLargeSize.Width(),
265             pPage,
266             rRenderer);
267         if (maLargePreview.GetSizePixel().Width() > 0)
268         {
269             // Create the small preview by scaling the large one down.
270             maSmallPreview = rRenderer.ScaleBitmap(
271                 maLargePreview.GetBitmapEx(),
272                 rSmallSize.Width());
273             // The large preview may not have the desired width.  Scale it
274             // accrodingly.
275             if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width())
276                 maLargePreview = rRenderer.ScaleBitmap(
277                     maLargePreview.GetBitmapEx(),
278                     rLargeSize.Width());
279             bModified = true;
280         }
281     }
282 
283     return bModified;
284 }
285 
286 
287 
288 
289 MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification (void)
290 {
291     if (meURLClassification == URLCLASS_UNDETERMINED)
292     {
293         if (msURL.getLength() == 0)
294             meURLClassification = URLCLASS_UNKNOWN;
295         else if (msURL.indexOf(::rtl::OUString::createFromAscii("presnt"))>=0)
296         {
297             meURLClassification = URLCLASS_PRESENTATION;
298         }
299         else if (msURL.indexOf(::rtl::OUString::createFromAscii("layout"))>=0)
300         {
301             meURLClassification = URLCLASS_LAYOUT;
302         }
303         else if (msURL.indexOf(::rtl::OUString::createFromAscii("educate"))>=0)
304         {
305             meURLClassification = URLCLASS_OTHER;
306         }
307         else
308         {
309             meURLClassification = URLCLASS_USER;
310         }
311     }
312 
313     return meURLClassification;
314 }
315 
316 
317 
318 //===== URLComparator =========================================================
319 
320 MasterPageDescriptor::URLComparator::URLComparator (const ::rtl::OUString& sURL)
321     : msURL(sURL)
322 {
323 }
324 
325 
326 
327 
328 bool MasterPageDescriptor::URLComparator::operator() (
329     const SharedMasterPageDescriptor& rDescriptor)
330 {
331     if (rDescriptor.get() == NULL)
332         return false;
333     else
334         return rDescriptor->msURL.equals(msURL);
335 }
336 
337 
338 
339 
340 // ===== StyleNameComparator ==================================================
341 
342 MasterPageDescriptor::StyleNameComparator::StyleNameComparator (const ::rtl::OUString& sStyleName)
343     : msStyleName(sStyleName)
344 {
345 }
346 
347 
348 
349 
350 bool MasterPageDescriptor::StyleNameComparator::operator() (
351     const SharedMasterPageDescriptor& rDescriptor)
352 {
353     if (rDescriptor.get() == NULL)
354         return false;
355     else
356         return rDescriptor->msStyleName.equals(msStyleName);
357 }
358 
359 
360 
361 
362 //===== PageObjectComparator ==================================================
363 
364 MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject)
365     : mpMasterPage(pPageObject)
366 {
367 }
368 
369 
370 
371 
372 bool MasterPageDescriptor::PageObjectComparator::operator() (
373     const SharedMasterPageDescriptor& rDescriptor)
374 {
375     if (rDescriptor.get() == NULL)
376         return false;
377     else
378         return rDescriptor->mpMasterPage==mpMasterPage;
379 }
380 
381 
382 
383 
384 //===== AllComparator =========================================================
385 
386 MasterPageDescriptor::AllComparator::AllComparator(const SharedMasterPageDescriptor& rDescriptor)
387     : mpDescriptor(rDescriptor)
388 {
389 }
390 
391 
392 
393 
394 bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor)
395 {
396     if (rDescriptor.get() == NULL)
397         return false;
398     else
399     {
400         // Take URL, page name, style name, and page object into account
401         // when comparing two descriptors.  When two descriptors are
402         // identical in any of these values then their are thought of as
403         // equivalent.  Only the Origin has to be the same in both
404         // descriptors.
405         return
406             mpDescriptor->meOrigin == rDescriptor->meOrigin
407             && (
408                 (mpDescriptor->msURL.getLength()>0
409                     && mpDescriptor->msURL.equals(rDescriptor->msURL))
410                 || (mpDescriptor->msPageName.getLength()>0
411                     && mpDescriptor->msPageName.equals(rDescriptor->msPageName))
412                 || (mpDescriptor->msStyleName.getLength()>0
413                     && mpDescriptor->msStyleName.equals(rDescriptor->msStyleName))
414                 || (mpDescriptor->mpMasterPage!=NULL
415                     && mpDescriptor->mpMasterPage==rDescriptor->mpMasterPage)
416                 || (mpDescriptor->mpPageObjectProvider.get()!=NULL
417                     && rDescriptor->mpPageObjectProvider.get()!=NULL
418                     && mpDescriptor->mpPageObjectProvider==rDescriptor->mpPageObjectProvider));
419     }
420 }
421 
422 
423 } } } // end of namespace ::sd::toolpanel::controls
424