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