1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_fpicker.hxx"
32 #include "previewadapter.hxx"
34 #ifndef _COM_SUN_STAR_UI_DIALOG_FILEPREVIEWIMAGEFORMATS_HPP_
35 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
37 #include "dibpreview.hxx"
38 #include "../misc/WinImplHelper.hxx"
43 //---------------------------------------------
45 //---------------------------------------------
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::lang
;
50 //---------------------------------------------
51 // An impl class to hide implementation details
53 //---------------------------------------------
55 class CPreviewAdapterImpl
58 CPreviewAdapterImpl(HINSTANCE instance
);
60 virtual ~CPreviewAdapterImpl();
62 virtual sal_Int32 SAL_CALL
getTargetColorDepth();
64 virtual sal_Int32 SAL_CALL
getAvailableWidth();
66 virtual sal_Int32 SAL_CALL
getAvailableHeight();
68 virtual void SAL_CALL
setImage( sal_Int16 aImageFormat
, const Any
& aImage
)
69 throw (IllegalArgumentException
,RuntimeException
);
71 virtual sal_Bool SAL_CALL
setShowState(sal_Bool bShowState
);
73 virtual sal_Bool SAL_CALL
getShowState();
75 virtual void SAL_CALL
setParent(HWND parent
);
77 virtual HWND SAL_CALL
getParent();
79 //-------------------------------------
80 // parent notification handler
81 //-------------------------------------
83 virtual void SAL_CALL
notifyParentShow(sal_Bool bShow
);
85 virtual void SAL_CALL
notifyParentSizeChanged();
87 virtual void SAL_CALL
notifyParentWindowPosChanged();
90 virtual void SAL_CALL
calcRightMargin();
92 virtual void SAL_CALL
rearrangeLayout();
94 void SAL_CALL
initializeActivePreview() throw(std::runtime_error
);
96 HWND SAL_CALL
findFileListbox() const;
100 HINSTANCE m_Instance
;
101 std::auto_ptr
<PreviewBase
> m_Preview
;
105 //prevent copy/assignment
107 CPreviewAdapterImpl(const CPreviewAdapterImpl
&);
108 CPreviewAdapterImpl
& operator=(const CPreviewAdapterImpl
&);
111 //-----------------------------------------
113 //-----------------------------------------
115 CPreviewAdapterImpl::CPreviewAdapterImpl(HINSTANCE instance
) :
116 m_Instance(instance
),
117 m_Preview(new PreviewBase()), // create dummy preview (NULL-Object pattern)
123 //-----------------------------------------
125 //-----------------------------------------
127 CPreviewAdapterImpl::~CPreviewAdapterImpl()
131 //-----------------------------------------
133 //-----------------------------------------
135 sal_Int32 SAL_CALL
CPreviewAdapterImpl::getTargetColorDepth()
137 return m_Preview
->getTargetColorDepth();
140 //-----------------------------------------
142 //-----------------------------------------
144 sal_Int32 SAL_CALL
CPreviewAdapterImpl::getAvailableWidth()
146 return m_Preview
->getAvailableWidth();
149 //-----------------------------------------
151 //-----------------------------------------
153 sal_Int32 SAL_CALL
CPreviewAdapterImpl::getAvailableHeight()
155 return m_Preview
->getAvailableHeight();
158 //-----------------------------------------
160 //-----------------------------------------
162 void SAL_CALL
CPreviewAdapterImpl::setImage( sal_Int16 aImageFormat
, const Any
& aImage
)
163 throw (IllegalArgumentException
,RuntimeException
)
165 m_Preview
->setImage(aImageFormat
,aImage
);
168 //-----------------------------------------
170 //-----------------------------------------
172 sal_Bool SAL_CALL
CPreviewAdapterImpl::setShowState( sal_Bool bShowState
)
174 sal_Bool bRet
= m_Preview
->setShowState(bShowState
);
179 //-----------------------------------------
181 //-----------------------------------------
183 sal_Bool SAL_CALL
CPreviewAdapterImpl::getShowState()
185 return m_Preview
->getShowState();
188 //-----------------------------------------
190 //-----------------------------------------
192 void SAL_CALL
CPreviewAdapterImpl::setParent(HWND parent
)
194 OSL_PRECOND(IsWindow(parent
),"Invalid FileDialog handle");
196 m_FileDialog
= parent
;
200 //-----------------------------------------
202 //-----------------------------------------
204 HWND SAL_CALL
CPreviewAdapterImpl::getParent()
209 //-----------------------------------------
211 //-----------------------------------------
213 void SAL_CALL
CPreviewAdapterImpl::calcRightMargin()
215 // Calculate the right reference margin
218 // 1. This method will be called before the dialog becomes
220 // 2. There exist a FileListbox with the id lst1 even
221 // if it is not visible like under Win2000/XP
222 // 3. Initially this FileListbox has the appropriate size
223 // to fit within the FileListbox
224 // 4. The margin between the right edge of the FileListbox
225 // and the right edge of the FileDialog will be constant
226 // even if the size of the dialog changes
228 HWND flb
= GetDlgItem(m_FileDialog
,lst1
);
230 OSL_ENSURE(IsWindow(flb
),"Filelistbox not found");
233 GetWindowRect(flb
,&rcFlb
);
236 GetWindowRect(m_FileDialog
,&rcFileDlg
);
238 m_RightMargin
= rcFileDlg
.right
- rcFlb
.right
;
241 //-----------------------------------------
243 //-----------------------------------------
245 void SAL_CALL
CPreviewAdapterImpl::notifyParentShow(sal_Bool
)
249 //-----------------------------------------
251 //-----------------------------------------
253 void SAL_CALL
CPreviewAdapterImpl::notifyParentSizeChanged()
258 //-----------------------------------------
260 //-----------------------------------------
262 void SAL_CALL
CPreviewAdapterImpl::notifyParentWindowPosChanged()
266 //-----------------------------------------
268 //-----------------------------------------
270 void SAL_CALL
CPreviewAdapterImpl::rearrangeLayout()
272 // try to get a handle to the filelistbox
273 // if there is no new-style filelistbox like
274 // in Win2000/XP there should be at least the
275 // old listbox, so we take this one
276 // lst1 - identifies the old-style filelistbox
277 // lst2 - identifies the new-style filelistbox
279 HWND flb_new
= findFileListbox();
281 // under Windows NT 4.0 the size of the old
282 // filelistbox will be used as reference for
283 // sizing the new filelistbox, so we have
284 // to change the size of it too
285 HWND flb_old
= GetDlgItem(m_FileDialog
,lst1
);
288 GetWindowRect(flb_new
,&rcFlbNew
);
291 GetWindowRect(m_FileDialog
,&rcFileDlg
);
292 rcFileDlg
.right
-= m_RightMargin
;
294 // the available area for the filelistbox should be
295 // the left edge of the filelistbox and the right
296 // edge of the OK button, we take this as reference
297 int height
= rcFlbNew
.bottom
- rcFlbNew
.top
;
298 int width
= rcFileDlg
.right
- rcFlbNew
.left
;
300 HWND prvwnd
= m_Preview
->getWindowHandle();
302 // we use GetWindowLong to ask for the visibility
303 // of the preview window because IsWindowVisible
304 // only returns true the specified window including
305 // its parent windows are visible
306 // this is not the case when we are called in response
307 // to the WM_SHOWWINDOW message, somehow the WS_VISIBLE
308 // style bit of the FileOpen dialog must be set after that
310 LONG lStyle
= GetWindowLong(prvwnd
,GWL_STYLE
);
311 sal_Bool bIsVisible
= (sal_Bool
)(lStyle
& WS_VISIBLE
);
315 if (IsWindow(prvwnd
) && bIsVisible
)
319 // resize the filelistbox to the half of the
321 bool bRet
= SetWindowPos(flb_new
,
322 NULL
, 0, 0, cx
, height
,
323 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
325 bRet
= SetWindowPos(flb_old
,
326 NULL
, 0, 0, cx
, height
,
327 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
329 // get the new dimensions of the filelistbox after
330 // resizing and take the right,top corner as starting
331 // point for the preview window
332 GetWindowRect(flb_new
,&rcFlbNew
);
333 POINT pt
= { rcFlbNew
.right
, rcFlbNew
.top
};
334 ScreenToClient(m_FileDialog
,&pt
);
336 // resize the preview window to fit within
337 // the available space and set the window
338 // to the top of the z-order else it will
341 HWND_TOP
, pt
.x
, pt
.y
, cx
, height
, SWP_NOACTIVATE
);
345 // resize the filelistbox to the maximum available
347 cx
= rcFileDlg
.right
- rcFlbNew
.left
;
349 // resize the old filelistbox
350 SetWindowPos(flb_old
,
351 NULL
, 0, 0, cx
, height
,
352 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
354 // resize the new filelistbox
355 SetWindowPos(flb_new
,
356 NULL
, 0, 0, cx
, height
,
357 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
361 //-----------------------------------------
363 //-----------------------------------------
365 void SAL_CALL
CPreviewAdapterImpl::initializeActivePreview() throw(std::runtime_error
)
367 sal_Bool bShowState
= m_Preview
->getImaginaryShowState();
371 m_Preview
->getImage(aImgFrmt
,aImg
);
373 HWND flb
= findFileListbox();
375 PreviewBase
* prv
= new CDIBPreview(
376 m_Instance
, GetParent(flb
), bShowState
);
378 m_Preview
.reset(prv
);
380 m_Preview
->setImage(aImgFrmt
,aImg
);
383 //-----------------------------------------
385 //-----------------------------------------
387 HWND SAL_CALL
CPreviewAdapterImpl::findFileListbox() const
389 // try to get a handle to the filelistbox
390 // if there is no new-style filelistbox like
391 // in Win2000/XP there should be at least the
392 // old listbox, so we take this one
393 // lst1 - identifies the old-style filelistbox
394 // lst2 - identifies the new-style filelistbox
396 HWND flb
= GetDlgItem(m_FileDialog
,lst2
);
398 flb
= GetDlgItem(m_FileDialog
,lst1
);
404 //##############################################################
407 //-----------------------------------------
408 // Special implementation for Win98
411 //-----------------------------------------
413 class CWin98PreviewAdapterImpl
: public CPreviewAdapterImpl
416 CWin98PreviewAdapterImpl(HINSTANCE instance
);
418 virtual void SAL_CALL
notifyParentWindowPosChanged();
421 virtual void SAL_CALL
rearrangeLayout();
423 bool isValidToolbarDimension() const;
426 sal_Bool m_PreviewActive
;
433 //--------------------------------------------
435 //--------------------------------------------
437 CWin98PreviewAdapterImpl::CWin98PreviewAdapterImpl(HINSTANCE instance
) :
438 CPreviewAdapterImpl(instance
),
439 m_PreviewActive(sal_False
),
447 //--------------------------------------------
449 //--------------------------------------------
451 void SAL_CALL
CWin98PreviewAdapterImpl::notifyParentWindowPosChanged()
455 // the reason for this condition is
457 // Under Windows 98 the message WM_SHOWWINDOW
458 // will be sent only the first time the
459 // GetOpenFileName function is called within
461 // so we must use another message to initialize
462 // the preview window
463 if (IsWindow(m_FileDialog
) && !m_PreviewActive
)
465 initializeActivePreview();
466 m_PreviewActive
= sal_True
;
470 if (IsWindow(m_FileDialog
) && !isValidToolbarDimension())
473 GetWindowRect(GetDlgItem(m_FileDialog
,stc1
),&rcStc1
);
476 GetWindowRect(GetDlgItem(m_FileDialog
,cmb2
),&rcCmb2
);
479 // the toolbar position is only valid
480 // if the left edge is greater or equal
481 // than the right edge of the drives listbox
482 // the stc1 static text is invisible at runtime
483 // but will be used as reference for the position
484 // and dimension of the toolbar
485 if (rcStc1
.left
>= rcCmb2
.right
)
487 // important: save the upper left corner in
488 // client coordinates
489 POINT pt
= {rcStc1
.left
,rcStc1
.top
};
490 ScreenToClient(m_FileDialog
,&pt
);
492 m_ToolbarPosX
= pt
.x
;
493 m_ToolbarPosY
= pt
.y
;
494 m_ToolbarWidth
= rcStc1
.right
- rcStc1
.left
;
495 m_ToolbarHeight
= rcStc1
.bottom
- rcStc1
.top
;
499 catch(std::runtime_error
&)
504 //--------------------------------------------
506 //--------------------------------------------
508 void SAL_CALL
CWin98PreviewAdapterImpl::rearrangeLayout()
510 CPreviewAdapterImpl::rearrangeLayout();
512 // fix the position of the upper toolbar
513 // because the FileDialog moves all windows
514 // that are to the right of the FileListbox
515 // so if we have changed the size of the
516 // FileListbox we would run into trouble else
517 if (isValidToolbarDimension())
519 HWND hwndTlb
= FindWindowEx(
520 m_FileDialog
,NULL
,TEXT("ToolbarWindow32"),NULL
);
522 SetWindowPos(hwndTlb
,
532 //--------------------------------------------
534 //--------------------------------------------
536 bool CWin98PreviewAdapterImpl::isValidToolbarDimension() const
538 return (m_ToolbarPosX
> 0 &&
540 m_ToolbarWidth
> 0 &&
541 m_ToolbarHeight
> 0);
544 //##############################################################
547 //--------------------------------------------
548 // Implementation for Windows 95/NT/ME/2000/XP
551 //--------------------------------------------
553 class CWin95NTPreviewAdapterImpl
: public CPreviewAdapterImpl
556 CWin95NTPreviewAdapterImpl(HINSTANCE instance
);
558 virtual void SAL_CALL
notifyParentShow(sal_Bool bShow
);
561 //--------------------------------------------
563 //--------------------------------------------
565 CWin95NTPreviewAdapterImpl::CWin95NTPreviewAdapterImpl(HINSTANCE instance
) :
566 CPreviewAdapterImpl(instance
)
570 //--------------------------------------------
572 //--------------------------------------------
574 void SAL_CALL
CWin95NTPreviewAdapterImpl::notifyParentShow(sal_Bool bShow
)
580 initializeActivePreview();
584 catch(std::runtime_error
&)
590 //##############################################################
593 //-------------------------------
595 //-------------------------------
597 CPreviewAdapter::CPreviewAdapter(HINSTANCE instance
)
600 m_pImpl
.reset(new CWin95NTPreviewAdapterImpl(instance
));
602 m_pImpl
.reset(new CWin98PreviewAdapterImpl(instance
));
605 //-------------------------------
607 //-------------------------------
609 CPreviewAdapter::~CPreviewAdapter()
613 //-------------------------------
615 //-------------------------------
617 Sequence
<sal_Int16
> SAL_CALL
CPreviewAdapter::getSupportedImageFormats()
619 com::sun::star::uno::Sequence
<sal_Int16
> imgFormats(1);
620 imgFormats
[0] = ::com::sun::star::ui::dialogs::FilePreviewImageFormats::BITMAP
;
624 //-------------------------------
626 //-------------------------------
628 sal_Int32 SAL_CALL
CPreviewAdapter::getTargetColorDepth()
630 return m_pImpl
->getTargetColorDepth();
633 //-------------------------------
635 //-------------------------------
637 sal_Int32 SAL_CALL
CPreviewAdapter::getAvailableWidth()
639 return m_pImpl
->getAvailableWidth();
642 //-------------------------------
644 //-------------------------------
646 sal_Int32 SAL_CALL
CPreviewAdapter::getAvailableHeight()
648 return m_pImpl
->getAvailableHeight();
651 //-------------------------------
653 //-------------------------------
655 void SAL_CALL
CPreviewAdapter::setImage( sal_Int16 aImageFormat
, const Any
& aImage
)
656 throw (IllegalArgumentException
, RuntimeException
)
658 m_pImpl
->setImage(aImageFormat
,aImage
);
661 //-------------------------------
663 //-------------------------------
665 sal_Bool SAL_CALL
CPreviewAdapter::setShowState( sal_Bool bShowState
)
667 return m_pImpl
->setShowState(bShowState
);
670 //-------------------------------
672 //-------------------------------
674 sal_Bool SAL_CALL
CPreviewAdapter::getShowState()
676 return m_pImpl
->getShowState();
679 //-------------------------------
681 //-------------------------------
683 void SAL_CALL
CPreviewAdapter::setParent(HWND parent
)
685 m_pImpl
->setParent(parent
);
688 //-------------------------------
690 //-------------------------------
692 void SAL_CALL
CPreviewAdapter::notifyParentShow(bool bShow
)
694 m_pImpl
->notifyParentShow(bShow
);
697 //-------------------------------
699 //-------------------------------
701 void SAL_CALL
CPreviewAdapter::notifyParentSizeChanged()
703 m_pImpl
->notifyParentSizeChanged();
706 //-------------------------------
708 //-------------------------------
710 void SAL_CALL
CPreviewAdapter::notifyParentWindowPosChanged()
712 m_pImpl
->notifyParentWindowPosChanged();