Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_features.h>
21 :
22 : #include <vcl/dialog.hxx>
23 : #include <vcl/msgbox.hxx>
24 : #include <vcl/wrkwin.hxx>
25 : #include <vcl/settings.hxx>
26 : #include <viewopt.hxx>
27 : #include <frmtool.hxx>
28 : #include <viscrs.hxx>
29 : #include <crsrsh.hxx>
30 : #include <doc.hxx>
31 : #include <swtable.hxx>
32 : #include <viewimp.hxx>
33 : #include <dview.hxx>
34 : #include <rootfrm.hxx>
35 : #include <txtfrm.hxx>
36 : #include <docary.hxx>
37 : #include <extinput.hxx>
38 : #include <ndtxt.hxx>
39 : #include <txtfld.hxx>
40 : #include <scriptinfo.hxx>
41 : #include <mdiexp.hxx>
42 : #include <wrtsh.hxx>
43 : #include <comcore.hrc>
44 : #include <view.hxx>
45 :
46 : #include <svx/sdr/overlay/overlaymanager.hxx>
47 : #include <svx/sdrpaintwindow.hxx>
48 : #include <vcl/svapp.hxx>
49 : #include <svx/sdr/overlay/overlayselection.hxx>
50 : #include <overlayrangesoutline.hxx>
51 :
52 : #include <boost/scoped_ptr.hpp>
53 :
54 : #include <touch/touch.h>
55 :
56 : extern void SwCalcPixStatics( OutputDevice *pOut );
57 :
58 : // Here static members are defined. They will get changed on alteration of the
59 : // MapMode. This is done so that on ShowCrsr the same size does not have to be
60 : // expensively determined again and again.
61 :
62 : long SwSelPaintRects::nPixPtX = 0;
63 : long SwSelPaintRects::nPixPtY = 0;
64 : MapMode* SwSelPaintRects::pMapMode = 0;
65 :
66 : // ----- Starting from here: classes / methods for the non-text-cursor -----
67 :
68 0 : SwVisCrsr::SwVisCrsr( const SwCrsrShell * pCShell )
69 0 : : m_pCrsrShell( pCShell )
70 : {
71 0 : pCShell->GetWin()->SetCursor( &m_aTxtCrsr );
72 0 : m_bIsVisible = m_aTxtCrsr.IsVisible();
73 0 : m_bIsDragCrsr = false;
74 0 : m_aTxtCrsr.SetWidth( 0 );
75 0 : }
76 :
77 0 : SwVisCrsr::~SwVisCrsr()
78 : {
79 0 : if( m_bIsVisible && m_aTxtCrsr.IsVisible() )
80 0 : m_aTxtCrsr.Hide();
81 :
82 0 : m_pCrsrShell->GetWin()->SetCursor( 0 );
83 0 : }
84 :
85 0 : void SwVisCrsr::Show()
86 : {
87 0 : if( !m_bIsVisible )
88 : {
89 0 : m_bIsVisible = true;
90 :
91 : // display at all?
92 0 : if( m_pCrsrShell->VisArea().IsOver( m_pCrsrShell->m_aCharRect ) )
93 0 : _SetPosAndShow();
94 : }
95 0 : }
96 :
97 0 : void SwVisCrsr::Hide()
98 : {
99 0 : if( m_bIsVisible )
100 : {
101 0 : m_bIsVisible = false;
102 :
103 0 : if( m_aTxtCrsr.IsVisible() ) // Shouldn't the flags be in effect?
104 0 : m_aTxtCrsr.Hide();
105 : }
106 0 : }
107 :
108 0 : void SwVisCrsr::_SetPosAndShow()
109 : {
110 0 : SwRect aRect;
111 0 : long nTmpY = m_pCrsrShell->m_aCrsrHeight.getY();
112 0 : if( 0 > nTmpY )
113 : {
114 0 : nTmpY = -nTmpY;
115 0 : m_aTxtCrsr.SetOrientation( 900 );
116 0 : aRect = SwRect( m_pCrsrShell->m_aCharRect.Pos(),
117 0 : Size( m_pCrsrShell->m_aCharRect.Height(), nTmpY ) );
118 0 : aRect.Pos().setX(aRect.Pos().getX() + m_pCrsrShell->m_aCrsrHeight.getX());
119 0 : if( m_pCrsrShell->IsOverwriteCrsr() )
120 0 : aRect.Pos().setY(aRect.Pos().getY() + aRect.Width());
121 : }
122 : else
123 : {
124 0 : m_aTxtCrsr.SetOrientation( 0 );
125 0 : aRect = SwRect( m_pCrsrShell->m_aCharRect.Pos(),
126 0 : Size( m_pCrsrShell->m_aCharRect.Width(), nTmpY ) );
127 0 : aRect.Pos().setY(aRect.Pos().getY() + m_pCrsrShell->m_aCrsrHeight.getX());
128 : }
129 :
130 : // check if cursor should show the current cursor bidi level
131 0 : m_aTxtCrsr.SetDirection( CURSOR_DIRECTION_NONE );
132 0 : const SwCursor* pTmpCrsr = m_pCrsrShell->_GetCrsr();
133 :
134 0 : if ( pTmpCrsr && !m_pCrsrShell->IsOverwriteCrsr() )
135 : {
136 0 : SwNode& rNode = pTmpCrsr->GetPoint()->nNode.GetNode();
137 0 : if( rNode.IsTxtNode() )
138 : {
139 0 : const SwTxtNode& rTNd = *rNode.GetTxtNode();
140 0 : const SwFrm* pFrm = rTNd.getLayoutFrm( m_pCrsrShell->GetLayout(), 0, 0, false );
141 0 : if ( pFrm )
142 : {
143 0 : const SwScriptInfo* pSI = ((SwTxtFrm*)pFrm)->GetScriptInfo();
144 : // cursor level has to be shown
145 0 : if ( pSI && pSI->CountDirChg() > 1 )
146 : {
147 : m_aTxtCrsr.SetDirection(
148 0 : ( pTmpCrsr->GetCrsrBidiLevel() % 2 ) ?
149 : CURSOR_DIRECTION_RTL :
150 0 : CURSOR_DIRECTION_LTR );
151 : }
152 0 : if ( pFrm->IsRightToLeft() )
153 : {
154 0 : const OutputDevice *pOut = m_pCrsrShell->GetOut();
155 0 : if ( pOut )
156 : {
157 0 : long nSize = pOut->GetSettings().GetStyleSettings().GetCursorSize();
158 0 : Size aSize( nSize, nSize );
159 0 : aSize = pOut->PixelToLogic( aSize );
160 0 : aRect.Left( aRect.Left() - aSize.Width() );
161 : }
162 : }
163 : }
164 : }
165 : }
166 :
167 0 : if( aRect.Height() )
168 : {
169 0 : ::SwCalcPixStatics( m_pCrsrShell->GetOut() );
170 0 : ::SwAlignRect( aRect, (SwViewShell*)m_pCrsrShell );
171 : }
172 0 : if( !m_pCrsrShell->IsOverwriteCrsr() || m_bIsDragCrsr ||
173 0 : m_pCrsrShell->IsSelection() )
174 0 : aRect.Width( 0 );
175 :
176 0 : m_aTxtCrsr.SetSize( aRect.SSize() );
177 :
178 0 : m_aTxtCrsr.SetPos( aRect.Pos() );
179 0 : if ( !m_pCrsrShell->IsCrsrReadonly() || m_pCrsrShell->GetViewOptions()->IsSelectionInReadonly() )
180 : {
181 0 : if ( m_pCrsrShell->GetDrawView() )
182 0 : ((SwDrawView*)m_pCrsrShell->GetDrawView())->SetAnimationEnabled(
183 0 : !m_pCrsrShell->IsSelection() );
184 :
185 0 : sal_uInt16 nStyle = m_bIsDragCrsr ? CURSOR_SHADOW : 0;
186 0 : if( nStyle != m_aTxtCrsr.GetStyle() )
187 : {
188 0 : m_aTxtCrsr.SetStyle( nStyle );
189 0 : m_aTxtCrsr.SetWindow( m_bIsDragCrsr ? m_pCrsrShell->GetWin() : 0 );
190 : }
191 :
192 0 : m_aTxtCrsr.Show();
193 : }
194 0 : }
195 :
196 0 : SwSelPaintRects::SwSelPaintRects( const SwCrsrShell& rCSh )
197 : : SwRects()
198 : , pCShell( &rCSh )
199 : #if HAVE_FEATURE_DESKTOP
200 : , mpCursorOverlay( 0 )
201 : , mbShowTxtInputFldOverlay( true )
202 0 : , mpTxtInputFldOverlay( NULL )
203 : #endif
204 : {
205 0 : }
206 :
207 0 : SwSelPaintRects::~SwSelPaintRects()
208 : {
209 0 : Hide();
210 0 : }
211 :
212 0 : void SwSelPaintRects::swapContent(SwSelPaintRects& rSwap)
213 : {
214 0 : SwRects::swap(rSwap);
215 :
216 : #if HAVE_FEATURE_DESKTOP
217 : // #i75172# also swap mpCursorOverlay
218 0 : sdr::overlay::OverlayObject* pTempOverlay = getCursorOverlay();
219 0 : setCursorOverlay(rSwap.getCursorOverlay());
220 0 : rSwap.setCursorOverlay(pTempOverlay);
221 :
222 0 : const bool bTempShowTxtInputFldOverlay = mbShowTxtInputFldOverlay;
223 0 : mbShowTxtInputFldOverlay = rSwap.mbShowTxtInputFldOverlay;
224 0 : rSwap.mbShowTxtInputFldOverlay = bTempShowTxtInputFldOverlay;
225 :
226 0 : sw::overlay::OverlayRangesOutline* pTempTxtInputFldOverlay = mpTxtInputFldOverlay;
227 0 : mpTxtInputFldOverlay = rSwap.mpTxtInputFldOverlay;
228 0 : rSwap.mpTxtInputFldOverlay = pTempTxtInputFldOverlay;
229 : #endif
230 0 : }
231 :
232 0 : void SwSelPaintRects::Hide()
233 : {
234 : #if HAVE_FEATURE_DESKTOP
235 0 : if(mpCursorOverlay)
236 : {
237 0 : delete mpCursorOverlay;
238 0 : mpCursorOverlay = 0;
239 : }
240 :
241 0 : if ( mpTxtInputFldOverlay != NULL )
242 : {
243 0 : delete mpTxtInputFldOverlay;
244 0 : mpTxtInputFldOverlay = NULL;
245 : }
246 : #endif
247 :
248 0 : SwRects::clear();
249 0 : }
250 :
251 0 : void SwSelPaintRects::Show()
252 : {
253 0 : SdrView* pView = (SdrView*)pCShell->GetDrawView();
254 :
255 0 : if(pView && pView->PaintWindowCount())
256 : {
257 : // reset rects
258 0 : SwRects::clear();
259 0 : FillRects();
260 :
261 : #if HAVE_FEATURE_DESKTOP
262 : // get new rects
263 0 : std::vector< basegfx::B2DRange > aNewRanges;
264 :
265 0 : for(sal_uInt16 a(0); a < size(); a++)
266 : {
267 0 : const SwRect aNextRect((*this)[a]);
268 0 : const Rectangle aPntRect(aNextRect.SVRect());
269 :
270 : aNewRanges.push_back(basegfx::B2DRange(
271 0 : aPntRect.Left(), aPntRect.Top(),
272 0 : aPntRect.Right() + 1, aPntRect.Bottom() + 1));
273 : }
274 :
275 0 : if(mpCursorOverlay)
276 : {
277 0 : if(!aNewRanges.empty())
278 : {
279 0 : static_cast< sdr::overlay::OverlaySelection* >(mpCursorOverlay)->setRanges(aNewRanges);
280 : }
281 : else
282 : {
283 0 : delete mpCursorOverlay;
284 0 : mpCursorOverlay = 0;
285 : }
286 : }
287 0 : else if(!empty())
288 : {
289 0 : SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
290 0 : rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
291 :
292 0 : if (xTargetOverlay.is())
293 : {
294 : // get the system's hilight color
295 0 : const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
296 0 : const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
297 :
298 : // create correct selection
299 : mpCursorOverlay = new sdr::overlay::OverlaySelection(
300 : sdr::overlay::OVERLAY_TRANSPARENT,
301 : aHighlight,
302 : aNewRanges,
303 0 : true);
304 :
305 0 : xTargetOverlay->add(*mpCursorOverlay);
306 0 : }
307 : }
308 :
309 0 : HighlightInputFld();
310 : #else
311 : const OutputDevice* pOut = GetShell()->GetWin();
312 : if ( ! pOut )
313 : pOut = GetShell()->GetOut();
314 : SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(const_cast<SwCrsrShell*>(GetShell()));
315 : if (!empty())
316 : {
317 : if (pWrtShell)
318 : {
319 : // Buffer will be deallocated in the UI layer
320 : MLORect *rects = (MLORect *) malloc((sizeof(MLORect))*size());
321 : for (size_t i = 0; i < size(); ++i)
322 : {
323 : Point origin = pOut->LogicToPixel((*this)[i].Pos());
324 : Size ssize = pOut->LogicToPixel((*this)[i].SSize());
325 : #ifdef IOS
326 : rects[i] = CGRectMake(origin.X(), origin.Y(),
327 : ssize.Width(), ssize.Height());
328 : #else
329 : // Not yet implemented
330 : (void) origin;
331 : (void) ssize;
332 : #endif
333 : }
334 : // GetShell returns a SwCrsrShell which actually is a SwWrtShell
335 : touch_ui_selection_start(MLOSelectionText, pWrtShell, rects, size(), NULL);
336 : }
337 : }
338 : else
339 : {
340 : touch_ui_selection_none();
341 : }
342 : #endif
343 : }
344 0 : }
345 :
346 : #if !HAVE_FEATURE_DESKTOP
347 :
348 : extern "C" void touch_lo_selection_attempt_resize(const void * /* documentHandle */,
349 : MLORect * /* selectedRectangles */,
350 : int /* numberOfRectangles */)
351 : {
352 : }
353 :
354 : #endif
355 :
356 0 : void SwSelPaintRects::HighlightInputFld()
357 : {
358 0 : std::vector< basegfx::B2DRange > aInputFldRanges;
359 :
360 0 : if ( mbShowTxtInputFldOverlay )
361 : {
362 : SwTxtInputFld* pCurTxtInputFldAtCrsr =
363 0 : dynamic_cast<SwTxtInputFld*>(GetShell()->GetTxtFldAtPos( GetShell()->GetCrsr()->Start(), false ));
364 0 : if ( pCurTxtInputFldAtCrsr != NULL )
365 : {
366 0 : SwTxtNode* pTxtNode = pCurTxtInputFldAtCrsr->GetpTxtNode();
367 : ::boost::scoped_ptr<SwShellCrsr> pCrsrForInputTxtFld(
368 0 : new SwShellCrsr( *GetShell(), SwPosition( *pTxtNode, *(pCurTxtInputFldAtCrsr->GetStart()) ) ) );
369 0 : pCrsrForInputTxtFld->SetMark();
370 0 : pCrsrForInputTxtFld->GetMark()->nNode = *pTxtNode;
371 0 : pCrsrForInputTxtFld->GetMark()->nContent.Assign( pTxtNode, *(pCurTxtInputFldAtCrsr->End()) );
372 :
373 0 : pCrsrForInputTxtFld->FillRects();
374 :
375 0 : for (size_t a(0); a < pCrsrForInputTxtFld->size(); ++a)
376 : {
377 0 : const SwRect aNextRect((*pCrsrForInputTxtFld)[a]);
378 0 : const Rectangle aPntRect(aNextRect.SVRect());
379 :
380 : aInputFldRanges.push_back(basegfx::B2DRange(
381 0 : aPntRect.Left(), aPntRect.Top(),
382 0 : aPntRect.Right() + 1, aPntRect.Bottom() + 1));
383 0 : }
384 : }
385 : }
386 :
387 0 : if ( aInputFldRanges.size() > 0 )
388 : {
389 0 : if ( mpTxtInputFldOverlay != NULL )
390 : {
391 0 : mpTxtInputFldOverlay->setRanges( aInputFldRanges );
392 : }
393 : else
394 : {
395 0 : SdrView* pView = (SdrView*)GetShell()->GetDrawView();
396 0 : SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
397 0 : rtl::Reference<sdr::overlay::OverlayManager> xTargetOverlay = pCandidate->GetOverlayManager();
398 :
399 0 : if (xTargetOverlay.is())
400 : {
401 : // use system's hilight color with decreased luminance as highlight color
402 0 : const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
403 0 : Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
404 0 : aHighlight.DecreaseLuminance( 128 );
405 :
406 0 : mpTxtInputFldOverlay = new sw::overlay::OverlayRangesOutline( aHighlight, aInputFldRanges );
407 0 : xTargetOverlay->add( *mpTxtInputFldOverlay );
408 0 : }
409 : }
410 : }
411 : else
412 : {
413 0 : if ( mpTxtInputFldOverlay != NULL )
414 : {
415 0 : delete mpTxtInputFldOverlay;
416 0 : mpTxtInputFldOverlay = NULL;
417 : }
418 0 : }
419 0 : }
420 :
421 0 : void SwSelPaintRects::Invalidate( const SwRect& rRect )
422 : {
423 0 : sal_uInt16 nSz = size();
424 0 : if( !nSz )
425 0 : return;
426 :
427 0 : SwRegionRects aReg( GetShell()->VisArea() );
428 0 : aReg.assign( begin(), end() );
429 0 : aReg -= rRect;
430 0 : SwRects::erase( begin(), begin() + nSz );
431 0 : SwRects::insert( begin(), aReg.begin(), aReg.end() );
432 :
433 : // If the selection is to the right or at the bottom, outside the
434 : // visible area, it is never aligned on one pixel at the right/bottom.
435 : // This has to be determined here and if that is the case the
436 : // rectangle has to be expanded.
437 0 : if( GetShell()->m_bVisPortChgd && 0 != ( nSz = size()) )
438 : {
439 0 : SwSelPaintRects::Get1PixelInLogic( *GetShell() );
440 0 : iterator it = begin();
441 0 : for( ; nSz--; ++it )
442 : {
443 0 : SwRect& rRectIt = *it;
444 0 : if( rRectIt.Right() == GetShell()->m_aOldRBPos.X() )
445 0 : rRectIt.Right( rRectIt.Right() + nPixPtX );
446 0 : if( rRectIt.Bottom() == GetShell()->m_aOldRBPos.Y() )
447 0 : rRectIt.Bottom( rRectIt.Bottom() + nPixPtY );
448 : }
449 0 : }
450 : }
451 :
452 0 : void SwSelPaintRects::Paint( const Rectangle& /*rRect*/ )
453 : {
454 : // nothing to do with overlays
455 0 : }
456 :
457 : // check current MapMode of the shell and set possibly the static members.
458 : // Optional set the parameters pX, pY
459 0 : void SwSelPaintRects::Get1PixelInLogic( const SwViewShell& rSh,
460 : long* pX, long* pY )
461 : {
462 0 : const OutputDevice* pOut = rSh.GetWin();
463 0 : if ( ! pOut )
464 0 : pOut = rSh.GetOut();
465 :
466 0 : const MapMode& rMM = pOut->GetMapMode();
467 0 : if( pMapMode->GetMapUnit() != rMM.GetMapUnit() ||
468 0 : pMapMode->GetScaleX() != rMM.GetScaleX() ||
469 0 : pMapMode->GetScaleY() != rMM.GetScaleY() )
470 : {
471 0 : *pMapMode = rMM;
472 0 : Size aTmp( 1, 1 );
473 0 : aTmp = pOut->PixelToLogic( aTmp );
474 0 : nPixPtX = aTmp.Width();
475 0 : nPixPtY = aTmp.Height();
476 : }
477 0 : if( pX )
478 0 : *pX = nPixPtX;
479 0 : if( pY )
480 0 : *pY = nPixPtY;
481 0 : }
482 :
483 0 : SwShellCrsr::SwShellCrsr(
484 : const SwCrsrShell& rCShell,
485 : const SwPosition &rPos )
486 : : SwCursor(rPos,0,false)
487 : , SwSelPaintRects(rCShell)
488 0 : , pPt(SwPaM::GetPoint())
489 0 : {}
490 :
491 0 : SwShellCrsr::SwShellCrsr(
492 : const SwCrsrShell& rCShell,
493 : const SwPosition &rPos,
494 : const Point& rPtPos,
495 : SwPaM* pRing )
496 : : SwCursor(rPos, pRing, false)
497 : , SwSelPaintRects(rCShell)
498 : , aMkPt(rPtPos)
499 : , aPtPt(rPtPos)
500 0 : , pPt(SwPaM::GetPoint())
501 0 : {}
502 :
503 0 : SwShellCrsr::SwShellCrsr( SwShellCrsr& rICrsr )
504 : : SwCursor(rICrsr)
505 0 : , SwSelPaintRects(*rICrsr.GetShell())
506 0 : , aMkPt(rICrsr.GetMkPos())
507 0 : , aPtPt(rICrsr.GetPtPos())
508 0 : , pPt(SwPaM::GetPoint())
509 0 : {}
510 :
511 0 : SwShellCrsr::~SwShellCrsr()
512 0 : {}
513 :
514 0 : bool SwShellCrsr::IsReadOnlyAvailable() const
515 : {
516 0 : return GetShell()->IsReadOnlyAvailable();
517 : }
518 :
519 0 : void SwShellCrsr::SetMark()
520 : {
521 0 : if( SwPaM::GetPoint() == pPt )
522 0 : aMkPt = aPtPt;
523 : else
524 0 : aPtPt = aMkPt;
525 0 : SwPaM::SetMark();
526 0 : }
527 :
528 0 : void SwShellCrsr::FillRects()
529 : {
530 : // calculate the new rectangles
531 0 : if( HasMark() &&
532 0 : GetPoint()->nNode.GetNode().IsCntntNode() &&
533 0 : GetPoint()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() ) &&
534 0 : (GetMark()->nNode == GetPoint()->nNode ||
535 0 : (GetMark()->nNode.GetNode().IsCntntNode() &&
536 0 : GetMark()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() ) ) ))
537 0 : GetShell()->GetLayout()->CalcFrmRects( *this, GetShell()->IsTableMode() );
538 0 : }
539 :
540 0 : void SwShellCrsr::Show()
541 : {
542 0 : SwShellCrsr * pTmp = this;
543 0 : do {
544 0 : pTmp->SwSelPaintRects::Show();
545 0 : } while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) );
546 0 : }
547 :
548 : // This rectangle gets painted anew, therefore the SSelection in this
549 : // area is invalid.
550 0 : void SwShellCrsr::Invalidate( const SwRect& rRect )
551 : {
552 0 : SwShellCrsr * pTmp = this;
553 :
554 0 : do
555 : {
556 0 : pTmp->SwSelPaintRects::Invalidate( rRect );
557 :
558 : // skip any non SwShellCrsr objects in the ring
559 : // see also: SwAutoFormat::DeleteSel()
560 0 : Ring* pTmpRing = pTmp;
561 0 : pTmp = 0;
562 0 : do
563 : {
564 0 : pTmpRing = pTmpRing->GetNext();
565 0 : pTmp = dynamic_cast<SwShellCrsr*>(pTmpRing);
566 : }
567 : while ( !pTmp );
568 : }
569 : while( this != pTmp );
570 0 : }
571 :
572 0 : void SwShellCrsr::Hide()
573 : {
574 0 : SwShellCrsr * pTmp = this;
575 0 : do {
576 0 : pTmp->SwSelPaintRects::Hide();
577 0 : } while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) );
578 0 : }
579 :
580 0 : SwCursor* SwShellCrsr::Create( SwPaM* pRing ) const
581 : {
582 0 : return new SwShellCrsr( *GetShell(), *GetPoint(), GetPtPos(), pRing );
583 : }
584 :
585 0 : short SwShellCrsr::MaxReplaceArived()
586 : {
587 0 : short nRet = RET_YES;
588 0 : Window* pDlg = (Window*) SwView::GetSearchDialog();
589 0 : if( pDlg )
590 : {
591 : // Terminate old actions. The table-frames get constructed and
592 : // a SSelection can be created.
593 0 : std::vector<sal_uInt16> aArr;
594 : sal_uInt16 nActCnt;
595 0 : SwViewShell *pShell = const_cast< SwCrsrShell* >( GetShell() ),
596 0 : *pSh = pShell;
597 0 : do {
598 0 : for( nActCnt = 0; pSh->ActionPend(); ++nActCnt )
599 0 : pSh->EndAction();
600 0 : aArr.push_back( nActCnt );
601 0 : } while( pShell != ( pSh = (SwViewShell*)pSh->GetNext() ) );
602 :
603 : {
604 0 : nRet = QueryBox( pDlg, SW_RES( MSG_COMCORE_ASKSEARCH )).Execute();
605 : }
606 :
607 0 : for( sal_uInt16 n = 0; n < aArr.size(); ++n )
608 : {
609 0 : for( nActCnt = aArr[n]; nActCnt--; )
610 0 : pSh->StartAction();
611 0 : pSh = (SwViewShell*)pSh->GetNext();
612 0 : }
613 : }
614 : else
615 : // otherwise from the Basic, and than switch to RET_YES
616 0 : nRet = RET_YES;
617 :
618 0 : return nRet;
619 : }
620 :
621 0 : void SwShellCrsr::SaveTblBoxCntnt( const SwPosition* pPos )
622 : {
623 0 : ((SwCrsrShell*)GetShell())->SaveTblBoxCntnt( pPos );
624 0 : }
625 :
626 0 : bool SwShellCrsr::UpDown( bool bUp, sal_uInt16 nCnt )
627 : {
628 : return SwCursor::UpDown( bUp, nCnt,
629 0 : &GetPtPos(), GetShell()->GetUpDownX() );
630 : }
631 :
632 : // if <true> than the cursor can be set to the position.
633 0 : bool SwShellCrsr::IsAtValidPos( bool bPoint ) const
634 : {
635 0 : if( GetShell() && ( GetShell()->IsAllProtect() ||
636 0 : GetShell()->GetViewOptions()->IsReadonly() ||
637 0 : ( GetShell()->Imp()->GetDrawView() &&
638 0 : GetShell()->Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )))
639 0 : return true;
640 :
641 0 : return SwCursor::IsAtValidPos( bPoint );
642 : }
643 :
644 0 : SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh,
645 : const SwPosition& rPos )
646 0 : : SwCursor(rPos,0,false), SwShellCrsr(rCrsrSh, rPos), SwTableCursor(rPos)
647 : {
648 0 : }
649 :
650 0 : SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh,
651 : const SwPosition& rMkPos, const Point& rMkPt,
652 : const SwPosition& rPtPos, const Point& rPtPt )
653 0 : : SwCursor(rPtPos,0,false), SwShellCrsr(rCrsrSh, rPtPos), SwTableCursor(rPtPos)
654 : {
655 0 : SetMark();
656 0 : *GetMark() = rMkPos;
657 0 : GetMkPos() = rMkPt;
658 0 : GetPtPos() = rPtPt;
659 0 : }
660 :
661 0 : SwShellTableCrsr::~SwShellTableCrsr() {}
662 :
663 0 : void SwShellTableCrsr::SetMark() { SwShellCrsr::SetMark(); }
664 :
665 0 : SwCursor* SwShellTableCrsr::Create( SwPaM* pRing ) const
666 : {
667 0 : return SwShellCrsr::Create( pRing );
668 : }
669 :
670 0 : short SwShellTableCrsr::MaxReplaceArived()
671 : {
672 0 : return SwShellCrsr::MaxReplaceArived();
673 : }
674 :
675 0 : void SwShellTableCrsr::SaveTblBoxCntnt( const SwPosition* pPos )
676 : {
677 0 : SwShellCrsr::SaveTblBoxCntnt( pPos );
678 0 : }
679 :
680 0 : void SwShellTableCrsr::FillRects()
681 : {
682 : // Calculate the new rectangles. If the cursor is still "parked" do nothing
683 0 : if (m_SelectedBoxes.empty() || bParked || !GetPoint()->nNode.GetIndex())
684 0 : return;
685 :
686 0 : SwRegionRects aReg( GetShell()->VisArea() );
687 0 : SwNodes& rNds = GetDoc()->GetNodes();
688 0 : for (size_t n = 0; n < m_SelectedBoxes.size(); ++n)
689 : {
690 0 : const SwStartNode* pSttNd = m_SelectedBoxes[n]->GetSttNd();
691 0 : const SwTableNode* pSelTblNd = pSttNd->FindTableNode();
692 :
693 0 : SwNodeIndex aIdx( *pSttNd );
694 0 : SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, true, false );
695 :
696 : // table in table
697 : // (see also lcl_FindTopLevelTable in unoobj2.cxx for a different
698 : // version to do this)
699 0 : const SwTableNode* pCurTblNd = pCNd ? pCNd->FindTableNode() : NULL;
700 0 : while ( pSelTblNd != pCurTblNd && pCurTblNd )
701 : {
702 0 : aIdx = pCurTblNd->EndOfSectionIndex();
703 0 : pCNd = rNds.GoNextSection( &aIdx, true, false );
704 0 : pCurTblNd = pCNd->FindTableNode();
705 : }
706 :
707 0 : if( !pCNd )
708 0 : continue;
709 :
710 0 : SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetSttPos() );
711 0 : while( pFrm && !pFrm->IsCellFrm() )
712 0 : pFrm = pFrm->GetUpper();
713 :
714 : OSL_ENSURE( pFrm, "Node not in a table" );
715 :
716 0 : while ( pFrm )
717 : {
718 0 : if( aReg.GetOrigin().IsOver( pFrm->Frm() ) )
719 0 : aReg -= pFrm->Frm();
720 :
721 0 : pFrm = pFrm->GetNextCellLeaf( MAKEPAGE_NONE );
722 : }
723 0 : }
724 0 : aReg.Invert();
725 0 : insert( begin(), aReg.begin(), aReg.end() );
726 : }
727 :
728 : // Check if the SPoint is within the Table-SSelection.
729 0 : bool SwShellTableCrsr::IsInside( const Point& rPt ) const
730 : {
731 : // Calculate the new rectangles. If the cursor is still "parked" do nothing
732 0 : if (m_SelectedBoxes.empty() || bParked || !GetPoint()->nNode.GetIndex())
733 0 : return false;
734 :
735 0 : SwNodes& rNds = GetDoc()->GetNodes();
736 0 : for (size_t n = 0; n < m_SelectedBoxes.size(); ++n)
737 : {
738 0 : SwNodeIndex aIdx( *m_SelectedBoxes[n]->GetSttNd() );
739 0 : SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, true, false );
740 0 : if( !pCNd )
741 0 : continue;
742 :
743 0 : SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetPtPos() );
744 0 : while( pFrm && !pFrm->IsCellFrm() )
745 0 : pFrm = pFrm->GetUpper();
746 : OSL_ENSURE( pFrm, "Node not in a table" );
747 0 : if( pFrm && pFrm->Frm().IsInside( rPt ) )
748 0 : return true;
749 0 : }
750 0 : return false;
751 : }
752 :
753 0 : bool SwShellTableCrsr::IsAtValidPos( bool bPoint ) const
754 : {
755 0 : return SwShellCrsr::IsAtValidPos( bPoint );
756 : }
757 :
758 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|