Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/chart2/XChartDocument.hpp>
21 : #include <hintids.hxx>
22 : #include <hints.hxx>
23 :
24 :
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/window.hxx>
27 : #include <editeng/boxitem.hxx>
28 : #include <swwait.hxx>
29 : #include <fmtfsize.hxx>
30 : #include <frmatr.hxx>
31 : #include <editsh.hxx>
32 : #include <doc.hxx>
33 : #include <IDocumentUndoRedo.hxx>
34 : #include <cntfrm.hxx>
35 : #include <pam.hxx>
36 : #include <ndtxt.hxx>
37 : #include <fldbas.hxx>
38 : #include <swtable.hxx>
39 : #include <swundo.hxx>
40 : #include <tblsel.hxx>
41 : #include <edimp.hxx>
42 : #include <tabfrm.hxx>
43 : #include <cellfrm.hxx>
44 : #include <cellatr.hxx>
45 : #include <swtblfmt.hxx>
46 : #include <swddetbl.hxx>
47 : #include <mdiexp.hxx>
48 : #include <unochart.hxx>
49 :
50 : using namespace ::com::sun::star;
51 : using namespace ::com::sun::star::uno;
52 :
53 : extern void ClearFEShellTabCols();
54 :
55 0 : const SwTable& SwEditShell::InsertTable( const SwInsertTableOptions& rInsTblOpts,
56 : sal_uInt16 nRows, sal_uInt16 nCols,
57 : sal_Int16 eAdj,
58 : const SwTableAutoFmt* pTAFmt )
59 : {
60 0 : StartAllAction();
61 0 : SwPosition* pPos = GetCrsr()->GetPoint();
62 :
63 0 : bool bEndUndo = 0 != pPos->nContent.GetIndex();
64 0 : if( bEndUndo )
65 : {
66 0 : StartUndo( UNDO_START );
67 0 : GetDoc()->SplitNode( *pPos, false );
68 : }
69 :
70 : /* If called from a shell the adjust item is propagated
71 : from pPos to the new content nodes in the table.
72 : */
73 : const SwTable *pTable = GetDoc()->InsertTable( rInsTblOpts, *pPos,
74 : nRows, nCols,
75 : eAdj, pTAFmt,
76 0 : 0, sal_True );
77 0 : if( bEndUndo )
78 0 : EndUndo( UNDO_END );
79 :
80 0 : EndAllAction();
81 0 : return *pTable;
82 : }
83 :
84 0 : sal_Bool SwEditShell::TextToTable( const SwInsertTableOptions& rInsTblOpts,
85 : sal_Unicode cCh,
86 : sal_Int16 eAdj,
87 : const SwTableAutoFmt* pTAFmt )
88 : {
89 0 : SwWait aWait( *GetDoc()->GetDocShell(), sal_True );
90 0 : sal_Bool bRet = sal_False;
91 0 : StartAllAction();
92 0 : FOREACHPAM_START(this)
93 0 : if( PCURCRSR->HasMark() )
94 : bRet |= 0 != GetDoc()->TextToTable( rInsTblOpts, *PCURCRSR, cCh,
95 0 : eAdj, pTAFmt );
96 0 : FOREACHPAM_END()
97 0 : EndAllAction();
98 0 : return bRet;
99 : }
100 :
101 0 : sal_Bool SwEditShell::TableToText( sal_Unicode cCh )
102 : {
103 0 : SwWait aWait( *GetDoc()->GetDocShell(), sal_True );
104 0 : sal_Bool bRet = sal_False;
105 0 : SwPaM* pCrsr = GetCrsr();
106 : const SwTableNode* pTblNd =
107 0 : GetDoc()->IsIdxInTbl( pCrsr->GetPoint()->nNode );
108 0 : if( IsTableMode() )
109 : {
110 0 : ClearMark();
111 0 : pCrsr = GetCrsr();
112 : }
113 0 : else if( !pTblNd || pCrsr->GetNext() != pCrsr )
114 0 : return bRet;
115 :
116 : // TL_CHART2:
117 : // tell the charts about the table to be deleted and have them use their own data
118 0 : GetDoc()->CreateChartInternalDataProviders( &pTblNd->GetTable() );
119 :
120 0 : StartAllAction();
121 :
122 : // verschiebe den akt. Cursor aus dem Tabellen Bereich
123 : // angemeldet ist
124 0 : SwNodeIndex aTabIdx( *pTblNd );
125 0 : pCrsr->DeleteMark();
126 0 : pCrsr->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
127 0 : pCrsr->GetPoint()->nContent.Assign( 0, 0 );
128 : // SPoint und Mark aus dem Bereich verschieben !!!
129 0 : pCrsr->SetMark();
130 0 : pCrsr->DeleteMark();
131 :
132 0 : bRet = GetDoc()->TableToText( pTblNd, cCh );
133 0 : pCrsr->GetPoint()->nNode = aTabIdx;
134 :
135 0 : SwCntntNode* pCNd = pCrsr->GetCntntNode();
136 0 : if( !pCNd )
137 0 : pCrsr->Move( fnMoveForward, fnGoCntnt );
138 : else
139 0 : pCrsr->GetPoint()->nContent.Assign( pCNd, 0 );
140 :
141 0 : EndAllAction();
142 0 : return bRet;
143 : }
144 :
145 0 : sal_Bool SwEditShell::IsTextToTableAvailable() const
146 : {
147 0 : sal_Bool bOnlyText = sal_False;
148 0 : FOREACHPAM_START(this)
149 0 : if( PCURCRSR->HasMark() && *PCURCRSR->GetPoint() != *PCURCRSR->GetMark() )
150 : {
151 0 : bOnlyText = sal_True;
152 :
153 : // pruefe ob in der Selection eine Tabelle liegt
154 0 : sal_uLong nStt = PCURCRSR->GetMark()->nNode.GetIndex(),
155 0 : nEnd = PCURCRSR->GetPoint()->nNode.GetIndex();
156 0 : if( nStt > nEnd ) { sal_uLong n = nStt; nStt = nEnd; nEnd = n; }
157 :
158 0 : for( ; nStt <= nEnd; ++nStt )
159 0 : if( !GetDoc()->GetNodes()[ nStt ]->IsTxtNode() )
160 : {
161 0 : bOnlyText = sal_False;
162 0 : break;
163 : }
164 :
165 0 : if( !bOnlyText )
166 0 : break;
167 : }
168 0 : FOREACHPAM_END()
169 :
170 0 : return bOnlyText;
171 : }
172 :
173 0 : void SwEditShell::InsertDDETable( const SwInsertTableOptions& rInsTblOpts,
174 : SwDDEFieldType* pDDEType,
175 : sal_uInt16 nRows, sal_uInt16 nCols,
176 : sal_Int16 eAdj )
177 : {
178 0 : SwPosition* pPos = GetCrsr()->GetPoint();
179 :
180 0 : StartAllAction();
181 :
182 0 : bool bEndUndo = 0 != pPos->nContent.GetIndex();
183 0 : if( bEndUndo )
184 : {
185 0 : StartUndo( UNDO_START );
186 0 : GetDoc()->SplitNode( *pPos, false );
187 : }
188 :
189 : const SwInsertTableOptions aInsTblOpts( rInsTblOpts.mnInsMode | tabopts::DEFAULT_BORDER,
190 0 : rInsTblOpts.mnRowsToRepeat );
191 : SwTable* pTbl = (SwTable*)GetDoc()->InsertTable( aInsTblOpts, *pPos,
192 0 : nRows, nCols, eAdj );
193 :
194 0 : SwTableNode* pTblNode = (SwTableNode*)pTbl->GetTabSortBoxes()[ 0 ]->
195 0 : GetSttNd()->FindTableNode();
196 0 : SwDDETable* pDDETbl = new SwDDETable( *pTbl, pDDEType );
197 0 : pTblNode->SetNewTable( pDDETbl ); // setze die DDE-Tabelle
198 :
199 0 : if( bEndUndo )
200 0 : EndUndo( UNDO_END );
201 :
202 0 : EndAllAction();
203 0 : }
204 :
205 : /*--------------------------------------------------------------------
206 : Beschreibung: Tabellenfelder einer Tabelle updaten
207 : --------------------------------------------------------------------*/
208 21 : void SwEditShell::UpdateTable()
209 : {
210 21 : const SwTableNode* pTblNd = IsCrsrInTbl();
211 :
212 : // Keine Arme keine Kekse
213 21 : if( pTblNd )
214 : {
215 21 : StartAllAction();
216 21 : if( DoesUndo() )
217 21 : StartUndo();
218 21 : EndAllTblBoxEdit();
219 21 : SwTableFmlUpdate aTblUpdate( (SwTable*)&pTblNd->GetTable() );
220 21 : GetDoc()->UpdateTblFlds( &aTblUpdate );
221 21 : if( DoesUndo() )
222 21 : EndUndo();
223 21 : EndAllAction();
224 : }
225 21 : }
226 :
227 : // Change Modus erfragen/setzen
228 0 : TblChgMode SwEditShell::GetTblChgMode() const
229 : {
230 : TblChgMode eMode;
231 0 : const SwTableNode* pTblNd = IsCrsrInTbl();
232 0 : if( pTblNd )
233 0 : eMode = pTblNd->GetTable().GetTblChgMode();
234 : else
235 0 : eMode = GetTblChgDefaultMode();
236 0 : return eMode;
237 : }
238 :
239 0 : void SwEditShell::SetTblChgMode( TblChgMode eMode )
240 : {
241 0 : const SwTableNode* pTblNd = IsCrsrInTbl();
242 :
243 : // Keine Arme keine Kekse
244 0 : if( pTblNd )
245 : {
246 0 : ((SwTable&)pTblNd->GetTable()).SetTblChgMode( eMode );
247 0 : if( !GetDoc()->IsModified() ) // Bug 57028
248 : {
249 0 : GetDoc()->GetIDocumentUndoRedo().SetUndoNoResetModified();
250 : }
251 0 : GetDoc()->SetModified();
252 : }
253 0 : }
254 :
255 0 : sal_Bool SwEditShell::GetTblBoxFormulaAttrs( SfxItemSet& rSet ) const
256 : {
257 0 : SwSelBoxes aBoxes;
258 0 : if( IsTableMode() )
259 0 : ::GetTblSelCrs( *this, aBoxes );
260 : else
261 : {
262 : do {
263 0 : SwFrm *pFrm = GetCurrFrm();
264 0 : do {
265 0 : pFrm = pFrm->GetUpper();
266 0 : } while ( pFrm && !pFrm->IsCellFrm() );
267 0 : if ( pFrm )
268 : {
269 0 : SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
270 0 : aBoxes.insert( pBox );
271 : }
272 : } while( false );
273 : }
274 :
275 0 : for (size_t n = 0; n < aBoxes.size(); ++n)
276 : {
277 0 : const SwTableBox* pSelBox = aBoxes[ n ];
278 0 : const SwTableBoxFmt* pTblFmt = (SwTableBoxFmt*)pSelBox->GetFrmFmt();
279 0 : if( !n )
280 : {
281 : // Formeln in die externe Darstellung bringen!
282 0 : const SwTable& rTbl = pSelBox->GetSttNd()->FindTableNode()->GetTable();
283 :
284 0 : SwTableFmlUpdate aTblUpdate( (SwTable*)&rTbl );
285 0 : aTblUpdate.eFlags = TBL_BOXNAME;
286 0 : ((SwDoc*)GetDoc())->UpdateTblFlds( &aTblUpdate );
287 :
288 0 : rSet.Put( pTblFmt->GetAttrSet() );
289 : }
290 : else
291 0 : rSet.MergeValues( pTblFmt->GetAttrSet() );
292 : }
293 0 : return 0 != rSet.Count();
294 : }
295 :
296 0 : void SwEditShell::SetTblBoxFormulaAttrs( const SfxItemSet& rSet )
297 : {
298 0 : SET_CURR_SHELL( this );
299 0 : SwSelBoxes aBoxes;
300 0 : if( IsTableMode() )
301 0 : ::GetTblSelCrs( *this, aBoxes );
302 : else
303 : {
304 : do {
305 0 : SwFrm *pFrm = GetCurrFrm();
306 0 : do {
307 0 : pFrm = pFrm->GetUpper();
308 0 : } while ( pFrm && !pFrm->IsCellFrm() );
309 0 : if ( pFrm )
310 : {
311 0 : SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
312 0 : aBoxes.insert( pBox );
313 : }
314 : } while( false );
315 : }
316 :
317 : // beim setzen einer Formel keine Ueberpruefung mehr vornehmen!
318 0 : if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA ))
319 0 : ClearTblBoxCntnt();
320 :
321 0 : StartAllAction();
322 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
323 0 : for (size_t n = 0; n < aBoxes.size(); ++n)
324 : {
325 0 : GetDoc()->SetTblBoxFormulaAttrs( *aBoxes[ n ], rSet );
326 : }
327 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
328 0 : EndAllAction();
329 0 : }
330 :
331 0 : sal_Bool SwEditShell::IsTableBoxTextFormat() const
332 : {
333 0 : if( IsTableMode() )
334 0 : return sal_False;
335 :
336 0 : SwTableBox *pBox = 0;
337 : {
338 0 : SwFrm *pFrm = GetCurrFrm();
339 0 : do {
340 0 : pFrm = pFrm->GetUpper();
341 0 : } while ( pFrm && !pFrm->IsCellFrm() );
342 0 : if ( pFrm )
343 0 : pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
344 : }
345 :
346 0 : if( !pBox )
347 0 : return sal_False;
348 :
349 : sal_uInt32 nFmt;
350 : const SfxPoolItem* pItem;
351 0 : if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetAttrSet().GetItemState(
352 0 : RES_BOXATR_FORMAT, sal_True, &pItem ))
353 : {
354 0 : nFmt = ((SwTblBoxNumFormat*)pItem)->GetValue();
355 0 : return GetDoc()->GetNumberFormatter()->IsTextFormat( nFmt ) ||
356 0 : NUMBERFORMAT_TEXT == nFmt;
357 : }
358 :
359 0 : sal_uLong nNd = pBox->IsValidNumTxtNd();
360 0 : if( ULONG_MAX == nNd )
361 0 : return sal_True;
362 :
363 0 : const String& rTxt = GetDoc()->GetNodes()[ nNd ]->GetTxtNode()->GetTxt();
364 0 : if( !rTxt.Len() )
365 0 : return sal_False;
366 :
367 : double fVal;
368 0 : return !GetDoc()->GetNumberFormatter()->IsNumberFormat( rTxt, nFmt, fVal );
369 : }
370 :
371 0 : String SwEditShell::GetTableBoxText() const
372 : {
373 0 : String sRet;
374 0 : if( !IsTableMode() )
375 : {
376 0 : SwTableBox *pBox = 0;
377 : {
378 0 : SwFrm *pFrm = GetCurrFrm();
379 0 : do {
380 0 : pFrm = pFrm->GetUpper();
381 0 : } while ( pFrm && !pFrm->IsCellFrm() );
382 0 : if ( pFrm )
383 0 : pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
384 : }
385 :
386 : sal_uLong nNd;
387 0 : if( pBox && ULONG_MAX != ( nNd = pBox->IsValidNumTxtNd() ) )
388 0 : sRet = GetDoc()->GetNodes()[ nNd ]->GetTxtNode()->GetTxt();
389 : }
390 0 : return sRet;
391 : }
392 :
393 0 : sal_Bool SwEditShell::SplitTable( sal_uInt16 eMode )
394 : {
395 0 : sal_Bool bRet = sal_False;
396 0 : SwPaM *pCrsr = GetCrsr();
397 0 : if( pCrsr->GetNode()->FindTableNode() )
398 : {
399 0 : StartAllAction();
400 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
401 :
402 0 : bRet = GetDoc()->SplitTable( *pCrsr->GetPoint(), eMode, sal_True );
403 :
404 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
405 0 : ClearFEShellTabCols();
406 0 : EndAllAction();
407 : }
408 0 : return bRet;
409 : }
410 :
411 0 : sal_Bool SwEditShell::MergeTable( sal_Bool bWithPrev, sal_uInt16 nMode )
412 : {
413 0 : sal_Bool bRet = sal_False;
414 0 : SwPaM *pCrsr = GetCrsr();
415 0 : if( pCrsr->GetNode()->FindTableNode() )
416 : {
417 0 : StartAllAction();
418 0 : GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
419 :
420 0 : bRet = GetDoc()->MergeTable( *pCrsr->GetPoint(), bWithPrev, nMode );
421 :
422 0 : GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
423 0 : ClearFEShellTabCols();
424 0 : EndAllAction();
425 : }
426 0 : return bRet;
427 : }
428 :
429 0 : sal_Bool SwEditShell::CanMergeTable( sal_Bool bWithPrev, sal_Bool* pChkNxtPrv ) const
430 : {
431 0 : sal_Bool bRet = sal_False;
432 0 : const SwPaM *pCrsr = GetCrsr();
433 0 : const SwTableNode* pTblNd = pCrsr->GetNode()->FindTableNode();
434 0 : if( pTblNd && !pTblNd->GetTable().ISA( SwDDETable ))
435 : {
436 0 : sal_Bool bNew = pTblNd->GetTable().IsNewModel();
437 0 : const SwNodes& rNds = GetDoc()->GetNodes();
438 0 : if( pChkNxtPrv )
439 : {
440 0 : const SwTableNode* pChkNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
441 0 : if( pChkNd && !pChkNd->GetTable().ISA( SwDDETable ) &&
442 0 : bNew == pChkNd->GetTable().IsNewModel() &&
443 : // Consider table in table case
444 0 : pChkNd->EndOfSectionIndex() == pTblNd->GetIndex() - 1 )
445 0 : *pChkNxtPrv = sal_True, bRet = sal_True; // mit Prev ist moeglich
446 : else
447 : {
448 0 : pChkNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
449 0 : if( pChkNd && !pChkNd->GetTable().ISA( SwDDETable ) &&
450 0 : bNew == pChkNd->GetTable().IsNewModel() )
451 0 : *pChkNxtPrv = sal_False, bRet = sal_True; // mit Next ist moeglich
452 : }
453 : }
454 : else
455 : {
456 0 : const SwTableNode* pTmpTblNd = 0;
457 :
458 0 : if( bWithPrev )
459 : {
460 0 : pTmpTblNd = rNds[ pTblNd->GetIndex() - 1 ]->FindTableNode();
461 : // Consider table in table case
462 0 : if ( pTmpTblNd && pTmpTblNd->EndOfSectionIndex() != pTblNd->GetIndex() - 1 )
463 0 : pTmpTblNd = 0;
464 : }
465 : else
466 0 : pTmpTblNd = rNds[ pTblNd->EndOfSectionIndex() + 1 ]->GetTableNode();
467 :
468 0 : bRet = pTmpTblNd && !pTmpTblNd->GetTable().ISA( SwDDETable ) &&
469 0 : bNew == pTmpTblNd->GetTable().IsNewModel();
470 : }
471 : }
472 0 : return bRet;
473 : }
474 :
475 : // setze das InsertDB als Tabelle Undo auf:
476 0 : void SwEditShell::AppendUndoForInsertFromDB( sal_Bool bIsTable )
477 : {
478 0 : GetDoc()->AppendUndoForInsertFromDB( *GetCrsr(), bIsTable );
479 0 : }
480 :
481 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|