1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: edtab.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <com/sun/star/chart2/XChartDocument.hpp>
35 #include <hintids.hxx>
38 #define _SVSTDARR_ULONGS
39 #include <svtools/svstdarr.hxx>
41 #ifndef _APP_HXX //autogen
42 #include <vcl/svapp.hxx>
44 #include <vcl/window.hxx>
45 #include <svx/boxitem.hxx>
47 #include <fmtfsize.hxx>
55 #include <swtable.hxx>
60 #include <cellfrm.hxx>
61 #include <cellatr.hxx>
62 #include <swtblfmt.hxx>
63 #include <swddetbl.hxx>
65 #include <unochart.hxx>
67 using namespace ::com::sun::star
;
68 using namespace ::com::sun::star::uno
;
70 extern void ClearFEShellTabCols();
72 const SwTable
& SwEditShell::InsertTable( const SwInsertTableOptions
& rInsTblOpts
,
73 USHORT nRows
, USHORT nCols
,
75 const SwTableAutoFmt
* pTAFmt
)
78 SwPosition
* pPos
= GetCrsr()->GetPoint();
80 BOOL bEndUndo
= 0 != pPos
->nContent
.GetIndex();
83 StartUndo( UNDO_START
);
84 GetDoc()->SplitNode( *pPos
, false );
87 /* #109161# If called from a shell the adjust item is propagated
88 from pPos to the new content nodes in the table.
90 const SwTable
*pTable
= GetDoc()->InsertTable( rInsTblOpts
, *pPos
,
101 BOOL
SwEditShell::TextToTable( const SwInsertTableOptions
& rInsTblOpts
,
104 const SwTableAutoFmt
* pTAFmt
)
106 SwWait
aWait( *GetDoc()->GetDocShell(), TRUE
);
109 FOREACHPAM_START(this)
110 if( PCURCRSR
->HasMark() )
111 bRet
|= 0 != GetDoc()->TextToTable( rInsTblOpts
, *PCURCRSR
, cCh
,
118 BOOL
SwEditShell::TableToText( sal_Unicode cCh
)
120 SwWait
aWait( *GetDoc()->GetDocShell(), TRUE
);
122 SwPaM
* pCrsr
= GetCrsr();
123 const SwTableNode
* pTblNd
=
124 GetDoc()->IsIdxInTbl( pCrsr
->GetPoint()->nNode
);
130 else if( !pTblNd
|| pCrsr
->GetNext() != pCrsr
)
134 // tell the charts about the table to be deleted and have them use their own data
135 GetDoc()->CreateChartInternalDataProviders( &pTblNd
->GetTable() );
139 // verschiebe den akt. Cursor aus dem Tabellen Bereich
141 SwNodeIndex
aTabIdx( *pTblNd
);
143 pCrsr
->GetPoint()->nNode
= *pTblNd
->EndOfSectionNode();
144 pCrsr
->GetPoint()->nContent
.Assign( 0, 0 );
145 // SPoint und Mark aus dem Bereich verschieben !!!
149 bRet
= GetDoc()->TableToText( pTblNd
, cCh
);
150 pCrsr
->GetPoint()->nNode
= aTabIdx
;
152 SwCntntNode
* pCNd
= pCrsr
->GetCntntNode();
154 pCrsr
->Move( fnMoveForward
, fnGoCntnt
);
156 pCrsr
->GetPoint()->nContent
.Assign( pCNd
, 0 );
162 BOOL
SwEditShell::IsTextToTableAvailable() const
164 BOOL bOnlyText
= FALSE
;
165 FOREACHPAM_START(this)
166 if( PCURCRSR
->HasMark() && *PCURCRSR
->GetPoint() != *PCURCRSR
->GetMark() )
170 // pruefe ob in der Selection eine Tabelle liegt
171 ULONG nStt
= PCURCRSR
->GetMark()->nNode
.GetIndex(),
172 nEnd
= PCURCRSR
->GetPoint()->nNode
.GetIndex();
173 if( nStt
> nEnd
) { ULONG n
= nStt
; nStt
= nEnd
; nEnd
= n
; }
175 for( ; nStt
<= nEnd
; ++nStt
)
176 if( !GetDoc()->GetNodes()[ nStt
]->IsTxtNode() )
190 void SwEditShell::InsertDDETable( const SwInsertTableOptions
& rInsTblOpts
,
191 SwDDEFieldType
* pDDEType
,
192 USHORT nRows
, USHORT nCols
,
195 SwPosition
* pPos
= GetCrsr()->GetPoint();
199 BOOL bEndUndo
= 0 != pPos
->nContent
.GetIndex();
202 StartUndo( UNDO_START
);
203 GetDoc()->SplitNode( *pPos
, false );
206 const SwInsertTableOptions
aInsTblOpts( rInsTblOpts
.mnInsMode
| tabopts::DEFAULT_BORDER
,
207 rInsTblOpts
.mnRowsToRepeat
);
208 SwTable
* pTbl
= (SwTable
*)GetDoc()->InsertTable( aInsTblOpts
, *pPos
,
209 nRows
, nCols
, eAdj
);
211 SwTableNode
* pTblNode
= (SwTableNode
*)pTbl
->GetTabSortBoxes()[ 0 ]->
212 GetSttNd()->FindTableNode();
213 SwDDETable
* pDDETbl
= new SwDDETable( *pTbl
, pDDEType
);
214 pTblNode
->SetNewTable( pDDETbl
); // setze die DDE-Tabelle
222 /*--------------------------------------------------------------------
223 Beschreibung: Tabellenfelder einer Tabelle updaten
224 --------------------------------------------------------------------*/
225 void SwEditShell::UpdateTable()
227 const SwTableNode
* pTblNd
= IsCrsrInTbl();
229 // Keine Arme keine Kekse
236 SwTableFmlUpdate
aTblUpdate( (SwTable
*)&pTblNd
->GetTable() );
237 GetDoc()->UpdateTblFlds( &aTblUpdate
);
244 // Change Modus erfragen/setzen
245 TblChgMode
SwEditShell::GetTblChgMode() const
248 const SwTableNode
* pTblNd
= IsCrsrInTbl();
250 eMode
= pTblNd
->GetTable().GetTblChgMode();
252 eMode
= GetTblChgDefaultMode();
256 void SwEditShell::SetTblChgMode( TblChgMode eMode
)
258 const SwTableNode
* pTblNd
= IsCrsrInTbl();
260 // Keine Arme keine Kekse
263 ((SwTable
&)pTblNd
->GetTable()).SetTblChgMode( eMode
);
264 if( !GetDoc()->IsModified() ) // Bug 57028
265 GetDoc()->SetUndoNoResetModified();
266 GetDoc()->SetModified();
270 BOOL
SwEditShell::GetTblBoxFormulaAttrs( SfxItemSet
& rSet
) const
274 ::GetTblSelCrs( *this, aBoxes
);
278 SwFrm
*pFrm
= GetCurrFrm();
280 pFrm
= pFrm
->GetUpper();
281 } while ( pFrm
&& !pFrm
->IsCellFrm() );
284 SwTableBox
*pBox
= (SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox();
285 aBoxes
.Insert( pBox
);
290 for( USHORT n
= 0; n
< aBoxes
.Count(); ++n
)
292 const SwTableBox
* pSelBox
= aBoxes
[ n
];
293 const SwTableBoxFmt
* pTblFmt
= (SwTableBoxFmt
*)pSelBox
->GetFrmFmt();
296 // Formeln in die externe Darstellung bringen!
297 const SwTable
& rTbl
= pSelBox
->GetSttNd()->FindTableNode()->GetTable();
299 SwTableFmlUpdate
aTblUpdate( (SwTable
*)&rTbl
);
300 aTblUpdate
.eFlags
= TBL_BOXNAME
;
301 ((SwDoc
*)GetDoc())->UpdateTblFlds( &aTblUpdate
);
303 rSet
.Put( pTblFmt
->GetAttrSet() );
306 rSet
.MergeValues( pTblFmt
->GetAttrSet() );
308 return 0 != rSet
.Count();
311 void SwEditShell::SetTblBoxFormulaAttrs( const SfxItemSet
& rSet
)
313 SET_CURR_SHELL( this );
316 ::GetTblSelCrs( *this, aBoxes
);
320 SwFrm
*pFrm
= GetCurrFrm();
322 pFrm
= pFrm
->GetUpper();
323 } while ( pFrm
&& !pFrm
->IsCellFrm() );
326 SwTableBox
*pBox
= (SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox();
327 aBoxes
.Insert( pBox
);
332 // beim setzen einer Formel keine Ueberpruefung mehr vornehmen!
333 if( SFX_ITEM_SET
== rSet
.GetItemState( RES_BOXATR_FORMULA
))
337 GetDoc()->StartUndo( UNDO_START
, NULL
);
338 for( USHORT n
= 0; n
< aBoxes
.Count(); ++n
)
339 GetDoc()->SetTblBoxFormulaAttrs( *aBoxes
[ n
], rSet
);
340 GetDoc()->EndUndo( UNDO_END
, NULL
);
344 BOOL
SwEditShell::IsTableBoxTextFormat() const
349 SwTableBox
*pBox
= 0;
351 SwFrm
*pFrm
= GetCurrFrm();
353 pFrm
= pFrm
->GetUpper();
354 } while ( pFrm
&& !pFrm
->IsCellFrm() );
356 pBox
= (SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox();
363 const SfxPoolItem
* pItem
;
364 if( SFX_ITEM_SET
== pBox
->GetFrmFmt()->GetAttrSet().GetItemState(
365 RES_BOXATR_FORMAT
, TRUE
, &pItem
))
367 nFmt
= ((SwTblBoxNumFormat
*)pItem
)->GetValue();
368 return GetDoc()->GetNumberFormatter()->IsTextFormat( nFmt
) ||
369 NUMBERFORMAT_TEXT
== nFmt
;
372 ULONG nNd
= pBox
->IsValidNumTxtNd();
373 if( ULONG_MAX
== nNd
)
376 const String
& rTxt
= GetDoc()->GetNodes()[ nNd
]->GetTxtNode()->GetTxt();
381 return !GetDoc()->GetNumberFormatter()->IsNumberFormat( rTxt
, nFmt
, fVal
);
384 String
SwEditShell::GetTableBoxText() const
389 SwTableBox
*pBox
= 0;
391 SwFrm
*pFrm
= GetCurrFrm();
393 pFrm
= pFrm
->GetUpper();
394 } while ( pFrm
&& !pFrm
->IsCellFrm() );
396 pBox
= (SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox();
400 if( pBox
&& ULONG_MAX
!= ( nNd
= pBox
->IsValidNumTxtNd() ) )
401 sRet
= GetDoc()->GetNodes()[ nNd
]->GetTxtNode()->GetTxt();
406 BOOL
SwEditShell::SplitTable( USHORT eMode
)
409 SwPaM
*pCrsr
= GetCrsr();
410 if( pCrsr
->GetNode()->FindTableNode() )
413 GetDoc()->StartUndo(UNDO_EMPTY
, NULL
);
415 bRet
= GetDoc()->SplitTable( *pCrsr
->GetPoint(), eMode
, TRUE
);
417 GetDoc()->EndUndo(UNDO_EMPTY
, NULL
);
418 ClearFEShellTabCols();
424 BOOL
SwEditShell::MergeTable( BOOL bWithPrev
, USHORT nMode
)
427 SwPaM
*pCrsr
= GetCrsr();
428 if( pCrsr
->GetNode()->FindTableNode() )
431 GetDoc()->StartUndo(UNDO_EMPTY
, NULL
);
433 bRet
= GetDoc()->MergeTable( *pCrsr
->GetPoint(), bWithPrev
, nMode
);
435 GetDoc()->EndUndo(UNDO_EMPTY
, NULL
);
436 ClearFEShellTabCols();
442 BOOL
SwEditShell::CanMergeTable( BOOL bWithPrev
, BOOL
* pChkNxtPrv
) const
445 const SwPaM
*pCrsr
= GetCrsr();
446 const SwTableNode
* pTblNd
= pCrsr
->GetNode()->FindTableNode();
447 if( pTblNd
&& !pTblNd
->GetTable().ISA( SwDDETable
))
449 BOOL bNew
= pTblNd
->GetTable().IsNewModel();
450 const SwNodes
& rNds
= GetDoc()->GetNodes();
453 const SwTableNode
* pChkNd
= rNds
[ pTblNd
->GetIndex() - 1 ]->FindTableNode();
454 if( pChkNd
&& !pChkNd
->GetTable().ISA( SwDDETable
) &&
455 bNew
== pChkNd
->GetTable().IsNewModel() &&
456 // --> FME 2004-09-17 #117418# Consider table in table case
457 pChkNd
->EndOfSectionIndex() == pTblNd
->GetIndex() - 1 )
459 *pChkNxtPrv
= TRUE
, bRet
= TRUE
; // mit Prev ist moeglich
462 pChkNd
= rNds
[ pTblNd
->EndOfSectionIndex() + 1 ]->GetTableNode();
463 if( pChkNd
&& !pChkNd
->GetTable().ISA( SwDDETable
) &&
464 bNew
== pChkNd
->GetTable().IsNewModel() )
465 *pChkNxtPrv
= FALSE
, bRet
= TRUE
; // mit Next ist moeglich
470 const SwTableNode
* pTmpTblNd
= 0;
474 pTmpTblNd
= rNds
[ pTblNd
->GetIndex() - 1 ]->FindTableNode();
475 // --> FME 2004-09-17 #117418# Consider table in table case
476 if ( pTmpTblNd
&& pTmpTblNd
->EndOfSectionIndex() != pTblNd
->GetIndex() - 1 )
481 pTmpTblNd
= rNds
[ pTblNd
->EndOfSectionIndex() + 1 ]->GetTableNode();
483 bRet
= pTmpTblNd
&& !pTmpTblNd
->GetTable().ISA( SwDDETable
) &&
484 bNew
== pTmpTblNd
->GetTable().IsNewModel();
490 // setze das InsertDB als Tabelle Undo auf:
491 void SwEditShell::AppendUndoForInsertFromDB( BOOL bIsTable
)
493 GetDoc()->AppendUndoForInsertFromDB( *GetCrsr(), bIsTable
);