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 "scitems.hxx"
22 :
23 : #include <memory> //auto_ptr
24 : #include <editeng/adjustitem.hxx>
25 : #include <svx/algitem.hxx>
26 : #include <editeng/editview.hxx>
27 : #include <editeng/editstat.hxx>
28 : #include <editeng/flditem.hxx>
29 : #include <editeng/justifyitem.hxx>
30 : #include <svx/svdetc.hxx>
31 : #include <editeng/editobj.hxx>
32 : #include <sfx2/dispatch.hxx>
33 : #include <sfx2/viewfrm.hxx>
34 : #include <sfx2/docfile.hxx>
35 : #include <svl/stritem.hxx>
36 : #include <svtools/svtabbx.hxx>
37 : #include <svl/urlbmk.hxx>
38 : #include <vcl/cursor.hxx>
39 : #include <vcl/graph.hxx>
40 : #include <vcl/hatch.hxx>
41 : #include <sot/formats.hxx>
42 : #include <comphelper/classids.hxx>
43 : #include <sal/macros.h>
44 :
45 : #include <svx/svdview.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
46 : #include <editeng/outliner.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
47 : #include <svx/svditer.hxx>
48 : #include <svx/svdocapt.hxx>
49 : #include <svx/svdpagv.hxx>
50 :
51 : #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
52 : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
53 : #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
54 : #include <com/sun/star/sheet/DataPilotTableResultData.hpp>
55 : #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
56 : #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
57 : #include <com/sun/star/sheet/MemberResultFlags.hpp>
58 : #include <com/sun/star/awt/KeyModifier.hpp>
59 : #include <com/sun/star/awt/MouseButton.hpp>
60 : #include <com/sun/star/script/vba/VBAEventId.hpp>
61 : #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
62 :
63 : #include "gridwin.hxx"
64 : #include "tabvwsh.hxx"
65 : #include "docsh.hxx"
66 : #include "viewdata.hxx"
67 : #include "tabview.hxx"
68 : #include "select.hxx"
69 : #include "scmod.hxx"
70 : #include "document.hxx"
71 : #include "attrib.hxx"
72 : #include "dbdata.hxx"
73 : #include "stlpool.hxx"
74 : #include "printfun.hxx"
75 : #include "cbutton.hxx"
76 : #include "sc.hrc"
77 : #include "globstr.hrc"
78 : #include "editutil.hxx"
79 : #include "scresid.hxx"
80 : #include "inputhdl.hxx"
81 : #include "uiitems.hxx" // Filter-Dialog - auslagern !!!
82 : #include "filtdlg.hxx"
83 : #include "impex.hxx" // Sylk-ID fuer CB
84 : #include "formulacell.hxx" // fuer Edit-Felder
85 : #include "patattr.hxx"
86 : #include "notemark.hxx"
87 : #include "rfindlst.hxx"
88 : #include "docpool.hxx"
89 : #include "output.hxx"
90 : #include "docfunc.hxx"
91 : #include "dbdocfun.hxx"
92 : #include "dpobject.hxx"
93 : #include "dpoutput.hxx"
94 : #include "transobj.hxx"
95 : #include "drwtrans.hxx"
96 : #include "seltrans.hxx"
97 : #include "sizedev.hxx"
98 : #include "AccessibilityHints.hxx"
99 : #include "dpsave.hxx"
100 : #include "viewuno.hxx"
101 : #include "compiler.hxx"
102 : #include "editable.hxx"
103 : #include "fillinfo.hxx"
104 : #include "userdat.hxx"
105 : #include "drwlayer.hxx"
106 : #include "validat.hxx"
107 : #include "tabprotection.hxx"
108 : #include "postit.hxx"
109 : #include "dpcontrol.hxx"
110 : #include "checklistmenu.hxx"
111 : #include "clipparam.hxx"
112 : #include "cellsh.hxx"
113 : #include "overlayobject.hxx"
114 : #include "cellsuno.hxx"
115 : #include "drawview.hxx"
116 : #include "dragdata.hxx"
117 : #include "cliputil.hxx"
118 : #include "queryentry.hxx"
119 : #include "markdata.hxx"
120 : #include "checklistmenu.hrc"
121 : #include "strload.hxx"
122 : #include "externalrefmgr.hxx"
123 :
124 : #include <svx/sdrpagewindow.hxx>
125 : #include <svx/sdr/overlay/overlaymanager.hxx>
126 : #include <vcl/svapp.hxx>
127 : #include <svx/sdr/overlay/overlayselection.hxx>
128 :
129 : #include <vector>
130 : #include <boost/scoped_ptr.hpp>
131 :
132 : using namespace com::sun::star;
133 : using ::com::sun::star::uno::Sequence;
134 : using ::com::sun::star::uno::Any;
135 :
136 : const sal_uInt8 SC_NESTEDBUTTON_NONE = 0;
137 : const sal_uInt8 SC_NESTEDBUTTON_DOWN = 1;
138 : const sal_uInt8 SC_NESTEDBUTTON_UP = 2;
139 :
140 : #define SC_AUTOFILTER_ALL 0
141 : #define SC_AUTOFILTER_TOP10 1
142 : #define SC_AUTOFILTER_CUSTOM 2
143 : #define SC_AUTOFILTER_EMPTY 3
144 : #define SC_AUTOFILTER_NOTEMPTY 4
145 :
146 : // Modi fuer die FilterListBox
147 : enum ScFilterBoxMode
148 : {
149 : SC_FILTERBOX_FILTER,
150 : SC_FILTERBOX_DATASELECT,
151 : SC_FILTERBOX_SCENARIO,
152 : SC_FILTERBOX_PAGEFIELD
153 : };
154 :
155 : extern SfxViewShell* pScActiveViewShell; // global.cxx
156 : extern sal_uInt16 nScClickMouseModifier; // global.cxx
157 : extern sal_uInt16 nScFillModeMouseModifier; // global.cxx
158 :
159 : struct ScGridWindow::MouseEventState
160 : {
161 : bool mbActivatePart;
162 :
163 0 : MouseEventState() : mbActivatePart(false) {}
164 : };
165 :
166 : #define SC_FILTERLISTBOX_LINES 12
167 :
168 : // ============================================================================
169 :
170 206 : ScGridWindow::VisibleRange::VisibleRange() :
171 206 : mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW)
172 : {
173 206 : }
174 :
175 3752 : bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const
176 : {
177 3752 : return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2;
178 : }
179 :
180 : // ============================================================================
181 :
182 : class ScFilterListBox : public ListBox
183 : {
184 : private:
185 : ScGridWindow* pGridWin;
186 : SCCOL nCol;
187 : SCROW nRow;
188 : sal_Bool bButtonDown;
189 : sal_Bool bInit;
190 : sal_Bool bCancelled;
191 : sal_Bool bInSelect;
192 : bool mbListHasDates;
193 : sal_uLong nSel;
194 : ScFilterBoxMode eMode;
195 :
196 : protected:
197 : virtual void LoseFocus();
198 : void SelectHdl();
199 :
200 : public:
201 : ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
202 : SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode );
203 : ~ScFilterListBox();
204 :
205 : virtual long PreNotify( NotifyEvent& rNEvt );
206 : virtual void Select();
207 :
208 0 : SCCOL GetCol() const { return nCol; }
209 0 : SCROW GetRow() const { return nRow; }
210 0 : ScFilterBoxMode GetMode() const { return eMode; }
211 : sal_Bool IsDataSelect() const { return (eMode == SC_FILTERBOX_DATASELECT); }
212 : void EndInit();
213 0 : sal_Bool IsInInit() const { return bInit; }
214 0 : void SetCancelled() { bCancelled = sal_True; }
215 0 : sal_Bool IsInSelect() const { return bInSelect; }
216 0 : void SetListHasDates(bool b) { mbListHasDates = b; }
217 0 : bool HasDates() const { return mbListHasDates; }
218 : };
219 :
220 : //-------------------------------------------------------------------
221 :
222 : // ListBox in einem FloatingWindow (pParent)
223 0 : ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
224 : SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) :
225 : ListBox( pParent, WB_AUTOHSCROLL ),
226 : pGridWin( pGrid ),
227 : nCol( nNewCol ),
228 : nRow( nNewRow ),
229 : bButtonDown( false ),
230 : bInit( sal_True ),
231 : bCancelled( false ),
232 : bInSelect( false ),
233 : mbListHasDates(false),
234 : nSel( 0 ),
235 0 : eMode( eNewMode )
236 : {
237 0 : }
238 :
239 0 : ScFilterListBox::~ScFilterListBox()
240 : {
241 0 : if (IsMouseCaptured())
242 0 : ReleaseMouse();
243 0 : }
244 :
245 0 : void ScFilterListBox::EndInit()
246 : {
247 0 : sal_uInt16 nPos = GetSelectEntryPos();
248 0 : if ( LISTBOX_ENTRY_NOTFOUND == nPos )
249 0 : nSel = 0;
250 : else
251 0 : nSel = nPos;
252 :
253 0 : bInit = false;
254 0 : }
255 :
256 0 : void ScFilterListBox::LoseFocus()
257 : {
258 : #ifndef UNX
259 : Hide();
260 : #endif
261 0 : }
262 :
263 : // -----------------------------------------------------------------------
264 :
265 0 : long ScFilterListBox::PreNotify( NotifyEvent& rNEvt )
266 : {
267 0 : long nDone = 0;
268 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
269 : {
270 0 : KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
271 0 : KeyCode aCode = aKeyEvt.GetKeyCode();
272 0 : if ( !aCode.GetModifier() ) // ohne alle Modifiers
273 : {
274 0 : sal_uInt16 nKey = aCode.GetCode();
275 0 : if ( nKey == KEY_RETURN )
276 : {
277 0 : SelectHdl(); // auswaehlen
278 0 : nDone = 1;
279 : }
280 0 : else if ( nKey == KEY_ESCAPE )
281 : {
282 0 : pGridWin->ClickExtern(); // loescht die List-Box !!!
283 0 : nDone = 1;
284 : }
285 : }
286 : }
287 :
288 0 : return nDone ? nDone : ListBox::PreNotify( rNEvt );
289 : }
290 :
291 0 : void ScFilterListBox::Select()
292 : {
293 0 : ListBox::Select();
294 0 : SelectHdl();
295 0 : }
296 :
297 0 : void ScFilterListBox::SelectHdl()
298 : {
299 0 : if ( !IsTravelSelect() && !bInit && !bCancelled )
300 : {
301 0 : sal_uInt16 nPos = GetSelectEntryPos();
302 0 : if ( LISTBOX_ENTRY_NOTFOUND != nPos )
303 : {
304 0 : nSel = nPos;
305 0 : if (!bButtonDown)
306 : {
307 : // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
308 0 : bInSelect = sal_True;
309 0 : pGridWin->FilterSelect( nSel );
310 0 : bInSelect = false;
311 : }
312 : }
313 : }
314 0 : }
315 :
316 : // ============================================================================
317 :
318 : // use a System floating window for the above filter listbox
319 : class ScFilterFloatingWindow : public FloatingWindow
320 : {
321 : public:
322 : ScFilterFloatingWindow( Window* pParent, WinBits nStyle = WB_STDFLOATWIN );
323 : virtual ~ScFilterFloatingWindow();
324 : // required for System FloatingWindows that will not process KeyInput by themselves
325 : virtual Window* GetPreferredKeyInputWindow();
326 : };
327 :
328 0 : ScFilterFloatingWindow::ScFilterFloatingWindow( Window* pParent, WinBits nStyle ) :
329 0 : FloatingWindow( pParent, nStyle|WB_SYSTEMWINDOW ) // make it a system floater
330 0 : {}
331 :
332 0 : ScFilterFloatingWindow::~ScFilterFloatingWindow()
333 : {
334 0 : EndPopupMode();
335 0 : }
336 :
337 0 : Window* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
338 : {
339 : // redirect keyinput in the child window
340 0 : return GetWindow(WINDOW_FIRSTCHILD) ? GetWindow(WINDOW_FIRSTCHILD)->GetPreferredKeyInputWindow() : NULL; // will be the FilterBox
341 : }
342 :
343 : // ============================================================================
344 :
345 0 : static sal_Bool lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange )
346 : {
347 : // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
348 : // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
349 : //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
350 :
351 0 : if ( !pDoc->IsBlockEditable( rRange.aStart.Tab(), rRange.aStart.Col(),rRange.aStart.Row(),
352 0 : rRange.aEnd.Col(),rRange.aEnd.Row() ) )
353 0 : return false;
354 :
355 0 : ScRefCellValue aCell;
356 0 : aCell.assign(*pDoc, rRange.aEnd);
357 0 : ScAddress aPos;
358 0 : return (aCell.meType == CELLTYPE_FORMULA && aCell.mpFormula->GetMatrixOrigin(aPos) && aPos == rRange.aStart);
359 : }
360 :
361 0 : static void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const Point& rPos, ScViewData* pViewData )
362 : {
363 0 : if (!pView && !pPV && !pDrDoc && !pViewData)
364 0 : return;
365 :
366 0 : ScDocument& rDoc = *pViewData->GetDocument();
367 0 : ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
368 0 : ScPostIt* pNote = rDoc.GetNotes( aCellPos.Tab() )->findByAddress( aCellPos );
369 0 : SdrObject* pObj = pNote ? pNote->GetCaption() : 0;
370 0 : if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) )
371 : {
372 0 : const ScProtectionAttr* pProtAttr = static_cast< const ScProtectionAttr* > (rDoc.GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ) );
373 0 : bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell() ;
374 0 : bool bProtectDoc = rDoc.IsTabProtected( aCellPos.Tab() ) || pViewData->GetSfxDocShell()->IsReadOnly() ;
375 : // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
376 0 : pView->LockInternalLayer( bProtectDoc && bProtectAttr );
377 : }
378 : }
379 :
380 0 : static bool lcl_GetHyperlinkCell(
381 : ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScRefCellValue& rCell, OUString& rURL )
382 : {
383 0 : bool bFound = false;
384 0 : do
385 : {
386 0 : ScAddress aPos(rPosX, rPosY, nTab);
387 0 : rCell.assign(*pDoc, aPos);
388 0 : if (rCell.isEmpty())
389 : {
390 0 : if ( rPosX <= 0 )
391 0 : return false; // alles leer bis links
392 : else
393 0 : --rPosX; // weitersuchen
394 : }
395 : else
396 : {
397 0 : const ScPatternAttr* pPattern = pDoc->GetPattern(aPos);
398 0 : if ( !((SfxStringItem&)pPattern->GetItem(ATTR_HYPERLINK)).GetValue().isEmpty() )
399 : {
400 0 : rURL = ((SfxStringItem&)pPattern->GetItem(ATTR_HYPERLINK)).GetValue();
401 0 : bFound = true;
402 : }
403 0 : else if (rCell.meType == CELLTYPE_EDIT)
404 0 : bFound = true;
405 0 : else if (rCell.meType == CELLTYPE_FORMULA && rCell.mpFormula->IsHyperLinkCell())
406 0 : bFound = true;
407 : else
408 0 : return false; // andere Zelle
409 : }
410 : }
411 0 : while ( !bFound );
412 :
413 0 : return bFound;
414 : }
415 :
416 : // ---------------------------------------------------------------------------
417 : // WB_DIALOGCONTROL noetig fuer UNO-Controls
418 206 : ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos )
419 : : Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ),
420 : DropTargetHelper( this ),
421 : DragSourceHelper( this ),
422 : mpOOCursors( NULL ),
423 : mpOOSelection( NULL ),
424 : mpOOSelectionBorder( NULL ),
425 : mpOOAutoFill( NULL ),
426 : mpOODragRect( NULL ),
427 : mpOOHeader( NULL ),
428 : mpOOShrink( NULL ),
429 : mpAutoFillRect(static_cast<Rectangle*>(NULL)),
430 : pViewData( pData ),
431 : eWhich( eWhichPos ),
432 : pNoteMarker( NULL ),
433 : pFilterBox( NULL ),
434 : pFilterFloat( NULL ),
435 : mpAutoFilterPopup(NULL),
436 : mpDPFieldPopup(NULL),
437 : mpFilterButton(NULL),
438 : nCursorHideCount( 0 ),
439 : nButtonDown( 0 ),
440 : nMouseStatus( SC_GM_NONE ),
441 : nNestedButtonState( SC_NESTEDBUTTON_NONE ),
442 : nPagebreakMouse( SC_PD_NONE ),
443 : nPageScript( 0 ),
444 : nDragStartX( -1 ),
445 : nDragStartY( -1 ),
446 : nDragEndX( -1 ),
447 : nDragEndY( -1 ),
448 : meDragInsertMode( INS_NONE ),
449 : nCurrentPointer( 0 ),
450 : aComboButton( this ),
451 : aCurMousePos( 0,0 ),
452 : nPaintCount( 0 ),
453 : bEEMouse( false ),
454 : bDPMouse( false ),
455 : bRFMouse( false ),
456 : bRFSize( false ),
457 : bPagebreakDrawn( false ),
458 : bDragRect( false ),
459 : bIsInScroll( false ),
460 : bIsInPaint( false ),
461 : bNeedsRepaint( false ),
462 : bAutoMarkVisible( false ),
463 206 : bListValButton( false )
464 : {
465 206 : switch(eWhich)
466 : {
467 : case SC_SPLIT_TOPLEFT:
468 1 : eHWhich = SC_SPLIT_LEFT;
469 1 : eVWhich = SC_SPLIT_TOP;
470 1 : break;
471 : case SC_SPLIT_TOPRIGHT:
472 1 : eHWhich = SC_SPLIT_RIGHT;
473 1 : eVWhich = SC_SPLIT_TOP;
474 1 : break;
475 : case SC_SPLIT_BOTTOMLEFT:
476 203 : eHWhich = SC_SPLIT_LEFT;
477 203 : eVWhich = SC_SPLIT_BOTTOM;
478 203 : break;
479 : case SC_SPLIT_BOTTOMRIGHT:
480 1 : eHWhich = SC_SPLIT_RIGHT;
481 1 : eVWhich = SC_SPLIT_BOTTOM;
482 1 : break;
483 : default:
484 : OSL_FAIL("GridWindow: falsche Position");
485 : }
486 :
487 206 : SetBackground();
488 :
489 206 : SetMapMode(pViewData->GetLogicMode(eWhich));
490 206 : EnableChildTransparentMode();
491 206 : SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS );
492 :
493 206 : SetHelpId( HID_SC_WIN_GRIDWIN );
494 206 : SetUniqueId( HID_SC_WIN_GRIDWIN );
495 :
496 206 : SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
497 206 : EnableRTL( false );
498 206 : }
499 :
500 612 : ScGridWindow::~ScGridWindow()
501 : {
502 : // #114409#
503 204 : ImpDestroyOverlayObjects();
504 :
505 204 : delete pFilterBox;
506 204 : delete pFilterFloat;
507 204 : delete pNoteMarker;
508 408 : }
509 :
510 0 : void ScGridWindow::Resize( const Size& )
511 : {
512 : // gar nix
513 0 : }
514 :
515 1663 : void ScGridWindow::ClickExtern()
516 : {
517 : do
518 : {
519 : // #i81298# don't delete the filter box when called from its select handler
520 : // (possible through row header size update)
521 : // #i84277# when initializing the filter box, a Basic error can deactivate the view
522 1663 : if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
523 : {
524 0 : break;
525 : }
526 :
527 1663 : DELETEZ(pFilterBox);
528 1663 : DELETEZ(pFilterFloat);
529 : }
530 : while (false);
531 :
532 1663 : if (mpDPFieldPopup)
533 : {
534 0 : mpDPFieldPopup->close(false);
535 0 : mpDPFieldPopup.reset();
536 : }
537 1663 : }
538 :
539 0 : IMPL_LINK_NOARG(ScGridWindow, PopupModeEndHdl)
540 : {
541 0 : if (pFilterBox)
542 0 : pFilterBox->SetCancelled(); // nicht mehr auswaehlen
543 0 : GrabFocus();
544 0 : return 0;
545 : }
546 :
547 0 : IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo*, pInfo )
548 : {
549 0 : if( pInfo->nCommand == SPELLCMD_STARTSPELLDLG )
550 0 : pViewData->GetDispatcher().Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
551 0 : return 0;
552 : }
553 :
554 0 : void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, sal_Bool bHasSelection, const String& rStr )
555 : {
556 : //! gridwin2 ?
557 :
558 0 : ScDocument* pDoc = pViewData->GetDocument();
559 0 : SCTAB nTab = pViewData->GetTabNo();
560 0 : ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
561 0 : if ( pDPObj && nCol > 0 )
562 : {
563 : // look for the dimension header left of the drop-down arrow
564 0 : sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
565 0 : long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
566 0 : if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
567 : {
568 0 : ScDPSaveData aSaveData( *pDPObj->GetSaveData() );
569 :
570 : bool bIsDataLayout;
571 0 : OUString aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
572 0 : if ( !bIsDataLayout )
573 : {
574 0 : ScDPSaveDimension* pDim = aSaveData.GetDimensionByName(aDimName);
575 :
576 0 : if ( bHasSelection )
577 : {
578 0 : const OUString aName = rStr;
579 0 : pDim->SetCurrentPage( &aName );
580 : }
581 : else
582 0 : pDim->SetCurrentPage( NULL );
583 :
584 0 : ScDPObject aNewObj( *pDPObj );
585 0 : aNewObj.SetSaveData( aSaveData );
586 0 : ScDBDocFunc aFunc( *pViewData->GetDocShell() );
587 0 : aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, false );
588 0 : pViewData->GetView()->CursorPosChanged(); // shells may be switched
589 0 : }
590 : }
591 : }
592 0 : }
593 :
594 : namespace {
595 :
596 0 : struct AutoFilterData : public ScCheckListMenuWindow::ExtendedData
597 : {
598 : ScAddress maPos;
599 : ScDBData* mpData;
600 : };
601 :
602 0 : class AutoFilterAction : public ScMenuFloatingWindow::Action
603 : {
604 : ScGridWindow* mpWindow;
605 : ScGridWindow::AutoFilterMode meMode;
606 : public:
607 0 : AutoFilterAction(ScGridWindow* p, ScGridWindow::AutoFilterMode eMode) :
608 0 : mpWindow(p), meMode(eMode) {}
609 0 : virtual void execute()
610 : {
611 0 : mpWindow->UpdateAutoFilterFromMenu(meMode);
612 0 : }
613 : };
614 :
615 0 : class AutoFilterPopupEndAction : public ScMenuFloatingWindow::Action
616 : {
617 : ScGridWindow* mpWindow;
618 : ScAddress maPos;
619 : public:
620 0 : AutoFilterPopupEndAction(ScGridWindow* p, const ScAddress& rPos) :
621 0 : mpWindow(p), maPos(rPos) {}
622 0 : virtual void execute()
623 : {
624 0 : mpWindow->RefreshAutoFilterButton(maPos);
625 0 : }
626 : };
627 :
628 : class AddItemToEntry : public std::unary_function<OUString, void>
629 : {
630 : ScQueryEntry::QueryItemsType& mrItems;
631 : public:
632 0 : AddItemToEntry(ScQueryEntry::QueryItemsType& rItems) : mrItems(rItems) {}
633 0 : void operator() (const OUString& rSelected)
634 : {
635 0 : ScQueryEntry::Item aNew;
636 0 : aNew.maString = rSelected;
637 0 : aNew.meType = ScQueryEntry::ByString;
638 0 : aNew.mfVal = 0.0;
639 0 : mrItems.push_back(aNew);
640 0 : }
641 : };
642 :
643 : class AddSelectedItemString : public std::unary_function<ScQueryEntry::Item, void>
644 : {
645 : boost::unordered_set<OUString, OUStringHash>& mrSet;
646 : public:
647 0 : AddSelectedItemString(boost::unordered_set<OUString, OUStringHash>& r) :
648 0 : mrSet(r) {}
649 :
650 0 : void operator() (const ScQueryEntry::Item& rItem)
651 : {
652 0 : mrSet.insert(rItem.maString);
653 0 : }
654 : };
655 :
656 : }
657 :
658 0 : void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
659 : {
660 0 : SCTAB nTab = pViewData->GetTabNo();
661 0 : ScDocument* pDoc = pViewData->GetDocument();
662 :
663 0 : mpAutoFilterPopup.reset(new ScCheckListMenuWindow(this, pDoc));
664 0 : mpAutoFilterPopup->setOKAction(new AutoFilterAction(this, Normal));
665 : mpAutoFilterPopup->setPopupEndAction(
666 0 : new AutoFilterPopupEndAction(this, ScAddress(nCol, nRow, nTab)));
667 0 : std::auto_ptr<AutoFilterData> pData(new AutoFilterData);
668 0 : pData->maPos = ScAddress(nCol, nRow, nTab);
669 :
670 0 : Point aPos = pViewData->GetScrPos(nCol, nRow, eWhich);
671 0 : long nSizeX = 0;
672 0 : long nSizeY = 0;
673 0 : pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
674 0 : Rectangle aCellRect(OutputToScreenPixel(aPos), Size(nSizeX, nSizeY));
675 :
676 0 : ScDBData* pDBData = pDoc->GetDBAtCursor(nCol, nRow, nTab);
677 0 : if (!pDBData)
678 0 : return;
679 :
680 0 : pData->mpData = pDBData;
681 0 : mpAutoFilterPopup->setExtendedData(pData.release());
682 :
683 0 : ScQueryParam aParam;
684 0 : pDBData->GetQueryParam(aParam);
685 0 : ScQueryEntry* pEntry = aParam.FindEntryByField(nCol, false);
686 0 : boost::unordered_set<OUString, OUStringHash> aSelected;
687 0 : if (pEntry && pEntry->bDoQuery)
688 : {
689 0 : if (pEntry->eOp == SC_EQUAL)
690 : {
691 0 : ScQueryEntry::QueryItemsType& rItems = pEntry->GetQueryItems();
692 0 : std::for_each(rItems.begin(), rItems.end(), AddSelectedItemString(aSelected));
693 : }
694 : }
695 :
696 : // Populate the check box list.
697 0 : bool bHasDates = false;
698 0 : std::vector<ScTypedStrData> aStrings;
699 0 : pDoc->GetFilterEntries(nCol, nRow, nTab, true, aStrings, bHasDates);
700 :
701 0 : mpAutoFilterPopup->setMemberSize(aStrings.size());
702 0 : std::vector<ScTypedStrData>::const_iterator it = aStrings.begin(), itEnd = aStrings.end();
703 0 : for (; it != itEnd; ++it)
704 : {
705 0 : const OUString& aVal = it->GetString();
706 0 : bool bSelected = true;
707 0 : if (!aSelected.empty())
708 0 : bSelected = aSelected.count(aVal) > 0;
709 0 : mpAutoFilterPopup->addMember(aVal, bSelected);
710 : }
711 0 : mpAutoFilterPopup->initMembers();
712 :
713 : // Populate the menu.
714 0 : mpAutoFilterPopup->addMenuItem(
715 0 : ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(),
716 0 : true, new AutoFilterAction(this, SortAscending));
717 0 : mpAutoFilterPopup->addMenuItem(
718 0 : ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(),
719 0 : true, new AutoFilterAction(this, SortDescending));
720 0 : mpAutoFilterPopup->addSeparator();
721 0 : mpAutoFilterPopup->addMenuItem(
722 0 : SC_RESSTR(SCSTR_TOP10FILTER), true, new AutoFilterAction(this, Top10));
723 0 : mpAutoFilterPopup->addMenuItem(
724 0 : SC_RESSTR(SCSTR_FILTER_EMPTY), true, new AutoFilterAction(this, Empty));
725 0 : mpAutoFilterPopup->addMenuItem(
726 0 : SC_RESSTR(SCSTR_FILTER_NOTEMPTY), true, new AutoFilterAction(this, NonEmpty));
727 0 : mpAutoFilterPopup->addSeparator();
728 0 : mpAutoFilterPopup->addMenuItem(
729 0 : SC_RESSTR(SCSTR_STDFILTER), true, new AutoFilterAction(this, Custom));
730 :
731 0 : ScCheckListMenuWindow::Config aConfig;
732 0 : aConfig.mbAllowEmptySet = false;
733 0 : aConfig.mbRTL = pViewData->GetDocument()->IsLayoutRTL(pViewData->GetTabNo());
734 0 : mpAutoFilterPopup->setConfig(aConfig);
735 0 : mpAutoFilterPopup->launch(aCellRect);
736 : }
737 :
738 0 : void ScGridWindow::RefreshAutoFilterButton(const ScAddress& rPos)
739 : {
740 0 : if (mpFilterButton)
741 : {
742 0 : bool bFilterActive = IsAutoFilterActive(rPos.Col(), rPos.Row(), rPos.Tab());
743 0 : mpFilterButton->setHasHiddenMember(bFilterActive);
744 0 : mpFilterButton->setPopupPressed(false);
745 0 : mpFilterButton->draw();
746 : }
747 0 : }
748 :
749 0 : void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
750 : {
751 : const AutoFilterData* pData =
752 0 : static_cast<const AutoFilterData*>(mpAutoFilterPopup->getExtendedData());
753 :
754 0 : if (!pData)
755 0 : return;
756 :
757 0 : const ScAddress& rPos = pData->maPos;
758 0 : ScDBData* pDBData = pData->mpData;
759 0 : if (!pDBData)
760 0 : return;
761 :
762 0 : switch (eMode)
763 : {
764 : case SortAscending:
765 : case SortDescending:
766 : {
767 0 : ScDocument* pDoc = pViewData->GetDocument();
768 0 : SCTAB nTab = pViewData->GetTabNo();
769 0 : SCCOL nCol = rPos.Col();
770 0 : ScSortParam aSortParam;
771 0 : pDBData->GetSortParam(aSortParam);
772 0 : if (nCol < aSortParam.nCol1 || nCol > aSortParam.nCol2)
773 : // out of bound
774 0 : return;
775 :
776 : bool bHasHeader = pDoc->HasColHeader(
777 0 : aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, nTab);
778 :
779 0 : aSortParam.bHasHeader = bHasHeader;
780 0 : aSortParam.bByRow = true;
781 0 : aSortParam.bCaseSens = false;
782 0 : aSortParam.bNaturalSort = false;
783 0 : aSortParam.bIncludePattern = true;
784 0 : aSortParam.bInplace = true;
785 0 : aSortParam.maKeyState[0].bDoSort = true;
786 0 : aSortParam.maKeyState[0].nField = nCol;
787 0 : aSortParam.maKeyState[0].bAscending = (eMode == SortAscending);
788 :
789 0 : for (size_t i = 1; i < aSortParam.GetSortKeyCount(); ++i)
790 0 : aSortParam.maKeyState[i].bDoSort = false;
791 :
792 0 : pViewData->GetViewShell()->UISort(aSortParam);
793 0 : return;
794 : }
795 : default:
796 : ;
797 : }
798 :
799 0 : if (eMode == Custom)
800 : {
801 0 : ScRange aRange;
802 0 : pDBData->GetArea(aRange);
803 0 : pViewData->GetView()->MarkRange(aRange);
804 0 : pViewData->GetView()->SetCursor(rPos.Col(), rPos.Row());
805 0 : pViewData->GetDispatcher().Execute(SID_FILTER, SFX_CALLMODE_SLOT|SFX_CALLMODE_RECORD);
806 0 : return;
807 : }
808 :
809 0 : ScQueryParam aParam;
810 0 : pDBData->GetQueryParam(aParam);
811 :
812 0 : if (eMode == Normal && mpAutoFilterPopup->isAllSelected())
813 : {
814 : // Remove this entry.
815 0 : aParam.RemoveEntryByField(rPos.Col());
816 : }
817 : else
818 : {
819 : // Try to use the existing entry for the column (if one exists).
820 0 : ScQueryEntry* pEntry = aParam.FindEntryByField(rPos.Col(), true);
821 :
822 0 : if (!pEntry)
823 : // Something went terribly wrong!
824 0 : return;
825 :
826 0 : pEntry->bDoQuery = true;
827 0 : pEntry->nField = rPos.Col();
828 0 : pEntry->eConnect = SC_AND;
829 :
830 0 : switch (eMode)
831 : {
832 : case Normal:
833 : {
834 0 : pEntry->eOp = SC_EQUAL;
835 :
836 0 : ScCheckListMenuWindow::ResultType aResult;
837 0 : mpAutoFilterPopup->getResult(aResult);
838 0 : std::vector<OUString> aSelected;
839 0 : ScCheckListMenuWindow::ResultType::const_iterator itr = aResult.begin(), itrEnd = aResult.end();
840 0 : for (; itr != itrEnd; ++itr)
841 : {
842 0 : if (itr->second)
843 0 : aSelected.push_back(itr->first);
844 : }
845 :
846 0 : ScQueryEntry::QueryItemsType& rItems = pEntry->GetQueryItems();
847 0 : rItems.clear();
848 0 : std::for_each(aSelected.begin(), aSelected.end(), AddItemToEntry(rItems));
849 : }
850 0 : break;
851 : case Top10:
852 0 : pEntry->eOp = SC_TOPVAL;
853 0 : pEntry->GetQueryItem().meType = ScQueryEntry::ByString;
854 0 : pEntry->GetQueryItem().maString = OUString("10");
855 0 : break;
856 : case Empty:
857 0 : pEntry->SetQueryByEmpty();
858 0 : break;
859 : case NonEmpty:
860 0 : pEntry->SetQueryByNonEmpty();
861 0 : break;
862 : default:
863 : // We don't know how to handle this!
864 0 : return;
865 : }
866 : }
867 :
868 0 : pViewData->GetView()->Query(aParam, NULL, true);
869 0 : pDBData->SetQueryParam(aParam);
870 : }
871 :
872 : namespace {
873 :
874 0 : void getCellGeometry(Point& rScrPos, Size& rScrSize, const ScViewData* pViewData, SCCOL nCol, SCROW nRow, ScSplitPos eWhich)
875 : {
876 : // Get the screen position of the cell.
877 0 : rScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
878 :
879 : // Get the screen size of the cell.
880 : long nSizeX, nSizeY;
881 0 : pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
882 0 : rScrSize = Size(nSizeX-1, nSizeY-1);
883 0 : }
884 :
885 : }
886 :
887 0 : void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
888 : {
889 0 : if (nCol == 0)
890 : // We assume that the page field button is located in cell to the immediate left.
891 0 : return;
892 :
893 0 : SCTAB nTab = pViewData->GetTabNo();
894 0 : ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
895 0 : if (!pDPObj)
896 0 : return;
897 :
898 0 : Point aScrPos;
899 0 : Size aScrSize;
900 0 : getCellGeometry(aScrPos, aScrSize, pViewData, nCol, nRow, eWhich);
901 0 : DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol-1, nRow, nTab), pDPObj);
902 : }
903 :
904 0 : void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
905 : {
906 0 : SCTAB nTab = pViewData->GetTabNo();
907 0 : ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
908 0 : if (!pDPObj)
909 0 : return;
910 :
911 0 : Point aScrPos;
912 0 : Size aScrSize;
913 0 : getCellGeometry(aScrPos, aScrSize, pViewData, nCol, nRow, eWhich);
914 0 : DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
915 : }
916 :
917 0 : void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange )
918 : {
919 0 : delete pFilterBox;
920 0 : delete pFilterFloat;
921 :
922 0 : SCCOL nCol = rScenRange.aEnd.Col(); // Zelle unterhalb des Buttons
923 0 : SCROW nRow = rScenRange.aStart.Row();
924 0 : if (nRow == 0)
925 : {
926 0 : nRow = rScenRange.aEnd.Row() + 1; // Bereich ganz oben -> Button unterhalb
927 0 : if (nRow>MAXROW) nRow = MAXROW;
928 : //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
929 : }
930 :
931 0 : ScDocument* pDoc = pViewData->GetDocument();
932 0 : SCTAB nTab = pViewData->GetTabNo();
933 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
934 :
935 0 : long nSizeX = 0;
936 0 : long nSizeY = 0;
937 0 : long nHeight = 0;
938 0 : pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
939 : // The button height should not use the merged cell height, should still use single row height
940 0 : nSizeY = pViewData->ToPixel(pDoc->GetRowHeight(nRow, nTab), pViewData->GetPPTY());
941 0 : Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
942 0 : if ( bLayoutRTL )
943 0 : aPos.X() -= nSizeX;
944 0 : Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
945 0 : aCellRect.Top() -= nSizeY;
946 0 : aCellRect.Bottom() -= nSizeY - 1;
947 : // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
948 : // (wenn die Linie verdeckt wird, sieht es komisch aus...)
949 :
950 0 : pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc.
951 0 : pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
952 0 : pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_SCENARIO );
953 0 : if ( bLayoutRTL )
954 0 : pFilterBox->EnableMirroring();
955 :
956 0 : nSizeX += 1;
957 :
958 : {
959 0 : Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
960 0 : MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
961 :
962 0 : nHeight = GetTextHeight();
963 0 : nHeight *= SC_FILTERLISTBOX_LINES;
964 :
965 0 : SetMapMode( aOldMode );
966 0 : SetFont( aOldFont );
967 : }
968 :
969 : // SetSize spaeter
970 :
971 : // ParentSize Abfrage fehlt
972 0 : Size aSize( nSizeX, nHeight );
973 0 : pFilterBox->SetSizePixel( aSize );
974 0 : pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!!
975 0 : pFilterBox->SetUpdateMode(false);
976 :
977 : // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
978 :
979 : // Listbox fuellen
980 :
981 0 : long nMaxText = 0;
982 0 : OUString aCurrent;
983 0 : OUString aTabName;
984 0 : SCTAB nTabCount = pDoc->GetTableCount();
985 0 : SCTAB nEntryCount = 0;
986 0 : for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
987 : {
988 0 : if (pDoc->HasScenarioRange( i, rScenRange ))
989 0 : if (pDoc->GetName( i, aTabName ))
990 : {
991 0 : pFilterBox->InsertEntry( aTabName );
992 0 : if (pDoc->IsActiveScenario(i))
993 0 : aCurrent = aTabName;
994 0 : long nTextWidth = pFilterBox->GetTextWidth( aTabName );
995 0 : if ( nTextWidth > nMaxText )
996 0 : nMaxText = nTextWidth;
997 0 : ++nEntryCount;
998 : }
999 : }
1000 0 : if (nEntryCount > SC_FILTERLISTBOX_LINES)
1001 0 : nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
1002 0 : nMaxText += 4; // fuer Rand
1003 0 : if ( nMaxText > 300 )
1004 0 : nMaxText = 300; // auch nicht uebertreiben (Pixel)
1005 :
1006 0 : if (nMaxText > nSizeX) // Groesse auf benoetigte Groesse anpassen
1007 : {
1008 0 : long nDiff = nMaxText - nSizeX;
1009 0 : aSize = Size( nMaxText, nHeight );
1010 0 : pFilterBox->SetSizePixel( aSize );
1011 0 : pFilterFloat->SetOutputSizePixel( aSize );
1012 :
1013 0 : if ( !bLayoutRTL )
1014 : {
1015 : // also move popup position
1016 0 : long nNewX = aCellRect.Left() - nDiff;
1017 0 : if ( nNewX < 0 )
1018 0 : nNewX = 0;
1019 0 : aCellRect.Left() = nNewX;
1020 : }
1021 : }
1022 :
1023 0 : pFilterFloat->SetOutputSizePixel( aSize );
1024 0 : pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS );
1025 :
1026 0 : pFilterBox->SetUpdateMode(sal_True);
1027 0 : pFilterBox->GrabFocus();
1028 :
1029 0 : sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;
1030 0 : if (!aCurrent.isEmpty())
1031 : {
1032 0 : nPos = pFilterBox->GetEntryPos(String(aCurrent));
1033 : }
1034 0 : if (LISTBOX_ENTRY_NOTFOUND == nPos && pFilterBox->GetEntryCount() > 0 )
1035 0 : nPos = 0;
1036 0 : if (LISTBOX_ENTRY_NOTFOUND != nPos )
1037 0 : pFilterBox->SelectEntryPos(nPos);
1038 :
1039 0 : pFilterBox->EndInit();
1040 :
1041 : // Szenario-Auswahl kommt aus MouseButtonDown:
1042 : // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1043 :
1044 0 : nMouseStatus = SC_GM_FILTER;
1045 0 : CaptureMouse();
1046 0 : }
1047 :
1048 0 : void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelect )
1049 : {
1050 0 : delete pFilterBox;
1051 0 : delete pFilterFloat;
1052 :
1053 : sal_uInt16 i;
1054 0 : ScDocument* pDoc = pViewData->GetDocument();
1055 0 : SCTAB nTab = pViewData->GetTabNo();
1056 0 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1057 :
1058 0 : long nSizeX = 0;
1059 0 : long nSizeY = 0;
1060 0 : long nHeight = 0;
1061 0 : pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
1062 0 : Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
1063 0 : if ( bLayoutRTL )
1064 0 : aPos.X() -= nSizeX;
1065 :
1066 0 : Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
1067 :
1068 0 : aPos.X() -= 1;
1069 0 : aPos.Y() += nSizeY - 1;
1070 :
1071 0 : pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc.
1072 0 : pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
1073 : pFilterBox = new ScFilterListBox(
1074 0 : pFilterFloat, this, nCol, nRow, bDataSelect ? SC_FILTERBOX_DATASELECT : SC_FILTERBOX_FILTER );
1075 : // Fix for bug fdo#44925
1076 0 : if (Application::GetSettings().GetLayoutRTL() != bLayoutRTL)
1077 0 : pFilterBox->EnableMirroring();
1078 :
1079 0 : nSizeX += 1;
1080 :
1081 : {
1082 0 : Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
1083 0 : MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
1084 :
1085 0 : nHeight = GetTextHeight();
1086 0 : nHeight *= SC_FILTERLISTBOX_LINES;
1087 :
1088 0 : SetMapMode( aOldMode );
1089 0 : SetFont( aOldFont );
1090 : }
1091 :
1092 : // SetSize spaeter
1093 :
1094 0 : bool bEmpty = false;
1095 0 : std::vector<ScTypedStrData> aStrings; // case sensitive
1096 0 : if ( bDataSelect ) // Auswahl-Liste
1097 : {
1098 : // Liste fuellen
1099 0 : pDoc->GetDataEntries(nCol, nRow, nTab, true, aStrings);
1100 0 : if (aStrings.empty())
1101 0 : bEmpty = true;
1102 : }
1103 : else // AutoFilter
1104 : {
1105 : //! wird der Titel ueberhaupt ausgewertet ???
1106 0 : OUString aString = pDoc->GetString(nCol, nRow, nTab);
1107 0 : pFilterBox->SetText( aString );
1108 :
1109 0 : long nMaxText = 0;
1110 :
1111 : // default entries
1112 : static const sal_uInt16 nDefIDs[] = { SCSTR_TOP10FILTER, SCSTR_STDFILTER, SCSTR_FILTER_EMPTY, SCSTR_FILTER_NOTEMPTY };
1113 0 : const size_t nDefCount = SAL_N_ELEMENTS(nDefIDs);
1114 0 : for (i=0; i<nDefCount; i++)
1115 : {
1116 0 : String aEntry( (ScResId) nDefIDs[i] );
1117 0 : pFilterBox->InsertEntry( aEntry );
1118 0 : long nTextWidth = pFilterBox->GetTextWidth( aEntry );
1119 0 : if ( nTextWidth > nMaxText )
1120 0 : nMaxText = nTextWidth;
1121 0 : }
1122 0 : pFilterBox->SetSeparatorPos( nDefCount - 1 );
1123 :
1124 : // get list entries
1125 0 : bool bHasDates = false;
1126 0 : pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates);
1127 0 : pFilterBox->SetListHasDates(bHasDates);
1128 :
1129 : // check widths of numerical entries (string entries are not included)
1130 : // so all numbers are completely visible
1131 0 : std::vector<ScTypedStrData>::const_iterator it = aStrings.begin(), itEnd = aStrings.end();
1132 0 : for (; it != itEnd; ++it)
1133 : {
1134 0 : if (!it->IsStrData()) // only numerical entries
1135 : {
1136 0 : long nTextWidth = pFilterBox->GetTextWidth(it->GetString());
1137 0 : if ( nTextWidth > nMaxText )
1138 0 : nMaxText = nTextWidth;
1139 : }
1140 : }
1141 :
1142 : // add scrollbar width if needed (string entries are counted here)
1143 : // (scrollbar is shown if the box is exactly full?)
1144 0 : if (aStrings.size() + nDefCount >= SC_FILTERLISTBOX_LINES)
1145 0 : nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
1146 :
1147 0 : nMaxText += 4; // for borders
1148 :
1149 0 : if ( nMaxText > nSizeX )
1150 0 : nSizeX = nMaxText; // just modify width - starting position is unchanged
1151 : }
1152 :
1153 0 : if (!bEmpty)
1154 : {
1155 : // Position und Groesse an Fenster anpassen
1156 : //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
1157 :
1158 0 : Size aParentSize = GetParent()->GetOutputSizePixel();
1159 0 : Size aSize( nSizeX, nHeight );
1160 :
1161 0 : if ( aSize.Height() > aParentSize.Height() )
1162 0 : aSize.Height() = aParentSize.Height();
1163 0 : if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
1164 0 : aPos.Y() = aParentSize.Height() - aSize.Height();
1165 :
1166 0 : pFilterBox->SetSizePixel( aSize );
1167 0 : pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!!
1168 0 : pFilterBox->SetUpdateMode(false);
1169 :
1170 0 : pFilterFloat->SetOutputSizePixel( aSize );
1171 0 : pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);
1172 :
1173 : // Listbox fuellen
1174 0 : bool bWait = aStrings.size() > 100;
1175 :
1176 0 : if (bWait)
1177 0 : EnterWait();
1178 :
1179 0 : std::vector<ScTypedStrData>::const_iterator it = aStrings.begin(), itEnd = aStrings.end();
1180 0 : for (; it != itEnd; ++it)
1181 0 : pFilterBox->InsertEntry(it->GetString());
1182 :
1183 0 : if (bWait)
1184 0 : LeaveWait();
1185 :
1186 0 : pFilterBox->SetUpdateMode(true);
1187 : }
1188 :
1189 0 : sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND;
1190 :
1191 0 : if (!bDataSelect) // AutoFilter: aktiven Eintrag selektieren
1192 : {
1193 0 : ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1194 0 : if (pDBData)
1195 : {
1196 0 : ScQueryParam aParam;
1197 0 : pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben
1198 :
1199 0 : sal_Bool bValid = sal_True;
1200 0 : SCSIZE nCount = aParam.GetEntryCount();
1201 0 : for (SCSIZE j = 0; j < nCount && bValid; ++j) // bisherige Filter-Einstellungen
1202 0 : if (aParam.GetEntry(j).bDoQuery)
1203 : {
1204 : //! Abfrage mit DrawButtons zusammenfassen!
1205 :
1206 0 : ScQueryEntry& rEntry = aParam.GetEntry(j);
1207 0 : if (j>0)
1208 0 : if (rEntry.eConnect != SC_AND)
1209 0 : bValid = false;
1210 0 : if (rEntry.nField == nCol)
1211 : {
1212 0 : const OUString& rQueryStr = rEntry.GetQueryItem().maString;
1213 0 : if (rEntry.eOp == SC_EQUAL)
1214 : {
1215 0 : if (!rQueryStr.isEmpty())
1216 : {
1217 0 : nSelPos = pFilterBox->GetEntryPos(rQueryStr);
1218 : }
1219 : }
1220 0 : else if ( rEntry.eOp == SC_TOPVAL && rQueryStr == "10" )
1221 0 : nSelPos = SC_AUTOFILTER_TOP10;
1222 : else
1223 0 : nSelPos = SC_AUTOFILTER_CUSTOM;
1224 : }
1225 : }
1226 :
1227 0 : if (!bValid)
1228 0 : nSelPos = SC_AUTOFILTER_CUSTOM;
1229 : }
1230 : }
1231 : else
1232 : {
1233 :
1234 : sal_uLong nIndex = ((SfxUInt32Item*)pDoc->GetAttr(
1235 0 : nCol, nRow, nTab, ATTR_VALIDDATA ))->GetValue();
1236 0 : if ( nIndex )
1237 : {
1238 0 : const ScValidationData* pData = pDoc->GetValidationEntry( nIndex );
1239 0 : if (pData)
1240 : {
1241 0 : ScTypedStrData* pNew = NULL;
1242 0 : OUString aDocStr = pDoc->GetString(nCol, nRow, nTab);
1243 0 : if ( pDoc->HasValueData( nCol, nRow, nTab ) )
1244 : {
1245 0 : double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nTab));
1246 0 : pNew = new ScTypedStrData(aDocStr, fVal, ScTypedStrData::Value);
1247 : }
1248 : else
1249 0 : pNew = new ScTypedStrData(aDocStr, 0.0, ScTypedStrData::Standard);
1250 :
1251 0 : bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING);
1252 0 : if ( bSortList )
1253 : {
1254 0 : std::vector<ScTypedStrData>::const_iterator itBeg = aStrings.begin(), itEnd = aStrings.end();
1255 : std::vector<ScTypedStrData>::const_iterator it =
1256 0 : std::find_if(itBeg, itEnd, FindTypedStrData(*pNew, true));
1257 0 : if (it != itEnd)
1258 : // Found!
1259 0 : nSelPos = std::distance(itBeg, it);
1260 : }
1261 : else
1262 : {
1263 : ScTypedStrData::EqualCaseSensitive aHdl;
1264 0 : std::vector<ScTypedStrData>::const_iterator itBeg = aStrings.begin(), itEnd = aStrings.end();
1265 0 : std::vector<ScTypedStrData>::const_iterator it = itBeg;
1266 0 : for (; it != itEnd && LISTBOX_ENTRY_NOTFOUND == nSelPos; ++it)
1267 : {
1268 0 : if (aHdl(*it, *pNew))
1269 0 : nSelPos = std::distance(itBeg, it);
1270 : }
1271 : }
1272 0 : delete pNew;
1273 : }
1274 : }
1275 : }
1276 :
1277 : // neu (309): irgendwas muss immer selektiert sein:
1278 0 : if ( LISTBOX_ENTRY_NOTFOUND == nSelPos && pFilterBox->GetEntryCount() > 0 && !bDataSelect)
1279 0 : nSelPos = 0;
1280 :
1281 : // keine leere Auswahl-Liste anzeigen:
1282 :
1283 0 : if ( bEmpty )
1284 : {
1285 0 : DELETEZ(pFilterBox); // war nix
1286 0 : DELETEZ(pFilterFloat);
1287 : }
1288 : else
1289 : {
1290 0 : pFilterBox->GrabFocus();
1291 :
1292 : // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1293 0 : if ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
1294 0 : pFilterBox->SelectEntryPos( nSelPos );
1295 : else
1296 : {
1297 0 : if (bDataSelect)
1298 0 : pFilterBox->SetNoSelection();
1299 : }
1300 :
1301 0 : pFilterBox->EndInit();
1302 :
1303 0 : if (!bDataSelect)
1304 : {
1305 : // AutoFilter (aus MouseButtonDown):
1306 : // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1307 :
1308 0 : nMouseStatus = SC_GM_FILTER;
1309 0 : CaptureMouse();
1310 : }
1311 0 : }
1312 0 : }
1313 :
1314 0 : void ScGridWindow::FilterSelect( sal_uLong nSel )
1315 : {
1316 0 : String aString = pFilterBox->GetEntry( static_cast< sal_uInt16 >( nSel ) );
1317 :
1318 0 : SCCOL nCol = pFilterBox->GetCol();
1319 0 : SCROW nRow = pFilterBox->GetRow();
1320 0 : switch ( pFilterBox->GetMode() )
1321 : {
1322 : case SC_FILTERBOX_DATASELECT:
1323 0 : ExecDataSelect( nCol, nRow, aString );
1324 0 : break;
1325 : case SC_FILTERBOX_FILTER:
1326 0 : ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() );
1327 0 : break;
1328 : case SC_FILTERBOX_SCENARIO:
1329 0 : pViewData->GetView()->UseScenario( aString );
1330 0 : break;
1331 : case SC_FILTERBOX_PAGEFIELD:
1332 : // first entry is "all"
1333 0 : ExecPageFieldSelect( nCol, nRow, (nSel != 0), aString );
1334 0 : break;
1335 : }
1336 :
1337 0 : if (pFilterFloat)
1338 0 : pFilterFloat->EndPopupMode();
1339 :
1340 0 : GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1341 0 : }
1342 :
1343 0 : void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr )
1344 : {
1345 0 : if ( rStr.Len() )
1346 : {
1347 0 : SCTAB nTab = pViewData->GetTabNo();
1348 0 : ScViewFunc* pView = pViewData->GetView();
1349 0 : pView->EnterData( nCol, nRow, nTab, rStr );
1350 :
1351 : // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1352 : // if the cursor is moved afterwards.
1353 0 : pView->CellContentChanged();
1354 : }
1355 0 : }
1356 :
1357 0 : void ScGridWindow::ExecFilter( sal_uLong nSel,
1358 : SCCOL nCol, SCROW nRow,
1359 : const String& aValue, bool bCheckForDates )
1360 : {
1361 0 : SCTAB nTab = pViewData->GetTabNo();
1362 0 : ScDocument* pDoc = pViewData->GetDocument();
1363 :
1364 0 : ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1365 0 : if (pDBData)
1366 : {
1367 0 : ScQueryParam aParam;
1368 0 : pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben
1369 :
1370 0 : if (SC_AUTOFILTER_CUSTOM == nSel)
1371 : {
1372 : SCTAB nAreaTab;
1373 : SCCOL nStartCol;
1374 : SCROW nStartRow;
1375 : SCCOL nEndCol;
1376 : SCROW nEndRow;
1377 0 : pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow );
1378 0 : pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab));
1379 0 : pViewData->GetView()->SetCursor(nCol,nRow); //! auch ueber Slot ??
1380 0 : pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
1381 : }
1382 : else
1383 : {
1384 0 : sal_Bool bDeleteOld = false;
1385 0 : SCSIZE nQueryPos = 0;
1386 0 : sal_Bool bFound = false;
1387 0 : if (!aParam.bInplace)
1388 0 : bDeleteOld = sal_True;
1389 0 : if (aParam.bRegExp)
1390 0 : bDeleteOld = sal_True;
1391 0 : SCSIZE nCount = aParam.GetEntryCount();
1392 0 : for (SCSIZE i = 0; i < nCount && !bDeleteOld; ++i) // bisherige Filter-Einstellungen
1393 0 : if (aParam.GetEntry(i).bDoQuery)
1394 : {
1395 : //! Abfrage mit DrawButtons zusammenfassen!
1396 :
1397 0 : ScQueryEntry& rEntry = aParam.GetEntry(i);
1398 0 : if (i>0)
1399 0 : if (rEntry.eConnect != SC_AND)
1400 0 : bDeleteOld = sal_True;
1401 :
1402 0 : if (rEntry.nField == nCol)
1403 : {
1404 0 : if (bFound) // diese Spalte zweimal?
1405 0 : bDeleteOld = sal_True;
1406 0 : nQueryPos = i;
1407 0 : bFound = sal_True;
1408 : }
1409 0 : if (!bFound)
1410 0 : nQueryPos = i + 1;
1411 : }
1412 :
1413 0 : if (bDeleteOld)
1414 : {
1415 0 : SCSIZE nEC = aParam.GetEntryCount();
1416 0 : for (SCSIZE i=0; i<nEC; i++)
1417 0 : aParam.GetEntry(i).Clear();
1418 0 : nQueryPos = 0;
1419 0 : aParam.bInplace = sal_True;
1420 0 : aParam.bRegExp = false;
1421 : }
1422 :
1423 0 : if ( nQueryPos < nCount || SC_AUTOFILTER_ALL == nSel ) // loeschen geht immer
1424 : {
1425 0 : if (nSel)
1426 : {
1427 0 : ScQueryEntry& rNewEntry = aParam.GetEntry(nQueryPos);
1428 0 : ScQueryEntry::Item& rItem = rNewEntry.GetQueryItem();
1429 0 : rNewEntry.bDoQuery = true;
1430 0 : rNewEntry.nField = nCol;
1431 0 : rItem.meType = bCheckForDates ? ScQueryEntry::ByDate : ScQueryEntry::ByString;
1432 :
1433 0 : if ( nSel == SC_AUTOFILTER_TOP10 )
1434 : {
1435 0 : rNewEntry.eOp = SC_TOPVAL;
1436 0 : rItem.maString = OUString("10");
1437 : }
1438 0 : else if (nSel == SC_AUTOFILTER_EMPTY)
1439 : {
1440 0 : rNewEntry.SetQueryByEmpty();
1441 : }
1442 0 : else if (nSel == SC_AUTOFILTER_NOTEMPTY)
1443 : {
1444 0 : rNewEntry.SetQueryByNonEmpty();
1445 : }
1446 : else
1447 : {
1448 0 : rNewEntry.eOp = SC_EQUAL;
1449 0 : rItem.maString = aValue;
1450 : }
1451 0 : if (nQueryPos > 0)
1452 0 : rNewEntry.eConnect = SC_AND;
1453 : }
1454 : else
1455 : {
1456 0 : if (bFound)
1457 0 : aParam.RemoveEntryByField(nCol);
1458 : }
1459 :
1460 : // end edit mode - like in ScCellShell::ExecuteDB
1461 0 : if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
1462 : {
1463 0 : SC_MOD()->InputEnterHandler();
1464 0 : pViewData->GetViewShell()->UpdateInputHandler();
1465 : }
1466 :
1467 0 : pViewData->GetView()->Query( aParam, NULL, true );
1468 0 : pDBData->SetQueryParam( aParam ); // speichern
1469 : }
1470 : else // "Zuviele Bedingungen"
1471 0 : pViewData->GetView()->ErrorMessage( STR_FILTER_TOOMANY );
1472 0 : }
1473 : }
1474 : else
1475 : {
1476 : OSL_FAIL("Wo ist der Datenbankbereich?");
1477 : }
1478 0 : }
1479 :
1480 0 : void ScGridWindow::SetPointer( const Pointer& rPointer )
1481 : {
1482 0 : nCurrentPointer = 0;
1483 0 : Window::SetPointer( rPointer );
1484 0 : }
1485 :
1486 10 : void ScGridWindow::MoveMouseStatus( ScGridWindow& rDestWin )
1487 : {
1488 10 : if (nButtonDown)
1489 : {
1490 0 : rDestWin.nButtonDown = nButtonDown;
1491 0 : rDestWin.nMouseStatus = nMouseStatus;
1492 : }
1493 :
1494 10 : if (bRFMouse)
1495 : {
1496 0 : rDestWin.bRFMouse = bRFMouse;
1497 0 : rDestWin.bRFSize = bRFSize;
1498 0 : rDestWin.nRFIndex = nRFIndex;
1499 0 : rDestWin.nRFAddX = nRFAddX;
1500 0 : rDestWin.nRFAddY = nRFAddY;
1501 0 : bRFMouse = false;
1502 : }
1503 :
1504 10 : if (nPagebreakMouse)
1505 : {
1506 0 : rDestWin.nPagebreakMouse = nPagebreakMouse;
1507 0 : rDestWin.nPagebreakBreak = nPagebreakBreak;
1508 0 : rDestWin.nPagebreakPrev = nPagebreakPrev;
1509 0 : rDestWin.aPagebreakSource = aPagebreakSource;
1510 0 : rDestWin.aPagebreakDrag = aPagebreakDrag;
1511 0 : nPagebreakMouse = SC_PD_NONE;
1512 : }
1513 10 : }
1514 :
1515 0 : bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, bool bAction )
1516 : {
1517 : // MouseEvent buttons must only be checked if bAction==TRUE
1518 : // to allow changing the mouse pointer in MouseMove,
1519 : // but not start AutoFill with right button (#74229#).
1520 : // with bAction==sal_True, SetFillMode / SetDragMode is called
1521 :
1522 0 : if ( bAction && !rMEvt.IsLeft() )
1523 0 : return false;
1524 :
1525 0 : bool bNewPointer = false;
1526 :
1527 0 : SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
1528 0 : bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
1529 :
1530 0 : if ( pViewData->IsActive() && !bOleActive )
1531 : {
1532 0 : ScDocument* pDoc = pViewData->GetDocument();
1533 0 : SCTAB nTab = pViewData->GetTabNo();
1534 0 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1535 :
1536 : // Auto-Fill
1537 :
1538 0 : ScRange aMarkRange;
1539 0 : if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE)
1540 : {
1541 0 : if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect)
1542 : {
1543 0 : Point aMousePos = rMEvt.GetPosPixel();
1544 0 : if (mpAutoFillRect->IsInside(aMousePos))
1545 : {
1546 0 : SetPointer( Pointer( POINTER_CROSS ) ); //! dickeres Kreuz ?
1547 0 : if (bAction)
1548 : {
1549 0 : SCCOL nX = aMarkRange.aEnd.Col();
1550 0 : SCROW nY = aMarkRange.aEnd.Row();
1551 :
1552 0 : if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) )
1553 : pViewData->SetDragMode(
1554 0 : aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX );
1555 : else
1556 : pViewData->SetFillMode(
1557 0 : aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY );
1558 :
1559 : // The simple selection must also be recognized when dragging,
1560 : // where the Marking flag is set and MarkToSimple won't work anymore.
1561 0 : pViewData->GetMarkData().MarkToSimple();
1562 : }
1563 0 : bNewPointer = true;
1564 : }
1565 : }
1566 : }
1567 :
1568 : // Embedded-Rechteck
1569 :
1570 0 : if (pDoc->IsEmbedded())
1571 : {
1572 0 : ScRange aRange;
1573 0 : pDoc->GetEmbedded( aRange );
1574 0 : if ( pViewData->GetTabNo() == aRange.aStart.Tab() )
1575 : {
1576 0 : Point aStartPos = pViewData->GetScrPos( aRange.aStart.Col(), aRange.aStart.Row(), eWhich );
1577 0 : Point aEndPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich );
1578 0 : Point aMousePos = rMEvt.GetPosPixel();
1579 0 : if ( bLayoutRTL )
1580 : {
1581 0 : aStartPos.X() += 2;
1582 0 : aEndPos.X() += 2;
1583 : }
1584 0 : bool bTop = ( aMousePos.X() >= aStartPos.X()-3 && aMousePos.X() <= aStartPos.X()+1 &&
1585 0 : aMousePos.Y() >= aStartPos.Y()-3 && aMousePos.Y() <= aStartPos.Y()+1 );
1586 0 : bool bBottom = ( aMousePos.X() >= aEndPos.X()-3 && aMousePos.X() <= aEndPos.X()+1 &&
1587 0 : aMousePos.Y() >= aEndPos.Y()-3 && aMousePos.Y() <= aEndPos.Y()+1 );
1588 0 : if ( bTop || bBottom )
1589 : {
1590 0 : SetPointer( Pointer( POINTER_CROSS ) );
1591 0 : if (bAction)
1592 : {
1593 0 : sal_uInt8 nMode = bTop ? SC_FILL_EMBED_LT : SC_FILL_EMBED_RB;
1594 : pViewData->SetDragMode(
1595 0 : aRange.aStart.Col(), aRange.aStart.Row(),
1596 0 : aRange.aEnd.Col(), aRange.aEnd.Row(), nMode );
1597 : }
1598 0 : bNewPointer = true;
1599 : }
1600 : }
1601 : }
1602 : }
1603 :
1604 0 : if (!bNewPointer && bAction)
1605 : {
1606 0 : pViewData->ResetFillMode();
1607 : }
1608 :
1609 0 : return bNewPointer;
1610 : }
1611 :
1612 0 : void ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt )
1613 : {
1614 0 : nNestedButtonState = SC_NESTEDBUTTON_DOWN;
1615 :
1616 0 : MouseEventState aState;
1617 0 : HandleMouseButtonDown(rMEvt, aState);
1618 0 : if (aState.mbActivatePart)
1619 0 : pViewData->GetView()->ActivatePart(eWhich);
1620 :
1621 0 : if ( nNestedButtonState == SC_NESTEDBUTTON_UP )
1622 : {
1623 : // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1624 : // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1625 : // simulate another MouseButtonUp call, so the selection state is consistent.
1626 :
1627 0 : nButtonDown = rMEvt.GetButtons();
1628 0 : FakeButtonUp();
1629 :
1630 0 : if ( IsTracking() )
1631 0 : EndTracking(); // normally done in VCL as part of MouseButtonUp handling
1632 : }
1633 0 : nNestedButtonState = SC_NESTEDBUTTON_NONE;
1634 0 : }
1635 :
1636 0 : void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventState& rState )
1637 : {
1638 : // We have to check if a context menu is shown and we have an UI
1639 : // active inplace client. In that case we have to ignore the event.
1640 : // Otherwise we would crash (context menu has been
1641 : // opened by inplace client and we would deactivate the inplace client,
1642 : // the contex menu is closed by VCL asynchronously which in the end
1643 : // would work on deleted objects or the context menu has no parent anymore)
1644 0 : SfxViewShell* pViewSh = pViewData->GetViewShell();
1645 0 : SfxInPlaceClient* pClient = pViewSh->GetIPClient();
1646 0 : if ( pClient &&
1647 0 : pClient->IsObjectInPlaceActive() &&
1648 0 : PopupMenu::IsInExecute() )
1649 0 : return;
1650 :
1651 0 : aCurMousePos = rMEvt.GetPosPixel();
1652 :
1653 : // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1654 : // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1655 0 : ClickExtern(); // loescht FilterBox, wenn vorhanden
1656 :
1657 0 : HideNoteMarker(); // Notiz-Anzeige
1658 :
1659 0 : bEEMouse = false;
1660 :
1661 0 : ScModule* pScMod = SC_MOD();
1662 0 : if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
1663 0 : return;
1664 :
1665 0 : pScActiveViewShell = pViewData->GetViewShell(); // falls auf Link geklickt wird
1666 0 : nScClickMouseModifier = rMEvt.GetModifier(); // um Control-Klick immer zu erkennen
1667 :
1668 0 : sal_Bool bDetective = pViewData->GetViewShell()->IsAuditShell();
1669 0 : sal_Bool bRefMode = pViewData->IsRefMode(); // Referenz angefangen
1670 0 : sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
1671 0 : sal_Bool bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE
1672 0 : sal_Bool bDouble = (rMEvt.GetClicks() == 2);
1673 :
1674 : // DeactivateIP passiert nur noch bei MarkListHasChanged
1675 :
1676 : // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1677 : // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1678 :
1679 0 : if ( !nButtonDown || !bDouble ) // single (first) click is always valid
1680 0 : nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works
1681 :
1682 0 : if ( ( bEditMode && pViewData->GetActivePart() == eWhich ) || !bFormulaMode )
1683 0 : GrabFocus();
1684 :
1685 : // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1686 : // but a single (first) click is always valid
1687 0 : if ( nMouseStatus == SC_GM_IGNORE && bDouble )
1688 : {
1689 0 : nButtonDown = 0;
1690 0 : nMouseStatus = SC_GM_NONE;
1691 0 : return;
1692 : }
1693 :
1694 0 : if ( bDetective ) // Detektiv-Fuell-Modus
1695 : {
1696 0 : if ( rMEvt.IsLeft() && !rMEvt.GetModifier() )
1697 : {
1698 0 : Point aPos = rMEvt.GetPosPixel();
1699 : SCsCOL nPosX;
1700 : SCsROW nPosY;
1701 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1702 :
1703 0 : SfxInt16Item aPosXItem( SID_RANGE_COL, nPosX );
1704 0 : SfxInt32Item aPosYItem( SID_RANGE_ROW, nPosY );
1705 0 : pViewData->GetDispatcher().Execute( SID_FILL_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
1706 0 : &aPosXItem, &aPosYItem, (void*)0L );
1707 :
1708 : }
1709 0 : nButtonDown = 0;
1710 0 : nMouseStatus = SC_GM_NONE;
1711 0 : return;
1712 : }
1713 :
1714 0 : if (!bDouble)
1715 0 : nMouseStatus = SC_GM_NONE;
1716 :
1717 0 : rState.mbActivatePart = !bFormulaMode; // Don't activate when in formula mode.
1718 :
1719 0 : if (bFormulaMode)
1720 : {
1721 0 : ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
1722 0 : pSelEng->SetWindow(this);
1723 0 : pSelEng->SetWhich(eWhich);
1724 0 : pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1725 : }
1726 :
1727 0 : if (bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()))
1728 : {
1729 0 : Point aPos = rMEvt.GetPosPixel();
1730 : SCsCOL nPosX;
1731 : SCsROW nPosY;
1732 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1733 :
1734 : EditView* pEditView;
1735 : SCCOL nEditCol;
1736 : SCROW nEditRow;
1737 0 : pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
1738 0 : SCCOL nEndCol = pViewData->GetEditEndCol();
1739 0 : SCROW nEndRow = pViewData->GetEditEndRow();
1740 :
1741 0 : if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
1742 0 : nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
1743 : {
1744 : // beim Klick in die Tabellen-EditView immer den Focus umsetzen
1745 0 : if (bFormulaMode) // sonst ist es oben schon passiert
1746 0 : GrabFocus();
1747 :
1748 0 : pScMod->SetInputMode( SC_INPUT_TABLE );
1749 0 : bEEMouse = true;
1750 0 : bEditMode = pEditView->MouseButtonDown( rMEvt );
1751 0 : return;
1752 : }
1753 : }
1754 :
1755 0 : if (pScMod->GetIsWaterCan())
1756 : {
1757 : //! was is mit'm Mac ???
1758 0 : if ( rMEvt.GetModifier() + rMEvt.GetButtons() == MOUSE_RIGHT )
1759 : {
1760 0 : nMouseStatus = SC_GM_WATERUNDO;
1761 0 : return;
1762 : }
1763 : }
1764 :
1765 : // Reihenfolge passend zum angezeigten Cursor:
1766 : // RangeFinder, AutoFill, PageBreak, Drawing
1767 :
1768 : bool bCorner;
1769 0 : bool bFound = HitRangeFinder(rMEvt.GetPosPixel(), bCorner, &nRFIndex, &nRFAddX, &nRFAddY);
1770 0 : bRFSize = bCorner;
1771 0 : if (bFound)
1772 : {
1773 0 : bRFMouse = true; // die anderen Variablen sind oben initialisiert
1774 :
1775 0 : rState.mbActivatePart = true; // always activate ?
1776 0 : StartTracking();
1777 0 : return;
1778 : }
1779 :
1780 0 : sal_Bool bCrossPointer = TestMouse( rMEvt, sal_True );
1781 0 : if ( bCrossPointer )
1782 : {
1783 0 : if ( bDouble )
1784 0 : pViewData->GetView()->FillCrossDblClick();
1785 : else
1786 0 : pScMod->InputEnterHandler(); // Autofill etc.
1787 : }
1788 :
1789 0 : if ( !bCrossPointer )
1790 : {
1791 0 : nPagebreakMouse = HitPageBreak( rMEvt.GetPosPixel(), &aPagebreakSource,
1792 0 : &nPagebreakBreak, &nPagebreakPrev );
1793 0 : if (nPagebreakMouse)
1794 : {
1795 0 : bPagebreakDrawn = false;
1796 0 : StartTracking();
1797 0 : PagebreakMove( rMEvt, false );
1798 0 : return;
1799 : }
1800 : }
1801 :
1802 0 : if (!bFormulaMode && !bEditMode && rMEvt.IsLeft())
1803 : {
1804 0 : if ( !bCrossPointer && DrawMouseButtonDown(rMEvt) )
1805 : {
1806 0 : return;
1807 : }
1808 :
1809 0 : pViewData->GetViewShell()->SetDrawShell( false ); // kein Draw-Objekt selektiert
1810 :
1811 : // TestMouse schon oben passiert
1812 : }
1813 :
1814 0 : Point aPos = rMEvt.GetPosPixel();
1815 : SCsCOL nPosX;
1816 : SCsROW nPosY;
1817 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1818 0 : SCTAB nTab = pViewData->GetTabNo();
1819 0 : ScDocument* pDoc = pViewData->GetDocument();
1820 :
1821 : // Auto filter / pivot table / data select popup. This shouldn't activate the part.
1822 :
1823 0 : if ( !bDouble && !bFormulaMode && rMEvt.IsLeft() )
1824 : {
1825 : SCsCOL nRealPosX;
1826 : SCsROW nRealPosY;
1827 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nRealPosX, nRealPosY, false );//the real row/col
1828 : ScMergeFlagAttr* pRealPosAttr = (ScMergeFlagAttr*)
1829 0 : pDoc->GetAttr( nRealPosX, nRealPosY, nTab, ATTR_MERGE_FLAG );
1830 : ScMergeFlagAttr* pAttr = (ScMergeFlagAttr*)
1831 0 : pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
1832 0 : if( pRealPosAttr->HasAutoFilter() )
1833 : {
1834 0 : SC_MOD()->InputEnterHandler();
1835 0 : if (DoAutoFilterButton( nRealPosX, nRealPosY, rMEvt))
1836 0 : return;
1837 : }
1838 0 : if (pAttr->HasAutoFilter())
1839 : {
1840 0 : if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
1841 : {
1842 0 : rState.mbActivatePart = false;
1843 0 : return;
1844 : }
1845 : }
1846 :
1847 0 : if (pAttr->HasPivotButton() || pAttr->HasPivotPopupButton())
1848 : {
1849 0 : DoPushPivotButton(nPosX, nPosY, rMEvt, pAttr->HasPivotButton(), pAttr->HasPivotPopupButton());
1850 0 : rState.mbActivatePart = false;
1851 0 : return;
1852 : }
1853 :
1854 : // List Validity drop-down button
1855 :
1856 0 : if ( bListValButton )
1857 : {
1858 0 : Rectangle aButtonRect = GetListValButtonRect( aListValPos );
1859 0 : if ( aButtonRect.IsInside( aPos ) )
1860 : {
1861 0 : LaunchDataSelectMenu( aListValPos.Col(), aListValPos.Row(), true );
1862 :
1863 0 : nMouseStatus = SC_GM_FILTER; // not set in DoAutoFilterMenue for bDataSelect
1864 0 : CaptureMouse();
1865 0 : rState.mbActivatePart = false;
1866 0 : return;
1867 : }
1868 : }
1869 : }
1870 :
1871 : //
1872 : // scenario selection
1873 : //
1874 :
1875 0 : ScRange aScenRange;
1876 0 : if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) )
1877 : {
1878 0 : DoScenarioMenu( aScenRange );
1879 0 : return;
1880 : }
1881 :
1882 : //
1883 : // Doppelklick angefangen ?
1884 : //
1885 :
1886 : // StopMarking kann aus DrawMouseButtonDown gerufen werden
1887 :
1888 0 : if ( nMouseStatus != SC_GM_IGNORE && !bRefMode )
1889 : {
1890 0 : if ( bDouble && !bCrossPointer )
1891 : {
1892 0 : if (nMouseStatus == SC_GM_TABDOWN)
1893 0 : nMouseStatus = SC_GM_DBLDOWN;
1894 : }
1895 : else
1896 0 : nMouseStatus = SC_GM_TABDOWN;
1897 : }
1898 :
1899 : //
1900 : // Links in Edit-Zellen
1901 : //
1902 :
1903 0 : sal_Bool bAlt = rMEvt.IsMod2();
1904 0 : if ( !bAlt && rMEvt.IsLeft() &&
1905 0 : GetEditUrl(rMEvt.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
1906 : {
1907 0 : SetPointer( Pointer( POINTER_REFHAND ) );
1908 0 : nMouseStatus = SC_GM_URLDOWN; // auch nur dann beim ButtonUp ausfuehren
1909 0 : return;
1910 : }
1911 :
1912 : //
1913 : // Gridwin - SelectionEngine
1914 : //
1915 :
1916 0 : if ( rMEvt.IsLeft() )
1917 : {
1918 0 : ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
1919 0 : pSelEng->SetWindow(this);
1920 0 : pSelEng->SetWhich(eWhich);
1921 0 : pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1922 :
1923 : // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1924 0 : if ( pViewData->GetView()->SelMouseButtonDown( rMEvt ) )
1925 : {
1926 0 : if (IsMouseCaptured())
1927 : {
1928 : // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1929 : //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1930 0 : ReleaseMouse();
1931 0 : StartTracking();
1932 : }
1933 0 : pViewData->GetMarkData().SetMarking(sal_True);
1934 0 : return;
1935 : }
1936 : }
1937 : }
1938 :
1939 0 : void ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
1940 : {
1941 0 : aCurMousePos = rMEvt.GetPosPixel();
1942 0 : ScDocument* pDoc = pViewData->GetDocument();
1943 0 : ScMarkData& rMark = pViewData->GetMarkData();
1944 :
1945 : // #i41690# detect a MouseButtonUp call from within MouseButtonDown
1946 : // (possible through Reschedule from storing an OLE object that is deselected)
1947 :
1948 0 : if ( nNestedButtonState == SC_NESTEDBUTTON_DOWN )
1949 0 : nNestedButtonState = SC_NESTEDBUTTON_UP;
1950 :
1951 0 : if (nButtonDown != rMEvt.GetButtons())
1952 0 : nMouseStatus = SC_GM_IGNORE; // reset und return
1953 :
1954 0 : nButtonDown = 0;
1955 :
1956 0 : if (nMouseStatus == SC_GM_IGNORE)
1957 : {
1958 0 : nMouseStatus = SC_GM_NONE;
1959 : // Selection-Engine: Markieren abbrechen
1960 0 : pViewData->GetView()->GetSelEngine()->Reset();
1961 0 : rMark.SetMarking(false);
1962 0 : if (pViewData->IsAnyFillMode())
1963 : {
1964 0 : pViewData->GetView()->StopRefMode();
1965 0 : pViewData->ResetFillMode();
1966 : }
1967 0 : StopMarking();
1968 0 : DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
1969 0 : ReleaseMouse();
1970 0 : return;
1971 : }
1972 :
1973 0 : if (nMouseStatus == SC_GM_FILTER)
1974 : {
1975 0 : nMouseStatus = SC_GM_NONE;
1976 0 : ReleaseMouse();
1977 0 : return; // da muss nix mehr passieren
1978 : }
1979 :
1980 0 : ScModule* pScMod = SC_MOD();
1981 0 : if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
1982 0 : return;
1983 :
1984 0 : SfxBindings& rBindings = pViewData->GetBindings();
1985 0 : if (bEEMouse && pViewData->HasEditView( eWhich ))
1986 : {
1987 : EditView* pEditView;
1988 : SCCOL nEditCol;
1989 : SCROW nEditRow;
1990 0 : pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
1991 0 : pEditView->MouseButtonUp( rMEvt );
1992 :
1993 0 : if ( rMEvt.IsMiddle() &&
1994 0 : GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
1995 : {
1996 : // EditView may have pasted from selection
1997 0 : pScMod->InputChanged( pEditView );
1998 : }
1999 : else
2000 0 : pScMod->InputSelection( pEditView ); // parentheses etc.
2001 :
2002 0 : pViewData->GetView()->InvalidateAttribs();
2003 0 : rBindings.Invalidate( SID_HYPERLINK_GETLINK );
2004 0 : bEEMouse = false;
2005 0 : return;
2006 : }
2007 :
2008 0 : if (bDPMouse)
2009 : {
2010 0 : DPMouseButtonUp( rMEvt ); // resets bDPMouse
2011 0 : return;
2012 : }
2013 :
2014 0 : if (bRFMouse)
2015 : {
2016 0 : RFMouseMove( rMEvt, sal_True ); // Range wieder richtigherum
2017 0 : bRFMouse = false;
2018 0 : SetPointer( Pointer( POINTER_ARROW ) );
2019 0 : ReleaseMouse();
2020 0 : return;
2021 : }
2022 :
2023 0 : if (nPagebreakMouse)
2024 : {
2025 0 : PagebreakMove( rMEvt, sal_True );
2026 0 : nPagebreakMouse = SC_PD_NONE;
2027 0 : SetPointer( Pointer( POINTER_ARROW ) );
2028 0 : ReleaseMouse();
2029 0 : return;
2030 : }
2031 :
2032 0 : if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus
2033 : {
2034 0 : ::svl::IUndoManager* pMgr = pViewData->GetDocShell()->GetUndoManager();
2035 0 : if ( pMgr->GetUndoActionCount() && pMgr->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE )
2036 0 : pMgr->Undo();
2037 0 : return;
2038 : }
2039 :
2040 0 : if (DrawMouseButtonUp(rMEvt)) // includes format paint brush handling for drawing objects
2041 : {
2042 0 : ScTabViewShell* pViewShell = pViewData->GetViewShell();
2043 0 : SfxBindings& rFrmBindings=pViewShell->GetViewFrame()->GetBindings();
2044 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_WIDTH);
2045 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_HEIGHT);
2046 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_POS_X);
2047 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_POS_Y);
2048 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_ANGLE);
2049 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_ROT_X);
2050 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_ROT_Y);
2051 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_AUTOWIDTH);
2052 0 : rFrmBindings.Invalidate(SID_ATTR_TRANSFORM_AUTOHEIGHT);
2053 0 : return;
2054 : }
2055 :
2056 0 : rMark.SetMarking(false);
2057 :
2058 0 : SetPointer( Pointer( POINTER_ARROW ) );
2059 :
2060 0 : if (pViewData->IsFillMode() ||
2061 0 : ( pViewData->GetFillMode() == SC_FILL_MATRIX && rMEvt.IsMod1() ))
2062 : {
2063 0 : nScFillModeMouseModifier = rMEvt.GetModifier();
2064 : SCCOL nStartCol;
2065 : SCROW nStartRow;
2066 : SCCOL nEndCol;
2067 : SCROW nEndRow;
2068 0 : pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
2069 0 : ScRange aDelRange;
2070 0 : sal_Bool bIsDel = pViewData->GetDelMark( aDelRange );
2071 :
2072 0 : ScViewFunc* pView = pViewData->GetView();
2073 0 : pView->StopRefMode();
2074 0 : pViewData->ResetFillMode();
2075 0 : pView->GetFunctionSet()->SetAnchorFlag( false ); // #i5819# don't use AutoFill anchor flag for selection
2076 :
2077 0 : if ( bIsDel )
2078 : {
2079 0 : pView->MarkRange( aDelRange, false );
2080 0 : pView->DeleteContents( IDF_CONTENTS );
2081 0 : SCTAB nTab = pViewData->GetTabNo();
2082 0 : ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
2083 0 : if ( aBlockRange != aDelRange )
2084 : {
2085 0 : if ( aDelRange.aStart.Row() == nStartRow )
2086 0 : aBlockRange.aEnd.SetCol( aDelRange.aStart.Col() - 1 );
2087 : else
2088 0 : aBlockRange.aEnd.SetRow( aDelRange.aStart.Row() - 1 );
2089 0 : pView->MarkRange( aBlockRange, false );
2090 : }
2091 : }
2092 : else
2093 0 : pViewData->GetDispatcher().Execute( FID_FILL_AUTO, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
2094 : }
2095 0 : else if (pViewData->GetFillMode() == SC_FILL_MATRIX)
2096 : {
2097 0 : SCTAB nTab = pViewData->GetTabNo();
2098 : SCCOL nStartCol;
2099 : SCROW nStartRow;
2100 : SCCOL nEndCol;
2101 : SCROW nEndRow;
2102 0 : pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
2103 0 : ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
2104 0 : SCCOL nFillCol = pViewData->GetRefEndX();
2105 0 : SCROW nFillRow = pViewData->GetRefEndY();
2106 0 : ScAddress aEndPos( nFillCol, nFillRow, nTab );
2107 :
2108 0 : ScTabView* pView = pViewData->GetView();
2109 0 : pView->StopRefMode();
2110 0 : pViewData->ResetFillMode();
2111 0 : pView->GetFunctionSet()->SetAnchorFlag( false );
2112 :
2113 0 : if ( aEndPos != aBlockRange.aEnd )
2114 : {
2115 0 : pViewData->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange, aEndPos, false );
2116 0 : pViewData->GetView()->MarkRange( ScRange( aBlockRange.aStart, aEndPos ) );
2117 : }
2118 : }
2119 0 : else if (pViewData->IsAnyFillMode())
2120 : {
2121 : // Embedded-Area has been changed
2122 0 : ScTabView* pView = pViewData->GetView();
2123 0 : pView->StopRefMode();
2124 0 : pViewData->ResetFillMode();
2125 0 : pView->GetFunctionSet()->SetAnchorFlag( false );
2126 0 : pViewData->GetDocShell()->UpdateOle(pViewData);
2127 : }
2128 :
2129 0 : sal_Bool bRefMode = pViewData->IsRefMode();
2130 0 : if (bRefMode)
2131 0 : pScMod->EndReference();
2132 :
2133 : //
2134 : // Giesskannen-Modus (Gestalter)
2135 : //
2136 :
2137 0 : if (pScMod->GetIsWaterCan())
2138 : {
2139 : // Abfrage auf Undo schon oben
2140 :
2141 : ScStyleSheetPool* pStylePool = (ScStyleSheetPool*)
2142 : (pViewData->GetDocument()->
2143 0 : GetStyleSheetPool());
2144 0 : if ( pStylePool )
2145 : {
2146 : SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)
2147 0 : pStylePool->GetActualStyleSheet();
2148 :
2149 0 : if ( pStyleSheet )
2150 : {
2151 0 : SfxStyleFamily eFamily = pStyleSheet->GetFamily();
2152 :
2153 0 : switch ( eFamily )
2154 : {
2155 : case SFX_STYLE_FAMILY_PARA:
2156 0 : pViewData->GetView()->SetStyleSheetToMarked( pStyleSheet );
2157 0 : pViewData->GetView()->DoneBlockMode();
2158 0 : break;
2159 :
2160 : case SFX_STYLE_FAMILY_PAGE:
2161 0 : pViewData->GetDocument()->SetPageStyle( pViewData->GetTabNo(),
2162 0 : pStyleSheet->GetName() );
2163 :
2164 : ScPrintFunc( pViewData->GetDocShell(),
2165 0 : pViewData->GetViewShell()->GetPrinter(sal_True),
2166 0 : pViewData->GetTabNo() ).UpdatePages();
2167 :
2168 0 : rBindings.Invalidate( SID_STATUS_PAGESTYLE );
2169 0 : break;
2170 :
2171 : default:
2172 0 : break;
2173 : }
2174 : }
2175 : }
2176 : }
2177 :
2178 0 : ScDBFunc* pView = pViewData->GetView();
2179 0 : ScDocument* pBrushDoc = pView->GetBrushDocument();
2180 0 : if ( pBrushDoc )
2181 : {
2182 0 : pView->PasteFromClip( IDF_ATTRIB, pBrushDoc );
2183 0 : if ( !pView->IsPaintBrushLocked() )
2184 0 : pView->ResetBrushDocument(); // invalidates pBrushDoc pointer
2185 : }
2186 :
2187 : //
2188 : // double click (only left button)
2189 : //
2190 :
2191 0 : sal_Bool bDouble = ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() );
2192 0 : if ( bDouble && !bRefMode && nMouseStatus == SC_GM_DBLDOWN && !pScMod->IsRefDialogOpen() )
2193 : {
2194 : // data pilot table
2195 0 : Point aPos = rMEvt.GetPosPixel();
2196 : SCsCOL nPosX;
2197 : SCsROW nPosY;
2198 0 : SCTAB nTab = pViewData->GetTabNo();
2199 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
2200 0 : ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, nTab );
2201 0 : if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
2202 : {
2203 0 : ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() );
2204 :
2205 : // Check for header drill-down first.
2206 0 : sheet::DataPilotTableHeaderData aData;
2207 0 : pDPObj->GetHeaderPositionData(aCellPos, aData);
2208 :
2209 0 : if ( ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
2210 0 : ! ( aData.Flags & sheet::MemberResultFlags::SUBTOTAL ) )
2211 : {
2212 : sal_uInt16 nDummy;
2213 0 : if ( pView->HasSelectionForDrillDown( nDummy ) )
2214 : {
2215 : // execute slot to show dialog
2216 0 : pViewData->GetDispatcher().Execute( SID_OUTLINE_SHOW, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
2217 : }
2218 : else
2219 : {
2220 : // toggle single entry
2221 0 : ScDPObject aNewObj( *pDPObj );
2222 0 : pDPObj->ToggleDetails( aData, &aNewObj );
2223 0 : ScDBDocFunc aFunc( *pViewData->GetDocShell() );
2224 0 : aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, false );
2225 0 : pViewData->GetView()->CursorPosChanged(); // shells may be switched
2226 0 : }
2227 : }
2228 : else
2229 : {
2230 : // Check if the data area is double-clicked.
2231 :
2232 0 : Sequence<sheet::DataPilotFieldFilter> aFilters;
2233 0 : if ( pDPObj->GetDataFieldPositionData(aCellPos, aFilters) )
2234 0 : pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters );
2235 : }
2236 :
2237 0 : return;
2238 : }
2239 :
2240 : // Check for cell protection attribute.
2241 0 : ScTableProtection* pProtect = pDoc->GetTabProtection( nTab );
2242 0 : bool bEditAllowed = true;
2243 0 : if ( pProtect && pProtect->isProtected() )
2244 : {
2245 0 : bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
2246 0 : bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
2247 0 : bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
2248 :
2249 0 : if ( bSkipProtected && bSkipUnprotected )
2250 0 : bEditAllowed = false;
2251 0 : else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
2252 0 : bEditAllowed = false;
2253 : }
2254 :
2255 0 : if ( bEditAllowed )
2256 : {
2257 : // edit cell contents
2258 0 : pViewData->GetViewShell()->UpdateInputHandler();
2259 0 : pScMod->SetInputMode( SC_INPUT_TABLE );
2260 0 : if (pViewData->HasEditView(eWhich))
2261 : {
2262 : // Text-Cursor gleich an die geklickte Stelle setzen
2263 0 : EditView* pEditView = pViewData->GetEditView( eWhich );
2264 0 : MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
2265 0 : pEditView->MouseButtonDown( aEditEvt );
2266 0 : pEditView->MouseButtonUp( aEditEvt );
2267 : }
2268 : }
2269 0 : return;
2270 : }
2271 :
2272 : //
2273 : // Links in edit cells
2274 : //
2275 :
2276 0 : sal_Bool bAlt = rMEvt.IsMod2();
2277 0 : if ( !bAlt && !bRefMode && !bDouble && nMouseStatus == SC_GM_URLDOWN )
2278 : {
2279 : // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2280 :
2281 0 : String aName, aUrl, aTarget;
2282 0 : if ( GetEditUrl( rMEvt.GetPosPixel(), &aName, &aUrl, &aTarget ) )
2283 : {
2284 0 : nMouseStatus = SC_GM_NONE; // keinen Doppelklick anfangen
2285 :
2286 : // ScGlobal::OpenURL() only understands Calc A1 style syntax.
2287 : // Convert it to Calc A1 before calling OpenURL().
2288 :
2289 0 : if (pDoc->GetAddressConvention() == formula::FormulaGrammar::CONV_OOO)
2290 0 : ScGlobal::OpenURL(aUrl, aTarget);
2291 : else
2292 : {
2293 0 : ScAddress aTempAddr;
2294 0 : ScAddress::ExternalInfo aExtInfo;
2295 0 : sal_uInt16 nRes = aTempAddr.Parse(aUrl, pDoc, pDoc->GetAddressConvention(), &aExtInfo);
2296 0 : if (!(nRes & SCA_VALID))
2297 : {
2298 : // Not a reference string. Pass it through unmodified.
2299 0 : ScGlobal::OpenURL(aUrl, aTarget);
2300 0 : return;
2301 : }
2302 :
2303 0 : OUStringBuffer aBuf;
2304 0 : if (aExtInfo.mbExternal)
2305 : {
2306 : // External reference.
2307 0 : ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
2308 0 : const OUString* pStr = pRefMgr->getExternalFileName(aExtInfo.mnFileId);
2309 0 : if (pStr)
2310 0 : aBuf.append(*pStr);
2311 :
2312 0 : aBuf.append('#');
2313 0 : aBuf.append(aExtInfo.maTabName);
2314 0 : aBuf.append('.');
2315 0 : OUString aRefCalcA1;
2316 0 : aTempAddr.Format(aRefCalcA1, SCA_ABS, NULL, formula::FormulaGrammar::CONV_OOO);
2317 0 : aBuf.append(aRefCalcA1);
2318 0 : ScGlobal::OpenURL(aBuf.makeStringAndClear(), aTarget);
2319 : }
2320 : else
2321 : {
2322 : // Internal reference.
2323 0 : aBuf.append('#');
2324 0 : OUString aUrlCalcA1;
2325 0 : aTempAddr.Format(aUrlCalcA1, SCA_ABS_3D, pDoc, formula::FormulaGrammar::CONV_OOO);
2326 0 : aBuf.append(aUrlCalcA1);
2327 0 : ScGlobal::OpenURL(aBuf.makeStringAndClear(), aTarget);
2328 0 : }
2329 : }
2330 :
2331 : // fire worksheet_followhyperlink event
2332 0 : uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor();
2333 0 : if( xVbaEvents.is() ) try
2334 : {
2335 0 : Point aPos = rMEvt.GetPosPixel();
2336 : SCsCOL nPosX;
2337 : SCsROW nPosY;
2338 0 : SCTAB nTab = pViewData->GetTabNo();
2339 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
2340 0 : OUString sURL;
2341 0 : ScRefCellValue aCell;
2342 0 : if (lcl_GetHyperlinkCell(pDoc, nPosX, nPosY, nTab, aCell, sURL))
2343 : {
2344 0 : ScAddress aCellPos( nPosX, nPosY, nTab );
2345 0 : uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) );
2346 0 : uno::Sequence< uno::Any > aArgs(1);
2347 0 : aArgs[0] <<= xCell;
2348 0 : xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs );
2349 0 : }
2350 : }
2351 0 : catch( uno::Exception& )
2352 : {
2353 : }
2354 :
2355 0 : return;
2356 0 : }
2357 : }
2358 :
2359 : //
2360 : // Gridwin - SelectionEngine
2361 : //
2362 :
2363 : // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2364 : // sal_True for any call, so IsLeft must be checked here, too.
2365 :
2366 0 : if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) )
2367 : {
2368 0 : pViewData->GetView()->SelectionChanged();
2369 :
2370 0 : SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher();
2371 0 : sal_Bool bFormulaMode = pScMod->IsFormulaMode();
2372 : OSL_ENSURE( pDisp || bFormulaMode, "Cursor auf nicht aktiver View bewegen ?" );
2373 :
2374 : // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2375 : // multiple selection, so the argument string completely describes the selection,
2376 : // and executing the slot won't change the existing selection (executing the slot
2377 : // here and from a recorded macro is treated equally)
2378 :
2379 0 : if ( pDisp && !bFormulaMode && !rMark.IsMultiMarked() )
2380 : {
2381 0 : String aAddr; // CurrentCell
2382 0 : if( rMark.IsMarked() )
2383 : {
2384 0 : ScRange aScRange;
2385 0 : rMark.GetMarkArea( aScRange );
2386 0 : aScRange.Format( aAddr, SCR_ABS );
2387 0 : if ( aScRange.aStart == aScRange.aEnd )
2388 : {
2389 : // make sure there is a range selection string even for a single cell
2390 0 : String aSingle = aAddr;
2391 0 : aAddr.Append( (sal_Char) ':' );
2392 0 : aAddr.Append( aSingle );
2393 : }
2394 :
2395 : //! SID_MARKAREA gibts nicht mehr ???
2396 : //! was passiert beim Markieren mit dem Cursor ???
2397 : }
2398 : else // nur Cursor bewegen
2399 : {
2400 0 : ScAddress aScAddress( pViewData->GetCurX(), pViewData->GetCurY(), 0 );
2401 0 : aScAddress.Format( aAddr, SCA_ABS );
2402 : }
2403 :
2404 0 : SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
2405 : // We don't want to align to the cursor position because if the
2406 : // cell cursor isn't visible after making selection, it would jump
2407 : // back to the origin of the selection where the cell cursor is.
2408 0 : SfxBoolItem aAlignCursorItem( FN_PARAM_2, false );
2409 : pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
2410 0 : &aPosItem, &aAlignCursorItem, (void*)0L );
2411 :
2412 0 : pViewData->GetView()->InvalidateAttribs();
2413 : }
2414 0 : return;
2415 : }
2416 : }
2417 :
2418 0 : void ScGridWindow::FakeButtonUp()
2419 : {
2420 0 : if ( nButtonDown )
2421 : {
2422 0 : MouseEvent aEvent( aCurMousePos ); // nButtons = 0 -> ignore
2423 0 : MouseButtonUp( aEvent );
2424 : }
2425 0 : }
2426 :
2427 0 : void ScGridWindow::MouseMove( const MouseEvent& rMEvt )
2428 : {
2429 0 : aCurMousePos = rMEvt.GetPosPixel();
2430 :
2431 0 : if ( rMEvt.IsLeaveWindow() && pNoteMarker && !pNoteMarker->IsByKeyboard() )
2432 0 : HideNoteMarker();
2433 :
2434 0 : ScModule* pScMod = SC_MOD();
2435 0 : if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
2436 0 : return;
2437 :
2438 : // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2439 : // nicht anders mit:
2440 :
2441 0 : if (bEEMouse && nButtonDown && !rMEvt.GetButtons())
2442 : {
2443 0 : bEEMouse = false;
2444 0 : nButtonDown = 0;
2445 0 : nMouseStatus = SC_GM_NONE;
2446 0 : return;
2447 : }
2448 :
2449 0 : if (nMouseStatus == SC_GM_IGNORE)
2450 0 : return;
2451 :
2452 0 : if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus -> nur auf Up warten
2453 0 : return;
2454 :
2455 0 : if ( pViewData->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2456 : {
2457 0 : SetPointer( Pointer( POINTER_FILL ) );
2458 0 : return;
2459 : }
2460 :
2461 0 : if (nMouseStatus == SC_GM_FILTER && pFilterBox)
2462 : {
2463 0 : Point aRelPos = pFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
2464 0 : if ( Rectangle(Point(),pFilterBox->GetOutputSizePixel()).IsInside(aRelPos) )
2465 : {
2466 0 : nButtonDown = 0;
2467 0 : nMouseStatus = SC_GM_NONE;
2468 0 : ReleaseMouse();
2469 0 : pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
2470 0 : return;
2471 : }
2472 : }
2473 :
2474 0 : sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
2475 :
2476 0 : if (bEEMouse && pViewData->HasEditView( eWhich ))
2477 : {
2478 : EditView* pEditView;
2479 : SCCOL nEditCol;
2480 : SCROW nEditRow;
2481 0 : pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
2482 0 : pEditView->MouseMove( rMEvt );
2483 0 : return;
2484 : }
2485 :
2486 0 : if (bDPMouse)
2487 : {
2488 0 : DPMouseMove( rMEvt );
2489 0 : return;
2490 : }
2491 :
2492 0 : if (bRFMouse)
2493 : {
2494 0 : RFMouseMove( rMEvt, false );
2495 0 : return;
2496 : }
2497 :
2498 0 : if (nPagebreakMouse)
2499 : {
2500 0 : PagebreakMove( rMEvt, false );
2501 0 : return;
2502 : }
2503 :
2504 : // anderen Mauszeiger anzeigen?
2505 :
2506 0 : sal_Bool bEditMode = pViewData->HasEditView(eWhich);
2507 :
2508 : //! Testen ob RefMode-Dragging !!!
2509 0 : if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
2510 : {
2511 0 : Point aPos = rMEvt.GetPosPixel();
2512 : SCsCOL nPosX;
2513 : SCsROW nPosY;
2514 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
2515 :
2516 : EditView* pEditView;
2517 : SCCOL nEditCol;
2518 : SCROW nEditRow;
2519 0 : pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
2520 0 : SCCOL nEndCol = pViewData->GetEditEndCol();
2521 0 : SCROW nEndRow = pViewData->GetEditEndRow();
2522 :
2523 0 : if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
2524 0 : nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
2525 : {
2526 : // Field can only be URL field
2527 0 : sal_Bool bAlt = rMEvt.IsMod2();
2528 0 : if ( !bAlt && !nButtonDown && pEditView && pEditView->GetFieldUnderMousePointer() )
2529 0 : SetPointer( Pointer( POINTER_REFHAND ) );
2530 0 : else if ( pEditView && pEditView->GetEditEngine()->IsVertical() )
2531 0 : SetPointer( Pointer( POINTER_TEXT_VERTICAL ) );
2532 : else
2533 0 : SetPointer( Pointer( POINTER_TEXT ) );
2534 0 : return;
2535 : }
2536 : }
2537 :
2538 0 : sal_Bool bWater = SC_MOD()->GetIsWaterCan() || pViewData->GetView()->HasPaintBrush();
2539 0 : if (bWater)
2540 0 : SetPointer( Pointer(POINTER_FILL) );
2541 :
2542 0 : if (!bWater)
2543 : {
2544 0 : sal_Bool bCross = false;
2545 :
2546 : // Range-Finder
2547 :
2548 : bool bCorner;
2549 0 : if ( HitRangeFinder( rMEvt.GetPosPixel(), bCorner ) )
2550 : {
2551 0 : if (bCorner)
2552 0 : SetPointer( Pointer( POINTER_CROSS ) );
2553 : else
2554 0 : SetPointer( Pointer( POINTER_HAND ) );
2555 0 : bCross = sal_True;
2556 : }
2557 :
2558 : // Page-Break-Modus
2559 :
2560 : sal_uInt16 nBreakType;
2561 0 : if ( !nButtonDown && pViewData->IsPagebreakMode() &&
2562 0 : ( nBreakType = HitPageBreak( rMEvt.GetPosPixel() ) ) != 0 )
2563 : {
2564 0 : PointerStyle eNew = POINTER_ARROW;
2565 0 : switch ( nBreakType )
2566 : {
2567 : case SC_PD_RANGE_L:
2568 : case SC_PD_RANGE_R:
2569 : case SC_PD_BREAK_H:
2570 0 : eNew = POINTER_ESIZE;
2571 0 : break;
2572 : case SC_PD_RANGE_T:
2573 : case SC_PD_RANGE_B:
2574 : case SC_PD_BREAK_V:
2575 0 : eNew = POINTER_SSIZE;
2576 0 : break;
2577 : case SC_PD_RANGE_TL:
2578 : case SC_PD_RANGE_BR:
2579 0 : eNew = POINTER_SESIZE;
2580 0 : break;
2581 : case SC_PD_RANGE_TR:
2582 : case SC_PD_RANGE_BL:
2583 0 : eNew = POINTER_NESIZE;
2584 0 : break;
2585 : }
2586 0 : SetPointer( Pointer( eNew ) );
2587 0 : bCross = sal_True;
2588 : }
2589 :
2590 : // Fill-Cursor anzeigen ?
2591 :
2592 0 : if ( !bFormulaMode && !nButtonDown )
2593 0 : if (TestMouse( rMEvt, false ))
2594 0 : bCross = sal_True;
2595 :
2596 0 : if ( nButtonDown && pViewData->IsAnyFillMode() )
2597 : {
2598 0 : SetPointer( Pointer( POINTER_CROSS ) );
2599 0 : bCross = sal_True;
2600 0 : nScFillModeMouseModifier = rMEvt.GetModifier(); // ausgewertet bei AutoFill und Matrix
2601 : }
2602 :
2603 0 : if (!bCross)
2604 : {
2605 0 : sal_Bool bAlt = rMEvt.IsMod2();
2606 :
2607 0 : if (bEditMode) // Edit-Mode muss zuerst kommen!
2608 0 : SetPointer( Pointer( POINTER_ARROW ) );
2609 0 : else if ( !bAlt && !nButtonDown &&
2610 0 : GetEditUrl(rMEvt.GetPosPixel()) )
2611 0 : SetPointer( Pointer( POINTER_REFHAND ) );
2612 0 : else if ( DrawMouseMove(rMEvt) ) // setzt Pointer um
2613 0 : return;
2614 : }
2615 : }
2616 :
2617 0 : if ( pViewData->GetView()->GetSelEngine()->SelMouseMove( rMEvt ) )
2618 0 : return;
2619 : }
2620 :
2621 0 : static void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseEvent& rEvt )
2622 : {
2623 0 : rEvent.Modifiers = 0;
2624 0 : if ( rEvt.IsShift() )
2625 0 : rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT;
2626 0 : if ( rEvt.IsMod1() )
2627 0 : rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1;
2628 0 : if ( rEvt.IsMod2() )
2629 0 : rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2;
2630 0 : if ( rEvt.IsMod3() )
2631 0 : rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD3;
2632 :
2633 0 : rEvent.Buttons = 0;
2634 0 : if ( rEvt.IsLeft() )
2635 0 : rEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT;
2636 0 : if ( rEvt.IsRight() )
2637 0 : rEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT;
2638 0 : if ( rEvt.IsMiddle() )
2639 0 : rEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE;
2640 :
2641 0 : rEvent.X = rEvt.GetPosPixel().X();
2642 0 : rEvent.Y = rEvt.GetPosPixel().Y();
2643 0 : rEvent.ClickCount = rEvt.GetClicks();
2644 0 : rEvent.PopupTrigger = false;
2645 0 : }
2646 :
2647 520 : long ScGridWindow::PreNotify( NotifyEvent& rNEvt )
2648 : {
2649 520 : bool bDone = false;
2650 520 : sal_uInt16 nType = rNEvt.GetType();
2651 520 : if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN )
2652 : {
2653 0 : Window* pWindow = rNEvt.GetWindow();
2654 0 : if (pWindow == this && pViewData)
2655 : {
2656 0 : SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame();
2657 0 : if (pViewFrame)
2658 : {
2659 0 : com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController();
2660 0 : if (xController.is())
2661 : {
2662 0 : ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
2663 0 : if (pImp && pImp->IsMouseListening())
2664 : {
2665 0 : ::com::sun::star::awt::MouseEvent aEvent;
2666 0 : lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() );
2667 0 : if ( rNEvt.GetWindow() )
2668 0 : aEvent.Source = rNEvt.GetWindow()->GetComponentInterface();
2669 0 : if ( nType == EVENT_MOUSEBUTTONDOWN)
2670 0 : bDone = pImp->MousePressed( aEvent );
2671 : else
2672 0 : bDone = pImp->MouseReleased( aEvent );
2673 : }
2674 0 : }
2675 : }
2676 : }
2677 : }
2678 520 : if (bDone) // event consumed by a listener
2679 : {
2680 0 : if ( nType == EVENT_MOUSEBUTTONDOWN )
2681 : {
2682 0 : const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent();
2683 0 : if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 )
2684 : {
2685 : // If a listener returned true for a right-click call, also prevent opening the context menu
2686 : // (this works only if the context menu is opened on mouse-down)
2687 0 : nMouseStatus = SC_GM_IGNORE;
2688 : }
2689 : }
2690 :
2691 0 : return 1;
2692 : }
2693 : else
2694 520 : return Window::PreNotify( rNEvt );
2695 : }
2696 :
2697 0 : void ScGridWindow::Tracking( const TrackingEvent& rTEvt )
2698 : {
2699 : // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2700 : // die verschiedenen MouseHandler verteilen...
2701 :
2702 0 : const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
2703 :
2704 0 : if ( rTEvt.IsTrackingCanceled() ) // alles abbrechen...
2705 : {
2706 0 : if (!pViewData->GetView()->IsInActivatePart() && !SC_MOD()->IsRefDialogOpen())
2707 : {
2708 0 : if (bDPMouse)
2709 0 : bDPMouse = false; // gezeichnet wird per bDragRect
2710 0 : if (bDragRect)
2711 : {
2712 : // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2713 0 : bDragRect = false;
2714 0 : UpdateDragRectOverlay();
2715 : }
2716 0 : if (bRFMouse)
2717 : {
2718 0 : RFMouseMove( rMEvt, true ); // richtig abbrechen geht dabei nicht...
2719 0 : bRFMouse = false;
2720 : }
2721 0 : if (nPagebreakMouse)
2722 : {
2723 : // if (bPagebreakDrawn)
2724 : // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2725 : // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
2726 0 : bPagebreakDrawn = false;
2727 0 : UpdateDragRectOverlay();
2728 0 : nPagebreakMouse = SC_PD_NONE;
2729 : }
2730 :
2731 0 : SetPointer( Pointer( POINTER_ARROW ) );
2732 0 : StopMarking();
2733 0 : MouseButtonUp( rMEvt ); // mit Status SC_GM_IGNORE aus StopMarking
2734 :
2735 0 : sal_Bool bRefMode = pViewData->IsRefMode();
2736 0 : if (bRefMode)
2737 0 : SC_MOD()->EndReference(); // Dialog nicht verkleinert lassen
2738 : }
2739 : }
2740 0 : else if ( rTEvt.IsTrackingEnded() )
2741 : {
2742 : // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2743 : // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2744 : // abgebrochen wurde.
2745 :
2746 0 : MouseEvent aUpEvt( rMEvt.GetPosPixel(), rMEvt.GetClicks(),
2747 0 : rMEvt.GetMode(), nButtonDown, rMEvt.GetModifier() );
2748 0 : MouseButtonUp( aUpEvt );
2749 : }
2750 : else
2751 0 : MouseMove( rMEvt );
2752 0 : }
2753 :
2754 0 : void ScGridWindow::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
2755 : {
2756 0 : if ( pFilterBox || nPagebreakMouse )
2757 0 : return;
2758 :
2759 0 : HideNoteMarker();
2760 :
2761 0 : CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );
2762 :
2763 0 : if (bEEMouse && pViewData->HasEditView( eWhich ))
2764 : {
2765 : EditView* pEditView;
2766 : SCCOL nEditCol;
2767 : SCROW nEditRow;
2768 0 : pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
2769 :
2770 : // don't remove the edit view while switching views
2771 0 : ScModule* pScMod = SC_MOD();
2772 0 : pScMod->SetInEditCommand( sal_True );
2773 :
2774 0 : pEditView->Command( aDragEvent );
2775 :
2776 0 : ScInputHandler* pHdl = pScMod->GetInputHdl();
2777 0 : if (pHdl)
2778 0 : pHdl->DataChanged();
2779 :
2780 0 : pScMod->SetInEditCommand( false );
2781 0 : if (!pViewData->IsActive()) // dropped to different view?
2782 : {
2783 0 : ScInputHandler* pViewHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
2784 0 : if ( pViewHdl && pViewData->HasEditView( eWhich ) )
2785 : {
2786 0 : pViewHdl->CancelHandler();
2787 0 : ShowCursor(); // missing from KillEditView
2788 : }
2789 : }
2790 : }
2791 : else
2792 0 : if ( !DrawCommand(aDragEvent) )
2793 0 : pViewData->GetView()->GetSelEngine()->Command( aDragEvent );
2794 : }
2795 :
2796 0 : static void lcl_SetTextCursorPos( ScViewData* pViewData, ScSplitPos eWhich, Window* pWin )
2797 : {
2798 0 : SCCOL nCol = pViewData->GetCurX();
2799 0 : SCROW nRow = pViewData->GetCurY();
2800 0 : Rectangle aEditArea = pViewData->GetEditArea( eWhich, nCol, nRow, pWin, NULL, sal_True );
2801 0 : aEditArea.Right() = aEditArea.Left();
2802 0 : aEditArea = pWin->PixelToLogic( aEditArea );
2803 0 : pWin->SetCursorRect( &aEditArea );
2804 0 : }
2805 :
2806 0 : void ScGridWindow::Command( const CommandEvent& rCEvt )
2807 : {
2808 : // The command event is send to the window after a possible context
2809 : // menu from an inplace client is closed. Now we have the chance to
2810 : // deactivate the inplace client without any problem regarding parent
2811 : // windows and code on the stack.
2812 0 : sal_uInt16 nCmd = rCEvt.GetCommand();
2813 0 : ScTabViewShell* pTabViewSh = pViewData->GetViewShell();
2814 0 : SfxInPlaceClient* pClient = pTabViewSh->GetIPClient();
2815 0 : if ( pClient &&
2816 0 : pClient->IsObjectInPlaceActive() &&
2817 : nCmd == COMMAND_CONTEXTMENU )
2818 : {
2819 0 : pTabViewSh->DeactivateOle();
2820 0 : return;
2821 : }
2822 :
2823 0 : ScModule* pScMod = SC_MOD();
2824 : OSL_ENSURE( nCmd != COMMAND_STARTDRAG, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2825 :
2826 0 : if ( nCmd == COMMAND_STARTEXTTEXTINPUT ||
2827 0 : nCmd == COMMAND_ENDEXTTEXTINPUT ||
2828 0 : nCmd == COMMAND_EXTTEXTINPUT ||
2829 0 : nCmd == COMMAND_CURSORPOS ||
2830 : nCmd == COMMAND_QUERYCHARPOSITION )
2831 : {
2832 0 : sal_Bool bEditView = pViewData->HasEditView( eWhich );
2833 0 : if (!bEditView)
2834 : {
2835 : // only if no cell editview is active, look at drawview
2836 0 : SdrView* pSdrView = pViewData->GetView()->GetSdrView();
2837 0 : if ( pSdrView )
2838 : {
2839 0 : OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
2840 0 : if ( pOlView && pOlView->GetWindow() == this )
2841 : {
2842 0 : pOlView->Command( rCEvt );
2843 0 : return; // done
2844 : }
2845 : }
2846 : }
2847 :
2848 0 : if ( nCmd == COMMAND_CURSORPOS && !bEditView )
2849 : {
2850 : // CURSORPOS may be called without following text input,
2851 : // to set the input method window position
2852 : // -> input mode must not be started,
2853 : // manually calculate text insert position if not in input mode
2854 :
2855 0 : lcl_SetTextCursorPos( pViewData, eWhich, this );
2856 0 : return;
2857 : }
2858 :
2859 0 : ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
2860 0 : if ( pHdl )
2861 : {
2862 0 : pHdl->InputCommand( rCEvt, sal_True );
2863 0 : return; // done
2864 : }
2865 :
2866 0 : Window::Command( rCEvt );
2867 0 : return;
2868 : }
2869 :
2870 0 : if ( nCmd == COMMAND_PASTESELECTION )
2871 : {
2872 0 : if ( bEEMouse )
2873 : {
2874 : // EditEngine handles selection in MouseButtonUp - no action
2875 : // needed in command handler
2876 : }
2877 : else
2878 : {
2879 0 : PasteSelection( rCEvt.GetMousePosPixel() );
2880 : }
2881 0 : return;
2882 : }
2883 :
2884 0 : if ( nCmd == COMMAND_INPUTLANGUAGECHANGE )
2885 : {
2886 : // #i55929# Font and font size state depends on input language if nothing is selected,
2887 : // so the slots have to be invalidated when the input language is changed.
2888 :
2889 0 : SfxBindings& rBindings = pViewData->GetBindings();
2890 0 : rBindings.Invalidate( SID_ATTR_CHAR_FONT );
2891 0 : rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
2892 0 : return;
2893 : }
2894 :
2895 0 : if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
2896 : {
2897 0 : sal_Bool bDone = pViewData->GetView()->ScrollCommand( rCEvt, eWhich );
2898 0 : if (!bDone)
2899 0 : Window::Command(rCEvt);
2900 0 : return;
2901 : }
2902 : // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2903 0 : sal_Bool bDisable = pScMod->IsFormulaMode() ||
2904 0 : pScMod->IsModalMode(pViewData->GetSfxDocShell());
2905 0 : if (bDisable)
2906 0 : return;
2907 :
2908 0 : if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() )
2909 : {
2910 0 : sal_Bool bMouse = rCEvt.IsMouseEvent();
2911 0 : if ( bMouse && nMouseStatus == SC_GM_IGNORE )
2912 0 : return;
2913 :
2914 0 : if (pViewData->IsAnyFillMode())
2915 : {
2916 0 : pViewData->GetView()->StopRefMode();
2917 0 : pViewData->ResetFillMode();
2918 : }
2919 0 : ReleaseMouse();
2920 0 : StopMarking();
2921 :
2922 0 : Point aPosPixel = rCEvt.GetMousePosPixel();
2923 0 : Point aMenuPos = aPosPixel;
2924 :
2925 0 : if ( bMouse )
2926 : {
2927 0 : SCsCOL nCellX = -1;
2928 0 : SCsROW nCellY = -1;
2929 0 : pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
2930 0 : ScDocument* pDoc = pViewData->GetDocument();
2931 0 : SCTAB nTab = pViewData->GetTabNo();
2932 0 : const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
2933 0 : bool bSelectAllowed = true;
2934 0 : if ( pProtect && pProtect->isProtected() )
2935 : {
2936 : // This sheet is protected. Check if a context menu is allowed on this cell.
2937 0 : bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED);
2938 0 : bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
2939 0 : bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
2940 :
2941 0 : if (bCellProtected)
2942 0 : bSelectAllowed = bSelProtected;
2943 : else
2944 0 : bSelectAllowed = bSelUnprotected;
2945 : }
2946 0 : if (!bSelectAllowed)
2947 : // Selecting this cell is not allowed, neither is context menu.
2948 0 : return;
2949 :
2950 : // #i18735# First select the item under the mouse pointer.
2951 : // This can change the selection, and the view state (edit mode, etc).
2952 0 : SelectForContextMenu( aPosPixel, nCellX, nCellY );
2953 : }
2954 :
2955 0 : sal_Bool bDone = false;
2956 0 : sal_Bool bEdit = pViewData->HasEditView(eWhich);
2957 0 : if ( !bEdit )
2958 : {
2959 : // Edit-Zelle mit Spelling-Errors ?
2960 0 : if ( bMouse && GetEditUrlOrError( sal_True, aPosPixel ) )
2961 : {
2962 : // GetEditUrlOrError hat den Cursor schon bewegt
2963 :
2964 0 : pScMod->SetInputMode( SC_INPUT_TABLE );
2965 0 : bEdit = pViewData->HasEditView(eWhich); // hat's geklappt ?
2966 :
2967 : OSL_ENSURE( bEdit, "kann nicht in Edit-Modus schalten" );
2968 : }
2969 : }
2970 0 : if ( bEdit )
2971 : {
2972 0 : EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0
2973 :
2974 0 : if ( !bMouse )
2975 : {
2976 0 : Cursor* pCur = pEditView->GetCursor();
2977 0 : if ( pCur )
2978 : {
2979 0 : Point aLogicPos = pCur->GetPos();
2980 : // use the position right of the cursor (spell popup is opened if
2981 : // the cursor is before the word, but not if behind it)
2982 0 : aLogicPos.X() += pCur->GetWidth();
2983 0 : aLogicPos.Y() += pCur->GetHeight() / 2; // center vertically
2984 0 : aMenuPos = LogicToPixel( aLogicPos );
2985 : }
2986 : }
2987 :
2988 : // if edit mode was just started above, online spelling may be incomplete
2989 0 : pEditView->GetEditEngine()->CompleteOnlineSpelling();
2990 :
2991 : // IsCursorAtWrongSpelledWord could be used for !bMouse
2992 : // if there was a corresponding ExecuteSpellPopup call
2993 :
2994 0 : if( pEditView->IsWrongSpelledWordAtPos( aMenuPos ) )
2995 : {
2996 : // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
2997 : // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
2998 : // (Bug #40968#)
2999 0 : ScInputHandler* pHdl = pScMod->GetInputHdl();
3000 0 : if (pHdl)
3001 0 : pHdl->SetModified();
3002 :
3003 0 : Link aLink = LINK( this, ScGridWindow, PopupSpellingHdl );
3004 0 : pEditView->ExecuteSpellPopup( aMenuPos, &aLink );
3005 :
3006 0 : bDone = sal_True;
3007 : }
3008 : }
3009 0 : else if ( !bMouse )
3010 : {
3011 : // non-edit menu by keyboard -> use lower right of cell cursor position
3012 0 : ScDocument* aDoc = pViewData->GetDocument();
3013 0 : SCTAB nTabNo = pViewData->GetTabNo();
3014 0 : sal_Bool bLayoutIsRTL = aDoc->IsLayoutRTL(nTabNo);
3015 :
3016 0 : SCCOL nCurX = pViewData->GetCurX();
3017 0 : SCROW nCurY = pViewData->GetCurY();
3018 0 : aMenuPos = pViewData->GetScrPos( nCurX, nCurY, eWhich, sal_True );
3019 : long nSizeXPix;
3020 : long nSizeYPix;
3021 0 : pViewData->GetMergeSizePixel( nCurX, nCurY, nSizeXPix, nSizeYPix );
3022 : // fdo#55432 take the correct position for RTL sheet
3023 0 : aMenuPos.X() += bLayoutIsRTL ? -nSizeXPix : nSizeXPix;
3024 0 : aMenuPos.Y() += nSizeYPix;
3025 :
3026 0 : if (pViewData)
3027 : {
3028 0 : ScTabViewShell* pViewSh = pViewData->GetViewShell();
3029 0 : if (pViewSh)
3030 : {
3031 : // Is a draw object selected?
3032 :
3033 0 : SdrView* pDrawView = pViewSh->GetSdrView();
3034 0 : if (pDrawView && pDrawView->AreObjectsMarked())
3035 : {
3036 : // #100442#; the conext menu should open in the middle of the selected objects
3037 0 : Rectangle aSelectRect(LogicToPixel(pDrawView->GetAllMarkedBoundRect()));
3038 0 : aMenuPos = aSelectRect.Center();
3039 : }
3040 : }
3041 : }
3042 : }
3043 :
3044 0 : if (!bDone)
3045 : {
3046 0 : SfxDispatcher::ExecutePopup( 0, this, &aMenuPos );
3047 : }
3048 : }
3049 : }
3050 :
3051 0 : void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY )
3052 : {
3053 : // #i18735# if the click was outside of the current selection,
3054 : // the cursor is moved or an object at the click position selected.
3055 : // (see SwEditWin::SelectMenuPosition in Writer)
3056 :
3057 0 : ScTabView* pView = pViewData->GetView();
3058 0 : ScDrawView* pDrawView = pView->GetScDrawView();
3059 :
3060 : // check cell edit mode
3061 :
3062 0 : if ( pViewData->HasEditView(eWhich) )
3063 : {
3064 0 : ScModule* pScMod = SC_MOD();
3065 0 : SCCOL nEditStartCol = pViewData->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
3066 0 : SCROW nEditStartRow = pViewData->GetEditViewRow();
3067 0 : SCCOL nEditEndCol = pViewData->GetEditEndCol();
3068 0 : SCROW nEditEndRow = pViewData->GetEditEndRow();
3069 :
3070 0 : if ( nCellX >= (SCsCOL) nEditStartCol && nCellX <= (SCsCOL) nEditEndCol &&
3071 0 : nCellY >= (SCsROW) nEditStartRow && nCellY <= (SCsROW) nEditEndRow )
3072 : {
3073 : // handle selection within the EditView
3074 :
3075 0 : EditView* pEditView = pViewData->GetEditView( eWhich ); // not NULL (HasEditView)
3076 0 : EditEngine* pEditEngine = pEditView->GetEditEngine();
3077 0 : Rectangle aOutputArea = pEditView->GetOutputArea();
3078 0 : Rectangle aVisArea = pEditView->GetVisArea();
3079 :
3080 0 : Point aTextPos = PixelToLogic( rPosPixel );
3081 0 : if ( pEditEngine->IsVertical() ) // have to manually transform position
3082 : {
3083 0 : aTextPos -= aOutputArea.TopRight();
3084 0 : long nTemp = -aTextPos.X();
3085 0 : aTextPos.X() = aTextPos.Y();
3086 0 : aTextPos.Y() = nTemp;
3087 : }
3088 : else
3089 0 : aTextPos -= aOutputArea.TopLeft();
3090 0 : aTextPos += aVisArea.TopLeft(); // position in the edit document
3091 :
3092 0 : EPosition aDocPosition = pEditEngine->FindDocPosition(aTextPos);
3093 0 : ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
3094 0 : ESelection aSelection = pEditView->GetSelection();
3095 0 : aSelection.Adjust(); // needed for IsLess/IsGreater
3096 0 : if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
3097 : {
3098 : // clicked outside the selected text - deselect and move text cursor
3099 0 : MouseEvent aEvent( rPosPixel );
3100 0 : pEditView->MouseButtonDown( aEvent );
3101 0 : pEditView->MouseButtonUp( aEvent );
3102 0 : pScMod->InputSelection( pEditView );
3103 : }
3104 :
3105 0 : return; // clicked within the edit view - keep edit mode
3106 : }
3107 : else
3108 : {
3109 : // outside of the edit view - end edit mode, regardless of cell selection, then continue
3110 0 : pScMod->InputEnterHandler();
3111 : }
3112 : }
3113 :
3114 : // check draw text edit mode
3115 :
3116 0 : Point aLogicPos = PixelToLogic( rPosPixel ); // after cell edit mode is ended
3117 0 : if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() )
3118 : {
3119 0 : OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView();
3120 0 : Rectangle aOutputArea = pOlView->GetOutputArea();
3121 0 : if ( aOutputArea.IsInside( aLogicPos ) )
3122 : {
3123 : // handle selection within the OutlinerView
3124 :
3125 0 : Outliner* pOutliner = pOlView->GetOutliner();
3126 0 : const EditEngine& rEditEngine = pOutliner->GetEditEngine();
3127 0 : Rectangle aVisArea = pOlView->GetVisArea();
3128 :
3129 0 : Point aTextPos = aLogicPos;
3130 0 : if ( pOutliner->IsVertical() ) // have to manually transform position
3131 : {
3132 0 : aTextPos -= aOutputArea.TopRight();
3133 0 : long nTemp = -aTextPos.X();
3134 0 : aTextPos.X() = aTextPos.Y();
3135 0 : aTextPos.Y() = nTemp;
3136 : }
3137 : else
3138 0 : aTextPos -= aOutputArea.TopLeft();
3139 0 : aTextPos += aVisArea.TopLeft(); // position in the edit document
3140 :
3141 0 : EPosition aDocPosition = rEditEngine.FindDocPosition(aTextPos);
3142 0 : ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
3143 0 : ESelection aSelection = pOlView->GetSelection();
3144 0 : aSelection.Adjust(); // needed for IsLess/IsGreater
3145 0 : if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
3146 : {
3147 : // clicked outside the selected text - deselect and move text cursor
3148 : // use DrawView to allow extra handling there (none currently)
3149 0 : MouseEvent aEvent( rPosPixel );
3150 0 : pDrawView->MouseButtonDown( aEvent, this );
3151 0 : pDrawView->MouseButtonUp( aEvent, this );
3152 : }
3153 :
3154 0 : return; // clicked within the edit area - keep edit mode
3155 : }
3156 : else
3157 : {
3158 : // Outside of the edit area - end text edit mode, then continue.
3159 : // DrawDeselectAll also ends text edit mode and updates the shells.
3160 : // If the click was on the edited object, it will be selected again below.
3161 0 : pView->DrawDeselectAll();
3162 : }
3163 : }
3164 :
3165 : // look for existing selection
3166 :
3167 0 : sal_Bool bHitSelected = false;
3168 0 : if ( pDrawView && pDrawView->IsMarkedObjHit( aLogicPos ) )
3169 : {
3170 : // clicked on selected object -> don't change anything
3171 0 : bHitSelected = sal_True;
3172 : }
3173 0 : else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) )
3174 : {
3175 : // clicked on selected cell -> don't change anything
3176 0 : bHitSelected = sal_True;
3177 : }
3178 :
3179 : // select drawing object or move cell cursor
3180 :
3181 0 : if ( !bHitSelected )
3182 : {
3183 0 : sal_Bool bWasDraw = ( pDrawView && pDrawView->AreObjectsMarked() );
3184 0 : sal_Bool bHitDraw = false;
3185 0 : if ( pDrawView )
3186 : {
3187 0 : pDrawView->UnmarkAllObj();
3188 : // Unlock the Internal Layer in order to activate the context menu.
3189 : // re-lock in ScDrawView::MarkListHasChanged()
3190 0 : lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), pDrawView->GetModel(), aLogicPos ,pViewData);
3191 0 : bHitDraw = pDrawView->MarkObj( aLogicPos );
3192 : // draw shell is activated in MarkListHasChanged
3193 : }
3194 0 : if ( !bHitDraw )
3195 : {
3196 0 : pView->Unmark();
3197 0 : pView->SetCursor(nCellX, nCellY);
3198 0 : if ( bWasDraw )
3199 0 : pViewData->GetViewShell()->SetDrawShell( false ); // switch shells
3200 : }
3201 : }
3202 : }
3203 :
3204 0 : void ScGridWindow::KeyInput(const KeyEvent& rKEvt)
3205 : {
3206 : // Cursor control for ref input dialog
3207 0 : const KeyCode& rKeyCode = rKEvt.GetKeyCode();
3208 0 : if( SC_MOD()->IsRefDialogOpen() )
3209 : {
3210 0 : if( !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
3211 : {
3212 0 : SC_MOD()->EndReference();
3213 0 : return;
3214 : }
3215 0 : else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) )
3216 : {
3217 : ScRange aRef(
3218 0 : pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
3219 0 : pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
3220 0 : SC_MOD()->SetReference( aRef, pViewData->GetDocument() );
3221 0 : return;
3222 : }
3223 : }
3224 0 : else if( rKeyCode.GetCode() == KEY_RETURN && pViewData->IsPasteMode() )
3225 : {
3226 0 : ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
3227 0 : ScClipUtil::PasteFromClipboard( pViewData, pTabViewShell, false );
3228 :
3229 : // Clear clipboard content.
3230 : uno::Reference<datatransfer::clipboard::XClipboard> xSystemClipboard =
3231 0 : TransferableHelper::GetSystemClipboard();
3232 0 : if (xSystemClipboard.is())
3233 : {
3234 0 : xSystemClipboard->setContents(
3235 : uno::Reference<datatransfer::XTransferable>(),
3236 0 : uno::Reference<datatransfer::clipboard::XClipboardOwner>());
3237 : }
3238 :
3239 : // hide the border around the copy source
3240 0 : pViewData->SetPasteMode( SC_PASTE_NONE );
3241 0 : UpdateCopySourceOverlay();
3242 0 : return;
3243 : }
3244 : // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3245 0 : else if( !pViewData->IsAnyFillMode() )
3246 : {
3247 0 : if (rKeyCode.GetCode() == KEY_ESCAPE)
3248 : {
3249 0 : pViewData->SetPasteMode( SC_PASTE_NONE );
3250 0 : UpdateCopySourceOverlay();
3251 : }
3252 : // query for existing note marker before calling ViewShell's keyboard handling
3253 : // which may remove the marker
3254 0 : sal_Bool bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() );
3255 0 : ScTabViewShell* pViewSh = pViewData->GetViewShell();
3256 :
3257 0 : if (pViewData->GetDocShell()->GetProgress())
3258 0 : return;
3259 :
3260 0 : if (DrawKeyInput(rKEvt))
3261 : {
3262 0 : const KeyCode& rLclKeyCode = rKEvt.GetKeyCode();
3263 0 : if (rLclKeyCode.GetCode() == KEY_DOWN
3264 0 : || rLclKeyCode.GetCode() == KEY_UP
3265 0 : || rLclKeyCode.GetCode() == KEY_LEFT
3266 0 : || rLclKeyCode.GetCode() == KEY_RIGHT)
3267 : {
3268 0 : ScTabViewShell* pViewShell = pViewData->GetViewShell();
3269 0 : SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings();
3270 0 : rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_X);
3271 0 : rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_Y);
3272 : }
3273 0 : return;
3274 : }
3275 :
3276 0 : if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3277 : { //! DrawShell abfragen !!!
3278 0 : if (pViewSh->TabKeyInput(rKEvt))
3279 0 : return;
3280 : }
3281 : else
3282 0 : if (pViewSh->SfxViewShell::KeyInput(rKEvt)) // von SfxViewShell
3283 0 : return;
3284 :
3285 0 : KeyCode aCode = rKEvt.GetKeyCode();
3286 0 : if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 )
3287 : {
3288 0 : if ( bHadKeyMarker )
3289 0 : HideNoteMarker();
3290 : else
3291 0 : pViewSh->Escape();
3292 0 : return;
3293 : }
3294 0 : if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 )
3295 : {
3296 : // ctrl-F1 shows or hides the note or redlining info for the cursor position
3297 : // (hard-coded because F1 can't be configured)
3298 :
3299 0 : if ( bHadKeyMarker )
3300 0 : HideNoteMarker(); // hide when previously visible
3301 : else
3302 0 : ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), sal_True );
3303 0 : return;
3304 : }
3305 0 : if (aCode.GetCode() == KEY_BRACKETLEFT && aCode.GetModifier() == KEY_MOD1)
3306 : {
3307 0 : pViewSh->DetectiveMarkPred();
3308 0 : return;
3309 : }
3310 0 : if (aCode.GetCode() == KEY_BRACKETRIGHT && aCode.GetModifier() == KEY_MOD1)
3311 : {
3312 0 : pViewSh->DetectiveMarkSucc();
3313 0 : return;
3314 : }
3315 :
3316 : }
3317 :
3318 0 : Window::KeyInput(rKEvt);
3319 : }
3320 :
3321 412 : void ScGridWindow::StopMarking()
3322 : {
3323 412 : DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3324 :
3325 412 : if (nButtonDown)
3326 : {
3327 0 : pViewData->GetMarkData().SetMarking(false);
3328 0 : nMouseStatus = SC_GM_IGNORE;
3329 : }
3330 412 : }
3331 :
3332 508 : void ScGridWindow::UpdateInputContext()
3333 : {
3334 508 : sal_Bool bReadOnly = pViewData->GetDocShell()->IsReadOnly();
3335 508 : sal_uLong nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT );
3336 :
3337 : // when font from InputContext is used,
3338 : // it must be taken from the cursor position's cell attributes
3339 :
3340 508 : InputContext aContext;
3341 508 : aContext.SetOptions( nOptions );
3342 508 : SetInputContext( aContext );
3343 508 : }
3344 :
3345 : //--------------------------------------------------------
3346 :
3347 : // sensitiver Bereich (Pixel)
3348 : #define SCROLL_SENSITIVE 20
3349 :
3350 0 : bool ScGridWindow::DropScroll( const Point& rMousePos )
3351 : {
3352 0 : SCsCOL nDx = 0;
3353 0 : SCsROW nDy = 0;
3354 0 : Size aSize = GetOutputSizePixel();
3355 :
3356 0 : if (aSize.Width() > SCROLL_SENSITIVE * 3)
3357 : {
3358 0 : if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 )
3359 0 : nDx = -1;
3360 0 : if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE
3361 0 : && pViewData->GetPosX(WhichH(eWhich)) < MAXCOL )
3362 0 : nDx = 1;
3363 : }
3364 0 : if (aSize.Height() > SCROLL_SENSITIVE * 3)
3365 : {
3366 0 : if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 )
3367 0 : nDy = -1;
3368 0 : if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE
3369 0 : && pViewData->GetPosY(WhichV(eWhich)) < MAXROW )
3370 0 : nDy = 1;
3371 : }
3372 :
3373 0 : if ( nDx != 0 || nDy != 0 )
3374 : {
3375 0 : if ( nDx != 0 )
3376 0 : pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
3377 0 : if ( nDy != 0 )
3378 0 : pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
3379 : }
3380 :
3381 0 : return false;
3382 : }
3383 :
3384 0 : static sal_Bool lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange)
3385 : {
3386 : // Testet, ob bei eingeschalteten RedLining,
3387 : // bei einem Drop ein Scenario betroffen ist.
3388 :
3389 0 : sal_Bool bReturn = false;
3390 0 : SCTAB nTab = aDragRange.aStart.Tab();
3391 0 : SCTAB nTabCount = pDoc->GetTableCount();
3392 :
3393 0 : if(pDoc->GetChangeTrack()!=NULL)
3394 : {
3395 0 : if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange))
3396 : {
3397 0 : bReturn = sal_True;
3398 : }
3399 : else
3400 : {
3401 0 : for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
3402 : {
3403 0 : if(pDoc->HasScenarioRange(i, aDragRange))
3404 : {
3405 0 : bReturn = sal_True;
3406 0 : break;
3407 : }
3408 : }
3409 : }
3410 : }
3411 0 : return bReturn;
3412 : }
3413 :
3414 0 : static ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource )
3415 : {
3416 0 : SCCOL nCol1 = nPosX;
3417 0 : SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() );
3418 0 : if ( nCol2 > MAXCOL )
3419 : {
3420 0 : nCol1 -= nCol2 - MAXCOL;
3421 0 : nCol2 = MAXCOL;
3422 : }
3423 0 : SCROW nRow1 = nPosY;
3424 0 : SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() );
3425 0 : if ( nRow2 > MAXROW )
3426 : {
3427 0 : nRow1 -= nRow2 - MAXROW;
3428 0 : nRow2 = MAXROW;
3429 : }
3430 :
3431 0 : return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
3432 : }
3433 :
3434 : //--------------------------------------------------------
3435 :
3436 : extern sal_Bool bPasteIsDrop; // viewfun4 -> move to header
3437 : extern sal_Bool bPasteIsMove; // viewfun7 -> move to header
3438 :
3439 : //--------------------------------------------------------
3440 :
3441 0 : sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt )
3442 : {
3443 0 : if ( rEvt.mbLeaving )
3444 : {
3445 0 : bDragRect = false;
3446 0 : UpdateDragRectOverlay();
3447 0 : return rEvt.mnAction;
3448 : }
3449 :
3450 0 : const ScDragData& rData = SC_MOD()->GetDragData();
3451 0 : if ( rData.pCellTransfer )
3452 : {
3453 : // Don't move source that would include filtered rows.
3454 0 : if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows())
3455 : {
3456 0 : if (bDragRect)
3457 : {
3458 0 : bDragRect = false;
3459 0 : UpdateDragRectOverlay();
3460 : }
3461 0 : return DND_ACTION_NONE;
3462 : }
3463 :
3464 0 : Point aPos = rEvt.maPosPixel;
3465 :
3466 0 : ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument();
3467 0 : ScDocument* pThisDoc = pViewData->GetDocument();
3468 0 : if (pSourceDoc == pThisDoc)
3469 : {
3470 0 : OUString aName;
3471 0 : if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos), aName ))
3472 : {
3473 0 : if (bDragRect) // Rechteck loeschen
3474 : {
3475 0 : bDragRect = false;
3476 0 : UpdateDragRectOverlay();
3477 : }
3478 :
3479 : //! highlight chart? (selection border?)
3480 :
3481 0 : sal_Int8 nRet = rEvt.mnAction;
3482 0 : return nRet;
3483 0 : }
3484 : }
3485 :
3486 0 : if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) // whole sheet?
3487 : {
3488 0 : sal_Bool bOk = pThisDoc->IsDocEditable();
3489 0 : return bOk ? rEvt.mnAction : 0; // don't draw selection frame
3490 : }
3491 :
3492 : SCsCOL nPosX;
3493 : SCsROW nPosY;
3494 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
3495 :
3496 0 : ScRange aSourceRange = rData.pCellTransfer->GetRange();
3497 0 : SCCOL nSourceStartX = aSourceRange.aStart.Col();
3498 0 : SCROW nSourceStartY = aSourceRange.aStart.Row();
3499 0 : SCCOL nSourceEndX = aSourceRange.aEnd.Col();
3500 0 : SCROW nSourceEndY = aSourceRange.aEnd.Row();
3501 0 : SCCOL nSizeX = nSourceEndX - nSourceStartX + 1;
3502 0 : SCROW nSizeY = nSourceEndY - nSourceStartY + 1;
3503 :
3504 0 : if ( rEvt.mnAction != DND_ACTION_MOVE )
3505 0 : nSizeY = rData.pCellTransfer->GetNonFilteredRows(); // copy/link: no filtered rows
3506 :
3507 0 : SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX();
3508 0 : if (nNewDragX<0) nNewDragX=0;
3509 0 : if (nNewDragX+(nSizeX-1) > MAXCOL)
3510 0 : nNewDragX = MAXCOL-(nSizeX-1);
3511 0 : SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY();
3512 0 : if (nNewDragY<0) nNewDragY=0;
3513 0 : if (nNewDragY+(nSizeY-1) > MAXROW)
3514 0 : nNewDragY = MAXROW-(nSizeY-1);
3515 :
3516 : // don't break scenario ranges, don't drop on filtered
3517 0 : SCTAB nTab = pViewData->GetTabNo();
3518 0 : ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange );
3519 0 : if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) ||
3520 0 : lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) ||
3521 0 : ScViewUtil::HasFiltered( aDropRange, pThisDoc) )
3522 : {
3523 0 : if (bDragRect)
3524 : {
3525 0 : bDragRect = false;
3526 0 : UpdateDragRectOverlay();
3527 : }
3528 0 : return DND_ACTION_NONE;
3529 : }
3530 :
3531 0 : InsCellCmd eDragInsertMode = INS_NONE;
3532 0 : Window::PointerState aState = GetPointerState();
3533 :
3534 : // check for datapilot item sorting
3535 0 : ScDPObject* pDPObj = NULL;
3536 0 : if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL )
3537 : {
3538 : // drop on DataPilot table: sort or nothing
3539 :
3540 0 : bool bDPSort = false;
3541 0 : if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj )
3542 : {
3543 0 : sheet::DataPilotTableHeaderData aDestData;
3544 0 : pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData );
3545 0 : bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field
3546 :
3547 : // look through the source range
3548 0 : for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow )
3549 0 : for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol )
3550 : {
3551 0 : sheet::DataPilotTableHeaderData aSourceData;
3552 0 : pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData );
3553 0 : if ( aSourceData.Dimension != aDestData.Dimension || aSourceData.MemberName.isEmpty() )
3554 0 : bValid = false; // empty (subtotal) or different field
3555 0 : }
3556 :
3557 0 : if ( bValid )
3558 : {
3559 : bool bIsDataLayout;
3560 0 : OUString aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
3561 0 : const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName );
3562 0 : if ( pDim )
3563 : {
3564 0 : ScRange aOutRange = pDPObj->GetOutRange();
3565 :
3566 0 : sal_uInt16 nOrient = pDim->GetOrientation();
3567 0 : if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN )
3568 : {
3569 0 : eDragInsertMode = INS_CELLSRIGHT;
3570 0 : nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1;
3571 0 : bDPSort = true;
3572 : }
3573 0 : else if ( nOrient == sheet::DataPilotFieldOrientation_ROW )
3574 : {
3575 0 : eDragInsertMode = INS_CELLSDOWN;
3576 0 : nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1;
3577 0 : bDPSort = true;
3578 : }
3579 0 : }
3580 0 : }
3581 : }
3582 :
3583 0 : if ( !bDPSort )
3584 : {
3585 : // no valid sorting in a DataPilot table -> disallow
3586 0 : if ( bDragRect )
3587 : {
3588 0 : bDragRect = false;
3589 0 : UpdateDragRectOverlay();
3590 : }
3591 0 : return DND_ACTION_NONE;
3592 : }
3593 : }
3594 0 : else if ( aState.mnState & KEY_MOD2 )
3595 : {
3596 0 : if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() )
3597 : {
3598 0 : long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) );
3599 0 : long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) );
3600 0 : if ( nDeltaX <= nDeltaY )
3601 : {
3602 0 : eDragInsertMode = INS_CELLSDOWN;
3603 : }
3604 : else
3605 : {
3606 0 : eDragInsertMode = INS_CELLSRIGHT;
3607 : }
3608 :
3609 0 : if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY &&
3610 0 : ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX &&
3611 0 : ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) ||
3612 0 : ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX &&
3613 0 : ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY &&
3614 0 : ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) )
3615 : {
3616 0 : if ( bDragRect )
3617 : {
3618 0 : bDragRect = false;
3619 0 : UpdateDragRectOverlay();
3620 : }
3621 0 : return DND_ACTION_NONE;
3622 : }
3623 : }
3624 : else
3625 : {
3626 0 : if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) )
3627 : {
3628 0 : eDragInsertMode = INS_CELLSDOWN;
3629 :
3630 : }
3631 : else
3632 : {
3633 0 : eDragInsertMode = INS_CELLSRIGHT;
3634 : }
3635 : }
3636 : }
3637 :
3638 0 : if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY ||
3639 0 : nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY ||
3640 0 : !bDragRect || eDragInsertMode != meDragInsertMode )
3641 : {
3642 0 : nDragStartX = nNewDragX;
3643 0 : nDragStartY = nNewDragY;
3644 0 : nDragEndX = nDragStartX+nSizeX-1;
3645 0 : nDragEndY = nDragStartY+nSizeY-1;
3646 0 : bDragRect = true;
3647 0 : meDragInsertMode = eDragInsertMode;
3648 :
3649 0 : UpdateDragRectOverlay();
3650 : }
3651 : }
3652 :
3653 0 : return rEvt.mnAction;
3654 : }
3655 :
3656 0 : sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt )
3657 : {
3658 0 : const ScDragData& rData = SC_MOD()->GetDragData();
3659 0 : if ( rEvt.mbLeaving )
3660 : {
3661 0 : DrawMarkDropObj( NULL );
3662 0 : if ( rData.pCellTransfer )
3663 0 : return AcceptPrivateDrop( rEvt ); // hide drop marker for internal D&D
3664 : else
3665 0 : return rEvt.mnAction;
3666 : }
3667 :
3668 0 : if ( pViewData->GetDocShell()->IsReadOnly() )
3669 0 : return DND_ACTION_NONE;
3670 :
3671 :
3672 0 : sal_Int8 nRet = DND_ACTION_NONE;
3673 :
3674 0 : if (rData.pCellTransfer)
3675 : {
3676 0 : ScRange aSource = rData.pCellTransfer->GetRange();
3677 0 : if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL ||
3678 0 : aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW )
3679 0 : DropScroll( rEvt.maPosPixel );
3680 :
3681 0 : nRet = AcceptPrivateDrop( rEvt );
3682 : }
3683 : else
3684 : {
3685 0 : if ( !rData.aLinkDoc.isEmpty() )
3686 : {
3687 0 : OUString aThisName;
3688 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
3689 0 : if (pDocSh && pDocSh->HasName())
3690 0 : aThisName = pDocSh->GetMedium()->GetName();
3691 :
3692 0 : if ( !rData.aLinkDoc.equals(aThisName) )
3693 0 : nRet = rEvt.mnAction;
3694 : }
3695 0 : else if (!rData.aJumpTarget.isEmpty())
3696 : {
3697 : // internal bookmarks (from Navigator)
3698 : // local jumps from an unnamed document are possible only within a document
3699 :
3700 0 : if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
3701 0 : nRet = rEvt.mnAction;
3702 : }
3703 : else
3704 : {
3705 0 : sal_Int8 nMyAction = rEvt.mnAction;
3706 :
3707 : // clear DND_ACTION_LINK when other actions are set. The usage below cannot handle
3708 : // multiple set values
3709 0 : if((nMyAction & DND_ACTION_LINK) && (nMyAction & (DND_ACTION_COPYMOVE)))
3710 : {
3711 0 : nMyAction &= ~DND_ACTION_LINK;
3712 : }
3713 :
3714 0 : if ( !rData.pDrawTransfer ||
3715 0 : !IsMyModel(rData.pDrawTransfer->GetDragSourceView()) ) // drawing within the document
3716 0 : if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE )
3717 0 : nMyAction = DND_ACTION_COPY;
3718 :
3719 0 : ScDocument* pThisDoc = pViewData->GetDocument();
3720 : SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(
3721 0 : pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) );
3722 0 : if ( pHitObj && nMyAction == DND_ACTION_LINK ) // && !rData.pDrawTransfer )
3723 : {
3724 0 : if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB)
3725 0 : || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE)
3726 0 : || IsDropFormatSupported(SOT_FORMAT_BITMAP) )
3727 : {
3728 : // graphic dragged onto drawing object
3729 0 : DrawMarkDropObj( pHitObj );
3730 0 : nRet = nMyAction;
3731 : }
3732 : }
3733 0 : if (!nRet)
3734 0 : DrawMarkDropObj( NULL );
3735 :
3736 0 : if (!nRet)
3737 : {
3738 0 : switch ( nMyAction )
3739 : {
3740 : case DND_ACTION_COPY:
3741 : case DND_ACTION_MOVE:
3742 : case DND_ACTION_COPYMOVE:
3743 : {
3744 0 : sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE );
3745 0 : if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
3746 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
3747 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
3748 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
3749 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
3750 0 : IsDropFormatSupported( SOT_FORMAT_STRING ) ||
3751 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) ||
3752 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
3753 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) ||
3754 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
3755 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) ||
3756 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) ||
3757 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) ||
3758 0 : IsDropFormatSupported( SOT_FORMAT_RTF ) ||
3759 0 : IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) ||
3760 0 : IsDropFormatSupported( SOT_FORMAT_BITMAP ) ||
3761 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ||
3762 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ||
3763 0 : ( !bMove && (
3764 0 : IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
3765 0 : IsDropFormatSupported( SOT_FORMAT_FILE ) ||
3766 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
3767 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
3768 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
3769 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) )
3770 : {
3771 0 : nRet = nMyAction;
3772 : }
3773 : }
3774 0 : break;
3775 : case DND_ACTION_LINK:
3776 0 : if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
3777 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
3778 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
3779 0 : IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
3780 0 : IsDropFormatSupported( SOT_FORMAT_FILE ) ||
3781 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
3782 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
3783 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
3784 0 : IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3785 : {
3786 0 : nRet = nMyAction;
3787 : }
3788 0 : break;
3789 : }
3790 :
3791 0 : if ( nRet )
3792 : {
3793 : // Simple check for protection: It's not known here if the drop will result
3794 : // in cells or drawing objects (some formats can be both) and how many cells
3795 : // the result will be. But if IsFormatEditable for the drop cell position
3796 : // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
3797 : // can already be rejected here.
3798 :
3799 0 : Point aPos = rEvt.maPosPixel;
3800 : SCsCOL nPosX;
3801 : SCsROW nPosY;
3802 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
3803 0 : SCTAB nTab = pViewData->GetTabNo();
3804 0 : ScDocument* pDoc = pViewData->GetDocument();
3805 :
3806 0 : ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY );
3807 0 : if ( !aTester.IsFormatEditable() )
3808 0 : nRet = DND_ACTION_NONE; // forbidden
3809 : }
3810 : }
3811 : }
3812 :
3813 : // scroll only for accepted formats
3814 0 : if (nRet)
3815 0 : DropScroll( rEvt.maPosPixel );
3816 : }
3817 :
3818 0 : return nRet;
3819 : }
3820 :
3821 0 : static sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false )
3822 : {
3823 0 : TransferableDataHelper aDataHelper( xTransfer );
3824 :
3825 0 : if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
3826 : {
3827 : // use bookmark formats if no sba is present
3828 :
3829 0 : if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
3830 0 : return SOT_FORMATSTR_ID_SOLK;
3831 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
3832 0 : return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
3833 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
3834 0 : return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
3835 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3836 0 : return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
3837 : }
3838 :
3839 0 : sal_uLong nFormatId = 0;
3840 0 : if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
3841 0 : nFormatId = SOT_FORMATSTR_ID_DRAWING;
3842 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
3843 0 : nFormatId = SOT_FORMATSTR_ID_SVXB;
3844 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) )
3845 : {
3846 : // If it's a Writer object, insert RTF instead of OLE
3847 :
3848 0 : sal_Bool bDoRtf = false;
3849 0 : SotStorageStreamRef xStm;
3850 0 : TransferableObjectDescriptor aObjDesc;
3851 0 : if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
3852 0 : aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) )
3853 : {
3854 0 : SotStorageRef xStore( new SotStorage( *xStm ) );
3855 0 : bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
3856 0 : aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
3857 0 : && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
3858 : }
3859 0 : if ( bDoRtf )
3860 0 : nFormatId = FORMAT_RTF;
3861 : else
3862 0 : nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
3863 : }
3864 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
3865 0 : nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
3866 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
3867 0 : nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE;
3868 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) )
3869 0 : nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE;
3870 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) )
3871 0 : nFormatId = SOT_FORMATSTR_ID_BIFF_8;
3872 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) )
3873 0 : nFormatId = SOT_FORMATSTR_ID_BIFF_5;
3874 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
3875 0 : nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
3876 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) )
3877 0 : nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
3878 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
3879 0 : nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
3880 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
3881 0 : nFormatId = SOT_FORMAT_RTF;
3882 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) )
3883 0 : nFormatId = SOT_FORMATSTR_ID_HTML;
3884 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) )
3885 0 : nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
3886 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) )
3887 0 : nFormatId = SOT_FORMATSTR_ID_SYLK;
3888 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
3889 0 : nFormatId = SOT_FORMATSTR_ID_LINK;
3890 0 : else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3891 0 : nFormatId = SOT_FORMAT_STRING;
3892 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
3893 0 : nFormatId = SOT_FORMAT_FILE_LIST;
3894 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3895 0 : nFormatId = SOT_FORMAT_FILE;
3896 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
3897 0 : nFormatId = SOT_FORMAT_STRING;
3898 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
3899 0 : nFormatId = SOT_FORMAT_GDIMETAFILE;
3900 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
3901 0 : nFormatId = SOT_FORMAT_BITMAP;
3902 :
3903 0 : return nFormatId;
3904 : }
3905 :
3906 0 : static sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer )
3907 : {
3908 0 : TransferableDataHelper aDataHelper( xTransfer );
3909 :
3910 0 : sal_uLong nFormatId = 0;
3911 0 : if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
3912 0 : nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
3913 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
3914 0 : nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
3915 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
3916 0 : nFormatId = SOT_FORMATSTR_ID_LINK;
3917 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
3918 0 : nFormatId = SOT_FORMAT_FILE_LIST;
3919 0 : else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )
3920 0 : nFormatId = SOT_FORMAT_FILE;
3921 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
3922 0 : nFormatId = SOT_FORMATSTR_ID_SOLK;
3923 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
3924 0 : nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
3925 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
3926 0 : nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
3927 0 : else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3928 0 : nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
3929 :
3930 0 : return nFormatId;
3931 : }
3932 :
3933 :
3934 0 : sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt )
3935 : {
3936 : // hide drop marker
3937 0 : bDragRect = false;
3938 0 : UpdateDragRectOverlay();
3939 :
3940 0 : ScModule* pScMod = SC_MOD();
3941 0 : const ScDragData& rData = pScMod->GetDragData();
3942 :
3943 : return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY,
3944 0 : PixelToLogic(rEvt.maPosPixel), rEvt.mnAction );
3945 : }
3946 :
3947 0 : sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
3948 : const Point& rLogicPos, sal_Int8 nDndAction )
3949 : {
3950 0 : if ( !pTransObj )
3951 0 : return 0;
3952 :
3953 0 : ScDocument* pSourceDoc = pTransObj->GetSourceDocument();
3954 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
3955 0 : ScDocument* pThisDoc = pViewData->GetDocument();
3956 0 : ScViewFunc* pView = pViewData->GetView();
3957 0 : SCTAB nThisTab = pViewData->GetTabNo();
3958 0 : sal_uInt16 nFlags = pTransObj->GetDragSourceFlags();
3959 :
3960 0 : sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
3961 0 : sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi );
3962 :
3963 : // workaround for wrong nDndAction on Windows when pressing solely
3964 : // the Alt key during drag and drop;
3965 : // can be removed after #i79215# has been fixed
3966 0 : if ( meDragInsertMode != INS_NONE )
3967 : {
3968 0 : bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi );
3969 : }
3970 :
3971 0 : sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK );
3972 :
3973 0 : ScRange aSource = pTransObj->GetRange();
3974 :
3975 : // only use visible tab from source range - when dragging within one table,
3976 : // all selected tables at the time of dropping are used (handled in MoveBlockTo)
3977 0 : SCTAB nSourceTab = pTransObj->GetVisibleTab();
3978 0 : aSource.aStart.SetTab( nSourceTab );
3979 0 : aSource.aEnd.SetTab( nSourceTab );
3980 :
3981 0 : SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1;
3982 0 : SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) :
3983 0 : pTransObj->GetNonFilteredRows()); // copy/link: no filtered rows
3984 : ScRange aDest( nDestPosX, nDestPosY, nThisTab,
3985 0 : nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab );
3986 :
3987 :
3988 : /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3989 : * dragging and adapted drawing of the selection frame. We check here
3990 : * (again) because this may actually also be called from PasteSelection(),
3991 : * we would have to duplicate determination of flags and destination range
3992 : * and would lose the context of the "filtered destination is OK" cases
3993 : * below, which is already awkward enough as is. */
3994 :
3995 : // Don't move filtered source.
3996 0 : bool bFiltered = (bIsMove && pTransObj->HasFilteredRows());
3997 0 : if (!bFiltered)
3998 : {
3999 0 : if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) ||
4000 0 : (!bIsLink && meDragInsertMode == INS_NONE)))
4001 : {
4002 : // Nothing. Either entire sheet to be dropped, or the one case
4003 : // where PasteFromClip() is to be called that handles a filtered
4004 : // destination itself. Drag-copy from another document without
4005 : // inserting cells.
4006 : }
4007 : else
4008 : // Don't copy or move to filtered destination.
4009 0 : bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc);
4010 : }
4011 :
4012 0 : sal_Bool bDone = false;
4013 :
4014 0 : if (!bFiltered && pSourceDoc == pThisDoc)
4015 : {
4016 0 : if ( nFlags & SC_DROP_TABLE ) // whole sheet?
4017 : {
4018 0 : if ( pThisDoc->IsDocEditable() )
4019 : {
4020 0 : SCTAB nSrcTab = aSource.aStart.Tab();
4021 0 : pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True ); // with Undo
4022 0 : pView->SetTabNo( nThisTab, sal_True );
4023 0 : bDone = sal_True;
4024 : }
4025 : }
4026 : else // move/copy block
4027 : {
4028 0 : OUString aChartName;
4029 0 : if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, aChartName ))
4030 : {
4031 0 : String aRangeName;
4032 0 : aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc );
4033 0 : SfxStringItem aNameItem( SID_CHART_NAME, aChartName );
4034 0 : SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName );
4035 0 : sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE;
4036 0 : pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
4037 0 : &aRangeItem, &aNameItem, (void*) NULL );
4038 0 : bDone = sal_True;
4039 : }
4040 0 : else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) )
4041 : {
4042 : // drop on DataPilot table: try to sort, fail if that isn't possible
4043 :
4044 0 : ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab );
4045 0 : if ( aDestPos != aSource.aStart )
4046 0 : bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos );
4047 : else
4048 0 : bDone = sal_True; // same position: nothing
4049 : }
4050 0 : else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() ||
4051 : nSourceTab != nThisTab )
4052 : {
4053 0 : String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
4054 0 : pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
4055 :
4056 0 : SCsCOL nCorrectCursorPosCol = 0;
4057 0 : SCsROW nCorrectCursorPosRow = 0;
4058 :
4059 0 : bDone = sal_True;
4060 0 : if ( meDragInsertMode != INS_NONE )
4061 : {
4062 : // call with bApi = sal_True to avoid error messages in drop handler
4063 0 : bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
4064 0 : if ( bDone )
4065 : {
4066 0 : if ( nThisTab == nSourceTab )
4067 : {
4068 0 : if ( meDragInsertMode == INS_CELLSDOWN &&
4069 0 : nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() )
4070 : {
4071 0 : bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc );
4072 0 : nCorrectCursorPosRow = nSizeY;
4073 : }
4074 0 : else if ( meDragInsertMode == INS_CELLSRIGHT &&
4075 0 : nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() )
4076 : {
4077 0 : bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc );
4078 0 : nCorrectCursorPosCol = nSizeX;
4079 : }
4080 : }
4081 0 : pDocSh->UpdateOle( pViewData );
4082 0 : pView->CellContentChanged();
4083 : }
4084 : }
4085 :
4086 0 : if ( bDone )
4087 : {
4088 0 : if ( bIsLink )
4089 : {
4090 : // call with bApi = sal_True to avoid error messages in drop handler
4091 0 : bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ );
4092 : }
4093 : else
4094 : {
4095 : // call with bApi = sal_True to avoid error messages in drop handler
4096 0 : bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ );
4097 : }
4098 : }
4099 :
4100 0 : if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab )
4101 : {
4102 0 : DelCellCmd eCmd = DEL_NONE;
4103 0 : if ( meDragInsertMode == INS_CELLSDOWN )
4104 : {
4105 0 : eCmd = DEL_CELLSUP;
4106 : }
4107 0 : else if ( meDragInsertMode == INS_CELLSRIGHT )
4108 : {
4109 0 : eCmd = DEL_CELLSLEFT;
4110 : }
4111 :
4112 0 : if ( ( eCmd == DEL_CELLSUP && nDestPosX == aSource.aStart.Col() ) ||
4113 0 : ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) )
4114 : {
4115 : // call with bApi = sal_True to avoid error messages in drop handler
4116 0 : bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ );
4117 0 : if ( bDone )
4118 : {
4119 0 : if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() )
4120 : {
4121 0 : bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc );
4122 : }
4123 0 : else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() )
4124 : {
4125 0 : bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc );
4126 : }
4127 0 : pDocSh->UpdateOle( pViewData );
4128 0 : pView->CellContentChanged();
4129 : }
4130 : }
4131 : }
4132 :
4133 0 : if ( bDone )
4134 : {
4135 0 : pView->MarkRange( aDest, false, false );
4136 :
4137 0 : SCCOL nDCol = pViewData->GetCurX() - aSource.aStart.Col() + nCorrectCursorPosCol;
4138 0 : SCROW nDRow = pViewData->GetCurY() - aSource.aStart.Row() + nCorrectCursorPosRow;
4139 0 : pView->SetCursor( aDest.aStart.Col() + nDCol, aDest.aStart.Row() + nDRow );
4140 : }
4141 :
4142 0 : pDocSh->GetUndoManager()->LeaveListAction();
4143 :
4144 : }
4145 : else
4146 0 : bDone = sal_True; // nothing to do
4147 : }
4148 :
4149 0 : if (bDone)
4150 0 : pTransObj->SetDragWasInternal(); // don't delete source in DragFinished
4151 : }
4152 0 : else if ( !bFiltered && pSourceDoc ) // between documents
4153 : {
4154 0 : if ( nFlags & SC_DROP_TABLE ) // copy/link sheets between documents
4155 : {
4156 0 : if ( pThisDoc->IsDocEditable() )
4157 : {
4158 0 : ScDocShell* pSrcShell = pTransObj->GetSourceDocShell();
4159 :
4160 0 : std::vector<SCTAB> nTabs;
4161 :
4162 0 : ScMarkData aMark = pTransObj->GetSourceMarkData();
4163 0 : SCTAB nTabCount = pSourceDoc->GetTableCount();
4164 :
4165 0 : for(SCTAB i=0; i<nTabCount; i++)
4166 : {
4167 0 : if(aMark.GetTableSelect(i))
4168 : {
4169 0 : nTabs.push_back(i);
4170 0 : for(SCTAB j=i+1;j<nTabCount;j++)
4171 : {
4172 0 : if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j)))
4173 : {
4174 0 : nTabs.push_back( j );
4175 0 : i=j;
4176 : }
4177 0 : else break;
4178 : }
4179 : }
4180 : }
4181 :
4182 0 : pView->ImportTables( pSrcShell,static_cast<SCTAB>(nTabs.size()), &nTabs[0], bIsLink, nThisTab );
4183 0 : bDone = sal_True;
4184 : }
4185 : }
4186 0 : else if ( bIsLink )
4187 : {
4188 : // as in PasteDDE
4189 : // (external references might be used instead?)
4190 :
4191 0 : SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell();
4192 : OSL_ENSURE(pSourceSh, "drag document has no shell");
4193 0 : if (pSourceSh)
4194 : {
4195 0 : String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY );
4196 0 : pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
4197 :
4198 0 : bDone = sal_True;
4199 0 : if ( meDragInsertMode != INS_NONE )
4200 : {
4201 : // call with bApi = sal_True to avoid error messages in drop handler
4202 0 : bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
4203 0 : if ( bDone )
4204 : {
4205 0 : pDocSh->UpdateOle( pViewData );
4206 0 : pView->CellContentChanged();
4207 : }
4208 : }
4209 :
4210 0 : if ( bDone )
4211 : {
4212 0 : String aApp = Application::GetAppName();
4213 0 : String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME );
4214 0 : String aItem;
4215 0 : aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc );
4216 :
4217 : // TODO: we could define ocQuote for "
4218 0 : const OUString aQuote('"');
4219 0 : const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
4220 0 : OUStringBuffer aFormula;
4221 0 : aFormula.append('=');
4222 0 : aFormula.append(ScCompiler::GetNativeSymbol(ocDde));
4223 0 : aFormula.append(ScCompiler::GetNativeSymbol(ocOpen));
4224 0 : aFormula.append(aQuote);
4225 0 : aFormula.append(aApp);
4226 0 : aFormula.append(aQuote);
4227 0 : aFormula.append(sSep);
4228 0 : aFormula.append(aQuote);
4229 0 : aFormula.append(aTopic);
4230 0 : aFormula.append(aQuote);
4231 0 : aFormula.append(sSep);
4232 0 : aFormula.append(aQuote);
4233 0 : aFormula.append(aItem);
4234 0 : aFormula.append(aQuote);
4235 0 : aFormula.append(ScCompiler::GetNativeSymbol(ocClose));
4236 :
4237 0 : pView->DoneBlockMode();
4238 0 : pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab );
4239 : pView->MarkCursor( nDestPosX + nSizeX - 1,
4240 0 : nDestPosY + nSizeY - 1, nThisTab );
4241 :
4242 0 : pView->EnterMatrix( aFormula.makeStringAndClear(), ::formula::FormulaGrammar::GRAM_NATIVE );
4243 :
4244 0 : pView->MarkRange( aDest, false, false );
4245 0 : pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
4246 : }
4247 :
4248 0 : pDocSh->GetUndoManager()->LeaveListAction();
4249 : }
4250 : }
4251 : else
4252 : {
4253 : //! HasSelectedBlockMatrixFragment without selected sheet?
4254 : //! or don't start dragging on a part of a matrix
4255 :
4256 0 : String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
4257 0 : pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
4258 :
4259 0 : bDone = sal_True;
4260 0 : if ( meDragInsertMode != INS_NONE )
4261 : {
4262 : // call with bApi = sal_True to avoid error messages in drop handler
4263 0 : bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
4264 0 : if ( bDone )
4265 : {
4266 0 : pDocSh->UpdateOle( pViewData );
4267 0 : pView->CellContentChanged();
4268 : }
4269 : }
4270 :
4271 0 : if ( bDone )
4272 : {
4273 0 : pView->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4274 0 : pView->SetCursor( nDestPosX, nDestPosY );
4275 0 : bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() ); // clip-doc
4276 0 : if ( bDone )
4277 : {
4278 0 : pView->MarkRange( aDest, false, false );
4279 0 : pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
4280 : }
4281 : }
4282 :
4283 0 : pDocSh->GetUndoManager()->LeaveListAction();
4284 :
4285 : // no longer call ResetMark here - the inserted block has been selected
4286 : // and may have been copied to primary selection
4287 : }
4288 : }
4289 :
4290 0 : sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE;
4291 0 : return nRet;
4292 : }
4293 :
4294 0 : sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
4295 : {
4296 0 : DrawMarkDropObj( NULL ); // drawing layer
4297 :
4298 0 : ScModule* pScMod = SC_MOD();
4299 0 : const ScDragData& rData = pScMod->GetDragData();
4300 0 : if (rData.pCellTransfer)
4301 0 : return ExecutePrivateDrop( rEvt );
4302 :
4303 0 : Point aPos = rEvt.maPosPixel;
4304 :
4305 0 : if ( !rData.aLinkDoc.isEmpty() )
4306 : {
4307 : // try to insert a link
4308 :
4309 0 : bool bOk = true;
4310 0 : OUString aThisName;
4311 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
4312 0 : if (pDocSh && pDocSh->HasName())
4313 0 : aThisName = pDocSh->GetMedium()->GetName();
4314 :
4315 0 : if ( rData.aLinkDoc.equals(aThisName) ) // error - no link within a document
4316 0 : bOk = false;
4317 : else
4318 : {
4319 0 : ScViewFunc* pView = pViewData->GetView();
4320 0 : if ( !rData.aLinkTable.isEmpty() )
4321 0 : pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
4322 0 : rData.aLinkTable );
4323 0 : else if ( !rData.aLinkArea.isEmpty() )
4324 : {
4325 : SCsCOL nPosX;
4326 : SCsROW nPosY;
4327 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4328 0 : pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
4329 :
4330 0 : pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
4331 0 : rData.aLinkArea, 0 );
4332 : }
4333 : else
4334 : {
4335 : OSL_FAIL("drop with link: no sheet nor area");
4336 0 : bOk = false;
4337 : }
4338 : }
4339 :
4340 0 : return bOk ? rEvt.mnAction : DND_ACTION_NONE; // don't try anything else
4341 : }
4342 :
4343 0 : Point aLogicPos = PixelToLogic(aPos);
4344 0 : sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK );
4345 :
4346 0 : if (!bIsLink && rData.pDrawTransfer)
4347 : {
4348 0 : sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags();
4349 :
4350 0 : sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
4351 0 : sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi );
4352 :
4353 0 : bPasteIsMove = bIsMove;
4354 :
4355 0 : pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() );
4356 :
4357 0 : if (bPasteIsMove)
4358 0 : rData.pDrawTransfer->SetDragWasInternal();
4359 0 : bPasteIsMove = false;
4360 :
4361 0 : return rEvt.mnAction;
4362 : }
4363 :
4364 :
4365 : SCsCOL nPosX;
4366 : SCsROW nPosY;
4367 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4368 :
4369 0 : if (!rData.aJumpTarget.isEmpty())
4370 : {
4371 : // internal bookmark (from Navigator)
4372 : // bookmark clipboard formats are in PasteScDataObject
4373 :
4374 0 : if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
4375 : {
4376 0 : pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget,
4377 0 : nPosX, nPosY );
4378 0 : return rEvt.mnAction;
4379 : }
4380 : }
4381 :
4382 0 : ScDocument* pThisDoc = pViewData->GetDocument();
4383 0 : SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) );
4384 0 : if ( pHitObj && bIsLink )
4385 : {
4386 : // dropped on drawing object
4387 : // PasteOnDrawObject checks for valid formats
4388 0 : if ( pViewData->GetView()->PasteOnDrawObject( rEvt.maDropEvent.Transferable, pHitObj, sal_True ) )
4389 0 : return rEvt.mnAction;
4390 : }
4391 :
4392 0 : sal_Bool bDone = false;
4393 :
4394 : sal_uLong nFormatId = bIsLink ?
4395 0 : lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) :
4396 0 : lcl_GetDropFormatId( rEvt.maDropEvent.Transferable );
4397 0 : if ( nFormatId )
4398 : {
4399 0 : pScMod->SetInExecuteDrop( sal_True ); // #i28468# prevent error messages from PasteDataFormat
4400 0 : bPasteIsDrop = sal_True;
4401 0 : bDone = pViewData->GetView()->PasteDataFormat(
4402 0 : nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink );
4403 0 : bPasteIsDrop = false;
4404 0 : pScMod->SetInExecuteDrop( false );
4405 : }
4406 :
4407 0 : sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE;
4408 0 : return nRet;
4409 : }
4410 :
4411 : //--------------------------------------------------------
4412 :
4413 0 : void ScGridWindow::PasteSelection( const Point& rPosPixel )
4414 : {
4415 0 : Point aLogicPos = PixelToLogic( rPosPixel );
4416 :
4417 : SCsCOL nPosX;
4418 : SCsROW nPosY;
4419 0 : pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY );
4420 :
4421 : // If the mouse down was inside a visible note window, ignore it and
4422 : // leave it up to the ScPostIt to handle it
4423 0 : SdrView* pDrawView = pViewData->GetViewShell()->GetSdrView();
4424 0 : if (pDrawView)
4425 : {
4426 0 : sal_uLong nCount = pDrawView->GetMarkedObjectCount();
4427 0 : for (sal_uLong i = 0; i < nCount; ++i)
4428 : {
4429 0 : SdrObject* pObj = pDrawView->GetMarkedObjectByIndex(i);
4430 0 : if (pObj && pObj->GetLogicRect().IsInside(aLogicPos))
4431 : {
4432 : // Inside an active drawing object. Bail out.
4433 0 : return;
4434 : }
4435 : }
4436 : }
4437 :
4438 0 : ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer();
4439 0 : if ( pOwnSelection )
4440 : {
4441 : // within Calc
4442 :
4443 0 : ScTransferObj* pCellTransfer = pOwnSelection->GetCellData();
4444 0 : if ( pCellTransfer )
4445 : {
4446 : // keep a reference to the data in case the selection is changed during paste
4447 0 : uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer );
4448 0 : DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY );
4449 : }
4450 : else
4451 : {
4452 0 : ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData();
4453 0 : if ( pDrawTransfer )
4454 : {
4455 : // keep a reference to the data in case the selection is changed during paste
4456 0 : uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer );
4457 :
4458 : // bSameDocClipboard argument for PasteDraw is needed
4459 : // because only DragData is checked directly inside PasteDraw
4460 0 : pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), false,
4461 0 : pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
4462 : }
4463 : }
4464 : }
4465 : else
4466 : {
4467 : // get selection from system
4468 :
4469 0 : TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4470 0 : uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable();
4471 0 : if ( xTransferable.is() )
4472 : {
4473 0 : sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true );
4474 0 : if ( nFormatId )
4475 : {
4476 0 : bPasteIsDrop = sal_True;
4477 0 : pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos );
4478 0 : bPasteIsDrop = false;
4479 : }
4480 0 : }
4481 : }
4482 : }
4483 :
4484 : //--------------------------------------------------------
4485 :
4486 53 : void ScGridWindow::UpdateEditViewPos()
4487 : {
4488 53 : if (pViewData->HasEditView(eWhich))
4489 : {
4490 : EditView* pView;
4491 : SCCOL nCol;
4492 : SCROW nRow;
4493 0 : pViewData->GetEditView( eWhich, pView, nCol, nRow );
4494 0 : SCCOL nEndCol = pViewData->GetEditEndCol();
4495 0 : SCROW nEndRow = pViewData->GetEditEndRow();
4496 :
4497 : // hide EditView?
4498 :
4499 0 : sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) );
4500 0 : if ( SC_MOD()->IsFormulaMode() )
4501 0 : if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() )
4502 0 : bHide = sal_True;
4503 :
4504 0 : if (bHide)
4505 : {
4506 0 : Rectangle aRect = pView->GetOutputArea();
4507 0 : long nHeight = aRect.Bottom() - aRect.Top();
4508 0 : aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()).
4509 0 : Height() * 2;
4510 0 : aRect.Bottom() = aRect.Top() + nHeight;
4511 0 : pView->SetOutputArea( aRect );
4512 0 : pView->HideCursor();
4513 : }
4514 : else
4515 : {
4516 : // bForceToTop = sal_True for editing
4517 0 : Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True );
4518 0 : Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() );
4519 :
4520 0 : Rectangle aRect = pView->GetOutputArea();
4521 0 : aRect.SetPos( aScrPos );
4522 0 : pView->SetOutputArea( aRect );
4523 0 : pView->ShowCursor();
4524 : }
4525 : }
4526 53 : }
4527 :
4528 53 : void ScGridWindow::ScrollPixel( long nDifX, long nDifY )
4529 : {
4530 53 : ClickExtern();
4531 53 : HideNoteMarker();
4532 :
4533 53 : bIsInScroll = true;
4534 :
4535 53 : SetMapMode(MAP_PIXEL);
4536 53 : Scroll( nDifX, nDifY, SCROLL_CHILDREN );
4537 53 : SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4538 :
4539 53 : UpdateEditViewPos();
4540 :
4541 53 : DrawAfterScroll();
4542 53 : bIsInScroll = false;
4543 53 : }
4544 :
4545 : // Formeln neu zeichnen -------------------------------------------------
4546 :
4547 8265 : void ScGridWindow::UpdateFormulas()
4548 : {
4549 8265 : if (pViewData->GetView()->IsMinimized())
4550 0 : return;
4551 :
4552 8265 : if ( nPaintCount )
4553 : {
4554 : // nicht anfangen, verschachtelt zu painten
4555 : // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4556 :
4557 0 : bNeedsRepaint = true; // -> am Ende vom Paint nochmal Invalidate auf alles
4558 0 : aRepaintPixel = Rectangle(); // alles
4559 0 : return;
4560 : }
4561 :
4562 8265 : SCCOL nX1 = pViewData->GetPosX( eHWhich );
4563 8265 : SCROW nY1 = pViewData->GetPosY( eVWhich );
4564 8265 : SCCOL nX2 = nX1 + pViewData->VisibleCellsX( eHWhich );
4565 8265 : SCROW nY2 = nY1 + pViewData->VisibleCellsY( eVWhich );
4566 :
4567 8265 : if (nX2 > MAXCOL) nX2 = MAXCOL;
4568 8265 : if (nY2 > MAXROW) nY2 = MAXROW;
4569 :
4570 : // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4571 :
4572 : // don't draw directly - instead use OutputData to find changed area and invalidate
4573 :
4574 8265 : SCROW nPosY = nY1;
4575 :
4576 8265 : ScDocShell* pDocSh = pViewData->GetDocShell();
4577 8265 : ScDocument* pDoc = pDocSh->GetDocument();
4578 8265 : SCTAB nTab = pViewData->GetTabNo();
4579 :
4580 8265 : pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
4581 :
4582 8265 : Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
4583 8265 : long nMirrorWidth = GetSizePixel().Width();
4584 8265 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
4585 8265 : if ( bLayoutRTL )
4586 : {
4587 1 : long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
4588 1 : nMirrorWidth = aScrPos.X() - nEndPixel;
4589 1 : aScrPos.X() = nEndPixel + 1;
4590 : }
4591 :
4592 8265 : long nScrX = aScrPos.X();
4593 8265 : long nScrY = aScrPos.Y();
4594 :
4595 8265 : double nPPTX = pViewData->GetPPTX();
4596 8265 : double nPPTY = pViewData->GetPPTY();
4597 :
4598 8265 : ScTableInfo aTabInfo;
4599 8265 : pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, false, false );
4600 :
4601 8265 : Fraction aZoomX = pViewData->GetZoomX();
4602 8265 : Fraction aZoomY = pViewData->GetZoomY();
4603 : ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
4604 : nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
4605 16530 : &aZoomX, &aZoomY );
4606 8265 : aOutputData.SetMirrorWidth( nMirrorWidth );
4607 :
4608 8265 : aOutputData.FindChanged();
4609 :
4610 16530 : PolyPolygon aChangedPoly( aOutputData.GetChangedArea() ); // logic (PixelToLogic)
4611 8265 : if ( aChangedPoly.Count() )
4612 : {
4613 121 : Invalidate(Region(aChangedPoly));
4614 : }
4615 :
4616 16530 : CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4617 : }
4618 :
4619 1349 : void ScGridWindow::UpdateAutoFillMark(bool bMarked, const ScRange& rMarkRange)
4620 : {
4621 1349 : if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) )
4622 : {
4623 399 : bAutoMarkVisible = bMarked;
4624 399 : if ( bMarked )
4625 397 : aAutoMarkPos = rMarkRange.aEnd;
4626 :
4627 399 : UpdateAutoFillOverlay();
4628 : }
4629 1349 : }
4630 :
4631 274 : void ScGridWindow::UpdateListValPos( bool bVisible, const ScAddress& rPos )
4632 : {
4633 274 : bool bOldButton = bListValButton;
4634 274 : ScAddress aOldPos = aListValPos;
4635 :
4636 274 : bListValButton = bVisible;
4637 274 : aListValPos = rPos;
4638 :
4639 274 : if ( bListValButton )
4640 : {
4641 0 : if ( !bOldButton || aListValPos != aOldPos )
4642 : {
4643 : // paint area of new button
4644 0 : Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) );
4645 : }
4646 : }
4647 274 : if ( bOldButton )
4648 : {
4649 0 : if ( !bListValButton || aListValPos != aOldPos )
4650 : {
4651 : // paint area of old button
4652 0 : Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) );
4653 : }
4654 : }
4655 274 : }
4656 :
4657 833 : void ScGridWindow::HideCursor()
4658 : {
4659 833 : ++nCursorHideCount;
4660 833 : }
4661 :
4662 632 : void ScGridWindow::ShowCursor()
4663 : {
4664 632 : --nCursorHideCount;
4665 632 : }
4666 :
4667 262 : void ScGridWindow::GetFocus()
4668 : {
4669 262 : ScTabViewShell* pViewShell = pViewData->GetViewShell();
4670 262 : pViewShell->GotFocus();
4671 262 : pViewShell->SetFormShellAtTop( false ); // focus in GridWindow -> FormShell no longer on top
4672 :
4673 262 : if (pViewShell->HasAccessibilityObjects())
4674 0 : pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible()));
4675 :
4676 :
4677 262 : if ( !SC_MOD()->IsFormulaMode() )
4678 : {
4679 262 : pViewShell->UpdateInputHandler();
4680 : // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4681 : // MO: nur wenn nicht im RefInput-Modus
4682 : // -> GetFocus/MouseButtonDown-Reihenfolge
4683 : // auf dem Mac
4684 : }
4685 :
4686 262 : pViewData->GetDocShell()->CheckConfigOptions();
4687 262 : Window::GetFocus();
4688 262 : }
4689 :
4690 258 : void ScGridWindow::LoseFocus()
4691 : {
4692 258 : ScTabViewShell* pViewShell = pViewData->GetViewShell();
4693 258 : pViewShell->LostFocus();
4694 :
4695 258 : if (pViewShell->HasAccessibilityObjects())
4696 2 : pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible()));
4697 :
4698 258 : Window::LoseFocus();
4699 258 : }
4700 :
4701 0 : Point ScGridWindow::GetMousePosPixel() const { return aCurMousePos; }
4702 :
4703 : //------------------------------------------------------------------------
4704 :
4705 0 : bool ScGridWindow::HitRangeFinder( const Point& rMouse, bool& rCorner,
4706 : sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY )
4707 : {
4708 0 : bool bFound = false;
4709 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
4710 0 : if (pHdl)
4711 : {
4712 0 : ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
4713 0 : if ( pRangeFinder && !pRangeFinder->IsHidden() &&
4714 0 : pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() )
4715 : {
4716 0 : ScDocument* pDoc = pViewData->GetDocument();
4717 0 : SCTAB nTab = pViewData->GetTabNo();
4718 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
4719 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
4720 :
4721 : SCsCOL nPosX;
4722 : SCsROW nPosY;
4723 0 : pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY );
4724 : // zusammengefasste (einzeln/Bereich) ???
4725 0 : ScAddress aAddr( nPosX, nPosY, nTab );
4726 :
4727 0 : Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, true );
4728 : long nSizeXPix;
4729 : long nSizeYPix;
4730 0 : pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix );
4731 0 : aNext.X() += nSizeXPix * nLayoutSign;
4732 0 : aNext.Y() += nSizeYPix;
4733 :
4734 : bool bCornerHor;
4735 0 : if ( bLayoutRTL )
4736 0 : bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 );
4737 : else
4738 0 : bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() );
4739 :
4740 0 : bool bCellCorner = ( bCornerHor &&
4741 0 : rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() );
4742 : // corner is hit only if the mouse is within the cell
4743 :
4744 0 : sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
4745 0 : for (sal_uInt16 i=nCount; i;)
4746 : {
4747 : // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4748 0 : --i;
4749 0 : ScRangeFindData* pData = pRangeFinder->GetObject(i);
4750 0 : if ( pData->aRef.In(aAddr) )
4751 : {
4752 0 : if (pIndex) *pIndex = i;
4753 0 : if (pAddX) *pAddX = nPosX - pData->aRef.aStart.Col();
4754 0 : if (pAddY) *pAddY = nPosY - pData->aRef.aStart.Row();
4755 0 : bFound = sal_True;
4756 0 : rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd );
4757 0 : break;
4758 : }
4759 : }
4760 : }
4761 : }
4762 0 : return bFound;
4763 : }
4764 :
4765 : #define SCE_TOP 1
4766 : #define SCE_BOTTOM 2
4767 : #define SCE_LEFT 4
4768 : #define SCE_RIGHT 8
4769 : #define SCE_ALL 15
4770 :
4771 0 : static void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges )
4772 : {
4773 : // der Range ist immer richtigherum
4774 :
4775 0 : SCCOL nCol1 = rRange.aStart.Col();
4776 0 : SCROW nRow1 = rRange.aStart.Row();
4777 0 : SCTAB nTab1 = rRange.aStart.Tab();
4778 0 : SCCOL nCol2 = rRange.aEnd.Col();
4779 0 : SCROW nRow2 = rRange.aEnd.Row();
4780 0 : SCTAB nTab2 = rRange.aEnd.Tab();
4781 0 : sal_Bool bHiddenEdge = false;
4782 : SCROW nTmp;
4783 :
4784 0 : ScDocument* pDoc = pDocSh->GetDocument();
4785 0 : while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) )
4786 : {
4787 0 : --nCol1;
4788 0 : bHiddenEdge = sal_True;
4789 : }
4790 0 : while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) )
4791 : {
4792 0 : ++nCol2;
4793 0 : bHiddenEdge = sal_True;
4794 : }
4795 0 : nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1);
4796 0 : if (!ValidRow(nTmp))
4797 0 : nTmp = 0;
4798 0 : if (nTmp < nRow1)
4799 : {
4800 0 : nRow1 = nTmp;
4801 0 : bHiddenEdge = sal_True;
4802 : }
4803 0 : nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1);
4804 0 : if (!ValidRow(nTmp))
4805 0 : nTmp = MAXROW;
4806 0 : if (nTmp > nRow2)
4807 : {
4808 0 : nRow2 = nTmp;
4809 0 : bHiddenEdge = sal_True;
4810 : }
4811 :
4812 0 : if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge )
4813 : {
4814 : // nur an den Raendern entlang
4815 : // (die Ecken werden evtl. zweimal getroffen)
4816 :
4817 0 : if ( nEdges & SCE_TOP )
4818 0 : pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS );
4819 0 : if ( nEdges & SCE_LEFT )
4820 0 : pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS );
4821 0 : if ( nEdges & SCE_RIGHT )
4822 0 : pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4823 0 : if ( nEdges & SCE_BOTTOM )
4824 0 : pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4825 : }
4826 : else // everything in one call
4827 0 : pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4828 0 : }
4829 :
4830 0 : static void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn )
4831 : {
4832 : // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4833 :
4834 0 : ScRange aOld = rOldUn;
4835 0 : ScRange aNew = rNewUn;
4836 0 : aOld.Justify();
4837 0 : aNew.Justify();
4838 :
4839 0 : if ( aOld.aStart == aOld.aEnd ) //! Tab ignorieren?
4840 0 : pDocSh->GetDocument()->ExtendMerge(aOld);
4841 0 : if ( aNew.aStart == aNew.aEnd ) //! Tab ignorieren?
4842 0 : pDocSh->GetDocument()->ExtendMerge(aNew);
4843 :
4844 0 : SCCOL nOldCol1 = aOld.aStart.Col();
4845 0 : SCROW nOldRow1 = aOld.aStart.Row();
4846 0 : SCCOL nOldCol2 = aOld.aEnd.Col();
4847 0 : SCROW nOldRow2 = aOld.aEnd.Row();
4848 0 : SCCOL nNewCol1 = aNew.aStart.Col();
4849 0 : SCROW nNewRow1 = aNew.aStart.Row();
4850 0 : SCCOL nNewCol2 = aNew.aEnd.Col();
4851 0 : SCROW nNewRow2 = aNew.aEnd.Row();
4852 0 : SCTAB nTab1 = aOld.aStart.Tab(); // Tab aendert sich nicht
4853 0 : SCTAB nTab2 = aOld.aEnd.Tab();
4854 :
4855 0 : if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 ||
4856 0 : nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 ||
4857 0 : ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 &&
4858 0 : nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) )
4859 : {
4860 : // komplett weggeschoben oder alle Seiten veraendert
4861 : // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4862 :
4863 0 : lcl_PaintOneRange( pDocSh, aOld, SCE_ALL );
4864 : }
4865 : else // alle vier Kanten einzeln testen
4866 : {
4867 : // oberer Teil
4868 0 : if ( nNewRow1 < nOldRow1 ) // nur obere Linie loeschen
4869 : lcl_PaintOneRange( pDocSh, ScRange(
4870 0 : nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL );
4871 0 : else if ( nNewRow1 > nOldRow1 ) // den Teil, der oben wegkommt
4872 : lcl_PaintOneRange( pDocSh, ScRange(
4873 : nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ),
4874 0 : SCE_ALL &~ SCE_BOTTOM );
4875 :
4876 : // unterer Teil
4877 0 : if ( nNewRow2 > nOldRow2 ) // nur untere Linie loeschen
4878 : lcl_PaintOneRange( pDocSh, ScRange(
4879 0 : nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
4880 0 : else if ( nNewRow2 < nOldRow2 ) // den Teil, der unten wegkommt
4881 : lcl_PaintOneRange( pDocSh, ScRange(
4882 : nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ),
4883 0 : SCE_ALL &~ SCE_TOP );
4884 :
4885 : // linker Teil
4886 0 : if ( nNewCol1 < nOldCol1 ) // nur linke Linie loeschen
4887 : lcl_PaintOneRange( pDocSh, ScRange(
4888 0 : nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL );
4889 0 : else if ( nNewCol1 > nOldCol1 ) // den Teil, der links wegkommt
4890 : lcl_PaintOneRange( pDocSh, ScRange(
4891 : nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ),
4892 0 : SCE_ALL &~ SCE_RIGHT );
4893 :
4894 : // rechter Teil
4895 0 : if ( nNewCol2 > nOldCol2 ) // nur rechte Linie loeschen
4896 : lcl_PaintOneRange( pDocSh, ScRange(
4897 0 : nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
4898 0 : else if ( nNewCol2 < nOldCol2 ) // den Teil, der rechts wegkommt
4899 : lcl_PaintOneRange( pDocSh, ScRange(
4900 : nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ),
4901 0 : SCE_ALL &~ SCE_LEFT );
4902 : }
4903 0 : }
4904 :
4905 0 : void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp )
4906 : {
4907 0 : ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
4908 0 : if (!pHdl)
4909 0 : return;
4910 0 : ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
4911 0 : if (!pRangeFinder || nRFIndex >= pRangeFinder->Count())
4912 0 : return;
4913 0 : ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex );
4914 :
4915 : // Mauszeiger
4916 :
4917 0 : if (bRFSize)
4918 0 : SetPointer( Pointer( POINTER_CROSS ) );
4919 : else
4920 0 : SetPointer( Pointer( POINTER_HAND ) );
4921 :
4922 : // Scrolling
4923 :
4924 0 : sal_Bool bTimer = false;
4925 0 : Point aPos = rMEvt.GetPosPixel();
4926 0 : SCsCOL nDx = 0;
4927 0 : SCsROW nDy = 0;
4928 0 : if ( aPos.X() < 0 ) nDx = -1;
4929 0 : if ( aPos.Y() < 0 ) nDy = -1;
4930 0 : Size aSize = GetOutputSizePixel();
4931 0 : if ( aPos.X() >= aSize.Width() )
4932 0 : nDx = 1;
4933 0 : if ( aPos.Y() >= aSize.Height() )
4934 0 : nDy = 1;
4935 0 : if ( nDx != 0 || nDy != 0 )
4936 : {
4937 0 : if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
4938 0 : if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
4939 0 : bTimer = sal_True;
4940 : }
4941 :
4942 : // Umschalten bei Fixierung (damit Scrolling funktioniert)
4943 :
4944 0 : if ( eWhich == pViewData->GetActivePart() ) //??
4945 : {
4946 0 : if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
4947 0 : if ( nDx > 0 )
4948 : {
4949 0 : if ( eWhich == SC_SPLIT_TOPLEFT )
4950 0 : pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
4951 0 : else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
4952 0 : pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
4953 : }
4954 :
4955 0 : if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
4956 0 : if ( nDy > 0 )
4957 : {
4958 0 : if ( eWhich == SC_SPLIT_TOPLEFT )
4959 0 : pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
4960 0 : else if ( eWhich == SC_SPLIT_TOPRIGHT )
4961 0 : pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
4962 : }
4963 : }
4964 :
4965 : // Verschieben
4966 :
4967 : SCsCOL nPosX;
4968 : SCsROW nPosY;
4969 0 : pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4970 :
4971 0 : ScRange aOld = pData->aRef;
4972 0 : ScRange aNew = aOld;
4973 0 : if ( bRFSize )
4974 : {
4975 0 : aNew.aEnd.SetCol((SCCOL)nPosX);
4976 0 : aNew.aEnd.SetRow((SCROW)nPosY);
4977 : }
4978 : else
4979 : {
4980 0 : long nStartX = nPosX - nRFAddX;
4981 0 : if ( nStartX < 0 ) nStartX = 0;
4982 0 : long nStartY = nPosY - nRFAddY;
4983 0 : if ( nStartY < 0 ) nStartY = 0;
4984 0 : long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col();
4985 0 : if ( nEndX > MAXCOL )
4986 : {
4987 0 : nStartX -= ( nEndX - MAXROW );
4988 0 : nEndX = MAXCOL;
4989 : }
4990 0 : long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row();
4991 0 : if ( nEndY > MAXROW )
4992 : {
4993 0 : nStartY -= ( nEndY - MAXROW );
4994 0 : nEndY = MAXROW;
4995 : }
4996 :
4997 0 : aNew.aStart.SetCol((SCCOL)nStartX);
4998 0 : aNew.aStart.SetRow((SCROW)nStartY);
4999 0 : aNew.aEnd.SetCol((SCCOL)nEndX);
5000 0 : aNew.aEnd.SetRow((SCROW)nEndY);
5001 : }
5002 :
5003 0 : if ( bUp )
5004 0 : aNew.Justify(); // beim ButtonUp wieder richtigherum
5005 :
5006 0 : if ( aNew != aOld )
5007 : {
5008 0 : pHdl->UpdateRange( nRFIndex, aNew );
5009 :
5010 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
5011 :
5012 : // nur das neuzeichnen, was sich veraendert hat...
5013 0 : lcl_PaintRefChanged( pDocSh, aOld, aNew );
5014 :
5015 : // neuen Rahmen nur drueberzeichnen (synchron)
5016 0 : pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) );
5017 :
5018 0 : Update(); // was man bewegt, will man auch sofort sehen
5019 : }
5020 :
5021 : // Timer fuer Scrolling
5022 :
5023 0 : if (bTimer)
5024 0 : pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen
5025 : else
5026 0 : pViewData->GetView()->ResetTimer();
5027 : }
5028 :
5029 : //------------------------------------------------------------------------
5030 :
5031 0 : bool ScGridWindow::GetEditUrl( const Point& rPos,
5032 : String* pName, String* pUrl, String* pTarget )
5033 : {
5034 0 : return GetEditUrlOrError( false, rPos, pName, pUrl, pTarget );
5035 : }
5036 :
5037 0 : bool ScGridWindow::GetEditUrlOrError( bool bSpellErr, const Point& rPos,
5038 : String* pName, String* pUrl, String* pTarget )
5039 : {
5040 : //! nPosX/Y mit uebergeben?
5041 : SCsCOL nPosX;
5042 : SCsROW nPosY;
5043 0 : pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY );
5044 :
5045 0 : SCTAB nTab = pViewData->GetTabNo();
5046 0 : ScDocShell* pDocSh = pViewData->GetDocShell();
5047 0 : ScDocument* pDoc = pDocSh->GetDocument();
5048 0 : OUString sURL;
5049 0 : ScRefCellValue aCell;
5050 0 : bool bFound = lcl_GetHyperlinkCell(pDoc, nPosX, nPosY, nTab, aCell, sURL);
5051 0 : if( !bFound )
5052 0 : return false;
5053 :
5054 0 : const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
5055 : // bForceToTop = sal_False, use the cell's real position
5056 0 : Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, false );
5057 0 : if (rPos.Y() < aEditRect.Top())
5058 0 : return false;
5059 :
5060 : // vertikal kann (noch) nicht angeklickt werden:
5061 :
5062 0 : if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
5063 0 : return false;
5064 :
5065 0 : sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
5066 : ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
5067 0 : GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK);
5068 : SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern->
5069 0 : GetItem(ATTR_HOR_JUSTIFY)).GetValue();
5070 :
5071 : // EditEngine
5072 :
5073 0 : ScFieldEditEngine aEngine(pDoc, pDoc->GetEditPool());
5074 0 : ScSizeDeviceProvider aProv(pDocSh);
5075 0 : aEngine.SetRefDevice( aProv.GetDevice() );
5076 0 : aEngine.SetRefMapMode( MAP_100TH_MM );
5077 0 : SfxItemSet aDefault( aEngine.GetEmptyItemSet() );
5078 0 : pPattern->FillEditItemSet( &aDefault );
5079 0 : SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
5080 0 : switch (eHorJust)
5081 : {
5082 : case SVX_HOR_JUSTIFY_LEFT:
5083 : case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
5084 : case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type
5085 0 : eSvxAdjust = SVX_ADJUST_LEFT;
5086 0 : break;
5087 : case SVX_HOR_JUSTIFY_RIGHT:
5088 0 : eSvxAdjust = SVX_ADJUST_RIGHT;
5089 0 : break;
5090 : case SVX_HOR_JUSTIFY_CENTER:
5091 0 : eSvxAdjust = SVX_ADJUST_CENTER;
5092 0 : break;
5093 : case SVX_HOR_JUSTIFY_BLOCK:
5094 0 : eSvxAdjust = SVX_ADJUST_BLOCK;
5095 0 : break;
5096 : }
5097 0 : aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
5098 0 : aEngine.SetDefaults( aDefault );
5099 0 : if (bSpellErr)
5100 0 : aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING );
5101 :
5102 0 : MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung
5103 0 : Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
5104 0 : long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1;
5105 0 : Size aPaperSize = Size( 1000000, 1000000 );
5106 0 : if (aCell.meType == CELLTYPE_FORMULA)
5107 : {
5108 0 : long nSizeX = 0;
5109 0 : long nSizeY = 0;
5110 0 : pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
5111 0 : aPaperSize = Size(nSizeX, nSizeY );
5112 0 : aPaperSize = PixelToLogic(aPaperSize);
5113 : }
5114 :
5115 0 : if (bBreak)
5116 0 : aPaperSize.Width() = nThisColLogic;
5117 0 : aEngine.SetPaperSize( aPaperSize );
5118 :
5119 0 : boost::scoped_ptr<EditTextObject> pTextObj;
5120 0 : if (aCell.meType == CELLTYPE_EDIT)
5121 : {
5122 0 : if (aCell.mpEditText)
5123 0 : aEngine.SetText(*aCell.mpEditText);
5124 : }
5125 : else // Not an Edit cell and is a formula cell with 'Hyperlink'
5126 : // function if we have no URL, otherwise it could be a formula
5127 : // cell ( or other type ? ) with a hyperlink associated with it.
5128 : {
5129 0 : if (sURL.isEmpty())
5130 0 : pTextObj.reset(aCell.mpFormula->CreateURLObject());
5131 : else
5132 0 : pTextObj.reset(ScEditUtil::CreateURLObjectFromURL(*pDoc, sURL, sURL));
5133 :
5134 0 : if (pTextObj.get())
5135 0 : aEngine.SetText(*pTextObj);
5136 : }
5137 :
5138 0 : long nStartX = aLogicEdit.Left();
5139 :
5140 0 : long nTextWidth = aEngine.CalcTextWidth();
5141 0 : long nTextHeight = aEngine.GetTextHeight();
5142 0 : if ( nTextWidth < nThisColLogic )
5143 : {
5144 0 : if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
5145 0 : nStartX += nThisColLogic - nTextWidth;
5146 0 : else if (eHorJust == SVX_HOR_JUSTIFY_CENTER)
5147 0 : nStartX += (nThisColLogic - nTextWidth) / 2;
5148 : }
5149 :
5150 0 : aLogicEdit.Left() = nStartX;
5151 0 : if (!bBreak)
5152 0 : aLogicEdit.Right() = nStartX + nTextWidth;
5153 :
5154 : // There is one glitch when dealing with a hyperlink cell and
5155 : // the cell content is NUMERIC. This defaults to right aligned and
5156 : // we need to adjust accordingly.
5157 0 : if (aCell.meType == CELLTYPE_FORMULA && aCell.mpFormula->IsValue() &&
5158 : eHorJust == SVX_HOR_JUSTIFY_STANDARD)
5159 : {
5160 0 : aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1;
5161 0 : aLogicEdit.Left() = aLogicEdit.Right() - nTextWidth;
5162 : }
5163 0 : aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight;
5164 :
5165 :
5166 0 : Point aLogicClick = PixelToLogic(rPos,aEditMode);
5167 0 : if ( aLogicEdit.IsInside(aLogicClick) )
5168 : {
5169 0 : EditView aTempView( &aEngine, this );
5170 0 : aTempView.SetOutputArea( aLogicEdit );
5171 :
5172 0 : sal_Bool bRet = false;
5173 0 : MapMode aOld = GetMapMode();
5174 0 : SetMapMode(aEditMode); // kein return mehr
5175 :
5176 0 : if (bSpellErr) // Spelling-Fehler suchen
5177 : {
5178 0 : bRet = aTempView.IsWrongSpelledWordAtPos( rPos );
5179 0 : if ( bRet )
5180 0 : pViewData->GetView()->SetCursor( nPosX, nPosY ); // Cursor setzen
5181 : }
5182 : else // URL suchen
5183 : {
5184 0 : const SvxFieldItem* pFieldItem = aTempView.GetFieldUnderMousePointer();
5185 :
5186 0 : if (pFieldItem)
5187 : {
5188 0 : const SvxFieldData* pField = pFieldItem->GetField();
5189 0 : if ( pField && pField->ISA(SvxURLField) )
5190 : {
5191 0 : if ( pName || pUrl || pTarget )
5192 : {
5193 0 : const SvxURLField* pURLField = (const SvxURLField*)pField;
5194 0 : if (pName)
5195 0 : *pName = pURLField->GetRepresentation();
5196 0 : if (pUrl)
5197 0 : *pUrl = pURLField->GetURL();
5198 0 : if (pTarget)
5199 0 : *pTarget = pURLField->GetTargetFrame();
5200 : }
5201 0 : bRet = sal_True;
5202 : }
5203 : }
5204 : }
5205 :
5206 0 : SetMapMode(aOld);
5207 :
5208 0 : return bRet;
5209 : }
5210 0 : return false;
5211 : }
5212 :
5213 0 : bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
5214 : {
5215 0 : ScDocument* pDoc = pViewData->GetDocument();
5216 0 : SCTAB nTab = pViewData->GetTabNo();
5217 0 : SCTAB nTabCount = pDoc->GetTableCount();
5218 0 : if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
5219 : {
5220 0 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5221 :
5222 0 : Size aButSize = pViewData->GetScenButSize();
5223 0 : long nBWidth = aButSize.Width();
5224 0 : if (!nBWidth)
5225 0 : return false; // noch kein Button gezeichnet -> da ist auch keiner
5226 0 : long nBHeight = aButSize.Height();
5227 0 : long nHSpace = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() );
5228 :
5229 : //! Ranges an der Table cachen!!!!
5230 :
5231 0 : ScMarkData aMarks;
5232 0 : for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
5233 0 : pDoc->MarkScenario( i, nTab, aMarks, false, SC_SCENARIO_SHOWFRAME );
5234 0 : ScRangeList aRanges;
5235 0 : aMarks.FillRangeListWithMarks( &aRanges, false );
5236 :
5237 :
5238 0 : size_t nRangeCount = aRanges.size();
5239 0 : for (size_t j=0; j< nRangeCount; ++j)
5240 : {
5241 0 : ScRange aRange = *aRanges[j];
5242 : // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5243 : // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5244 0 : pDoc->ExtendTotalMerge( aRange );
5245 :
5246 0 : bool bTextBelow = ( aRange.aStart.Row() == 0 );
5247 :
5248 0 : Point aButtonPos;
5249 0 : if ( bTextBelow )
5250 : {
5251 0 : aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1,
5252 0 : eWhich, sal_True );
5253 : }
5254 : else
5255 : {
5256 0 : aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(),
5257 0 : eWhich, sal_True );
5258 0 : aButtonPos.Y() -= nBHeight;
5259 : }
5260 0 : if ( bLayoutRTL )
5261 0 : aButtonPos.X() -= nHSpace - 1;
5262 : else
5263 0 : aButtonPos.X() -= nBWidth - nHSpace; // same for top or bottom
5264 :
5265 0 : Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) );
5266 0 : if ( aButRect.IsInside( rPosPixel ) )
5267 : {
5268 0 : rScenRange = aRange;
5269 0 : return true;
5270 : }
5271 0 : }
5272 : }
5273 :
5274 0 : return false;
5275 : }
5276 :
5277 : // #114409#
5278 165 : void ScGridWindow::DrawLayerCreated()
5279 : {
5280 165 : SetMapMode( GetDrawMapMode() );
5281 :
5282 : // initially create overlay objects
5283 165 : ImpCreateOverlayObjects();
5284 165 : }
5285 :
5286 : // #114409#
5287 612 : void ScGridWindow::CursorChanged()
5288 : {
5289 : // here the created OverlayObjects may be transformed in later versions. For
5290 : // now, just re-create them
5291 :
5292 612 : UpdateCursorOverlay();
5293 612 : }
5294 :
5295 : // #114409#
5296 1466 : void ScGridWindow::ImpCreateOverlayObjects()
5297 : {
5298 1466 : UpdateCursorOverlay();
5299 1466 : UpdateCopySourceOverlay();
5300 1466 : UpdateSelectionOverlay();
5301 1466 : UpdateAutoFillOverlay();
5302 1466 : UpdateDragRectOverlay();
5303 1466 : UpdateHeaderOverlay();
5304 1466 : UpdateShrinkOverlay();
5305 1466 : }
5306 :
5307 : // #114409#
5308 1505 : void ScGridWindow::ImpDestroyOverlayObjects()
5309 : {
5310 1505 : DeleteCursorOverlay();
5311 1505 : DeleteCopySourceOverlay();
5312 1505 : DeleteSelectionOverlay();
5313 1505 : DeleteAutoFillOverlay();
5314 1505 : DeleteDragRectOverlay();
5315 1505 : DeleteHeaderOverlay();
5316 1505 : DeleteShrinkOverlay();
5317 1505 : }
5318 :
5319 1301 : void ScGridWindow::UpdateAllOverlays()
5320 : {
5321 : // delete and re-allocate all overlay objects
5322 :
5323 1301 : ImpDestroyOverlayObjects();
5324 1301 : ImpCreateOverlayObjects();
5325 1301 : }
5326 :
5327 3583 : void ScGridWindow::DeleteCursorOverlay()
5328 : {
5329 3583 : DELETEZ( mpOOCursors );
5330 3583 : }
5331 :
5332 2971 : void ScGridWindow::DeleteCopySourceOverlay()
5333 : {
5334 2971 : DELETEZ( mpOOSelectionBorder );
5335 2971 : }
5336 :
5337 1466 : void ScGridWindow::UpdateCopySourceOverlay()
5338 : {
5339 1466 : MapMode aDrawMode = GetDrawMapMode();
5340 1466 : MapMode aOldMode = GetMapMode();
5341 1466 : if ( aOldMode != aDrawMode )
5342 18 : SetMapMode( aDrawMode );
5343 :
5344 1466 : DeleteCopySourceOverlay();
5345 :
5346 1466 : if (!pViewData->ShowPasteSource())
5347 1466 : return;
5348 0 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5349 0 : if (!xOverlayManager.is())
5350 0 : return;
5351 0 : ScTransferObj* pTransObj = ScTransferObj::GetOwnClipboard( pViewData->GetActiveWin() );
5352 0 : if (!pTransObj)
5353 0 : return;
5354 0 : ScDocument* pClipDoc = pTransObj->GetDocument();
5355 0 : if (!pClipDoc)
5356 0 : return;
5357 :
5358 0 : SCTAB nCurTab = pViewData->GetCurPos().Tab();
5359 :
5360 0 : ScClipParam& rClipParam = pClipDoc->GetClipParam();
5361 0 : mpOOSelectionBorder = new ::sdr::overlay::OverlayObjectList;
5362 0 : for ( size_t i = 0; i < rClipParam.maRanges.size(); ++i )
5363 : {
5364 0 : ScRange* p = rClipParam.maRanges[i];
5365 0 : if (p->aStart.Tab() != nCurTab)
5366 0 : continue;
5367 :
5368 0 : SCCOL nClipStartX = p->aStart.Col();
5369 0 : SCROW nClipStartY = p->aStart.Row();
5370 0 : SCCOL nClipEndX = p->aEnd.Col();
5371 0 : SCROW nClipEndY = p->aEnd.Row();
5372 :
5373 0 : Point aClipStartScrPos = pViewData->GetScrPos( nClipStartX, nClipStartY, eWhich );
5374 0 : Point aClipEndScrPos = pViewData->GetScrPos( nClipEndX + 1, nClipEndY + 1, eWhich );
5375 0 : aClipStartScrPos -= Point(1, 1);
5376 0 : long nSizeXPix = aClipEndScrPos.X() - aClipStartScrPos.X();
5377 0 : long nSizeYPix = aClipEndScrPos.Y() - aClipStartScrPos.Y();
5378 :
5379 0 : Rectangle aRect( aClipStartScrPos, Size(nSizeXPix, nSizeYPix) );
5380 :
5381 :
5382 0 : Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5383 :
5384 0 : Rectangle aLogic = PixelToLogic(aRect, aDrawMode);
5385 0 : ::basegfx::B2DRange aRange(aLogic.Left(), aLogic.Top(), aLogic.Right(), aLogic.Bottom());
5386 0 : ScOverlayDashedBorder* pDashedBorder = new ScOverlayDashedBorder(aRange, aHighlight);
5387 0 : xOverlayManager->add(*pDashedBorder);
5388 0 : mpOOSelectionBorder->append(*pDashedBorder);
5389 : }
5390 :
5391 0 : if ( aOldMode != aDrawMode )
5392 0 : SetMapMode( aOldMode );
5393 : }
5394 :
5395 2078 : void ScGridWindow::UpdateCursorOverlay()
5396 : {
5397 2078 : MapMode aDrawMode = GetDrawMapMode();
5398 4034 : MapMode aOldMode = GetMapMode();
5399 2078 : if ( aOldMode != aDrawMode )
5400 23 : SetMapMode( aDrawMode );
5401 :
5402 : // Existing OverlayObjects may be transformed in later versions.
5403 : // For now, just re-create them.
5404 :
5405 2078 : DeleteCursorOverlay();
5406 :
5407 4034 : std::vector<Rectangle> aPixelRects;
5408 :
5409 : //
5410 : // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5411 : //
5412 :
5413 2078 : SCTAB nTab = pViewData->GetTabNo();
5414 2078 : SCCOL nX = pViewData->GetCurX();
5415 2078 : SCROW nY = pViewData->GetCurY();
5416 :
5417 2078 : if (!maVisibleRange.isInside(nX, nY))
5418 2200 : return;
5419 :
5420 : // don't show the cursor in overlapped cells
5421 :
5422 1956 : ScDocument* pDoc = pViewData->GetDocument();
5423 1956 : const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
5424 1956 : const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
5425 1956 : sal_Bool bOverlapped = rMergeFlag.IsOverlapped();
5426 :
5427 : // left or above of the screen?
5428 :
5429 1956 : sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
5430 1956 : if (!bVis)
5431 : {
5432 16 : SCCOL nEndX = nX;
5433 16 : SCROW nEndY = nY;
5434 16 : const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
5435 16 : if (rMerge.GetColMerge() > 1)
5436 0 : nEndX += rMerge.GetColMerge()-1;
5437 16 : if (rMerge.GetRowMerge() > 1)
5438 0 : nEndY += rMerge.GetRowMerge()-1;
5439 16 : bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
5440 : }
5441 :
5442 1956 : if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
5443 : {
5444 1930 : Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
5445 1930 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5446 :
5447 : // completely right of/below the screen?
5448 : // (test with logical start position in aScrPos)
5449 : sal_Bool bMaybeVisible;
5450 1930 : if ( bLayoutRTL )
5451 2 : bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
5452 : else
5453 : {
5454 1928 : Size aOutSize = GetOutputSizePixel();
5455 1928 : bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
5456 : }
5457 1930 : if ( bMaybeVisible )
5458 : {
5459 : long nSizeXPix;
5460 : long nSizeYPix;
5461 1906 : pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
5462 :
5463 1906 : if ( bLayoutRTL )
5464 2 : aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring
5465 :
5466 : // Now, draw the cursor.
5467 :
5468 1906 : aScrPos.X() -= 2;
5469 1906 : aScrPos.Y() -= 2;
5470 1906 : Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5471 :
5472 1906 : aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
5473 1906 : aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
5474 1906 : aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
5475 1906 : aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
5476 : }
5477 : }
5478 :
5479 1956 : if ( !aPixelRects.empty() )
5480 : {
5481 : // #i70788# get the OverlayManager safely
5482 1906 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5483 :
5484 1906 : if (xOverlayManager.is())
5485 : {
5486 1858 : Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
5487 1858 : if (pViewData->GetActivePart() != eWhich)
5488 : // non-active pane uses a different color.
5489 21 : aCursorColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor;
5490 1858 : std::vector< basegfx::B2DRange > aRanges;
5491 3716 : const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5492 :
5493 9290 : for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5494 : {
5495 7432 : const Rectangle aRA(aPixelRects[a]);
5496 7432 : basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
5497 7432 : aRB.transform(aTransform);
5498 7432 : aRanges.push_back(aRB);
5499 : }
5500 :
5501 : sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5502 : sdr::overlay::OVERLAY_SOLID,
5503 : aCursorColor,
5504 : aRanges,
5505 1858 : false);
5506 :
5507 1858 : xOverlayManager->add(*pOverlay);
5508 1858 : mpOOCursors = new ::sdr::overlay::OverlayObjectList;
5509 3716 : mpOOCursors->append(*pOverlay);
5510 1906 : }
5511 : }
5512 :
5513 1956 : if ( aOldMode != aDrawMode )
5514 1977 : SetMapMode( aOldMode );
5515 : }
5516 :
5517 3173 : void ScGridWindow::DeleteSelectionOverlay()
5518 : {
5519 3173 : DELETEZ( mpOOSelection );
5520 3173 : }
5521 :
5522 1668 : void ScGridWindow::UpdateSelectionOverlay()
5523 : {
5524 1668 : MapMode aDrawMode = GetDrawMapMode();
5525 3336 : MapMode aOldMode = GetMapMode();
5526 1668 : if ( aOldMode != aDrawMode )
5527 0 : SetMapMode( aDrawMode );
5528 :
5529 1668 : DeleteSelectionOverlay();
5530 3336 : std::vector<Rectangle> aPixelRects;
5531 1668 : GetSelectionRects( aPixelRects );
5532 :
5533 1668 : if ( aPixelRects.size() && pViewData->IsActive() )
5534 : {
5535 : // #i70788# get the OverlayManager safely
5536 213 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5537 :
5538 213 : if (xOverlayManager.is())
5539 : {
5540 213 : std::vector< basegfx::B2DRange > aRanges;
5541 426 : const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5542 :
5543 451 : for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5544 : {
5545 238 : const Rectangle aRA(aPixelRects[a]);
5546 238 : basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom());
5547 238 : aRB.transform(aTransform);
5548 238 : aRanges.push_back(aRB);
5549 : }
5550 :
5551 : // get the system's hilight color
5552 426 : const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
5553 213 : const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
5554 :
5555 : sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5556 : sdr::overlay::OVERLAY_TRANSPARENT,
5557 : aHighlight,
5558 : aRanges,
5559 213 : true);
5560 :
5561 213 : xOverlayManager->add(*pOverlay);
5562 213 : mpOOSelection = new ::sdr::overlay::OverlayObjectList;
5563 426 : mpOOSelection->append(*pOverlay);
5564 213 : }
5565 : }
5566 :
5567 1668 : if ( aOldMode != aDrawMode )
5568 1668 : SetMapMode( aOldMode );
5569 1668 : }
5570 :
5571 3370 : void ScGridWindow::DeleteAutoFillOverlay()
5572 : {
5573 3370 : DELETEZ( mpOOAutoFill );
5574 3370 : mpAutoFillRect.reset();
5575 3370 : }
5576 :
5577 1865 : void ScGridWindow::UpdateAutoFillOverlay()
5578 : {
5579 1865 : MapMode aDrawMode = GetDrawMapMode();
5580 3646 : MapMode aOldMode = GetMapMode();
5581 1865 : if ( aOldMode != aDrawMode )
5582 3 : SetMapMode( aDrawMode );
5583 :
5584 1865 : DeleteAutoFillOverlay();
5585 :
5586 : //
5587 : // get the AutoFill handle rectangle in pixels
5588 : //
5589 :
5590 5221 : if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() &&
5591 5221 : !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
5592 : {
5593 1674 : SCCOL nX = aAutoMarkPos.Col();
5594 1674 : SCROW nY = aAutoMarkPos.Row();
5595 :
5596 1674 : if (!maVisibleRange.isInside(nX, nY))
5597 : // Autofill mark is not visible. Bail out.
5598 1949 : return;
5599 :
5600 1590 : SCTAB nTab = pViewData->GetTabNo();
5601 1590 : ScDocument* pDoc = pViewData->GetDocument();
5602 1590 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5603 :
5604 1590 : Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
5605 : long nSizeXPix;
5606 : long nSizeYPix;
5607 1590 : pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
5608 1590 : if ( bLayoutRTL )
5609 2 : aFillPos.X() -= nSizeXPix + 3;
5610 : else
5611 1588 : aFillPos.X() += nSizeXPix - 2;
5612 :
5613 1590 : aFillPos.Y() += nSizeYPix;
5614 1590 : aFillPos.Y() -= 2;
5615 1590 : mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6)));
5616 :
5617 : // #i70788# get the OverlayManager safely
5618 1590 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5619 :
5620 1590 : if (xOverlayManager.is())
5621 : {
5622 1558 : Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
5623 1558 : if (pViewData->GetActivePart() != eWhich)
5624 : // non-active pane uses a different color.
5625 19 : aHandleColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor;
5626 1558 : std::vector< basegfx::B2DRange > aRanges;
5627 3116 : const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5628 1558 : basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);
5629 :
5630 1558 : aRB.transform(aTransform);
5631 1558 : aRanges.push_back(aRB);
5632 :
5633 : sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5634 : sdr::overlay::OVERLAY_SOLID,
5635 : aHandleColor,
5636 : aRanges,
5637 1558 : false);
5638 :
5639 1558 : xOverlayManager->add(*pOverlay);
5640 1558 : mpOOAutoFill = new ::sdr::overlay::OverlayObjectList;
5641 3116 : mpOOAutoFill->append(*pOverlay);
5642 : }
5643 :
5644 1590 : if ( aOldMode != aDrawMode )
5645 3 : SetMapMode( aOldMode );
5646 1781 : }
5647 : }
5648 :
5649 2971 : void ScGridWindow::DeleteDragRectOverlay()
5650 : {
5651 2971 : DELETEZ( mpOODragRect );
5652 2971 : }
5653 :
5654 1466 : void ScGridWindow::UpdateDragRectOverlay()
5655 : {
5656 1466 : MapMode aDrawMode = GetDrawMapMode();
5657 2932 : MapMode aOldMode = GetMapMode();
5658 1466 : if ( aOldMode != aDrawMode )
5659 0 : SetMapMode( aDrawMode );
5660 :
5661 1466 : DeleteDragRectOverlay();
5662 :
5663 : //
5664 : // get the rectangles in pixels (moved from DrawDragRect)
5665 : //
5666 :
5667 1466 : if ( bDragRect || bPagebreakDrawn )
5668 : {
5669 0 : std::vector<Rectangle> aPixelRects;
5670 :
5671 0 : SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col();
5672 0 : SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row();
5673 0 : SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col();
5674 0 : SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row();
5675 :
5676 0 : SCTAB nTab = pViewData->GetTabNo();
5677 :
5678 0 : SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
5679 0 : SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
5680 0 : if (nX1 < nPosX) nX1 = nPosX;
5681 0 : if (nX2 < nPosX) nX2 = nPosX;
5682 0 : if (nY1 < nPosY) nY1 = nPosY;
5683 0 : if (nY2 < nPosY) nY2 = nPosY;
5684 :
5685 0 : Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
5686 :
5687 0 : long nSizeXPix=0;
5688 0 : long nSizeYPix=0;
5689 0 : ScDocument* pDoc = pViewData->GetDocument();
5690 0 : double nPPTX = pViewData->GetPPTX();
5691 0 : double nPPTY = pViewData->GetPPTY();
5692 : SCCOLROW i;
5693 :
5694 0 : sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5695 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
5696 :
5697 0 : if (ValidCol(nX2) && nX2>=nX1)
5698 0 : for (i=nX1; i<=nX2; i++)
5699 0 : nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
5700 : else
5701 : {
5702 0 : aScrPos.X() -= nLayoutSign;
5703 0 : nSizeXPix += 2;
5704 : }
5705 :
5706 0 : if (ValidRow(nY2) && nY2>=nY1)
5707 0 : for (i=nY1; i<=nY2; i++)
5708 0 : nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
5709 : else
5710 : {
5711 0 : aScrPos.Y() -= 1;
5712 0 : nSizeYPix += 2;
5713 : }
5714 :
5715 0 : aScrPos.X() -= 2 * nLayoutSign;
5716 0 : aScrPos.Y() -= 2;
5717 0 : Rectangle aRect( aScrPos.X(), aScrPos.Y(),
5718 0 : aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
5719 0 : if ( bLayoutRTL )
5720 : {
5721 0 : aRect.Left() = aRect.Right(); // end position is left
5722 0 : aRect.Right() = aScrPos.X();
5723 : }
5724 :
5725 0 : if ( meDragInsertMode == INS_CELLSDOWN )
5726 : {
5727 0 : aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) );
5728 0 : aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) );
5729 0 : aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) );
5730 0 : aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) );
5731 : }
5732 0 : else if ( meDragInsertMode == INS_CELLSRIGHT )
5733 : {
5734 0 : aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) );
5735 0 : aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) );
5736 0 : aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) );
5737 0 : aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) );
5738 : }
5739 : else
5740 : {
5741 0 : aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) );
5742 0 : aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) );
5743 0 : aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) );
5744 0 : aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) );
5745 : }
5746 :
5747 : // #i70788# get the OverlayManager safely
5748 0 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5749 :
5750 0 : if (xOverlayManager.is())
5751 : {
5752 0 : std::vector< basegfx::B2DRange > aRanges;
5753 0 : const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5754 :
5755 0 : for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5756 : {
5757 0 : const Rectangle aRA(aPixelRects[a]);
5758 0 : basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
5759 0 : aRB.transform(aTransform);
5760 0 : aRanges.push_back(aRB);
5761 : }
5762 :
5763 : sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5764 : sdr::overlay::OVERLAY_INVERT,
5765 : Color(COL_BLACK),
5766 : aRanges,
5767 0 : false);
5768 :
5769 0 : xOverlayManager->add(*pOverlay);
5770 0 : mpOODragRect = new ::sdr::overlay::OverlayObjectList;
5771 0 : mpOODragRect->append(*pOverlay);
5772 0 : }
5773 : }
5774 :
5775 1466 : if ( aOldMode != aDrawMode )
5776 1466 : SetMapMode( aOldMode );
5777 1466 : }
5778 :
5779 2971 : void ScGridWindow::DeleteHeaderOverlay()
5780 : {
5781 2971 : DELETEZ( mpOOHeader );
5782 2971 : }
5783 :
5784 1466 : void ScGridWindow::UpdateHeaderOverlay()
5785 : {
5786 1466 : MapMode aDrawMode = GetDrawMapMode();
5787 2932 : MapMode aOldMode = GetMapMode();
5788 1466 : if ( aOldMode != aDrawMode )
5789 0 : SetMapMode( aDrawMode );
5790 :
5791 1466 : DeleteHeaderOverlay();
5792 :
5793 : // Pixel rectangle is in aInvertRect
5794 1466 : if ( !aInvertRect.IsEmpty() )
5795 : {
5796 : // #i70788# get the OverlayManager safely
5797 0 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5798 :
5799 0 : if (xOverlayManager.is())
5800 : {
5801 : // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5802 0 : std::vector< basegfx::B2DRange > aRanges;
5803 0 : const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5804 0 : basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1);
5805 :
5806 0 : aRB.transform(aTransform);
5807 0 : aRanges.push_back(aRB);
5808 :
5809 : sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5810 : sdr::overlay::OVERLAY_INVERT,
5811 : Color(COL_BLACK),
5812 : aRanges,
5813 0 : false);
5814 :
5815 0 : xOverlayManager->add(*pOverlay);
5816 0 : mpOOHeader = new ::sdr::overlay::OverlayObjectList;
5817 0 : mpOOHeader->append(*pOverlay);
5818 0 : }
5819 : }
5820 :
5821 1466 : if ( aOldMode != aDrawMode )
5822 1466 : SetMapMode( aOldMode );
5823 1466 : }
5824 :
5825 2971 : void ScGridWindow::DeleteShrinkOverlay()
5826 : {
5827 2971 : DELETEZ( mpOOShrink );
5828 2971 : }
5829 :
5830 1466 : void ScGridWindow::UpdateShrinkOverlay()
5831 : {
5832 1466 : MapMode aDrawMode = GetDrawMapMode();
5833 2932 : MapMode aOldMode = GetMapMode();
5834 1466 : if ( aOldMode != aDrawMode )
5835 0 : SetMapMode( aDrawMode );
5836 :
5837 1466 : DeleteShrinkOverlay();
5838 :
5839 : //
5840 : // get the rectangle in pixels
5841 : //
5842 :
5843 1466 : Rectangle aPixRect;
5844 1466 : ScRange aRange;
5845 1466 : SCTAB nTab = pViewData->GetTabNo();
5846 1466 : if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() &&
5847 0 : pViewData->GetDelMark( aRange ) )
5848 : {
5849 : //! limit to visible area
5850 0 : if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
5851 0 : aRange.aStart.Row() <= aRange.aEnd.Row() )
5852 : {
5853 0 : Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
5854 0 : aRange.aStart.Row(), eWhich );
5855 0 : Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
5856 0 : aRange.aEnd.Row()+1, eWhich );
5857 0 : aEnd.X() -= 1;
5858 0 : aEnd.Y() -= 1;
5859 :
5860 0 : aPixRect = Rectangle( aStart,aEnd );
5861 : }
5862 : }
5863 :
5864 1466 : if ( !aPixRect.IsEmpty() )
5865 : {
5866 : // #i70788# get the OverlayManager safely
5867 0 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5868 :
5869 0 : if (xOverlayManager.is())
5870 : {
5871 0 : std::vector< basegfx::B2DRange > aRanges;
5872 0 : const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5873 0 : basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1);
5874 :
5875 0 : aRB.transform(aTransform);
5876 0 : aRanges.push_back(aRB);
5877 :
5878 : sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5879 : sdr::overlay::OVERLAY_INVERT,
5880 : Color(COL_BLACK),
5881 : aRanges,
5882 0 : false);
5883 :
5884 0 : xOverlayManager->add(*pOverlay);
5885 0 : mpOOShrink = new ::sdr::overlay::OverlayObjectList;
5886 0 : mpOOShrink->append(*pOverlay);
5887 0 : }
5888 : }
5889 :
5890 1466 : if ( aOldMode != aDrawMode )
5891 1466 : SetMapMode( aOldMode );
5892 1466 : }
5893 :
5894 : // #i70788# central method to get the OverlayManager safely
5895 3711 : rtl::Reference<sdr::overlay::OverlayManager> ScGridWindow::getOverlayManager()
5896 : {
5897 3711 : SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView();
5898 :
5899 3711 : if(pPV)
5900 : {
5901 3631 : SdrPageWindow* pPageWin = pPV->FindPageWindow( *this );
5902 :
5903 3631 : if ( pPageWin )
5904 : {
5905 3631 : return (pPageWin->GetOverlayManager());
5906 : }
5907 : }
5908 :
5909 80 : return rtl::Reference<sdr::overlay::OverlayManager>();
5910 : }
5911 :
5912 2 : void ScGridWindow::flushOverlayManager()
5913 : {
5914 : // #i70788# get the OverlayManager safely
5915 2 : rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager();
5916 :
5917 2 : if (xOverlayManager.is())
5918 2 : xOverlayManager->flush();
5919 2 : }
5920 :
5921 0 : void ScGridWindow::SetInRefMode( bool bInRefMode )
5922 : {
5923 0 : WinBits nBits = GetStyle();
5924 0 : if(bInRefMode)
5925 0 : nBits |= WB_REFMODE;
5926 : else
5927 0 : nBits &= ~WB_REFMODE;
5928 :
5929 0 : SetStyle( nBits );
5930 93 : }
5931 :
5932 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|