bump product version to 5.0.4.1
[LibreOffice.git] / sfx2 / source / control / recentdocsview.cxx
blob43b8d55e1a8576756719d9bb72a87d0305dd7ae8
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sax/tools/converter.hxx>
21 #include <sfx2/recentdocsview.hxx>
22 #include <sfx2/templateabstractview.hxx>
23 #include <sfx2/app.hxx>
24 #include <sfx2/sfx.hrc>
25 #include <sfx2/sfxresid.hxx>
26 #include <unotools/historyoptions.hxx>
27 #include <vcl/builderfactory.hxx>
28 #include <vcl/pngread.hxx>
29 #include <tools/urlobj.hxx>
30 #include <com/sun/star/util/URLTransformer.hpp>
31 #include <com/sun/star/frame/Desktop.hpp>
32 #include <com/sun/star/frame/XFrame.hpp>
33 #include <templateview.hrc>
35 #include <officecfg/Office/Common.hxx>
37 using namespace ::com::sun::star;
38 using namespace com::sun::star::uno;
39 using namespace com::sun::star::lang;
40 using namespace com::sun::star::frame;
41 using namespace com::sun::star::beans;
43 namespace {
45 /// Set (larger) font for the Welcome message.
46 void SetMessageFont(vcl::RenderContext& rRenderContext)
48 vcl::Font aFont(rRenderContext.GetFont());
49 aFont.SetHeight(aFont.GetHeight() * 1.3);
50 rRenderContext.SetFont(aFont);
55 RecentDocsView::RecentDocsView( vcl::Window* pParent )
56 : ThumbnailView(pParent)
57 , mnFileTypes(TYPE_NONE)
58 , mnTextHeight(30)
59 , mnItemPadding(5)
60 , mnItemMaxTextLength(30)
61 , mnLastMouseDownItem(THUMBNAILVIEW_ITEM_NOTFOUND)
62 , maWelcomeImage(SfxResId(IMG_WELCOME))
63 , maWelcomeLine1(SfxResId(STR_WELCOME_LINE1))
64 , maWelcomeLine2(SfxResId(STR_WELCOME_LINE2))
66 Rectangle aScreen = Application::GetScreenPosSizePixel(Application::GetDisplayBuiltInScreen());
67 mnItemMaxSize = std::min(aScreen.GetWidth(),aScreen.GetHeight()) > 800 ? 256 : 192;
69 SetStyle(GetStyle() | WB_VSCROLL);
70 setItemMaxTextLength( mnItemMaxTextLength );
71 setItemDimensions( mnItemMaxSize, mnItemMaxSize, mnTextHeight, mnItemPadding );
73 maFillColor = Color(officecfg::Office::Common::Help::StartCenter::StartCenterThumbnailsBackgroundColor::get());
74 maTextColor = Color(officecfg::Office::Common::Help::StartCenter::StartCenterThumbnailsTextColor::get());
75 maHighlightColor = Color(officecfg::Office::Common::Help::StartCenter::StartCenterThumbnailsHighlightColor::get());
76 maHighlightTextColor = Color(officecfg::Office::Common::Help::StartCenter::StartCenterThumbnailsHighlightTextColor::get());
77 mfHighlightTransparence = 0.25;
80 VCL_BUILDER_FACTORY(RecentDocsView)
82 bool RecentDocsView::typeMatchesExtension(ApplicationType type, const OUString &rExt)
84 bool bRet = false;
86 if (rExt == "odt" || rExt == "doc" || rExt == "docx" ||
87 rExt == "rtf" || rExt == "txt" || rExt == "odm" || rExt == "otm")
89 bRet = type & TYPE_WRITER;
91 else if (rExt == "ods" || rExt == "xls" || rExt == "xlsx")
93 bRet = type & TYPE_CALC;
95 else if (rExt == "odp" || rExt == "pps" || rExt == "ppt" ||
96 rExt == "pptx")
98 bRet = type & TYPE_IMPRESS;
100 else if (rExt == "odg")
102 bRet = type & TYPE_DRAW;
104 else if (rExt == "odb")
106 bRet = type & TYPE_DATABASE;
108 else if (rExt == "odf")
110 bRet = type & TYPE_MATH;
112 else
114 bRet = type & TYPE_OTHER;
117 return bRet;
120 bool RecentDocsView::isAcceptedFile(const OUString &rURL) const
122 INetURLObject aUrl(rURL);
123 OUString aExt = aUrl.getExtension();
124 return (mnFileTypes & TYPE_WRITER && typeMatchesExtension(TYPE_WRITER, aExt)) ||
125 (mnFileTypes & TYPE_CALC && typeMatchesExtension(TYPE_CALC, aExt)) ||
126 (mnFileTypes & TYPE_IMPRESS && typeMatchesExtension(TYPE_IMPRESS, aExt)) ||
127 (mnFileTypes & TYPE_DRAW && typeMatchesExtension(TYPE_DRAW, aExt)) ||
128 (mnFileTypes & TYPE_DATABASE && typeMatchesExtension(TYPE_DATABASE,aExt)) ||
129 (mnFileTypes & TYPE_MATH && typeMatchesExtension(TYPE_MATH, aExt)) ||
130 (mnFileTypes & TYPE_OTHER && typeMatchesExtension(TYPE_OTHER, aExt));
133 BitmapEx RecentDocsView::getDefaultThumbnail(const OUString &rURL)
135 BitmapEx aImg;
136 INetURLObject aUrl(rURL);
137 OUString aExt = aUrl.getExtension();
139 if ( typeMatchesExtension( TYPE_WRITER, aExt) )
140 aImg = BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_TEXT ) );
141 else if ( typeMatchesExtension( TYPE_CALC, aExt) )
142 aImg = BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_SHEET ) );
143 else if ( typeMatchesExtension( TYPE_IMPRESS, aExt) )
144 aImg = BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_PRESENTATION ) );
145 else if ( typeMatchesExtension( TYPE_DRAW, aExt) )
146 aImg = BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_DRAWING ) );
147 else if ( typeMatchesExtension( TYPE_DATABASE, aExt) )
148 aImg = BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_DATABASE ) );
149 else if ( typeMatchesExtension( TYPE_MATH, aExt) )
150 aImg = BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_MATH ) );
151 else
152 aImg = BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_DEFAULT ) );
154 return aImg;
157 void RecentDocsView::insertItem(const OUString &rURL, const OUString &rTitle, const BitmapEx &rThumbnail, sal_uInt16 nId)
159 RecentDocsViewItem *pChild = new RecentDocsViewItem(*this, rURL, rTitle, rThumbnail, nId, GetThumbnailSize());
161 AppendItem(pChild);
164 void RecentDocsView::Reload()
166 Clear();
168 Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
169 for ( int i = 0; i < aHistoryList.getLength(); i++ )
171 Sequence< PropertyValue >& rRecentEntry = aHistoryList[i];
173 OUString aURL;
174 OUString aTitle;
175 BitmapEx aThumbnail;
177 for ( int j = 0; j < rRecentEntry.getLength(); j++ )
179 Any a = rRecentEntry[j].Value;
181 if (rRecentEntry[j].Name == "URL")
182 a >>= aURL;
183 else if (rRecentEntry[j].Name == "Title")
184 a >>= aTitle;
185 else if (rRecentEntry[j].Name == "Thumbnail")
187 OUString aBase64;
188 a >>= aBase64;
189 if (!aBase64.isEmpty())
191 Sequence<sal_Int8> aDecoded;
192 sax::Converter::decodeBase64(aDecoded, aBase64);
194 SvMemoryStream aStream(aDecoded.getArray(), aDecoded.getLength(), StreamMode::READ);
195 vcl::PNGReader aReader(aStream);
196 aThumbnail = aReader.Read();
201 if (isAcceptedFile(aURL))
203 insertItem(aURL, aTitle, aThumbnail, i+1);
207 CalculateItemPositions();
208 Invalidate();
211 void RecentDocsView::MouseButtonDown( const MouseEvent& rMEvt )
213 if (rMEvt.IsLeft())
215 mnLastMouseDownItem = ImplGetItem(rMEvt.GetPosPixel());
217 // ignore to avoid stuff done in ThumbnailView; we don't do selections etc.
218 return;
221 ThumbnailView::MouseButtonDown(rMEvt);
224 void RecentDocsView::MouseButtonUp(const MouseEvent& rMEvt)
226 if (rMEvt.IsLeft())
228 if( rMEvt.GetClicks() > 1 )
229 return;
231 size_t nPos = ImplGetItem(rMEvt.GetPosPixel());
232 ThumbnailViewItem* pItem = ImplGetItem(nPos);
234 if (pItem && nPos == mnLastMouseDownItem)
235 pItem->MouseButtonUp(rMEvt);
237 mnLastMouseDownItem = THUMBNAILVIEW_ITEM_NOTFOUND;
239 if (pItem)
240 return;
242 ThumbnailView::MouseButtonUp(rMEvt);
245 void RecentDocsView::OnItemDblClicked(ThumbnailViewItem *pItem)
247 RecentDocsViewItem* pRecentItem = dynamic_cast< RecentDocsViewItem* >(pItem);
248 if (pRecentItem)
249 pRecentItem->OpenDocument();
252 void RecentDocsView::Paint(vcl::RenderContext& rRenderContext, const Rectangle &aRect)
254 // Set preferred width
255 if (mFilteredItemList.empty())
257 rRenderContext.Push(PushFlags::FONT);
258 SetMessageFont(rRenderContext);
259 set_width_request(std::max(rRenderContext.GetTextWidth(maWelcomeLine1),
260 rRenderContext.GetTextWidth(maWelcomeLine2)));
261 rRenderContext.Pop();
263 else
265 set_width_request(mnTextHeight + mnItemMaxSize + 2 * mnItemPadding);
268 if (mItemList.size() == 0)
270 // No recent files to be shown yet. Show a welcome screen.
271 rRenderContext.Push(PushFlags::FONT | PushFlags::TEXTCOLOR);
272 SetMessageFont(rRenderContext);
273 SetTextColor(maTextColor);
275 long nTextHeight = rRenderContext.GetTextHeight();
277 long nTextWidth1 = rRenderContext.GetTextWidth(maWelcomeLine1);
278 long nTextWidth2 = rRenderContext.GetTextWidth(maWelcomeLine2);
280 const Size& rImgSize = maWelcomeImage.GetSizePixel();
281 const Size& rSize = GetSizePixel();
283 const int nX = (rSize.Width() - rImgSize.Width())/2;
284 const int nY = (rSize.Height() - 3 * nTextHeight - rImgSize.Height())/2;
286 Point aImgPoint(nX, nY);
287 Point aStr1Point((rSize.Width() - nTextWidth1)/2, nY + rImgSize.Height());
288 Point aStr2Point((rSize.Width() - nTextWidth2)/2, nY + rImgSize.Height() + 1.5 * nTextHeight);
290 rRenderContext.DrawImage(aImgPoint, rImgSize, maWelcomeImage);
291 rRenderContext.DrawText(aStr1Point, maWelcomeLine1);
292 rRenderContext.DrawText(aStr2Point, maWelcomeLine2);
294 rRenderContext.Pop();
296 else
298 ThumbnailView::Paint(rRenderContext, aRect);
302 void RecentDocsView::LoseFocus()
304 deselectItems();
306 ThumbnailView::LoseFocus();
309 void RecentDocsView::Clear()
311 Invalidate();
312 ThumbnailView::Clear();
315 IMPL_STATIC_LINK( RecentDocsView, ExecuteHdl_Impl, LoadRecentFile*, pLoadRecentFile )
319 // Asynchronous execution as this can lead to our own destruction!
320 // Framework can recycle our current frame and the layout manager disposes all user interface
321 // elements if a component gets detached from its frame!
322 pLoadRecentFile->xDispatch->dispatch( pLoadRecentFile->aTargetURL, pLoadRecentFile->aArgSeq );
324 catch ( const Exception& )
328 delete pLoadRecentFile;
329 return 0;
332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */