summaryrefslogtreecommitdiff
path: root/vcl/source/window/floatwin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/window/floatwin.cxx')
-rw-r--r--vcl/source/window/floatwin.cxx878
1 files changed, 878 insertions, 0 deletions
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
new file mode 100644
index 000000000000..170fcbd65cee
--- /dev/null
+++ b/vcl/source/window/floatwin.cxx
@@ -0,0 +1,878 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#include <vcl/svdata.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/brdwin.hxx>
+#include <vcl/event.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/floatwin.hxx>
+#include <vcl/window.h>
+#ifndef _SV_RC_H
+#include <tools/rc.h>
+#endif
+#include <vcl/salframe.hxx>
+#include <tools/debug.hxx>
+
+
+// =======================================================================
+
+class FloatingWindow::ImplData
+{
+public:
+ ImplData();
+ ~ImplData();
+
+ ToolBox* mpBox;
+ Rectangle maItemEdgeClipRect; // used to clip the common edge between a toolbar item and the border of this window
+};
+
+FloatingWindow::ImplData::ImplData()
+{
+ mpBox = NULL;
+}
+
+FloatingWindow::ImplData::~ImplData()
+{
+}
+
+Rectangle& FloatingWindow::ImplGetItemEdgeClipRect()
+{
+ return mpImplData->maItemEdgeClipRect;
+}
+
+// =======================================================================
+
+void FloatingWindow::ImplInit( Window* pParent, WinBits nStyle )
+{
+ mpImplData = new ImplData;
+
+ mpWindowImpl->mbFloatWin = sal_True;
+ mbInCleanUp = sal_False;
+ mbGrabFocus = sal_False;
+
+ DBG_ASSERT( pParent, "FloatWindow::FloatingWindow(): - pParent == NULL!" );
+
+ if ( !pParent )
+ pParent = ImplGetSVData()->maWinData.mpAppWin;
+
+ DBG_ASSERT( pParent, "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists" );
+
+ // no Border, then we dont need a border window
+ if ( !nStyle )
+ {
+ mpWindowImpl->mbOverlapWin = sal_True;
+ nStyle |= WB_DIALOGCONTROL;
+ SystemWindow::ImplInit( pParent, nStyle, NULL );
+ }
+ else
+ {
+ if ( !(nStyle & WB_NODIALOGCONTROL) )
+ nStyle |= WB_DIALOGCONTROL;
+
+ if( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE)
+ && !(nStyle & WB_OWNERDRAWDECORATION) )
+ {
+ WinBits nFloatWinStyle = nStyle;
+ // #99154# floaters are not closeable by default anymore, eg fullscreen floater
+ // nFloatWinStyle |= WB_CLOSEABLE;
+ mpWindowImpl->mbFrame = sal_True;
+ mpWindowImpl->mbOverlapWin = sal_True;
+ SystemWindow::ImplInit( pParent, nFloatWinStyle & ~WB_BORDER, NULL );
+ }
+ else
+ {
+ ImplBorderWindow* pBorderWin;
+ sal_uInt16 nBorderStyle = BORDERWINDOW_STYLE_BORDER | BORDERWINDOW_STYLE_FLOAT;
+
+ if( nStyle & WB_OWNERDRAWDECORATION ) nBorderStyle |= BORDERWINDOW_STYLE_FRAME;
+ else nBorderStyle |= BORDERWINDOW_STYLE_OVERLAP;
+
+ if ( (nStyle & WB_SYSTEMWINDOW) && !(nStyle & (WB_MOVEABLE | WB_SIZEABLE)) )
+ {
+ nBorderStyle |= BORDERWINDOW_STYLE_FRAME;
+ nStyle |= WB_CLOSEABLE; // make undecorated floaters closeable
+ }
+ pBorderWin = new ImplBorderWindow( pParent, nStyle, nBorderStyle );
+ SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
+ pBorderWin->mpWindowImpl->mpClientWindow = this;
+ pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
+ pBorderWin->SetDisplayActive( sal_True );
+ mpWindowImpl->mpBorderWindow = pBorderWin;
+ mpWindowImpl->mpRealParent = pParent;
+ }
+ }
+ SetActivateMode( 0 );
+
+ mpNextFloat = NULL;
+ mpFirstPopupModeWin = NULL;
+ mnPostId = 0;
+ mnTitle = (nStyle & WB_MOVEABLE) ? FLOATWIN_TITLE_NORMAL : FLOATWIN_TITLE_NONE;
+ mnOldTitle = mnTitle;
+ mnPopupModeFlags = 0;
+ mbInPopupMode = sal_False;
+ mbPopupMode = sal_False;
+ mbPopupModeCanceled = sal_False;
+ mbPopupModeTearOff = sal_False;
+ mbMouseDown = sal_False;
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+}
+
+// =======================================================================
+
+FloatingWindow::FloatingWindow( Window* pParent, WinBits nStyle ) :
+ SystemWindow( WINDOW_FLOATINGWINDOW )
+{
+ ImplInit( pParent, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+FloatingWindow::FloatingWindow( Window* pParent, const ResId& rResId ) :
+ SystemWindow( WINDOW_FLOATINGWINDOW )
+{
+ rResId.SetRT( RSC_FLOATINGWINDOW );
+ WinBits nStyle = ImplInitRes( rResId );
+ ImplInit( pParent, nStyle );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplLoadRes( const ResId& rResId )
+{
+ SystemWindow::ImplLoadRes( rResId );
+
+ sal_uLong nObjMask = ReadLongRes();
+
+ if ( (RSC_FLOATINGWINDOW_WHMAPMODE | RSC_FLOATINGWINDOW_WIDTH |
+ RSC_FLOATINGWINDOW_HEIGHT) & nObjMask )
+ {
+ // Groessenangabe aus der Resource verwenden
+ Size aSize;
+ MapUnit eSizeMap = MAP_PIXEL;
+
+ if ( RSC_FLOATINGWINDOW_WHMAPMODE & nObjMask )
+ eSizeMap = (MapUnit) ReadShortRes();
+ if ( RSC_FLOATINGWINDOW_WIDTH & nObjMask )
+ aSize.Width() = ReadShortRes();
+ if ( RSC_FLOATINGWINDOW_HEIGHT & nObjMask )
+ aSize.Height() = ReadShortRes();
+
+ SetRollUpOutputSizePixel( LogicToPixel( aSize, eSizeMap ) );
+ }
+
+ if (nObjMask & RSC_FLOATINGWINDOW_ZOOMIN )
+ {
+ if ( ReadShortRes() )
+ RollUp();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+FloatingWindow::~FloatingWindow()
+{
+ if( mbPopupModeCanceled )
+ // indicates that ESC key was pressed
+ // will be handled in Window::ImplGrabFocus()
+ SetDialogControlFlags( GetDialogControlFlags() | WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL );
+
+ if ( IsInPopupMode() )
+ EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL | FLOATWIN_POPUPMODEEND_DONTCALLHDL );
+
+ if ( mnPostId )
+ Application::RemoveUserEvent( mnPostId );
+
+ delete mpImplData;
+}
+
+// -----------------------------------------------------------------------
+
+Point FloatingWindow::CalcFloatingPosition( Window* pWindow, const Rectangle& rRect, sal_uLong nFlags, sal_uInt16& rArrangeIndex )
+{
+ return ImplCalcPos( pWindow, rRect, nFlags, rArrangeIndex );
+}
+
+// -----------------------------------------------------------------------
+
+Point FloatingWindow::ImplCalcPos( Window* pWindow,
+ const Rectangle& rRect, sal_uLong nFlags,
+ sal_uInt16& rArrangeIndex )
+{
+ // Fenster-Position ermitteln
+ Point aPos;
+ Size aSize = pWindow->GetSizePixel();
+ Rectangle aScreenRect = pWindow->ImplGetFrameWindow()->GetDesktopRectPixel();
+ FloatingWindow *pFloatingWindow = dynamic_cast<FloatingWindow*>( pWindow );
+
+ // convert....
+ Window* pW = pWindow;
+ if ( pW->mpWindowImpl->mpRealParent )
+ pW = pW->mpWindowImpl->mpRealParent;
+
+ Rectangle normRect( rRect ); // rRect is already relative to top-level window
+ normRect.SetPos( pW->ScreenToOutputPixel( normRect.TopLeft() ) );
+
+ sal_Bool bRTL = Application::GetSettings().GetLayoutRTL();
+
+ Rectangle devRect( pW->OutputToAbsoluteScreenPixel( normRect.TopLeft() ),
+ pW->OutputToAbsoluteScreenPixel( normRect.BottomRight() ) );
+
+ Rectangle devRectRTL( devRect );
+ if( bRTL )
+ // create a rect that can be compared to desktop coordinates
+ devRectRTL = pW->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect );
+ if( Application::GetScreenCount() > 1 && ! Application::IsMultiDisplay() )
+ aScreenRect = Application::GetScreenPosSizePixel(
+ Application::GetBestScreen( bRTL ? devRectRTL : devRect ) );
+
+
+ sal_uInt16 nArrangeAry[5];
+ sal_uInt16 nArrangeIndex;
+ sal_Bool bBreak;
+ Point e1,e2; // the common edge between the item rect and the floating window
+
+ if ( nFlags & FLOATWIN_POPUPMODE_LEFT )
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_LEFT;
+ }
+ else if ( nFlags & FLOATWIN_POPUPMODE_RIGHT )
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_RIGHT;
+ }
+ else if ( nFlags & FLOATWIN_POPUPMODE_UP )
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_UP;
+ }
+ else
+ {
+ nArrangeAry[0] = FLOATWIN_POPUPMODE_DOWN;
+ nArrangeAry[1] = FLOATWIN_POPUPMODE_UP;
+ nArrangeAry[2] = FLOATWIN_POPUPMODE_RIGHT;
+ nArrangeAry[3] = FLOATWIN_POPUPMODE_LEFT;
+ nArrangeAry[4] = FLOATWIN_POPUPMODE_DOWN;
+ }
+ if ( nFlags & FLOATWIN_POPUPMODE_NOAUTOARRANGE )
+ nArrangeIndex = 4;
+ else
+ nArrangeIndex = 0;
+
+ for ( ; nArrangeIndex < 5; nArrangeIndex++ )
+ {
+ bBreak = sal_True;
+ switch ( nArrangeAry[nArrangeIndex] )
+ {
+
+ case FLOATWIN_POPUPMODE_LEFT:
+ aPos.X() = devRect.Left()-aSize.Width()+1;
+ aPos.Y() = devRect.Top();
+ aPos.Y() -= pWindow->mpWindowImpl->mnTopBorder;
+ if( bRTL ) // --- RTL --- we're comparing screen coordinates here
+ {
+ if( (devRectRTL.Right()+aSize.Width()) > aScreenRect.Right() )
+ bBreak = sal_False;
+ }
+ else
+ {
+ if ( aPos.X() < aScreenRect.Left() )
+ bBreak = sal_False;
+ }
+ if( bBreak )
+ {
+ e1 = devRect.TopLeft();
+ e2 = devRect.BottomLeft();
+ // set non-zero width
+ e2.X()++;
+ // don't clip corners
+ e1.Y()++;
+ e2.Y()--;
+ }
+ break;
+ case FLOATWIN_POPUPMODE_RIGHT:
+ aPos = devRect.TopRight();
+ aPos.Y() -= pWindow->mpWindowImpl->mnTopBorder;
+ if( bRTL ) // --- RTL --- we're comparing screen coordinates here
+ {
+ if( (devRectRTL.Left() - aSize.Width()) < aScreenRect.Left() )
+ bBreak = sal_False;
+ }
+ else
+ {
+ if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
+ bBreak = sal_False;
+ }
+ if( bBreak )
+ {
+ e1 = devRect.TopRight();
+ e2 = devRect.BottomRight();
+ // set non-zero width
+ e2.X()++;
+ // don't clip corners
+ e1.Y()++;
+ e2.Y()--;
+ }
+ break;
+ case FLOATWIN_POPUPMODE_UP:
+ aPos.X() = devRect.Left();
+ aPos.Y() = devRect.Top()-aSize.Height()+1;
+ if ( aPos.Y() < aScreenRect.Top() )
+ bBreak = sal_False;
+ if( bBreak )
+ {
+ e1 = devRect.TopLeft();
+ e2 = devRect.TopRight();
+ // set non-zero height
+ e2.Y()++;
+ // don't clip corners
+ e1.X()++;
+ e2.X()--;
+ }
+ break;
+ case FLOATWIN_POPUPMODE_DOWN:
+ aPos = devRect.BottomLeft();
+ if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
+ bBreak = sal_False;
+ if( bBreak )
+ {
+ e1 = devRect.BottomLeft();
+ e2 = devRect.BottomRight();
+ // set non-zero height
+ e2.Y()++;
+ // don't clip corners
+ e1.X()++;
+ e2.X()--;
+ }
+ break;
+ }
+
+ // Evt. noch anpassen
+ if ( bBreak && !(nFlags & FLOATWIN_POPUPMODE_NOAUTOARRANGE) )
+ {
+ if ( (nArrangeAry[nArrangeIndex] == FLOATWIN_POPUPMODE_LEFT) ||
+ (nArrangeAry[nArrangeIndex] == FLOATWIN_POPUPMODE_RIGHT) )
+ {
+ if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
+ {
+ aPos.Y() = devRect.Bottom()-aSize.Height()+1;
+ if ( aPos.Y() < aScreenRect.Top() )
+ aPos.Y() = aScreenRect.Top();
+ }
+ }
+ else
+ {
+ if( bRTL ) // --- RTL --- we're comparing screen coordinates here
+ {
+ if( devRectRTL.Right()-aSize.Width()+1 < aScreenRect.Left() )
+ aPos.X() -= aScreenRect.Left() - devRectRTL.Right() + aSize.Width() - 1;
+ else if( aPos.X() + aSize.Width() > aScreenRect.Right() )
+ {
+ aPos.X() -= aSize.Width()-2; // popup to left instead
+ aPos.Y() -= 2;
+ }
+ }
+ else if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
+ {
+ aPos.X() = devRect.Right()-aSize.Width()+1;
+ if ( aPos.X() < aScreenRect.Left() )
+ aPos.X() = aScreenRect.Left();
+ }
+ }
+ }
+
+ if ( bBreak )
+ break;
+ }
+ if ( nArrangeIndex > 4 )
+ nArrangeIndex = 4;
+
+ rArrangeIndex = nArrangeIndex;
+
+ aPos = pW->AbsoluteScreenToOutputPixel( aPos );
+
+ // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
+ if( pFloatingWindow )
+ {
+ pFloatingWindow->mpImplData->maItemEdgeClipRect =
+ Rectangle( e1, e2 );
+ }
+
+ // caller expects cordinates relative to top-level win
+ return pW->OutputToScreenPixel( aPos );
+}
+
+// -----------------------------------------------------------------------
+
+FloatingWindow* FloatingWindow::ImplFloatHitTest( Window* pReference, const Point& rPos, sal_uInt16& rHitTest )
+{
+ FloatingWindow* pWin = this;
+
+ Point aAbsolute( rPos );
+
+ // compare coordinates in absolute screen coordinates
+ if( pReference->ImplHasMirroredGraphics() )
+ {
+ if(!pReference->IsRTLEnabled() )
+ // --- RTL --- re-mirror back to get device coordiantes
+ pReference->ImplReMirror( aAbsolute );
+
+ Rectangle aRect( pReference->ScreenToOutputPixel(aAbsolute), Size(1,1) ) ;
+ aRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect );
+ aAbsolute = aRect.TopLeft();
+ }
+ else
+ aAbsolute = Point( pReference->OutputToAbsoluteScreenPixel(
+ pReference->ScreenToOutputPixel(rPos) ) );
+
+ do
+ {
+ // compute the floating window's size in absolute screen coordinates
+
+ // use the border window to have the exact position
+ Window *pBorderWin = pWin->GetWindow( WINDOW_BORDER );
+
+ Point aPt; // the top-left corner in output coordinates ie (0,0)
+ Rectangle devRect( pBorderWin->ImplOutputToUnmirroredAbsoluteScreenPixel( Rectangle( aPt, pBorderWin->GetSizePixel()) ) ) ;
+ if ( devRect.IsInside( aAbsolute ) )
+ {
+ rHitTest = IMPL_FLOATWIN_HITTEST_WINDOW;
+ return pWin;
+ }
+
+ // test, if mouse is in rectangle, (this is typically the rect of the active
+ // toolbox item or similar)
+ // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
+ // is already in absolute device coordinates
+ if ( pWin->maFloatRect.IsInside( aAbsolute ) )
+ {
+ rHitTest = IMPL_FLOATWIN_HITTEST_RECT;
+ return pWin;
+ }
+
+ pWin = pWin->mpNextFloat;
+ }
+ while ( pWin );
+
+ rHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+FloatingWindow* FloatingWindow::ImplFindLastLevelFloat()
+{
+ FloatingWindow* pWin = this;
+ FloatingWindow* pLastFoundWin = pWin;
+
+ do
+ {
+ if ( pWin->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NEWLEVEL )
+ pLastFoundWin = pWin;
+
+ pWin = pWin->mpNextFloat;
+ }
+ while ( pWin );
+
+ return pLastFoundWin;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool FloatingWindow::ImplIsFloatPopupModeWindow( const Window* pWindow )
+{
+ FloatingWindow* pWin = this;
+
+ do
+ {
+ if ( pWin->mpFirstPopupModeWin == pWindow )
+ return sal_True;
+
+ pWin = pWin->mpNextFloat;
+ }
+ while ( pWin );
+
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FloatingWindow, ImplEndPopupModeHdl, void*, EMPTYARG )
+{
+ mnPostId = 0;
+ mnPopupModeFlags = 0;
+ mbPopupMode = sal_False;
+ PopupModeEnd();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long FloatingWindow::Notify( NotifyEvent& rNEvt )
+{
+ // Zuerst Basisklasse rufen wegen TabSteuerung
+ long nRet = SystemWindow::Notify( rNEvt );
+ if ( !nRet )
+ {
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ sal_uInt16 nKeyCode = aKeyCode.GetCode();
+
+ if ( (nKeyCode == KEY_ESCAPE) && (GetStyle() & WB_CLOSEABLE) )
+ {
+ Close();
+ return sal_True;
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::StateChanged( StateChangedType nType )
+{
+ SystemWindow::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SystemWindow::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplCallPopupModeEnd()
+{
+ // PopupMode wurde beendet
+ mbInPopupMode = sal_False;
+
+ // Handler asyncron rufen
+ if ( !mnPostId )
+ Application::PostUserEvent( mnPostId, LINK( this, FloatingWindow, ImplEndPopupModeHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::PopupModeEnd()
+{
+ maPopupModeEndHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::SetTitleType( sal_uInt16 nTitle )
+{
+ if ( (mnTitle != nTitle) && mpWindowImpl->mpBorderWindow )
+ {
+ mnTitle = nTitle;
+ Size aOutSize = GetOutputSizePixel();
+ sal_uInt16 nTitleStyle;
+ if ( nTitle == FLOATWIN_TITLE_NORMAL )
+ nTitleStyle = BORDERWINDOW_TITLE_SMALL;
+ else if ( nTitle == FLOATWIN_TITLE_TEAROFF )
+ nTitleStyle = BORDERWINDOW_TITLE_TEAROFF;
+ else // nTitle == FLOATWIN_TITLE_NONE
+ nTitleStyle = BORDERWINDOW_TITLE_NONE;
+ ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetTitleType( nTitleStyle, aOutSize );
+ ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::StartPopupMode( const Rectangle& rRect, sal_uLong nFlags )
+{
+ // avoid flickering
+ if ( IsVisible() )
+ Show( sal_False, SHOW_NOFOCUSCHANGE );
+
+ if ( IsRollUp() )
+ RollDown();
+
+ // remove title
+ mnOldTitle = mnTitle;
+ if ( nFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF )
+ SetTitleType( FLOATWIN_TITLE_TEAROFF );
+ else
+ SetTitleType( FLOATWIN_TITLE_NONE );
+
+ // avoid close on focus change for decorated floating windows only
+ if( mpWindowImpl->mbFrame && (GetStyle() & WB_MOVEABLE) )
+ nFlags |= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
+
+ // #102010# For debugging Accessibility
+ static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
+ if( pEnv && *pEnv )
+ nFlags |= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
+
+ // compute window position according to flags and arrangement
+ sal_uInt16 nArrangeIndex;
+ SetPosPixel( ImplCalcPos( this, rRect, nFlags, nArrangeIndex ) );
+
+ // set data and display window
+ // convert maFloatRect to absolute device coordinates
+ // so they can be compared across different frames
+ // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
+ maFloatRect = rRect;
+ if( GetParent()->ImplHasMirroredGraphics() )
+ {
+ maFloatRect.SetPos( GetParent()->ScreenToOutputPixel( rRect.TopLeft() ) );
+ maFloatRect = GetParent()->ImplOutputToUnmirroredAbsoluteScreenPixel( maFloatRect );
+ }
+ else
+ maFloatRect.SetPos( GetParent()->OutputToAbsoluteScreenPixel( GetParent()->ScreenToOutputPixel( rRect.TopLeft() ) ) );
+
+ maFloatRect.Left() -= 2;
+ maFloatRect.Top() -= 2;
+ maFloatRect.Right() += 2;
+ maFloatRect.Bottom() += 2;
+ mnPopupModeFlags = nFlags;
+ mbInPopupMode = sal_True;
+ mbPopupMode = sal_True;
+ mbPopupModeCanceled = sal_False;
+ mbPopupModeTearOff = sal_False;
+ mbMouseDown = sal_False;
+
+ mbOldSaveBackMode = IsSaveBackgroundEnabled();
+ EnableSaveBackground();
+
+ // add FloatingWindow to list of windows that are in popup mode
+ ImplSVData* pSVData = ImplGetSVData();
+ mpNextFloat = pSVData->maWinData.mpFirstFloat;
+ pSVData->maWinData.mpFirstFloat = this;
+ if( nFlags & FLOATWIN_POPUPMODE_GRABFOCUS )
+ {
+ // force key input even without focus (useful for menues)
+ mbGrabFocus = sal_True;
+ }
+ Show( sal_True, SHOW_NOACTIVATE );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::StartPopupMode( ToolBox* pBox, sal_uLong nFlags )
+{
+ // get selected button
+ sal_uInt16 nItemId = pBox->GetDownItemId();
+ if ( !nItemId )
+ return;
+
+ mpImplData->mpBox = pBox;
+ pBox->ImplFloatControl( sal_True, this );
+
+ // retrieve some data from the ToolBox
+ Rectangle aRect = pBox->GetItemRect( nItemId );
+ Point aPos;
+ // convert to parent's screen coordinates
+ aPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
+ aRect.SetPos( aPos );
+
+ nFlags |=
+ FLOATWIN_POPUPMODE_NOFOCUSCLOSE |
+// FLOATWIN_POPUPMODE_NOMOUSECLOSE |
+ FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE |
+// FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE | // #105968# floating toolboxes should close when clicked in (parent's) float rect
+ FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE;
+// | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
+
+/*
+ * FLOATWIN_POPUPMODE_NOKEYCLOSE |
+ * don't set since it disables closing floaters with escape
+ */
+
+ // Flags fuer Positionierung bestimmen
+ if ( !(nFlags & (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_UP |
+ FLOATWIN_POPUPMODE_LEFT | FLOATWIN_POPUPMODE_RIGHT |
+ FLOATWIN_POPUPMODE_NOAUTOARRANGE)) )
+ {
+ if ( pBox->IsHorizontal() )
+ nFlags |= FLOATWIN_POPUPMODE_DOWN;
+ else
+ nFlags |= FLOATWIN_POPUPMODE_RIGHT;
+ }
+
+ // FloatingModus starten
+ StartPopupMode( aRect, nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::ImplEndPopupMode( sal_uInt16 nFlags, sal_uLong nFocusId )
+{
+ if ( !mbInPopupMode )
+ return;
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ mbInCleanUp = sal_True; // prevent killing this window due to focus change while working with it
+
+ // Bei allen nachfolgenden PopupMode-Fenster den Modus auch beenden
+ while ( pSVData->maWinData.mpFirstFloat && pSVData->maWinData.mpFirstFloat != this )
+ pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+
+
+ // Fenster aus der Liste austragen
+ pSVData->maWinData.mpFirstFloat = mpNextFloat;
+ mpNextFloat = NULL;
+
+ sal_uLong nPopupModeFlags = mnPopupModeFlags;
+
+ // Wenn nicht abgerissen wurde, dann Fenster wieder Hiden
+ if ( !(nFlags & FLOATWIN_POPUPMODEEND_TEAROFF) ||
+ !(nPopupModeFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF) )
+ {
+ Show( sal_False, SHOW_NOFOCUSCHANGE );
+
+ // Focus evt. auf ein entsprechendes FloatingWindow weiterschalten
+ if ( nFocusId )
+ Window::EndSaveFocus( nFocusId );
+ else if ( pSVData->maWinData.mpFocusWin && pSVData->maWinData.mpFirstFloat &&
+ ImplIsWindowOrChild( pSVData->maWinData.mpFocusWin ) )
+ pSVData->maWinData.mpFirstFloat->GrabFocus();
+ mbPopupModeTearOff = sal_False;
+ }
+ else
+ {
+ mbPopupModeTearOff = sal_True;
+ if ( nFocusId )
+ Window::EndSaveFocus( nFocusId, sal_False );
+ }
+ EnableSaveBackground( mbOldSaveBackMode );
+
+ mbPopupModeCanceled = (nFlags & FLOATWIN_POPUPMODEEND_CANCEL) != 0;
+
+ // Gegebenenfalls den Title wieder herstellen
+ SetTitleType( mnOldTitle );
+
+ // ToolBox wieder auf normal schalten
+ if ( mpImplData->mpBox )
+ {
+ mpImplData->mpBox->ImplFloatControl( sal_False, this );
+ mpImplData->mpBox = NULL;
+ }
+
+ // Je nach Parameter den PopupModeEnd-Handler rufen
+ if ( !(nFlags & FLOATWIN_POPUPMODEEND_DONTCALLHDL) )
+ ImplCallPopupModeEnd();
+
+ // Je nach Parameter die restlichen Fenster auch noch schliessen
+ if ( nFlags & FLOATWIN_POPUPMODEEND_CLOSEALL )
+ {
+ if ( !(nPopupModeFlags & FLOATWIN_POPUPMODE_NEWLEVEL) )
+ {
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ }
+ }
+
+ mbInCleanUp = sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::EndPopupMode( sal_uInt16 nFlags )
+{
+ ImplEndPopupMode( nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::AddPopupModeWindow( Window* pWindow )
+{
+ // !!! bisher erst 1 Fenster und noch keine Liste
+ mpFirstPopupModeWin = pWindow;
+}
+
+// -----------------------------------------------------------------------
+
+void FloatingWindow::RemovePopupModeWindow( Window* pWindow )
+{
+ // !!! bisher erst 1 Fenster und noch keine Liste
+ if ( mpFirstPopupModeWin == pWindow )
+ mpFirstPopupModeWin = NULL;
+}
+