summaryrefslogtreecommitdiff
path: root/sw/source/core/edit/edtab.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/edit/edtab.cxx')
-rw-r--r--sw/source/core/edit/edtab.cxx492
1 files changed, 492 insertions, 0 deletions
diff --git a/sw/source/core/edit/edtab.cxx b/sw/source/core/edit/edtab.cxx
new file mode 100644
index 000000000000..76a37e4e8627
--- /dev/null
+++ b/sw/source/core/edit/edtab.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <hintids.hxx>
+#include <hints.hxx>
+
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#include <vcl/window.hxx>
+#include <editeng/boxitem.hxx>
+#include <swwait.hxx>
+#include <fmtfsize.hxx>
+#include <frmatr.hxx>
+#include <editsh.hxx>
+#include <doc.hxx>
+#include <cntfrm.hxx>
+#include <pam.hxx>
+#include <ndtxt.hxx>
+#include <fldbas.hxx>
+#include <swtable.hxx>
+#include <swundo.hxx>
+#include <tblsel.hxx>
+#include <edimp.hxx>
+#include <tabfrm.hxx>
+#include <cellfrm.hxx>
+#include <cellatr.hxx>
+#include <swtblfmt.hxx>
+#include <swddetbl.hxx>
+#include <mdiexp.hxx>
+#include <unochart.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+extern void ClearFEShellTabCols();
+
+const SwTable& SwEditShell::InsertTable( const SwInsertTableOptions& rInsTblOpts,
+ USHORT nRows, USHORT nCols,
+ sal_Int16 eAdj,
+ const SwTableAutoFmt* pTAFmt )
+{
+ StartAllAction();
+ SwPosition* pPos = GetCrsr()->GetPoint();
+
+ BOOL bEndUndo = 0 != pPos->nContent.GetIndex();
+ if( bEndUndo )
+ {
+ StartUndo( UNDO_START );
+ GetDoc()->SplitNode( *pPos, false );
+ }
+
+ /* #109161# If called from a shell the adjust item is propagated
+ from pPos to the new content nodes in the table.
+ */
+ const SwTable *pTable = GetDoc()->InsertTable( rInsTblOpts, *pPos,
+ nRows, nCols,
+ eAdj, pTAFmt,
+ 0, TRUE );
+ if( bEndUndo )
+ EndUndo( UNDO_END );
+
+ EndAllAction();
+ return *pTable;
+}
+
+BOOL SwEditShell::TextToTable( const SwInsertTableOptions& rInsTblOpts,
+ sal_Unicode cCh,
+ sal_Int16 eAdj,
+ const SwTableAutoFmt* pTAFmt )
+{
+ SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+ BOOL bRet = FALSE;
+ StartAllAction();
+ FOREACHPAM_START(this)
+ if( PCURCRSR->HasMark() )
+ bRet |= 0 != GetDoc()->TextToTable( rInsTblOpts, *PCURCRSR, cCh,
+ eAdj, pTAFmt );
+ FOREACHPAM_END()
+ EndAllAction();
+ return bRet;
+}
+
+BOOL SwEditShell::TableToText( sal_Unicode cCh )
+{
+ SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+ BOOL bRet = FALSE;
+ SwPaM* pCrsr = GetCrsr();
+ const SwTableNode* pTblNd =
+ GetDoc()->IsIdxInTbl( pCrsr->GetPoint()->nNode );
+ if( IsTableMode() )
+ {
+ ClearMark();
+ pCrsr = GetCrsr();
+ }
+ else if( !pTblNd || pCrsr->GetNext() != pCrsr )
+ return bRet;
+
+ // TL_CHART2:
+ // tell the charts about the table to be deleted and have them use their own data
+ GetDoc()->CreateChartInternalDataProviders( &pTblNd->GetTable() );
+
+ StartAllAction();
+
+ // verschiebe den akt. Cursor aus dem Tabellen Bereich
+ // angemeldet ist
+ SwNodeIndex aTabIdx( *pTblNd );
+ pCrsr->DeleteMark();
+ pCrsr->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
+ pCrsr->GetPoint()->nContent.Assign( 0, 0 );
+ // SPoint und Mark aus dem Bereich verschieben !!!
+ pCrsr->SetMark();
+ pCrsr->DeleteMark();
+
+ bRet = GetDoc()->TableToText( pTblNd, cCh );
+ pCrsr->GetPoint()->nNode = aTabIdx;
+
+ SwCntntNode* pCNd = pCrsr->GetCntntNode();
+ if( !pCNd )
+ pCrsr->Move( fnMoveForward, fnGoCntnt );
+ else
+ pCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
+
+ EndAllAction();
+ return bRet;
+}
+
+BOOL SwEditShell::IsTextToTableAvailable() const
+{
+ BOOL bOnlyText = FALSE;
+ FOREACHPAM_START(this)
+ if( PCURCRSR->HasMark() && *PCURCRSR->GetPoint() != *PCURCRSR->GetMark() )
+ {
+ bOnlyText = TRUE;
+
+ // pruefe ob in der Selection eine Tabelle liegt
+ ULONG nStt = PCURCRSR->GetMark()->nNode.GetIndex(),
+ nEnd = PCURCRSR->GetPoint()->nNode.GetIndex();
+ if( nStt > nEnd ) { ULONG n = nStt; nStt = nEnd; nEnd = n; }
+
+ for( ; nStt <= nEnd; ++nStt )
+ if( !GetDoc()->GetNodes()[ nStt ]->IsTxtNode() )
+ {
+ bOnlyText = FALSE;
+ break;
+ }
+
+ if( !bOnlyText )
+ break;
+ }
+ FOREACHPAM_END()
+
+ return bOnlyText;
+}
+
+void SwEditShell::InsertDDETable( const SwInsertTableOptions& rInsTblOpts,
+ SwDDEFieldType* pDDEType,
+ USHORT nRows, USHORT nCols,
+ sal_Int16 eAdj )
+{
+ SwPosition* pPos = GetCrsr()->GetPoint();
+
+ StartAllAction();
+
+ BOOL bEndUndo = 0 != pPos->nContent.GetIndex();
+ if( bEndUndo )
+ {
+ StartUndo( UNDO_START );
+ GetDoc()->SplitNode( *pPos, false );
+ }
+
+ const SwInsertTableOptions aInsTblOpts( rInsTblOpts.mnInsMode | tabopts::DEFAULT_BORDER,
+ rInsTblOpts.mnRowsToRepeat );
+ SwTable* pTbl = (SwTable*)GetDoc()->InsertTable( aInsTblOpts, *pPos,
+ nRows, nCols, eAdj );
+
+ SwTableNode* pTblNode = (SwTableNode*)pTbl->GetTabSortBoxes()[ 0 ]->
+ GetSttNd()->FindTableNode();
+ SwDDETable* pDDETbl = new SwDDETable( *pTbl, pDDEType );
+ pTblNode->SetNewTable( pDDETbl ); // setze die DDE-Tabelle
+
+ if( bEndUndo )
+ EndUndo( UNDO_END );
+
+ EndAllAction();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Tabellenfelder einer Tabelle updaten
+ --------------------------------------------------------------------*/
+void SwEditShell::UpdateTable()
+{
+ const SwTableNode* pTblNd = IsCrsrInTbl();
+
+ // Keine Arme keine Kekse
+ if( pTblNd )
+ {
+ StartAllAction();
+ if( DoesUndo() )
+ StartUndo();
+ EndAllTblBoxEdit();
+ SwTableFmlUpdate aTblUpdate( (SwTable*)&pTblNd->GetTable() );
+ GetDoc()->UpdateTblFlds( &aTblUpdate );
+ if( DoesUndo() )
+ EndUndo();
+ EndAllAction();
+ }
+}
+
+ // Change Modus erfragen/setzen
+TblChgMode SwEditShell::GetTblChgMode() const
+{
+ TblChgMode eMode;
+ const SwTableNode* pTblNd = IsCrsrInTbl();
+ if( pTblNd )
+ eMode = pTblNd->GetTable().GetTblChgMode();
+ else
+ eMode = GetTblChgDefaultMode();
+ return eMode;
+}
+
+void SwEditShell::SetTblChgMode( TblChgMode eMode )
+{
+ const SwTableNode* pTblNd = IsCrsrInTbl();
+
+ // Keine Arme keine Kekse
+ if( pTblNd )
+ {
+ ((SwTable&)pTblNd->GetTable()).SetTblChgMode( eMode );
+ if( !GetDoc()->IsModified() ) // Bug 57028
+ GetDoc()->SetUndoNoResetModified();
+ GetDoc()->SetModified();
+ }
+}
+
+BOOL SwEditShell::GetTblBoxFormulaAttrs( SfxItemSet& rSet ) const
+{
+ SwSelBoxes aBoxes;
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ do {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if ( pFrm )
+ {
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+ } while( FALSE );
+ }
+
+ for( USHORT n = 0; n < aBoxes.Count(); ++n )
+ {
+ const SwTableBox* pSelBox = aBoxes[ n ];
+ const SwTableBoxFmt* pTblFmt = (SwTableBoxFmt*)pSelBox->GetFrmFmt();
+ if( !n )
+ {
+ // Formeln in die externe Darstellung bringen!
+ const SwTable& rTbl = pSelBox->GetSttNd()->FindTableNode()->GetTable();
+
+ SwTableFmlUpdate aTblUpdate( (SwTable*)&rTbl );
+ aTblUpdate.eFlags = TBL_BOXNAME;
+ ((SwDoc*)GetDoc())->UpdateTblFlds( &aTblUpdate );
+
+ rSet.Put( pTblFmt->GetAttrSet() );
+ }
+ else
+ rSet.MergeValues( pTblFmt->GetAttrSet() );
+ }
+ return 0 != rSet.Count();
+}
+
+void SwEditShell::SetTblBoxFormulaAttrs( const SfxItemSet& rSet )
+{
+ SET_CURR_SHELL( this );
+ SwSelBoxes aBoxes;
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ do {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if ( pFrm )
+ {
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+ } while( FALSE );
+ }
+
+ // beim setzen einer Formel keine Ueberpruefung mehr vornehmen!
+ if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA ))
+ ClearTblBoxCntnt();
+
+ StartAllAction();
+ GetDoc()->StartUndo( UNDO_START, NULL );
+ for( USHORT n = 0; n < aBoxes.Count(); ++n )
+ GetDoc()->SetTblBoxFormulaAttrs( *aBoxes[ n ], rSet );
+ GetDoc()->EndUndo( UNDO_END, NULL );
+ EndAllAction();
+}
+
+BOOL SwEditShell::IsTableBoxTextFormat() const
+{
+ if( IsTableMode() )
+ return FALSE;
+
+ SwTableBox *pBox = 0;
+ {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if ( pFrm )
+ pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ }
+
+ if( !pBox )
+ return FALSE;
+
+ sal_uInt32 nFmt;
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetAttrSet().GetItemState(
+ RES_BOXATR_FORMAT, TRUE, &pItem ))
+ {
+ nFmt = ((SwTblBoxNumFormat*)pItem)->GetValue();
+ return GetDoc()->GetNumberFormatter()->IsTextFormat( nFmt ) ||
+ NUMBERFORMAT_TEXT == nFmt;
+ }
+
+ ULONG nNd = pBox->IsValidNumTxtNd();
+ if( ULONG_MAX == nNd )
+ return TRUE;
+
+ const String& rTxt = GetDoc()->GetNodes()[ nNd ]->GetTxtNode()->GetTxt();
+ if( !rTxt.Len() )
+ return FALSE;
+
+ double fVal;
+ return !GetDoc()->GetNumberFormatter()->IsNumberFormat( rTxt, nFmt, fVal );
+}
+
+String SwEditShell::GetTableBoxText() const
+{
+ String sRet;
+ if( !IsTableMode() )
+ {
+ SwTableBox *pBox = 0;
+ {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if ( pFrm )
+ pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ }
+
+ ULONG nNd;
+ if( pBox && ULONG_MAX != ( nNd = pBox->IsValidNumTxtNd() ) )
+ sRet = GetDoc()->GetNodes()[ nNd ]->GetTxtNode()->GetTxt();
+ }
+ return sRet;
+}
+
+BOOL SwEditShell::SplitTable( USHORT eMode )
+{
+ BOOL bRet = FALSE;
+ SwPaM *pCrsr = GetCrsr();
+ if( pCrsr->GetNode()->FindTableNode() )
+ {
+ StartAllAction();
+ GetDoc()->StartUndo(UNDO_EMPTY, NULL);
+
+ bRet = GetDoc()->SplitTable( *pCrsr->GetPoint(), eMode, TRUE );
+
+ GetDoc()->EndUndo(UNDO_EMPTY, NULL);
+ ClearFEShellTabCols();
+ EndAllAction();
+ }
+ return bRet;
+}
+
+BOOL SwEditShell::MergeTable( BOOL bWithPrev, USHORT nMode )
+{
+ BOOL bRet = FALSE;
+ SwPaM *pCrsr = GetCrsr();
+ if( pCrsr->GetNode()->FindTableNode() )
+ {
+ StartAllAction();
+ GetDoc()->StartUndo(UNDO_EMPTY, NULL);
+
+ bRet = GetDoc()->MergeTable( *pCrsr->GetPoint(), bWithPrev, nMode );
+
+ GetDoc()->EndUndo(UNDO_EMPTY, NULL);
+ ClearFEShellTabCols();
+ EndAllAction();
+ }
+ return bRet;
+}
+
+BOOL SwEditShell::CanMergeTable( BOOL bWithPrev, BOOL* pChkNxtPrv ) const
+{
+ BOOL bRet = FALSE;
+ const SwPaM *pCrsr = GetCrsr();
+ const SwTableNode* pTblNd = pCrsr->GetNode()->FindTableNode();
+ if( pTblNd && !pTblNd->GetTable().ISA( SwDDETable ))
+ {
+ BOOL bNew = pTblNd->GetTable().IsNewModel();
+ const SwNodes& rNds = GetDoc()->GetNodes();
+ if( pChkNxtPrv )
+ {
+ const SwTableNode* pChkNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
+ if( pChkNd && !pChkNd->GetTable().ISA( SwDDETable ) &&
+ bNew == pChkNd->GetTable().IsNewModel() &&
+ // --> FME 2004-09-17 #117418# Consider table in table case
+ pChkNd->EndOfSectionIndex() == pTblNd->GetIndex() - 1 )
+ // <--
+ *pChkNxtPrv = TRUE, bRet = TRUE; // mit Prev ist moeglich
+ else
+ {
+ pChkNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
+ if( pChkNd && !pChkNd->GetTable().ISA( SwDDETable ) &&
+ bNew == pChkNd->GetTable().IsNewModel() )
+ *pChkNxtPrv = FALSE, bRet = TRUE; // mit Next ist moeglich
+ }
+ }
+ else
+ {
+ const SwTableNode* pTmpTblNd = 0;
+
+ if( bWithPrev )
+ {
+ pTmpTblNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
+ // --> FME 2004-09-17 #117418# Consider table in table case
+ if ( pTmpTblNd && pTmpTblNd->EndOfSectionIndex() != pTblNd->GetIndex() - 1 )
+ pTmpTblNd = 0;
+ // <--
+ }
+ else
+ pTmpTblNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
+
+ bRet = pTmpTblNd && !pTmpTblNd->GetTable().ISA( SwDDETable ) &&
+ bNew == pTmpTblNd->GetTable().IsNewModel();
+ }
+ }
+ return bRet;
+}
+
+ // setze das InsertDB als Tabelle Undo auf:
+void SwEditShell::AppendUndoForInsertFromDB( BOOL bIsTable )
+{
+ GetDoc()->AppendUndoForInsertFromDB( *GetCrsr(), bIsTable );
+}
+