1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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
)
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";
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
);
72 return isValid(pTempItem
->getPath());
74 TemplateContainerItem
*pContainerItem
= const_cast<TemplateContainerItem
*>(dynamic_cast<const TemplateContainerItem
*>(pItem
));
77 std::vector
<TemplateItemProperties
> &rTemplates
= pContainerItem
->maTemplates
;
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
))
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);
122 bool ViewFilter_Keyword::operator ()(const ThumbnailViewItem
*pItem
)
126 return pItem
->maTitle
.matchIgnoreAsciiCase(maKeyword
);
129 TemplateAbstractView::TemplateAbstractView (vcl::Window
*pParent
, WinBits nWinStyle
, bool bDisableTransientChildren
)
130 : ThumbnailView(pParent
,nWinStyle
,bDisableTransientChildren
),
132 maAllButton(VclPtr
<PushButton
>::Create(this, SfxResId(BTN_ALL_TEMPLATES
))),
133 maFTName(VclPtr
<FixedText
>::Create(this, SfxResId(FT_NAME
)))
136 maAllButton
->SetStyle(maAllButton
->GetStyle() | WB_FLATBUTTON
);
137 maAllButton
->SetClickHdl(LINK(this,TemplateAbstractView
,ShowRootRegionHdl
));
141 TemplateAbstractView::TemplateAbstractView(vcl::Window
*pParent
)
142 : ThumbnailView(pParent
),
144 maAllButton(VclPtr
<PushButton
>::Create(this, SfxResId(BTN_ALL_TEMPLATES
))),
145 maFTName(VclPtr
<FixedText
>::Create(this, SfxResId(FT_NAME
)))
148 maAllButton
->SetStyle(maAllButton
->GetStyle() | WB_FLATBUTTON
);
149 maAllButton
->SetClickHdl(LINK(this,TemplateAbstractView
,ShowRootRegionHdl
));
153 TemplateAbstractView::~TemplateAbstractView()
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
));
186 CalculateItemPositions();
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
));
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
;
238 Size aSize
= rImg
.GetSizePixel();
240 if (aSize
.Width() == 0)
243 if (aSize
.Height() == 0)
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
));
255 BitmapEx
TemplateAbstractView::getDefaultThumbnail( const OUString
& rPath
)
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
) );
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
)
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
)
293 mnCurRegionId
= pContainerItem
->mnRegionId
+1;
294 maCurRegionName
= pContainerItem
->maTitle
;
295 maFTName
->SetText(maCurRegionName
);
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(),
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: */