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