bump product version to 4.1.6.2
[LibreOffice.git] / fpicker / source / win32 / filepicker / previewadapter.cxx
blob23aab44f834a9bcbe1b03ce9ef4994400187df7c
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 .
21 #include <tchar.h>
22 #include "previewadapter.hxx"
24 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
25 #include "dibpreview.hxx"
26 #include "../misc/WinImplHelper.hxx"
28 #include <memory>
29 #include <stdexcept>
31 //---------------------------------------------
33 //---------------------------------------------
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
38 //---------------------------------------------
39 // An impl class to hide implementation details
40 // from clients
41 //---------------------------------------------
43 class CPreviewAdapterImpl
45 public:
46 CPreviewAdapterImpl(HINSTANCE instance);
48 virtual ~CPreviewAdapterImpl();
50 virtual sal_Int32 SAL_CALL getTargetColorDepth();
52 virtual sal_Int32 SAL_CALL getAvailableWidth();
54 virtual sal_Int32 SAL_CALL getAvailableHeight();
56 virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const Any& aImage )
57 throw (IllegalArgumentException,RuntimeException);
59 virtual sal_Bool SAL_CALL setShowState(sal_Bool bShowState);
61 virtual sal_Bool SAL_CALL getShowState();
63 virtual void SAL_CALL setParent(HWND parent);
65 virtual HWND SAL_CALL getParent();
67 //-------------------------------------
68 // parent notification handler
69 //-------------------------------------
71 virtual void SAL_CALL notifyParentShow(sal_Bool bShow);
73 virtual void SAL_CALL notifyParentSizeChanged();
75 virtual void SAL_CALL notifyParentWindowPosChanged();
77 protected:
78 virtual void SAL_CALL calcRightMargin();
80 virtual void SAL_CALL rearrangeLayout();
82 void SAL_CALL initializeActivePreview() throw(std::runtime_error);
84 HWND SAL_CALL findFileListbox() const;
86 // member
87 protected:
88 HINSTANCE m_Instance;
89 std::auto_ptr<PreviewBase> m_Preview;
90 HWND m_FileDialog;
91 int m_RightMargin;
93 //prevent copy/assignment
94 private:
95 CPreviewAdapterImpl(const CPreviewAdapterImpl&);
96 CPreviewAdapterImpl& operator=(const CPreviewAdapterImpl&);
99 //-----------------------------------------
101 //-----------------------------------------
103 CPreviewAdapterImpl::CPreviewAdapterImpl(HINSTANCE instance) :
104 m_Instance(instance),
105 m_Preview(new PreviewBase()), // create dummy preview (NULL-Object pattern)
106 m_FileDialog(0),
107 m_RightMargin(0)
111 //-----------------------------------------
113 //-----------------------------------------
115 CPreviewAdapterImpl::~CPreviewAdapterImpl()
119 //-----------------------------------------
121 //-----------------------------------------
123 sal_Int32 SAL_CALL CPreviewAdapterImpl::getTargetColorDepth()
125 return m_Preview->getTargetColorDepth();
128 //-----------------------------------------
130 //-----------------------------------------
132 sal_Int32 SAL_CALL CPreviewAdapterImpl::getAvailableWidth()
134 return m_Preview->getAvailableWidth();
137 //-----------------------------------------
139 //-----------------------------------------
141 sal_Int32 SAL_CALL CPreviewAdapterImpl::getAvailableHeight()
143 return m_Preview->getAvailableHeight();
146 //-----------------------------------------
148 //-----------------------------------------
150 void SAL_CALL CPreviewAdapterImpl::setImage( sal_Int16 aImageFormat, const Any& aImage )
151 throw (IllegalArgumentException,RuntimeException)
153 m_Preview->setImage(aImageFormat,aImage);
156 //-----------------------------------------
158 //-----------------------------------------
160 sal_Bool SAL_CALL CPreviewAdapterImpl::setShowState( sal_Bool bShowState )
162 sal_Bool bRet = m_Preview->setShowState(bShowState);
163 rearrangeLayout();
164 return bRet;
167 //-----------------------------------------
169 //-----------------------------------------
171 sal_Bool SAL_CALL CPreviewAdapterImpl::getShowState()
173 return m_Preview->getShowState();
176 //-----------------------------------------
178 //-----------------------------------------
180 void SAL_CALL CPreviewAdapterImpl::setParent(HWND parent)
182 OSL_PRECOND(IsWindow(parent),"Invalid FileDialog handle");
184 m_FileDialog = parent;
185 calcRightMargin();
188 //-----------------------------------------
190 //-----------------------------------------
192 HWND SAL_CALL CPreviewAdapterImpl::getParent()
194 return m_FileDialog;
197 //-----------------------------------------
199 //-----------------------------------------
201 void SAL_CALL CPreviewAdapterImpl::calcRightMargin()
203 // Calculate the right reference margin
205 // Assumtions:
206 // 1. This method will be called before the dialog becomes
207 // visible
208 // 2. There exist a FileListbox with the id lst1 even
209 // if it is not visible like under Win2000/XP
210 // 3. Initially this FileListbox has the appropriate size
211 // to fit within the FileListbox
212 // 4. The margin between the right edge of the FileListbox
213 // and the right edge of the FileDialog will be constant
214 // even if the size of the dialog changes
216 HWND flb = GetDlgItem(m_FileDialog,lst1);
218 OSL_ENSURE(IsWindow(flb),"Filelistbox not found");
220 RECT rcFlb;
221 GetWindowRect(flb,&rcFlb);
223 RECT rcFileDlg;
224 GetWindowRect(m_FileDialog,&rcFileDlg);
226 m_RightMargin = rcFileDlg.right - rcFlb.right;
229 //-----------------------------------------
231 //-----------------------------------------
233 void SAL_CALL CPreviewAdapterImpl::notifyParentShow(sal_Bool)
237 //-----------------------------------------
239 //-----------------------------------------
241 void SAL_CALL CPreviewAdapterImpl::notifyParentSizeChanged()
243 rearrangeLayout();
246 //-----------------------------------------
248 //-----------------------------------------
250 void SAL_CALL CPreviewAdapterImpl::notifyParentWindowPosChanged()
254 //-----------------------------------------
256 //-----------------------------------------
258 void SAL_CALL CPreviewAdapterImpl::rearrangeLayout()
260 // try to get a handle to the filelistbox
261 // if there is no new-style filelistbox like
262 // in Win2000/XP there should be at least the
263 // old listbox, so we take this one
264 // lst1 - identifies the old-style filelistbox
265 // lst2 - identifies the new-style filelistbox
266 // see dlgs.h
267 HWND flb_new = findFileListbox();
269 // under Windows NT 4.0 the size of the old
270 // filelistbox will be used as reference for
271 // sizing the new filelistbox, so we have
272 // to change the size of it too
273 HWND flb_old = GetDlgItem(m_FileDialog,lst1);
275 RECT rcFlbNew;
276 GetWindowRect(flb_new,&rcFlbNew);
278 RECT rcFileDlg;
279 GetWindowRect(m_FileDialog,&rcFileDlg);
280 rcFileDlg.right -= m_RightMargin;
282 // the available area for the filelistbox should be
283 // the left edge of the filelistbox and the right
284 // edge of the OK button, we take this as reference
285 int height = rcFlbNew.bottom - rcFlbNew.top;
286 int width = rcFileDlg.right - rcFlbNew.left;
288 HWND prvwnd = m_Preview->getWindowHandle();
290 // we use GetWindowLong to ask for the visibility
291 // of the preview window because IsWindowVisible
292 // only returns true the specified window including
293 // its parent windows are visible
294 // this is not the case when we are called in response
295 // to the WM_SHOWWINDOW message, somehow the WS_VISIBLE
296 // style bit of the FileOpen dialog must be set after that
297 // message
298 LONG lStyle = GetWindowLong(prvwnd,GWL_STYLE);
299 bool bIsVisible = ((lStyle & WS_VISIBLE) != 0);
301 int cx = 0;
303 if (IsWindow(prvwnd) && bIsVisible)
305 cx = width/2;
307 // resize the filelistbox to the half of the
308 // available space
309 SetWindowPos(flb_new,
310 NULL, 0, 0, cx, height,
311 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
313 SetWindowPos(flb_old,
314 NULL, 0, 0, cx, height,
315 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
317 // get the new dimensions of the filelistbox after
318 // resizing and take the right,top corner as starting
319 // point for the preview window
320 GetWindowRect(flb_new,&rcFlbNew);
321 POINT pt = { rcFlbNew.right, rcFlbNew.top };
322 ScreenToClient(m_FileDialog,&pt);
324 // resize the preview window to fit within
325 // the available space and set the window
326 // to the top of the z-order else it will
327 // be invisible
328 SetWindowPos(prvwnd,
329 HWND_TOP, pt.x, pt.y, cx, height, SWP_NOACTIVATE);
331 else
333 // resize the filelistbox to the maximum available
334 // space
335 cx = rcFileDlg.right - rcFlbNew.left;
337 // resize the old filelistbox
338 SetWindowPos(flb_old,
339 NULL, 0, 0, cx, height,
340 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
342 // resize the new filelistbox
343 SetWindowPos(flb_new,
344 NULL, 0, 0, cx, height,
345 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
349 //-----------------------------------------
351 //-----------------------------------------
353 void SAL_CALL CPreviewAdapterImpl::initializeActivePreview() throw(std::runtime_error)
355 sal_Bool bShowState = m_Preview->getImaginaryShowState();
357 sal_Int16 aImgFrmt;
358 Any aImg;
359 m_Preview->getImage(aImgFrmt,aImg);
361 HWND flb = findFileListbox();
363 PreviewBase* prv = new CDIBPreview(
364 m_Instance, GetParent(flb), bShowState);
366 m_Preview.reset(prv);
368 m_Preview->setImage(aImgFrmt,aImg);
371 //-----------------------------------------
373 //-----------------------------------------
375 HWND SAL_CALL CPreviewAdapterImpl::findFileListbox() const
377 // try to get a handle to the filelistbox
378 // if there is no new-style filelistbox like
379 // in Win2000/XP there should be at least the
380 // old listbox, so we take this one
381 // lst1 - identifies the old-style filelistbox
382 // lst2 - identifies the new-style filelistbox
383 // see dlgs.h
384 HWND flb = GetDlgItem(m_FileDialog,lst2);
385 if (!IsWindow(flb))
386 flb = GetDlgItem(m_FileDialog,lst1);
388 return flb;
392 //##############################################################
395 //--------------------------------------------
396 // Implementation for Windows 95/NT/ME/2000/XP
397 // because:
399 //--------------------------------------------
401 class CWin95NTPreviewAdapterImpl : public CPreviewAdapterImpl
403 public:
404 CWin95NTPreviewAdapterImpl(HINSTANCE instance);
406 virtual void SAL_CALL notifyParentShow(sal_Bool bShow);
409 //--------------------------------------------
411 //--------------------------------------------
413 CWin95NTPreviewAdapterImpl::CWin95NTPreviewAdapterImpl(HINSTANCE instance) :
414 CPreviewAdapterImpl(instance)
418 //--------------------------------------------
420 //--------------------------------------------
422 void SAL_CALL CWin95NTPreviewAdapterImpl::notifyParentShow(sal_Bool bShow)
426 if (bShow)
428 initializeActivePreview();
429 rearrangeLayout();
432 catch(std::runtime_error&)
438 //##############################################################
441 //-------------------------------
442 // ctor
443 //-------------------------------
445 CPreviewAdapter::CPreviewAdapter(HINSTANCE instance)
447 m_pImpl.reset(new CWin95NTPreviewAdapterImpl(instance));
450 //-------------------------------
452 //-------------------------------
454 CPreviewAdapter::~CPreviewAdapter()
458 //-------------------------------
460 //-------------------------------
462 Sequence<sal_Int16> SAL_CALL CPreviewAdapter::getSupportedImageFormats()
464 com::sun::star::uno::Sequence<sal_Int16> imgFormats(1);
465 imgFormats[0] = ::com::sun::star::ui::dialogs::FilePreviewImageFormats::BITMAP;
466 return imgFormats;
469 //-------------------------------
471 //-------------------------------
473 sal_Int32 SAL_CALL CPreviewAdapter::getTargetColorDepth()
475 return m_pImpl->getTargetColorDepth();
478 //-------------------------------
480 //-------------------------------
482 sal_Int32 SAL_CALL CPreviewAdapter::getAvailableWidth()
484 return m_pImpl->getAvailableWidth();
487 //-------------------------------
489 //-------------------------------
491 sal_Int32 SAL_CALL CPreviewAdapter::getAvailableHeight()
493 return m_pImpl->getAvailableHeight();
496 //-------------------------------
498 //-------------------------------
500 void SAL_CALL CPreviewAdapter::setImage( sal_Int16 aImageFormat, const Any& aImage )
501 throw (IllegalArgumentException, RuntimeException)
503 m_pImpl->setImage(aImageFormat,aImage);
506 //-------------------------------
508 //-------------------------------
510 sal_Bool SAL_CALL CPreviewAdapter::setShowState( sal_Bool bShowState )
512 return m_pImpl->setShowState(bShowState);
515 //-------------------------------
517 //-------------------------------
519 sal_Bool SAL_CALL CPreviewAdapter::getShowState()
521 return m_pImpl->getShowState();
524 //-------------------------------
526 //-------------------------------
528 void SAL_CALL CPreviewAdapter::setParent(HWND parent)
530 m_pImpl->setParent(parent);
533 //-------------------------------
535 //-------------------------------
537 void SAL_CALL CPreviewAdapter::notifyParentShow(bool bShow)
539 m_pImpl->notifyParentShow(bShow);
542 //-------------------------------
544 //-------------------------------
546 void SAL_CALL CPreviewAdapter::notifyParentSizeChanged()
548 m_pImpl->notifyParentSizeChanged();
551 //-------------------------------
553 //-------------------------------
555 void SAL_CALL CPreviewAdapter::notifyParentWindowPosChanged()
557 m_pImpl->notifyParentWindowPosChanged();
560 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */