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 :
21 : #include "tablecontroller.hxx"
22 :
23 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
24 : #include <com/sun/star/container/XIndexAccess.hpp>
25 :
26 : #include <com/sun/star/beans/XPropertySet.hpp>
27 : #include <com/sun/star/table/XMergeableCellRange.hpp>
28 : #include <com/sun/star/table/XMergeableCell.hpp>
29 :
30 : #include <sal/config.h>
31 :
32 : #include <vcl/svapp.hxx>
33 : #include <svl/whiter.hxx>
34 :
35 : #include <sfx2/request.hxx>
36 :
37 : #include <editeng/scripttypeitem.hxx>
38 : #include <svx/svdotable.hxx>
39 : #include <svx/sdr/overlay/overlayobjectcell.hxx>
40 : #include <svx/sdr/overlay/overlaymanager.hxx>
41 : #include <svx/svxids.hrc>
42 : #include <editeng/outlobj.hxx>
43 : #include <svx/svdoutl.hxx>
44 : #include <svx/svdpagv.hxx>
45 : #include <svx/svdetc.hxx>
46 : #include <editeng/editobj.hxx>
47 : #include "editeng/editstat.hxx"
48 : #include "editeng/unolingu.hxx"
49 : #include "svx/sdrpagewindow.hxx"
50 : #include <svx/selectioncontroller.hxx>
51 : #include <svx/svdmodel.hxx>
52 : #include "svx/sdrpaintwindow.hxx"
53 : #include <svx/svxdlg.hxx>
54 : #include <editeng/boxitem.hxx>
55 : #include "cell.hxx"
56 : #include <editeng/borderline.hxx>
57 : #include <editeng/colritem.hxx>
58 : #include "editeng/bolnitem.hxx"
59 : #include "svx/svdstr.hrc"
60 : #include "svx/svdglob.hxx"
61 : #include "svx/svdpage.hxx"
62 : #include "tableundo.hxx"
63 : #include "tablelayouter.hxx"
64 :
65 : using ::editeng::SvxBorderLine;
66 : using ::rtl::OUString;
67 : using namespace ::sdr::table;
68 : using namespace ::com::sun::star;
69 : using namespace ::com::sun::star::uno;
70 : using namespace ::com::sun::star::table;
71 : using namespace ::com::sun::star::beans;
72 : using namespace ::com::sun::star::container;
73 : using namespace ::com::sun::star::text;
74 : using namespace ::com::sun::star::style;
75 :
76 : namespace sdr { namespace table {
77 :
78 : // --------------------------------------------------------------------
79 : // class SvxTableControllerModifyListener
80 : // --------------------------------------------------------------------
81 :
82 0 : class SvxTableControllerModifyListener : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener >
83 : {
84 : public:
85 0 : SvxTableControllerModifyListener( SvxTableController* pController )
86 0 : : mpController( pController ) {}
87 :
88 : // XModifyListener
89 : virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
90 :
91 : // XEventListener
92 : virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
93 :
94 : SvxTableController* mpController;
95 : };
96 :
97 : // --------------------------------------------------------------------
98 : // XModifyListener
99 : // --------------------------------------------------------------------
100 :
101 0 : void SAL_CALL SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
102 : {
103 0 : if( mpController )
104 0 : mpController->onTableModified();
105 0 : }
106 :
107 : // --------------------------------------------------------------------
108 : // XEventListener
109 : // --------------------------------------------------------------------
110 :
111 0 : void SAL_CALL SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
112 : {
113 0 : mpController = 0;
114 0 : }
115 :
116 : // --------------------------------------------------------------------
117 : // class SvxTableController
118 : // --------------------------------------------------------------------
119 :
120 0 : rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
121 : {
122 0 : return SvxTableController::create( pView, pObj, xRefController );
123 : }
124 :
125 : // --------------------------------------------------------------------
126 :
127 0 : rtl::Reference< sdr::SelectionController > SvxTableController::create( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
128 : {
129 0 : if( xRefController.is() )
130 : {
131 0 : SvxTableController* pController = dynamic_cast< SvxTableController* >( xRefController.get() );
132 0 : if( pController && (pController->mxTableObj.get() == pObj) && (pController->mpView == pView) )
133 0 : return xRefController;
134 : }
135 0 : return new SvxTableController( pView, pObj );
136 : }
137 :
138 : // --------------------------------------------------------------------
139 :
140 0 : SvxTableController::SvxTableController( SdrObjEditView* pView, const SdrObject* pObj )
141 : : mbCellSelectionMode(false)
142 : , mbLeftButtonDown(false)
143 : , mpSelectionOverlay(0)
144 : , mpView( dynamic_cast< SdrView* >( pView ) )
145 : , mxTableObj( dynamic_cast< SdrTableObj* >( const_cast< SdrObject* >( pObj ) ) )
146 : , mpModel( 0 )
147 0 : , mnUpdateEvent( 0 )
148 : {
149 0 : if( pObj )
150 0 : mpModel = pObj->GetModel();
151 :
152 0 : if( mxTableObj.is() )
153 : {
154 0 : static_cast< const SdrTableObj* >( pObj )->getActiveCellPos( maCursorFirstPos );
155 0 : maCursorLastPos = maCursorFirstPos;
156 :
157 0 : Reference< XTable > xTable( static_cast< const SdrTableObj* >( pObj )->getTable() );
158 0 : if( xTable.is() )
159 : {
160 0 : mxModifyListener = new SvxTableControllerModifyListener( this );
161 0 : xTable->addModifyListener( mxModifyListener );
162 :
163 0 : mxTable.set( dynamic_cast< TableModel* >( xTable.get() ) );
164 0 : }
165 : }
166 0 : }
167 :
168 : // --------------------------------------------------------------------
169 :
170 0 : SvxTableController::~SvxTableController()
171 : {
172 0 : if( mnUpdateEvent )
173 : {
174 0 : Application::RemoveUserEvent( mnUpdateEvent );
175 : }
176 :
177 0 : if( mxModifyListener.is() && mxTableObj.get() )
178 : {
179 0 : Reference< XTable > xTable( static_cast< SdrTableObj* >( mxTableObj.get() )->getTable() );
180 0 : if( xTable.is() )
181 : {
182 0 : xTable->removeModifyListener( mxModifyListener );
183 0 : mxModifyListener.clear();
184 0 : }
185 : }
186 0 : }
187 :
188 : // --------------------------------------------------------------------
189 :
190 : const sal_uInt16 ACTION_NONE = 0;
191 : const sal_uInt16 ACTION_GOTO_FIRST_CELL = 1;
192 : const sal_uInt16 ACTION_GOTO_FIRST_COLUMN = 2;
193 : const sal_uInt16 ACTION_GOTO_FIRST_ROW = 3;
194 : const sal_uInt16 ACTION_GOTO_LEFT_CELL = 4;
195 : const sal_uInt16 ACTION_GOTO_UP_CELL = 5;
196 : const sal_uInt16 ACTION_GOTO_RIGHT_CELL = 6;
197 : const sal_uInt16 ACTION_GOTO_DOWN_CELL = 7;
198 : const sal_uInt16 ACTION_GOTO_LAST_CELL = 8;
199 : const sal_uInt16 ACTION_GOTO_LAST_COLUMN = 9;
200 : const sal_uInt16 ACTION_GOTO_LAST_ROW = 10;
201 : const sal_uInt16 ACTION_EDIT_CELL = 11;
202 : const sal_uInt16 ACTION_STOP_TEXT_EDIT = 12;
203 : const sal_uInt16 ACTION_REMOVE_SELECTION = 13;
204 : const sal_uInt16 ACTION_START_SELECTION = 14;
205 : const sal_uInt16 ACTION_HANDLED_BY_VIEW = 15;
206 : const sal_uInt16 ACTION_TAB = 18;
207 :
208 0 : bool SvxTableController::onKeyInput(const KeyEvent& rKEvt, Window* pWindow )
209 : {
210 0 : if( !checkTableObject() )
211 0 : return false;
212 :
213 : // check if we are read only
214 0 : if( mpModel && mpModel->IsReadOnly())
215 : {
216 0 : switch( rKEvt.GetKeyCode().GetCode() )
217 : {
218 : case awt::Key::DOWN:
219 : case awt::Key::UP:
220 : case awt::Key::LEFT:
221 : case awt::Key::RIGHT:
222 : case awt::Key::TAB:
223 : case awt::Key::HOME:
224 : case awt::Key::END:
225 : case awt::Key::NUM2:
226 : case awt::Key::NUM4:
227 : case awt::Key::NUM6:
228 : case awt::Key::NUM8:
229 : case awt::Key::ESCAPE:
230 : case awt::Key::F2:
231 0 : break;
232 : default:
233 : // tell the view we eat the event, no further processing needed
234 0 : return true;
235 : }
236 : }
237 :
238 0 : sal_uInt16 nAction = getKeyboardAction( rKEvt, pWindow );
239 :
240 0 : return executeAction( nAction, ( rKEvt.GetKeyCode().IsShift() ) ? sal_True : sal_False, pWindow );
241 : }
242 :
243 : // --------------------------------------------------------------------
244 : // ::com::sun::star::awt::XMouseClickHandler:
245 : // --------------------------------------------------------------------
246 :
247 0 : bool SvxTableController::onMouseButtonDown(const MouseEvent& rMEvt, Window* pWindow )
248 : {
249 0 : if( !pWindow || !checkTableObject() )
250 0 : return false;
251 :
252 0 : SdrViewEvent aVEvt;
253 0 : if( !rMEvt.IsRight() && mpView->PickAnything(rMEvt,SDRMOUSEBUTTONDOWN, aVEvt) == SDRHIT_HANDLE )
254 0 : return false;
255 :
256 0 : TableHitKind eHit = static_cast< SdrTableObj* >(mxTableObj.get())->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), maMouseDownPos.mnCol, maMouseDownPos.mnRow, 0 );
257 :
258 0 : mbLeftButtonDown = (rMEvt.GetClicks() == 1) && rMEvt.IsLeft();
259 :
260 0 : if( eHit == SDRTABLEHIT_CELL )
261 : {
262 0 : StartSelection( maMouseDownPos );
263 0 : return true;
264 : }
265 :
266 0 : if( rMEvt.IsRight() && eHit != SDRTABLEHIT_NONE )
267 0 : return true; // right click will become context menu
268 :
269 : // for cell selektion with the mouse remember our first hit
270 0 : if( mbLeftButtonDown )
271 : {
272 0 : RemoveSelection();
273 :
274 0 : Point aPnt(rMEvt.GetPosPixel());
275 0 : if (pWindow!=NULL)
276 0 : aPnt=pWindow->PixelToLogic(aPnt);
277 :
278 0 : SdrHdl* pHdl = mpView->PickHandle(aPnt);
279 :
280 0 : if( pHdl )
281 : {
282 0 : mbLeftButtonDown = false;
283 : }
284 : else
285 : {
286 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
287 :
288 0 : if( !pWindow || !pTableObj || eHit == SDRTABLEHIT_NONE)
289 : {
290 0 : mbLeftButtonDown = false;
291 : }
292 : }
293 : }
294 :
295 0 : return false;
296 : }
297 :
298 : // --------------------------------------------------------------------
299 :
300 0 : bool SvxTableController::onMouseButtonUp(const MouseEvent& rMEvt, Window* /*pWin*/)
301 : {
302 0 : if( !checkTableObject() )
303 0 : return false;
304 :
305 0 : mbLeftButtonDown = false;
306 :
307 0 : if( rMEvt.GetClicks() == 2 )
308 0 : return true;
309 :
310 0 : return false;
311 : }
312 :
313 : // --------------------------------------------------------------------
314 :
315 0 : bool SvxTableController::onMouseMove(const MouseEvent& rMEvt, Window* pWindow )
316 : {
317 0 : if( !checkTableObject() )
318 0 : return false;
319 :
320 0 : if( rMEvt.IsLeft() )
321 : {
322 0 : int i = 0;
323 0 : i++;
324 : }
325 :
326 0 : SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
327 0 : CellPos aPos;
328 0 : if( mbLeftButtonDown && pTableObj && pTableObj->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), aPos.mnCol, aPos.mnRow, 0 ) != SDRTABLEHIT_NONE )
329 : {
330 0 : if(aPos != maMouseDownPos)
331 : {
332 0 : if( mbCellSelectionMode )
333 : {
334 0 : setSelectedCells( maMouseDownPos, aPos );
335 0 : return true;
336 : }
337 : else
338 : {
339 0 : StartSelection( maMouseDownPos );
340 : }
341 : }
342 0 : else if( mbCellSelectionMode )
343 : {
344 0 : UpdateSelection( aPos );
345 0 : return true;
346 : }
347 : }
348 0 : return false;
349 : }
350 :
351 : // --------------------------------------------------------------------
352 :
353 0 : void SvxTableController::onSelectionHasChanged()
354 : {
355 0 : bool bSelected = false;
356 :
357 0 : SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
358 0 : if( pTableObj && pTableObj->IsTextEditActive() )
359 : {
360 0 : pTableObj->getActiveCellPos( maCursorFirstPos );
361 0 : maCursorLastPos = maCursorFirstPos;
362 0 : mbCellSelectionMode = false;
363 : }
364 : else
365 : {
366 0 : const SdrMarkList& rMarkList= mpView->GetMarkedObjectList();
367 0 : if( rMarkList.GetMarkCount() == 1 )
368 0 : bSelected = mxTableObj.get() == rMarkList.GetMark(0)->GetMarkedSdrObj();
369 : }
370 :
371 0 : if( bSelected )
372 : {
373 0 : updateSelectionOverlay();
374 : }
375 : else
376 : {
377 0 : destroySelectionOverlay();
378 : }
379 0 : }
380 :
381 : // --------------------------------------------------------------------
382 :
383 0 : void SvxTableController::GetState( SfxItemSet& rSet )
384 : {
385 0 : if( !mxTable.is() || !mxTableObj.is() || !mxTableObj->GetModel() )
386 0 : return;
387 :
388 0 : SfxItemSet* pSet = 0;
389 :
390 0 : bool bVertDone = false;
391 :
392 : // Iterate over all requested items in the set.
393 0 : SfxWhichIter aIter( rSet );
394 0 : sal_uInt16 nWhich = aIter.FirstWhich();
395 0 : while (nWhich)
396 : {
397 0 : switch (nWhich)
398 : {
399 : case SID_TABLE_VERT_BOTTOM:
400 : case SID_TABLE_VERT_CENTER:
401 : case SID_TABLE_VERT_NONE:
402 : {
403 0 : if( !mxTable.is() || !mxTableObj->GetModel() )
404 : {
405 0 : rSet.DisableItem(nWhich);
406 : }
407 0 : else if(!bVertDone)
408 : {
409 0 : if( !pSet )
410 : {
411 0 : pSet = new SfxItemSet( mxTableObj->GetModel()->GetItemPool() );
412 0 : MergeAttrFromSelectedCells(*pSet, sal_False);
413 : }
414 :
415 0 : SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_BLOCK;
416 :
417 0 : if( pSet->GetItemState( SDRATTR_TEXT_VERTADJUST ) != SFX_ITEM_DONTCARE )
418 0 : eAdj = ((SdrTextVertAdjustItem&)(pSet->Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
419 :
420 0 : rSet.Put(SfxBoolItem(SID_TABLE_VERT_BOTTOM, eAdj == SDRTEXTVERTADJUST_BOTTOM));
421 0 : rSet.Put(SfxBoolItem(SID_TABLE_VERT_CENTER, eAdj == SDRTEXTVERTADJUST_CENTER));
422 0 : rSet.Put(SfxBoolItem(SID_TABLE_VERT_NONE, eAdj == SDRTEXTVERTADJUST_TOP));
423 0 : bVertDone = true;
424 : }
425 0 : break;
426 : }
427 : case SID_TABLE_DELETE_ROW:
428 0 : if( !mxTable.is() || !hasSelectedCells() || (mxTable->getRowCount() <= 1) )
429 0 : rSet.DisableItem(SID_TABLE_DELETE_ROW);
430 0 : break;
431 : case SID_TABLE_DELETE_COL:
432 0 : if( !mxTable.is() || !hasSelectedCells() || (mxTable->getColumnCount() <= 1) )
433 0 : rSet.DisableItem(SID_TABLE_DELETE_COL);
434 0 : break;
435 : case SID_TABLE_MERGE_CELLS:
436 0 : if( !mxTable.is() || !hasSelectedCells() )
437 0 : rSet.DisableItem(SID_TABLE_MERGE_CELLS);
438 0 : break;
439 : case SID_TABLE_SPLIT_CELLS:
440 0 : if( !hasSelectedCells() || !mxTable.is() )
441 0 : rSet.DisableItem(SID_TABLE_SPLIT_CELLS);
442 0 : break;
443 :
444 : case SID_OPTIMIZE_TABLE:
445 : case SID_TABLE_DISTRIBUTE_COLUMNS:
446 : case SID_TABLE_DISTRIBUTE_ROWS:
447 : {
448 0 : bool bDistributeColumns = false;
449 0 : bool bDistributeRows = false;
450 0 : if( mxTable.is() )
451 : {
452 0 : CellPos aStart, aEnd;
453 0 : getSelectedCells( aStart, aEnd );
454 :
455 0 : bDistributeColumns = aStart.mnCol != aEnd.mnCol;
456 0 : bDistributeRows = aStart.mnRow != aEnd.mnRow;
457 : }
458 0 : if( !bDistributeColumns && !bDistributeRows )
459 0 : rSet.DisableItem(SID_OPTIMIZE_TABLE);
460 0 : if( !bDistributeColumns )
461 0 : rSet.DisableItem(SID_TABLE_DISTRIBUTE_COLUMNS);
462 0 : if( !bDistributeRows )
463 0 : rSet.DisableItem(SID_TABLE_DISTRIBUTE_ROWS);
464 0 : break;
465 : }
466 :
467 : case SID_AUTOFORMAT:
468 : case SID_TABLE_SORT_DIALOG:
469 : case SID_TABLE_AUTOSUM:
470 : // if( !mxTable.is() )
471 : // rSet.DisableItem( nWhich );
472 0 : break;
473 : default:
474 0 : break;
475 : }
476 0 : nWhich = aIter.NextWhich();
477 : }
478 0 : if( pSet )
479 0 : delete pSet;
480 : }
481 :
482 : // --------------------------------------------------------------------
483 :
484 0 : void SvxTableController::onInsert( sal_uInt16 nSId, const SfxItemSet* pArgs )
485 : {
486 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
487 0 : if( !pTableObj )
488 0 : return;
489 :
490 0 : if( mxTable.is() ) try
491 : {
492 : //
493 0 : bool bInsertAfter = true;
494 0 : sal_uInt16 nCount = 0;
495 0 : if( pArgs )
496 : {
497 0 : const SfxPoolItem* pItem = 0;
498 0 : pArgs->GetItemState(nSId, sal_False, &pItem);
499 0 : if (pItem)
500 : {
501 0 : nCount = ((const SfxInt16Item* )pItem)->GetValue();
502 0 : if(SFX_ITEM_SET == pArgs->GetItemState(SID_TABLE_PARAM_INSERT_AFTER, sal_True, &pItem))
503 0 : bInsertAfter = ((const SfxBoolItem* )pItem)->GetValue();
504 : }
505 : }
506 :
507 0 : CellPos aStart, aEnd;
508 0 : if( hasSelectedCells() )
509 : {
510 0 : getSelectedCells( aStart, aEnd );
511 : }
512 : else
513 : {
514 0 : if( bInsertAfter )
515 : {
516 0 : aStart.mnCol = mxTable->getColumnCount() - 1;
517 0 : aStart.mnRow = mxTable->getRowCount() - 1;
518 0 : aEnd = aStart;
519 : }
520 : }
521 :
522 0 : if( pTableObj->IsTextEditActive() )
523 0 : mpView->SdrEndTextEdit(sal_True);
524 :
525 0 : RemoveSelection();
526 :
527 0 : const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
528 :
529 0 : const bool bUndo = mpModel && mpModel->IsUndoEnabled();
530 :
531 0 : switch( nSId )
532 : {
533 : case SID_TABLE_INSERT_COL:
534 : {
535 0 : TableModelNotifyGuard aGuard( mxTable.get() );
536 :
537 0 : if( bUndo )
538 : {
539 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSCOL) );
540 0 : mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
541 : }
542 :
543 0 : Reference< XTableColumns > xCols( mxTable->getColumns() );
544 0 : const sal_Int32 nNewColumns = (nCount == 0) ? (aEnd.mnCol - aStart.mnCol + 1) : nCount;
545 0 : const sal_Int32 nNewStartColumn = aEnd.mnCol + (bInsertAfter ? 1 : 0);
546 0 : xCols->insertByIndex( nNewStartColumn, nNewColumns );
547 :
548 0 : for( sal_Int32 nOffset = 0; nOffset < nNewColumns; nOffset++ )
549 : {
550 0 : Reference< XPropertySet >( xCols->getByIndex( aEnd.mnCol + nOffset + 1 ), UNO_QUERY_THROW )->
551 : setPropertyValue( sSize,
552 0 : Reference< XPropertySet >( xCols->getByIndex( aStart.mnCol + nOffset ), UNO_QUERY_THROW )->
553 0 : getPropertyValue( sSize ) );
554 : }
555 :
556 0 : if( bUndo )
557 0 : mpModel->EndUndo();
558 :
559 0 : aStart.mnCol = nNewStartColumn;
560 0 : aStart.mnRow = 0;
561 0 : aEnd.mnCol = aStart.mnCol + nNewColumns - 1;
562 0 : aEnd.mnRow = mxTable->getRowCount() - 1;
563 0 : break;
564 : }
565 :
566 : case SID_TABLE_INSERT_ROW:
567 : {
568 0 : TableModelNotifyGuard aGuard( mxTable.get() );
569 :
570 0 : if( bUndo )
571 : {
572 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSROW ) );
573 0 : mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
574 : }
575 :
576 0 : Reference< XTableRows > xRows( mxTable->getRows() );
577 0 : const sal_Int32 nNewRows = (nCount == 0) ? (aEnd.mnRow - aStart.mnRow + 1) : nCount;
578 0 : const sal_Int32 nNewRowStart = aEnd.mnRow + (bInsertAfter ? 1 : 0);
579 0 : xRows->insertByIndex( nNewRowStart, nNewRows );
580 :
581 0 : for( sal_Int32 nOffset = 0; nOffset < nNewRows; nOffset++ )
582 : {
583 0 : Reference< XPropertySet >( xRows->getByIndex( aEnd.mnRow + nOffset + 1 ), UNO_QUERY_THROW )->
584 : setPropertyValue( sSize,
585 0 : Reference< XPropertySet >( xRows->getByIndex( aStart.mnRow + nOffset ), UNO_QUERY_THROW )->
586 0 : getPropertyValue( sSize ) );
587 : }
588 :
589 0 : if( bUndo )
590 0 : mpModel->EndUndo();
591 :
592 0 : aStart.mnCol = 0;
593 0 : aStart.mnRow = nNewRowStart;
594 0 : aEnd.mnCol = mxTable->getColumnCount() - 1;
595 0 : aEnd.mnRow = aStart.mnRow + nNewRows - 1;
596 0 : break;
597 : }
598 : }
599 :
600 0 : StartSelection( aStart );
601 0 : UpdateSelection( aEnd );
602 : }
603 0 : catch( Exception& )
604 : {
605 : OSL_FAIL("svx::SvxTableController::onInsert(), exception caught!");
606 : }
607 : }
608 :
609 : // --------------------------------------------------------------------
610 :
611 0 : void SvxTableController::onDelete( sal_uInt16 nSId )
612 : {
613 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
614 0 : if( !pTableObj )
615 0 : return;
616 :
617 0 : if( mxTable.is() && hasSelectedCells() )
618 : {
619 0 : CellPos aStart, aEnd;
620 0 : getSelectedCells( aStart, aEnd );
621 :
622 0 : if( pTableObj->IsTextEditActive() )
623 0 : mpView->SdrEndTextEdit(sal_True);
624 :
625 0 : RemoveSelection();
626 :
627 0 : bool bDeleteTable = false;
628 0 : switch( nSId )
629 : {
630 : case SID_TABLE_DELETE_COL:
631 : {
632 0 : const sal_Int32 nRemovedColumns = aEnd.mnCol - aStart.mnCol + 1;
633 0 : if( nRemovedColumns == mxTable->getColumnCount() )
634 : {
635 0 : bDeleteTable = true;
636 : }
637 : else
638 : {
639 0 : Reference< XTableColumns > xCols( mxTable->getColumns() );
640 0 : xCols->removeByIndex( aStart.mnCol, nRemovedColumns );
641 : }
642 0 : break;
643 : }
644 :
645 : case SID_TABLE_DELETE_ROW:
646 : {
647 0 : const sal_Int32 nRemovedRows = aEnd.mnRow - aStart.mnRow + 1;
648 0 : if( nRemovedRows == mxTable->getRowCount() )
649 : {
650 0 : bDeleteTable = true;
651 : }
652 : else
653 : {
654 0 : Reference< XTableRows > xRows( mxTable->getRows() );
655 0 : xRows->removeByIndex( aStart.mnRow, nRemovedRows );
656 : }
657 0 : break;
658 : }
659 : }
660 :
661 0 : if( bDeleteTable )
662 0 : mpView->DeleteMarkedObj();
663 : else
664 0 : UpdateTableShape();
665 : }
666 : }
667 :
668 : // --------------------------------------------------------------------
669 :
670 0 : void SvxTableController::onSelect( sal_uInt16 nSId )
671 : {
672 0 : if( mxTable.is() )
673 : {
674 0 : const sal_Int32 nRowCount = mxTable->getRowCount();
675 0 : const sal_Int32 nColCount = mxTable->getColumnCount();
676 0 : if( nRowCount && nColCount )
677 : {
678 0 : CellPos aStart, aEnd;
679 0 : getSelectedCells( aStart, aEnd );
680 :
681 0 : switch( nSId )
682 : {
683 : case SID_TABLE_SELECT_ALL:
684 0 : aEnd.mnCol = 0; aEnd.mnRow = 0;
685 0 : aStart.mnCol = nColCount - 1; aStart.mnRow = nRowCount - 1;
686 0 : break;
687 : case SID_TABLE_SELECT_COL:
688 0 : aEnd.mnRow = nRowCount - 1;
689 0 : aStart.mnRow = 0;
690 0 : break;
691 : case SID_TABLE_SELECT_ROW:
692 0 : aEnd.mnCol = nColCount - 1;
693 0 : aStart.mnCol = 0;
694 0 : break;
695 : }
696 :
697 0 : StartSelection( aEnd );
698 0 : gotoCell( aStart, true, 0 );
699 : }
700 : }
701 0 : }
702 :
703 : // --------------------------------------------------------------------
704 0 : void SvxTableController::onFormatTable( SfxRequest& rReq )
705 : {
706 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
707 0 : if( !pTableObj )
708 0 : return;
709 :
710 0 : const SfxItemSet* pArgs = rReq.GetArgs();
711 :
712 0 : if( !pArgs && pTableObj->GetModel() )
713 : {
714 0 : SfxItemSet aNewAttr( pTableObj->GetModel()->GetItemPool() );
715 0 : MergeAttrFromSelectedCells(aNewAttr, sal_False);
716 :
717 : // merge drawing layer text distance items into SvxBoxItem used by the dialog
718 0 : SvxBoxItem aBoxItem( static_cast< const SvxBoxItem& >( aNewAttr.Get( SDRATTR_TABLE_BORDER ) ) );
719 0 : aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLeftDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LEFTDIST))).GetValue()), BOX_LINE_LEFT );
720 0 : aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextRightDistItem&)(aNewAttr.Get(SDRATTR_TEXT_RIGHTDIST))).GetValue()), BOX_LINE_RIGHT );
721 0 : aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextUpperDistItem&)(aNewAttr.Get(SDRATTR_TEXT_UPPERDIST))).GetValue()), BOX_LINE_TOP );
722 0 : aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLowerDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LOWERDIST))).GetValue()), BOX_LINE_BOTTOM );
723 0 : aNewAttr.Put( aBoxItem );
724 :
725 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
726 0 : std::auto_ptr< SfxAbstractTabDialog > pDlg( pFact ? pFact->CreateSvxFormatCellsDialog( NULL, &aNewAttr, pTableObj->GetModel(), pTableObj) : 0 );
727 0 : if( pDlg.get() && pDlg->Execute() )
728 : {
729 0 : SfxItemSet aNewSet( *(pDlg->GetOutputItemSet ()) );
730 :
731 0 : SvxBoxItem aNewBoxItem( static_cast< const SvxBoxItem& >( aNewSet.Get( SDRATTR_TABLE_BORDER ) ) );
732 :
733 0 : if( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) != aBoxItem.GetDistance( BOX_LINE_LEFT ) )
734 0 : aNewSet.Put(SdrTextLeftDistItem( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) ) );
735 :
736 0 : if( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) != aBoxItem.GetDistance( BOX_LINE_RIGHT ) )
737 0 : aNewSet.Put(SdrTextRightDistItem( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) ) );
738 :
739 0 : if( aNewBoxItem.GetDistance( BOX_LINE_TOP ) != aBoxItem.GetDistance( BOX_LINE_TOP ) )
740 0 : aNewSet.Put(SdrTextUpperDistItem( aNewBoxItem.GetDistance( BOX_LINE_TOP ) ) );
741 :
742 0 : if( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) != aBoxItem.GetDistance( BOX_LINE_BOTTOM ) )
743 0 : aNewSet.Put(SdrTextLowerDistItem( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) ) );
744 :
745 0 : SetAttrToSelectedCells(aNewSet, sal_False);
746 : }
747 0 : UpdateTableShape();
748 : }
749 : }
750 :
751 : // --------------------------------------------------------------------
752 :
753 0 : void SvxTableController::Execute( SfxRequest& rReq )
754 : {
755 0 : const sal_uInt16 nSId = rReq.GetSlot();
756 0 : switch( nSId )
757 : {
758 : case SID_TABLE_INSERT_ROW:
759 : case SID_TABLE_INSERT_COL:
760 0 : onInsert( nSId, rReq.GetArgs() );
761 0 : break;
762 : case SID_TABLE_DELETE_ROW:
763 : case SID_TABLE_DELETE_COL:
764 0 : onDelete( nSId );
765 0 : break;
766 : case SID_TABLE_SELECT_ALL:
767 : case SID_TABLE_SELECT_COL:
768 : case SID_TABLE_SELECT_ROW:
769 0 : onSelect( nSId );
770 0 : break;
771 : case SID_FORMAT_TABLE_DLG:
772 0 : onFormatTable( rReq );
773 0 : break;
774 :
775 : case SID_FRAME_LINESTYLE:
776 : case SID_FRAME_LINECOLOR:
777 : case SID_ATTR_BORDER:
778 : {
779 0 : const SfxItemSet* pArgs = rReq.GetArgs();
780 0 : if( pArgs )
781 0 : ApplyBorderAttr( *pArgs );
782 : }
783 0 : break;
784 :
785 : case SID_ATTR_FILL_STYLE:
786 : {
787 0 : const SfxItemSet* pArgs = rReq.GetArgs();
788 0 : if( pArgs )
789 0 : SetAttributes( *pArgs, false );
790 : }
791 0 : break;
792 :
793 : case SID_TABLE_MERGE_CELLS:
794 0 : MergeMarkedCells();
795 0 : break;
796 :
797 : case SID_TABLE_SPLIT_CELLS:
798 0 : SplitMarkedCells();
799 0 : break;
800 :
801 : case SID_TABLE_DISTRIBUTE_COLUMNS:
802 0 : DistributeColumns();
803 0 : break;
804 :
805 : case SID_TABLE_DISTRIBUTE_ROWS:
806 0 : DistributeRows();
807 0 : break;
808 :
809 : case SID_TABLE_VERT_BOTTOM:
810 : case SID_TABLE_VERT_CENTER:
811 : case SID_TABLE_VERT_NONE:
812 0 : SetVertical( nSId );
813 0 : break;
814 :
815 : case SID_AUTOFORMAT:
816 : case SID_TABLE_SORT_DIALOG:
817 : case SID_TABLE_AUTOSUM:
818 : default:
819 0 : break;
820 :
821 : case SID_TABLE_STYLE:
822 0 : SetTableStyle( rReq.GetArgs() );
823 0 : break;
824 :
825 : case SID_TABLE_STYLE_SETTINGS:
826 0 : SetTableStyleSettings( rReq.GetArgs() );
827 0 : break;
828 : }
829 0 : }
830 :
831 0 : void SvxTableController::SetTableStyle( const SfxItemSet* pArgs )
832 : {
833 0 : SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
834 0 : SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;
835 :
836 0 : if( !pTableObj || !pModel || !pArgs || (SFX_ITEM_SET != pArgs->GetItemState(SID_TABLE_STYLE, sal_False)) )
837 0 : return;
838 :
839 0 : const SfxStringItem* pArg = dynamic_cast< const SfxStringItem* >( &pArgs->Get( SID_TABLE_STYLE ) );
840 0 : if( pArg && mxTable.is() ) try
841 : {
842 0 : Reference< XStyleFamiliesSupplier > xSFS( pModel->getUnoModel(), UNO_QUERY_THROW );
843 0 : Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
844 0 : const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
845 0 : Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );
846 :
847 0 : if( xTableFamilyAccess->hasByName( pArg->GetValue() ) )
848 : {
849 : // found table style with the same name
850 0 : Reference< XIndexAccess > xNewTableStyle( xTableFamilyAccess->getByName( pArg->GetValue() ), UNO_QUERY_THROW );
851 :
852 0 : const bool bUndo = pModel->IsUndoEnabled();
853 :
854 0 : if( bUndo )
855 : {
856 0 : pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE) );
857 0 : pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
858 : }
859 :
860 0 : pTableObj->setTableStyle( xNewTableStyle );
861 :
862 0 : const sal_Int32 nRowCount = mxTable->getRowCount();
863 0 : const sal_Int32 nColCount = mxTable->getColumnCount();
864 0 : for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
865 : {
866 0 : for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ ) try
867 : {
868 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
869 0 : if( xCell.is() )
870 : {
871 0 : SfxItemSet aSet( xCell->GetItemSet() );
872 0 : bool bChanges = false;
873 0 : const SfxItemSet& rStyleAttribs = xCell->GetStyleSheet()->GetItemSet();
874 :
875 0 : for ( sal_uInt16 nWhich = SDRATTR_START; nWhich <= SDRATTR_TABLE_LAST; nWhich++ )
876 : {
877 0 : if( (rStyleAttribs.GetItemState( nWhich ) == SFX_ITEM_ON) && (aSet.GetItemState( nWhich ) == SFX_ITEM_ON) )
878 : {
879 0 : aSet.ClearItem( nWhich );
880 0 : bChanges = true;
881 : }
882 : }
883 :
884 0 : if( bChanges )
885 : {
886 0 : if( bUndo )
887 0 : xCell->AddUndo();
888 :
889 0 : xCell->SetMergedItemSetAndBroadcast( aSet, sal_True );
890 0 : }
891 0 : }
892 : }
893 0 : catch( Exception& )
894 : {
895 : OSL_FAIL( "svx::SvxTableController::SetTableStyle(), exception caught!" );
896 : }
897 : }
898 :
899 0 : if( bUndo )
900 0 : pModel->EndUndo();
901 0 : }
902 : }
903 0 : catch( Exception& )
904 : {
905 : OSL_FAIL( "svx::SvxTableController::SetTableStyle(), exception caught!" );
906 : }
907 : }
908 :
909 0 : void SvxTableController::SetTableStyleSettings( const SfxItemSet* pArgs )
910 : {
911 0 : SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
912 0 : SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;
913 :
914 0 : if( !pTableObj || !pModel )
915 : return;
916 :
917 0 : TableStyleSettings aSettings( pTableObj->getTableStyleSettings() );
918 :
919 0 : const SfxPoolItem *pPoolItem=NULL;
920 :
921 0 : if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTROWSTYLE, sal_False,&pPoolItem)) )
922 0 : aSettings.mbUseFirstRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
923 :
924 0 : if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTROWSTYLE, sal_False,&pPoolItem)) )
925 0 : aSettings.mbUseLastRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
926 :
927 0 : if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGROWSTYLE, sal_False,&pPoolItem)) )
928 0 : aSettings.mbUseRowBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
929 :
930 0 : if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE, sal_False,&pPoolItem)) )
931 0 : aSettings.mbUseFirstColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
932 :
933 0 : if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTCOLUMNSTYLE, sal_False,&pPoolItem)) )
934 0 : aSettings.mbUseLastColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
935 :
936 0 : if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE, sal_False,&pPoolItem)) )
937 0 : aSettings.mbUseColumnBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();
938 :
939 0 : if( aSettings == pTableObj->getTableStyleSettings() )
940 : return;
941 :
942 0 : const bool bUndo = pModel->IsUndoEnabled();
943 :
944 0 : if( bUndo )
945 : {
946 0 : pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS) );
947 0 : pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
948 : }
949 :
950 0 : pTableObj->setTableStyleSettings( aSettings );
951 :
952 0 : if( bUndo )
953 0 : pModel->EndUndo();
954 : }
955 :
956 0 : void SvxTableController::SetVertical( sal_uInt16 nSId )
957 : {
958 0 : SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
959 0 : if( mxTable.is() && pTableObj )
960 : {
961 0 : TableModelNotifyGuard aGuard( mxTable.get() );
962 :
963 0 : CellPos aStart, aEnd;
964 0 : getSelectedCells( aStart, aEnd );
965 :
966 0 : SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_TOP;
967 :
968 0 : switch( nSId )
969 : {
970 : case SID_TABLE_VERT_BOTTOM:
971 0 : eAdj = SDRTEXTVERTADJUST_BOTTOM;
972 0 : break;
973 : case SID_TABLE_VERT_CENTER:
974 0 : eAdj = SDRTEXTVERTADJUST_CENTER;
975 0 : break;
976 : //case SID_TABLE_VERT_NONE:
977 : default:
978 0 : break;
979 : }
980 :
981 0 : SdrTextVertAdjustItem aItem( eAdj );
982 :
983 0 : for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
984 : {
985 0 : for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
986 : {
987 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
988 0 : if( xCell.is() )
989 0 : xCell->SetMergedItem(aItem);
990 0 : }
991 : }
992 :
993 0 : UpdateTableShape();
994 : }
995 0 : }
996 :
997 0 : void SvxTableController::MergeMarkedCells()
998 : {
999 0 : CellPos aStart, aEnd;
1000 0 : getSelectedCells( aStart, aEnd );
1001 0 : SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1002 0 : if( pTableObj )
1003 : {
1004 0 : if( pTableObj->IsTextEditActive() )
1005 0 : mpView->SdrEndTextEdit(sal_True);
1006 :
1007 0 : TableModelNotifyGuard aGuard( mxTable.get() );
1008 0 : MergeRange( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow );
1009 : }
1010 0 : }
1011 :
1012 0 : void SvxTableController::SplitMarkedCells()
1013 : {
1014 0 : if( mxTable.is() )
1015 : {
1016 0 : CellPos aStart, aEnd;
1017 0 : getSelectedCells( aStart, aEnd );
1018 :
1019 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1020 0 : std::auto_ptr< SvxAbstractSplittTableDialog > xDlg( pFact ? pFact->CreateSvxSplittTableDialog( NULL, false, 99, 99 ) : 0 );
1021 0 : if( xDlg.get() && xDlg->Execute() )
1022 : {
1023 0 : const sal_Int32 nCount = xDlg->GetCount() - 1;
1024 0 : if( nCount < 1 )
1025 0 : return;
1026 :
1027 0 : getSelectedCells( aStart, aEnd );
1028 :
1029 0 : Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) ), UNO_QUERY_THROW );
1030 :
1031 0 : const sal_Int32 nRowCount = mxTable->getRowCount();
1032 0 : const sal_Int32 nColCount = mxTable->getColumnCount();
1033 :
1034 :
1035 0 : SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
1036 0 : if( pTableObj )
1037 : {
1038 0 : if( pTableObj->IsTextEditActive() )
1039 0 : mpView->SdrEndTextEdit(sal_True);
1040 :
1041 0 : TableModelNotifyGuard aGuard( mxTable.get() );
1042 :
1043 0 : const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1044 0 : if( bUndo )
1045 : {
1046 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_SPLIT) );
1047 0 : mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
1048 : }
1049 :
1050 0 : if( xDlg->IsHorizontal() )
1051 : {
1052 0 : xRange->split( 0, nCount );
1053 : }
1054 : else
1055 : {
1056 0 : xRange->split( nCount, 0 );
1057 : }
1058 :
1059 0 : if( bUndo )
1060 0 : mpModel->EndUndo();
1061 : }
1062 0 : aEnd.mnRow += mxTable->getRowCount() - nRowCount;
1063 0 : aEnd.mnCol += mxTable->getColumnCount() - nColCount;
1064 :
1065 0 : setSelectedCells( aStart, aEnd );
1066 0 : }
1067 : }
1068 : }
1069 :
1070 0 : void SvxTableController::DistributeColumns()
1071 : {
1072 0 : SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
1073 0 : if( pTableObj )
1074 : {
1075 0 : const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1076 0 : if( bUndo )
1077 : {
1078 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS) );
1079 0 : mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
1080 : }
1081 :
1082 0 : CellPos aStart, aEnd;
1083 0 : getSelectedCells( aStart, aEnd );
1084 0 : pTableObj->DistributeColumns( aStart.mnCol, aEnd.mnCol );
1085 :
1086 0 : if( bUndo )
1087 0 : mpModel->EndUndo();
1088 : }
1089 0 : }
1090 :
1091 0 : void SvxTableController::DistributeRows()
1092 : {
1093 0 : SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
1094 0 : if( pTableObj )
1095 : {
1096 0 : const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1097 0 : if( bUndo )
1098 : {
1099 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS) );
1100 0 : mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
1101 : }
1102 :
1103 0 : CellPos aStart, aEnd;
1104 0 : getSelectedCells( aStart, aEnd );
1105 0 : pTableObj->DistributeRows( aStart.mnRow, aEnd.mnRow );
1106 :
1107 0 : if( bUndo )
1108 0 : mpModel->EndUndo();
1109 : }
1110 0 : }
1111 :
1112 0 : bool SvxTableController::DeleteMarked()
1113 : {
1114 0 : if( mbCellSelectionMode )
1115 : {
1116 0 : if( mxTable.is() )
1117 : {
1118 0 : CellPos aStart, aEnd;
1119 0 : getSelectedCells( aStart, aEnd );
1120 0 : for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
1121 : {
1122 0 : for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
1123 : {
1124 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1125 0 : if( xCell.is() )
1126 0 : xCell->SetOutlinerParaObject( 0 );
1127 0 : }
1128 : }
1129 :
1130 0 : UpdateTableShape();
1131 0 : return true;
1132 : }
1133 : }
1134 :
1135 0 : return false;
1136 : }
1137 :
1138 0 : bool SvxTableController::GetStyleSheet( SfxStyleSheet*& rpStyleSheet ) const
1139 : {
1140 0 : if( hasSelectedCells() )
1141 : {
1142 0 : rpStyleSheet = 0;
1143 :
1144 0 : if( mxTable.is() )
1145 : {
1146 0 : SfxStyleSheet* pRet=0;
1147 0 : bool b1st=true;
1148 :
1149 0 : CellPos aStart, aEnd;
1150 0 : const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );
1151 :
1152 0 : for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
1153 : {
1154 0 : for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
1155 : {
1156 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1157 0 : if( xCell.is() )
1158 : {
1159 0 : SfxStyleSheet* pSS=xCell->GetStyleSheet();
1160 0 : if(b1st)
1161 : {
1162 0 : pRet=pSS;
1163 : }
1164 0 : else if(pRet != pSS)
1165 : {
1166 0 : return true;
1167 : }
1168 0 : b1st=false;
1169 : }
1170 0 : }
1171 : }
1172 0 : rpStyleSheet = pRet;
1173 0 : return true;
1174 : }
1175 : }
1176 0 : return false;
1177 : }
1178 :
1179 0 : bool SvxTableController::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr )
1180 : {
1181 0 : if( hasSelectedCells() && (!pStyleSheet || pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_FRAME) )
1182 : {
1183 0 : if( mxTable.is() )
1184 : {
1185 0 : CellPos aStart, aEnd;
1186 0 : getSelectedCells( aStart, aEnd );
1187 :
1188 0 : for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
1189 : {
1190 0 : for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
1191 : {
1192 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1193 0 : if( xCell.is() )
1194 0 : xCell->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1195 0 : }
1196 : }
1197 :
1198 0 : UpdateTableShape();
1199 0 : return true;
1200 : }
1201 : }
1202 0 : return false;
1203 : }
1204 :
1205 : // --------------------------------------------------------------------
1206 : // internals
1207 : // --------------------------------------------------------------------
1208 :
1209 0 : bool SvxTableController::checkTableObject()
1210 : {
1211 0 : return mxTableObj.is();
1212 : }
1213 :
1214 : // --------------------------------------------------------------------
1215 :
1216 0 : sal_uInt16 SvxTableController::getKeyboardAction( const KeyEvent& rKEvt, Window* /*pWindow*/ )
1217 : {
1218 0 : const bool bMod1 = rKEvt.GetKeyCode().IsMod1(); // ctrl
1219 0 : const bool bMod2 = rKEvt.GetKeyCode().IsMod2() != 0; // Alt
1220 :
1221 0 : const bool bTextEdit = mpView->IsTextEdit();
1222 :
1223 0 : sal_uInt16 nAction = ACTION_HANDLED_BY_VIEW;
1224 :
1225 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1226 0 : if( !pTableObj )
1227 0 : return nAction;
1228 :
1229 : // handle special keys
1230 0 : const sal_Int16 nCode = rKEvt.GetKeyCode().GetCode();
1231 0 : switch( nCode )
1232 : {
1233 : case awt::Key::ESCAPE: // handle escape
1234 : {
1235 0 : if( bTextEdit )
1236 : {
1237 : // escape during text edit ends text edit
1238 0 : nAction = ACTION_STOP_TEXT_EDIT;
1239 : }
1240 0 : if( mbCellSelectionMode )
1241 : {
1242 : // escape with selected cells removes selection
1243 0 : nAction = ACTION_REMOVE_SELECTION;
1244 : }
1245 0 : break;
1246 : }
1247 : case awt::Key::RETURN: // handle return
1248 : {
1249 0 : if( !bMod1 && !bMod2 && !bTextEdit )
1250 : {
1251 : // when not already editing, return starts text edit
1252 0 : setSelectionStart( pTableObj->getFirstCell() );
1253 0 : nAction = ACTION_EDIT_CELL;
1254 : }
1255 0 : break;
1256 : }
1257 : case awt::Key::F2: // f2 toggles text edit
1258 : {
1259 0 : if( bMod1 || bMod2 ) // f2 with modifiers is handled by the view
1260 : {
1261 : }
1262 0 : else if( bTextEdit )
1263 : {
1264 : // f2 during text edit stops text edit
1265 0 : nAction = ACTION_STOP_TEXT_EDIT;
1266 : }
1267 0 : else if( mbCellSelectionMode )
1268 : {
1269 : // f2 with selected cells removes selection
1270 0 : nAction = ACTION_REMOVE_SELECTION;
1271 : }
1272 : else
1273 : {
1274 : // f2 with no selection and no text edit starts text edit
1275 0 : setSelectionStart( pTableObj->getFirstCell() );
1276 0 : nAction = ACTION_EDIT_CELL;
1277 : }
1278 0 : break;
1279 : }
1280 : case awt::Key::HOME:
1281 : case awt::Key::NUM7:
1282 : {
1283 0 : if( (bMod1 || bMod2) && (bTextEdit || mbCellSelectionMode) )
1284 : {
1285 0 : if( bMod1 && !bMod2 )
1286 : {
1287 : // strg + home jumps to first cell
1288 0 : nAction = ACTION_GOTO_FIRST_CELL;
1289 : }
1290 0 : else if( !bMod1 && bMod2 )
1291 : {
1292 : // alt + home jumps to first column
1293 0 : nAction = ACTION_GOTO_FIRST_COLUMN;
1294 : }
1295 : }
1296 0 : break;
1297 : }
1298 : case awt::Key::END:
1299 : case awt::Key::NUM1:
1300 : {
1301 0 : if( (bMod1 || bMod2) && (bTextEdit || mbCellSelectionMode) )
1302 : {
1303 0 : if( bMod1 && !bMod2 )
1304 : {
1305 : // strg + end jumps to last cell
1306 0 : nAction = ACTION_GOTO_LAST_CELL;
1307 : }
1308 0 : else if( !bMod1 && bMod2 )
1309 : {
1310 : // alt + home jumps to last column
1311 0 : nAction = ACTION_GOTO_LAST_COLUMN;
1312 : }
1313 : }
1314 0 : break;
1315 : }
1316 :
1317 : case awt::Key::TAB:
1318 : {
1319 0 : if( bTextEdit || mbCellSelectionMode )
1320 0 : nAction = ACTION_TAB;
1321 0 : break;
1322 : }
1323 :
1324 : case awt::Key::UP:
1325 : case awt::Key::NUM8:
1326 : case awt::Key::DOWN:
1327 : case awt::Key::NUM2:
1328 : case awt::Key::LEFT:
1329 : case awt::Key::NUM4:
1330 : case awt::Key::RIGHT:
1331 : case awt::Key::NUM6:
1332 : {
1333 0 : bool bTextMove = false;
1334 :
1335 0 : if( !bMod1 && bMod2 )
1336 : {
1337 0 : if( (nCode == awt::Key::UP) || (nCode == awt::Key::NUM8) )
1338 : {
1339 0 : nAction = ACTION_GOTO_LEFT_CELL;
1340 : }
1341 0 : else if( (nCode == awt::Key::DOWN) || (nCode == awt::Key::NUM2) )
1342 : {
1343 0 : nAction = ACTION_GOTO_RIGHT_CELL;
1344 : }
1345 0 : break;
1346 : }
1347 :
1348 0 : if( !bTextMove )
1349 : {
1350 0 : OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
1351 0 : if( pOLV )
1352 : {
1353 0 : RemoveSelection();
1354 : // during text edit, check if we navigate out of the cell
1355 0 : ESelection aOldSelection = pOLV->GetSelection();
1356 0 : pOLV->PostKeyEvent(rKEvt);
1357 0 : bTextMove = pOLV && ( aOldSelection.IsEqual(pOLV->GetSelection()) );
1358 0 : if( !bTextMove )
1359 : {
1360 0 : nAction = ACTION_NONE;
1361 : }
1362 : }
1363 : }
1364 :
1365 0 : if( mbCellSelectionMode || bTextMove )
1366 : {
1367 : // no text edit, navigate in cells if selection active
1368 0 : switch( nCode )
1369 : {
1370 : case awt::Key::LEFT:
1371 : case awt::Key::NUM4:
1372 0 : nAction = ACTION_GOTO_LEFT_CELL;
1373 0 : break;
1374 : case awt::Key::RIGHT:
1375 : case awt::Key::NUM6:
1376 0 : nAction = ACTION_GOTO_RIGHT_CELL;
1377 0 : break;
1378 : case awt::Key::DOWN:
1379 : case awt::Key::NUM2:
1380 0 : nAction = ACTION_GOTO_DOWN_CELL;
1381 0 : break;
1382 : case awt::Key::UP:
1383 : case awt::Key::NUM8:
1384 0 : nAction = ACTION_GOTO_UP_CELL;
1385 0 : break;
1386 : }
1387 : }
1388 0 : break;
1389 : }
1390 : case awt::Key::PAGEUP:
1391 0 : if( bMod2 )
1392 0 : nAction = ACTION_GOTO_FIRST_ROW;
1393 0 : break;
1394 :
1395 : case awt::Key::PAGEDOWN:
1396 0 : if( bMod2 )
1397 0 : nAction = ACTION_GOTO_LAST_ROW;
1398 0 : break;
1399 : }
1400 0 : return nAction;
1401 : }
1402 :
1403 0 : bool SvxTableController::executeAction( sal_uInt16 nAction, bool bSelect, Window* pWindow )
1404 : {
1405 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1406 0 : if( !pTableObj )
1407 0 : return false;
1408 :
1409 0 : switch( nAction )
1410 : {
1411 : case ACTION_GOTO_FIRST_CELL:
1412 : {
1413 0 : gotoCell( pTableObj->getFirstCell(), bSelect, pWindow, nAction );
1414 0 : break;
1415 : }
1416 :
1417 : case ACTION_GOTO_LEFT_CELL:
1418 : {
1419 0 : gotoCell( pTableObj->getLeftCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction );
1420 0 : break;
1421 : }
1422 :
1423 : case ACTION_GOTO_RIGHT_CELL:
1424 : {
1425 0 : gotoCell( pTableObj->getRightCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction);
1426 0 : break;
1427 : }
1428 :
1429 : case ACTION_GOTO_LAST_CELL:
1430 : {
1431 0 : gotoCell( pTableObj->getLastCell(), bSelect, pWindow, nAction );
1432 0 : break;
1433 : }
1434 :
1435 : case ACTION_GOTO_FIRST_COLUMN:
1436 : {
1437 0 : CellPos aPos( pTableObj->getFirstCell().mnCol, getSelectionEnd().mnRow );
1438 0 : gotoCell( aPos, bSelect, pWindow, nAction );
1439 : break;
1440 : }
1441 :
1442 : case ACTION_GOTO_LAST_COLUMN:
1443 : {
1444 0 : CellPos aPos( pTableObj->getLastCell().mnCol, getSelectionEnd().mnRow );
1445 0 : gotoCell( aPos, bSelect, pWindow, nAction );
1446 : break;
1447 : }
1448 :
1449 : case ACTION_GOTO_FIRST_ROW:
1450 : {
1451 0 : CellPos aPos( getSelectionEnd().mnCol, pTableObj->getFirstCell().mnRow );
1452 0 : gotoCell( aPos, bSelect, pWindow, nAction );
1453 : break;
1454 : }
1455 :
1456 : case ACTION_GOTO_UP_CELL:
1457 : {
1458 0 : gotoCell( pTableObj->getUpCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
1459 0 : break;
1460 : }
1461 :
1462 : case ACTION_GOTO_DOWN_CELL:
1463 : {
1464 0 : gotoCell( pTableObj->getDownCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
1465 0 : break;
1466 : }
1467 :
1468 : case ACTION_GOTO_LAST_ROW:
1469 : {
1470 0 : CellPos aPos( getSelectionEnd().mnCol, pTableObj->getLastCell().mnRow );
1471 0 : gotoCell( aPos, bSelect, pWindow, nAction );
1472 : break;
1473 : }
1474 :
1475 : case ACTION_EDIT_CELL:
1476 0 : EditCell( getSelectionStart(), pWindow, 0, nAction );
1477 0 : break;
1478 :
1479 : case ACTION_STOP_TEXT_EDIT:
1480 0 : StopTextEdit();
1481 0 : break;
1482 :
1483 : case ACTION_REMOVE_SELECTION:
1484 0 : RemoveSelection();
1485 0 : break;
1486 :
1487 : case ACTION_START_SELECTION:
1488 0 : StartSelection( getSelectionStart() );
1489 0 : break;
1490 :
1491 : case ACTION_TAB:
1492 : {
1493 0 : if( bSelect )
1494 0 : gotoCell( pTableObj->getPreviousCell( getSelectionEnd(), true ), false, pWindow, nAction );
1495 : else
1496 : {
1497 0 : CellPos aSelectionEnd( getSelectionEnd() );
1498 0 : CellPos aNextCell( pTableObj->getNextCell( aSelectionEnd, true ) );
1499 0 : if( aSelectionEnd == aNextCell )
1500 : {
1501 0 : onInsert( SID_TABLE_INSERT_ROW, 0 );
1502 0 : aNextCell = pTableObj->getNextCell( aSelectionEnd, true );
1503 : }
1504 0 : gotoCell( aNextCell, false, pWindow, nAction );
1505 : }
1506 0 : break;
1507 : }
1508 : }
1509 :
1510 0 : return nAction != ACTION_HANDLED_BY_VIEW;
1511 : }
1512 :
1513 : // --------------------------------------------------------------------
1514 :
1515 0 : void SvxTableController::gotoCell( const CellPos& rPos, bool bSelect, Window* pWindow, sal_uInt16 nAction )
1516 : {
1517 0 : if( mxTableObj.is() && static_cast<SdrTableObj*>(mxTableObj.get())->IsTextEditActive() )
1518 0 : mpView->SdrEndTextEdit(sal_True);
1519 :
1520 0 : if( bSelect )
1521 : {
1522 0 : maCursorLastPos = rPos;
1523 0 : if( mxTableObj.is() )
1524 0 : static_cast< SdrTableObj* >( mxTableObj.get() )->setActiveCell( rPos );
1525 :
1526 0 : if( !mbCellSelectionMode )
1527 : {
1528 0 : setSelectedCells( maCursorFirstPos, rPos );
1529 : }
1530 : else
1531 : {
1532 0 : UpdateSelection( rPos );
1533 : }
1534 : }
1535 : else
1536 : {
1537 0 : RemoveSelection();
1538 0 : EditCell( rPos, pWindow, 0, nAction );
1539 : }
1540 0 : }
1541 :
1542 : // --------------------------------------------------------------------
1543 :
1544 0 : const CellPos& SvxTableController::getSelectionStart()
1545 : {
1546 0 : checkCell( maCursorFirstPos );
1547 0 : return maCursorFirstPos;
1548 : }
1549 :
1550 : // --------------------------------------------------------------------
1551 :
1552 0 : void SvxTableController::setSelectionStart( const CellPos& rPos )
1553 : {
1554 0 : maCursorFirstPos = rPos;
1555 0 : }
1556 :
1557 : // --------------------------------------------------------------------
1558 :
1559 0 : const CellPos& SvxTableController::getSelectionEnd()
1560 : {
1561 0 : checkCell( maCursorLastPos );
1562 0 : return maCursorLastPos;
1563 : }
1564 :
1565 : // --------------------------------------------------------------------
1566 :
1567 0 : void SvxTableController::MergeRange( sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow )
1568 : {
1569 0 : if( mxTable.is() ) try
1570 : {
1571 0 : Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( nFirstCol, nFirstRow,nLastCol, nLastRow ) ), UNO_QUERY_THROW );
1572 0 : if( xRange->isMergeable() )
1573 : {
1574 0 : const bool bUndo = mpModel && mpModel->IsUndoEnabled();
1575 0 : if( bUndo )
1576 : {
1577 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_MERGE) );
1578 0 : mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj.get()) );
1579 : }
1580 :
1581 0 : xRange->merge();
1582 :
1583 0 : if( bUndo )
1584 0 : mpModel->EndUndo();
1585 0 : }
1586 : }
1587 0 : catch( Exception& )
1588 : {
1589 : DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" );
1590 : }
1591 0 : }
1592 :
1593 :
1594 :
1595 : // --------------------------------------------------------------------
1596 :
1597 0 : void SvxTableController::checkCell( CellPos& rPos )
1598 : {
1599 0 : if( mxTable.is() ) try
1600 : {
1601 0 : if( rPos.mnCol >= mxTable->getColumnCount() )
1602 0 : rPos.mnCol = mxTable->getColumnCount()-1;
1603 :
1604 0 : if( rPos.mnRow >= mxTable->getRowCount() )
1605 0 : rPos.mnRow = mxTable->getRowCount()-1;
1606 : }
1607 0 : catch( Exception& )
1608 : {
1609 : OSL_FAIL("sdr::table::SvxTableController::checkCell(), exception caught!" );
1610 : }
1611 0 : }
1612 :
1613 : // --------------------------------------------------------------------
1614 :
1615 0 : void SvxTableController::findMergeOrigin( CellPos& rPos )
1616 : {
1617 0 : if( mxTable.is() ) try
1618 : {
1619 0 : Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ), UNO_QUERY_THROW );
1620 0 : if( xCell.is() && xCell->isMerged() )
1621 : {
1622 0 : ::findMergeOrigin( mxTable, rPos.mnCol, rPos.mnRow, rPos.mnCol, rPos.mnRow );
1623 0 : }
1624 : }
1625 0 : catch( Exception& )
1626 : {
1627 : OSL_FAIL("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" );
1628 : }
1629 0 : }
1630 :
1631 : // --------------------------------------------------------------------
1632 :
1633 0 : void SvxTableController::EditCell( const CellPos& rPos, ::Window* pWindow, const awt::MouseEvent* pMouseEvent /*= 0*/, sal_uInt16 nAction /*= ACTION_NONE */ )
1634 : {
1635 0 : SdrPageView* pPV = mpView->GetSdrPageView();
1636 :
1637 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1638 0 : if( pTableObj && pTableObj->GetPage() == pPV->GetPage() )
1639 : {
1640 0 : bool bEmptyOutliner = false;
1641 :
1642 0 : if(!pTableObj->GetOutlinerParaObject() && mpView->GetTextEditOutliner())
1643 : {
1644 0 : ::Outliner* pOutl = mpView->GetTextEditOutliner();
1645 0 : sal_uIntPtr nParaAnz = pOutl->GetParagraphCount();
1646 0 : Paragraph* p1stPara = pOutl->GetParagraph( 0 );
1647 :
1648 0 : if(nParaAnz==1 && p1stPara)
1649 : {
1650 : // Bei nur einem Pararaph
1651 0 : if (pOutl->GetText(p1stPara).Len() == 0)
1652 : {
1653 0 : bEmptyOutliner = true;
1654 : }
1655 : }
1656 : }
1657 :
1658 0 : CellPos aPos( rPos );
1659 0 : findMergeOrigin( aPos );
1660 :
1661 0 : if( pTableObj != mpView->GetTextEditObject() || bEmptyOutliner || !pTableObj->IsTextEditActive( aPos ) )
1662 : {
1663 0 : if( pTableObj->IsTextEditActive() )
1664 0 : mpView->SdrEndTextEdit(sal_True);
1665 :
1666 0 : pTableObj->setActiveCell( aPos );
1667 :
1668 : // create new outliner, owner will be the SdrObjEditView
1669 0 : SdrOutliner* pOutl = SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT, mpModel );
1670 0 : if( pTableObj->IsVerticalWriting() )
1671 0 : pOutl->SetVertical( sal_True );
1672 :
1673 0 : if(mpView->SdrBeginTextEdit(pTableObj, pPV, pWindow, sal_True, pOutl))
1674 : {
1675 0 : maCursorLastPos = maCursorFirstPos = rPos;
1676 :
1677 0 : OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
1678 :
1679 0 : bool bNoSel = true;
1680 :
1681 0 : if( pMouseEvent )
1682 : {
1683 0 : ::MouseEvent aMEvt( *pMouseEvent );
1684 :
1685 0 : SdrViewEvent aVEvt;
1686 0 : SdrHitKind eHit = mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);
1687 :
1688 0 : if (eHit == SDRHIT_TEXTEDIT)
1689 : {
1690 : // Text getroffen
1691 0 : pOLV->MouseButtonDown(aMEvt);
1692 0 : pOLV->MouseMove(aMEvt);
1693 0 : pOLV->MouseButtonUp(aMEvt);
1694 : // pOLV->MouseButtonDown(aMEvt);
1695 0 : bNoSel = false;
1696 : }
1697 : else
1698 : {
1699 0 : nAction = ACTION_GOTO_LEFT_CELL;
1700 0 : }
1701 : }
1702 :
1703 0 : if( bNoSel )
1704 : {
1705 : // Move cursor to end of text
1706 0 : ESelection aNewSelection;
1707 :
1708 0 : const WritingMode eMode = pTableObj->GetWritingMode();
1709 0 : if( ((nAction == ACTION_GOTO_LEFT_CELL) || (nAction == ACTION_GOTO_RIGHT_CELL)) && (eMode != WritingMode_TB_RL) )
1710 : {
1711 : const bool bLast = ((nAction == ACTION_GOTO_LEFT_CELL) && (eMode == WritingMode_LR_TB)) ||
1712 0 : ((nAction == ACTION_GOTO_RIGHT_CELL) && (eMode == WritingMode_RL_TB));
1713 :
1714 0 : if( bLast )
1715 0 : aNewSelection = ESelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND);
1716 : }
1717 0 : pOLV->SetSelection(aNewSelection);
1718 : }
1719 : }
1720 : }
1721 : }
1722 0 : }
1723 :
1724 : // --------------------------------------------------------------------
1725 :
1726 0 : bool SvxTableController::StopTextEdit()
1727 : {
1728 0 : if(mpView->IsTextEdit())
1729 : {
1730 0 : mpView->SdrEndTextEdit();
1731 0 : mpView->SetCurrentObj(OBJ_TABLE);
1732 0 : mpView->SetEditMode(SDREDITMODE_EDIT);
1733 0 : return true;
1734 : }
1735 : else
1736 : {
1737 0 : return false;
1738 : }
1739 : }
1740 :
1741 : // --------------------------------------------------------------------
1742 :
1743 0 : void SvxTableController::getSelectedCells( CellPos& rFirst, CellPos& rLast )
1744 : {
1745 0 : if( mbCellSelectionMode )
1746 : {
1747 0 : checkCell( maCursorFirstPos );
1748 0 : checkCell( maCursorLastPos );
1749 :
1750 0 : rFirst.mnCol = std::min( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
1751 0 : rFirst.mnRow = std::min( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );
1752 0 : rLast.mnCol = std::max( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
1753 0 : rLast.mnRow = std::max( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );
1754 :
1755 0 : bool bExt = false;
1756 0 : if( mxTable.is() ) do
1757 : {
1758 0 : bExt = false;
1759 0 : for( sal_Int32 nRow = rFirst.mnRow; nRow <= rLast.mnRow && !bExt; nRow++ )
1760 : {
1761 0 : for( sal_Int32 nCol = rFirst.mnCol; nCol <= rLast.mnCol && !bExt; nCol++ )
1762 : {
1763 0 : Reference< XMergeableCell > xCell( mxTable->getCellByPosition( nCol, nRow ), UNO_QUERY );
1764 0 : if( !xCell.is() )
1765 0 : continue;
1766 :
1767 0 : if( xCell->isMerged() )
1768 : {
1769 0 : CellPos aPos( nCol, nRow );
1770 0 : findMergeOrigin( aPos );
1771 0 : if( (aPos.mnCol < rFirst.mnCol) || (aPos.mnRow < rFirst.mnRow) )
1772 : {
1773 0 : rFirst.mnCol = std::min( rFirst.mnCol, aPos.mnCol );
1774 0 : rFirst.mnRow = std::min( rFirst.mnRow, aPos.mnRow );
1775 0 : bExt = true;
1776 : }
1777 : }
1778 : else
1779 : {
1780 0 : if( ((nCol + xCell->getColumnSpan() - 1) > rLast.mnCol) || (nRow + xCell->getRowSpan() - 1 ) > rLast.mnRow )
1781 : {
1782 0 : rLast.mnCol = std::max( rLast.mnCol, nCol + xCell->getColumnSpan() - 1 );
1783 0 : rLast.mnRow = std::max( rLast.mnRow, nRow + xCell->getRowSpan() - 1 );
1784 0 : bExt = true;
1785 : }
1786 : }
1787 0 : }
1788 : }
1789 : }
1790 : while(bExt);
1791 : }
1792 0 : else if( mpView && mpView->IsTextEdit() )
1793 : {
1794 0 : rFirst = getSelectionStart();
1795 0 : findMergeOrigin( rFirst );
1796 0 : rLast = rFirst;
1797 :
1798 0 : if( mxTable.is() )
1799 : {
1800 0 : Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rLast.mnCol, rLast.mnRow ), UNO_QUERY );
1801 0 : if( xCell.is() )
1802 : {
1803 0 : rLast.mnCol += xCell->getColumnSpan() - 1;
1804 0 : rLast.mnRow += xCell->getRowSpan() - 1;
1805 0 : }
1806 : }
1807 : }
1808 : else
1809 : {
1810 0 : rFirst.mnCol = 0;
1811 0 : rFirst.mnRow = 0;
1812 0 : if( mxTable.is() )
1813 : {
1814 0 : rLast.mnRow = mxTable->getRowCount()-1;
1815 0 : rLast.mnCol = mxTable->getColumnCount()-1;
1816 : }
1817 : else
1818 : {
1819 0 : rLast.mnRow = 0;
1820 0 : rLast.mnCol = 0;
1821 : }
1822 : }
1823 0 : }
1824 :
1825 : // --------------------------------------------------------------------
1826 :
1827 0 : void SvxTableController::StartSelection( const CellPos& rPos )
1828 : {
1829 0 : StopTextEdit();
1830 0 : mbCellSelectionMode = true;
1831 0 : maCursorLastPos = maCursorFirstPos = rPos;
1832 0 : mpView->MarkListHasChanged();
1833 0 : }
1834 :
1835 : // --------------------------------------------------------------------
1836 :
1837 0 : void SvxTableController::setSelectedCells( const CellPos& rStart, const CellPos& rEnd )
1838 : {
1839 0 : StopTextEdit();
1840 0 : mbCellSelectionMode = true;
1841 0 : maCursorFirstPos = rStart;
1842 0 : UpdateSelection( rEnd );
1843 0 : }
1844 :
1845 : // --------------------------------------------------------------------
1846 :
1847 0 : void SvxTableController::UpdateSelection( const CellPos& rPos )
1848 : {
1849 0 : maCursorLastPos = rPos;
1850 0 : mpView->MarkListHasChanged();
1851 0 : }
1852 :
1853 : // --------------------------------------------------------------------
1854 :
1855 0 : void SvxTableController::clearSelection()
1856 : {
1857 0 : RemoveSelection();
1858 0 : }
1859 :
1860 : // --------------------------------------------------------------------
1861 :
1862 0 : void SvxTableController::selectAll()
1863 : {
1864 0 : if( mxTable.is() )
1865 : {
1866 0 : CellPos aPos1, aPos2( mxTable->getColumnCount()-1, mxTable->getRowCount()-1 );
1867 0 : if( (aPos2.mnCol >= 0) && (aPos2.mnRow >= 0) )
1868 : {
1869 0 : setSelectedCells( aPos1, aPos2 );
1870 : }
1871 : }
1872 0 : }
1873 :
1874 : // --------------------------------------------------------------------
1875 :
1876 0 : void SvxTableController::RemoveSelection()
1877 : {
1878 0 : if( mbCellSelectionMode )
1879 : {
1880 0 : mbCellSelectionMode = false;
1881 0 : mpView->MarkListHasChanged();
1882 : }
1883 0 : }
1884 :
1885 : // --------------------------------------------------------------------
1886 :
1887 0 : void SvxTableController::onTableModified()
1888 : {
1889 0 : if( mnUpdateEvent == 0 )
1890 0 : mnUpdateEvent = Application::PostUserEvent( LINK( this, SvxTableController, UpdateHdl ) );
1891 0 : }
1892 : // --------------------------------------------------------------------
1893 :
1894 0 : void SvxTableController::updateSelectionOverlay()
1895 : {
1896 0 : destroySelectionOverlay();
1897 0 : if( mbCellSelectionMode )
1898 : {
1899 0 : ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
1900 0 : if( pTableObj )
1901 : {
1902 0 : sdr::overlay::OverlayObjectCell::RangeVector aRanges;
1903 :
1904 0 : Rectangle aRect;
1905 0 : CellPos aStart,aEnd;
1906 0 : getSelectedCells( aStart, aEnd );
1907 0 : pTableObj->getCellBounds( aStart, aRect );
1908 :
1909 0 : basegfx::B2DRange a2DRange( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
1910 0 : a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );
1911 :
1912 0 : findMergeOrigin( aEnd );
1913 0 : pTableObj->getCellBounds( aEnd, aRect );
1914 0 : a2DRange.expand( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
1915 0 : a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );
1916 0 : aRanges.push_back( a2DRange );
1917 :
1918 0 : ::Color aHighlight( COL_BLUE );
1919 0 : OutputDevice* pOutDev = mpView->GetFirstOutputDevice();
1920 0 : if( pOutDev )
1921 0 : aHighlight = pOutDev->GetSettings().GetStyleSettings().GetHighlightColor();
1922 :
1923 0 : const sal_uInt32 nCount = mpView->PaintWindowCount();
1924 0 : for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
1925 : {
1926 0 : SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(nIndex);
1927 0 : if( pPaintWindow )
1928 : {
1929 0 : rtl::Reference < ::sdr::overlay::OverlayManager > xOverlayManager = pPaintWindow->GetOverlayManager();
1930 0 : if( xOverlayManager.is() )
1931 : {
1932 : // sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT;
1933 0 : sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_TRANSPARENT;
1934 :
1935 0 : sdr::overlay::OverlayObjectCell* pOverlay = new sdr::overlay::OverlayObjectCell( eType, aHighlight, aRanges );
1936 :
1937 0 : xOverlayManager->add(*pOverlay);
1938 0 : mpSelectionOverlay = new ::sdr::overlay::OverlayObjectList;
1939 0 : mpSelectionOverlay->append(*pOverlay);
1940 0 : }
1941 : }
1942 0 : }
1943 : }
1944 : }
1945 0 : }
1946 :
1947 : // --------------------------------------------------------------------
1948 :
1949 0 : void SvxTableController::destroySelectionOverlay()
1950 : {
1951 0 : if( mpSelectionOverlay )
1952 : {
1953 0 : delete mpSelectionOverlay;
1954 0 : mpSelectionOverlay = 0;
1955 : }
1956 0 : }
1957 :
1958 : // --------------------------------------------------------------------
1959 :
1960 0 : void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const
1961 : {
1962 0 : if( mxTable.is() )
1963 : {
1964 0 : CellPos aStart, aEnd;
1965 0 : const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );
1966 :
1967 0 : for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
1968 : {
1969 0 : for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
1970 : {
1971 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
1972 0 : if( xCell.is() && !xCell->isMerged() )
1973 : {
1974 0 : const SfxItemSet& rSet = xCell->GetItemSet();
1975 0 : SfxWhichIter aIter(rSet);
1976 0 : sal_uInt16 nWhich(aIter.FirstWhich());
1977 0 : while(nWhich)
1978 : {
1979 0 : if(!bOnlyHardAttr)
1980 : {
1981 0 : if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False))
1982 0 : rAttr.InvalidateItem(nWhich);
1983 : else
1984 0 : rAttr.MergeValue(rSet.Get(nWhich), sal_True);
1985 : }
1986 0 : else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False))
1987 : {
1988 0 : const SfxPoolItem& rItem = rSet.Get(nWhich);
1989 0 : rAttr.MergeValue(rItem, sal_True);
1990 : }
1991 :
1992 0 : nWhich = aIter.NextWhich();
1993 0 : }
1994 : }
1995 0 : }
1996 : }
1997 : }
1998 :
1999 0 : if( mpView->IsTextEdit() )
2000 : {
2001 : }
2002 0 : }
2003 :
2004 : // --------------------------------------------------------------------
2005 :
2006 : const sal_uInt16 CELL_BEFORE = 0x0001;
2007 : const sal_uInt16 CELL_LEFT = 0x0002;
2008 : const sal_uInt16 CELL_RIGHT = 0x0004;
2009 : const sal_uInt16 CELL_AFTER = 0x0008;
2010 :
2011 : const sal_uInt16 CELL_UPPER = 0x0010;
2012 : const sal_uInt16 CELL_TOP = 0x0020;
2013 : const sal_uInt16 CELL_BOTTOM = 0x0040;
2014 : const sal_uInt16 CELL_LOWER = 0x0080;
2015 :
2016 : // --------------------------------------------------------------------
2017 :
2018 0 : static void ImplSetLinePreserveColor( SvxBoxItem& rNewFrame, const SvxBorderLine* pNew, sal_uInt16 nLine )
2019 : {
2020 0 : if( pNew )
2021 : {
2022 0 : const SvxBorderLine* pOld = rNewFrame.GetLine(nLine);
2023 0 : if( pOld )
2024 : {
2025 0 : SvxBorderLine aNewLine( *pNew );
2026 0 : aNewLine.SetColor( pOld->GetColor() );
2027 0 : rNewFrame.SetLine( &aNewLine, nLine );
2028 0 : return;
2029 : }
2030 : }
2031 0 : rNewFrame.SetLine( pNew, nLine );
2032 : }
2033 :
2034 : // --------------------------------------------------------------------
2035 :
2036 0 : static void ImplApplyBoxItem( sal_uInt16 nCellFlags, const SvxBoxItem* pBoxItem, const SvxBoxInfoItem* pBoxInfoItem, SvxBoxItem& rNewFrame )
2037 : {
2038 0 : if( (nCellFlags & (CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
2039 : {
2040 : // current cell is outside the selection
2041 :
2042 0 : if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
2043 : {
2044 0 : if( nCellFlags & CELL_UPPER )
2045 : {
2046 0 : if( pBoxInfoItem->IsValid(VALID_TOP) )
2047 0 : rNewFrame.SetLine(0, BOX_LINE_BOTTOM );
2048 : }
2049 0 : else if( nCellFlags & CELL_LOWER )
2050 : {
2051 0 : if( pBoxInfoItem->IsValid(VALID_BOTTOM) )
2052 0 : rNewFrame.SetLine( 0, BOX_LINE_TOP );
2053 : }
2054 : }
2055 0 : else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
2056 : {
2057 0 : if( nCellFlags & CELL_BEFORE )
2058 : {
2059 0 : if( pBoxInfoItem->IsValid(VALID_LEFT) )
2060 0 : rNewFrame.SetLine( 0, BOX_LINE_RIGHT );
2061 : }
2062 0 : else if( nCellFlags & CELL_AFTER )
2063 : {
2064 0 : if( pBoxInfoItem->IsValid(VALID_RIGHT) )
2065 0 : rNewFrame.SetLine( 0, BOX_LINE_LEFT );
2066 : }
2067 : }
2068 : }
2069 : else
2070 : {
2071 : // current cell is inside the selection
2072 :
2073 0 : if( (nCellFlags & CELL_LEFT) ? pBoxInfoItem->IsValid(VALID_LEFT) : pBoxInfoItem->IsValid(VALID_VERT) )
2074 0 : rNewFrame.SetLine( (nCellFlags & CELL_LEFT) ? pBoxItem->GetLeft() : pBoxInfoItem->GetVert(), BOX_LINE_LEFT );
2075 :
2076 0 : if( (nCellFlags & CELL_RIGHT) ? pBoxInfoItem->IsValid(VALID_RIGHT) : pBoxInfoItem->IsValid(VALID_VERT) )
2077 0 : rNewFrame.SetLine( (nCellFlags & CELL_RIGHT) ? pBoxItem->GetRight() : pBoxInfoItem->GetVert(), BOX_LINE_RIGHT );
2078 :
2079 0 : if( (nCellFlags & CELL_TOP) ? pBoxInfoItem->IsValid(VALID_TOP) : pBoxInfoItem->IsValid(VALID_HORI) )
2080 0 : rNewFrame.SetLine( (nCellFlags & CELL_TOP) ? pBoxItem->GetTop() : pBoxInfoItem->GetHori(), BOX_LINE_TOP );
2081 :
2082 0 : if( (nCellFlags & CELL_BOTTOM) ? pBoxInfoItem->IsValid(VALID_BOTTOM) : pBoxInfoItem->IsValid(VALID_HORI) )
2083 0 : rNewFrame.SetLine( (nCellFlags & CELL_BOTTOM) ? pBoxItem->GetBottom() : pBoxInfoItem->GetHori(), BOX_LINE_BOTTOM );
2084 :
2085 : // apply distance to borders
2086 0 : if( pBoxInfoItem->IsValid( VALID_DISTANCE ) )
2087 0 : for( sal_uInt16 nLine = 0; nLine < 4; ++nLine )
2088 0 : rNewFrame.SetDistance( pBoxItem->GetDistance( nLine ), nLine );
2089 : }
2090 0 : }
2091 :
2092 : // --------------------------------------------------------------------
2093 :
2094 0 : static void ImplSetLineColor( SvxBoxItem& rNewFrame, sal_uInt16 nLine, const Color& rColor )
2095 : {
2096 0 : const SvxBorderLine* pSourceLine = rNewFrame.GetLine( nLine );
2097 0 : if( pSourceLine )
2098 : {
2099 0 : SvxBorderLine aLine( *pSourceLine );
2100 0 : aLine.SetColor( rColor );
2101 0 : rNewFrame.SetLine( &aLine, nLine );
2102 : }
2103 0 : }
2104 :
2105 : // --------------------------------------------------------------------
2106 :
2107 0 : static void ImplApplyLineColorItem( sal_uInt16 nCellFlags, const SvxColorItem* pLineColorItem, SvxBoxItem& rNewFrame )
2108 : {
2109 0 : const Color aColor( pLineColorItem->GetValue() );
2110 :
2111 0 : if( (nCellFlags & (CELL_LOWER|CELL_BEFORE|CELL_AFTER)) == 0 )
2112 0 : ImplSetLineColor( rNewFrame, BOX_LINE_BOTTOM, aColor );
2113 :
2114 0 : if( (nCellFlags & (CELL_UPPER|CELL_BEFORE|CELL_AFTER)) == 0 )
2115 0 : ImplSetLineColor( rNewFrame, BOX_LINE_TOP, aColor );
2116 :
2117 0 : if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_AFTER)) == 0 )
2118 0 : ImplSetLineColor( rNewFrame, BOX_LINE_RIGHT, aColor );
2119 :
2120 0 : if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_BEFORE)) == 0 )
2121 0 : ImplSetLineColor( rNewFrame, BOX_LINE_LEFT, aColor );
2122 0 : }
2123 :
2124 : // --------------------------------------------------------------------
2125 :
2126 0 : static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags, const SvxBorderLine* pBorderLineItem, SvxBoxItem& rNewFrame )
2127 : {
2128 0 : if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
2129 : {
2130 0 : if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
2131 : {
2132 0 : if( nCellFlags & CELL_UPPER )
2133 : {
2134 0 : if( rNewFrame.GetBottom() )
2135 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
2136 : }
2137 0 : else if( nCellFlags & CELL_LOWER )
2138 : {
2139 0 : if( rNewFrame.GetTop() )
2140 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
2141 : }
2142 : }
2143 0 : else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
2144 : {
2145 0 : if( nCellFlags & CELL_BEFORE )
2146 : {
2147 0 : if( rNewFrame.GetRight() )
2148 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
2149 : }
2150 0 : else if( nCellFlags & CELL_AFTER )
2151 : {
2152 0 : if( rNewFrame.GetLeft() )
2153 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
2154 : }
2155 : }
2156 : }
2157 : else
2158 : {
2159 0 : if( rNewFrame.GetBottom() )
2160 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
2161 0 : if( rNewFrame.GetTop() )
2162 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
2163 0 : if( rNewFrame.GetRight() )
2164 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
2165 0 : if( rNewFrame.GetLeft() )
2166 0 : ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
2167 : }
2168 0 : }
2169 :
2170 : // --------------------------------------------------------------------
2171 :
2172 0 : void SvxTableController::ApplyBorderAttr( const SfxItemSet& rAttr )
2173 : {
2174 0 : if( mxTable.is() )
2175 : {
2176 0 : const sal_Int32 nRowCount = mxTable->getRowCount();
2177 0 : const sal_Int32 nColCount = mxTable->getColumnCount();
2178 0 : if( nRowCount && nColCount )
2179 : {
2180 0 : const SvxBoxItem* pBoxItem = 0;
2181 0 : if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER, sal_False) )
2182 0 : pBoxItem = dynamic_cast< const SvxBoxItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER ) );
2183 :
2184 0 : const SvxBoxInfoItem* pBoxInfoItem = 0;
2185 0 : if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER_INNER, sal_False) )
2186 0 : pBoxInfoItem = dynamic_cast< const SvxBoxInfoItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER_INNER ) );
2187 :
2188 0 : const SvxColorItem* pLineColorItem = 0;
2189 0 : if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINECOLOR, sal_False) )
2190 0 : pLineColorItem = dynamic_cast< const SvxColorItem* >( &rAttr.Get( SID_FRAME_LINECOLOR ) );
2191 :
2192 0 : const SvxBorderLine* pBorderLineItem = 0;
2193 0 : if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINESTYLE, sal_False) )
2194 0 : pBorderLineItem = ((const SvxLineItem&)rAttr.Get( SID_FRAME_LINESTYLE )).GetLine();
2195 :
2196 0 : if( pBoxInfoItem && !pBoxItem )
2197 : {
2198 0 : const static SvxBoxItem gaEmptyBoxItem( SDRATTR_TABLE_BORDER );
2199 0 : pBoxItem = &gaEmptyBoxItem;
2200 : }
2201 0 : else if( pBoxItem && !pBoxInfoItem )
2202 : {
2203 0 : const static SvxBoxInfoItem gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER );
2204 0 : pBoxInfoItem = &gaEmptyBoxInfoItem;
2205 : }
2206 :
2207 0 : CellPos aStart, aEnd;
2208 0 : getSelectedCells( aStart, aEnd );
2209 :
2210 0 : const sal_Int32 nLastRow = std::min( aEnd.mnRow + 2, nRowCount );
2211 0 : const sal_Int32 nLastCol = std::min( aEnd.mnCol + 2, nColCount );
2212 :
2213 0 : for( sal_Int32 nRow = std::max( aStart.mnRow - 1, (sal_Int32)0 ); nRow < nLastRow; nRow++ )
2214 : {
2215 0 : sal_uInt16 nRowFlags = 0;
2216 0 : nRowFlags |= (nRow == aStart.mnRow) ? CELL_TOP : 0;
2217 0 : nRowFlags |= (nRow == aEnd.mnRow) ? CELL_BOTTOM : 0;
2218 0 : nRowFlags |= (nRow < aStart.mnRow) ? CELL_UPPER : 0;
2219 0 : nRowFlags |= (nRow > aEnd.mnRow) ? CELL_LOWER : 0;
2220 :
2221 0 : for( sal_Int32 nCol = std::max( aStart.mnCol - 1, (sal_Int32)0 ); nCol < nLastCol; nCol++ )
2222 : {
2223 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
2224 0 : if( !xCell.is() )
2225 0 : continue;
2226 :
2227 0 : const SfxItemSet& rSet = xCell->GetItemSet();
2228 0 : const SvxBoxItem* pOldOuter = (const SvxBoxItem*) &rSet.Get( SDRATTR_TABLE_BORDER );
2229 :
2230 0 : SvxBoxItem aNewFrame( *pOldOuter );
2231 :
2232 0 : sal_uInt16 nCellFlags = nRowFlags;
2233 0 : nCellFlags |= (nCol == aStart.mnCol) ? CELL_LEFT : 0;
2234 0 : nCellFlags |= (nCol == aEnd.mnCol) ? CELL_RIGHT : 0;
2235 0 : nCellFlags |= (nCol < aStart.mnCol) ? CELL_BEFORE : 0;
2236 0 : nCellFlags |= (nCol > aEnd.mnCol) ? CELL_AFTER : 0;
2237 :
2238 0 : if( pBoxItem && pBoxInfoItem )
2239 0 : ImplApplyBoxItem( nCellFlags, pBoxItem, pBoxInfoItem, aNewFrame );
2240 :
2241 0 : if( pLineColorItem )
2242 0 : ImplApplyLineColorItem( nCellFlags, pLineColorItem, aNewFrame );
2243 :
2244 0 : if( pBorderLineItem )
2245 0 : ImplApplyBorderLineItem( nCellFlags, pBorderLineItem, aNewFrame );
2246 :
2247 0 : if (aNewFrame != *pOldOuter)
2248 : {
2249 0 : SfxItemSet aAttr(*rSet.GetPool(), rSet.GetRanges());
2250 0 : aAttr.Put(aNewFrame);
2251 0 : xCell->SetMergedItemSetAndBroadcast( aAttr, false );
2252 : }
2253 0 : }
2254 : }
2255 : }
2256 : }
2257 0 : }
2258 :
2259 : // --------------------------------------------------------------------
2260 :
2261 0 : void SvxTableController::UpdateTableShape()
2262 : {
2263 0 : SdrObject* pTableObj = mxTableObj.get();
2264 0 : if( pTableObj )
2265 : {
2266 0 : pTableObj->ActionChanged();
2267 0 : pTableObj->BroadcastObjectChange();
2268 : }
2269 0 : updateSelectionOverlay();
2270 0 : }
2271 :
2272 :
2273 : // --------------------------------------------------------------------
2274 :
2275 0 : void SvxTableController::SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll)
2276 : {
2277 0 : if( mxTable.is() )
2278 : {
2279 0 : const bool bUndo = mpModel && mpModel->IsUndoEnabled();
2280 :
2281 0 : if( bUndo )
2282 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );
2283 :
2284 0 : CellPos aStart, aEnd;
2285 0 : getSelectedCells( aStart, aEnd );
2286 :
2287 0 : SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges());
2288 0 : aAttr.Put(rAttr, sal_True);
2289 :
2290 0 : const bool bFrame = (rAttr.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rAttr.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);
2291 :
2292 0 : if( bFrame )
2293 : {
2294 0 : aAttr.ClearItem( SDRATTR_TABLE_BORDER );
2295 0 : aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
2296 : }
2297 :
2298 0 : for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
2299 : {
2300 0 : for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
2301 : {
2302 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
2303 0 : if( xCell.is() )
2304 : {
2305 0 : if( bUndo )
2306 0 : xCell->AddUndo();
2307 0 : xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
2308 : }
2309 0 : }
2310 : }
2311 :
2312 0 : if( bFrame )
2313 : {
2314 0 : ApplyBorderAttr( rAttr );
2315 : }
2316 :
2317 0 : UpdateTableShape();
2318 :
2319 0 : if( bUndo )
2320 0 : mpModel->EndUndo();
2321 :
2322 : }
2323 0 : }
2324 :
2325 : // --------------------------------------------------------------------
2326 :
2327 0 : bool SvxTableController::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
2328 : {
2329 0 : if( mxTableObj.is() && hasSelectedCells() )
2330 : {
2331 0 : MergeAttrFromSelectedCells( rTargetSet, bOnlyHardAttr );
2332 :
2333 0 : if( mpView->IsTextEdit() )
2334 : {
2335 0 : if( mxTableObj->GetOutlinerParaObject() )
2336 0 : rTargetSet.Put( SvxScriptTypeItem( mxTableObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
2337 :
2338 0 : OutlinerView* pTextEditOutlinerView = mpView->GetTextEditOutlinerView();
2339 0 : if(pTextEditOutlinerView)
2340 : {
2341 : // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
2342 0 : rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), sal_False);
2343 0 : rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ), sal_False );
2344 : }
2345 : }
2346 :
2347 0 : return true;
2348 : }
2349 : else
2350 : {
2351 0 : return false;
2352 : }
2353 : }
2354 :
2355 : // --------------------------------------------------------------------
2356 :
2357 0 : bool SvxTableController::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
2358 : {
2359 0 : if( mbCellSelectionMode || mpView->IsTextEdit() )
2360 : {
2361 0 : SetAttrToSelectedCells( rSet, bReplaceAll );
2362 0 : return true;
2363 : }
2364 0 : return false;
2365 : }
2366 :
2367 : // --------------------------------------------------------------------
2368 :
2369 0 : bool SvxTableController::GetMarkedObjModel( SdrPage* pNewPage )
2370 : {
2371 0 : if( mxTableObj.is() && mbCellSelectionMode && pNewPage ) try
2372 : {
2373 0 : ::sdr::table::SdrTableObj& rTableObj = *static_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
2374 :
2375 0 : CellPos aStart, aEnd;
2376 0 : getSelectedCells( aStart, aEnd );
2377 :
2378 0 : SdrTableObj* pNewTableObj = rTableObj.CloneRange( aStart, aEnd );
2379 :
2380 0 : pNewTableObj->SetPage( pNewPage );
2381 0 : pNewTableObj->SetModel( pNewPage->GetModel() );
2382 :
2383 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
2384 0 : pNewPage->InsertObject(pNewTableObj,CONTAINER_APPEND,&aReason);
2385 :
2386 0 : return true;
2387 : }
2388 0 : catch( Exception& )
2389 : {
2390 : OSL_FAIL( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2391 : }
2392 0 : return false;
2393 : }
2394 :
2395 : // --------------------------------------------------------------------
2396 :
2397 0 : bool SvxTableController::PasteObjModel( const SdrModel& rModel )
2398 : {
2399 0 : if( mxTableObj.is() && mpView && (rModel.GetPageCount() >= 1) )
2400 : {
2401 0 : const SdrPage* pPastePage = rModel.GetPage(0);
2402 0 : if( pPastePage && pPastePage->GetObjCount() == 1 )
2403 : {
2404 0 : SdrTableObj* pPasteTableObj = dynamic_cast< SdrTableObj* >( pPastePage->GetObj(0) );
2405 0 : if( pPasteTableObj )
2406 : {
2407 0 : return PasteObject( pPasteTableObj );
2408 : }
2409 : }
2410 : }
2411 :
2412 0 : return false;
2413 : }
2414 :
2415 : // --------------------------------------------------------------------
2416 :
2417 0 : bool SvxTableController::PasteObject( SdrTableObj* pPasteTableObj )
2418 : {
2419 0 : if( !pPasteTableObj )
2420 0 : return false;
2421 :
2422 0 : Reference< XTable > xPasteTable( pPasteTableObj->getTable() );
2423 0 : if( !xPasteTable.is() )
2424 0 : return false;
2425 :
2426 0 : if( !mxTable.is() )
2427 0 : return false;
2428 :
2429 0 : sal_Int32 nPasteColumns = xPasteTable->getColumnCount();
2430 0 : sal_Int32 nPasteRows = xPasteTable->getRowCount();
2431 :
2432 0 : CellPos aStart, aEnd;
2433 0 : getSelectedCells( aStart, aEnd );
2434 :
2435 0 : if( mpView->IsTextEdit() )
2436 0 : mpView->SdrEndTextEdit(sal_True);
2437 :
2438 0 : sal_Int32 nColumns = mxTable->getColumnCount();
2439 0 : sal_Int32 nRows = mxTable->getRowCount();
2440 :
2441 0 : const sal_Int32 nMissing = nPasteRows - ( nRows - aStart.mnRow );
2442 0 : if( nMissing > 0 )
2443 : {
2444 0 : Reference< XTableRows > xRows( mxTable->getRows() );
2445 0 : xRows->insertByIndex( nRows, nMissing );
2446 0 : nRows = mxTable->getRowCount();
2447 : }
2448 :
2449 0 : nPasteRows = std::min( nPasteRows, nRows - aStart.mnRow );
2450 0 : nPasteColumns = std::min( nPasteColumns, nColumns - aStart.mnCol );
2451 :
2452 : // copy cell contents
2453 0 : for( sal_Int32 nRow = 0; nRow < nPasteRows; ++nRow )
2454 : {
2455 0 : for( sal_Int32 nCol = 0; nCol < nPasteColumns; ++nCol )
2456 : {
2457 0 : CellRef xTargetCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( aStart.mnCol + nCol, aStart.mnRow + nRow ).get() ) );
2458 0 : if( xTargetCell.is() && !xTargetCell->isMerged() )
2459 : {
2460 0 : xTargetCell->AddUndo();
2461 0 : xTargetCell->cloneFrom( dynamic_cast< Cell* >( xPasteTable->getCellByPosition( nCol, nRow ).get() ) );
2462 0 : nCol += xTargetCell->getColumnSpan() - 1;
2463 : }
2464 0 : }
2465 : }
2466 :
2467 0 : UpdateTableShape();
2468 :
2469 0 : return true;
2470 : }
2471 :
2472 0 : bool SvxTableController::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& /*rFormatSet*/ )
2473 : {
2474 : // SdrView::TakeFormatPaintBrush() is enough
2475 0 : return false;
2476 : }
2477 :
2478 0 : bool SvxTableController::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
2479 : {
2480 0 : if( mbCellSelectionMode )
2481 : {
2482 0 : SdrTextObj* pTableObj = dynamic_cast<SdrTextObj*>( mxTableObj.get() );
2483 0 : if( !pTableObj )
2484 0 : return false;
2485 :
2486 0 : const bool bUndo = mpModel && mpModel->IsUndoEnabled();
2487 :
2488 0 : if( bUndo )
2489 0 : mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );
2490 :
2491 0 : CellPos aStart, aEnd;
2492 0 : getSelectedCells( aStart, aEnd );
2493 :
2494 0 : SfxItemSet aAttr(*rFormatSet.GetPool(), rFormatSet.GetRanges());
2495 0 : aAttr.Put(rFormatSet, sal_True);
2496 :
2497 0 : const bool bFrame = (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);
2498 :
2499 0 : if( bFrame )
2500 : {
2501 0 : aAttr.ClearItem( SDRATTR_TABLE_BORDER );
2502 0 : aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
2503 : }
2504 :
2505 0 : const sal_uInt16* pRanges = rFormatSet.GetRanges();
2506 0 : bool bTextOnly = true;
2507 :
2508 0 : while( *pRanges )
2509 : {
2510 0 : if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
2511 : {
2512 0 : bTextOnly = true;
2513 0 : break;
2514 : }
2515 0 : pRanges += 2;
2516 : }
2517 :
2518 0 : const bool bReplaceAll = false;
2519 0 : for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
2520 : {
2521 0 : for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
2522 : {
2523 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
2524 0 : if( xCell.is() )
2525 : {
2526 0 : if( bUndo )
2527 0 : xCell->AddUndo();
2528 0 : if( !bTextOnly )
2529 0 : xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
2530 :
2531 0 : SdrText* pText = static_cast< SdrText* >( xCell.get() );
2532 0 : mpView->ApplyFormatPaintBrushToText( rFormatSet, *pTableObj, pText, bNoCharacterFormats, bNoParagraphFormats );
2533 : }
2534 0 : }
2535 : }
2536 :
2537 0 : if( bFrame )
2538 : {
2539 0 : ApplyBorderAttr( rFormatSet );
2540 : }
2541 :
2542 0 : UpdateTableShape();
2543 :
2544 0 : if( bUndo )
2545 0 : mpModel->EndUndo();
2546 :
2547 0 : return true;
2548 :
2549 : }
2550 0 : return false;
2551 : }
2552 :
2553 :
2554 : // --------------------------------------------------------------------
2555 :
2556 0 : IMPL_LINK_NOARG(SvxTableController, UpdateHdl)
2557 : {
2558 0 : mnUpdateEvent = 0;
2559 :
2560 0 : if( mbCellSelectionMode )
2561 : {
2562 0 : CellPos aStart( maCursorFirstPos );
2563 0 : CellPos aEnd( maCursorLastPos );
2564 0 : checkCell(aStart);
2565 0 : checkCell(aEnd);
2566 0 : if( aStart != maCursorFirstPos || aEnd != maCursorLastPos )
2567 : {
2568 0 : setSelectedCells( aStart, aEnd );
2569 : }
2570 : }
2571 0 : updateSelectionOverlay();
2572 :
2573 0 : return 0;
2574 : }
2575 :
2576 63 : } }
2577 :
2578 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|