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/recentdocsviewitem.hxx>
11 :
12 : #include <com/sun/star/frame/Desktop.hpp>
13 : #include <com/sun/star/util/URLTransformer.hpp>
14 : #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
15 : #include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx>
16 : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
17 : #include <i18nutil/paper.hxx>
18 : #include <sfx2/recentdocsview.hxx>
19 : #include <sfx2/sfxresid.hxx>
20 : #include <sfx2/templateabstractview.hxx>
21 : #include <tools/urlobj.hxx>
22 : #include <unotools/historyoptions.hxx>
23 : #include <vcl/svapp.hxx>
24 :
25 : #include <templateview.hrc>
26 :
27 : using namespace basegfx;
28 : using namespace com::sun::star;
29 : using namespace com::sun::star::uno;
30 : using namespace drawinglayer::primitive2d;
31 : using namespace drawinglayer::processor2d;
32 :
33 : /// Icon that the user can click to remove the document from the recent documents.
34 : struct theRemoveRecentBitmap : public rtl::StaticWithInit<BitmapEx, theRemoveRecentBitmap>
35 : {
36 0 : BitmapEx operator()()
37 : {
38 0 : return SfxResId(IMG_RECENTDOC_REMOVE);
39 : }
40 :
41 : };
42 :
43 : /// Highlighted version of icon that the user can click to remove the document from the recent documents.
44 : struct theRemoveRecentBitmapHighlighted : public rtl::StaticWithInit<BitmapEx, theRemoveRecentBitmapHighlighted>
45 : {
46 0 : BitmapEx operator()()
47 : {
48 0 : return SfxResId(IMG_RECENTDOC_REMOVE_HIGHLIGHTED);
49 : }
50 :
51 : };
52 :
53 0 : RecentDocsViewItem::RecentDocsViewItem(ThumbnailView &rView, const OUString &rURL,
54 : const OUString &rTitle, const BitmapEx &rThumbnail, sal_uInt16 nId)
55 : : ThumbnailViewItem(rView, nId),
56 : maURL(rURL),
57 0 : m_bRemoveIconHighlighted(false)
58 : {
59 0 : OUString aTitle(rTitle);
60 0 : INetURLObject aURLObj(rURL);
61 :
62 0 : if( aURLObj.GetProtocol() == INET_PROT_FILE )
63 0 : m_sHelpText = aURLObj.getFSysPath(INetURLObject::FSYS_DETECT);
64 0 : if( m_sHelpText.isEmpty() )
65 0 : m_sHelpText = aURLObj.GetURLNoPass();
66 :
67 0 : RecentDocsView& rRecentView = dynamic_cast<RecentDocsView&>(rView);
68 0 : long nThumbnailSize = rRecentView.GetThumbnailSize();
69 :
70 0 : if (aTitle.isEmpty())
71 0 : aTitle = aURLObj.GetName(INetURLObject::DECODE_WITH_CHARSET);
72 :
73 0 : BitmapEx aThumbnail(rThumbnail);
74 0 : if (aThumbnail.IsEmpty() && aURLObj.GetProtocol() == INET_PROT_FILE)
75 0 : aThumbnail = ThumbnailView::readThumbnail(rURL);
76 :
77 0 : if (aThumbnail.IsEmpty())
78 : {
79 : // Use the default thumbnail if we have nothing else
80 0 : BitmapEx aExt(RecentDocsView::getDefaultThumbnail(rURL));
81 0 : Size aExtSize(aExt.GetSizePixel());
82 :
83 : // attempt to make it appear as if it is on a piece of paper
84 : long nPaperHeight;
85 : long nPaperWidth;
86 0 : if( RecentDocsView::typeMatchesExtension(TYPE_IMPRESS, aURLObj.getExtension()) )
87 : {
88 : // Swap width and height (PAPER_SCREEN_4_3 definition make it needed)
89 0 : PaperInfo aInfo(PAPER_SCREEN_4_3);
90 0 : nPaperHeight = aInfo.getWidth();
91 0 : nPaperWidth = aInfo.getHeight();
92 : }
93 : else
94 : {
95 0 : PaperInfo aInfo(PaperInfo::getSystemDefaultPaper());
96 0 : nPaperHeight = aInfo.getHeight();
97 0 : nPaperWidth = aInfo.getWidth();
98 : }
99 0 : double ratio = double(nThumbnailSize) / double(std::max(nPaperHeight, nPaperWidth));
100 0 : Size aThumbnailSize(nPaperWidth * ratio, nPaperHeight * ratio);
101 :
102 0 : if (aExtSize.Width() > aThumbnailSize.Width() || aExtSize.Height() > aThumbnailSize.Height())
103 : {
104 0 : aExt = TemplateAbstractView::scaleImg(aExt, aThumbnailSize.Width(), aThumbnailSize.Height());
105 0 : aExtSize = aExt.GetSizePixel();
106 : }
107 :
108 : // create empty, and copy the default thumbnail in
109 0 : sal_uInt8 nAlpha = 255;
110 0 : aThumbnail = BitmapEx(Bitmap(aThumbnailSize, 24), AlphaMask(aThumbnailSize, &nAlpha));
111 :
112 : aThumbnail.CopyPixel(
113 0 : Rectangle(Point((aThumbnailSize.Width() - aExtSize.Width()) / 2, (aThumbnailSize.Height() - aExtSize.Height()) / 2), aExtSize),
114 : Rectangle(Point(0, 0), aExtSize),
115 0 : &aExt);
116 : }
117 :
118 0 : maTitle = aTitle;
119 0 : maPreview1 = TemplateAbstractView::scaleImg(aThumbnail, nThumbnailSize, nThumbnailSize);
120 0 : }
121 :
122 0 : void RecentDocsViewItem::setEditTitle (bool edit, bool bChangeFocus)
123 : {
124 : // Unused parameters.
125 : (void)edit;
126 : (void)bChangeFocus;
127 0 : }
128 :
129 0 : Rectangle RecentDocsViewItem::updateHighlight(bool bVisible, const Point& rPoint)
130 : {
131 0 : Rectangle aRect(ThumbnailViewItem::updateHighlight(bVisible, rPoint));
132 :
133 0 : if (bVisible && getRemoveIconArea().IsInside(rPoint))
134 : {
135 0 : if (!m_bRemoveIconHighlighted)
136 0 : aRect.Union(getRemoveIconArea());
137 :
138 0 : m_bRemoveIconHighlighted = true;
139 : }
140 : else
141 : {
142 0 : if (m_bRemoveIconHighlighted)
143 0 : aRect.Union(getRemoveIconArea());
144 :
145 0 : m_bRemoveIconHighlighted = false;
146 : }
147 :
148 0 : return aRect;
149 : }
150 :
151 0 : Rectangle RecentDocsViewItem::getRemoveIconArea() const
152 : {
153 0 : Rectangle aArea(getDrawArea());
154 0 : Size aSize(theRemoveRecentBitmap::get().GetSizePixel());
155 :
156 : return Rectangle(
157 0 : Point(aArea.Right() - aSize.Width() - THUMBNAILVIEW_ITEM_CORNER, aArea.Top() + THUMBNAILVIEW_ITEM_CORNER),
158 0 : aSize);
159 : }
160 :
161 0 : OUString RecentDocsViewItem::getHelpText() const
162 : {
163 0 : return m_sHelpText;
164 : }
165 :
166 0 : void RecentDocsViewItem::Paint(drawinglayer::processor2d::BaseProcessor2D *pProcessor, const ThumbnailItemAttributes *pAttrs)
167 : {
168 0 : ThumbnailViewItem::Paint(pProcessor, pAttrs);
169 :
170 : // paint the remove icon when highlighted
171 0 : if (isHighlighted())
172 : {
173 0 : drawinglayer::primitive2d::Primitive2DSequence aSeq(1);
174 :
175 0 : Point aIconPos(getRemoveIconArea().TopLeft());
176 :
177 0 : aSeq[0] = drawinglayer::primitive2d::Primitive2DReference(new DiscreteBitmapPrimitive2D(
178 : m_bRemoveIconHighlighted? theRemoveRecentBitmapHighlighted::get(): theRemoveRecentBitmap::get(),
179 0 : B2DPoint(aIconPos.X(), aIconPos.Y())));
180 :
181 0 : pProcessor->process(aSeq);
182 : }
183 0 : }
184 :
185 0 : void RecentDocsViewItem::MouseButtonUp(const MouseEvent& rMEvt)
186 : {
187 0 : if (rMEvt.IsLeft())
188 : {
189 0 : if (getRemoveIconArea().IsInside(rMEvt.GetPosPixel()))
190 : {
191 0 : SvtHistoryOptions().DeleteItem(ePICKLIST, maURL);
192 0 : mrParent.Reload();
193 0 : return;
194 : }
195 :
196 0 : OpenDocument();
197 0 : return;
198 : }
199 : }
200 :
201 0 : void RecentDocsViewItem::OpenDocument()
202 : {
203 : // show busy mouse pointer
204 0 : mrParent.SetPointer(Pointer(POINTER_WAIT));
205 :
206 0 : Reference<frame::XDispatch> xDispatch;
207 0 : Reference<frame::XDispatchProvider> xDispatchProvider;
208 0 : css::util::URL aTargetURL;
209 0 : Sequence<beans::PropertyValue> aArgsList;
210 :
211 0 : uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(::comphelper::getProcessComponentContext());
212 0 : uno::Reference<frame::XFrame> xActiveFrame = xDesktop->getActiveFrame();
213 :
214 : //osl::ClearableMutexGuard aLock(m_aMutex);
215 0 : xDispatchProvider = Reference<frame::XDispatchProvider>(xActiveFrame, UNO_QUERY);
216 : //aLock.clear();
217 :
218 0 : aTargetURL.Complete = maURL;
219 0 : Reference<util::XURLTransformer> xTrans(util::URLTransformer::create(::comphelper::getProcessComponentContext()));
220 0 : xTrans->parseStrict(aTargetURL);
221 :
222 0 : sal_Int32 nSize = 2;
223 0 : aArgsList.realloc(nSize);
224 0 : aArgsList[0].Name = "Referer";
225 0 : aArgsList[0].Value = makeAny(OUString("private:user"));
226 :
227 : // documents will never be opened as templates
228 0 : aArgsList[1].Name = "AsTemplate";
229 0 : aArgsList[1].Value = makeAny(false);
230 :
231 0 : xDispatch = xDispatchProvider->queryDispatch(aTargetURL, "_default", 0);
232 :
233 0 : if (xDispatch.is())
234 : {
235 : // Call dispatch asychronously as we can be destroyed while dispatch is
236 : // executed. VCL is not able to survive this as it wants to call listeners
237 : // after select!!!
238 0 : LoadRecentFile* pLoadRecentFile = new LoadRecentFile;
239 0 : pLoadRecentFile->xDispatch = xDispatch;
240 0 : pLoadRecentFile->aTargetURL = aTargetURL;
241 0 : pLoadRecentFile->aArgSeq = aArgsList;
242 :
243 0 : Application::PostUserEvent(STATIC_LINK(0, RecentDocsView, ExecuteHdl_Impl), pLoadRecentFile);
244 0 : }
245 951 : }
246 :
247 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|