summaryrefslogtreecommitdiff
path: root/vcl/source/window/seleng.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/window/seleng.cxx')
-rw-r--r--vcl/source/window/seleng.cxx506
1 files changed, 506 insertions, 0 deletions
diff --git a/vcl/source/window/seleng.cxx b/vcl/source/window/seleng.cxx
new file mode 100644
index 000000000000..8fd3b665aa8a
--- /dev/null
+++ b/vcl/source/window/seleng.cxx
@@ -0,0 +1,506 @@
+/*************************************************************************
+ *
+ * $RCSfile: seleng.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <tools/ref.hxx>
+#include <window.hxx>
+#include <seleng.hxx>
+#include <tools/debug.hxx>
+
+#pragma hdrstop
+
+// TODO: FunctionSet::SelectAtPoint raus
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelectionEngine()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+SelectionEngine::SelectionEngine( Window* pWindow, FunctionSet* pFuncSet ) :
+ pWin( pWindow )
+{
+ eSelMode = SINGLE_SELECTION;
+ pFunctionSet = pFuncSet;
+ nFlags = SELENG_EXPANDONMOVE;
+ nLockedMods = 0;
+
+ aWTimer.SetTimeoutHdl( LINK( this, SelectionEngine, ImpWatchDog ) );
+ aWTimer.SetTimeout( SELENG_AUTOREPEAT_INTERVAL );
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::~SelectionEngine()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+SelectionEngine::~SelectionEngine()
+{
+ aWTimer.Stop();
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::ImpWatchDog()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+IMPL_LINK( SelectionEngine, ImpWatchDog, Timer*, EMPTYARG )
+{
+ if ( !aArea.IsInside( aLastMove.GetPosPixel() ) )
+ SelMouseMove( aLastMove );
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SetSelectionMode()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::SetSelectionMode( SelectionMode eMode )
+{
+ eSelMode = eMode;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::ActivateDragMode()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::ActivateDragMode()
+{
+ DBG_ERRORFILE( "SelectionEngine::ActivateDragMode not implemented" );
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::CursorPosChanging()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::CursorPosChanging( BOOL bShift, BOOL /* bMod1 */ )
+{
+ if ( !pFunctionSet )
+ return;
+
+ if ( bShift && eSelMode != SINGLE_SELECTION )
+ {
+ if ( IsAddMode() )
+ {
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ }
+ else
+ {
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->DeselectAll();
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ }
+ }
+ else
+ {
+ if ( IsAddMode() )
+ {
+ if ( nFlags & SELENG_HAS_ANCH )
+ {
+ // pFunctionSet->CreateCursor();
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH);
+ }
+ }
+ else
+ {
+ pFunctionSet->DeselectAll();
+ nFlags &= (~SELENG_HAS_ANCH);
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelMouseButtonDown()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 07.06.95
+|*
+*************************************************************************/
+
+BOOL SelectionEngine::SelMouseButtonDown( const MouseEvent& rMEvt )
+{
+ nFlags &= (~SELENG_CMDEVT);
+ if ( !pFunctionSet || !pWin || rMEvt.GetClicks() > 1 || rMEvt.IsRight() )
+ return FALSE;
+
+ USHORT nModifier = rMEvt.GetModifier() | nLockedMods;
+ if ( nModifier & KEY_MOD2 )
+ return FALSE;
+ // in SingleSelection: Control-Taste filtern (damit auch
+ // mit Ctrl-Click ein D&D gestartet werden kann)
+ if ( nModifier == KEY_MOD1 && eSelMode == SINGLE_SELECTION )
+ nModifier = 0;
+
+ Point aPos = rMEvt.GetPosPixel();
+ aLastMove = rMEvt;
+
+ pWin->CaptureMouse();
+ nFlags |= SELENG_IN_SEL;
+
+ switch ( nModifier )
+ {
+ case 0: // KEY_NO_KEY
+ {
+ BOOL bSelAtPoint = pFunctionSet->IsSelectionAtPoint( aPos );
+ nFlags &= (~SELENG_IN_ADD);
+ if ( (nFlags & SELENG_DRG_ENAB) && bSelAtPoint )
+ {
+ nFlags |= SELENG_WAIT_UPEVT;
+ nFlags &= ~(SELENG_IN_SEL);
+ pWin->ReleaseMouse();
+ return TRUE; //auf STARTDRAG-Command-Event warten
+ }
+ if ( eSelMode != SINGLE_SELECTION )
+ {
+ if( !IsAddMode() )
+ pFunctionSet->DeselectAll();
+ else
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH); // bHasAnchor = FALSE;
+ }
+ pFunctionSet->SetCursorAtPoint( aPos );
+ // Sonderbehandlung Single-Selection, damit Select+Drag
+ // in einem Zug moeglich ist
+ if (eSelMode == SINGLE_SELECTION && (nFlags & SELENG_DRG_ENAB))
+ nFlags |= SELENG_WAIT_UPEVT;
+ return TRUE;
+ }
+
+ case KEY_SHIFT:
+ if ( eSelMode == SINGLE_SELECTION )
+ {
+ pWin->ReleaseMouse();
+ nFlags &= (~SELENG_IN_SEL);
+ return FALSE;
+ }
+ if ( nFlags & SELENG_ADD_ALW )
+ nFlags |= SELENG_IN_ADD;
+ else
+ nFlags &= (~SELENG_IN_ADD);
+
+ if( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ if ( !(nFlags & SELENG_IN_ADD) )
+ pFunctionSet->DeselectAll();
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ pFunctionSet->SetCursorAtPoint( aPos );
+ return TRUE;
+
+ case KEY_MOD1:
+ // Control nur bei Mehrfachselektion erlaubt
+ if ( eSelMode != MULTIPLE_SELECTION )
+ {
+ nFlags &= (~SELENG_IN_SEL);
+ pWin->ReleaseMouse();
+ return TRUE; // Mausclick verschlucken
+ }
+ if ( nFlags & SELENG_HAS_ANCH )
+ {
+ // pFunctionSet->CreateCursor();
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH);
+ }
+ if ( pFunctionSet->IsSelectionAtPoint( aPos ) )
+ {
+ pFunctionSet->DeselectAtPoint( aPos );
+ pFunctionSet->SetCursorAtPoint( aPos, TRUE );
+ }
+ else
+ {
+ pFunctionSet->SetCursorAtPoint( aPos );
+ }
+ return TRUE;
+
+ case KEY_SHIFT + KEY_MOD1:
+ if ( eSelMode != MULTIPLE_SELECTION )
+ {
+ pWin->ReleaseMouse();
+ nFlags &= (~SELENG_IN_SEL);
+ return FALSE;
+ }
+ nFlags |= SELENG_IN_ADD; //bIsInAddMode = TRUE;
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->CreateAnchor();
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ pFunctionSet->SetCursorAtPoint( aPos );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelMouseButtonUp()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+BOOL SelectionEngine::SelMouseButtonUp( const MouseEvent& /* rMEvt */ )
+{
+ aWTimer.Stop();
+ //DbgOut("Up");
+ if( !pFunctionSet || !pWin )
+ {
+ nFlags &= ~(SELENG_CMDEVT | SELENG_WAIT_UPEVT | SELENG_IN_SEL);
+ return FALSE;
+ }
+ pWin->ReleaseMouse();
+
+ if( (nFlags & SELENG_WAIT_UPEVT) && !(nFlags & SELENG_CMDEVT) &&
+ eSelMode != SINGLE_SELECTION)
+ {
+ // MouseButtonDown in Sel aber kein CommandEvent eingetrudelt
+ // ==> deselektieren
+ USHORT nModifier = aLastMove.GetModifier() | nLockedMods;
+ if( nModifier == KEY_MOD1 || IsAlwaysAdding() )
+ {
+ if( !(nModifier & KEY_SHIFT) )
+ {
+ pFunctionSet->DestroyAnchor();
+ nFlags &= (~SELENG_HAS_ANCH); // nix Anker
+ }
+ pFunctionSet->DeselectAtPoint( aLastMove.GetPosPixel() );
+ nFlags &= (~SELENG_HAS_ANCH); // nix Anker
+ pFunctionSet->SetCursorAtPoint( aLastMove.GetPosPixel(), TRUE );
+ }
+ else
+ {
+ pFunctionSet->DeselectAll();
+ nFlags &= (~SELENG_HAS_ANCH); // nix Anker
+ pFunctionSet->SetCursorAtPoint( aLastMove.GetPosPixel() );
+ }
+ }
+
+ nFlags &= ~(SELENG_CMDEVT | SELENG_WAIT_UPEVT | SELENG_IN_SEL);
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SelMouseMove()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+BOOL SelectionEngine::SelMouseMove( const MouseEvent& rMEvt )
+{
+
+ if ( !pFunctionSet || !(nFlags & SELENG_IN_SEL) ||
+ (nFlags & (SELENG_CMDEVT | SELENG_WAIT_UPEVT)) )
+ return FALSE;
+
+ if( !(nFlags & SELENG_EXPANDONMOVE) )
+ return FALSE; // auf DragEvent warten!
+
+ aLastMove = rMEvt;
+ // wenn die Maus ausserhalb der Area steht, dann wird die
+ // Frequenz des SetCursorAtPoint() nur durch den Timer bestimmt
+ if( aWTimer.IsActive() && !aArea.IsInside( rMEvt.GetPosPixel() ))
+ return TRUE;
+
+
+ aWTimer.Start();
+ if ( eSelMode != SINGLE_SELECTION )
+ {
+ if ( !(nFlags & SELENG_HAS_ANCH) )
+ {
+ pFunctionSet->CreateAnchor();
+ //DbgOut("Move:Creating anchor");
+ nFlags |= SELENG_HAS_ANCH;
+ }
+ }
+
+ //DbgOut("Move:SetCursor");
+ pFunctionSet->SetCursorAtPoint( rMEvt.GetPosPixel() );
+
+ return TRUE;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::SetWindow()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 10.10.94
+|* Letzte Aenderung OV 10.10.94
+|*
+*************************************************************************/
+
+void SelectionEngine::SetWindow( Window* pNewWin )
+{
+ if( pNewWin != pWin )
+ {
+ if ( pWin && (nFlags & SELENG_IN_SEL) )
+ pWin->ReleaseMouse();
+ pWin = pNewWin;
+ if ( pWin && ( nFlags & SELENG_IN_SEL ) )
+ pWin->CaptureMouse();
+ }
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::Reset()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 07.07.95
+|* Letzte Aenderung OV 07.07.95
+|*
+*************************************************************************/
+
+void SelectionEngine::Reset()
+{
+ aWTimer.Stop();
+ if ( nFlags & SELENG_IN_SEL )
+ pWin->ReleaseMouse();
+ nFlags &= ~(SELENG_HAS_ANCH | SELENG_IN_SEL);
+ nLockedMods = 0;
+}
+
+/*************************************************************************
+|*
+|* SelectionEngine::Command()
+|*
+|* Beschreibung SELENG.SDW
+|* Ersterstellung OV 07.07.95
+|* Letzte Aenderung OV 07.07.95
+|*
+*************************************************************************/
+
+void SelectionEngine::Command( const CommandEvent& rCEvt )
+{
+ // Timer aWTimer ist beim Aufspannen einer Selektion aktiv
+ if ( !pFunctionSet || !pWin || aWTimer.IsActive() )
+ return;
+ aWTimer.Stop();
+ nFlags |= SELENG_CMDEVT;
+ if ( rCEvt.GetCommand() == COMMAND_STARTDRAG )
+ {
+ if ( nFlags & SELENG_DRG_ENAB )
+ {
+ DBG_ASSERT( rCEvt.IsMouseEvent(), "STARTDRAG: Not a MouseEvent" );
+ if ( pFunctionSet->IsSelectionAtPoint( rCEvt.GetMousePosPixel() ) )
+ {
+ aLastMove = MouseEvent( rCEvt.GetMousePosPixel(),
+ aLastMove.GetClicks(), aLastMove.GetMode(),
+ aLastMove.GetButtons(), aLastMove.GetModifier() );
+ pFunctionSet->BeginDrag();
+ nFlags &= ~(SELENG_CMDEVT|SELENG_WAIT_UPEVT|SELENG_IN_SEL);
+ }
+ else
+ nFlags &= ~SELENG_CMDEVT;
+ }
+ else
+ nFlags &= ~SELENG_CMDEVT;
+ }
+}