/src/libreoffice/svx/source/gallery2/galctrl.cxx
Line | Count | Source |
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 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #include <config_features.h> |
21 | | |
22 | | #include <sfx2/viewfrm.hxx> |
23 | | #include <sfx2/dispatch.hxx> |
24 | | #include <sfx2/sfxsids.hrc> |
25 | | #include <avmedia/mediaplayer.hxx> |
26 | | #include <galbrws1.hxx> |
27 | | #include <svx/galtheme.hxx> |
28 | | #include <svx/galmisc.hxx> |
29 | | #include <svx/galctrl.hxx> |
30 | | #include <galobj.hxx> |
31 | | #include <avmedia/mediawindow.hxx> |
32 | | #include <vcl/event.hxx> |
33 | | #include <vcl/commandevent.hxx> |
34 | | #include <vcl/graphicfilter.hxx> |
35 | | #include <bitmaps.hlst> |
36 | | #include <svl/itemset.hxx> |
37 | | |
38 | | GalleryPreview::GalleryPreview(GalleryBrowser* pParent, std::unique_ptr<weld::ScrolledWindow> xScrolledWindow) |
39 | 0 | : mxScrolledWindow(std::move(xScrolledWindow)) |
40 | 0 | , mpParent(pParent) |
41 | 0 | , mpTheme(nullptr) |
42 | 0 | { |
43 | 0 | } |
44 | | |
45 | | void GalleryPreview::Show() |
46 | 0 | { |
47 | 0 | mxScrolledWindow->show(); |
48 | 0 | weld::CustomWidgetController::Show(); |
49 | 0 | } |
50 | | |
51 | | void GalleryPreview::Hide() |
52 | 0 | { |
53 | 0 | weld::CustomWidgetController::Hide(); |
54 | 0 | mxScrolledWindow->hide(); |
55 | 0 | } |
56 | | |
57 | | GalleryPreview::~GalleryPreview() |
58 | 0 | { |
59 | 0 | } |
60 | | |
61 | | void GalleryPreview::SetDrawingArea(weld::DrawingArea* pDrawingArea) |
62 | 0 | { |
63 | 0 | CustomWidgetController::SetDrawingArea(pDrawingArea); |
64 | 0 | Size aSize = pDrawingArea->get_ref_device().LogicToPixel(Size(70, 88), MapMode(MapUnit::MapAppFont)); |
65 | 0 | pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); |
66 | 0 | SetOutputSizePixel(aSize); |
67 | |
|
68 | 0 | mxDragDropTargetHelper.reset(new GalleryDragDrop(mpParent, pDrawingArea->get_drop_target())); |
69 | 0 | } |
70 | | |
71 | | namespace |
72 | | { |
73 | | bool ImplGetGraphicCenterRect(const weld::CustomWidgetController& rWidget, const Graphic& rGraphic, tools::Rectangle& rResultRect) |
74 | 0 | { |
75 | 0 | const Size aWinSize(rWidget.GetOutputSizePixel()); |
76 | 0 | Size aNewSize(rWidget.GetDrawingArea()->get_ref_device().LogicToPixel(rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode())); |
77 | 0 | bool bRet = false; |
78 | |
|
79 | 0 | if( aNewSize.Width() && aNewSize.Height() ) |
80 | 0 | { |
81 | | // scale to fit window |
82 | 0 | const double fGrfWH = static_cast<double>(aNewSize.Width()) / aNewSize.Height(); |
83 | 0 | const double fWinWH = static_cast<double>(aWinSize.Width()) / aWinSize.Height(); |
84 | |
|
85 | 0 | if ( fGrfWH < fWinWH ) |
86 | 0 | { |
87 | 0 | aNewSize.setWidth( static_cast<tools::Long>( aWinSize.Height() * fGrfWH ) ); |
88 | 0 | aNewSize.setHeight( aWinSize.Height() ); |
89 | 0 | } |
90 | 0 | else |
91 | 0 | { |
92 | 0 | aNewSize.setWidth( aWinSize.Width() ); |
93 | 0 | aNewSize.setHeight( static_cast<tools::Long>( aWinSize.Width() / fGrfWH) ); |
94 | 0 | } |
95 | |
|
96 | 0 | const Point aNewPos( ( aWinSize.Width() - aNewSize.Width() ) >> 1, |
97 | 0 | ( aWinSize.Height() - aNewSize.Height() ) >> 1 ); |
98 | |
|
99 | 0 | rResultRect = tools::Rectangle( aNewPos, aNewSize ); |
100 | 0 | bRet = true; |
101 | 0 | } |
102 | |
|
103 | 0 | return bRet; |
104 | 0 | } |
105 | | } |
106 | | |
107 | | bool GalleryPreview::ImplGetGraphicCenterRect( const Graphic& rGraphic, tools::Rectangle& rResultRect ) const |
108 | 0 | { |
109 | 0 | return ::ImplGetGraphicCenterRect(*this, rGraphic, rResultRect); |
110 | 0 | } |
111 | | |
112 | | void GalleryPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/) |
113 | 0 | { |
114 | 0 | rRenderContext.SetBackground(Wallpaper(GALLERY_BG_COLOR)); |
115 | 0 | rRenderContext.Erase(); |
116 | |
|
117 | 0 | if (ImplGetGraphicCenterRect(m_aGraphicObj.GetGraphic(), m_aPreviewRect)) |
118 | 0 | { |
119 | 0 | const Point aPos( m_aPreviewRect.TopLeft() ); |
120 | 0 | const Size aSize( m_aPreviewRect.GetSize() ); |
121 | |
|
122 | 0 | if( m_aGraphicObj.IsAnimated() ) |
123 | 0 | m_aGraphicObj.StartAnimation(rRenderContext, aPos, aSize); |
124 | 0 | else |
125 | 0 | m_aGraphicObj.Draw(rRenderContext, aPos, aSize); |
126 | 0 | } |
127 | 0 | } |
128 | | |
129 | | bool GalleryPreview::MouseButtonDown(const MouseEvent& rMEvt) |
130 | 0 | { |
131 | 0 | if (mpTheme && (rMEvt.GetClicks() == 2)) |
132 | 0 | mpParent->TogglePreview(); |
133 | 0 | return true; |
134 | 0 | } |
135 | | |
136 | | bool GalleryPreview::Command(const CommandEvent& rCEvt) |
137 | 0 | { |
138 | 0 | if (mpTheme && (rCEvt.GetCommand() == CommandEventId::ContextMenu)) |
139 | 0 | { |
140 | 0 | mpParent->ShowContextMenu(rCEvt); |
141 | 0 | return true; |
142 | 0 | } |
143 | 0 | return false; |
144 | 0 | } |
145 | | |
146 | | bool GalleryPreview::KeyInput(const KeyEvent& rKEvt) |
147 | 0 | { |
148 | 0 | if(mpTheme) |
149 | 0 | { |
150 | 0 | GalleryBrowser* pBrowser = mpParent; |
151 | |
|
152 | 0 | switch( rKEvt.GetKeyCode().GetCode() ) |
153 | 0 | { |
154 | 0 | case KEY_BACKSPACE: |
155 | 0 | pBrowser->TogglePreview(); |
156 | 0 | break; |
157 | | |
158 | 0 | case KEY_HOME: |
159 | 0 | pBrowser->Travel( GalleryBrowserTravel::First ); |
160 | 0 | break; |
161 | | |
162 | 0 | case KEY_END: |
163 | 0 | pBrowser->Travel( GalleryBrowserTravel::Last ); |
164 | 0 | break; |
165 | | |
166 | 0 | case KEY_LEFT: |
167 | 0 | case KEY_UP: |
168 | 0 | pBrowser->Travel( GalleryBrowserTravel::Previous ); |
169 | 0 | break; |
170 | | |
171 | 0 | case KEY_RIGHT: |
172 | 0 | case KEY_DOWN: |
173 | 0 | pBrowser->Travel( GalleryBrowserTravel::Next ); |
174 | 0 | break; |
175 | | |
176 | 0 | default: |
177 | 0 | { |
178 | 0 | if (!pBrowser->KeyInput(rKEvt)) |
179 | 0 | return false; |
180 | 0 | } |
181 | 0 | break; |
182 | 0 | } |
183 | | |
184 | 0 | return true; |
185 | 0 | } |
186 | 0 | return false; |
187 | 0 | } |
188 | | |
189 | | bool GalleryPreview::StartDrag() |
190 | 0 | { |
191 | 0 | if (mpTheme) |
192 | 0 | return mpParent->StartDrag(); |
193 | 0 | return true; |
194 | 0 | } |
195 | | |
196 | | void GalleryPreview::PreviewMedia( const INetURLObject& rURL ) |
197 | 0 | { |
198 | 0 | #if HAVE_FEATURE_AVMEDIA |
199 | 0 | if (rURL.GetProtocol() == INetProtocol::NotValid) |
200 | 0 | return; |
201 | | |
202 | 0 | ::avmedia::MediaFloater* pFloater = avmedia::getMediaFloater(); |
203 | |
|
204 | 0 | if (!pFloater) |
205 | 0 | { |
206 | 0 | if (SfxViewFrame* pViewFrm = SfxViewFrame::Current()) |
207 | 0 | pViewFrm->GetBindings().GetDispatcher()->Execute( SID_AVMEDIA_PLAYER, SfxCallMode::SYNCHRON ); |
208 | 0 | pFloater = avmedia::getMediaFloater(); |
209 | 0 | } |
210 | |
|
211 | 0 | if (pFloater) |
212 | 0 | pFloater->setURL( rURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ), u""_ustr, true ); |
213 | | #else |
214 | | (void) rURL; |
215 | | #endif |
216 | 0 | } |
217 | | |
218 | | DialogGalleryPreview::DialogGalleryPreview() |
219 | 0 | { |
220 | 0 | } |
221 | | |
222 | | void DialogGalleryPreview::SetDrawingArea(weld::DrawingArea* pDrawingArea) |
223 | 0 | { |
224 | 0 | CustomWidgetController::SetDrawingArea(pDrawingArea); |
225 | 0 | Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(70, 88), MapMode(MapUnit::MapAppFont))); |
226 | 0 | pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); |
227 | 0 | } |
228 | | |
229 | | bool DialogGalleryPreview::SetGraphic( const INetURLObject& _aURL ) |
230 | 0 | { |
231 | 0 | bool bRet = true; |
232 | 0 | Graphic aGraphic; |
233 | 0 | #if HAVE_FEATURE_AVMEDIA |
234 | 0 | if( ::avmedia::MediaWindow::isMediaURL( _aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ), u""_ustr ) ) |
235 | 0 | { |
236 | 0 | aGraphic = Bitmap(RID_SVXBMP_GALLERY_MEDIA); |
237 | 0 | } |
238 | 0 | else |
239 | 0 | #endif |
240 | 0 | { |
241 | 0 | GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); |
242 | 0 | GalleryProgress aProgress( &rFilter ); |
243 | 0 | if( rFilter.ImportGraphic( aGraphic, _aURL ) ) |
244 | 0 | bRet = false; |
245 | 0 | } |
246 | |
|
247 | 0 | SetGraphic( aGraphic ); |
248 | 0 | Invalidate(); |
249 | 0 | return bRet; |
250 | 0 | } |
251 | | |
252 | | bool DialogGalleryPreview::ImplGetGraphicCenterRect( const Graphic& rGraphic, tools::Rectangle& rResultRect ) const |
253 | 0 | { |
254 | 0 | return ::ImplGetGraphicCenterRect(*this, rGraphic, rResultRect); |
255 | 0 | } |
256 | | |
257 | | void DialogGalleryPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) |
258 | 0 | { |
259 | 0 | rRenderContext.SetBackground(Wallpaper(GALLERY_BG_COLOR)); |
260 | |
|
261 | 0 | if (ImplGetGraphicCenterRect(maGraphicObj.GetGraphic(), maPreviewRect)) |
262 | 0 | { |
263 | 0 | const Point aPos( maPreviewRect.TopLeft() ); |
264 | 0 | const Size aSize( maPreviewRect.GetSize() ); |
265 | |
|
266 | 0 | if( maGraphicObj.IsAnimated() ) |
267 | 0 | maGraphicObj.StartAnimation(rRenderContext, aPos, aSize); |
268 | 0 | else |
269 | 0 | maGraphicObj.Draw(rRenderContext, aPos, aSize); |
270 | 0 | } |
271 | 0 | } |
272 | | |
273 | | void GalleryIconView::drawTransparenceBackground(vcl::RenderContext& rOut, const Point& rPos, const Size& rSize) |
274 | 0 | { |
275 | | // draw checkered background |
276 | 0 | static const sal_uInt32 nLen(8); |
277 | 0 | static const Color aW(COL_WHITE); |
278 | 0 | static const Color aG(0xef, 0xef, 0xef); |
279 | |
|
280 | 0 | rOut.DrawCheckered(rPos, rSize, nLen, aW, aG); |
281 | 0 | } |
282 | | |
283 | | GalleryIconView::GalleryIconView(GalleryBrowser* pParent, std::unique_ptr<weld::ScrolledWindow> xScrolledWindow) |
284 | 0 | : ValueSet(std::move(xScrolledWindow)) |
285 | 0 | , mpParent(pParent) |
286 | 0 | , mpTheme(nullptr) |
287 | 0 | { |
288 | 0 | } |
289 | | |
290 | | GalleryIconView::~GalleryIconView() |
291 | 0 | { |
292 | 0 | } |
293 | | |
294 | | void GalleryIconView::SetDrawingArea(weld::DrawingArea* pDrawingArea) |
295 | 0 | { |
296 | 0 | ValueSet::SetDrawingArea(pDrawingArea); |
297 | |
|
298 | 0 | SetStyle(GetStyle() | WB_TABSTOP | WB_3DLOOK | WB_BORDER | WB_ITEMBORDER | WB_DOUBLEBORDER | WB_VSCROLL | WB_FLATVALUESET); |
299 | 0 | EnableFullItemMode( false ); |
300 | |
|
301 | 0 | SetExtraSpacing( 2 ); |
302 | 0 | SetItemWidth( S_THUMB + 6 ); |
303 | 0 | SetItemHeight( S_THUMB + 6 ); |
304 | |
|
305 | 0 | mxDragDropTargetHelper.reset(new GalleryDragDrop(mpParent, pDrawingArea->get_drop_target())); |
306 | 0 | } |
307 | | |
308 | | void GalleryIconView::UserDraw(const UserDrawEvent& rUDEvt) |
309 | 0 | { |
310 | 0 | const sal_uInt16 nId = rUDEvt.GetItemId(); |
311 | |
|
312 | 0 | if (!nId || !mpTheme) |
313 | 0 | return; |
314 | | |
315 | 0 | const tools::Rectangle& rRect = rUDEvt.GetRect(); |
316 | 0 | const Size aSize(rRect.GetWidth(), rRect.GetHeight()); |
317 | 0 | Bitmap aBitmap; |
318 | 0 | Size aPreparedSize; |
319 | 0 | OUString aItemTextTitle; |
320 | 0 | OUString aItemTextPath; |
321 | |
|
322 | 0 | mpTheme->GetPreviewBitmapAndStrings(nId - 1, aBitmap, aPreparedSize, aItemTextTitle, aItemTextPath); |
323 | |
|
324 | 0 | bool bNeedToCreate(aBitmap.IsEmpty()); |
325 | |
|
326 | 0 | if (!bNeedToCreate && aItemTextTitle.isEmpty()) |
327 | 0 | { |
328 | 0 | bNeedToCreate = true; |
329 | 0 | } |
330 | |
|
331 | 0 | if (!bNeedToCreate && aPreparedSize != aSize) |
332 | 0 | { |
333 | 0 | bNeedToCreate = true; |
334 | 0 | } |
335 | |
|
336 | 0 | if (bNeedToCreate) |
337 | 0 | { |
338 | 0 | std::unique_ptr<SgaObject> pObj = mpTheme->AcquireObject(nId - 1); |
339 | |
|
340 | 0 | if(pObj) |
341 | 0 | { |
342 | 0 | aBitmap = pObj->createPreviewBitmap(aSize); |
343 | 0 | aItemTextTitle = GalleryBrowser::GetItemText(*pObj, GalleryItemFlags::Title); |
344 | |
|
345 | 0 | mpTheme->SetPreviewBitmapAndStrings(nId - 1, aBitmap, aSize, aItemTextTitle, aItemTextPath); |
346 | 0 | } |
347 | 0 | } |
348 | |
|
349 | 0 | if (!aBitmap.IsEmpty()) |
350 | 0 | { |
351 | 0 | const Size aBitmapExSizePixel(aBitmap.GetSizePixel()); |
352 | 0 | const Point aPos( |
353 | 0 | ((aSize.Width() - aBitmapExSizePixel.Width()) >> 1) + rRect.Left(), |
354 | 0 | ((aSize.Height() - aBitmapExSizePixel.Height()) >> 1) + rRect.Top()); |
355 | 0 | OutputDevice* pDev = rUDEvt.GetRenderContext(); |
356 | |
|
357 | 0 | if(aBitmap.HasAlpha()) |
358 | 0 | { |
359 | | // draw checkered background for full rectangle. |
360 | 0 | GalleryIconView::drawTransparenceBackground(*pDev, rRect.TopLeft(), rRect.GetSize()); |
361 | 0 | } |
362 | |
|
363 | 0 | pDev->DrawBitmap(aPos, aBitmap); |
364 | 0 | } |
365 | |
|
366 | 0 | SetItemText(nId, aItemTextTitle); |
367 | 0 | } |
368 | | |
369 | | bool GalleryIconView::MouseButtonDown(const MouseEvent& rMEvt) |
370 | 0 | { |
371 | 0 | bool bRet = ValueSet::MouseButtonDown(rMEvt); |
372 | |
|
373 | 0 | if (rMEvt.GetClicks() == 2) |
374 | 0 | mpParent->TogglePreview(); |
375 | |
|
376 | 0 | return bRet; |
377 | 0 | } |
378 | | |
379 | | bool GalleryIconView::Command(const CommandEvent& rCEvt) |
380 | 0 | { |
381 | 0 | bool bRet = ValueSet::Command(rCEvt); |
382 | |
|
383 | 0 | if (!bRet && rCEvt.GetCommand() == CommandEventId::ContextMenu) |
384 | 0 | { |
385 | 0 | bRet = mpParent->ShowContextMenu(rCEvt); |
386 | 0 | } |
387 | |
|
388 | 0 | return bRet; |
389 | 0 | } |
390 | | |
391 | | bool GalleryIconView::KeyInput(const KeyEvent& rKEvt) |
392 | 0 | { |
393 | 0 | if (!mpTheme || !mpParent->KeyInput(rKEvt)) |
394 | 0 | return ValueSet::KeyInput(rKEvt); |
395 | 0 | return true; |
396 | 0 | } |
397 | | |
398 | | bool GalleryIconView::StartDrag() |
399 | 0 | { |
400 | 0 | Select(); |
401 | 0 | return mpParent->StartDrag(); |
402 | 0 | } |
403 | | |
404 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |