blob: 8b8f22750f468073ffd0d7d5900109ca5b13d971 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#ifndef _SVSTDARR_HXX
#define _SVSTDARR_USHORTS
#include <svl/svstdarr.hxx>
#endif
#include <vcl/dialog.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/wrkwin.hxx>
#include <viewopt.hxx>
#include <frmtool.hxx>
#include <viscrs.hxx>
#include <crsrsh.hxx>
#include <doc.hxx>
#include <swtable.hxx>
#include <viewimp.hxx>
#include <dview.hxx>
#include <rootfrm.hxx>
#include <txtfrm.hxx>
#include <docary.hxx>
#include <extinput.hxx>
#include <ndtxt.hxx>
#include <txtfld.hxx>
#include <scriptinfo.hxx>
#include <mdiexp.hxx>
#ifndef _COMCORE_HRC
#include <comcore.hrc> // ResId fuer Abfrage wenn zu Search & Replaces
#endif
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <vcl/svapp.hxx>
#include <svx/sdr/overlay/overlayselection.hxx>
#include <overlayrangesoutline.hxx>
#include <boost/scoped_ptr.hpp>
extern void SwCalcPixStatics( OutputDevice *pOut );
//Damit beim ShowCrsr nicht immer wieder die gleiche Size teuer ermittelt
//werden muss, hier statische Member, die beim Wechsel des MapModes
// angepasst werden
long SwSelPaintRects::nPixPtX = 0;
long SwSelPaintRects::nPixPtY = 0;
MapMode* SwSelPaintRects::pMapMode = 0;
#ifdef SHOW_BOOKMARKS
// #include <IMark.hxx>
//
// class SwBookmarkRects : public SwSelPaintRects
// {
// virtual void Paint( const Rectangle& rRect );
// virtual void FillRects();
//
// public:
// SwBookmarkRects( const SwCrsrShell& rSh ) : SwSelPaintRects( rSh ) {}
// };
//
// void SwBookmarkRects::Paint( const Rectangle& rRect )
// {
// Window* pWin = GetShell()->GetWin();
//
// RasterOp eOld( pWin->GetRasterOp() );
// sal_Bool bLCol = pWin->IsLineColor();
// Color aLCol( pWin->GetLineColor() );
// sal_Bool bFCol = pWin->IsFillColor();
// Color aFCol( pWin->GetFillColor() );
//
// pWin->SetRasterOp( ROP_XOR );
// Color aCol( RGB_COLORDATA( 0xF0, 0xC8, 0xF0 ) ^ COL_WHITE );
// pWin->SetFillColor( aCol );
// pWin->SetLineColor( aCol );
//
// pWin->DrawRect( rRect );
//
// if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor();
// if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor();
// pWin->SetRasterOp( eOld );
// }
//
// void SwBookmarkRects::FillRects()
// {
// SwRegionRects aReg( GetShell()->VisArea() );
//
// const SwBookmarks& rBkmkTbl = GetShell()->getIDocumentMarkAccess()->getBookmarks();
// SwShellCrsr* pCrsr = 0;
// for( sal_uInt16 n = 0; n < rBkmkTbl.Count(); ++n )
// {
// const SwBookmark& rBkmk = *rBkmkTbl[ n ];
// if( rBkmk.IsBookMark() && rBkmk.GetOtherPos() )
// {
// if( !pCrsr )
// {
// pCrsr = new SwShellCrsr( *GetShell(), rBkmk.GetPos() );
// pCrsr->SetMark();
// }
// else
// *pCrsr->GetPoint() = rBkmk.GetPos();
// *pCrsr->GetMark() = *rBkmk.GetOtherPos();
// pCrsr->FillRects();
// for( sal_uInt16 i = 0; i < pCrsr->Count(); ++i )
// aReg -= (*pCrsr)[ i ];
//
// pCrsr->Remove( 0, i );
// }
// }
// if( pCrsr ) delete pCrsr;
//
// aReg.Invert();
// SwRects::Insert( &aReg, 0 );
// }
//
// SwBookmarkRects* pBookMarkRects = 0;
//
// void ShowBookmarks( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 )
// {
// if( !pBookMarkRects && pSh->getIDocumentMarkAccess()->getBookmarks().Count() )
// pBookMarkRects = new SwBookmarkRects( *pSh );
//
// if( pBookMarkRects )
// {
// switch( nAction )
// {
// case 1: pBookMarkRects->Show(); break;
// case 2: pBookMarkRects->Hide(); break;
// case 3: pBookMarkRects->Invalidate( *pRect ); break;
// }
//
// if( !pBookMarkRects->Count() )
// delete pBookMarkRects, pBookMarkRects = 0;
// }
// }
//
// #define SHOWBOOKMARKS1( nAct ) ShowBookmarks( GetShell(),nAct );
// #define SHOWBOOKMARKS2( nAct, pRect ) ShowBookmarks( GetShell(),nAct, pRect );
#else
#define SHOWBOOKMARKS1( nAct )
#define SHOWBOOKMARKS2( nAct, pRect )
#endif
#ifdef SHOW_REDLINES
#include <redline.hxx>
class SwRedlineRects : public SwSelPaintRects
{
sal_uInt16 nMode;
sal_uInt16 nNm;
virtual void Paint( const Rectangle& rRect );
virtual void FillRects();
public:
SwRedlineRects( const SwCrsrShell& rSh, sal_uInt16 nName, sal_uInt16 n )
: SwSelPaintRects( rSh ), nMode( n ), nNm( nName )
{}
};
void SwRedlineRects::Paint( const Rectangle& rRect )
{
Window* pWin = GetShell()->GetWin();
RasterOp eOld( pWin->GetRasterOp() );
sal_Bool bLCol = pWin->IsLineColor();
Color aLCol( pWin->GetLineColor() );
sal_Bool bFCol = pWin->IsFillColor();
Color aFCol( pWin->GetFillColor() );
pWin->SetRasterOp( ROP_XOR );
Color aCol;
sal_uInt8 nVal = 0xc8 - ( (nMode / 4) * 16 );
switch( nMode % 4 )
{
case 0: aCol = RGB_COLORDATA( nVal, nVal, 0xFF ); break;
case 1: aCol = RGB_COLORDATA( 0xFF, 0xc8, nVal ); break;
case 2: aCol = RGB_COLORDATA( nVal, 0xFF, nVal ); break;
case 3: aCol = RGB_COLORDATA( 0xFF, nVal, nVal ); break;
}
aCol = aCol.GetColor() ^ COL_WHITE;
pWin->SetFillColor( aCol );
pWin->SetLineColor( aCol );
pWin->DrawRect( rRect );
if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor();
if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor();
pWin->SetRasterOp( eOld );
}
void SwRedlineRects::FillRects()
{
SwRegionRects aReg( GetShell()->VisArea() );
const SwRedlineTbl& rTbl = GetShell()->GetDoc()->GetRedlineTbl();
SwShellCrsr* pCrsr = 0;
for( sal_uInt16 n = 0; n < rTbl.Count(); ++n )
{
const SwRedline& rRed = *rTbl[ n ];
if( rRed.HasMark() && (nMode % 4 ) == rRed.GetType() &&
nNm == rRed.GetAuthor() )
{
if( !pCrsr )
{
pCrsr = new SwShellCrsr( *GetShell(), *rRed.GetPoint() );
pCrsr->SetMark();
}
else
*pCrsr->GetPoint() = *rRed.GetPoint();
*pCrsr->GetMark() = *rRed.GetMark();
pCrsr->FillRects();
for( sal_uInt16 i = 0; i < pCrsr->Count(); ++i )
aReg -= (*pCrsr)[ i ];
pCrsr->Remove( 0, i );
}
}
if( pCrsr ) delete pCrsr;
aReg.Invert();
SwRects::Insert( &aReg, 0 );
}
SwRedlineRects* aRedlines[ 10 * 4 ];
static int bFirstCall = sal_True;
void ShowRedlines( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 )
{
if( bFirstCall )
{
memset( aRedlines, 0, sizeof(aRedlines));
bFirstCall = sal_False;
}
const SwRedlineTbl& rTbl = pSh->GetDoc()->GetRedlineTbl();
const SwRedlineAuthorTbl& rAuthorTbl = pSh->GetDoc()->GetRedlineAuthorTbl();
for( sal_uInt16 n = 0; n < rAuthorTbl.Count(); ++n )
{
for( int i = 0; i < 4; ++i )
{
SwRedlineRects** ppRedRect = &aRedlines[ n * 4 + i ];
if( rTbl.Count() && !*ppRedRect )
*ppRedRect = new SwRedlineRects( *pSh, n, n * 4 + i );
if( *ppRedRect )
{
switch( nAction )
{
case 1: (*ppRedRect)->Show(); break;
case 2: (*ppRedRect)->Hide(); break;
case 3: (*ppRedRect)->Invalidate( *pRect ); break;
}
if( !(*ppRedRect)->Count() )
delete *ppRedRect, *ppRedRect = 0;
}
}
}
}
#define SHOWREDLINES1( nAct ) ShowRedlines( GetShell(),nAct );
#define SHOWREDLINES2( nAct, pRect ) ShowRedlines( GetShell(),nAct, pRect );
#else
#define SHOWREDLINES1( nAct )
#define SHOWREDLINES2( nAct, pRect )
#endif
#ifdef JP_REDLINE
if( GetDoc()->GetRedlineTbl().Count() )
{
SwRedlineTbl& rRedlineTbl = (SwRedlineTbl&)GetDoc()->GetRedlineTbl();
for( sal_uInt16 i = 0; i < rRedlineTbl.Count(); ++i )
rRedlineTbl[ i ]->HideRects( *GetShell() );
}
#endif
// -------- Ab hier Klassen / Methoden fuer den nicht Text-Cursor ------
SwVisCrsr::SwVisCrsr( const SwCrsrShell * pCShell )
: pCrsrShell( pCShell )
{
pCShell->GetWin()->SetCursor( &aTxtCrsr );
bIsVisible = aTxtCrsr.IsVisible();
bIsDragCrsr = sal_False;
aTxtCrsr.SetWidth( 0 );
#ifdef SW_CRSR_TIMER
bTimerOn = sal_True;
SetTimeout( 50 ); // 50msec Verzoegerung
#endif
}
SwVisCrsr::~SwVisCrsr()
{
#ifdef SW_CRSR_TIMER
if( bTimerOn )
Stop(); // Timer stoppen
#endif
if( bIsVisible && aTxtCrsr.IsVisible() )
aTxtCrsr.Hide();
pCrsrShell->GetWin()->SetCursor( 0 );
}
void SwVisCrsr::Show()
{
if( !bIsVisible )
{
bIsVisible = sal_True;
// muss ueberhaupt angezeigt werden ?
if( pCrsrShell->VisArea().IsOver( pCrsrShell->aCharRect ) )
#ifdef SW_CRSR_TIMER
{
if( bTimerOn )
Start(); // Timer aufsetzen
else
{
if( IsActive() )
Stop(); // Timer Stoppen
_SetPosAndShow();
}
}
#else
_SetPosAndShow();
#endif
}
}
void SwVisCrsr::Hide()
{
if( bIsVisible )
{
bIsVisible = sal_False;
#ifdef SW_CRSR_TIMER
if( IsActive() )
Stop(); // Timer Stoppen
#endif
if( aTxtCrsr.IsVisible() ) // sollten die Flags nicht gueltig sein?
aTxtCrsr.Hide();
}
}
#ifdef SW_CRSR_TIMER
void __EXPORT SwVisCrsr::Timeout()
{
ASSERT( !bIsDragCrsr, "Timer vorher abschalten" );
if( bIsVisible )
{
if ( !pCrsrShell->GetWin() ) //SwFrmFmt::GetGraphic setzt das Win temp aus!
Start();
else
_SetPosAndShow();
}
}
sal_Bool SwCrsrShell::ChgCrsrTimerFlag( sal_Bool bTimerOn )
{
return pVisCrsr->ChgTimerFlag( bTimerOn );
}
sal_Bool SwVisCrsr::ChgTimerFlag( sal_Bool bFlag )
{
bOld = bTimerOn;
if( !bFlag && bIsVisible && IsActive() )
{
Stop(); // Timer Stoppen
_SetPosAndShow();
}
bTimerOn = bFlag;
return bOld;
}
#endif
void SwVisCrsr::_SetPosAndShow()
{
SwRect aRect;
long nTmpY = pCrsrShell->aCrsrHeight.Y();
if( 0 > nTmpY )
{
nTmpY = -nTmpY;
aTxtCrsr.SetOrientation( 900 );
aRect = SwRect( pCrsrShell->aCharRect.Pos(),
Size( pCrsrShell->aCharRect.Height(), nTmpY ) );
aRect.Pos().X() += pCrsrShell->aCrsrHeight.X();
if( pCrsrShell->IsOverwriteCrsr() )
aRect.Pos().Y() += aRect.Width();
}
else
{
aTxtCrsr.SetOrientation( 0 );
aRect = SwRect( pCrsrShell->aCharRect.Pos(),
Size( pCrsrShell->aCharRect.Width(), nTmpY ) );
aRect.Pos().Y() += pCrsrShell->aCrsrHeight.X();
}
// check if cursor should show the current cursor bidi level
aTxtCrsr.SetDirection( CURSOR_DIRECTION_NONE );
const SwCursor* pTmpCrsr = pCrsrShell->_GetCrsr();
if ( pTmpCrsr && !pCrsrShell->IsOverwriteCrsr() )
{
SwNode& rNode = pTmpCrsr->GetPoint()->nNode.GetNode();
if( rNode.IsTxtNode() )
{
const SwTxtNode& rTNd = *rNode.GetTxtNode();
const SwFrm* pFrm = rTNd.getLayoutFrm( pCrsrShell->GetLayout(), 0, 0, sal_False );
if ( pFrm )
{
const SwScriptInfo* pSI = ((SwTxtFrm*)pFrm)->GetScriptInfo();
// cursor level has to be shown
if ( pSI && pSI->CountDirChg() > 1 )
{
aTxtCrsr.SetDirection(
( pTmpCrsr->GetCrsrBidiLevel() % 2 ) ?
CURSOR_DIRECTION_RTL :
CURSOR_DIRECTION_LTR );
}
if ( pFrm->IsRightToLeft() )
{
const OutputDevice *pOut = pCrsrShell->GetOut();
if ( pOut )
{
long nSize = pOut->GetSettings().GetStyleSettings().GetCursorSize();
Size aSize( nSize, nSize );
aSize = pOut->PixelToLogic( aSize );
aRect.Left( aRect.Left() - aSize.Width() );
}
}
}
}
}
if( aRect.Height() )
{
::SwCalcPixStatics( pCrsrShell->GetOut() );
::SwAlignRect( aRect, (ViewShell*)pCrsrShell );
}
if( !pCrsrShell->IsOverwriteCrsr() || bIsDragCrsr ||
pCrsrShell->IsSelection() )
aRect.Width( 0 );
aTxtCrsr.SetSize( aRect.SSize() );
aTxtCrsr.SetPos( aRect.Pos() );
if ( !pCrsrShell->IsCrsrReadonly() || pCrsrShell->GetViewOptions()->IsSelectionInReadonly() )
{
if ( pCrsrShell->GetDrawView() )
((SwDrawView*)pCrsrShell->GetDrawView())->SetAnimationEnabled(
!pCrsrShell->IsSelection() );
sal_uInt16 nStyle = bIsDragCrsr ? CURSOR_SHADOW : 0;
if( nStyle != aTxtCrsr.GetStyle() )
{
aTxtCrsr.SetStyle( nStyle );
aTxtCrsr.SetWindow( bIsDragCrsr ? pCrsrShell->GetWin() : 0 );
}
aTxtCrsr.Show();
}
}
//////////////////////////////////////////////////////////////////////////////
SwSelPaintRects::SwSelPaintRects( const SwCrsrShell& rCSh )
: SwRects( 0 )
, pCShell( &rCSh )
, mpCursorOverlay( 0 )
, mbShowTxtInputFldOverlay( true )
, mpTxtInputFldOverlay( NULL )
{
}
SwSelPaintRects::~SwSelPaintRects()
{
Hide();
}
void SwSelPaintRects::swapContent(SwSelPaintRects& rSwap)
{
SwRects aTempRects;
aTempRects.Insert(this, 0);
Remove(0, Count());
Insert(&rSwap, 0);
rSwap.Remove(0, rSwap.Count());
rSwap.Insert(&aTempRects, 0);
// #i75172# also swap mpCursorOverlay
sdr::overlay::OverlayObject* pTempOverlay = getCursorOverlay();
setCursorOverlay(rSwap.getCursorOverlay());
rSwap.setCursorOverlay(pTempOverlay);
const bool bTempShowTxtInputFldOverlay = mbShowTxtInputFldOverlay;
mbShowTxtInputFldOverlay = rSwap.mbShowTxtInputFldOverlay;
rSwap.mbShowTxtInputFldOverlay = bTempShowTxtInputFldOverlay;
sw::overlay::OverlayRangesOutline* pTempTxtInputFldOverlay = mpTxtInputFldOverlay;
mpTxtInputFldOverlay = rSwap.mpTxtInputFldOverlay;
rSwap.mpTxtInputFldOverlay = pTempTxtInputFldOverlay;
}
void SwSelPaintRects::Hide()
{
if(mpCursorOverlay)
{
delete mpCursorOverlay;
mpCursorOverlay = 0;
}
if ( mpTxtInputFldOverlay != NULL )
{
delete mpTxtInputFldOverlay;
mpTxtInputFldOverlay = NULL;
}
SwRects::Remove( 0, Count() );
}
void SwSelPaintRects::Show()
{
SdrView* pView = (SdrView*)pCShell->GetDrawView();
if(pView && pView->PaintWindowCount())
{
// reset rects
SwRects::Remove( 0, SwRects::Count() );
FillRects();
// get new rects
std::vector< basegfx::B2DRange > aNewRanges;
for(sal_uInt16 a(0); a < Count(); a++)
{
const SwRect aNextRect((*this)[a]);
const Rectangle aPntRect(aNextRect.SVRect());
aNewRanges.push_back(basegfx::B2DRange(
aPntRect.Left(), aPntRect.Top(),
aPntRect.Right() + 1, aPntRect.Bottom() + 1));
}
if(mpCursorOverlay)
{
if(aNewRanges.size())
{
static_cast< sdr::overlay::OverlaySelection* >(mpCursorOverlay)->setRanges(aNewRanges);
}
else
{
delete mpCursorOverlay;
mpCursorOverlay = 0;
}
}
else if(Count())
{
SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
if(pTargetOverlay)
{
// get the system's hilight color
const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
// create correct selection
mpCursorOverlay = new sdr::overlay::OverlaySelection(
sdr::overlay::OVERLAY_TRANSPARENT,
aHighlight,
aNewRanges,
true);
pTargetOverlay->add(*mpCursorOverlay);
}
}
HighlightInputFld();
}
}
void SwSelPaintRects::HighlightInputFld()
{
std::vector< basegfx::B2DRange > aInputFldRanges;
if ( mbShowTxtInputFldOverlay )
{
SwTxtInputFld* pCurTxtInputFldAtCrsr =
dynamic_cast<SwTxtInputFld*>(GetShell()->GetTxtFldAtPos( GetShell()->GetCrsr()->Start(), false ));
if ( pCurTxtInputFldAtCrsr != NULL )
{
SwTxtNode* pTxtNode = pCurTxtInputFldAtCrsr->GetpTxtNode();
::boost::scoped_ptr<SwShellCrsr> pCrsrForInputTxtFld(
new SwShellCrsr( *GetShell(), SwPosition( *pTxtNode, *(pCurTxtInputFldAtCrsr->GetStart()) ) ) );
pCrsrForInputTxtFld->SetMark();
pCrsrForInputTxtFld->GetMark()->nNode = *pTxtNode;
pCrsrForInputTxtFld->GetMark()->nContent.Assign( pTxtNode, *(pCurTxtInputFldAtCrsr->End()) );
pCrsrForInputTxtFld->FillRects();
for( sal_uInt16 a(0); a < pCrsrForInputTxtFld->Count(); ++a )
{
const SwRect aNextRect((*pCrsrForInputTxtFld)[a]);
const Rectangle aPntRect(aNextRect.SVRect());
aInputFldRanges.push_back(basegfx::B2DRange(
aPntRect.Left(), aPntRect.Top(),
aPntRect.Right() + 1, aPntRect.Bottom() + 1));
}
}
}
if ( aInputFldRanges.size() > 0 )
{
if ( mpTxtInputFldOverlay != NULL )
{
mpTxtInputFldOverlay->setRanges( aInputFldRanges );
}
else
{
SdrView* pView = (SdrView*)GetShell()->GetDrawView();
SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
if(pTargetOverlay)
{
// use system's hilight color with decreased luminance as highlight color
const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
aHighlight.DecreaseLuminance( 128 );
mpTxtInputFldOverlay = new sw::overlay::OverlayRangesOutline( aHighlight, aInputFldRanges );
pTargetOverlay->add( *mpTxtInputFldOverlay );
}
}
}
else
{
if ( mpTxtInputFldOverlay != NULL )
{
delete mpTxtInputFldOverlay;
mpTxtInputFldOverlay = NULL;
}
}
}
void SwSelPaintRects::Invalidate( const SwRect& rRect )
{
sal_uInt16 nSz = Count();
if( !nSz )
return;
SwRegionRects aReg( GetShell()->VisArea() );
aReg.Remove( 0, aReg.Count() );
aReg.Insert( this, 0 );
aReg -= rRect;
SwRects::Remove( 0, nSz );
SwRects::Insert( &aReg, 0 );
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Liegt die Selection rechts oder unten ausserhalb des sichtbaren
// Bereiches, so ist diese nie auf eine Pixel rechts/unten aligned.
// Das muss hier erkannt und ggf. das Rechteckt erweitert werden.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if( GetShell()->bVisPortChgd && 0 != ( nSz = Count()) )
{
SwSelPaintRects::Get1PixelInLogic( *GetShell() );
SwRect* pRect = (SwRect*)GetData();
for( ; nSz--; ++pRect )
{
if( pRect->Right() == GetShell()->aOldRBPos.X() )
pRect->Right( pRect->Right() + nPixPtX );
if( pRect->Bottom() == GetShell()->aOldRBPos.Y() )
pRect->Bottom( pRect->Bottom() + nPixPtY );
}
}
}
void SwSelPaintRects::Paint( const Rectangle& /*rRect*/ )
{
// nothing to do with overlays
}
// check current MapMode of the shell and set possibly the static members.
// Optional set the parameters pX, pY
void SwSelPaintRects::Get1PixelInLogic( const ViewShell& rSh,
long* pX, long* pY )
{
const OutputDevice* pOut = rSh.GetWin();
if ( ! pOut )
pOut = rSh.GetOut();
const MapMode& rMM = pOut->GetMapMode();
if( pMapMode->GetMapUnit() != rMM.GetMapUnit() ||
pMapMode->GetScaleX() != rMM.GetScaleX() ||
pMapMode->GetScaleY() != rMM.GetScaleY() )
{
*pMapMode = rMM;
Size aTmp( 1, 1 );
aTmp = pOut->PixelToLogic( aTmp );
nPixPtX = aTmp.Width();
nPixPtY = aTmp.Height();
}
if( pX )
*pX = nPixPtX;
if( pY )
*pY = nPixPtY;
}
/* */
SwShellCrsr::SwShellCrsr(
const SwCrsrShell& rCShell,
const SwPosition &rPos )
: SwCursor(rPos,0,false)
, SwSelPaintRects(rCShell)
, pPt(SwPaM::GetPoint())
{}
SwShellCrsr::SwShellCrsr(
const SwCrsrShell& rCShell,
const SwPosition &rPos,
const Point& rPtPos,
SwPaM* pRing )
: SwCursor(rPos, pRing, false)
, SwSelPaintRects(rCShell)
, aMkPt(rPtPos)
, aPtPt(rPtPos)
, pPt(SwPaM::GetPoint())
{}
SwShellCrsr::SwShellCrsr( SwShellCrsr& rICrsr )
: SwCursor(rICrsr)
, SwSelPaintRects(*rICrsr.GetShell())
, aMkPt(rICrsr.GetMkPos())
, aPtPt(rICrsr.GetPtPos())
, pPt(SwPaM::GetPoint())
{}
SwShellCrsr::~SwShellCrsr()
{}
bool SwShellCrsr::IsReadOnlyAvailable() const
{
return GetShell()->IsReadOnlyAvailable();
}
void SwShellCrsr::SetMark()
{
if( SwPaM::GetPoint() == pPt )
aMkPt = aPtPt;
else
aPtPt = aMkPt;
SwPaM::SetMark();
}
void SwShellCrsr::FillRects()
{
// die neuen Rechtecke berechnen
if ( HasMark()
&& GetPoint()->nNode.GetNode().IsCntntNode()
&& GetPoint()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() )
&& ( GetMark()->nNode == GetPoint()->nNode
|| ( GetMark()->nNode.GetNode().IsCntntNode()
&& GetMark()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() ) ) ) )
{
GetShell()->GetLayout()->CalcFrmRects( *this );
}
}
void SwShellCrsr::Show()
{
SwShellCrsr * pTmp = this;
do {
pTmp->SwSelPaintRects::Show();
} while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) );
SHOWBOOKMARKS1( 1 )
SHOWREDLINES1( 1 )
}
// Dieses Rechteck wird neu gepaintet, also ist die SSelection in
// dem Bereich ungueltig
void SwShellCrsr::Invalidate( const SwRect& rRect )
{
SwShellCrsr * pTmp = this;
do
{
pTmp->SwSelPaintRects::Invalidate( rRect );
// --> FME 2005-08-18 #125102#
// skip any non SwShellCrsr objects in the ring
// (see:SwAutoFormat::DeleteSel()
// <--
Ring* pTmpRing = pTmp;
pTmp = 0;
do
{
pTmpRing = pTmpRing->GetNext();
pTmp = dynamic_cast<SwShellCrsr*>(pTmpRing);
}
while ( !pTmp );
}
while( this != pTmp );
SHOWBOOKMARKS2( 3, &rRect )
SHOWREDLINES2( 3, &rRect )
}
void SwShellCrsr::Hide()
{
SwShellCrsr * pTmp = this;
do {
pTmp->SwSelPaintRects::Hide();
} while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) );
SHOWBOOKMARKS1( 2 )
SHOWREDLINES1( 2 )
}
SwCursor* SwShellCrsr::Create( SwPaM* pRing ) const
{
return new SwShellCrsr( *GetShell(), *GetPoint(), GetPtPos(), pRing );
}
short SwShellCrsr::MaxReplaceArived()
{
short nRet = RET_YES;
Window* pDlg = LAYOUT_THIS_WINDOW (::GetSearchDialog());
if( pDlg )
{
// alte Actions beenden; die Tabellen-Frames werden angelegt und
// eine SSelection kann erzeugt werden
SvUShorts aArr;
sal_uInt16 nActCnt;
ViewShell *pShell = const_cast< SwCrsrShell* >( GetShell() ),
*pSh = pShell;
do {
for( nActCnt = 0; pSh->ActionPend(); ++nActCnt )
pSh->EndAction();
aArr.Insert( nActCnt, aArr.Count() );
} while( pShell != ( pSh = (ViewShell*)pSh->GetNext() ) );
{
nRet = QueryBox( pDlg, SW_RES( MSG_COMCORE_ASKSEARCH )).Execute();
}
for( sal_uInt16 n = 0; n < aArr.Count(); ++n )
{
for( nActCnt = aArr[n]; nActCnt--; )
pSh->StartAction();
pSh = (ViewShell*)pSh->GetNext();
} //swmod 071107//swmod 071225
}
else
// ansonsten aus dem Basic, und dann auf RET_YES schalten
nRet = RET_YES;
return nRet;
}
void SwShellCrsr::SaveTblBoxCntnt( const SwPosition* pPos )
{
((SwCrsrShell*)GetShell())->SaveTblBoxCntnt( pPos );
}
sal_Bool SwShellCrsr::UpDown( sal_Bool bUp, sal_uInt16 nCnt )
{
return SwCursor::UpDown( bUp, nCnt,
&GetPtPos(), GetShell()->GetUpDownX() );
}
#ifdef DBG_UTIL
// JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung
// am sichtbaren Cursor
sal_Bool SwShellCrsr::IsSelOvr( int eFlags )
{
return SwCursor::IsSelOvr( eFlags );
}
#endif
// sal_True: an die Position kann der Cursor gesetzt werden
sal_Bool SwShellCrsr::IsAtValidPos( sal_Bool bPoint ) const
{
if( GetShell() && ( GetShell()->IsAllProtect() ||
GetShell()->GetViewOptions()->IsReadonly() ||
( GetShell()->Imp()->GetDrawView() &&
GetShell()->Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )))
return sal_True;
return SwCursor::IsAtValidPos( bPoint );
}
/* */
SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh,
const SwPosition& rPos )
: SwCursor(rPos,0,false), SwShellCrsr(rCrsrSh, rPos), SwTableCursor(rPos)
{
}
SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh,
const SwPosition& rMkPos, const Point& rMkPt,
const SwPosition& rPtPos, const Point& rPtPt )
: SwCursor(rPtPos,0,false), SwShellCrsr(rCrsrSh, rPtPos), SwTableCursor(rPtPos)
{
SetMark();
*GetMark() = rMkPos;
GetMkPos() = rMkPt;
GetPtPos() = rPtPt;
}
SwShellTableCrsr::~SwShellTableCrsr() {}
void SwShellTableCrsr::SetMark() { SwShellCrsr::SetMark(); }
SwCursor* SwShellTableCrsr::Create( SwPaM* pRing ) const
{
return SwShellCrsr::Create( pRing );
}
short SwShellTableCrsr::MaxReplaceArived()
{
return SwShellCrsr::MaxReplaceArived();
}
void SwShellTableCrsr::SaveTblBoxCntnt( const SwPosition* pPos )
{
SwShellCrsr::SaveTblBoxCntnt( pPos );
}
void SwShellTableCrsr::FillRects()
{
// die neuen Rechtecke berechnen
// JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!!
if( !aSelBoxes.Count() || bParked ||
!GetPoint()->nNode.GetIndex() )
return;
SwRegionRects aReg( GetShell()->VisArea() );
SwNodes& rNds = GetDoc()->GetNodes();
for( sal_uInt16 n = 0; n < aSelBoxes.Count(); ++n )
{
const SwStartNode* pSttNd = (*(aSelBoxes.GetData() + n ))->GetSttNd();
const SwTableNode* pSelTblNd = pSttNd->FindTableNode();
SwNodeIndex aIdx( *pSttNd );
SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False );
// TABLE IN TABLE
// (see also lcl_FindTopLevelTable in unoobj2.cxx for a different
// version to do this)
const SwTableNode* pCurTblNd = pCNd->FindTableNode();
while ( pSelTblNd != pCurTblNd && pCurTblNd )
{
aIdx = pCurTblNd->EndOfSectionIndex();
pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False );
pCurTblNd = pCNd->FindTableNode();
}
if( !pCNd )
continue;
SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetSttPos() );
while( pFrm && !pFrm->IsCellFrm() )
pFrm = pFrm->GetUpper();
ASSERT( pFrm, "Node nicht in einer Tabelle" );
while ( pFrm )
{
if( pFrm && aReg.GetOrigin().IsOver( pFrm->Frm() ) )
aReg -= pFrm->Frm();
pFrm = pFrm->GetNextCellLeaf( MAKEPAGE_NONE );
}
}
aReg.Invert();
Insert( &aReg, 0 );
}
// Pruefe, ob sich der SPoint innerhalb der Tabellen-SSelection befindet
sal_Bool SwShellTableCrsr::IsInside( const Point& rPt ) const
{
// die neuen Rechtecke berechnen
// JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!!
if( !aSelBoxes.Count() || bParked ||
!GetPoint()->nNode.GetIndex() )
return sal_False;
SwNodes& rNds = GetDoc()->GetNodes();
for( sal_uInt16 n = 0; n < aSelBoxes.Count(); ++n )
{
SwNodeIndex aIdx( *(*(aSelBoxes.GetData() + n ))->GetSttNd() );
SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False );
if( !pCNd )
continue;
SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetPtPos() );
while( pFrm && !pFrm->IsCellFrm() )
pFrm = pFrm->GetUpper();
ASSERT( pFrm, "Node nicht in einer Tabelle" );
if( pFrm && pFrm->Frm().IsInside( rPt ) )
return sal_True;
}
return sal_False;
}
#ifdef DBG_UTIL
// JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung
// am sichtbaren Cursor
sal_Bool SwShellTableCrsr::IsSelOvr( int eFlags )
{
return SwShellCrsr::IsSelOvr( eFlags );
}
#endif
sal_Bool SwShellTableCrsr::IsAtValidPos( sal_Bool bPoint ) const
{
return SwShellCrsr::IsAtValidPos( bPoint );
}