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