Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #include <sfx2/templateabstractview.hxx>
11 :
12 : #include <comphelper/processfactory.hxx>
13 : #include <sfx2/templateview.hxx>
14 : #include <sfx2/templateviewitem.hxx>
15 : #include <tools/urlobj.hxx>
16 : #include <unotools/ucbstreamhelper.hxx>
17 : #include <vcl/pngread.hxx>
18 :
19 : #include <com/sun/star/embed/ElementModes.hpp>
20 : #include <com/sun/star/embed/XStorage.hpp>
21 : #include <com/sun/star/embed/StorageFactory.hpp>
22 : #include <com/sun/star/lang/XComponent.hpp>
23 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
24 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
25 :
26 0 : bool ViewFilter_Application::isValid (const OUString &rPath) const
27 : {
28 0 : bool bRet = true;
29 :
30 0 : INetURLObject aUrl(rPath);
31 0 : OUString aExt = aUrl.getExtension();
32 0 : if (mApp == FILTER_APP_WRITER)
33 : {
34 0 : bRet = aExt == "ott" || aExt == "stw" || aExt == "oth" || aExt == "dot" || aExt == "dotx";
35 : }
36 0 : else if (mApp == FILTER_APP_CALC)
37 : {
38 0 : bRet = aExt == "ots" || aExt == "stc" || aExt == "xlt" || aExt == "xltm" || aExt == "xltx";
39 : }
40 0 : else if (mApp == FILTER_APP_IMPRESS)
41 : {
42 0 : bRet = aExt == "otp" || aExt == "sti" || aExt == "pot" || aExt == "potm" || aExt == "potx";
43 : }
44 0 : else if (mApp == FILTER_APP_DRAW)
45 : {
46 0 : bRet = aExt == "otg" || aExt == "std";
47 : }
48 :
49 0 : return bRet;
50 : }
51 :
52 0 : bool ViewFilter_Application::operator () (const ThumbnailViewItem *pItem)
53 : {
54 0 : const TemplateViewItem *pTempItem = static_cast<const TemplateViewItem*>(pItem);
55 :
56 0 : return isValid(pTempItem->getPath());
57 : }
58 :
59 0 : bool ViewFilter_Keyword::operator ()(const ThumbnailViewItem *pItem)
60 : {
61 : assert(pItem);
62 :
63 0 : return pItem->maTitle.matchIgnoreAsciiCase(maKeyword);
64 : }
65 :
66 0 : TemplateAbstractView::TemplateAbstractView (Window *pParent, WinBits nWinStyle, bool bDisableTransientChildren)
67 : : ThumbnailView(pParent,nWinStyle,bDisableTransientChildren),
68 0 : mpItemView(new TemplateView(this))
69 : {
70 0 : mpItemView->setItemStateHdl(LINK(this,TemplateAbstractView,OverlayItemStateHdl));
71 0 : }
72 :
73 0 : TemplateAbstractView::TemplateAbstractView(Window *pParent, const ResId &rResId, bool bDisableTransientChildren)
74 : : ThumbnailView(pParent,rResId,bDisableTransientChildren),
75 0 : mpItemView(new TemplateView(this))
76 : {
77 0 : mpItemView->setItemStateHdl(LINK(this,TemplateAbstractView,OverlayItemStateHdl));
78 0 : }
79 :
80 0 : TemplateAbstractView::~TemplateAbstractView ()
81 : {
82 0 : delete mpItemView;
83 0 : }
84 :
85 0 : void TemplateAbstractView::setItemDimensions(long ItemWidth, long ThumbnailHeight, long DisplayHeight, int itemPadding)
86 : {
87 0 : ThumbnailView::setItemDimensions(ItemWidth,ThumbnailHeight,DisplayHeight,itemPadding);
88 :
89 0 : mpItemView->setItemDimensions(ItemWidth,ThumbnailHeight,DisplayHeight,itemPadding);
90 0 : }
91 :
92 0 : sal_uInt16 TemplateAbstractView::getOverlayRegionId() const
93 : {
94 0 : return mpItemView->getId();
95 : }
96 :
97 0 : const OUString &TemplateAbstractView::getOverlayName() const
98 : {
99 0 : return mpItemView->getName();
100 : }
101 :
102 0 : bool TemplateAbstractView::isOverlayVisible () const
103 : {
104 0 : return mpItemView->IsVisible();
105 : }
106 :
107 0 : void TemplateAbstractView::deselectOverlayItems()
108 : {
109 0 : mpItemView->deselectItems();
110 0 : }
111 :
112 0 : void TemplateAbstractView::deselectOverlayItem(const sal_uInt16 nItemId)
113 : {
114 0 : mpItemView->deselectItem(nItemId);
115 0 : }
116 :
117 0 : void TemplateAbstractView::sortOverlayItems(const boost::function<bool (const ThumbnailViewItem*,
118 : const ThumbnailViewItem*) > &func)
119 : {
120 0 : mpItemView->sortItems(func);
121 0 : }
122 :
123 0 : void TemplateAbstractView::filterTemplatesByKeyword(const OUString &rKeyword)
124 : {
125 0 : if (mpItemView->IsVisible())
126 0 : mpItemView->filterItems(ViewFilter_Keyword(rKeyword));
127 0 : }
128 :
129 0 : void TemplateAbstractView::setOverlayDblClickHdl(const Link &rLink)
130 : {
131 0 : mpItemView->setDblClickHdl(rLink);
132 0 : }
133 :
134 0 : void TemplateAbstractView::setOverlayCloseHdl(const Link &rLink)
135 : {
136 0 : mpItemView->setCloseHdl(rLink);
137 0 : }
138 :
139 0 : BitmapEx TemplateAbstractView::scaleImg (const BitmapEx &rImg, long width, long height)
140 : {
141 0 : BitmapEx aImg = rImg;
142 :
143 0 : if ( !rImg.IsEmpty() )
144 : {
145 :
146 0 : const Size& aImgSize = aImg.GetSizePixel();
147 0 : double nRatio = double(aImgSize.getWidth()) / double(aImgSize.getHeight());
148 :
149 0 : long nDestWidth = aImgSize.getWidth();
150 0 : long nDestHeight = aImgSize.getHeight();
151 :
152 : // Which one side is the overflowing most?
153 0 : long nDistW = aImgSize.getWidth() - width;
154 0 : long nDistH = aImgSize.getHeight() - height;
155 :
156 : // Use the biggest overflow side to make it fit the destination
157 0 : if ( nDistW >= nDistH && nDistW > 0 )
158 : {
159 0 : nDestWidth = width;
160 0 : nDestHeight = width / nRatio;
161 : }
162 0 : else if ( nDistW < nDistH && nDistH > 0 )
163 : {
164 0 : nDestHeight = height;
165 0 : nDestWidth = height * nRatio;
166 : }
167 :
168 0 : aImg.Scale(Size(nDestWidth,nDestHeight));
169 : }
170 :
171 0 : return aImg;
172 : }
173 :
174 0 : BitmapEx TemplateAbstractView::fetchThumbnail (const OUString &msURL, long width, long height)
175 : {
176 : using namespace ::com::sun::star;
177 : using namespace ::com::sun::star::uno;
178 :
179 : // Load the thumbnail from a template document.
180 0 : uno::Reference<io::XInputStream> xIStream;
181 :
182 0 : uno::Reference< uno::XComponentContext > xContext (comphelper::getProcessComponentContext());
183 :
184 : try
185 : {
186 0 : uno::Reference<lang::XSingleServiceFactory> xStorageFactory = embed::StorageFactory::create( xContext );
187 :
188 0 : uno::Sequence<uno::Any> aArgs (2);
189 0 : aArgs[0] <<= msURL;
190 0 : aArgs[1] <<= embed::ElementModes::READ;
191 : uno::Reference<embed::XStorage> xDocStorage (
192 0 : xStorageFactory->createInstanceWithArguments(aArgs),
193 0 : uno::UNO_QUERY);
194 :
195 : try
196 : {
197 0 : if (xDocStorage.is())
198 : {
199 : uno::Reference<embed::XStorage> xStorage (
200 0 : xDocStorage->openStorageElement(
201 : "Thumbnails",
202 0 : embed::ElementModes::READ));
203 0 : if (xStorage.is())
204 : {
205 : uno::Reference<io::XStream> xThumbnailCopy (
206 0 : xStorage->cloneStreamElement("thumbnail.png"));
207 0 : if (xThumbnailCopy.is())
208 0 : xIStream = xThumbnailCopy->getInputStream();
209 0 : }
210 : }
211 : }
212 0 : catch (const uno::Exception& rException)
213 : {
214 : OSL_TRACE (
215 : "caught exception while trying to access Thumbnail/thumbnail.png of %s: %s",
216 : ::rtl::OUStringToOString(msURL,
217 : RTL_TEXTENCODING_UTF8).getStr(),
218 : ::rtl::OUStringToOString(rException.Message,
219 : RTL_TEXTENCODING_UTF8).getStr());
220 : }
221 :
222 : try
223 : {
224 : // An (older) implementation had a bug - The storage
225 : // name was "Thumbnail" instead of "Thumbnails". The
226 : // old name is still used as fallback but this code can
227 : // be removed soon.
228 0 : if ( ! xIStream.is())
229 : {
230 : uno::Reference<embed::XStorage> xStorage (
231 0 : xDocStorage->openStorageElement( "Thumbnail",
232 0 : embed::ElementModes::READ));
233 0 : if (xStorage.is())
234 : {
235 : uno::Reference<io::XStream> xThumbnailCopy (
236 0 : xStorage->cloneStreamElement("thumbnail.png"));
237 0 : if (xThumbnailCopy.is())
238 0 : xIStream = xThumbnailCopy->getInputStream();
239 0 : }
240 : }
241 : }
242 0 : catch (const uno::Exception& rException)
243 : {
244 : OSL_TRACE (
245 : "caught exception while trying to access Thumbnails/thumbnail.png of %s: %s",
246 : ::rtl::OUStringToOString(msURL,
247 : RTL_TEXTENCODING_UTF8).getStr(),
248 : ::rtl::OUStringToOString(rException.Message,
249 : RTL_TEXTENCODING_UTF8).getStr());
250 0 : }
251 : }
252 0 : catch (const uno::Exception& rException)
253 : {
254 : OSL_TRACE (
255 : "caught exception while trying to access tuhmbnail of %s: %s",
256 : ::rtl::OUStringToOString(msURL,
257 : RTL_TEXTENCODING_UTF8).getStr(),
258 : ::rtl::OUStringToOString(rException.Message,
259 : RTL_TEXTENCODING_UTF8).getStr());
260 : }
261 :
262 : // Extract the image from the stream.
263 0 : BitmapEx aThumbnail;
264 0 : if (xIStream.is())
265 : {
266 : ::std::auto_ptr<SvStream> pStream (
267 0 : ::utl::UcbStreamHelper::CreateStream (xIStream));
268 0 : ::vcl::PNGReader aReader (*pStream);
269 0 : aThumbnail = aReader.Read ();
270 : }
271 :
272 0 : return TemplateAbstractView::scaleImg(aThumbnail,width,height);
273 : }
274 :
275 0 : void TemplateAbstractView::Resize()
276 : {
277 0 : mpItemView->SetSizePixel(GetSizePixel());
278 0 : ThumbnailView::Resize();
279 0 : }
280 :
281 0 : void TemplateAbstractView::Paint(const Rectangle &rRect)
282 : {
283 0 : if (!mpItemView->IsVisible())
284 0 : ThumbnailView::Paint(rRect);
285 0 : }
286 :
287 0 : void TemplateAbstractView::DrawItem(ThumbnailViewItem *pItem)
288 : {
289 0 : if (!mpItemView->IsVisible())
290 0 : ThumbnailView::DrawItem(pItem);
291 0 : }
292 :
293 0 : IMPL_LINK(TemplateAbstractView, OverlayItemStateHdl, const ThumbnailViewItem*, pItem)
294 : {
295 0 : maOverlayItemStateHdl.Call((void*)pItem);
296 0 : return 0;
297 : }
298 :
299 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|