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