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/.
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
;
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
)
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
)
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" ||
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
;
114 bRet
= type
& TYPE_OTHER
;
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
)
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
) );
152 aImg
= BitmapEx ( SfxResId( SFX_FILE_THUMBNAIL_DEFAULT
) );
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());
164 void RecentDocsView::Reload()
168 Sequence
< Sequence
< PropertyValue
> > aHistoryList
= SvtHistoryOptions().GetList( ePICKLIST
);
169 for ( int i
= 0; i
< aHistoryList
.getLength(); i
++ )
171 Sequence
< PropertyValue
>& rRecentEntry
= aHistoryList
[i
];
177 for ( int j
= 0; j
< rRecentEntry
.getLength(); j
++ )
179 Any a
= rRecentEntry
[j
].Value
;
181 if (rRecentEntry
[j
].Name
== "URL")
183 else if (rRecentEntry
[j
].Name
== "Title")
185 else if (rRecentEntry
[j
].Name
== "Thumbnail")
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();
211 void RecentDocsView::MouseButtonDown( const MouseEvent
& rMEvt
)
215 mnLastMouseDownItem
= ImplGetItem(rMEvt
.GetPosPixel());
217 // ignore to avoid stuff done in ThumbnailView; we don't do selections etc.
221 ThumbnailView::MouseButtonDown(rMEvt
);
224 void RecentDocsView::MouseButtonUp(const MouseEvent
& rMEvt
)
228 if( rMEvt
.GetClicks() > 1 )
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
;
242 ThumbnailView::MouseButtonUp(rMEvt
);
245 void RecentDocsView::OnItemDblClicked(ThumbnailViewItem
*pItem
)
247 RecentDocsViewItem
* pRecentItem
= dynamic_cast< RecentDocsViewItem
* >(pItem
);
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();
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();
298 ThumbnailView::Paint(rRenderContext
, aRect
);
302 void RecentDocsView::LoseFocus()
306 ThumbnailView::LoseFocus();
309 void RecentDocsView::Clear()
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
;
332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */