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 <hintids.hxx>
21 :
22 : #include <tools/errinf.hxx>
23 : #include <vcl/svapp.hxx>
24 : #include <basegfx/vector/b2dvector.hxx>
25 : #include <svx/svxids.hrc>
26 : #include <editeng/protitem.hxx>
27 : #include <editeng/brushitem.hxx>
28 : #include <editeng/frmdiritem.hxx>
29 : #include <svtools/ruler.hxx>
30 : #include <swwait.hxx>
31 : #include <fmtfsize.hxx>
32 : #include <fmtornt.hxx>
33 : #include <frmatr.hxx>
34 : #include <docary.hxx>
35 : #include <fesh.hxx>
36 : #include <doc.hxx>
37 : #include <IDocumentState.hxx>
38 : #include <IDocumentLayoutAccess.hxx>
39 : #include <cntfrm.hxx>
40 : #include <rootfrm.hxx>
41 : #include <pagefrm.hxx>
42 : #include <tabfrm.hxx>
43 : #include <rowfrm.hxx>
44 : #include <cellfrm.hxx>
45 : #include <flyfrm.hxx>
46 : #include <dflyobj.hxx>
47 : #include <swtable.hxx>
48 : #include <swddetbl.hxx>
49 : #include <ndtxt.hxx>
50 : #include <calc.hxx>
51 : #include <tabcol.hxx>
52 : #include <cellatr.hxx>
53 : #include <pam.hxx>
54 : #include <pamtyp.hxx>
55 : #include <viscrs.hxx>
56 : #include <tblsel.hxx>
57 : #include <swtblfmt.hxx>
58 : #include <swerror.h>
59 : #include <swundo.hxx>
60 : #include <frmtool.hxx>
61 :
62 : #include <node.hxx>
63 : #include <sortedobjs.hxx>
64 :
65 : using namespace ::com::sun::star;
66 :
67 : // also see swtable.cxx
68 : #define COLFUZZY 20L
69 :
70 0 : inline bool IsSame( long nA, long nB ) { return std::abs(nA-nB) <= COLFUZZY; }
71 :
72 : // table column cache
73 : SwTabCols *pLastCols = 0;
74 : const SwTable *pColumnCacheLastTable = 0;
75 : const SwTabFrm *pColumnCacheLastTabFrm = 0;
76 : const SwFrm *pColumnCacheLastCellFrm = 0;
77 :
78 : // table row cache
79 : SwTabCols *pLastRows = 0;
80 : const SwTable *pRowCacheLastTable = 0;
81 : const SwTabFrm *pRowCacheLastTabFrm = 0;
82 : const SwFrm *pRowCacheLastCellFrm = 0;
83 :
84 : class TblWait
85 : {
86 : SwWait *pWait;
87 : public:
88 : TblWait(size_t nCnt, SwFrm *pFrm, SwDocShell &rDocShell, size_t nCnt2 = 0);
89 4 : ~TblWait() { delete pWait; }
90 : };
91 :
92 4 : TblWait::TblWait(size_t const nCnt, SwFrm *pFrm, SwDocShell &rDocShell, size_t const nCnt2):
93 4 : pWait( 0 )
94 : {
95 8 : bool bWait = 20 < nCnt || 20 < nCnt2 || (pFrm &&
96 8 : 20 < pFrm->ImplFindTabFrm()->GetTable()->GetTabLines().size());
97 4 : if( bWait )
98 0 : pWait = new SwWait( rDocShell, true );
99 4 : }
100 :
101 0 : void SwFEShell::ParkCursorInTab()
102 : {
103 0 : SwCursor * pSwCrsr = GetSwCrsr();
104 :
105 : OSL_ENSURE(pSwCrsr, "no SwCursor");
106 :
107 0 : SwPosition aStartPos = *pSwCrsr->GetPoint(), aEndPos = aStartPos;
108 :
109 0 : SwCursor * pTmpCrsr = (SwCursor *) pSwCrsr;
110 :
111 : /* Search least and greatest position in current cursor ring.
112 : */
113 0 : do
114 : {
115 0 : const SwPosition * pPt = pTmpCrsr->GetPoint(),
116 0 : * pMk = pTmpCrsr->GetMark();
117 :
118 0 : if (*pPt < aStartPos)
119 0 : aStartPos = *pPt;
120 :
121 0 : if (*pPt > aEndPos)
122 0 : aEndPos = *pPt;
123 :
124 0 : if (*pMk < aStartPos)
125 0 : aStartPos = *pMk;
126 :
127 0 : if (*pMk > aEndPos)
128 0 : aEndPos = *pMk;
129 :
130 0 : pTmpCrsr = (SwCursor *) pTmpCrsr->GetNext();
131 : }
132 : while (pTmpCrsr != pSwCrsr);
133 :
134 0 : KillPams();
135 :
136 : /* @@@ semantic: SwCursor::operator=() is not implemented @@@ */
137 :
138 : /* Set cursor to end of selection to ensure IsLastCellInRow works
139 : properly. */
140 : {
141 0 : SwCursor aTmpCrsr( aEndPos, 0, false );
142 0 : *pSwCrsr = aTmpCrsr;
143 : }
144 :
145 : /* Move the cursor out of the columns to delete and stay in the
146 : same row. If the table has only one column the cursor will
147 : stay in the row and the shell will take care of it. */
148 0 : if (IsLastCellInRow())
149 : {
150 : /* If the cursor is in the last row of the table, first
151 : try to move it to the previous cell. If that fails move
152 : it to the next cell. */
153 :
154 : {
155 0 : SwCursor aTmpCrsr( aStartPos, 0, false );
156 0 : *pSwCrsr = aTmpCrsr;
157 : }
158 :
159 0 : if (! pSwCrsr->GoPrevCell())
160 : {
161 0 : SwCursor aTmpCrsr( aEndPos, 0, false );
162 0 : *pSwCrsr = aTmpCrsr;
163 0 : pSwCrsr->GoNextCell();
164 : }
165 : }
166 : else
167 : {
168 : /* If the cursor is not in the last row of the table, first
169 : try to move it to the next cell. If that fails move it
170 : to the previous cell. */
171 :
172 : {
173 0 : SwCursor aTmpCrsr( aEndPos, 0, false );
174 0 : *pSwCrsr = aTmpCrsr;
175 : }
176 :
177 0 : if (! pSwCrsr->GoNextCell())
178 : {
179 0 : SwCursor aTmpCrsr( aStartPos, 0, false );
180 0 : *pSwCrsr = aTmpCrsr;
181 0 : pSwCrsr->GoPrevCell();
182 : }
183 0 : }
184 0 : }
185 :
186 4 : bool SwFEShell::InsertRow( sal_uInt16 nCnt, bool bBehind )
187 : {
188 : // check if Point/Mark of current cursor are in a table
189 4 : SwFrm *pFrm = GetCurrFrm();
190 4 : if( !pFrm || !pFrm->IsInTab() )
191 0 : return false;
192 :
193 4 : if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
194 : {
195 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
196 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
197 0 : return false;
198 : }
199 :
200 4 : SET_CURR_SHELL( this );
201 4 : StartAllAction();
202 :
203 : // search boxes via the layout
204 8 : SwSelBoxes aBoxes;
205 4 : bool bSelectAll = StartsWithTable() && ExtendedSelectedAll(/*bFootnotes=*/false);
206 4 : if (bSelectAll)
207 : {
208 : // Set the end of the selection to the last paragraph of the last cell of the table.
209 2 : SwPaM* pPaM = getShellCrsr(false);
210 2 : SwNode* pNode = pPaM->Start()->nNode.GetNode().FindTableNode()->EndOfSectionNode();
211 : // pNode is the end node of the table, we want the last node before the end node of the last cell.
212 2 : pPaM->End()->nNode = pNode->GetIndex() - 2;
213 2 : pPaM->End()->nContent.Assign(pPaM->End()->nNode.GetNode().GetCntntNode(), 0);
214 : }
215 4 : GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
216 :
217 4 : TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.size() );
218 :
219 4 : bool bRet = false;
220 4 : if ( aBoxes.size() )
221 4 : bRet = GetDoc()->InsertRow( aBoxes, nCnt, bBehind );
222 :
223 4 : EndAllActionAndCall();
224 8 : return bRet;
225 : }
226 :
227 0 : bool SwFEShell::InsertCol( sal_uInt16 nCnt, bool bBehind )
228 : {
229 : // check if Point/Mark of current cursor are in a table
230 0 : SwFrm *pFrm = GetCurrFrm();
231 0 : if( !pFrm || !pFrm->IsInTab() )
232 0 : return false;
233 :
234 0 : if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
235 : {
236 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
237 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
238 0 : return false;
239 : }
240 :
241 0 : SET_CURR_SHELL( this );
242 :
243 0 : if( !CheckSplitCells( *this, nCnt + 1, nsSwTblSearchType::TBLSEARCH_COL ) )
244 : {
245 : ErrorHandler::HandleError( ERR_TBLINSCOL_ERROR,
246 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
247 0 : return false;
248 : }
249 :
250 0 : StartAllAction();
251 : // search boxes via the layout
252 0 : SwSelBoxes aBoxes;
253 0 : GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
254 :
255 0 : TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.size() );
256 :
257 0 : bool bRet = false;
258 0 : if( !aBoxes.empty() )
259 0 : bRet = GetDoc()->InsertCol( aBoxes, nCnt, bBehind );
260 :
261 0 : EndAllActionAndCall();
262 0 : return bRet;
263 : }
264 :
265 : // Determines if the current cursor is in the last row of the table.
266 0 : bool SwFEShell::IsLastCellInRow() const
267 : {
268 0 : SwTabCols aTabCols;
269 0 : GetTabCols( aTabCols );
270 0 : bool bResult = false;
271 :
272 0 : if (IsTableRightToLeft())
273 : /* If the table is right-to-left the last row is the most left one. */
274 0 : bResult = 0 == GetCurTabColNum();
275 : else
276 : /* If the table is left-to-right the last row is the most right one. */
277 0 : bResult = aTabCols.Count() == GetCurTabColNum();
278 :
279 0 : return bResult;
280 : }
281 :
282 0 : bool SwFEShell::DeleteCol()
283 : {
284 : // check if Point/Mark of current cursor are in a table
285 0 : SwFrm *pFrm = GetCurrFrm();
286 0 : if( !pFrm || !pFrm->IsInTab() )
287 0 : return false;
288 :
289 0 : if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
290 : {
291 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
292 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
293 0 : return false;
294 : }
295 :
296 0 : SET_CURR_SHELL( this );
297 0 : StartAllAction();
298 :
299 : // search boxes via the layout
300 : bool bRet;
301 0 : SwSelBoxes aBoxes;
302 0 : GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
303 0 : if ( !aBoxes.empty() )
304 : {
305 0 : TblWait( aBoxes.size(), pFrm, *GetDoc()->GetDocShell() );
306 :
307 : // remove crsr from the deletion area.
308 : // Put them behind/on the table; via the
309 : // document position they will be put to the old position
310 0 : while( !pFrm->IsCellFrm() )
311 0 : pFrm = pFrm->GetUpper();
312 :
313 0 : ParkCursorInTab();
314 :
315 : // then delete the column
316 0 : StartUndo(UNDO_COL_DELETE);
317 0 : bRet = GetDoc()->DeleteRowCol( aBoxes, true );
318 0 : EndUndo(UNDO_COL_DELETE);
319 :
320 : }
321 : else
322 0 : bRet = false;
323 :
324 0 : EndAllActionAndCall();
325 0 : return bRet;
326 : }
327 :
328 0 : bool SwFEShell::DeleteTable()
329 : {
330 0 : return DeleteRow(true);
331 : }
332 :
333 0 : bool SwFEShell::DeleteRow(bool bCompleteTable)
334 : {
335 : // check if Point/Mark of current cursor are in a table
336 0 : SwFrm *pFrm = GetCurrFrm();
337 0 : if( !pFrm || !pFrm->IsInTab() )
338 0 : return false;
339 :
340 0 : if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
341 : {
342 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
343 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
344 0 : return false;
345 : }
346 :
347 0 : SET_CURR_SHELL( this );
348 0 : StartAllAction();
349 :
350 : // search for boxes via the layout
351 : bool bRet;
352 0 : SwSelBoxes aBoxes;
353 0 : GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
354 :
355 0 : if( !aBoxes.empty() )
356 : {
357 0 : TblWait( aBoxes.size(), pFrm, *GetDoc()->GetDocShell() );
358 :
359 : // Delete cursors from the deletion area.
360 : // Then the cursor is:
361 : // 1. the following row, if there is another row after this
362 : // 2. the preceding row, if there is another row before this
363 : // 3. otherwise below the table
364 : {
365 0 : SwTableNode* pTblNd = ((SwCntntFrm*)pFrm)->GetNode()->FindTableNode();
366 :
367 : // search all boxes / lines
368 0 : _FndBox aFndBox( 0, 0 );
369 : {
370 0 : _FndPara aPara( aBoxes, &aFndBox );
371 0 : ForEach_FndLineCopyCol( pTblNd->GetTable().GetTabLines(), &aPara );
372 : }
373 :
374 0 : if( aFndBox.GetLines().empty() )
375 : {
376 0 : EndAllActionAndCall();
377 0 : return false;
378 : }
379 :
380 0 : KillPams();
381 :
382 0 : _FndBox* pFndBox = &aFndBox;
383 0 : while( 1 == pFndBox->GetLines().size() &&
384 0 : 1 == pFndBox->GetLines().front().GetBoxes().size() )
385 : {
386 0 : _FndBox* pTmp = &pFndBox->GetLines().front().GetBoxes()[0];
387 0 : if( pTmp->GetBox()->GetSttNd() )
388 0 : break; // otherwise too far
389 0 : pFndBox = pTmp;
390 : }
391 :
392 0 : SwTableLine* pDelLine = pFndBox->GetLines().back().GetLine();
393 0 : SwTableBox* pDelBox = pDelLine->GetTabBoxes().back();
394 0 : while( !pDelBox->GetSttNd() )
395 : {
396 0 : SwTableLine* pLn = pDelBox->GetTabLines().back();
397 0 : pDelBox = pLn->GetTabBoxes().back();
398 : }
399 0 : SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(),
400 0 : pDelBox, true );
401 0 : while( pNextBox &&
402 0 : pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
403 0 : pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox );
404 :
405 0 : if( !pNextBox ) // no next? then the previous
406 : {
407 0 : pDelLine = pFndBox->GetLines().front().GetLine();
408 0 : pDelBox = pDelLine->GetTabBoxes()[ 0 ];
409 0 : while( !pDelBox->GetSttNd() )
410 0 : pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
411 0 : pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(),
412 0 : pDelBox, true );
413 0 : while( pNextBox &&
414 0 : pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
415 0 : pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox );
416 : }
417 :
418 : sal_uLong nIdx;
419 0 : if( pNextBox ) // put cursor here
420 0 : nIdx = pNextBox->GetSttIdx() + 1;
421 : else // otherwise below the table
422 0 : nIdx = pTblNd->EndOfSectionIndex() + 1;
423 :
424 0 : SwNodeIndex aIdx( GetDoc()->GetNodes(), nIdx );
425 0 : SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
426 0 : if( !pCNd )
427 0 : pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
428 :
429 0 : if( pCNd )
430 : {
431 0 : SwPaM* pPam = GetCrsr();
432 0 : pPam->GetPoint()->nNode = aIdx;
433 0 : pPam->GetPoint()->nContent.Assign( pCNd, 0 );
434 0 : pPam->SetMark(); // both want something
435 0 : pPam->DeleteMark();
436 0 : }
437 : }
438 :
439 : // now delete the lines
440 0 : StartUndo(bCompleteTable ? UNDO_UI_TABLE_DELETE : UNDO_ROW_DELETE);
441 0 : bRet = GetDoc()->DeleteRowCol( aBoxes );
442 0 : EndUndo(bCompleteTable ? UNDO_UI_TABLE_DELETE : UNDO_ROW_DELETE);
443 : }
444 : else
445 0 : bRet = false;
446 :
447 0 : EndAllActionAndCall();
448 0 : return bRet;
449 : }
450 :
451 0 : sal_uInt16 SwFEShell::MergeTab()
452 : {
453 : // check if Point/Mark of current cursor are in a table
454 0 : sal_uInt16 nRet = TBLMERGE_NOSELECTION;
455 0 : if( IsTableMode() )
456 : {
457 0 : SwShellTableCrsr* pTableCrsr = GetTableCrsr();
458 0 : const SwTableNode* pTblNd = pTableCrsr->GetNode().FindTableNode();
459 0 : if( pTblNd->GetTable().ISA( SwDDETable ))
460 : {
461 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
462 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
463 : }
464 : else
465 : {
466 0 : SET_CURR_SHELL( this );
467 0 : StartAllAction();
468 :
469 : TblWait(pTableCrsr->GetSelectedBoxesCount(), 0,
470 0 : *GetDoc()->GetDocShell(),
471 0 : pTblNd->GetTable().GetTabLines().size() );
472 :
473 0 : nRet = GetDoc()->MergeTbl( *pTableCrsr );
474 :
475 0 : KillPams();
476 :
477 0 : EndAllActionAndCall();
478 : }
479 : }
480 0 : return nRet;
481 : }
482 :
483 0 : bool SwFEShell::SplitTab( bool bVert, sal_uInt16 nCnt, bool bSameHeight )
484 : {
485 : // check if Point/Mark of current cursor are in a table
486 0 : SwFrm *pFrm = GetCurrFrm();
487 0 : if( !pFrm || !pFrm->IsInTab() )
488 0 : return false;
489 :
490 0 : if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
491 : {
492 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
493 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
494 0 : return false;
495 : }
496 :
497 0 : SET_CURR_SHELL( this );
498 :
499 0 : if( bVert && !CheckSplitCells( *this, nCnt + 1 ) )
500 : {
501 : ErrorHandler::HandleError( ERR_TBLSPLIT_ERROR,
502 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
503 0 : return false;
504 : }
505 0 : StartAllAction();
506 : // search boxes via the layout
507 : bool bRet;
508 0 : SwSelBoxes aBoxes;
509 0 : GetTblSel( *this, aBoxes );
510 0 : if( !aBoxes.empty() )
511 : {
512 0 : TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.size() );
513 :
514 : // now delete the columns
515 0 : bRet = GetDoc()->SplitTbl( aBoxes, bVert, nCnt, bSameHeight );
516 :
517 0 : DELETEZ( pLastCols );
518 0 : DELETEZ( pLastRows );
519 : }
520 : else
521 0 : bRet = false;
522 0 : EndAllActionAndCall();
523 0 : return bRet;
524 : }
525 :
526 8 : void SwFEShell::_GetTabCols( SwTabCols &rToFill, const SwFrm *pBox ) const
527 : {
528 8 : const SwTabFrm *pTab = pBox->FindTabFrm();
529 8 : if ( pLastCols )
530 : {
531 6 : bool bDel = true;
532 6 : if ( pColumnCacheLastTable == pTab->GetTable() )
533 : {
534 6 : bDel = false;
535 6 : SWRECTFN( pTab )
536 :
537 6 : const SwPageFrm* pPage = pTab->FindPageFrm();
538 12 : const sal_uLong nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() -
539 12 : (pPage->Frm().*fnRect->fnGetLeft)();
540 12 : const sal_uLong nRightMax = (pTab->Frm().*fnRect->fnGetRight)() -
541 12 : (pPage->Frm().*fnRect->fnGetLeft)();
542 :
543 6 : if ( pColumnCacheLastTabFrm != pTab )
544 : {
545 : // if TabFrm was changed, we only shift a little bit
546 : // as the width is the same
547 0 : SWRECTFNX( pColumnCacheLastTabFrm )
548 0 : if( (pColumnCacheLastTabFrm->Frm().*fnRectX->fnGetWidth)() ==
549 0 : (pTab->Frm().*fnRect->fnGetWidth)() )
550 : {
551 0 : pLastCols->SetLeftMin( nLeftMin );
552 :
553 0 : pColumnCacheLastTabFrm = pTab;
554 : }
555 : else
556 0 : bDel = true;
557 : }
558 :
559 18 : if ( !bDel &&
560 12 : pLastCols->GetLeftMin () == (sal_uInt16)nLeftMin &&
561 12 : pLastCols->GetLeft () == (sal_uInt16)(pTab->Prt().*fnRect->fnGetLeft)() &&
562 18 : pLastCols->GetRight () == (sal_uInt16)(pTab->Prt().*fnRect->fnGetRight)()&&
563 6 : pLastCols->GetRightMax() == (sal_uInt16)nRightMax - pLastCols->GetLeftMin() )
564 : {
565 6 : if ( pColumnCacheLastCellFrm != pBox )
566 : {
567 : pTab->GetTable()->GetTabCols( *pLastCols,
568 0 : ((SwCellFrm*)pBox)->GetTabBox(), true);
569 0 : pColumnCacheLastCellFrm = pBox;
570 : }
571 6 : rToFill = *pLastCols;
572 : }
573 : else
574 0 : bDel = true;
575 : }
576 6 : if ( bDel )
577 0 : DELETEZ(pLastCols);
578 : }
579 8 : if ( !pLastCols )
580 : {
581 2 : GetDoc()->GetTabCols( rToFill, 0, (SwCellFrm*)pBox );
582 :
583 2 : pLastCols = new SwTabCols( rToFill );
584 2 : pColumnCacheLastTable = pTab->GetTable();
585 2 : pColumnCacheLastTabFrm = pTab;
586 2 : pColumnCacheLastCellFrm= pBox;
587 : }
588 :
589 : #if OSL_DEBUG_LEVEL > 1
590 : SwTabColsEntry aEntry;
591 : for ( sal_uInt16 i = 0; i < rToFill.Count(); ++i )
592 : {
593 : aEntry = rToFill.GetEntry( i );
594 : (void)aEntry;
595 : }
596 : #endif
597 8 : }
598 :
599 4 : void SwFEShell::_GetTabRows( SwTabCols &rToFill, const SwFrm *pBox ) const
600 : {
601 4 : const SwTabFrm *pTab = pBox->FindTabFrm();
602 4 : if ( pLastRows )
603 : {
604 2 : bool bDel = true;
605 2 : if ( pRowCacheLastTable == pTab->GetTable() )
606 : {
607 2 : bDel = false;
608 2 : SWRECTFN( pTab )
609 2 : const SwPageFrm* pPage = pTab->FindPageFrm();
610 : const long nLeftMin = ( bVert ?
611 0 : pTab->GetPrtLeft() - pPage->Frm().Left() :
612 2 : pTab->GetPrtTop() - pPage->Frm().Top() );
613 2 : const long nLeft = bVert ? LONG_MAX : 0;
614 2 : const long nRight = (pTab->Prt().*fnRect->fnGetHeight)();
615 2 : const long nRightMax = bVert ? nRight : LONG_MAX;
616 :
617 4 : if ( pRowCacheLastTabFrm != pTab ||
618 2 : pRowCacheLastCellFrm != pBox )
619 0 : bDel = true;
620 :
621 6 : if ( !bDel &&
622 4 : pLastRows->GetLeftMin () == nLeftMin &&
623 4 : pLastRows->GetLeft () == nLeft &&
624 6 : pLastRows->GetRight () == nRight &&
625 2 : pLastRows->GetRightMax() == nRightMax )
626 : {
627 2 : rToFill = *pLastRows;
628 : }
629 : else
630 0 : bDel = true;
631 : }
632 2 : if ( bDel )
633 0 : DELETEZ(pLastRows);
634 : }
635 4 : if ( !pLastRows )
636 : {
637 2 : GetDoc()->GetTabRows( rToFill, 0, (SwCellFrm*)pBox );
638 :
639 2 : pLastRows = new SwTabCols( rToFill );
640 2 : pRowCacheLastTable = pTab->GetTable();
641 2 : pRowCacheLastTabFrm = pTab;
642 2 : pRowCacheLastCellFrm= pBox;
643 : }
644 4 : }
645 :
646 0 : void SwFEShell::SetTabCols( const SwTabCols &rNew, bool bCurRowOnly )
647 : {
648 0 : SwFrm *pBox = GetCurrFrm();
649 0 : if( !pBox || !pBox->IsInTab() )
650 0 : return;
651 :
652 0 : SET_CURR_SHELL( this );
653 0 : StartAllAction();
654 :
655 0 : do {
656 0 : pBox = pBox->GetUpper();
657 0 : } while ( !pBox->IsCellFrm() );
658 :
659 0 : GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
660 0 : EndAllActionAndCall();
661 : }
662 :
663 8 : void SwFEShell::GetTabCols( SwTabCols &rToFill ) const
664 : {
665 8 : const SwFrm *pFrm = GetCurrFrm();
666 8 : if( !pFrm || !pFrm->IsInTab() )
667 8 : return;
668 8 : do
669 8 : { pFrm = pFrm->GetUpper();
670 8 : } while ( !pFrm->IsCellFrm() );
671 :
672 8 : _GetTabCols( rToFill, pFrm );
673 : }
674 :
675 4 : void SwFEShell::GetTabRows( SwTabCols &rToFill ) const
676 : {
677 4 : const SwFrm *pFrm = GetCurrFrm();
678 4 : if( !pFrm || !pFrm->IsInTab() )
679 4 : return;
680 4 : do
681 4 : { pFrm = pFrm->GetUpper();
682 4 : } while ( !pFrm->IsCellFrm() );
683 :
684 4 : _GetTabRows( rToFill, pFrm );
685 : }
686 :
687 0 : void SwFEShell::SetTabRows( const SwTabCols &rNew, bool bCurColOnly )
688 : {
689 0 : SwFrm *pBox = GetCurrFrm();
690 0 : if( !pBox || !pBox->IsInTab() )
691 0 : return;
692 :
693 0 : SET_CURR_SHELL( this );
694 0 : StartAllAction();
695 :
696 0 : do {
697 0 : pBox = pBox->GetUpper();
698 0 : } while ( !pBox->IsCellFrm() );
699 :
700 0 : GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox );
701 0 : EndAllActionAndCall();
702 : }
703 :
704 0 : void SwFEShell::GetMouseTabRows( SwTabCols &rToFill, const Point &rPt ) const
705 : {
706 0 : const SwFrm *pBox = GetBox( rPt );
707 0 : if ( pBox )
708 0 : _GetTabRows( rToFill, pBox );
709 0 : }
710 :
711 0 : void SwFEShell::SetMouseTabRows( const SwTabCols &rNew, bool bCurColOnly, const Point &rPt )
712 : {
713 0 : const SwFrm *pBox = GetBox( rPt );
714 0 : if( pBox )
715 : {
716 0 : SET_CURR_SHELL( this );
717 0 : StartAllAction();
718 0 : GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox );
719 0 : EndAllActionAndCall();
720 : }
721 0 : }
722 :
723 0 : void SwFEShell::SetRowSplit( const SwFmtRowSplit& rNew )
724 : {
725 0 : SET_CURR_SHELL( this );
726 0 : StartAllAction();
727 0 : GetDoc()->SetRowSplit( *getShellCrsr( false ), rNew );
728 0 : EndAllActionAndCall();
729 0 : }
730 :
731 0 : void SwFEShell::GetRowSplit( SwFmtRowSplit*& rpSz ) const
732 : {
733 0 : GetDoc()->GetRowSplit( *getShellCrsr( false ), rpSz );
734 0 : }
735 :
736 0 : void SwFEShell::SetRowHeight( const SwFmtFrmSize &rNew )
737 : {
738 0 : SET_CURR_SHELL( this );
739 0 : StartAllAction();
740 0 : GetDoc()->SetRowHeight( *getShellCrsr( false ), rNew );
741 0 : EndAllActionAndCall();
742 0 : }
743 :
744 0 : void SwFEShell::GetRowHeight( SwFmtFrmSize *& rpSz ) const
745 : {
746 0 : GetDoc()->GetRowHeight( *getShellCrsr( false ), rpSz );
747 0 : }
748 :
749 2 : bool SwFEShell::BalanceRowHeight( bool bTstOnly )
750 : {
751 2 : SET_CURR_SHELL( this );
752 2 : if( !bTstOnly )
753 0 : StartAllAction();
754 2 : bool bRet = GetDoc()->BalanceRowHeight( *getShellCrsr( false ), bTstOnly );
755 2 : if( !bTstOnly )
756 0 : EndAllActionAndCall();
757 2 : return bRet;
758 : }
759 :
760 0 : void SwFEShell::SetRowBackground( const SvxBrushItem &rNew )
761 : {
762 0 : SET_CURR_SHELL( this );
763 0 : StartAllAction();
764 0 : GetDoc()->SetRowBackground( *getShellCrsr( false ), rNew );
765 0 : EndAllActionAndCall();
766 0 : }
767 :
768 0 : bool SwFEShell::GetRowBackground( SvxBrushItem &rToFill ) const
769 : {
770 0 : return GetDoc()->GetRowBackground( *getShellCrsr( false ), rToFill );
771 : }
772 :
773 0 : void SwFEShell::SetTabBorders( const SfxItemSet& rSet )
774 : {
775 0 : SET_CURR_SHELL( this );
776 0 : StartAllAction();
777 0 : GetDoc()->SetTabBorders( *getShellCrsr( false ), rSet );
778 0 : EndAllActionAndCall();
779 0 : }
780 :
781 0 : void SwFEShell::SetTabLineStyle( const Color* pColor, bool bSetLine,
782 : const editeng::SvxBorderLine* pBorderLine )
783 : {
784 0 : SET_CURR_SHELL( this );
785 0 : StartAllAction();
786 0 : GetDoc()->SetTabLineStyle( *getShellCrsr( false ),
787 0 : pColor, bSetLine, pBorderLine );
788 0 : EndAllActionAndCall();
789 0 : }
790 :
791 18 : void SwFEShell::GetTabBorders( SfxItemSet& rSet ) const
792 : {
793 18 : GetDoc()->GetTabBorders( *getShellCrsr( false ), rSet );
794 18 : }
795 :
796 0 : void SwFEShell::SetBoxBackground( const SvxBrushItem &rNew )
797 : {
798 0 : SET_CURR_SHELL( this );
799 0 : StartAllAction();
800 0 : GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew );
801 0 : EndAllActionAndCall();
802 0 : }
803 :
804 4 : bool SwFEShell::GetBoxBackground( SvxBrushItem &rToFill ) const
805 : {
806 4 : return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill );
807 : }
808 :
809 0 : void SwFEShell::SetBoxDirection( const SvxFrameDirectionItem& rNew )
810 : {
811 0 : SET_CURR_SHELL( this );
812 0 : StartAllAction();
813 0 : GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew );
814 0 : EndAllActionAndCall();
815 0 : }
816 :
817 0 : bool SwFEShell::GetBoxDirection( SvxFrameDirectionItem& rToFill ) const
818 : {
819 0 : return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill );
820 : }
821 :
822 0 : void SwFEShell::SetBoxAlign( sal_uInt16 nAlign )
823 : {
824 0 : SET_CURR_SHELL( this );
825 0 : StartAllAction();
826 0 : GetDoc()->SetBoxAlign( *getShellCrsr( false ), nAlign );
827 0 : EndAllActionAndCall();
828 0 : }
829 :
830 18 : sal_uInt16 SwFEShell::GetBoxAlign() const
831 : {
832 18 : return GetDoc()->GetBoxAlign( *getShellCrsr( false ) );
833 : }
834 :
835 0 : void SwFEShell::SetTabBackground( const SvxBrushItem &rNew )
836 : {
837 0 : SwFrm *pFrm = GetCurrFrm();
838 0 : if( !pFrm || !pFrm->IsInTab() )
839 0 : return;
840 :
841 0 : SET_CURR_SHELL( this );
842 0 : StartAllAction();
843 0 : GetDoc()->SetAttr( rNew, *pFrm->ImplFindTabFrm()->GetFmt() );
844 0 : EndAllAction(); // no call, nothing changes!
845 0 : GetDoc()->getIDocumentState().SetModified();
846 : }
847 :
848 0 : void SwFEShell::GetTabBackground( SvxBrushItem &rToFill ) const
849 : {
850 0 : SwFrm *pFrm = GetCurrFrm();
851 0 : if( pFrm && pFrm->IsInTab() )
852 0 : rToFill = pFrm->ImplFindTabFrm()->GetFmt()->makeBackgroundBrushItem();
853 0 : }
854 :
855 18 : bool SwFEShell::HasWholeTabSelection() const
856 : {
857 : // whole table selected?
858 18 : if ( IsTableMode() )
859 : {
860 0 : SwSelBoxes aBoxes;
861 0 : ::GetTblSelCrs( *this, aBoxes );
862 0 : if( !aBoxes.empty() )
863 : {
864 0 : const SwTableNode *pTblNd = IsCrsrInTbl();
865 0 : return pTblNd &&
866 0 : aBoxes[0]->GetSttIdx() - 1 == pTblNd->EndOfSectionNode()->StartOfSectionIndex() &&
867 0 : aBoxes.back()->GetSttNd()->EndOfSectionIndex() + 1 == pTblNd->EndOfSectionIndex();
868 0 : }
869 : }
870 18 : return false;
871 : }
872 :
873 14 : bool SwFEShell::HasBoxSelection() const
874 : {
875 14 : if(!IsCrsrInTbl())
876 0 : return false;
877 : // whole table selected?
878 14 : if( IsTableMode() )
879 0 : return true;
880 14 : SwPaM* pPam = GetCrsr();
881 : // empty boxes are also selected as the absence of selection
882 14 : bool bChg = false;
883 14 : if( pPam->GetPoint() == pPam->End())
884 : {
885 14 : bChg = true;
886 14 : pPam->Exchange();
887 : }
888 : SwNode* pNd;
889 28 : if( pPam->GetPoint()->nNode.GetIndex() -1 ==
890 28 : ( pNd = &pPam->GetNode())->StartOfSectionIndex() &&
891 42 : !pPam->GetPoint()->nContent.GetIndex() &&
892 14 : pPam->GetMark()->nNode.GetIndex() + 1 ==
893 14 : pNd->EndOfSectionIndex())
894 : {
895 14 : SwNodeIndex aIdx( *pNd->EndOfSectionNode(), -1 );
896 14 : SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
897 14 : if( !pCNd )
898 : {
899 0 : pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx );
900 : OSL_ENSURE( pCNd, "no ContentNode in box ??" );
901 : }
902 14 : if( pPam->GetMark()->nContent == pCNd->Len() )
903 : {
904 2 : if( bChg )
905 2 : pPam->Exchange();
906 2 : return true;
907 12 : }
908 : }
909 12 : if( bChg )
910 12 : pPam->Exchange();
911 12 : return false;
912 : }
913 :
914 0 : void SwFEShell::ProtectCells()
915 : {
916 0 : SvxProtectItem aProt( RES_PROTECT );
917 0 : aProt.SetCntntProtect( true );
918 :
919 0 : SET_CURR_SHELL( this );
920 0 : StartAllAction();
921 :
922 0 : GetDoc()->SetBoxAttr( *getShellCrsr( false ), aProt );
923 :
924 0 : if( !IsCrsrReadonly() )
925 : {
926 0 : if( IsTableMode() )
927 0 : ClearMark();
928 0 : ParkCursorInTab();
929 : }
930 0 : EndAllActionAndCall();
931 0 : }
932 :
933 : // cancel table selection
934 0 : void SwFEShell::UnProtectCells()
935 : {
936 0 : SET_CURR_SHELL( this );
937 0 : StartAllAction();
938 :
939 0 : SwSelBoxes aBoxes;
940 0 : if( IsTableMode() )
941 0 : ::GetTblSelCrs( *this, aBoxes );
942 : else
943 : {
944 0 : SwFrm *pFrm = GetCurrFrm();
945 0 : do {
946 0 : pFrm = pFrm->GetUpper();
947 0 : } while ( pFrm && !pFrm->IsCellFrm() );
948 0 : if( pFrm )
949 : {
950 0 : SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
951 0 : aBoxes.insert( pBox );
952 : }
953 : }
954 :
955 0 : if( !aBoxes.empty() )
956 0 : GetDoc()->UnProtectCells( aBoxes );
957 :
958 0 : EndAllActionAndCall();
959 0 : }
960 :
961 0 : void SwFEShell::UnProtectTbls()
962 : {
963 0 : SET_CURR_SHELL( this );
964 0 : StartAllAction();
965 0 : GetDoc()->UnProtectTbls( *GetCrsr() );
966 0 : EndAllActionAndCall();
967 0 : }
968 :
969 0 : bool SwFEShell::HasTblAnyProtection( const OUString* pTblName,
970 : bool* pFullTblProtection )
971 : {
972 0 : return GetDoc()->HasTblAnyProtection( GetCrsr()->GetPoint(), pTblName,
973 0 : pFullTblProtection );
974 : }
975 :
976 0 : bool SwFEShell::CanUnProtectCells() const
977 : {
978 0 : bool bUnProtectAvailable = false;
979 0 : const SwTableNode *pTblNd = IsCrsrInTbl();
980 0 : if( pTblNd && !pTblNd->IsProtect() )
981 : {
982 0 : SwSelBoxes aBoxes;
983 0 : if( IsTableMode() )
984 0 : ::GetTblSelCrs( *this, aBoxes );
985 : else
986 : {
987 0 : SwFrm *pFrm = GetCurrFrm();
988 0 : do {
989 0 : pFrm = pFrm->GetUpper();
990 0 : } while ( pFrm && !pFrm->IsCellFrm() );
991 0 : if( pFrm )
992 : {
993 0 : SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
994 0 : aBoxes.insert( pBox );
995 : }
996 : }
997 0 : if( !aBoxes.empty() )
998 0 : bUnProtectAvailable = ::HasProtectedCells( aBoxes );
999 : }
1000 0 : return bUnProtectAvailable;
1001 : }
1002 :
1003 0 : sal_uInt16 SwFEShell::GetRowsToRepeat() const
1004 : {
1005 0 : const SwFrm *pFrm = GetCurrFrm();
1006 0 : const SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0;
1007 0 : if( pTab )
1008 0 : return pTab->GetTable()->GetRowsToRepeat();
1009 0 : return 0;
1010 : }
1011 :
1012 0 : void SwFEShell::SetRowsToRepeat( sal_uInt16 nSet )
1013 : {
1014 0 : SwFrm *pFrm = GetCurrFrm();
1015 0 : SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0;
1016 0 : if( pTab && pTab->GetTable()->GetRowsToRepeat() != nSet )
1017 : {
1018 0 : SwWait aWait( *GetDoc()->GetDocShell(), true );
1019 0 : SET_CURR_SHELL( this );
1020 0 : StartAllAction();
1021 0 : GetDoc()->SetRowsToRepeat( *pTab->GetTable(), nSet );
1022 0 : EndAllActionAndCall();
1023 : }
1024 0 : }
1025 :
1026 : // returns the number of rows consecutively selected from top
1027 0 : static sal_uInt16 lcl_GetRowNumber( const SwPosition& rPos )
1028 : {
1029 0 : sal_uInt16 nRet = USHRT_MAX;
1030 0 : Point aTmpPt;
1031 : const SwCntntNode *pNd;
1032 : const SwCntntFrm *pFrm;
1033 :
1034 0 : if( 0 != ( pNd = rPos.nNode.GetNode().GetCntntNode() ))
1035 0 : pFrm = pNd->getLayoutFrm( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aTmpPt, &rPos, false );
1036 : else
1037 0 : pFrm = 0;
1038 :
1039 0 : if ( pFrm && pFrm->IsInTab() )
1040 : {
1041 0 : const SwFrm* pRow = pFrm->GetUpper();
1042 0 : while ( !pRow->GetUpper()->IsTabFrm() )
1043 0 : pRow = pRow->GetUpper();
1044 :
1045 0 : const SwTabFrm* pTabFrm = (const SwTabFrm*)pRow->GetUpper();
1046 0 : const SwTableLine* pTabLine = static_cast<const SwRowFrm*>(pRow)->GetTabLine();
1047 :
1048 0 : sal_uInt16 nI = 0;
1049 0 : while ( nI < pTabFrm->GetTable()->GetTabLines().size() )
1050 : {
1051 0 : if ( pTabFrm->GetTable()->GetTabLines()[ nI ] == pTabLine )
1052 : {
1053 0 : nRet = nI;
1054 0 : break;
1055 : }
1056 0 : ++nI;
1057 : }
1058 : }
1059 :
1060 0 : return nRet;
1061 : }
1062 :
1063 0 : sal_uInt16 SwFEShell::GetRowSelectionFromTop() const
1064 : {
1065 0 : sal_uInt16 nRet = 0;
1066 0 : const SwPaM* pPaM = IsTableMode() ? GetTableCrsr() : _GetCrsr();
1067 0 : const sal_uInt16 nPtLine = lcl_GetRowNumber( *pPaM->GetPoint() );
1068 :
1069 0 : if ( !IsTableMode() )
1070 : {
1071 0 : nRet = 0 == nPtLine ? 1 : 0;
1072 : }
1073 : else
1074 : {
1075 0 : const sal_uInt16 nMkLine = lcl_GetRowNumber( *pPaM->GetMark() );
1076 :
1077 0 : if ( ( nPtLine == 0 && nMkLine != USHRT_MAX ) ||
1078 0 : ( nMkLine == 0 && nPtLine != USHRT_MAX ) )
1079 : {
1080 0 : nRet = std::max( nPtLine, nMkLine ) + 1;
1081 : }
1082 : }
1083 :
1084 0 : return nRet;
1085 : }
1086 :
1087 : /*
1088 : * 1. case: bRepeat = true
1089 : * returns true if the current frame is located inside a table headline in
1090 : * a follow frame
1091 : *
1092 : * 2. case: bRepeat = false
1093 : * returns true if the current frame is localed inside a table headline OR
1094 : * inside the first line of a table!!!
1095 : */
1096 6 : bool SwFEShell::CheckHeadline( bool bRepeat ) const
1097 : {
1098 6 : bool bRet = false;
1099 6 : if ( !IsTableMode() )
1100 : {
1101 2 : SwFrm *pFrm = GetCurrFrm(); // DONE MULTIIHEADER
1102 2 : if ( pFrm && pFrm->IsInTab() )
1103 : {
1104 2 : SwTabFrm* pTab = pFrm->FindTabFrm();
1105 2 : if ( bRepeat )
1106 : {
1107 2 : bRet = pTab->IsFollow() && pTab->IsInHeadline( *pFrm );
1108 : }
1109 : else
1110 : {
1111 0 : bRet = ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pFrm ) ||
1112 0 : pTab->IsInHeadline( *pFrm );
1113 : }
1114 : }
1115 : }
1116 6 : return bRet;
1117 : }
1118 :
1119 0 : void SwFEShell::AdjustCellWidth( bool bBalance )
1120 : {
1121 0 : SET_CURR_SHELL( this );
1122 0 : StartAllAction();
1123 :
1124 : // switch on wait-cursor, as we do not know how
1125 : // much content is affected
1126 : TblWait aWait(::std::numeric_limits<size_t>::max(), 0,
1127 0 : *GetDoc()->GetDocShell());
1128 :
1129 0 : GetDoc()->AdjustCellWidth( *getShellCrsr( false ), bBalance );
1130 0 : EndAllActionAndCall();
1131 0 : }
1132 :
1133 4 : bool SwFEShell::IsAdjustCellWidthAllowed( bool bBalance ) const
1134 : {
1135 : // at least one row with content should be contained in the selection
1136 :
1137 4 : SwFrm *pFrm = GetCurrFrm();
1138 4 : if( !pFrm || !pFrm->IsInTab() )
1139 0 : return false;
1140 :
1141 4 : SwSelBoxes aBoxes;
1142 4 : ::GetTblSelCrs( *this, aBoxes );
1143 :
1144 4 : if ( bBalance )
1145 2 : return aBoxes.size() > 1;
1146 :
1147 2 : if ( aBoxes.empty() )
1148 : {
1149 2 : do
1150 2 : { pFrm = pFrm->GetUpper();
1151 2 : } while ( !pFrm->IsCellFrm() );
1152 2 : SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
1153 2 : aBoxes.insert( pBox );
1154 : }
1155 :
1156 4 : for (size_t i = 0; i < aBoxes.size(); ++i)
1157 : {
1158 2 : SwTableBox *pBox = aBoxes[i];
1159 2 : if ( pBox->GetSttNd() )
1160 : {
1161 2 : SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
1162 2 : SwTxtNode* pCNd = aIdx.GetNode().GetTxtNode();
1163 2 : if( !pCNd )
1164 0 : pCNd = (SwTxtNode*)GetDoc()->GetNodes().GoNext( &aIdx );
1165 :
1166 6 : while ( pCNd )
1167 : {
1168 2 : if (!pCNd->GetTxt().isEmpty())
1169 0 : return true;
1170 2 : ++aIdx;
1171 2 : pCNd = aIdx.GetNode().GetTxtNode();
1172 2 : }
1173 : }
1174 : }
1175 2 : return false;
1176 : }
1177 :
1178 : // AutoFormat for the table/table selection
1179 0 : bool SwFEShell::SetTableAutoFmt( const SwTableAutoFmt& rNew )
1180 : {
1181 0 : SwTableNode *pTblNd = (SwTableNode*)IsCrsrInTbl();
1182 0 : if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
1183 0 : return false;
1184 :
1185 0 : SwSelBoxes aBoxes;
1186 :
1187 0 : if ( !IsTableMode() ) // if cursors are not current
1188 0 : GetCrsr();
1189 :
1190 : // whole table or only current selection
1191 0 : if( IsTableMode() )
1192 0 : ::GetTblSelCrs( *this, aBoxes );
1193 : else
1194 : {
1195 0 : const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
1196 0 : for (size_t n = 0; n < rTBoxes.size(); ++n)
1197 : {
1198 0 : SwTableBox* pBox = rTBoxes[ n ];
1199 0 : aBoxes.insert( pBox );
1200 : }
1201 : }
1202 :
1203 : bool bRet;
1204 0 : if( !aBoxes.empty() )
1205 : {
1206 0 : SET_CURR_SHELL( this );
1207 0 : StartAllAction();
1208 0 : bRet = GetDoc()->SetTableAutoFmt( aBoxes, rNew );
1209 0 : DELETEZ( pLastCols );
1210 0 : DELETEZ( pLastRows );
1211 0 : EndAllActionAndCall();
1212 : }
1213 : else
1214 0 : bRet = false;
1215 0 : return bRet;
1216 : }
1217 :
1218 0 : bool SwFEShell::GetTableAutoFmt( SwTableAutoFmt& rGet )
1219 : {
1220 0 : const SwTableNode *pTblNd = IsCrsrInTbl();
1221 0 : if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
1222 0 : return false;
1223 :
1224 0 : SwSelBoxes aBoxes;
1225 :
1226 0 : if ( !IsTableMode() ) // if cursor are not current
1227 0 : GetCrsr();
1228 :
1229 : // whole table or only current selection
1230 0 : if( IsTableMode() )
1231 0 : ::GetTblSelCrs( *this, aBoxes );
1232 : else
1233 : {
1234 0 : const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
1235 0 : for (size_t n = 0; n < rTBoxes.size(); ++n)
1236 : {
1237 0 : SwTableBox* pBox = rTBoxes[ n ];
1238 0 : aBoxes.insert( pBox );
1239 : }
1240 : }
1241 :
1242 0 : return GetDoc()->GetTableAutoFmt( aBoxes, rGet );
1243 : }
1244 :
1245 0 : bool SwFEShell::DeleteTblSel()
1246 : {
1247 : // check if SPoint/Mark of current cursor are in a table
1248 0 : SwFrm *pFrm = GetCurrFrm();
1249 0 : if( !pFrm || !pFrm->IsInTab() )
1250 0 : return false;
1251 :
1252 0 : if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
1253 : {
1254 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
1255 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
1256 0 : return false;
1257 : }
1258 :
1259 0 : SET_CURR_SHELL( this );
1260 0 : StartAllAction();
1261 :
1262 : // search boxes via the layout
1263 : bool bRet;
1264 0 : SwSelBoxes aBoxes;
1265 0 : GetTblSelCrs( *this, aBoxes );
1266 0 : if( !aBoxes.empty() )
1267 : {
1268 0 : TblWait( aBoxes.size(), pFrm, *GetDoc()->GetDocShell() );
1269 :
1270 : // cursor should be removed from deletion area.
1271 : // Put them behind/on the table; via the document
1272 : // position they'll be set to the old position
1273 0 : while( !pFrm->IsCellFrm() )
1274 0 : pFrm = pFrm->GetUpper();
1275 0 : ParkCrsr( SwNodeIndex( *((SwCellFrm*)pFrm)->GetTabBox()->GetSttNd() ));
1276 :
1277 0 : bRet = GetDoc()->DeleteRowCol( aBoxes );
1278 :
1279 0 : DELETEZ( pLastCols );
1280 0 : DELETEZ( pLastRows );
1281 : }
1282 : else
1283 0 : bRet = false;
1284 0 : EndAllActionAndCall();
1285 0 : return bRet;
1286 : }
1287 :
1288 4 : size_t SwFEShell::GetCurTabColNum() const
1289 : {
1290 : //!!!GetCurMouseTabColNum() mitpflegen!!!!
1291 4 : size_t nRet = 0;
1292 :
1293 4 : SwFrm *pFrm = GetCurrFrm();
1294 : OSL_ENSURE( pFrm, "Crsr parked?" );
1295 :
1296 : // check if SPoint/Mark of current cursor are in a table
1297 4 : if( pFrm && pFrm->IsInTab() )
1298 : {
1299 4 : do { // JP 26.09.95: why compare with CntntFrame
1300 : // and not with CellFrame ????
1301 4 : pFrm = pFrm->GetUpper();
1302 4 : } while ( !pFrm->IsCellFrm() );
1303 4 : SWRECTFN( pFrm )
1304 :
1305 4 : const SwPageFrm* pPage = pFrm->FindPageFrm();
1306 :
1307 : // get TabCols, as only via these we get to the position
1308 4 : SwTabCols aTabCols;
1309 4 : GetTabCols( aTabCols );
1310 :
1311 4 : if( pFrm->FindTabFrm()->IsRightToLeft() )
1312 : {
1313 0 : long nX = (pFrm->Frm().*fnRect->fnGetRight)() - (pPage->Frm().*fnRect->fnGetLeft)();
1314 :
1315 0 : const long nRight = aTabCols.GetLeftMin() + aTabCols.GetRight();;
1316 :
1317 0 : if ( !::IsSame( nX, nRight ) )
1318 : {
1319 0 : nX = nRight - nX + aTabCols.GetLeft();
1320 0 : for ( size_t i = 0; i < aTabCols.Count(); ++i )
1321 0 : if ( ::IsSame( nX, aTabCols[i] ) )
1322 : {
1323 0 : nRet = i + 1;
1324 0 : break;
1325 : }
1326 : }
1327 : }
1328 : else
1329 : {
1330 4 : const long nX = (pFrm->Frm().*fnRect->fnGetLeft)() -
1331 4 : (pPage->Frm().*fnRect->fnGetLeft)();
1332 :
1333 4 : const long nLeft = aTabCols.GetLeftMin();
1334 :
1335 4 : if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
1336 : {
1337 0 : for ( size_t i = 0; i < aTabCols.Count(); ++i )
1338 0 : if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
1339 : {
1340 0 : nRet = i + 1;
1341 0 : break;
1342 : }
1343 : }
1344 4 : }
1345 : }
1346 4 : return nRet;
1347 : }
1348 :
1349 0 : static const SwFrm *lcl_FindFrmInTab( const SwLayoutFrm *pLay, const Point &rPt, SwTwips nFuzzy )
1350 : {
1351 0 : const SwFrm *pFrm = pLay->Lower();
1352 :
1353 0 : while( pFrm && pLay->IsAnLower( pFrm ) )
1354 : {
1355 0 : if ( pFrm->Frm().IsNear( rPt, nFuzzy ) )
1356 : {
1357 0 : if ( pFrm->IsLayoutFrm() )
1358 : {
1359 0 : const SwFrm *pTmp = ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, rPt, nFuzzy );
1360 0 : if ( pTmp )
1361 0 : return pTmp;
1362 : }
1363 :
1364 0 : return pFrm;
1365 : }
1366 :
1367 0 : pFrm = pFrm->FindNext();
1368 : }
1369 :
1370 0 : return 0;
1371 : }
1372 :
1373 0 : static const SwCellFrm *lcl_FindFrm( const SwLayoutFrm *pLay, const Point &rPt,
1374 : SwTwips nFuzzy, bool* pbRow, bool* pbCol )
1375 : {
1376 : // bMouseMoveRowCols :
1377 : // Method is called for
1378 : // - Moving columns/rows with the mouse or
1379 : // - Enhanced table selection
1380 0 : const bool bMouseMoveRowCols = 0 == pbCol;
1381 :
1382 0 : bool bCloseToRow = false;
1383 0 : bool bCloseToCol = false;
1384 :
1385 0 : const SwFrm *pFrm = pLay->ContainsCntnt();
1386 0 : const SwFrm* pRet = 0;
1387 :
1388 0 : if ( pFrm )
1389 : {
1390 0 : do
1391 : {
1392 0 : if ( pFrm->IsInTab() )
1393 0 : pFrm = ((SwFrm*)pFrm)->ImplFindTabFrm();
1394 :
1395 0 : if ( pFrm->IsTabFrm() )
1396 : {
1397 0 : Point aPt( rPt );
1398 0 : bool bSearchForFrmInTab = true;
1399 0 : SwTwips nTmpFuzzy = nFuzzy;
1400 :
1401 0 : if ( !bMouseMoveRowCols )
1402 : {
1403 : // We ignore nested tables for the enhanced table selection:
1404 0 : while ( pFrm->GetUpper()->IsInTab() )
1405 0 : pFrm = pFrm->GetUpper()->FindTabFrm();
1406 :
1407 : // We first check if the given point is 'close' to the left or top
1408 : // border of the table frame:
1409 : OSL_ENSURE( pFrm, "Nested table frame without outer table" );
1410 0 : SWRECTFN( pFrm )
1411 0 : const bool bRTL = pFrm->IsRightToLeft();
1412 :
1413 0 : SwRect aTabRect = pFrm->Prt();
1414 0 : aTabRect.Pos() += pFrm->Frm().Pos();
1415 :
1416 : const SwTwips nLeft = bRTL ?
1417 0 : (aTabRect.*fnRect->fnGetRight)() :
1418 0 : (aTabRect.*fnRect->fnGetLeft)();
1419 0 : const SwTwips nTop = (aTabRect.*fnRect->fnGetTop)();
1420 :
1421 0 : SwTwips& rPointX = bVert ? aPt.Y() : aPt.X();
1422 0 : SwTwips& rPointY = bVert ? aPt.X() : aPt.Y();
1423 :
1424 0 : const SwTwips nXDiff = (*fnRect->fnXDiff)( nLeft, rPointX ) * ( bRTL ? (-1) : 1 );
1425 0 : const SwTwips nYDiff = (*fnRect->fnYDiff)( nTop, rPointY );
1426 :
1427 0 : bCloseToRow = nXDiff >= 0 && nXDiff < nFuzzy;
1428 0 : bCloseToCol = nYDiff >= 0 && nYDiff < nFuzzy;
1429 :
1430 0 : if ( bCloseToCol && 2 * nYDiff > nFuzzy )
1431 : {
1432 0 : const SwFrm* pPrev = pFrm->GetPrev();
1433 0 : if ( pPrev )
1434 : {
1435 0 : SwRect aPrevRect = pPrev->Prt();
1436 0 : aPrevRect.Pos() += pPrev->Frm().Pos();
1437 :
1438 0 : if( aPrevRect.IsInside( rPt ) )
1439 : {
1440 0 : bCloseToCol = false;
1441 : }
1442 : }
1443 :
1444 : }
1445 :
1446 : // If we found the point to be 'close' to the left or top border
1447 : // of the table frame, we adjust the point to be on that border:
1448 0 : if ( bCloseToRow && bCloseToCol )
1449 0 : aPt = bRTL ? aTabRect.TopRight() : (aTabRect.*fnRect->fnGetPos)();
1450 0 : else if ( bCloseToRow )
1451 0 : rPointX = nLeft;
1452 0 : else if ( bCloseToCol )
1453 0 : rPointY = nTop;
1454 :
1455 0 : if ( !bCloseToRow && !bCloseToCol )
1456 0 : bSearchForFrmInTab = false;
1457 :
1458 : // Since the point has been adjusted, we call lcl_FindFrmInTab()
1459 : // with a fuzzy value of 1:
1460 0 : nTmpFuzzy = 1;
1461 : }
1462 :
1463 : const SwFrm* pTmp = bSearchForFrmInTab ?
1464 : ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, aPt, nTmpFuzzy ) :
1465 0 : 0;
1466 :
1467 0 : if ( pTmp )
1468 : {
1469 0 : pFrm = pTmp;
1470 0 : break;
1471 : }
1472 : }
1473 0 : pFrm = pFrm->FindNextCnt();
1474 :
1475 0 : } while ( pFrm && pLay->IsAnLower( pFrm ) );
1476 : }
1477 :
1478 0 : if ( pFrm && pFrm->IsInTab() && pLay->IsAnLower( pFrm ) )
1479 : {
1480 0 : do
1481 : {
1482 : // We allow mouse drag of table borders within nested tables,
1483 : // but disallow hotspot selection of nested tables.
1484 0 : if ( bMouseMoveRowCols )
1485 : {
1486 : // find the next cell frame
1487 0 : while ( pFrm && !pFrm->IsCellFrm() )
1488 0 : pFrm = pFrm->GetUpper();
1489 : }
1490 : else
1491 : {
1492 : // find the most upper cell frame:
1493 0 : while ( pFrm &&
1494 0 : ( !pFrm->IsCellFrm() ||
1495 0 : !pFrm->GetUpper()->GetUpper()->IsTabFrm() ||
1496 0 : pFrm->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
1497 0 : pFrm = pFrm->GetUpper();
1498 : }
1499 :
1500 0 : if ( pFrm ) // Note: this condition should be the same like the while condition!!!
1501 : {
1502 : // #i32329# Enhanced table selection
1503 : // used for hotspot selection of tab/cols/rows
1504 0 : if ( !bMouseMoveRowCols )
1505 : {
1506 :
1507 : OSL_ENSURE( pbCol && pbRow, "pbCol or pbRow missing" );
1508 :
1509 0 : if ( bCloseToRow || bCloseToCol )
1510 : {
1511 0 : *pbRow = bCloseToRow;
1512 0 : *pbCol = bCloseToCol;
1513 0 : pRet = pFrm;
1514 0 : break;
1515 : }
1516 : }
1517 : else
1518 : {
1519 : // used for mouse move of columns/rows
1520 0 : const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
1521 0 : SwRect aTabRect = pTabFrm->Prt();
1522 0 : aTabRect.Pos() += pTabFrm->Frm().Pos();
1523 :
1524 0 : SWRECTFN( pTabFrm )
1525 :
1526 0 : const SwTwips nTabTop = (aTabRect.*fnRect->fnGetTop)();
1527 0 : const SwTwips nMouseTop = bVert ? rPt.X() : rPt.Y();
1528 :
1529 : // Do not allow to drag upper table border:
1530 0 : if ( !::IsSame( nTabTop, nMouseTop ) )
1531 : {
1532 0 : if ( ::IsSame( pFrm->Frm().Left(), rPt.X() ) ||
1533 0 : ::IsSame( pFrm->Frm().Right(),rPt.X() ) )
1534 : {
1535 0 : if ( pbRow ) *pbRow = false;
1536 0 : pRet = pFrm;
1537 0 : break;
1538 : }
1539 0 : if ( ::IsSame( pFrm->Frm().Top(), rPt.Y() ) ||
1540 0 : ::IsSame( pFrm->Frm().Bottom(),rPt.Y() ) )
1541 : {
1542 0 : if ( pbRow ) *pbRow = true;
1543 0 : pRet = pFrm;
1544 0 : break;
1545 : }
1546 : }
1547 : }
1548 :
1549 0 : pFrm = pFrm->GetUpper();
1550 : }
1551 : } while ( pFrm );
1552 : }
1553 :
1554 : // robust:
1555 : OSL_ENSURE( !pRet || pRet->IsCellFrm(), "lcl_FindFrm() is supposed to find a cell frame!" );
1556 0 : return pRet && pRet->IsCellFrm() ? static_cast<const SwCellFrm*>(pRet) : 0;
1557 : }
1558 :
1559 : // pbCol = 0 => Used for moving table rows/cols with mouse
1560 : // pbCol != 0 => Used for selecting table/rows/cols
1561 :
1562 : #define ENHANCED_TABLE_SELECTION_FUZZY 10
1563 :
1564 0 : const SwFrm* SwFEShell::GetBox( const Point &rPt, bool* pbRow, bool* pbCol ) const
1565 : {
1566 0 : const SwPageFrm *pPage = (SwPageFrm*)GetLayout()->Lower();
1567 0 : vcl::Window* pOutWin = GetWin();
1568 0 : SwTwips nFuzzy = COLFUZZY;
1569 0 : if( pOutWin )
1570 : {
1571 : // #i32329# Enhanced table selection
1572 0 : SwTwips nSize = pbCol ? ENHANCED_TABLE_SELECTION_FUZZY : RULER_MOUSE_MARGINWIDTH;
1573 0 : Size aTmp( nSize, nSize );
1574 0 : aTmp = pOutWin->PixelToLogic( aTmp );
1575 0 : nFuzzy = aTmp.Width();
1576 : }
1577 :
1578 0 : while ( pPage && !pPage->Frm().IsNear( rPt, nFuzzy ) )
1579 0 : pPage = (SwPageFrm*)pPage->GetNext();
1580 :
1581 0 : const SwCellFrm *pFrm = 0;
1582 0 : if ( pPage )
1583 : {
1584 : // We cannot search the box by GetCrsrOfst or GetCntntPos.
1585 : // This would lead to a performance collapse for documents
1586 : // with a lot of paragraphs/tables on one page
1587 : //(BrowseMode!)
1588 :
1589 : // check flys first
1590 0 : if ( pPage->GetSortedObjs() )
1591 : {
1592 0 : for ( size_t i = 0; !pFrm && i < pPage->GetSortedObjs()->size(); ++i )
1593 : {
1594 0 : SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
1595 0 : if ( pObj->ISA(SwFlyFrm) )
1596 : {
1597 : pFrm = lcl_FindFrm( static_cast<SwFlyFrm*>(pObj),
1598 0 : rPt, nFuzzy, pbRow, pbCol );
1599 : }
1600 : }
1601 : }
1602 0 : const SwLayoutFrm *pLay = (SwLayoutFrm*)pPage->Lower();
1603 0 : while ( pLay && !pFrm )
1604 : {
1605 0 : pFrm = lcl_FindFrm( pLay, rPt, nFuzzy, pbRow, pbCol );
1606 0 : pLay = (SwLayoutFrm*)pLay->GetNext();
1607 : }
1608 : }
1609 0 : return pFrm;
1610 : }
1611 :
1612 : /* Helper function*/
1613 : /* calculated the distance between Point rC and Line Segment (rA, rB) */
1614 0 : static double lcl_DistancePoint2Segment( const Point& rA, const Point& rB, const Point& rC )
1615 : {
1616 0 : double nRet = 0;
1617 :
1618 0 : const basegfx::B2DVector aBC( rC.X() - rB.X(), rC.Y() - rB.Y() );
1619 0 : const basegfx::B2DVector aAB( rB.X() - rA.X(), rB.Y() - rA.Y() );
1620 0 : const double nDot1 = aBC.scalar( aAB );
1621 :
1622 0 : if ( nDot1 > 0 ) // check outside case 1
1623 0 : nRet = aBC.getLength();
1624 : else
1625 : {
1626 0 : const basegfx::B2DVector aAC( rC.X() - rA.X(), rC.Y() - rA.Y() );
1627 0 : const basegfx::B2DVector aBA( rA.X() - rB.X(), rA.Y() - rB.Y() );
1628 0 : const double nDot2 = aAC.scalar( aBA );
1629 :
1630 0 : if ( nDot2 > 0 ) // check outside case 2
1631 0 : nRet = aAC.getLength();
1632 : else
1633 : {
1634 0 : const double nDiv = aAB.getLength();
1635 0 : nRet = nDiv ? aAB.cross( aAC ) / nDiv : 0;
1636 0 : }
1637 : }
1638 :
1639 0 : return std::abs(nRet);
1640 : }
1641 :
1642 : /* Helper function*/
1643 0 : static Point lcl_ProjectOntoClosestTableFrm( const SwTabFrm& rTab, const Point& rPoint, bool bRowDrag )
1644 : {
1645 0 : Point aRet( rPoint );
1646 0 : const SwTabFrm* pCurrentTab = &rTab;
1647 0 : const bool bVert = pCurrentTab->IsVertical();
1648 0 : const bool bRTL = pCurrentTab->IsRightToLeft();
1649 :
1650 : // Western Layout:
1651 : // bRowDrag = true => compare to left border of table
1652 : // bRowDrag = false => compare to top border of table
1653 :
1654 : // Asian Layout:
1655 : // bRowDrag = true => compare to right border of table
1656 : // bRowDrag = false => compare to top border of table
1657 :
1658 : // RTL Layout:
1659 : // bRowDrag = true => compare to right border of table
1660 : // bRowDrag = false => compare to top border of table
1661 0 : bool bLeft = false;
1662 0 : bool bRight = false;
1663 :
1664 0 : if ( bRowDrag )
1665 : {
1666 0 : if ( bVert || bRTL )
1667 0 : bRight = true;
1668 : else
1669 0 : bLeft = true;
1670 : }
1671 :
1672 : // used to find the minimal distance
1673 0 : double nMin = -1;
1674 0 : Point aMin1;
1675 0 : Point aMin2;
1676 :
1677 0 : Point aS1;
1678 0 : Point aS2;
1679 :
1680 0 : while ( pCurrentTab )
1681 : {
1682 0 : SwRect aTabRect( pCurrentTab->Prt() );
1683 0 : aTabRect += pCurrentTab->Frm().Pos();
1684 :
1685 0 : if ( bLeft )
1686 : {
1687 : // distance to left table border
1688 0 : aS1 = aTabRect.TopLeft();
1689 0 : aS2 = aTabRect.BottomLeft();
1690 : }
1691 0 : else if ( bRight )
1692 : {
1693 : // distance to right table border
1694 0 : aS1 = aTabRect.TopRight();
1695 0 : aS2 = aTabRect.BottomRight();
1696 : }
1697 : else //if ( bTop )
1698 : {
1699 : // distance to top table border
1700 0 : aS1 = aTabRect.TopLeft();
1701 0 : aS2 = aTabRect.TopRight();
1702 : }
1703 :
1704 0 : const double nDist = lcl_DistancePoint2Segment( aS1, aS2, rPoint );
1705 :
1706 0 : if ( nDist < nMin || -1 == nMin )
1707 : {
1708 0 : aMin1 = aS1;
1709 0 : aMin2 = aS2;
1710 0 : nMin = nDist;
1711 : }
1712 :
1713 0 : pCurrentTab = pCurrentTab->GetFollow();
1714 : }
1715 :
1716 : // project onto closest line:
1717 0 : if ( bLeft || bRight )
1718 : {
1719 0 : aRet.setX(aMin1.getX());
1720 0 : if ( aRet.getY() > aMin2.getY() )
1721 0 : aRet.setY(aMin2.getY());
1722 0 : else if ( aRet.getY() < aMin1.getY() )
1723 0 : aRet.setY(aMin1.getY());
1724 : }
1725 : else
1726 : {
1727 0 : aRet.setY(aMin1.getY());
1728 0 : if ( aRet.getX() > aMin2.getX() )
1729 0 : aRet.setX(aMin2.getX());
1730 0 : else if ( aRet.getX() < aMin1.getX() )
1731 0 : aRet.setX(aMin1.getX());
1732 : }
1733 :
1734 0 : return aRet;
1735 : }
1736 :
1737 : // #i32329# Enhanced table selection
1738 0 : bool SwFEShell::SelTblRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
1739 : {
1740 0 : bool bRet = false;
1741 0 : Point aEndPt;
1742 0 : if ( pEnd )
1743 0 : aEndPt = *pEnd;
1744 :
1745 0 : SwPosition* ppPos[2] = { 0, 0 };
1746 0 : Point paPt [2] = { rPt, aEndPt };
1747 0 : bool pbRow[2] = { false, false };
1748 0 : bool pbCol[2] = { false, false };
1749 :
1750 : // pEnd is set during dragging.
1751 0 : for ( sal_uInt16 i = 0; i < ( pEnd ? 2 : 1 ); ++i )
1752 : {
1753 : const SwCellFrm* pFrm =
1754 0 : static_cast<const SwCellFrm*>(GetBox( paPt[i], &pbRow[i], &pbCol[i] ) );
1755 :
1756 0 : if( pFrm )
1757 : {
1758 0 : while( pFrm && pFrm->Lower() && pFrm->Lower()->IsRowFrm() )
1759 0 : pFrm = static_cast<const SwCellFrm*>( static_cast<const SwLayoutFrm*>( pFrm->Lower() )->Lower() );
1760 0 : if( pFrm && pFrm->GetTabBox()->GetSttNd() &&
1761 0 : pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() )
1762 0 : pFrm = 0;
1763 : }
1764 :
1765 0 : if ( pFrm )
1766 : {
1767 0 : const SwCntntFrm* pCntnt = ::GetCellCntnt( *pFrm );
1768 :
1769 0 : if ( pCntnt && pCntnt->IsTxtFrm() )
1770 : {
1771 0 : ppPos[i] = new SwPosition( *pCntnt->GetNode() );
1772 0 : ppPos[i]->nContent.Assign( const_cast<SwCntntNode*>(pCntnt->GetNode()), 0 );
1773 :
1774 : // paPt[i] will not be used any longer, now we use it to store
1775 : // a position inside the content frame
1776 0 : paPt[i] = pCntnt->Frm().Center();
1777 : }
1778 : }
1779 :
1780 : // no calculation of end frame if start frame has not been found.
1781 0 : if ( 1 == i || !ppPos[0] || !pEnd || !pFrm )
1782 : break;
1783 :
1784 : // find 'closest' table frame to pEnd:
1785 0 : const SwTabFrm* pCurrentTab = pFrm->FindTabFrm();
1786 0 : if ( pCurrentTab->IsFollow() )
1787 0 : pCurrentTab = pCurrentTab->FindMaster( true );
1788 :
1789 0 : const Point aProjection = lcl_ProjectOntoClosestTableFrm( *pCurrentTab, *pEnd, bRowDrag );
1790 0 : paPt[1] = aProjection;
1791 : }
1792 :
1793 0 : if ( ppPos[0] )
1794 : {
1795 0 : SwShellCrsr* pCrsr = _GetCrsr();
1796 0 : SwCrsrSaveState aSaveState( *pCrsr );
1797 0 : SwPosition aOldPos( *pCrsr->GetPoint() );
1798 :
1799 0 : pCrsr->DeleteMark();
1800 0 : *pCrsr->GetPoint() = *ppPos[0];
1801 0 : pCrsr->GetPtPos() = paPt[0];
1802 :
1803 0 : if ( !pCrsr->IsInProtectTable( false, true ) )
1804 : {
1805 0 : bool bNewSelection = true;
1806 :
1807 0 : if ( ppPos[1] )
1808 : {
1809 0 : if ( ppPos[1]->nNode.GetNode().StartOfSectionNode() !=
1810 0 : aOldPos.nNode.GetNode().StartOfSectionNode() )
1811 : {
1812 0 : pCrsr->SetMark();
1813 0 : SwCrsrSaveState aSaveState2( *pCrsr );
1814 0 : *pCrsr->GetPoint() = *ppPos[1];
1815 0 : pCrsr->GetPtPos() = paPt[1];
1816 :
1817 0 : if ( pCrsr->IsInProtectTable( false, false ) )
1818 : {
1819 0 : pCrsr->RestoreSavePos();
1820 0 : bNewSelection = false;
1821 0 : }
1822 : }
1823 : else
1824 : {
1825 0 : pCrsr->RestoreSavePos();
1826 0 : bNewSelection = false;
1827 : }
1828 : }
1829 :
1830 0 : if ( bNewSelection )
1831 : {
1832 : // #i35543# SelTblRowCol should remove any existing
1833 : // table cursor:
1834 0 : if ( IsTableMode() )
1835 0 : TblCrsrToCursor();
1836 :
1837 0 : if ( pbRow[0] && pbCol[0] )
1838 0 : bRet = SwCrsrShell::SelTbl();
1839 0 : else if ( pbRow[0] )
1840 0 : bRet = SwCrsrShell::_SelTblRowOrCol( true, true );
1841 0 : else if ( pbCol[0] )
1842 0 : bRet = SwCrsrShell::_SelTblRowOrCol( false, true );
1843 : }
1844 : else
1845 0 : bRet = true;
1846 : }
1847 :
1848 0 : delete ppPos[0];
1849 0 : delete ppPos[1];
1850 : }
1851 :
1852 0 : return bRet;
1853 : }
1854 :
1855 0 : SwTab SwFEShell::WhichMouseTabCol( const Point &rPt ) const
1856 : {
1857 0 : SwTab nRet = SwTab::COL_NONE;
1858 0 : bool bRow = false;
1859 0 : bool bCol = false;
1860 0 : bool bSelect = false;
1861 :
1862 : // First try: Do we get the row/col move cursor?
1863 0 : SwCellFrm* pFrm = (SwCellFrm*)GetBox( rPt, &bRow, 0 );
1864 :
1865 0 : if ( !pFrm )
1866 : {
1867 : // Second try: Do we get the row/col/tab selection cursor?
1868 0 : pFrm = (SwCellFrm*)GetBox( rPt, &bRow, &bCol );
1869 0 : bSelect = true;
1870 : }
1871 :
1872 0 : if( pFrm )
1873 : {
1874 0 : while( pFrm && pFrm->Lower() && pFrm->Lower()->IsRowFrm() )
1875 0 : pFrm = (SwCellFrm*)((SwLayoutFrm*)pFrm->Lower())->Lower();
1876 0 : if( pFrm && pFrm->GetTabBox()->GetSttNd() &&
1877 0 : pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() )
1878 0 : pFrm = 0;
1879 : }
1880 :
1881 0 : if( pFrm )
1882 : {
1883 0 : if ( !bSelect )
1884 : {
1885 0 : if ( pFrm->IsVertical() )
1886 0 : nRet = bRow ? SwTab::COL_VERT : SwTab::ROW_VERT;
1887 : else
1888 0 : nRet = bRow ? SwTab::ROW_HORI : SwTab::COL_HORI;
1889 : }
1890 : else
1891 : {
1892 0 : const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
1893 0 : if ( pTabFrm->IsVertical() )
1894 : {
1895 0 : if ( bRow && bCol )
1896 : {
1897 0 : nRet = SwTab::SEL_VERT;
1898 : }
1899 0 : else if ( bRow )
1900 : {
1901 0 : nRet = SwTab::ROWSEL_VERT;
1902 : }
1903 0 : else if ( bCol )
1904 : {
1905 0 : nRet = SwTab::COLSEL_VERT;
1906 : }
1907 : }
1908 : else
1909 : {
1910 0 : if ( bRow && bCol )
1911 : {
1912 0 : nRet = pTabFrm->IsRightToLeft() ?
1913 : SwTab::SEL_HORI_RTL :
1914 0 : SwTab::SEL_HORI;
1915 : }
1916 0 : else if ( bRow )
1917 : {
1918 0 : nRet = pTabFrm->IsRightToLeft() ?
1919 : SwTab::ROWSEL_HORI_RTL :
1920 0 : SwTab::ROWSEL_HORI;
1921 : }
1922 0 : else if ( bCol )
1923 : {
1924 0 : nRet = SwTab::COLSEL_HORI;
1925 : }
1926 : }
1927 : }
1928 : }
1929 :
1930 0 : return nRet;
1931 : }
1932 :
1933 : // -> #i23726#
1934 0 : SwTxtNode * SwFEShell::GetNumRuleNodeAtPos( const Point &rPt)
1935 : {
1936 0 : SwTxtNode * pResult = NULL;
1937 :
1938 : SwContentAtPos aCntntAtPos
1939 0 : (SwContentAtPos::SW_NUMLABEL);
1940 :
1941 0 : if( GetContentAtPos(rPt, aCntntAtPos) && aCntntAtPos.aFnd.pNode)
1942 0 : pResult = aCntntAtPos.aFnd.pNode->GetTxtNode();
1943 :
1944 0 : return pResult;
1945 : }
1946 :
1947 0 : bool SwFEShell::IsNumLabel( const Point &rPt, int nMaxOffset )
1948 : {
1949 0 : bool bResult = false;
1950 :
1951 : SwContentAtPos aCntntAtPos
1952 0 : (SwContentAtPos::SW_NUMLABEL);
1953 :
1954 0 : if( GetContentAtPos(rPt, aCntntAtPos))
1955 : {
1956 0 : if ((nMaxOffset >= 0 && aCntntAtPos.nDist <= nMaxOffset) ||
1957 : (nMaxOffset < 0))
1958 0 : bResult = true;
1959 : }
1960 :
1961 0 : return bResult;
1962 : }
1963 : // <- #i23726#
1964 :
1965 : // #i42921#
1966 0 : bool SwFEShell::IsVerticalModeAtNdAndPos( const SwTxtNode& _rTxtNode,
1967 : const Point& _rDocPos ) const
1968 : {
1969 0 : bool bRet( false );
1970 :
1971 : const short nTextDir =
1972 0 : _rTxtNode.GetTextDirection( SwPosition(_rTxtNode), &_rDocPos );
1973 0 : switch ( nTextDir )
1974 : {
1975 : case -1:
1976 : case FRMDIR_HORI_RIGHT_TOP:
1977 : case FRMDIR_HORI_LEFT_TOP:
1978 : {
1979 0 : bRet = false;
1980 : }
1981 0 : break;
1982 : case FRMDIR_VERT_TOP_LEFT:
1983 : case FRMDIR_VERT_TOP_RIGHT:
1984 : {
1985 0 : bRet = true;
1986 : }
1987 0 : break;
1988 : }
1989 :
1990 0 : return bRet;
1991 : }
1992 :
1993 0 : void SwFEShell::GetMouseTabCols( SwTabCols &rToFill, const Point &rPt ) const
1994 : {
1995 0 : const SwFrm *pBox = GetBox( rPt );
1996 0 : if ( pBox )
1997 0 : _GetTabCols( rToFill, pBox );
1998 0 : }
1999 :
2000 0 : void SwFEShell::SetMouseTabCols( const SwTabCols &rNew, bool bCurRowOnly,
2001 : const Point &rPt )
2002 : {
2003 0 : const SwFrm *pBox = GetBox( rPt );
2004 0 : if( pBox )
2005 : {
2006 0 : SET_CURR_SHELL( this );
2007 0 : StartAllAction();
2008 0 : GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
2009 0 : EndAllActionAndCall();
2010 : }
2011 0 : }
2012 :
2013 0 : sal_uInt16 SwFEShell::GetCurMouseColNum( const Point &rPt,
2014 : SwGetCurColNumPara* pPara ) const
2015 : {
2016 0 : return _GetCurColNum( GetBox( rPt ), pPara );
2017 : }
2018 :
2019 0 : size_t SwFEShell::GetCurMouseTabColNum( const Point &rPt ) const
2020 : {
2021 : //!!!GetCurTabColNum() mitpflegen!!!!
2022 0 : size_t nRet = 0;
2023 :
2024 0 : const SwFrm *pFrm = GetBox( rPt );
2025 : OSL_ENSURE( pFrm, "Table not found" );
2026 0 : if( pFrm )
2027 : {
2028 0 : const long nX = pFrm->Frm().Left();
2029 :
2030 : // get TabCols, only via these we get the position
2031 0 : SwTabCols aTabCols;
2032 0 : GetMouseTabCols( aTabCols, rPt );
2033 :
2034 0 : const long nLeft = aTabCols.GetLeftMin();
2035 :
2036 0 : if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
2037 : {
2038 0 : for ( size_t i = 0; i < aTabCols.Count(); ++i )
2039 0 : if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
2040 : {
2041 0 : nRet = i + 1;
2042 0 : break;
2043 : }
2044 0 : }
2045 : }
2046 0 : return nRet;
2047 : }
2048 :
2049 4722 : void ClearFEShellTabCols()
2050 : {
2051 4722 : DELETEZ( pLastCols );
2052 4722 : DELETEZ( pLastRows );
2053 4722 : }
2054 :
2055 0 : void SwFEShell::GetTblAttr( SfxItemSet &rSet ) const
2056 : {
2057 0 : SwFrm *pFrm = GetCurrFrm();
2058 0 : if( pFrm && pFrm->IsInTab() )
2059 0 : rSet.Put( pFrm->ImplFindTabFrm()->GetFmt()->GetAttrSet() );
2060 0 : }
2061 :
2062 0 : void SwFEShell::SetTblAttr( const SfxItemSet &rNew )
2063 : {
2064 0 : SwFrm *pFrm = GetCurrFrm();
2065 0 : if( pFrm && pFrm->IsInTab() )
2066 : {
2067 0 : SET_CURR_SHELL( this );
2068 0 : StartAllAction();
2069 0 : SwTabFrm *pTab = pFrm->FindTabFrm();
2070 0 : pTab->GetTable()->SetHTMLTableLayout( 0 );
2071 0 : GetDoc()->SetAttr( rNew, *pTab->GetFmt() );
2072 0 : GetDoc()->getIDocumentState().SetModified();
2073 0 : EndAllActionAndCall();
2074 : }
2075 0 : }
2076 :
2077 : /** move cursor within a table into previous/next row (same column)
2078 : * @param pShell cursor shell whose cursor is to be moved
2079 : * @param bUp true: move up, false: move down
2080 : * @returns true if successful
2081 : */
2082 0 : static bool lcl_GoTableRow( SwCrsrShell* pShell, bool bUp )
2083 : {
2084 : OSL_ENSURE( pShell != NULL, "need shell" );
2085 :
2086 0 : SwPaM* pPam = pShell->GetCrsr();
2087 0 : const SwStartNode* pTableBox = pPam->GetNode().FindTableBoxStartNode();
2088 : OSL_ENSURE( pTableBox != NULL, "I'm living in a box... NOT!" );
2089 :
2090 : // move cursor to start node of table box
2091 0 : pPam->GetPoint()->nNode = pTableBox->GetIndex();
2092 0 : pPam->GetPoint()->nContent.Assign( NULL, 0 );
2093 0 : GoInCntnt( *pPam, fnMoveForward );
2094 :
2095 : // go to beginning end of table box
2096 0 : SwPosSection fnPosSect = bUp ? fnSectionStart : fnSectionEnd;
2097 0 : pShell->MoveSection( fnSectionCurr, fnPosSect );
2098 :
2099 : // and go up/down into next content
2100 0 : return bUp ? pShell->Up() : pShell->Down();
2101 : }
2102 :
2103 : // aender eine Zellenbreite/-Hoehe/Spaltenbreite/Zeilenhoehe
2104 0 : bool SwFEShell::SetColRowWidthHeight( sal_uInt16 eType, sal_uInt16 nDiff )
2105 : {
2106 0 : SwFrm *pFrm = GetCurrFrm();
2107 0 : if( !pFrm || !pFrm->IsInTab() )
2108 0 : return false;
2109 :
2110 0 : if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType &&
2111 0 : pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
2112 : {
2113 : ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
2114 0 : ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
2115 0 : return false;
2116 : }
2117 :
2118 0 : SET_CURR_SHELL( this );
2119 0 : StartAllAction();
2120 :
2121 0 : do {
2122 0 : pFrm = pFrm->GetUpper();
2123 0 : } while( !pFrm->IsCellFrm() );
2124 :
2125 0 : SwTabFrm *pTab = pFrm->ImplFindTabFrm();
2126 :
2127 : // if the table is in relative values (USHRT_MAX)
2128 : // then it should be recalculated to absolute values now
2129 0 : const SwFmtFrmSize& rTblFrmSz = pTab->GetFmt()->GetFrmSize();
2130 0 : SWRECTFN( pTab )
2131 0 : long nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
2132 0 : if( TBLVAR_CHGABS == pTab->GetTable()->GetTblChgMode() &&
2133 0 : ( eType & nsTblChgWidthHeightType::WH_COL_LEFT || eType & nsTblChgWidthHeightType::WH_COL_RIGHT ) &&
2134 0 : text::HoriOrientation::NONE == pTab->GetFmt()->GetHoriOrient().GetHoriOrient() &&
2135 0 : nPrtWidth != rTblFrmSz.GetWidth() )
2136 : {
2137 0 : SwFmtFrmSize aSz( rTblFrmSz );
2138 0 : aSz.SetWidth( pTab->Prt().Width() );
2139 0 : pTab->GetFmt()->SetFmtAttr( aSz );
2140 : }
2141 :
2142 0 : if( (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) ==
2143 : (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL) )
2144 : {
2145 0 : nDiff = sal_uInt16((pFrm->Frm().*fnRect->fnGetWidth)());
2146 :
2147 : // we must move the cursor outside the current cell before
2148 : // deleting the cells.
2149 : TblChgWidthHeightType eTmp =
2150 0 : static_cast<TblChgWidthHeightType>( eType & 0xfff );
2151 0 : switch( eTmp )
2152 : {
2153 : case nsTblChgWidthHeightType::WH_ROW_TOP:
2154 0 : lcl_GoTableRow( this, true );
2155 0 : break;
2156 : case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
2157 0 : lcl_GoTableRow( this, false );
2158 0 : break;
2159 : case nsTblChgWidthHeightType::WH_COL_LEFT:
2160 0 : GoPrevCell();
2161 0 : break;
2162 : case nsTblChgWidthHeightType::WH_COL_RIGHT:
2163 0 : GoNextCell();
2164 0 : break;
2165 : default:
2166 0 : break;
2167 : }
2168 : }
2169 :
2170 0 : SwTwips nLogDiff = nDiff;
2171 0 : nLogDiff *= pTab->GetFmt()->GetFrmSize().GetWidth();
2172 0 : nLogDiff /= nPrtWidth;
2173 :
2174 : /** The cells are destroyed in here */
2175 : bool bRet = GetDoc()->SetColRowWidthHeight(
2176 0 : *(SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(),
2177 0 : eType, nDiff, nLogDiff );
2178 :
2179 0 : delete pLastCols, pLastCols = 0;
2180 0 : EndAllActionAndCall();
2181 :
2182 0 : if( bRet && (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) == nsTblChgWidthHeightType::WH_FLAG_INSDEL )
2183 : {
2184 0 : switch(eType & ~(nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL))
2185 : {
2186 : case nsTblChgWidthHeightType::WH_CELL_LEFT:
2187 : case nsTblChgWidthHeightType::WH_COL_LEFT:
2188 0 : GoPrevCell();
2189 0 : break;
2190 :
2191 : case nsTblChgWidthHeightType::WH_CELL_RIGHT:
2192 : case nsTblChgWidthHeightType::WH_COL_RIGHT:
2193 0 : GoNextCell();
2194 0 : break;
2195 :
2196 : case nsTblChgWidthHeightType::WH_CELL_TOP:
2197 : case nsTblChgWidthHeightType::WH_ROW_TOP:
2198 0 : lcl_GoTableRow( this, true );
2199 0 : break;
2200 :
2201 : case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
2202 : case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
2203 0 : lcl_GoTableRow( this, false );
2204 0 : break;
2205 : }
2206 : }
2207 :
2208 0 : return bRet;
2209 : }
2210 :
2211 0 : static bool lcl_IsFormulaSelBoxes( const SwTable& rTbl, const SwTblBoxFormula& rFml,
2212 : SwCellFrms& rCells )
2213 : {
2214 0 : SwTblBoxFormula aTmp( rFml );
2215 0 : SwSelBoxes aBoxes;
2216 0 : aTmp.GetBoxesOfFormula(rTbl, aBoxes);
2217 0 : for (size_t nSelBoxes = aBoxes.size(); nSelBoxes; )
2218 : {
2219 0 : SwTableBox* pBox = aBoxes[ --nSelBoxes ];
2220 0 : SwCellFrms::iterator iC;
2221 0 : for( iC = rCells.begin(); iC != rCells.end(); ++iC )
2222 0 : if( (*iC)->GetTabBox() == pBox )
2223 0 : break; // found
2224 :
2225 0 : if( iC == rCells.end() )
2226 0 : return false;
2227 : }
2228 :
2229 0 : return true;
2230 : }
2231 :
2232 : // ask formula for auto-sum
2233 0 : bool SwFEShell::GetAutoSum( OUString& rFml ) const
2234 : {
2235 0 : SwFrm *pFrm = GetCurrFrm();
2236 0 : SwTabFrm *pTab = pFrm ? pFrm->ImplFindTabFrm() : 0;
2237 0 : if( !pTab )
2238 0 : return false;
2239 :
2240 0 : SwCellFrms aCells;
2241 0 : OUString sFields;
2242 0 : if( ::GetAutoSumSel( *this, aCells ))
2243 : {
2244 0 : sal_uInt16 nW = 0;
2245 0 : for( size_t n = aCells.size(); n; )
2246 : {
2247 0 : SwCellFrm* pCFrm = aCells[ --n ];
2248 0 : sal_uInt16 nBoxW = pCFrm->GetTabBox()->IsFormulaOrValueBox();
2249 0 : if( !nBoxW )
2250 0 : break;
2251 :
2252 0 : if( !nW )
2253 : {
2254 0 : if( USHRT_MAX == nBoxW )
2255 0 : continue; // skip space at beginning
2256 :
2257 : // formula only if box is contained
2258 0 : if( RES_BOXATR_FORMULA == nBoxW &&
2259 0 : !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
2260 0 : GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells))
2261 : {
2262 0 : nW = RES_BOXATR_VALUE;
2263 : // restore previous spaces!
2264 0 : for( size_t i = aCells.size(); n+1 < i; )
2265 : {
2266 0 : sFields = "|<" + aCells[--i]->GetTabBox()->GetName() + ">"
2267 0 : + sFields;
2268 : }
2269 : }
2270 : else
2271 0 : nW = nBoxW;
2272 : }
2273 0 : else if( RES_BOXATR_VALUE == nW )
2274 : {
2275 : // search for values, Value/Formula/Text found -> include
2276 0 : if( RES_BOXATR_FORMULA == nBoxW &&
2277 0 : ::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
2278 0 : GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
2279 0 : break;
2280 0 : else if( USHRT_MAX != nBoxW )
2281 0 : sFields = OUString(cListDelim) + sFields;
2282 : else
2283 0 : break;
2284 : }
2285 0 : else if( RES_BOXATR_FORMULA == nW )
2286 : {
2287 : // only continue search when the current formula points to
2288 : // all boxes contained in the selection
2289 0 : if( RES_BOXATR_FORMULA == nBoxW )
2290 : {
2291 0 : if( !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
2292 0 : GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
2293 : {
2294 : // redo only for values!
2295 :
2296 0 : nW = RES_BOXATR_VALUE;
2297 0 : sFields = OUString();
2298 : // restore previous spaces!
2299 0 : for( size_t i = aCells.size(); n+1 < i; )
2300 : {
2301 0 : sFields = "|<" + aCells[--i]->GetTabBox()->GetName() + ">"
2302 0 : + sFields;
2303 : }
2304 : }
2305 : else
2306 0 : sFields = OUString(cListDelim) + sFields;
2307 : }
2308 0 : else if( USHRT_MAX == nBoxW )
2309 0 : break;
2310 : else
2311 0 : continue; // ignore this box
2312 : }
2313 : else
2314 : // all other stuff terminates the loop
2315 : // possibly allow texts??
2316 0 : break;
2317 :
2318 0 : sFields = "<" + pCFrm->GetTabBox()->GetName() + ">" + sFields;
2319 : }
2320 : }
2321 :
2322 0 : rFml = OUString::createFromAscii( sCalc_Sum );
2323 0 : if (!sFields.isEmpty())
2324 : {
2325 0 : rFml += "(" + sFields + ")";
2326 : }
2327 :
2328 0 : return true;
2329 : }
2330 :
2331 8 : bool SwFEShell::IsTableRightToLeft() const
2332 : {
2333 8 : SwFrm *pFrm = GetCurrFrm();
2334 8 : if( !pFrm || !pFrm->IsInTab() )
2335 0 : return false;
2336 :
2337 8 : return pFrm->ImplFindTabFrm()->IsRightToLeft();
2338 : }
2339 :
2340 0 : bool SwFEShell::IsMouseTableRightToLeft(const Point &rPt) const
2341 : {
2342 0 : SwFrm *pFrm = (SwFrm *)GetBox( rPt );
2343 0 : const SwTabFrm* pTabFrm = pFrm ? pFrm->ImplFindTabFrm() : 0;
2344 : OSL_ENSURE( pTabFrm, "Table not found" );
2345 0 : return pTabFrm ? pTabFrm->IsRightToLeft() : sal_False;
2346 : }
2347 :
2348 8 : bool SwFEShell::IsTableVertical() const
2349 : {
2350 8 : SwFrm *pFrm = GetCurrFrm();
2351 8 : if( !pFrm || !pFrm->IsInTab() )
2352 0 : return false;
2353 :
2354 8 : return pFrm->ImplFindTabFrm()->IsVertical();
2355 270 : }
2356 :
2357 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|