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