bump product version to 5.0.4.1
[LibreOffice.git] / sfx2 / source / control / templateabstractview.cxx
blob11b985dd5e157e3c39bb68cab0cae433fd5122b1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sfx2/templateabstractview.hxx>
12 #include <comphelper/processfactory.hxx>
13 #include <sfx2/sfxresid.hxx>
14 #include <sfx2/templatecontaineritem.hxx>
15 #include <sfx2/templateviewitem.hxx>
16 #include <tools/urlobj.hxx>
17 #include <unotools/ucbstreamhelper.hxx>
18 #include <vcl/pngread.hxx>
20 #include <basegfx/polygon/b2dpolygon.hxx>
21 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
22 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
23 #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
25 #include <com/sun/star/embed/ElementModes.hpp>
26 #include <com/sun/star/embed/XStorage.hpp>
27 #include <com/sun/star/embed/StorageFactory.hpp>
28 #include <com/sun/star/lang/XComponent.hpp>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
32 #include "../doc/doc.hrc"
33 #include "templateview.hrc"
35 using namespace basegfx;
36 using namespace drawinglayer::primitive2d;
38 bool ViewFilter_Application::isFilteredExtension(FILTER_APPLICATION filter, const OUString &rExt)
40 bool bRet = true;
42 if (filter == FILTER_APPLICATION::WRITER)
44 bRet = rExt == "ott" || rExt == "stw" || rExt == "oth" || rExt == "dot" || rExt == "dotx" || rExt == "otm";
46 else if (filter == FILTER_APPLICATION::CALC)
48 bRet = rExt == "ots" || rExt == "stc" || rExt == "xlt" || rExt == "xltm" || rExt == "xltx";
50 else if (filter == FILTER_APPLICATION::IMPRESS)
52 bRet = rExt == "otp" || rExt == "sti" || rExt == "pot" || rExt == "potm" || rExt == "potx";
54 else if (filter == FILTER_APPLICATION::DRAW)
56 bRet = rExt == "otg" || rExt == "std";
59 return bRet;
62 bool ViewFilter_Application::isValid (const OUString &rPath) const
64 INetURLObject aUrl(rPath);
65 return isFilteredExtension(mApp, aUrl.getExtension());
68 bool ViewFilter_Application::operator () (const ThumbnailViewItem *pItem)
70 const TemplateViewItem *pTempItem = dynamic_cast<const TemplateViewItem*>(pItem);
71 if (pTempItem)
72 return isValid(pTempItem->getPath());
74 TemplateContainerItem *pContainerItem = const_cast<TemplateContainerItem*>(dynamic_cast<const TemplateContainerItem*>(pItem));
75 if (pContainerItem)
77 std::vector<TemplateItemProperties> &rTemplates = pContainerItem->maTemplates;
79 size_t nVisCount = 0;
81 // Clear thumbnails
82 pContainerItem->maPreview1.Clear();
83 pContainerItem->maPreview2.Clear();
84 pContainerItem->maPreview3.Clear();
85 pContainerItem->maPreview4.Clear();
87 for (size_t i = 0, n = rTemplates.size(); i < n && pContainerItem->HasMissingPreview(); ++i)
89 if (isValid(rTemplates[i].aPath))
91 ++nVisCount;
92 if ( pContainerItem->maPreview1.IsEmpty( ) )
94 pContainerItem->maPreview1 = TemplateAbstractView::scaleImg(rTemplates[i].aThumbnail,
95 TEMPLATE_THUMBNAIL_MAX_WIDTH*0.75,
96 TEMPLATE_THUMBNAIL_MAX_HEIGHT*0.75);
98 else if ( pContainerItem->maPreview2.IsEmpty() )
100 pContainerItem->maPreview2 = TemplateAbstractView::scaleImg(rTemplates[i].aThumbnail,
101 TEMPLATE_THUMBNAIL_MAX_WIDTH*0.75,
102 TEMPLATE_THUMBNAIL_MAX_HEIGHT*0.75);
104 else if ( pContainerItem->maPreview3.IsEmpty() )
106 pContainerItem->maPreview3 = TemplateAbstractView::scaleImg(rTemplates[i].aThumbnail,
107 TEMPLATE_THUMBNAIL_MAX_WIDTH*0.75,
108 TEMPLATE_THUMBNAIL_MAX_HEIGHT*0.75);
110 else if ( pContainerItem->maPreview4.IsEmpty() )
112 pContainerItem->maPreview4 = TemplateAbstractView::scaleImg(rTemplates[i].aThumbnail,
113 TEMPLATE_THUMBNAIL_MAX_WIDTH*0.75,
114 TEMPLATE_THUMBNAIL_MAX_HEIGHT*0.75);
119 return true;
122 bool ViewFilter_Keyword::operator ()(const ThumbnailViewItem *pItem)
124 assert(pItem);
126 return pItem->maTitle.matchIgnoreAsciiCase(maKeyword);
129 TemplateAbstractView::TemplateAbstractView (vcl::Window *pParent, WinBits nWinStyle, bool bDisableTransientChildren)
130 : ThumbnailView(pParent,nWinStyle,bDisableTransientChildren),
131 mnCurRegionId(0),
132 maAllButton(VclPtr<PushButton>::Create(this, SfxResId(BTN_ALL_TEMPLATES))),
133 maFTName(VclPtr<FixedText>::Create(this, SfxResId(FT_NAME)))
135 maAllButton->Hide();
136 maAllButton->SetStyle(maAllButton->GetStyle() | WB_FLATBUTTON);
137 maAllButton->SetClickHdl(LINK(this,TemplateAbstractView,ShowRootRegionHdl));
138 maFTName->Hide();
141 TemplateAbstractView::TemplateAbstractView(vcl::Window *pParent)
142 : ThumbnailView(pParent),
143 mnCurRegionId(0),
144 maAllButton(VclPtr<PushButton>::Create(this, SfxResId(BTN_ALL_TEMPLATES))),
145 maFTName(VclPtr<FixedText>::Create(this, SfxResId(FT_NAME)))
147 maAllButton->Hide();
148 maAllButton->SetStyle(maAllButton->GetStyle() | WB_FLATBUTTON);
149 maAllButton->SetClickHdl(LINK(this,TemplateAbstractView,ShowRootRegionHdl));
150 maFTName->Hide();
153 TemplateAbstractView::~TemplateAbstractView()
155 disposeOnce();
158 void TemplateAbstractView::dispose()
160 maAllButton.disposeAndClear();
161 maFTName.disposeAndClear();
162 ThumbnailView::dispose();
165 void TemplateAbstractView::insertItem(const TemplateItemProperties &rTemplate)
167 const TemplateItemProperties *pCur = &rTemplate;
169 TemplateViewItem *pChild = new TemplateViewItem(*this, pCur->nId);
170 pChild->mnDocId = pCur->nDocId;
171 pChild->mnRegionId = pCur->nRegionId;
172 pChild->maTitle = pCur->aName;
173 pChild->setPath(pCur->aPath);
174 pChild->maPreview1 = pCur->aThumbnail;
176 if ( pCur->aThumbnail.IsEmpty() )
178 // Use the default thumbnail if we have nothing else
179 pChild->maPreview1 = TemplateAbstractView::getDefaultThumbnail(pCur->aPath);
182 pChild->setSelectClickHdl(LINK(this,ThumbnailView,OnItemSelected));
184 AppendItem(pChild);
186 CalculateItemPositions();
187 Invalidate();
190 void TemplateAbstractView::insertItems(const std::vector<TemplateItemProperties> &rTemplates)
192 std::vector<ThumbnailViewItem*> aItems(rTemplates.size());
193 for (size_t i = 0, n = rTemplates.size(); i < n; ++i )
195 //TODO: CHECK IF THE ITEM IS A FOLDER OR NOT
196 const TemplateItemProperties *pCur = &rTemplates[i];
198 TemplateViewItem *pChild = new TemplateViewItem(*this, pCur->nId);
199 pChild->mnDocId = pCur->nDocId;
200 pChild->mnRegionId = pCur->nRegionId;
201 pChild->maTitle = pCur->aName;
202 pChild->setPath(pCur->aPath);
203 pChild->maPreview1 = pCur->aThumbnail;
205 if ( pCur->aThumbnail.IsEmpty() )
207 // Use the default thumbnail if we have nothing else
208 pChild->maPreview1 = TemplateAbstractView::getDefaultThumbnail(pCur->aPath);
211 pChild->setSelectClickHdl(LINK(this,ThumbnailView,OnItemSelected));
213 aItems[i] = pChild;
216 updateItems(aItems);
222 void TemplateAbstractView::setOpenRegionHdl(const Link<> &rLink)
224 maOpenRegionHdl = rLink;
227 void TemplateAbstractView::setOpenTemplateHdl(const Link<> &rLink)
229 maOpenTemplateHdl = rLink;
232 BitmapEx TemplateAbstractView::scaleImg (const BitmapEx &rImg, long width, long height)
234 BitmapEx aImg = rImg;
236 if (!rImg.IsEmpty())
238 Size aSize = rImg.GetSizePixel();
240 if (aSize.Width() == 0)
241 aSize.Width() = 1;
243 if (aSize.Height() == 0)
244 aSize.Height() = 1;
246 // make the picture fit the given width/height constraints
247 double nRatio = std::min(double(width)/double(aSize.Width()), double(height)/double(aSize.Height()));
249 aImg.Scale(Size(aSize.Width() * nRatio, aSize.Height() * nRatio));
252 return aImg;
255 BitmapEx TemplateAbstractView::getDefaultThumbnail( const OUString& rPath )
257 BitmapEx aImg;
258 INetURLObject aUrl(rPath);
259 OUString aExt = aUrl.getExtension();
261 if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::WRITER, aExt) )
262 aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_TEXT ) );
263 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::CALC, aExt) )
264 aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_SHEET ) );
265 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::IMPRESS, aExt) )
266 aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_PRESENTATION ) );
267 else if ( ViewFilter_Application::isFilteredExtension( FILTER_APPLICATION::DRAW, aExt) )
268 aImg = BitmapEx ( SfxResId( SFX_THUMBNAIL_DRAWING ) );
270 return aImg;
273 BitmapEx TemplateAbstractView::fetchThumbnail (const OUString &msURL, long width, long height)
275 return TemplateAbstractView::scaleImg(ThumbnailView::readThumbnail(msURL), width, height);
278 IMPL_LINK_NOARG(TemplateAbstractView, ShowRootRegionHdl)
280 showRootRegion();
281 return 0;
284 void TemplateAbstractView::OnItemDblClicked (ThumbnailViewItem *pItem)
286 //Check if the item is a TemplateContainerItem (Folder) or a TemplateViewItem (File)
288 TemplateContainerItem* pContainerItem = dynamic_cast<TemplateContainerItem*>(pItem);
289 if ( pContainerItem )
291 // Fill templates
293 mnCurRegionId = pContainerItem->mnRegionId+1;
294 maCurRegionName = pContainerItem->maTitle;
295 maFTName->SetText(maCurRegionName);
296 showRegion(pItem);
298 else
300 maOpenTemplateHdl.Call(pItem);
304 void TemplateAbstractView::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
306 ThumbnailView::Paint(rRenderContext, rRect);
308 Rectangle aRect(rRect.TopLeft(),
309 Point(rRect.BottomRight().X(),
310 mnHeaderHeight));
312 drawinglayer::primitive2d::Primitive2DSequence aSeq(1);
313 aSeq[0] = drawinglayer::primitive2d::Primitive2DReference(
314 new PolyPolygonColorPrimitive2D(B2DPolyPolygon(Polygon(aRect).getB2DPolygon()),
315 maFillColor.getBColor()));
317 const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
318 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> mpProcessor(
319 drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(rRenderContext, aNewViewInfos));
321 mpProcessor->process(aSeq);
324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */