update ooo310-m15
[ooovba.git] / sc / source / ui / view / gridwin2.cxx
blob4434440b81eb78152c5b2f0b3baa038cf027115a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gridwin2.cxx,v $
10 * $Revision: 1.16.32.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <vcl/msgbox.hxx>
40 #include <vcl/sound.hxx>
42 #include "gridwin.hxx"
43 #include "tabvwsh.hxx"
44 #include "docsh.hxx"
45 #include "viewdata.hxx"
46 #include "pivot.hxx"
47 //CHINA001 #include "pfiltdlg.hxx"
48 #include "uiitems.hxx"
49 #include "scresid.hxx"
50 #include "sc.hrc"
51 #include "globstr.hrc"
52 #include "pagedata.hxx"
53 #include "dpobject.hxx"
54 #include "dpsave.hxx"
55 #include "dpoutput.hxx" // ScDPPositionData
56 #include "dpshttab.hxx"
57 #include "dbdocfun.hxx"
58 #include "dpcontrol.hxx"
59 #include "dpcontrol.hrc"
60 #include "strload.hxx"
61 #include "userlist.hxx"
63 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
64 #include "scabstdlg.hxx" //CHINA001
66 #include <vector>
67 #include <hash_map>
69 using namespace com::sun::star;
70 using ::std::vector;
71 using ::std::auto_ptr;
72 using ::std::hash_map;
73 using ::rtl::OUString;
74 using ::rtl::OUStringHash;
76 // STATIC DATA -----------------------------------------------------------
78 // -----------------------------------------------------------------------
80 BOOL ScGridWindow::HasPageFieldData( SCCOL nCol, SCROW nRow ) const
82 ScDocument* pDoc = pViewData->GetDocument();
83 SCTAB nTab = pViewData->GetTabNo();
84 ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
85 if ( pDPObj && nCol > 0 )
87 // look for the dimension header left of the drop-down arrow
88 USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
89 long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
90 if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
92 BOOL bIsDataLayout = FALSE;
93 String aFieldName = pDPObj->GetDimName( nField, bIsDataLayout );
94 if ( aFieldName.Len() && !bIsDataLayout )
95 return TRUE;
98 return FALSE;
101 // private method for mouse button handling
102 BOOL ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow )
104 if ( HasPageFieldData( nCol, nRow ) )
106 DoPageFieldMenue( nCol, nRow );
107 return TRUE;
109 return FALSE;
112 void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
114 ScDocument* pDoc = pViewData->GetDocument();
115 SCTAB nTab = pViewData->GetTabNo();
117 ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
119 #if OLD_PIVOT_IMPLEMENTATION
120 ScPivotCollection* pPivotCollection = pDoc->GetPivotCollection();
121 ScPivot* pPivot = pPivotCollection->GetPivotAtCursor(nCol, nRow, nTab);
123 if (pPivot) // alte Pivottabellen
125 if (pPivot->IsFilterAtCursor(nCol, nRow, nTab))
127 ReleaseMouse(); // falls schon beim ButtonDown gecaptured, #44018#
129 ScQueryParam aQueryParam;
130 pPivot->GetQuery(aQueryParam);
131 SCTAB nSrcTab = pPivot->GetSrcArea().aStart.Tab();
133 SfxItemSet aArgSet( pViewData->GetViewShell()->GetPool(),
134 SCITEM_QUERYDATA, SCITEM_QUERYDATA );
135 aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, pViewData, &aQueryParam ) );
137 //CHINA001 ScPivotFilterDlg* pDlg = new ScPivotFilterDlg(
138 //CHINA001 pViewData->GetViewShell()->GetDialogParent(),
139 //CHINA001 aArgSet, nSrcTab );
140 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
141 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
143 AbstractScPivotFilterDlg* pDlg = pFact->CreateScPivotFilterDlg( pViewData->GetViewShell()->GetDialogParent(),
144 aArgSet, nSrcTab,
145 RID_SCDLG_PIVOTFILTER);
146 DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
147 if ( pDlg->Execute() == RET_OK )
149 ScPivot* pNewPivot = pPivot->CreateNew();
151 const ScQueryItem& rQueryItem = pDlg->GetOutputItem();
152 pNewPivot->SetQuery(rQueryItem.GetQueryData());
154 PivotField* pColArr = new PivotField[PIVOT_MAXFIELD];
155 SCSIZE nColCount;
156 pPivot->GetColFields( pColArr, nColCount );
157 PivotField* pRowArr = new PivotField[PIVOT_MAXFIELD];
158 SCSIZE nRowCount;
159 pPivot->GetRowFields( pRowArr, nRowCount );
160 PivotField* pDataArr = new PivotField[PIVOT_MAXFIELD];
161 SCSIZE nDataCount;
162 pPivot->GetDataFields( pDataArr, nDataCount );
164 pNewPivot->SetColFields( pColArr, nColCount );
165 pNewPivot->SetRowFields( pRowArr, nRowCount );
166 pNewPivot->SetDataFields( pDataArr, nDataCount );
168 pNewPivot->SetName( pPivot->GetName() );
169 pNewPivot->SetTag( pPivot->GetTag() );
171 pViewData->GetDocShell()->PivotUpdate( pPivot, pNewPivot );
173 delete pDlg;
175 else
177 SCCOL nField;
178 if (pPivot->GetColFieldAtCursor(nCol, nRow, nTab, nField))
180 bPivotMouse = TRUE;
181 nPivotField = nField;
182 bPivotColField = TRUE;
183 nPivotCol = nCol;
184 pDragPivot = pPivot;
185 PivotTestMouse( rMEvt, TRUE );
186 // CaptureMouse();
187 StartTracking();
189 else if (pPivot->GetRowFieldAtCursor(nCol, nRow, nTab, nField))
191 bPivotMouse = TRUE;
192 nPivotField = nField;
193 bPivotColField = FALSE;
194 nPivotCol = nCol;
195 pDragPivot = pPivot;
196 PivotTestMouse( rMEvt, TRUE );
197 // CaptureMouse();
198 StartTracking();
202 #endif
204 if (pDPObj)
206 USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
207 ScAddress aPos( nCol, nRow, nTab );
208 long nField = pDPObj->GetHeaderDim( aPos, nOrient );
209 if ( nField >= 0 )
211 bDPMouse = TRUE;
212 nDPField = nField;
213 pDragDPObj = pDPObj;
215 if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj))
217 // field name pop up menu has been launched. Don't activate
218 // field move.
219 bDPMouse = false;
220 return;
223 DPTestMouse( rMEvt, TRUE );
224 StartTracking();
226 else if ( pDPObj->IsFilterButton(aPos) )
228 ReleaseMouse(); // may have been captured in ButtonDown
230 ScQueryParam aQueryParam;
231 SCTAB nSrcTab = 0;
232 const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
233 DBG_ASSERT(pDesc, "no sheet source for filter button");
234 if (pDesc)
236 aQueryParam = pDesc->aQueryParam;
237 nSrcTab = pDesc->aSourceRange.aStart.Tab();
240 SfxItemSet aArgSet( pViewData->GetViewShell()->GetPool(),
241 SCITEM_QUERYDATA, SCITEM_QUERYDATA );
242 aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, pViewData, &aQueryParam ) );
244 //CHINA001 ScPivotFilterDlg* pDlg = new ScPivotFilterDlg(
245 //CHINA001 pViewData->GetViewShell()->GetDialogParent(),
246 //CHINA001 aArgSet, nSrcTab );
247 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
248 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
250 AbstractScPivotFilterDlg* pDlg = pFact->CreateScPivotFilterDlg( pViewData->GetViewShell()->GetDialogParent(),
251 aArgSet, nSrcTab,
252 RID_SCDLG_PIVOTFILTER);
253 DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
254 if ( pDlg->Execute() == RET_OK )
256 ScSheetSourceDesc aNewDesc;
257 if (pDesc)
258 aNewDesc = *pDesc;
260 const ScQueryItem& rQueryItem = pDlg->GetOutputItem();
261 aNewDesc.aQueryParam = rQueryItem.GetQueryData();
263 ScDPObject aNewObj( *pDPObj );
264 aNewObj.SetSheetDesc( aNewDesc );
265 ScDBDocFunc aFunc( *pViewData->GetDocShell() );
266 aFunc.DataPilotUpdate( pDPObj, &aNewObj, TRUE, FALSE );
267 pViewData->GetView()->CursorPosChanged(); // shells may be switched
269 delete pDlg;
271 else
272 Sound::Beep();
274 else
276 DBG_ERROR("Da is ja garnix");
280 #if OLD_PIVOT_IMPLEMENTATION
281 void ScGridWindow::DoPivotDrop( BOOL bDelete, BOOL bToCols, SCSIZE nDestPos )
283 if ( nPivotField == PIVOT_DATA_FIELD && bDelete )
285 pViewData->GetView()->ErrorMessage(STR_PIVOT_MOVENOTALLOWED);
286 return;
289 if ( bPivotColField != bToCols && !bDelete )
291 SCSIZE nDestCount = bToCols ? pDragPivot->GetColFieldCount()
292 : pDragPivot->GetRowFieldCount();
293 if ( nDestCount >= PIVOT_MAXFIELD ) // schon voll?
295 // Versuch, mehr als PIVOT_MAXFIELD Eintraege zu erzeugen
296 pViewData->GetView()->ErrorMessage(STR_PIVOT_ERROR);
297 return;
301 PivotField* pColArr = new PivotField[PIVOT_MAXFIELD];
302 SCSIZE nColCount;
303 pDragPivot->GetColFields( pColArr, nColCount );
305 PivotField* pRowArr = new PivotField[PIVOT_MAXFIELD];
306 SCSIZE nRowCount;
307 pDragPivot->GetRowFields( pRowArr, nRowCount );
309 PivotField* pDataArr = new PivotField[PIVOT_MAXFIELD];
310 SCSIZE nDataCount;
311 pDragPivot->GetDataFields( pDataArr, nDataCount );
313 SCSIZE nOldPos = 0;
314 PivotField aMoveField;
316 PivotField* pSource = bPivotColField ? pColArr : pRowArr;
317 SCSIZE& rCount = bPivotColField ? nColCount : nRowCount;
319 BOOL bFound = FALSE;
320 for (SCSIZE i=0; i<rCount && !bFound; i++)
321 if (pSource[i].nCol == nPivotField)
323 nOldPos = i;
324 aMoveField = pSource[i];
325 --rCount;
326 if (i<rCount)
327 memmove( &pSource[i], &pSource[i+1], (rCount-i)*sizeof(PivotField) );
328 if ( bPivotColField == bToCols )
329 if (nDestPos > i)
330 --nDestPos;
331 bFound = TRUE;
334 if (bFound)
336 if (!bDelete)
338 PivotField* pDest = bToCols ? pColArr : pRowArr;
339 SCSIZE& rDestCount = bToCols ? nColCount : nRowCount;
341 if (nDestPos < rDestCount)
342 memmove( &pDest[nDestPos+1], &pDest[nDestPos],
343 (rDestCount-nDestPos)*sizeof(PivotField) );
344 pDest[nDestPos] = aMoveField;
345 ++rDestCount;
348 BOOL bEmpty = ( nColCount + nRowCount == 0 ||
349 ( nColCount + nRowCount == 1 && nDataCount <= 1 ) );
351 if ( bEmpty ) // Pivottabelle loeschen
353 pViewData->GetDocShell()->PivotUpdate( pDragPivot, NULL );
355 else
357 ScPivot* pNewPivot = pDragPivot->CreateNew();
358 pNewPivot->SetColFields( pColArr, nColCount );
359 pNewPivot->SetRowFields( pRowArr, nRowCount );
360 pNewPivot->SetDataFields( pDataArr, nDataCount );
362 pNewPivot->SetName( pDragPivot->GetName() );
363 pNewPivot->SetTag( pDragPivot->GetTag() );
365 pViewData->GetDocShell()->PivotUpdate( pDragPivot, pNewPivot );
367 pDragPivot = NULL;
369 else
371 DBG_ASSERT(0,"Pivot-Eintrag nicht gefunden");
374 delete[] pColArr;
375 delete[] pRowArr;
376 delete[] pDataArr;
379 BOOL ScGridWindow::PivotTestMouse( const MouseEvent& rMEvt, BOOL bMove )
381 BOOL bRet = FALSE;
382 BOOL bTimer = FALSE;
383 Point aPos = rMEvt.GetPosPixel();
385 SCsCOL nDx = 0;
386 SCsROW nDy = 0;
387 if ( aPos.X() < 0 )
388 nDx = -1;
389 if ( aPos.Y() < 0 )
390 nDy = -1;
391 Size aSize = GetOutputSizePixel();
392 if ( aPos.X() >= aSize.Width() )
393 nDx = 1;
394 if ( aPos.Y() >= aSize.Height() )
395 nDy = 1;
396 if ( nDx != 0 || nDy != 0 )
398 if (bDragRect)
400 // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
401 bDragRect = FALSE;
402 UpdateDragRectOverlay();
405 if ( nDx != 0 )
406 pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
407 if ( nDy != 0 )
408 pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
410 bTimer = TRUE;
413 SCsCOL nPosX;
414 SCsROW nPosY;
415 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
416 BOOL bMouseLeft;
417 BOOL bMouseTop;
418 pViewData->GetMouseQuadrant( aPos, eWhich, nPosX, nPosY, bMouseLeft, bMouseTop );
420 SCCOL nPiCol1;
421 SCROW nPiRow1;
422 SCCOL nPiCol2;
423 SCROW nPiRow2;
424 SCTAB nTab;
425 pDragPivot->GetDestArea( nPiCol1, nPiRow1, nPiCol2, nPiRow2, nTab );
427 if ( nPosX >= (SCsCOL) nPiCol1 && nPosX <= (SCsCOL) nPiCol2 &&
428 nPosY >= (SCsROW) nPiRow1 && nPosY <= (SCsROW) nPiRow2 )
430 SCsROW nFilterAdd = 2; // Platz fuer Filter-Button
431 SCsROW nColRows = 1; //! Ueberschrift: 0, wenn keine Zeilen, aber mehrere Datenfelder
432 SCCOL nNewStartX;
433 SCROW nNewStartY;
434 SCCOL nNewEndX;
435 SCROW nNewEndY;
437 SCsCOL nRelX = nPosX - (SCsCOL) nPiCol1;
438 SCsROW nRelY = nPosY - (SCsROW) nPiRow1 - nFilterAdd;
440 PivotField* pFieldArr = new PivotField[PIVOT_MAXFIELD];
441 SCSIZE nColCount;
442 pDragPivot->GetColFields( pFieldArr, nColCount );
443 SCSIZE nRowCount;
444 pDragPivot->GetRowFields( pFieldArr, nRowCount );
445 delete[] pFieldArr;
447 BOOL bBefore;
448 SCsCOL nColSize = static_cast<SCsCOL>(Max( nColCount, (SCSIZE) 1 ));
449 SCsROW nRowSize = static_cast<SCsROW>(Max( nRowCount, (SCSIZE) 1 ));
451 BOOL bToCols;
452 if (nRelX < nColSize && nRelY >= nRowSize)
453 bToCols = TRUE; // links
454 else if (nRelY < nRowSize && nRelX >= nColSize)
455 bToCols = FALSE; // oben
456 else
457 bToCols = ( nRelY-nRowSize > static_cast<SCsCOLROW>(nRelX-nColSize) );
459 SCsCOL nDestCol = 0;
460 SCsROW nDestRow = 0;
461 BOOL bNothing = FALSE;
463 if ( bToCols )
465 bBefore = bMouseLeft;
466 nDestCol = nRelX;
467 if (nDestCol < 0)
469 nDestCol = 0;
470 bBefore = TRUE;
472 if (nDestCol >= static_cast<SCsCOL>(nColCount))
474 nDestCol = static_cast<SCsCOL>(nColCount)-1;
475 bBefore = FALSE;
478 nNewStartY = nPiRow1 + nFilterAdd + static_cast<SCROW>(nRowCount) + nColRows;
479 nNewEndY = nPiRow2 - 1;
480 nNewStartX = nPiCol1 + (SCCOL) nDestCol;
481 nNewEndX = nNewStartX;
483 if ( !bPivotColField ) // von der anderen Seite
485 if (bBefore)
486 nNewEndX = nNewStartX - 1; // vor dem Feld
487 else
488 nNewStartX = nNewEndX + 1; // hinter dem Feld
490 else
492 SCCOL nThisCol = (SCCOL) nPosX; // absolute Spalte ( == Maus )
493 if ( nThisCol < nPivotCol )
495 nNewEndX = nNewStartX - 1; // vor dem Feld
496 bBefore = TRUE;
498 else if ( nThisCol > nPivotCol )
500 nNewStartX = nNewEndX + 1; // hinter dem Feld
501 bBefore = FALSE;
503 else
504 bNothing = TRUE;
506 SetPointer( Pointer( POINTER_PIVOT_ROW ) );
508 else
510 if (nRelY <= 0 && static_cast<SCsCOLROW>(nRelX) < static_cast<SCsCOLROW>(nColCount)+static_cast<SCsCOLROW>(nRowCount))
512 nDestRow = static_cast<SCsCOLROW>(nRelX) - static_cast<SCsCOLROW>(nColCount);
513 bBefore = bMouseLeft;
515 else
517 nDestRow = nRelY-1;
518 bBefore = bMouseTop;
520 if (nDestRow < 0)
522 nDestRow = 0;
523 bBefore = TRUE;
525 if (nDestRow >= static_cast<SCsROW>(nRowCount))
527 nDestRow = static_cast<SCsROW>(nRowCount)-1;
528 bBefore = FALSE;
531 nNewStartX = nPiCol1 + (SCCOL) nColCount;
532 nNewEndX = nPiCol2 - 1;
533 nNewStartY = nPiRow1 + nFilterAdd + nDestRow + nColRows;
534 nNewEndY = nNewStartY;
535 if ( bPivotColField ) // von der anderen Seite
537 if (bBefore)
538 nNewEndY = nNewStartY - 1; // vor dem Feld
539 else
540 nNewStartY = nNewEndY + 1; // hinter dem Feld
542 else
544 SCCOL nThisCol =
545 static_cast<SCCOL>(static_cast<SCCOLROW>(nDestRow) +
546 static_cast<SCCOLROW>(nColCount) + nPiCol1);
547 // absolute Spalte
548 if ( nThisCol < nPivotCol )
550 bBefore = TRUE;
551 nNewEndY = nNewStartY - 1; // vor dem Feld
553 else if ( nThisCol > nPivotCol )
555 bBefore = FALSE;
556 nNewStartY = nNewEndY + 1; // hinter dem Feld
558 else
559 bNothing = TRUE;
561 SetPointer( Pointer( POINTER_PIVOT_COL ) );
564 if (bMove)
566 if ( nNewStartX != nDragStartX || nNewEndX != nDragEndX ||
567 nNewStartY != nDragStartY || nNewEndY != nDragEndY || !bDragRect )
569 //if (bDragRect)
570 // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
572 nDragStartX = nNewStartX;
573 nDragStartY = nNewStartY;
574 nDragEndX = nNewEndX;
575 nDragEndY = nNewEndY;
576 bDragRect = TRUE;
578 // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
580 UpdateDragRectOverlay();
583 else
585 if (bDragRect)
587 // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
588 bDragRect = FALSE;
589 UpdateDragRectOverlay();
592 if (!bNothing)
594 SCSIZE nDestPos = bToCols ? static_cast<SCSIZE>(nDestCol) : static_cast<SCSIZE>(nDestRow);
595 if (!bBefore)
596 ++nDestPos;
597 DoPivotDrop( FALSE, bToCols, nDestPos );
601 bRet = TRUE;
603 else
605 if (bMove)
606 SetPointer( Pointer( POINTER_PIVOT_DELETE ) );
607 // if (bDragRect)
608 // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
609 bDragRect = FALSE;
610 UpdateDragRectOverlay();
612 if (!bMove)
613 DoPivotDrop( TRUE, FALSE,0 );
616 if (bTimer && bMove)
617 pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen
618 else
619 pViewData->GetView()->ResetTimer();
621 return bRet;
624 void ScGridWindow::PivotMouseMove( const MouseEvent& rMEvt )
626 PivotTestMouse( rMEvt, TRUE );
629 void ScGridWindow::PivotMouseButtonUp( const MouseEvent& rMEvt )
631 bPivotMouse = FALSE; // als erstes, falls PivotTestMouse eine Fehlermeldung bringt
632 ReleaseMouse();
634 PivotTestMouse( rMEvt, FALSE );
635 SetPointer( Pointer( POINTER_ARROW ) );
637 #endif
639 // -----------------------------------------------------------------------
641 // Data Pilot interaction
644 void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, BOOL bMove )
646 DBG_ASSERT(pDragDPObj, "pDragDPObj missing");
648 // scroll window if at edges
649 //! move this to separate method
651 BOOL bTimer = FALSE;
652 Point aPixel = rMEvt.GetPosPixel();
654 SCsCOL nDx = 0;
655 SCsROW nDy = 0;
656 if ( aPixel.X() < 0 )
657 nDx = -1;
658 if ( aPixel.Y() < 0 )
659 nDy = -1;
660 Size aSize = GetOutputSizePixel();
661 if ( aPixel.X() >= aSize.Width() )
662 nDx = 1;
663 if ( aPixel.Y() >= aSize.Height() )
664 nDy = 1;
665 if ( nDx != 0 || nDy != 0 )
667 UpdateDragRect( FALSE, Rectangle() );
669 if ( nDx != 0)
670 pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
671 if ( nDy != 0 )
672 pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
674 bTimer = TRUE;
677 // ---
679 SCsCOL nPosX;
680 SCsROW nPosY;
681 pViewData->GetPosFromPixel( aPixel.X(), aPixel.Y(), eWhich, nPosX, nPosY );
682 BOOL bMouseLeft;
683 BOOL bMouseTop;
684 pViewData->GetMouseQuadrant( aPixel, eWhich, nPosX, nPosY, bMouseLeft, bMouseTop );
686 ScAddress aPos( nPosX, nPosY, pViewData->GetTabNo() );
688 Rectangle aPosRect;
689 USHORT nOrient;
690 long nDimPos;
691 BOOL bHasRange = pDragDPObj->GetHeaderDrag( aPos, bMouseLeft, bMouseTop, nDPField,
692 aPosRect, nOrient, nDimPos );
693 UpdateDragRect( bHasRange && bMove, aPosRect );
695 if (bMove) // set mouse pointer
697 PointerStyle ePointer = POINTER_PIVOT_DELETE;
698 if ( bHasRange )
699 switch (nOrient)
701 case sheet::DataPilotFieldOrientation_COLUMN: ePointer = POINTER_PIVOT_COL; break;
702 case sheet::DataPilotFieldOrientation_ROW: ePointer = POINTER_PIVOT_ROW; break;
703 case sheet::DataPilotFieldOrientation_PAGE:
704 case sheet::DataPilotFieldOrientation_DATA: ePointer = POINTER_PIVOT_FIELD; break;
706 SetPointer( ePointer );
708 else // execute change
710 if (!bHasRange)
711 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
713 BOOL bIsDataLayout;
714 String aDimName = pDragDPObj->GetDimName( nDPField, bIsDataLayout );
715 if ( bIsDataLayout && ( nOrient != sheet::DataPilotFieldOrientation_COLUMN &&
716 nOrient != sheet::DataPilotFieldOrientation_ROW ) )
718 // removing data layout is not allowed
719 pViewData->GetView()->ErrorMessage(STR_PIVOT_MOVENOTALLOWED);
721 else
723 ScDPSaveData aSaveData( *pDragDPObj->GetSaveData() );
725 ScDPSaveDimension* pDim;
726 if ( bIsDataLayout )
727 pDim = aSaveData.GetDataLayoutDimension();
728 else
729 pDim = aSaveData.GetDimensionByName(aDimName);
730 pDim->SetOrientation( nOrient );
731 aSaveData.SetPosition( pDim, nDimPos );
733 //! docfunc method with ScDPSaveData as argument?
735 ScDPObject aNewObj( *pDragDPObj );
736 aNewObj.SetSaveData( aSaveData );
737 ScDBDocFunc aFunc( *pViewData->GetDocShell() );
738 // when dragging fields, allow re-positioning (bAllowMove)
739 aFunc.DataPilotUpdate( pDragDPObj, &aNewObj, TRUE, FALSE, TRUE );
740 pViewData->GetView()->CursorPosChanged(); // shells may be switched
744 if (bTimer && bMove)
745 pViewData->GetView()->SetTimer( this, rMEvt ); // repeat event
746 else
747 pViewData->GetView()->ResetTimer();
750 bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj)
752 // Get the geometry of the cell.
753 Point aSrcPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich);
754 long nSizeX, nSizeY;
755 pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
756 Size aSrcSize(nSizeX-1, nSizeY-1);
758 // Check if the mouse cursor is clicking on the popup arrow box.
759 ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings());
760 aBtn.setBoundingBox(aSrcPos, aSrcSize);
761 Point aPopupPos;
762 Size aPopupSize;
763 aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
764 Rectangle aRec(aPopupPos, aPopupSize);
765 if (aRec.IsInside(rMEvt.GetPosPixel()))
767 // Mouse cursor inside the popup arrow box. Launch the field menu.
768 DPLaunchFieldPopupMenu(OutputToScreenPixel(aSrcPos), aSrcSize, rPos, pDPObj);
769 return true;
772 return false;
775 namespace {
777 struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData
779 ScPivotParam maDPParam;
780 ScDPObject* mpDPObj;
781 long mnDim;
784 class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
786 public:
787 explicit DPFieldPopupOKAction(ScGridWindow* p) :
788 mpGridWindow(p) {}
790 virtual void execute()
792 mpGridWindow->UpdateDPFromFieldPopupMenu();
794 private:
795 ScGridWindow* mpGridWindow;
798 class PopupSortAction : public ScMenuFloatingWindow::Action
800 public:
801 enum SortType { ASCENDING, DESCENDING, CUSTOM };
803 explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
804 maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
806 virtual void execute()
808 switch (meType)
810 case ASCENDING:
811 mpViewShell->DataPilotSort(maPos, true);
812 break;
813 case DESCENDING:
814 mpViewShell->DataPilotSort(maPos, false);
815 break;
816 case CUSTOM:
817 mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
818 break;
819 default:
824 private:
825 ScAddress maPos;
826 SortType meType;
827 sal_uInt16 mnUserListIndex;
828 ScTabViewShell* mpViewShell;
833 void ScGridWindow::DPLaunchFieldPopupMenu(
834 const Point& rSrcPos, const Size& rSrcSize, const ScAddress& rPos, ScDPObject* pDPObj)
836 // We need to get the list of field members.
837 auto_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
838 pDPObj->FillLabelData(pDPData->maDPParam);
839 pDPData->mpDPObj = pDPObj;
841 USHORT nOrient;
842 pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
844 if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim))
845 // out-of-bound dimension ID. This should never happen!
846 return;
848 const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
850 mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this));
851 mpDPFieldPopup->setExtendedData(pDPData.release());
852 mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
854 sal_Int32 n = rLabelData.maMembers.getLength();
855 mpDPFieldPopup->setMemberSize(n);
856 for (sal_Int32 i = 0; i < n; ++i)
857 mpDPFieldPopup->addMember(rLabelData.maMembers[i], rLabelData.maVisible[i]);
858 mpDPFieldPopup->initMembers();
861 vector<OUString> aUserSortNames;
862 ScUserList* pUserList = ScGlobal::GetUserList();
863 if (pUserList)
865 sal_uInt16 n = pUserList->GetCount();
866 aUserSortNames.reserve(n);
867 for (sal_uInt16 i = 0; i < n; ++i)
869 ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[i]);
870 aUserSortNames.push_back(pData->GetString());
874 // Populate the menus.
875 ScTabViewShell* pViewShell = pViewData->GetViewShell();
876 mpDPFieldPopup->addMenuItem(
877 ScRscStrLoader(RID_SC_DPCONTROL, STR_MENU_SORT_ASC).GetString(), true,
878 new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
879 mpDPFieldPopup->addMenuItem(
880 ScRscStrLoader(RID_SC_DPCONTROL, STR_MENU_SORT_DESC).GetString(), true,
881 new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
882 ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
883 ScRscStrLoader(RID_SC_DPCONTROL, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty());
885 if (pSubMenu && !aUserSortNames.empty())
887 size_t n = aUserSortNames.size();
888 for (size_t i = 0; i < n; ++i)
890 pSubMenu->addMenuItem(
891 aUserSortNames[i], true,
892 new PopupSortAction(rPos, PopupSortAction::CUSTOM, i, pViewShell));
896 mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
897 Rectangle aCellRect(rSrcPos, rSrcSize);
898 mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS));
901 void ScGridWindow::UpdateDPFromFieldPopupMenu()
903 if (!mpDPFieldPopup.get())
904 return;
906 DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
907 if (!pDPData)
908 return;
910 ScDPObject* pDPObj = pDPData->mpDPObj;
911 ScDPObject aNewDPObj(*pDPObj);
912 aNewDPObj.BuildAllDimensionMembers();
913 ScDPSaveData* pSaveData = aNewDPObj.GetSaveData();
915 BOOL bIsDataLayout;
916 String aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
917 ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName);
918 if (!pDim)
919 return;
921 hash_map<OUString, bool, OUStringHash> aResult;
922 mpDPFieldPopup->getResult(aResult);
923 pDim->UpdateMemberVisibility(aResult);
925 ScDBDocFunc aFunc(*pViewData->GetDocShell());
926 aFunc.DataPilotUpdate(pDPObj, &aNewDPObj, true, false);
929 void ScGridWindow::DPMouseMove( const MouseEvent& rMEvt )
931 DPTestMouse( rMEvt, TRUE );
934 void ScGridWindow::DPMouseButtonUp( const MouseEvent& rMEvt )
936 bDPMouse = FALSE;
937 ReleaseMouse();
939 DPTestMouse( rMEvt, FALSE );
940 SetPointer( Pointer( POINTER_ARROW ) );
943 // -----------------------------------------------------------------------
945 void ScGridWindow::UpdateDragRect( BOOL bShowRange, const Rectangle& rPosRect )
947 SCCOL nStartX = ( rPosRect.Left() >= 0 ) ? static_cast<SCCOL>(rPosRect.Left()) : SCCOL_MAX;
948 SCROW nStartY = ( rPosRect.Top() >= 0 ) ? static_cast<SCROW>(rPosRect.Top()) : SCROW_MAX;
949 SCCOL nEndX = ( rPosRect.Right() >= 0 ) ? static_cast<SCCOL>(rPosRect.Right()) : SCCOL_MAX;
950 SCROW nEndY = ( rPosRect.Bottom() >= 0 ) ? static_cast<SCROW>(rPosRect.Bottom()) : SCROW_MAX;
952 if ( bShowRange == bDragRect && nDragStartX == nStartX && nDragEndX == nEndX &&
953 nDragStartY == nStartY && nDragEndY == nEndY )
955 return; // everything unchanged
958 // if ( bDragRect )
959 // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
960 if ( bShowRange )
962 nDragStartX = nStartX;
963 nDragStartY = nStartY;
964 nDragEndX = nEndX;
965 nDragEndY = nEndY;
966 bDragRect = TRUE;
967 // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, FALSE );
969 else
970 bDragRect = FALSE;
972 UpdateDragRectOverlay();
975 // -----------------------------------------------------------------------
977 // Page-Break-Modus
979 USHORT ScGridWindow::HitPageBreak( const Point& rMouse, ScRange* pSource,
980 SCCOLROW* pBreak, SCCOLROW* pPrev )
982 USHORT nFound = SC_PD_NONE; // 0
983 ScRange aSource;
984 SCCOLROW nBreak = 0;
985 SCCOLROW nPrev = 0;
987 ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData();
988 if ( pPageData )
990 BOOL bHori = FALSE;
991 BOOL bVert = FALSE;
992 SCCOL nHitX = 0;
993 SCROW nHitY = 0;
995 long nMouseX = rMouse.X();
996 long nMouseY = rMouse.Y();
997 SCsCOL nPosX;
998 SCsROW nPosY;
999 pViewData->GetPosFromPixel( nMouseX, nMouseY, eWhich, nPosX, nPosY );
1000 Point aTL = pViewData->GetScrPos( nPosX, nPosY, eWhich );
1001 Point aBR = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
1003 // Horizontal mehr Toleranz als vertikal, weil mehr Platz ist
1004 if ( nMouseX <= aTL.X() + 4 )
1006 bHori = TRUE;
1007 nHitX = nPosX;
1009 else if ( nMouseX >= aBR.X() - 6 )
1011 bHori = TRUE;
1012 nHitX = nPosX+1; // linker Rand der naechsten Zelle
1014 if ( nMouseY <= aTL.Y() + 2 )
1016 bVert = TRUE;
1017 nHitY = nPosY;
1019 else if ( nMouseY >= aBR.Y() - 4 )
1021 bVert = TRUE;
1022 nHitY = nPosY+1; // oberer Rand der naechsten Zelle
1025 if ( bHori || bVert )
1027 USHORT nCount = sal::static_int_cast<USHORT>( pPageData->GetCount() );
1028 for (USHORT nPos=0; nPos<nCount && !nFound; nPos++)
1030 ScPrintRangeData& rData = pPageData->GetData(nPos);
1031 ScRange aRange = rData.GetPrintRange();
1032 BOOL bLHit = ( bHori && nHitX == aRange.aStart.Col() );
1033 BOOL bRHit = ( bHori && nHitX == aRange.aEnd.Col() + 1 );
1034 BOOL bTHit = ( bVert && nHitY == aRange.aStart.Row() );
1035 BOOL bBHit = ( bVert && nHitY == aRange.aEnd.Row() + 1 );
1036 BOOL bInsideH = ( nPosX >= aRange.aStart.Col() && nPosX <= aRange.aEnd.Col() );
1037 BOOL bInsideV = ( nPosY >= aRange.aStart.Row() && nPosY <= aRange.aEnd.Row() );
1039 if ( bLHit )
1041 if ( bTHit )
1042 nFound = SC_PD_RANGE_TL;
1043 else if ( bBHit )
1044 nFound = SC_PD_RANGE_BL;
1045 else if ( bInsideV )
1046 nFound = SC_PD_RANGE_L;
1048 else if ( bRHit )
1050 if ( bTHit )
1051 nFound = SC_PD_RANGE_TR;
1052 else if ( bBHit )
1053 nFound = SC_PD_RANGE_BR;
1054 else if ( bInsideV )
1055 nFound = SC_PD_RANGE_R;
1057 else if ( bTHit && bInsideH )
1058 nFound = SC_PD_RANGE_T;
1059 else if ( bBHit && bInsideH )
1060 nFound = SC_PD_RANGE_B;
1061 if (nFound)
1062 aSource = aRange;
1064 // Umbrueche
1066 if ( bVert && bInsideH && !nFound )
1068 size_t nRowCount = rData.GetPagesY();
1069 const SCROW* pRowEnd = rData.GetPageEndY();
1070 for (size_t nRowPos=0; nRowPos+1<nRowCount; nRowPos++)
1071 if ( pRowEnd[nRowPos]+1 == nHitY )
1073 nFound = SC_PD_BREAK_V;
1074 aSource = aRange;
1075 nBreak = nHitY;
1076 if ( nRowPos )
1077 nPrev = pRowEnd[nRowPos-1]+1;
1078 else
1079 nPrev = aRange.aStart.Row();
1082 if ( bHori && bInsideV && !nFound )
1084 size_t nColCount = rData.GetPagesX();
1085 const SCCOL* pColEnd = rData.GetPageEndX();
1086 for (size_t nColPos=0; nColPos+1<nColCount; nColPos++)
1087 if ( pColEnd[nColPos]+1 == nHitX )
1089 nFound = SC_PD_BREAK_H;
1090 aSource = aRange;
1091 nBreak = nHitX;
1092 if ( nColPos )
1093 nPrev = pColEnd[nColPos-1]+1;
1094 else
1095 nPrev = aRange.aStart.Col();
1102 if (pSource)
1103 *pSource = aSource; // Druckbereich
1104 if (pBreak)
1105 *pBreak = nBreak; // X/Y Position des verchobenen Seitenumbruchs
1106 if (pPrev)
1107 *pPrev = nPrev; // X/Y Anfang der Seite, die am Umbruch zuende ist
1108 return nFound;
1111 void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp )
1113 //! Scrolling und Umschalten mit RFMouseMove zusammenfassen !
1114 //! (Weginvertieren vor dem Scrolling ist anders)
1116 // Scrolling
1118 BOOL bTimer = FALSE;
1119 Point aPos = rMEvt.GetPosPixel();
1120 SCsCOL nDx = 0;
1121 SCsROW nDy = 0;
1122 if ( aPos.X() < 0 ) nDx = -1;
1123 if ( aPos.Y() < 0 ) nDy = -1;
1124 Size aSize = GetOutputSizePixel();
1125 if ( aPos.X() >= aSize.Width() )
1126 nDx = 1;
1127 if ( aPos.Y() >= aSize.Height() )
1128 nDy = 1;
1129 if ( nDx != 0 || nDy != 0 )
1131 if ( bPagebreakDrawn ) // weginvertieren
1133 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
1134 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
1135 bPagebreakDrawn = FALSE;
1136 UpdateDragRectOverlay();
1139 if ( nDx != 0 ) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
1140 if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
1141 bTimer = TRUE;
1144 // Umschalten bei Fixierung (damit Scrolling funktioniert)
1146 if ( eWhich == pViewData->GetActivePart() ) //??
1148 if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
1149 if ( nDx > 0 )
1151 if ( eWhich == SC_SPLIT_TOPLEFT )
1152 pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
1153 else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
1154 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
1157 if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
1158 if ( nDy > 0 )
1160 if ( eWhich == SC_SPLIT_TOPLEFT )
1161 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
1162 else if ( eWhich == SC_SPLIT_TOPRIGHT )
1163 pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
1167 // ab hier neu
1169 // gesucht wird eine Position zwischen den Zellen (vor nPosX / nPosY)
1170 SCsCOL nPosX;
1171 SCsROW nPosY;
1172 pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1173 BOOL bLeft, bTop;
1174 pViewData->GetMouseQuadrant( aPos, eWhich, nPosX, nPosY, bLeft, bTop );
1175 if ( !bLeft ) ++nPosX;
1176 if ( !bTop ) ++nPosY;
1178 BOOL bBreak = ( nPagebreakMouse == SC_PD_BREAK_H || nPagebreakMouse == SC_PD_BREAK_V );
1179 BOOL bHide = FALSE;
1180 BOOL bToEnd = FALSE;
1181 ScRange aDrawRange = aPagebreakSource;
1182 if ( bBreak )
1184 if ( nPagebreakMouse == SC_PD_BREAK_H )
1186 if ( nPosX > aPagebreakSource.aStart.Col() &&
1187 nPosX <= aPagebreakSource.aEnd.Col() + 1 ) // ans Ende ist auch erlaubt
1189 bToEnd = ( nPosX == aPagebreakSource.aEnd.Col() + 1 );
1190 aDrawRange.aStart.SetCol( nPosX );
1191 aDrawRange.aEnd.SetCol( nPosX - 1 );
1193 else
1194 bHide = TRUE;
1196 else
1198 if ( nPosY > aPagebreakSource.aStart.Row() &&
1199 nPosY <= aPagebreakSource.aEnd.Row() + 1 ) // ans Ende ist auch erlaubt
1201 bToEnd = ( nPosY == aPagebreakSource.aEnd.Row() + 1 );
1202 aDrawRange.aStart.SetRow( nPosY );
1203 aDrawRange.aEnd.SetRow( nPosY - 1 );
1205 else
1206 bHide = TRUE;
1209 else
1211 if ( nPagebreakMouse & SC_PD_RANGE_L )
1212 aDrawRange.aStart.SetCol( nPosX );
1213 if ( nPagebreakMouse & SC_PD_RANGE_T )
1214 aDrawRange.aStart.SetRow( nPosY );
1215 if ( nPagebreakMouse & SC_PD_RANGE_R )
1217 if ( nPosX > 0 )
1218 aDrawRange.aEnd.SetCol( nPosX-1 );
1219 else
1220 bHide = TRUE;
1222 if ( nPagebreakMouse & SC_PD_RANGE_B )
1224 if ( nPosY > 0 )
1225 aDrawRange.aEnd.SetRow( nPosY-1 );
1226 else
1227 bHide = TRUE;
1229 if ( aDrawRange.aStart.Col() > aDrawRange.aEnd.Col() ||
1230 aDrawRange.aStart.Row() > aDrawRange.aEnd.Row() )
1231 bHide = TRUE;
1234 if ( !bPagebreakDrawn || bUp || aDrawRange != aPagebreakDrag )
1236 // zeichnen...
1238 if ( bPagebreakDrawn )
1240 // weginvertieren
1241 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
1242 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
1243 bPagebreakDrawn = FALSE;
1245 aPagebreakDrag = aDrawRange;
1246 if ( !bUp && !bHide )
1248 // hininvertieren
1249 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
1250 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), FALSE );
1251 bPagebreakDrawn = TRUE;
1253 UpdateDragRectOverlay();
1256 // bei ButtonUp die Aenderung ausfuehren
1258 if ( bUp )
1260 ScViewFunc* pViewFunc = pViewData->GetView();
1261 ScDocShell* pDocSh = pViewData->GetDocShell();
1262 ScDocument* pDoc = pDocSh->GetDocument();
1263 SCTAB nTab = pViewData->GetTabNo();
1264 BOOL bUndo (pDoc->IsUndoEnabled());
1266 if ( bBreak )
1268 BOOL bColumn = ( nPagebreakMouse == SC_PD_BREAK_H );
1269 SCCOLROW nNew = bColumn ? static_cast<SCCOLROW>(nPosX) : static_cast<SCCOLROW>(nPosY);
1270 if ( nNew != nPagebreakBreak )
1272 if (bUndo)
1274 String aUndo = ScGlobal::GetRscString( STR_UNDO_DRAG_BREAK );
1275 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
1278 BOOL bGrow = !bHide && nNew > nPagebreakBreak;
1279 if ( bColumn )
1281 if (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakBreak), nTab) & BREAK_MANUAL)
1283 ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab );
1284 pViewFunc->DeletePageBreak( TRUE, TRUE, &aOldAddr, FALSE );
1286 if ( !bHide && !bToEnd ) // am Ende nicht
1288 ScAddress aNewAddr( static_cast<SCCOL>(nNew), nPosY, nTab );
1289 pViewFunc->InsertPageBreak( TRUE, TRUE, &aNewAddr, FALSE );
1291 if ( bGrow )
1293 // vorigen Break auf hart, und Skalierung aendern
1294 bool bManualBreak = (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakPrev), nTab) & BREAK_MANUAL);
1295 if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && !bManualBreak )
1297 ScAddress aPrev( static_cast<SCCOL>(nPagebreakPrev), nPosY, nTab );
1298 pViewFunc->InsertPageBreak( TRUE, TRUE, &aPrev, FALSE );
1301 if (!pDocSh->AdjustPrintZoom( ScRange(
1302 static_cast<SCCOL>(nPagebreakPrev),0,nTab, static_cast<SCCOL>(nNew-1),0,nTab ) ))
1303 bGrow = FALSE;
1306 else
1308 if (pDoc->HasRowBreak(nPagebreakBreak, nTab) & BREAK_MANUAL)
1310 ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab );
1311 pViewFunc->DeletePageBreak( FALSE, TRUE, &aOldAddr, FALSE );
1313 if ( !bHide && !bToEnd ) // am Ende nicht
1315 ScAddress aNewAddr( nPosX, nNew, nTab );
1316 pViewFunc->InsertPageBreak( FALSE, TRUE, &aNewAddr, FALSE );
1318 if ( bGrow )
1320 // vorigen Break auf hart, und Skalierung aendern
1321 bool bManualBreak = (pDoc->HasRowBreak(nPagebreakPrev, nTab) & BREAK_MANUAL);
1322 if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak )
1324 ScAddress aPrev( nPosX, nPagebreakPrev, nTab );
1325 pViewFunc->InsertPageBreak( FALSE, TRUE, &aPrev, FALSE );
1328 if (!pDocSh->AdjustPrintZoom( ScRange(
1329 0,nPagebreakPrev,nTab, 0,nNew-1,nTab ) ))
1330 bGrow = FALSE;
1334 if (bUndo)
1336 pDocSh->GetUndoManager()->LeaveListAction();
1339 if (!bGrow) // sonst in AdjustPrintZoom schon passiert
1341 pViewFunc->UpdatePageBreakData( TRUE );
1342 pDocSh->SetDocumentModified();
1346 else if ( bHide || aPagebreakDrag != aPagebreakSource )
1348 // Druckbereich setzen
1350 String aNewRanges;
1351 USHORT nOldCount = pDoc->GetPrintRangeCount( nTab );
1352 if ( nOldCount )
1354 for (USHORT nPos=0; nPos<nOldCount; nPos++)
1356 const ScRange* pOld = pDoc->GetPrintRange( nTab, nPos );
1357 if ( pOld )
1359 String aTemp;
1360 if ( *pOld != aPagebreakSource )
1361 pOld->Format( aTemp, SCA_VALID );
1362 else if ( !bHide )
1363 aPagebreakDrag.Format( aTemp, SCA_VALID );
1364 if (aTemp.Len())
1366 if ( aNewRanges.Len() )
1367 aNewRanges += ';';
1368 aNewRanges += aTemp;
1373 else if (!bHide)
1374 aPagebreakDrag.Format( aNewRanges, SCA_VALID );
1376 pViewFunc->SetPrintRanges( pDoc->IsPrintEntireSheet( nTab ), &aNewRanges, NULL, NULL, FALSE );
1380 // Timer fuer Scrolling
1382 if (bTimer && !bUp)
1383 pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen
1384 else
1385 pViewData->GetView()->ResetTimer();