1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: previewadapter.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_fpicker.hxx"
35 #include "previewadapter.hxx"
37 #ifndef _COM_SUN_STAR_UI_DIALOG_FILEPREVIEWIMAGEFORMATS_HPP_
38 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
40 #include "dibpreview.hxx"
41 #include "../misc/WinImplHelper.hxx"
46 //---------------------------------------------
48 //---------------------------------------------
50 using namespace ::com::sun::star::uno
;
51 using namespace ::com::sun::star::lang
;
53 //---------------------------------------------
54 // An impl class to hide implementation details
56 //---------------------------------------------
58 class CPreviewAdapterImpl
61 CPreviewAdapterImpl(HINSTANCE instance
);
63 virtual ~CPreviewAdapterImpl();
65 virtual sal_Int32 SAL_CALL
getTargetColorDepth();
67 virtual sal_Int32 SAL_CALL
getAvailableWidth();
69 virtual sal_Int32 SAL_CALL
getAvailableHeight();
71 virtual void SAL_CALL
setImage( sal_Int16 aImageFormat
, const Any
& aImage
)
72 throw (IllegalArgumentException
,RuntimeException
);
74 virtual sal_Bool SAL_CALL
setShowState(sal_Bool bShowState
);
76 virtual sal_Bool SAL_CALL
getShowState();
78 virtual void SAL_CALL
setParent(HWND parent
);
80 virtual HWND SAL_CALL
getParent();
82 //-------------------------------------
83 // parent notification handler
84 //-------------------------------------
86 virtual void SAL_CALL
notifyParentShow(sal_Bool bShow
);
88 virtual void SAL_CALL
notifyParentSizeChanged();
90 virtual void SAL_CALL
notifyParentWindowPosChanged();
93 virtual void SAL_CALL
calcRightMargin();
95 virtual void SAL_CALL
rearrangeLayout();
97 void SAL_CALL
initializeActivePreview() throw(std::runtime_error
);
99 HWND SAL_CALL
findFileListbox() const;
103 HINSTANCE m_Instance
;
104 std::auto_ptr
<PreviewBase
> m_Preview
;
108 //prevent copy/assignment
110 CPreviewAdapterImpl(const CPreviewAdapterImpl
&);
111 CPreviewAdapterImpl
& operator=(const CPreviewAdapterImpl
&);
114 //-----------------------------------------
116 //-----------------------------------------
118 CPreviewAdapterImpl::CPreviewAdapterImpl(HINSTANCE instance
) :
119 m_Instance(instance
),
120 m_Preview(new PreviewBase()), // create dummy preview (NULL-Object pattern)
126 //-----------------------------------------
128 //-----------------------------------------
130 CPreviewAdapterImpl::~CPreviewAdapterImpl()
134 //-----------------------------------------
136 //-----------------------------------------
138 sal_Int32 SAL_CALL
CPreviewAdapterImpl::getTargetColorDepth()
140 return m_Preview
->getTargetColorDepth();
143 //-----------------------------------------
145 //-----------------------------------------
147 sal_Int32 SAL_CALL
CPreviewAdapterImpl::getAvailableWidth()
149 return m_Preview
->getAvailableWidth();
152 //-----------------------------------------
154 //-----------------------------------------
156 sal_Int32 SAL_CALL
CPreviewAdapterImpl::getAvailableHeight()
158 return m_Preview
->getAvailableHeight();
161 //-----------------------------------------
163 //-----------------------------------------
165 void SAL_CALL
CPreviewAdapterImpl::setImage( sal_Int16 aImageFormat
, const Any
& aImage
)
166 throw (IllegalArgumentException
,RuntimeException
)
168 m_Preview
->setImage(aImageFormat
,aImage
);
171 //-----------------------------------------
173 //-----------------------------------------
175 sal_Bool SAL_CALL
CPreviewAdapterImpl::setShowState( sal_Bool bShowState
)
177 sal_Bool bRet
= m_Preview
->setShowState(bShowState
);
182 //-----------------------------------------
184 //-----------------------------------------
186 sal_Bool SAL_CALL
CPreviewAdapterImpl::getShowState()
188 return m_Preview
->getShowState();
191 //-----------------------------------------
193 //-----------------------------------------
195 void SAL_CALL
CPreviewAdapterImpl::setParent(HWND parent
)
197 OSL_PRECOND(IsWindow(parent
),"Invalid FileDialog handle");
199 m_FileDialog
= parent
;
203 //-----------------------------------------
205 //-----------------------------------------
207 HWND SAL_CALL
CPreviewAdapterImpl::getParent()
212 //-----------------------------------------
214 //-----------------------------------------
216 void SAL_CALL
CPreviewAdapterImpl::calcRightMargin()
218 // Calculate the right reference margin
221 // 1. This method will be called before the dialog becomes
223 // 2. There exist a FileListbox with the id lst1 even
224 // if it is not visible like under Win2000/XP
225 // 3. Initially this FileListbox has the appropriate size
226 // to fit within the FileListbox
227 // 4. The margin between the right edge of the FileListbox
228 // and the right edge of the FileDialog will be constant
229 // even if the size of the dialog changes
231 HWND flb
= GetDlgItem(m_FileDialog
,lst1
);
233 OSL_ENSURE(IsWindow(flb
),"Filelistbox not found");
236 GetWindowRect(flb
,&rcFlb
);
239 GetWindowRect(m_FileDialog
,&rcFileDlg
);
241 m_RightMargin
= rcFileDlg
.right
- rcFlb
.right
;
244 //-----------------------------------------
246 //-----------------------------------------
248 void SAL_CALL
CPreviewAdapterImpl::notifyParentShow(sal_Bool
)
252 //-----------------------------------------
254 //-----------------------------------------
256 void SAL_CALL
CPreviewAdapterImpl::notifyParentSizeChanged()
261 //-----------------------------------------
263 //-----------------------------------------
265 void SAL_CALL
CPreviewAdapterImpl::notifyParentWindowPosChanged()
269 //-----------------------------------------
271 //-----------------------------------------
273 void SAL_CALL
CPreviewAdapterImpl::rearrangeLayout()
275 // try to get a handle to the filelistbox
276 // if there is no new-style filelistbox like
277 // in Win2000/XP there should be at least the
278 // old listbox, so we take this one
279 // lst1 - identifies the old-style filelistbox
280 // lst2 - identifies the new-style filelistbox
282 HWND flb_new
= findFileListbox();
284 // under Windows NT 4.0 the size of the old
285 // filelistbox will be used as reference for
286 // sizing the new filelistbox, so we have
287 // to change the size of it too
288 HWND flb_old
= GetDlgItem(m_FileDialog
,lst1
);
291 GetWindowRect(flb_new
,&rcFlbNew
);
294 GetWindowRect(m_FileDialog
,&rcFileDlg
);
295 rcFileDlg
.right
-= m_RightMargin
;
297 // the available area for the filelistbox should be
298 // the left edge of the filelistbox and the right
299 // edge of the OK button, we take this as reference
300 int height
= rcFlbNew
.bottom
- rcFlbNew
.top
;
301 int width
= rcFileDlg
.right
- rcFlbNew
.left
;
303 HWND prvwnd
= m_Preview
->getWindowHandle();
305 // we use GetWindowLong to ask for the visibility
306 // of the preview window because IsWindowVisible
307 // only returns true the specified window including
308 // its parent windows are visible
309 // this is not the case when we are called in response
310 // to the WM_SHOWWINDOW message, somehow the WS_VISIBLE
311 // style bit of the FileOpen dialog must be set after that
313 LONG lStyle
= GetWindowLong(prvwnd
,GWL_STYLE
);
314 BOOL bIsVisible
= (BOOL
)(lStyle
& WS_VISIBLE
);
318 if (IsWindow(prvwnd
) && bIsVisible
)
322 // resize the filelistbox to the half of the
324 BOOL bRet
= SetWindowPos(flb_new
,
325 NULL
, 0, 0, cx
, height
,
326 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
328 bRet
= SetWindowPos(flb_old
,
329 NULL
, 0, 0, cx
, height
,
330 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
332 // get the new dimensions of the filelistbox after
333 // resizing and take the right,top corner as starting
334 // point for the preview window
335 GetWindowRect(flb_new
,&rcFlbNew
);
336 POINT pt
= { rcFlbNew
.right
, rcFlbNew
.top
};
337 ScreenToClient(m_FileDialog
,&pt
);
339 // resize the preview window to fit within
340 // the available space and set the window
341 // to the top of the z-order else it will
344 HWND_TOP
, pt
.x
, pt
.y
, cx
, height
, SWP_NOACTIVATE
);
348 // resize the filelistbox to the maximum available
350 cx
= rcFileDlg
.right
- rcFlbNew
.left
;
352 // resize the old filelistbox
353 SetWindowPos(flb_old
,
354 NULL
, 0, 0, cx
, height
,
355 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
357 // resize the new filelistbox
358 SetWindowPos(flb_new
,
359 NULL
, 0, 0, cx
, height
,
360 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
364 //-----------------------------------------
366 //-----------------------------------------
368 void SAL_CALL
CPreviewAdapterImpl::initializeActivePreview() throw(std::runtime_error
)
370 sal_Bool bShowState
= m_Preview
->getImaginaryShowState();
374 m_Preview
->getImage(aImgFrmt
,aImg
);
376 HWND flb
= findFileListbox();
378 PreviewBase
* prv
= new CDIBPreview(
379 m_Instance
, GetParent(flb
), bShowState
);
381 m_Preview
.reset(prv
);
383 m_Preview
->setImage(aImgFrmt
,aImg
);
386 //-----------------------------------------
388 //-----------------------------------------
390 HWND SAL_CALL
CPreviewAdapterImpl::findFileListbox() const
392 // try to get a handle to the filelistbox
393 // if there is no new-style filelistbox like
394 // in Win2000/XP there should be at least the
395 // old listbox, so we take this one
396 // lst1 - identifies the old-style filelistbox
397 // lst2 - identifies the new-style filelistbox
399 HWND flb
= GetDlgItem(m_FileDialog
,lst2
);
401 flb
= GetDlgItem(m_FileDialog
,lst1
);
407 //##############################################################
410 //-----------------------------------------
411 // Special implementation for Win98
414 //-----------------------------------------
416 class CWin98PreviewAdapterImpl
: public CPreviewAdapterImpl
419 CWin98PreviewAdapterImpl(HINSTANCE instance
);
421 virtual void SAL_CALL
notifyParentWindowPosChanged();
424 virtual void SAL_CALL
rearrangeLayout();
426 bool isValidToolbarDimension() const;
429 sal_Bool m_PreviewActive
;
436 //--------------------------------------------
438 //--------------------------------------------
440 CWin98PreviewAdapterImpl::CWin98PreviewAdapterImpl(HINSTANCE instance
) :
441 CPreviewAdapterImpl(instance
),
442 m_PreviewActive(sal_False
),
450 //--------------------------------------------
452 //--------------------------------------------
454 void SAL_CALL
CWin98PreviewAdapterImpl::notifyParentWindowPosChanged()
458 // the reason for this condition is
460 // Under Windows 98 the message WM_SHOWWINDOW
461 // will be sent only the first time the
462 // GetOpenFileName function is called within
464 // so we must use another message to initialize
465 // the preview window
466 if (IsWindow(m_FileDialog
) && !m_PreviewActive
)
468 initializeActivePreview();
469 m_PreviewActive
= sal_True
;
473 if (IsWindow(m_FileDialog
) && !isValidToolbarDimension())
476 GetWindowRect(GetDlgItem(m_FileDialog
,stc1
),&rcStc1
);
479 GetWindowRect(GetDlgItem(m_FileDialog
,cmb2
),&rcCmb2
);
482 // the toolbar position is only valid
483 // if the left edge is greater or equal
484 // than the right edge of the drives listbox
485 // the stc1 static text is invisible at runtime
486 // but will be used as reference for the position
487 // and dimension of the toolbar
488 if (rcStc1
.left
>= rcCmb2
.right
)
490 // important: save the upper left corner in
491 // client coordinates
492 POINT pt
= {rcStc1
.left
,rcStc1
.top
};
493 ScreenToClient(m_FileDialog
,&pt
);
495 m_ToolbarPosX
= pt
.x
;
496 m_ToolbarPosY
= pt
.y
;
497 m_ToolbarWidth
= rcStc1
.right
- rcStc1
.left
;
498 m_ToolbarHeight
= rcStc1
.bottom
- rcStc1
.top
;
502 catch(std::runtime_error
&)
507 //--------------------------------------------
509 //--------------------------------------------
511 void SAL_CALL
CWin98PreviewAdapterImpl::rearrangeLayout()
513 CPreviewAdapterImpl::rearrangeLayout();
515 // fix the position of the upper toolbar
516 // because the FileDialog moves all windows
517 // that are to the right of the FileListbox
518 // so if we have changed the size of the
519 // FileListbox we would run into trouble else
520 if (isValidToolbarDimension())
522 HWND hwndTlb
= FindWindowEx(
523 m_FileDialog
,NULL
,TEXT("ToolbarWindow32"),NULL
);
525 SetWindowPos(hwndTlb
,
535 //--------------------------------------------
537 //--------------------------------------------
539 bool CWin98PreviewAdapterImpl::isValidToolbarDimension() const
541 return (m_ToolbarPosX
> 0 &&
543 m_ToolbarWidth
> 0 &&
544 m_ToolbarHeight
> 0);
547 //##############################################################
550 //--------------------------------------------
551 // Implementation for Windows 95/NT/ME/2000/XP
554 //--------------------------------------------
556 class CWin95NTPreviewAdapterImpl
: public CPreviewAdapterImpl
559 CWin95NTPreviewAdapterImpl(HINSTANCE instance
);
561 virtual void SAL_CALL
notifyParentShow(sal_Bool bShow
);
564 //--------------------------------------------
566 //--------------------------------------------
568 CWin95NTPreviewAdapterImpl::CWin95NTPreviewAdapterImpl(HINSTANCE instance
) :
569 CPreviewAdapterImpl(instance
)
573 //--------------------------------------------
575 //--------------------------------------------
577 void SAL_CALL
CWin95NTPreviewAdapterImpl::notifyParentShow(sal_Bool bShow
)
583 initializeActivePreview();
587 catch(std::runtime_error
&)
593 //##############################################################
596 //-------------------------------
598 //-------------------------------
600 CPreviewAdapter::CPreviewAdapter(HINSTANCE instance
)
603 m_pImpl
.reset(new CWin95NTPreviewAdapterImpl(instance
));
605 m_pImpl
.reset(new CWin98PreviewAdapterImpl(instance
));
608 //-------------------------------
610 //-------------------------------
612 CPreviewAdapter::~CPreviewAdapter()
616 //-------------------------------
618 //-------------------------------
620 Sequence
<sal_Int16
> SAL_CALL
CPreviewAdapter::getSupportedImageFormats()
622 com::sun::star::uno::Sequence
<sal_Int16
> imgFormats(1);
623 imgFormats
[0] = ::com::sun::star::ui::dialogs::FilePreviewImageFormats::BITMAP
;
627 //-------------------------------
629 //-------------------------------
631 sal_Int32 SAL_CALL
CPreviewAdapter::getTargetColorDepth()
633 return m_pImpl
->getTargetColorDepth();
636 //-------------------------------
638 //-------------------------------
640 sal_Int32 SAL_CALL
CPreviewAdapter::getAvailableWidth()
642 return m_pImpl
->getAvailableWidth();
645 //-------------------------------
647 //-------------------------------
649 sal_Int32 SAL_CALL
CPreviewAdapter::getAvailableHeight()
651 return m_pImpl
->getAvailableHeight();
654 //-------------------------------
656 //-------------------------------
658 void SAL_CALL
CPreviewAdapter::setImage( sal_Int16 aImageFormat
, const Any
& aImage
)
659 throw (IllegalArgumentException
, RuntimeException
)
661 m_pImpl
->setImage(aImageFormat
,aImage
);
664 //-------------------------------
666 //-------------------------------
668 sal_Bool SAL_CALL
CPreviewAdapter::setShowState( sal_Bool bShowState
)
670 return m_pImpl
->setShowState(bShowState
);
673 //-------------------------------
675 //-------------------------------
677 sal_Bool SAL_CALL
CPreviewAdapter::getShowState()
679 return m_pImpl
->getShowState();
682 //-------------------------------
684 //-------------------------------
686 void SAL_CALL
CPreviewAdapter::setParent(HWND parent
)
688 m_pImpl
->setParent(parent
);
691 //-------------------------------
693 //-------------------------------
695 void SAL_CALL
CPreviewAdapter::notifyParentShow(bool bShow
)
697 m_pImpl
->notifyParentShow(bShow
);
700 //-------------------------------
702 //-------------------------------
704 void SAL_CALL
CPreviewAdapter::notifyParentSizeChanged()
706 m_pImpl
->notifyParentSizeChanged();
709 //-------------------------------
711 //-------------------------------
713 void SAL_CALL
CPreviewAdapter::notifyParentWindowPosChanged()
715 m_pImpl
->notifyParentWindowPosChanged();