1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "scitems.hxx"
23 #include <memory> //auto_ptr
24 #include <editeng/adjustitem.hxx>
25 #include <svx/algitem.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/editstat.hxx>
28 #include <editeng/flditem.hxx>
29 #include <editeng/justifyitem.hxx>
30 #include <svx/svdetc.hxx>
31 #include <editeng/editobj.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/viewfrm.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <svl/stritem.hxx>
36 #include <svtools/svtabbx.hxx>
37 #include <svl/urlbmk.hxx>
38 #include <vcl/cursor.hxx>
39 #include <vcl/graph.hxx>
40 #include <vcl/hatch.hxx>
41 #include <sot/formats.hxx>
42 #include <comphelper/classids.hxx>
43 #include <sal/macros.h>
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>
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>
63 #include "gridwin.hxx"
64 #include "tabvwsh.hxx"
66 #include "viewdata.hxx"
67 #include "tabview.hxx"
70 #include "document.hxx"
73 #include "stlpool.hxx"
74 #include "printfun.hxx"
75 #include "cbutton.hxx"
77 #include "globstr.hrc"
78 #include "editutil.hxx"
79 #include "scresid.hxx"
80 #include "inputhdl.hxx"
81 #include "uiitems.hxx" // Filter-Dialog - auslagern !!!
82 #include "filtdlg.hxx"
83 #include "impex.hxx" // Sylk-ID fuer CB
84 #include "formulacell.hxx" // fuer Edit-Felder
85 #include "patattr.hxx"
86 #include "notemark.hxx"
87 #include "rfindlst.hxx"
88 #include "docpool.hxx"
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"
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"
124 #include <svx/sdrpagewindow.hxx>
125 #include <svx/sdr/overlay/overlaymanager.hxx>
126 #include <vcl/svapp.hxx>
127 #include <svx/sdr/overlay/overlayselection.hxx>
130 #include <boost/scoped_ptr.hpp>
132 using namespace com::sun::star
;
133 using ::com::sun::star::uno::Sequence
;
134 using ::com::sun::star::uno::Any
;
136 const sal_uInt8 SC_NESTEDBUTTON_NONE
= 0;
137 const sal_uInt8 SC_NESTEDBUTTON_DOWN
= 1;
138 const sal_uInt8 SC_NESTEDBUTTON_UP
= 2;
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
146 // Modi fuer die FilterListBox
150 SC_FILTERBOX_DATASELECT
,
151 SC_FILTERBOX_SCENARIO
,
152 SC_FILTERBOX_PAGEFIELD
155 extern SfxViewShell
* pScActiveViewShell
; // global.cxx
156 extern sal_uInt16 nScClickMouseModifier
; // global.cxx
157 extern sal_uInt16 nScFillModeMouseModifier
; // global.cxx
159 struct ScGridWindow::MouseEventState
163 MouseEventState() : mbActivatePart(false) {}
166 #define SC_FILTERLISTBOX_LINES 12
168 // ============================================================================
170 ScGridWindow::VisibleRange::VisibleRange() :
171 mnCol1(0), mnCol2(MAXCOL
), mnRow1(0), mnRow2(MAXROW
)
175 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol
, SCROW nRow
) const
177 return mnCol1
<= nCol
&& nCol
<= mnCol2
&& mnRow1
<= nRow
&& nRow
<= mnRow2
;
180 // ============================================================================
182 class ScFilterListBox
: public ListBox
185 ScGridWindow
* pGridWin
;
188 sal_Bool bButtonDown
;
194 ScFilterBoxMode eMode
;
197 virtual void LoseFocus();
201 ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
202 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
);
205 virtual long PreNotify( NotifyEvent
& rNEvt
);
206 virtual void Select();
208 SCCOL
GetCol() const { return nCol
; }
209 SCROW
GetRow() const { return nRow
; }
210 ScFilterBoxMode
GetMode() const { return eMode
; }
211 sal_Bool
IsDataSelect() const { return (eMode
== SC_FILTERBOX_DATASELECT
); }
213 sal_Bool
IsInInit() const { return bInit
; }
214 void SetCancelled() { bCancelled
= sal_True
; }
215 sal_Bool
IsInSelect() const { return bInSelect
; }
216 void SetListHasDates(bool b
) { mbListHasDates
= b
; }
217 bool HasDates() const { return mbListHasDates
; }
220 //-------------------------------------------------------------------
222 // ListBox in einem FloatingWindow (pParent)
223 ScFilterListBox::ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
224 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
) :
225 ListBox( pParent
, WB_AUTOHSCROLL
),
229 bButtonDown( false ),
233 mbListHasDates(false),
239 ScFilterListBox::~ScFilterListBox()
241 if (IsMouseCaptured())
245 void ScFilterListBox::EndInit()
247 sal_uInt16 nPos
= GetSelectEntryPos();
248 if ( LISTBOX_ENTRY_NOTFOUND
== nPos
)
256 void ScFilterListBox::LoseFocus()
263 // -----------------------------------------------------------------------
265 long ScFilterListBox::PreNotify( NotifyEvent
& rNEvt
)
268 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
270 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
271 KeyCode aCode
= aKeyEvt
.GetKeyCode();
272 if ( !aCode
.GetModifier() ) // ohne alle Modifiers
274 sal_uInt16 nKey
= aCode
.GetCode();
275 if ( nKey
== KEY_RETURN
)
277 SelectHdl(); // auswaehlen
280 else if ( nKey
== KEY_ESCAPE
)
282 pGridWin
->ClickExtern(); // loescht die List-Box !!!
288 return nDone
? nDone
: ListBox::PreNotify( rNEvt
);
291 void ScFilterListBox::Select()
297 void ScFilterListBox::SelectHdl()
299 if ( !IsTravelSelect() && !bInit
&& !bCancelled
)
301 sal_uInt16 nPos
= GetSelectEntryPos();
302 if ( LISTBOX_ENTRY_NOTFOUND
!= nPos
)
307 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
308 bInSelect
= sal_True
;
309 pGridWin
->FilterSelect( nSel
);
316 // ============================================================================
318 // use a System floating window for the above filter listbox
319 class ScFilterFloatingWindow
: public FloatingWindow
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();
328 ScFilterFloatingWindow::ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
) :
329 FloatingWindow( pParent
, nStyle
|WB_SYSTEMWINDOW
) // make it a system floater
332 ScFilterFloatingWindow::~ScFilterFloatingWindow()
337 Window
* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
339 // redirect keyinput in the child window
340 return GetWindow(WINDOW_FIRSTCHILD
) ? GetWindow(WINDOW_FIRSTCHILD
)->GetPreferredKeyInputWindow() : NULL
; // will be the FilterBox
343 // ============================================================================
345 static sal_Bool
lcl_IsEditableMatrix( ScDocument
* pDoc
, const ScRange
& rRange
)
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 ???
351 if ( !pDoc
->IsBlockEditable( rRange
.aStart
.Tab(), rRange
.aStart
.Col(),rRange
.aStart
.Row(),
352 rRange
.aEnd
.Col(),rRange
.aEnd
.Row() ) )
355 ScRefCellValue aCell
;
356 aCell
.assign(*pDoc
, rRange
.aEnd
);
358 return (aCell
.meType
== CELLTYPE_FORMULA
&& aCell
.mpFormula
->GetMatrixOrigin(aPos
) && aPos
== rRange
.aStart
);
361 static void lcl_UnLockComment( ScDrawView
* pView
, SdrPageView
* pPV
, SdrModel
* pDrDoc
, const Point
& rPos
, ScViewData
* pViewData
)
363 if (!pView
&& !pPV
&& !pDrDoc
&& !pViewData
)
366 ScDocument
& rDoc
= *pViewData
->GetDocument();
367 ScAddress
aCellPos( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
368 ScPostIt
* pNote
= rDoc
.GetNotes( aCellPos
.Tab() )->findByAddress( aCellPos
);
369 SdrObject
* pObj
= pNote
? pNote
->GetCaption() : 0;
370 if( pObj
&& pObj
->GetLogicRect().IsInside( rPos
) && ScDrawLayer::IsNoteCaption( pObj
) )
372 const ScProtectionAttr
* pProtAttr
= static_cast< const ScProtectionAttr
* > (rDoc
.GetAttr( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab(), ATTR_PROTECTION
) );
373 bool bProtectAttr
= pProtAttr
->GetProtection() || pProtAttr
->GetHideCell() ;
374 bool bProtectDoc
= rDoc
.IsTabProtected( aCellPos
.Tab() ) || pViewData
->GetSfxDocShell()->IsReadOnly() ;
375 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
376 pView
->LockInternalLayer( bProtectDoc
&& bProtectAttr
);
380 static bool lcl_GetHyperlinkCell(
381 ScDocument
* pDoc
, SCCOL
& rPosX
, SCROW
& rPosY
, SCTAB nTab
, ScRefCellValue
& rCell
, OUString
& rURL
)
386 ScAddress
aPos(rPosX
, rPosY
, nTab
);
387 rCell
.assign(*pDoc
, aPos
);
391 return false; // alles leer bis links
393 --rPosX
; // weitersuchen
397 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(aPos
);
398 if ( !((SfxStringItem
&)pPattern
->GetItem(ATTR_HYPERLINK
)).GetValue().isEmpty() )
400 rURL
= ((SfxStringItem
&)pPattern
->GetItem(ATTR_HYPERLINK
)).GetValue();
403 else if (rCell
.meType
== CELLTYPE_EDIT
)
405 else if (rCell
.meType
== CELLTYPE_FORMULA
&& rCell
.mpFormula
->IsHyperLinkCell())
408 return false; // andere Zelle
416 // ---------------------------------------------------------------------------
417 // WB_DIALOGCONTROL noetig fuer UNO-Controls
418 ScGridWindow::ScGridWindow( Window
* pParent
, ScViewData
* pData
, ScSplitPos eWhichPos
)
419 : Window( pParent
, WB_CLIPCHILDREN
| WB_DIALOGCONTROL
),
420 DropTargetHelper( this ),
421 DragSourceHelper( this ),
423 mpOOSelection( NULL
),
424 mpOOSelectionBorder( NULL
),
425 mpOOAutoFill( NULL
),
426 mpOODragRect( NULL
),
429 mpAutoFillRect(static_cast<Rectangle
*>(NULL
)),
434 pFilterFloat( NULL
),
435 mpAutoFilterPopup(NULL
),
436 mpDPFieldPopup(NULL
),
437 mpFilterButton(NULL
),
438 nCursorHideCount( 0 ),
440 nMouseStatus( SC_GM_NONE
),
441 nNestedButtonState( SC_NESTEDBUTTON_NONE
),
442 nPagebreakMouse( SC_PD_NONE
),
448 meDragInsertMode( INS_NONE
),
449 nCurrentPointer( 0 ),
450 aComboButton( this ),
457 bPagebreakDrawn( false ),
459 bIsInScroll( false ),
461 bNeedsRepaint( false ),
462 bAutoMarkVisible( false ),
463 bListValButton( false )
467 case SC_SPLIT_TOPLEFT
:
468 eHWhich
= SC_SPLIT_LEFT
;
469 eVWhich
= SC_SPLIT_TOP
;
471 case SC_SPLIT_TOPRIGHT
:
472 eHWhich
= SC_SPLIT_RIGHT
;
473 eVWhich
= SC_SPLIT_TOP
;
475 case SC_SPLIT_BOTTOMLEFT
:
476 eHWhich
= SC_SPLIT_LEFT
;
477 eVWhich
= SC_SPLIT_BOTTOM
;
479 case SC_SPLIT_BOTTOMRIGHT
:
480 eHWhich
= SC_SPLIT_RIGHT
;
481 eVWhich
= SC_SPLIT_BOTTOM
;
484 OSL_FAIL("GridWindow: falsche Position");
489 SetMapMode(pViewData
->GetLogicMode(eWhich
));
490 EnableChildTransparentMode();
491 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN
| WINDOW_DLGCTRL_WANTFOCUS
);
493 SetHelpId( HID_SC_WIN_GRIDWIN
);
494 SetUniqueId( HID_SC_WIN_GRIDWIN
);
496 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
500 ScGridWindow::~ScGridWindow()
503 ImpDestroyOverlayObjects();
510 void ScGridWindow::Resize( const Size
& )
515 void ScGridWindow::ClickExtern()
519 // #i81298# don't delete the filter box when called from its select handler
520 // (possible through row header size update)
521 // #i84277# when initializing the filter box, a Basic error can deactivate the view
522 if ( pFilterBox
&& ( pFilterBox
->IsInSelect() || pFilterBox
->IsInInit() ) )
528 DELETEZ(pFilterFloat
);
534 mpDPFieldPopup
->close(false);
535 mpDPFieldPopup
.reset();
539 IMPL_LINK_NOARG(ScGridWindow
, PopupModeEndHdl
)
542 pFilterBox
->SetCancelled(); // nicht mehr auswaehlen
547 IMPL_LINK( ScGridWindow
, PopupSpellingHdl
, SpellCallbackInfo
*, pInfo
)
549 if( pInfo
->nCommand
== SPELLCMD_STARTSPELLDLG
)
550 pViewData
->GetDispatcher().Execute( SID_SPELL_DIALOG
, SFX_CALLMODE_ASYNCHRON
);
554 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol
, SCROW nRow
, sal_Bool bHasSelection
, const String
& rStr
)
558 ScDocument
* pDoc
= pViewData
->GetDocument();
559 SCTAB nTab
= pViewData
->GetTabNo();
560 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
561 if ( pDPObj
&& nCol
> 0 )
563 // look for the dimension header left of the drop-down arrow
564 sal_uInt16 nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
565 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
566 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
568 ScDPSaveData
aSaveData( *pDPObj
->GetSaveData() );
571 OUString aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
572 if ( !bIsDataLayout
)
574 ScDPSaveDimension
* pDim
= aSaveData
.GetDimensionByName(aDimName
);
578 const OUString aName
= rStr
;
579 pDim
->SetCurrentPage( &aName
);
582 pDim
->SetCurrentPage( NULL
);
584 ScDPObject
aNewObj( *pDPObj
);
585 aNewObj
.SetSaveData( aSaveData
);
586 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
587 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, sal_True
, false );
588 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
596 struct AutoFilterData
: public ScCheckListMenuWindow::ExtendedData
602 class AutoFilterAction
: public ScMenuFloatingWindow::Action
604 ScGridWindow
* mpWindow
;
605 ScGridWindow::AutoFilterMode meMode
;
607 AutoFilterAction(ScGridWindow
* p
, ScGridWindow::AutoFilterMode eMode
) :
608 mpWindow(p
), meMode(eMode
) {}
609 virtual void execute()
611 mpWindow
->UpdateAutoFilterFromMenu(meMode
);
615 class AutoFilterPopupEndAction
: public ScMenuFloatingWindow::Action
617 ScGridWindow
* mpWindow
;
620 AutoFilterPopupEndAction(ScGridWindow
* p
, const ScAddress
& rPos
) :
621 mpWindow(p
), maPos(rPos
) {}
622 virtual void execute()
624 mpWindow
->RefreshAutoFilterButton(maPos
);
628 class AddItemToEntry
: public std::unary_function
<OUString
, void>
630 ScQueryEntry::QueryItemsType
& mrItems
;
632 AddItemToEntry(ScQueryEntry::QueryItemsType
& rItems
) : mrItems(rItems
) {}
633 void operator() (const OUString
& rSelected
)
635 ScQueryEntry::Item aNew
;
636 aNew
.maString
= rSelected
;
637 aNew
.meType
= ScQueryEntry::ByString
;
639 mrItems
.push_back(aNew
);
643 class AddSelectedItemString
: public std::unary_function
<ScQueryEntry::Item
, void>
645 boost::unordered_set
<OUString
, OUStringHash
>& mrSet
;
647 AddSelectedItemString(boost::unordered_set
<OUString
, OUStringHash
>& r
) :
650 void operator() (const ScQueryEntry::Item
& rItem
)
652 mrSet
.insert(rItem
.maString
);
658 void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol
, SCROW nRow
)
660 SCTAB nTab
= pViewData
->GetTabNo();
661 ScDocument
* pDoc
= pViewData
->GetDocument();
663 mpAutoFilterPopup
.reset(new ScCheckListMenuWindow(this, pDoc
));
664 mpAutoFilterPopup
->setOKAction(new AutoFilterAction(this, Normal
));
665 mpAutoFilterPopup
->setPopupEndAction(
666 new AutoFilterPopupEndAction(this, ScAddress(nCol
, nRow
, nTab
)));
667 std::auto_ptr
<AutoFilterData
> pData(new AutoFilterData
);
668 pData
->maPos
= ScAddress(nCol
, nRow
, nTab
);
670 Point aPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
673 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
674 Rectangle
aCellRect(OutputToScreenPixel(aPos
), Size(nSizeX
, nSizeY
));
676 ScDBData
* pDBData
= pDoc
->GetDBAtCursor(nCol
, nRow
, nTab
);
680 pData
->mpData
= pDBData
;
681 mpAutoFilterPopup
->setExtendedData(pData
.release());
684 pDBData
->GetQueryParam(aParam
);
685 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(nCol
, false);
686 boost::unordered_set
<OUString
, OUStringHash
> aSelected
;
687 if (pEntry
&& pEntry
->bDoQuery
)
689 if (pEntry
->eOp
== SC_EQUAL
)
691 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
692 std::for_each(rItems
.begin(), rItems
.end(), AddSelectedItemString(aSelected
));
696 // Populate the check box list.
697 bool bHasDates
= false;
698 std::vector
<ScTypedStrData
> aStrings
;
699 pDoc
->GetFilterEntries(nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
701 mpAutoFilterPopup
->setMemberSize(aStrings
.size());
702 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
703 for (; it
!= itEnd
; ++it
)
705 const OUString
& aVal
= it
->GetString();
706 bool bSelected
= true;
707 if (!aSelected
.empty())
708 bSelected
= aSelected
.count(aVal
) > 0;
709 mpAutoFilterPopup
->addMember(aVal
, bSelected
);
711 mpAutoFilterPopup
->initMembers();
713 // Populate the menu.
714 mpAutoFilterPopup
->addMenuItem(
715 ScRscStrLoader(RID_POPUP_FILTER
, STR_MENU_SORT_ASC
).GetString(),
716 true, new AutoFilterAction(this, SortAscending
));
717 mpAutoFilterPopup
->addMenuItem(
718 ScRscStrLoader(RID_POPUP_FILTER
, STR_MENU_SORT_DESC
).GetString(),
719 true, new AutoFilterAction(this, SortDescending
));
720 mpAutoFilterPopup
->addSeparator();
721 mpAutoFilterPopup
->addMenuItem(
722 SC_RESSTR(SCSTR_TOP10FILTER
), true, new AutoFilterAction(this, Top10
));
723 mpAutoFilterPopup
->addMenuItem(
724 SC_RESSTR(SCSTR_FILTER_EMPTY
), true, new AutoFilterAction(this, Empty
));
725 mpAutoFilterPopup
->addMenuItem(
726 SC_RESSTR(SCSTR_FILTER_NOTEMPTY
), true, new AutoFilterAction(this, NonEmpty
));
727 mpAutoFilterPopup
->addSeparator();
728 mpAutoFilterPopup
->addMenuItem(
729 SC_RESSTR(SCSTR_STDFILTER
), true, new AutoFilterAction(this, Custom
));
731 ScCheckListMenuWindow::Config aConfig
;
732 aConfig
.mbAllowEmptySet
= false;
733 aConfig
.mbRTL
= pViewData
->GetDocument()->IsLayoutRTL(pViewData
->GetTabNo());
734 mpAutoFilterPopup
->setConfig(aConfig
);
735 mpAutoFilterPopup
->launch(aCellRect
);
738 void ScGridWindow::RefreshAutoFilterButton(const ScAddress
& rPos
)
742 bool bFilterActive
= IsAutoFilterActive(rPos
.Col(), rPos
.Row(), rPos
.Tab());
743 mpFilterButton
->setHasHiddenMember(bFilterActive
);
744 mpFilterButton
->setPopupPressed(false);
745 mpFilterButton
->draw();
749 void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode
)
751 const AutoFilterData
* pData
=
752 static_cast<const AutoFilterData
*>(mpAutoFilterPopup
->getExtendedData());
757 const ScAddress
& rPos
= pData
->maPos
;
758 ScDBData
* pDBData
= pData
->mpData
;
767 ScDocument
* pDoc
= pViewData
->GetDocument();
768 SCTAB nTab
= pViewData
->GetTabNo();
769 SCCOL nCol
= rPos
.Col();
770 ScSortParam aSortParam
;
771 pDBData
->GetSortParam(aSortParam
);
772 if (nCol
< aSortParam
.nCol1
|| nCol
> aSortParam
.nCol2
)
776 bool bHasHeader
= pDoc
->HasColHeader(
777 aSortParam
.nCol1
, aSortParam
.nRow1
, aSortParam
.nCol2
, aSortParam
.nRow2
, nTab
);
779 aSortParam
.bHasHeader
= bHasHeader
;
780 aSortParam
.bByRow
= true;
781 aSortParam
.bCaseSens
= false;
782 aSortParam
.bNaturalSort
= false;
783 aSortParam
.bIncludePattern
= true;
784 aSortParam
.bInplace
= true;
785 aSortParam
.maKeyState
[0].bDoSort
= true;
786 aSortParam
.maKeyState
[0].nField
= nCol
;
787 aSortParam
.maKeyState
[0].bAscending
= (eMode
== SortAscending
);
789 for (size_t i
= 1; i
< aSortParam
.GetSortKeyCount(); ++i
)
790 aSortParam
.maKeyState
[i
].bDoSort
= false;
792 pViewData
->GetViewShell()->UISort(aSortParam
);
802 pDBData
->GetArea(aRange
);
803 pViewData
->GetView()->MarkRange(aRange
);
804 pViewData
->GetView()->SetCursor(rPos
.Col(), rPos
.Row());
805 pViewData
->GetDispatcher().Execute(SID_FILTER
, SFX_CALLMODE_SLOT
|SFX_CALLMODE_RECORD
);
810 pDBData
->GetQueryParam(aParam
);
812 if (eMode
== Normal
&& mpAutoFilterPopup
->isAllSelected())
814 // Remove this entry.
815 aParam
.RemoveEntryByField(rPos
.Col());
819 // Try to use the existing entry for the column (if one exists).
820 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(rPos
.Col(), true);
823 // Something went terribly wrong!
826 pEntry
->bDoQuery
= true;
827 pEntry
->nField
= rPos
.Col();
828 pEntry
->eConnect
= SC_AND
;
834 pEntry
->eOp
= SC_EQUAL
;
836 ScCheckListMenuWindow::ResultType aResult
;
837 mpAutoFilterPopup
->getResult(aResult
);
838 std::vector
<OUString
> aSelected
;
839 ScCheckListMenuWindow::ResultType::const_iterator itr
= aResult
.begin(), itrEnd
= aResult
.end();
840 for (; itr
!= itrEnd
; ++itr
)
843 aSelected
.push_back(itr
->first
);
846 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
848 std::for_each(aSelected
.begin(), aSelected
.end(), AddItemToEntry(rItems
));
852 pEntry
->eOp
= SC_TOPVAL
;
853 pEntry
->GetQueryItem().meType
= ScQueryEntry::ByString
;
854 pEntry
->GetQueryItem().maString
= OUString("10");
857 pEntry
->SetQueryByEmpty();
860 pEntry
->SetQueryByNonEmpty();
863 // We don't know how to handle this!
868 pViewData
->GetView()->Query(aParam
, NULL
, true);
869 pDBData
->SetQueryParam(aParam
);
874 void getCellGeometry(Point
& rScrPos
, Size
& rScrSize
, const ScViewData
* pViewData
, SCCOL nCol
, SCROW nRow
, ScSplitPos eWhich
)
876 // Get the screen position of the cell.
877 rScrPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
879 // Get the screen size of the cell.
881 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
882 rScrSize
= Size(nSizeX
-1, nSizeY
-1);
887 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol
, SCROW nRow
)
890 // We assume that the page field button is located in cell to the immediate left.
893 SCTAB nTab
= pViewData
->GetTabNo();
894 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
900 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
901 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
-1, nRow
, nTab
), pDPObj
);
904 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol
, SCROW nRow
)
906 SCTAB nTab
= pViewData
->GetTabNo();
907 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
913 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
914 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
, nRow
, nTab
), pDPObj
);
917 void ScGridWindow::DoScenarioMenu( const ScRange
& rScenRange
)
922 SCCOL nCol
= rScenRange
.aEnd
.Col(); // Zelle unterhalb des Buttons
923 SCROW nRow
= rScenRange
.aStart
.Row();
926 nRow
= rScenRange
.aEnd
.Row() + 1; // Bereich ganz oben -> Button unterhalb
927 if (nRow
>MAXROW
) nRow
= MAXROW
;
928 //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
931 ScDocument
* pDoc
= pViewData
->GetDocument();
932 SCTAB nTab
= pViewData
->GetTabNo();
933 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
938 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
939 // The button height should not use the merged cell height, should still use single row height
940 nSizeY
= pViewData
->ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
941 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
944 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
945 aCellRect
.Top() -= nSizeY
;
946 aCellRect
.Bottom() -= nSizeY
- 1;
947 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
948 // (wenn die Linie verdeckt wird, sieht es komisch aus...)
950 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
951 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
952 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_SCENARIO
);
954 pFilterBox
->EnableMirroring();
959 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
960 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
962 nHeight
= GetTextHeight();
963 nHeight
*= SC_FILTERLISTBOX_LINES
;
965 SetMapMode( aOldMode
);
971 // ParentSize Abfrage fehlt
972 Size
aSize( nSizeX
, nHeight
);
973 pFilterBox
->SetSizePixel( aSize
);
974 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
975 pFilterBox
->SetUpdateMode(false);
977 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
984 SCTAB nTabCount
= pDoc
->GetTableCount();
985 SCTAB nEntryCount
= 0;
986 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
988 if (pDoc
->HasScenarioRange( i
, rScenRange
))
989 if (pDoc
->GetName( i
, aTabName
))
991 pFilterBox
->InsertEntry( aTabName
);
992 if (pDoc
->IsActiveScenario(i
))
994 long nTextWidth
= pFilterBox
->GetTextWidth( aTabName
);
995 if ( nTextWidth
> nMaxText
)
996 nMaxText
= nTextWidth
;
1000 if (nEntryCount
> SC_FILTERLISTBOX_LINES
)
1001 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
1002 nMaxText
+= 4; // fuer Rand
1003 if ( nMaxText
> 300 )
1004 nMaxText
= 300; // auch nicht uebertreiben (Pixel)
1006 if (nMaxText
> nSizeX
) // Groesse auf benoetigte Groesse anpassen
1008 long nDiff
= nMaxText
- nSizeX
;
1009 aSize
= Size( nMaxText
, nHeight
);
1010 pFilterBox
->SetSizePixel( aSize
);
1011 pFilterFloat
->SetOutputSizePixel( aSize
);
1015 // also move popup position
1016 long nNewX
= aCellRect
.Left() - nDiff
;
1019 aCellRect
.Left() = nNewX
;
1023 pFilterFloat
->SetOutputSizePixel( aSize
);
1024 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1026 pFilterBox
->SetUpdateMode(sal_True
);
1027 pFilterBox
->GrabFocus();
1029 sal_uInt16 nPos
= LISTBOX_ENTRY_NOTFOUND
;
1030 if (!aCurrent
.isEmpty())
1032 nPos
= pFilterBox
->GetEntryPos(String(aCurrent
));
1034 if (LISTBOX_ENTRY_NOTFOUND
== nPos
&& pFilterBox
->GetEntryCount() > 0 )
1036 if (LISTBOX_ENTRY_NOTFOUND
!= nPos
)
1037 pFilterBox
->SelectEntryPos(nPos
);
1039 pFilterBox
->EndInit();
1041 // Szenario-Auswahl kommt aus MouseButtonDown:
1042 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1044 nMouseStatus
= SC_GM_FILTER
;
1048 void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol
, SCROW nRow
, bool bDataSelect
)
1051 delete pFilterFloat
;
1054 ScDocument
* pDoc
= pViewData
->GetDocument();
1055 SCTAB nTab
= pViewData
->GetTabNo();
1056 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1061 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1062 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1066 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
1069 aPos
.Y() += nSizeY
- 1;
1071 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
1072 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
1073 pFilterBox
= new ScFilterListBox(
1074 pFilterFloat
, this, nCol
, nRow
, bDataSelect
? SC_FILTERBOX_DATASELECT
: SC_FILTERBOX_FILTER
);
1075 // Fix for bug fdo#44925
1076 if (Application::GetSettings().GetLayoutRTL() != bLayoutRTL
)
1077 pFilterBox
->EnableMirroring();
1082 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
1083 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
1085 nHeight
= GetTextHeight();
1086 nHeight
*= SC_FILTERLISTBOX_LINES
;
1088 SetMapMode( aOldMode
);
1089 SetFont( aOldFont
);
1094 bool bEmpty
= false;
1095 std::vector
<ScTypedStrData
> aStrings
; // case sensitive
1096 if ( bDataSelect
) // Auswahl-Liste
1099 pDoc
->GetDataEntries(nCol
, nRow
, nTab
, true, aStrings
);
1100 if (aStrings
.empty())
1105 //! wird der Titel ueberhaupt ausgewertet ???
1106 OUString aString
= pDoc
->GetString(nCol
, nRow
, nTab
);
1107 pFilterBox
->SetText( aString
);
1112 static const sal_uInt16 nDefIDs
[] = { SCSTR_TOP10FILTER
, SCSTR_STDFILTER
, SCSTR_FILTER_EMPTY
, SCSTR_FILTER_NOTEMPTY
};
1113 const size_t nDefCount
= SAL_N_ELEMENTS(nDefIDs
);
1114 for (i
=0; i
<nDefCount
; i
++)
1116 String
aEntry( (ScResId
) nDefIDs
[i
] );
1117 pFilterBox
->InsertEntry( aEntry
);
1118 long nTextWidth
= pFilterBox
->GetTextWidth( aEntry
);
1119 if ( nTextWidth
> nMaxText
)
1120 nMaxText
= nTextWidth
;
1122 pFilterBox
->SetSeparatorPos( nDefCount
- 1 );
1125 bool bHasDates
= false;
1126 pDoc
->GetFilterEntries( nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
1127 pFilterBox
->SetListHasDates(bHasDates
);
1129 // check widths of numerical entries (string entries are not included)
1130 // so all numbers are completely visible
1131 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1132 for (; it
!= itEnd
; ++it
)
1134 if (!it
->IsStrData()) // only numerical entries
1136 long nTextWidth
= pFilterBox
->GetTextWidth(it
->GetString());
1137 if ( nTextWidth
> nMaxText
)
1138 nMaxText
= nTextWidth
;
1142 // add scrollbar width if needed (string entries are counted here)
1143 // (scrollbar is shown if the box is exactly full?)
1144 if (aStrings
.size() + nDefCount
>= SC_FILTERLISTBOX_LINES
)
1145 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
1147 nMaxText
+= 4; // for borders
1149 if ( nMaxText
> nSizeX
)
1150 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
1155 // Position und Groesse an Fenster anpassen
1156 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
1158 Size aParentSize
= GetParent()->GetOutputSizePixel();
1159 Size
aSize( nSizeX
, nHeight
);
1161 if ( aSize
.Height() > aParentSize
.Height() )
1162 aSize
.Height() = aParentSize
.Height();
1163 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
1164 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
1166 pFilterBox
->SetSizePixel( aSize
);
1167 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1168 pFilterBox
->SetUpdateMode(false);
1170 pFilterFloat
->SetOutputSizePixel( aSize
);
1171 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1174 bool bWait
= aStrings
.size() > 100;
1179 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1180 for (; it
!= itEnd
; ++it
)
1181 pFilterBox
->InsertEntry(it
->GetString());
1186 pFilterBox
->SetUpdateMode(true);
1189 sal_uInt16 nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
1191 if (!bDataSelect
) // AutoFilter: aktiven Eintrag selektieren
1193 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1196 ScQueryParam aParam
;
1197 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1199 sal_Bool bValid
= sal_True
;
1200 SCSIZE nCount
= aParam
.GetEntryCount();
1201 for (SCSIZE j
= 0; j
< nCount
&& bValid
; ++j
) // bisherige Filter-Einstellungen
1202 if (aParam
.GetEntry(j
).bDoQuery
)
1204 //! Abfrage mit DrawButtons zusammenfassen!
1206 ScQueryEntry
& rEntry
= aParam
.GetEntry(j
);
1208 if (rEntry
.eConnect
!= SC_AND
)
1210 if (rEntry
.nField
== nCol
)
1212 const OUString
& rQueryStr
= rEntry
.GetQueryItem().maString
;
1213 if (rEntry
.eOp
== SC_EQUAL
)
1215 if (!rQueryStr
.isEmpty())
1217 nSelPos
= pFilterBox
->GetEntryPos(rQueryStr
);
1220 else if ( rEntry
.eOp
== SC_TOPVAL
&& rQueryStr
== "10" )
1221 nSelPos
= SC_AUTOFILTER_TOP10
;
1223 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1228 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1234 sal_uLong nIndex
= ((SfxUInt32Item
*)pDoc
->GetAttr(
1235 nCol
, nRow
, nTab
, ATTR_VALIDDATA
))->GetValue();
1238 const ScValidationData
* pData
= pDoc
->GetValidationEntry( nIndex
);
1241 ScTypedStrData
* pNew
= NULL
;
1242 OUString aDocStr
= pDoc
->GetString(nCol
, nRow
, nTab
);
1243 if ( pDoc
->HasValueData( nCol
, nRow
, nTab
) )
1245 double fVal
= pDoc
->GetValue(ScAddress(nCol
, nRow
, nTab
));
1246 pNew
= new ScTypedStrData(aDocStr
, fVal
, ScTypedStrData::Value
);
1249 pNew
= new ScTypedStrData(aDocStr
, 0.0, ScTypedStrData::Standard
);
1251 bool bSortList
= ( pData
->GetListType() == ValidListType::SORTEDASCENDING
);
1254 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1255 std::vector
<ScTypedStrData
>::const_iterator it
=
1256 std::find_if(itBeg
, itEnd
, FindTypedStrData(*pNew
, true));
1259 nSelPos
= std::distance(itBeg
, it
);
1263 ScTypedStrData::EqualCaseSensitive aHdl
;
1264 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1265 std::vector
<ScTypedStrData
>::const_iterator it
= itBeg
;
1266 for (; it
!= itEnd
&& LISTBOX_ENTRY_NOTFOUND
== nSelPos
; ++it
)
1268 if (aHdl(*it
, *pNew
))
1269 nSelPos
= std::distance(itBeg
, it
);
1277 // neu (309): irgendwas muss immer selektiert sein:
1278 if ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
&& pFilterBox
->GetEntryCount() > 0 && !bDataSelect
)
1281 // keine leere Auswahl-Liste anzeigen:
1285 DELETEZ(pFilterBox
); // war nix
1286 DELETEZ(pFilterFloat
);
1290 pFilterBox
->GrabFocus();
1292 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1293 if ( LISTBOX_ENTRY_NOTFOUND
!= nSelPos
)
1294 pFilterBox
->SelectEntryPos( nSelPos
);
1298 pFilterBox
->SetNoSelection();
1301 pFilterBox
->EndInit();
1305 // AutoFilter (aus MouseButtonDown):
1306 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1308 nMouseStatus
= SC_GM_FILTER
;
1314 void ScGridWindow::FilterSelect( sal_uLong nSel
)
1316 String aString
= pFilterBox
->GetEntry( static_cast< sal_uInt16
>( nSel
) );
1318 SCCOL nCol
= pFilterBox
->GetCol();
1319 SCROW nRow
= pFilterBox
->GetRow();
1320 switch ( pFilterBox
->GetMode() )
1322 case SC_FILTERBOX_DATASELECT
:
1323 ExecDataSelect( nCol
, nRow
, aString
);
1325 case SC_FILTERBOX_FILTER
:
1326 ExecFilter( nSel
, nCol
, nRow
, aString
, pFilterBox
->HasDates() );
1328 case SC_FILTERBOX_SCENARIO
:
1329 pViewData
->GetView()->UseScenario( aString
);
1331 case SC_FILTERBOX_PAGEFIELD
:
1332 // first entry is "all"
1333 ExecPageFieldSelect( nCol
, nRow
, (nSel
!= 0), aString
);
1338 pFilterFloat
->EndPopupMode();
1340 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1343 void ScGridWindow::ExecDataSelect( SCCOL nCol
, SCROW nRow
, const String
& rStr
)
1347 SCTAB nTab
= pViewData
->GetTabNo();
1348 ScViewFunc
* pView
= pViewData
->GetView();
1349 pView
->EnterData( nCol
, nRow
, nTab
, rStr
);
1351 // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1352 // if the cursor is moved afterwards.
1353 pView
->CellContentChanged();
1357 void ScGridWindow::ExecFilter( sal_uLong nSel
,
1358 SCCOL nCol
, SCROW nRow
,
1359 const String
& aValue
, bool bCheckForDates
)
1361 SCTAB nTab
= pViewData
->GetTabNo();
1362 ScDocument
* pDoc
= pViewData
->GetDocument();
1364 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1367 ScQueryParam aParam
;
1368 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1370 if (SC_AUTOFILTER_CUSTOM
== nSel
)
1377 pDBData
->GetArea( nAreaTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
);
1378 pViewData
->GetView()->MarkRange( ScRange( nStartCol
,nStartRow
,nAreaTab
,nEndCol
,nEndRow
,nAreaTab
));
1379 pViewData
->GetView()->SetCursor(nCol
,nRow
); //! auch ueber Slot ??
1380 pViewData
->GetDispatcher().Execute( SID_FILTER
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1384 sal_Bool bDeleteOld
= false;
1385 SCSIZE nQueryPos
= 0;
1386 sal_Bool bFound
= false;
1387 if (!aParam
.bInplace
)
1388 bDeleteOld
= sal_True
;
1390 bDeleteOld
= sal_True
;
1391 SCSIZE nCount
= aParam
.GetEntryCount();
1392 for (SCSIZE i
= 0; i
< nCount
&& !bDeleteOld
; ++i
) // bisherige Filter-Einstellungen
1393 if (aParam
.GetEntry(i
).bDoQuery
)
1395 //! Abfrage mit DrawButtons zusammenfassen!
1397 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1399 if (rEntry
.eConnect
!= SC_AND
)
1400 bDeleteOld
= sal_True
;
1402 if (rEntry
.nField
== nCol
)
1404 if (bFound
) // diese Spalte zweimal?
1405 bDeleteOld
= sal_True
;
1415 SCSIZE nEC
= aParam
.GetEntryCount();
1416 for (SCSIZE i
=0; i
<nEC
; i
++)
1417 aParam
.GetEntry(i
).Clear();
1419 aParam
.bInplace
= sal_True
;
1420 aParam
.bRegExp
= false;
1423 if ( nQueryPos
< nCount
|| SC_AUTOFILTER_ALL
== nSel
) // loeschen geht immer
1427 ScQueryEntry
& rNewEntry
= aParam
.GetEntry(nQueryPos
);
1428 ScQueryEntry::Item
& rItem
= rNewEntry
.GetQueryItem();
1429 rNewEntry
.bDoQuery
= true;
1430 rNewEntry
.nField
= nCol
;
1431 rItem
.meType
= bCheckForDates
? ScQueryEntry::ByDate
: ScQueryEntry::ByString
;
1433 if ( nSel
== SC_AUTOFILTER_TOP10
)
1435 rNewEntry
.eOp
= SC_TOPVAL
;
1436 rItem
.maString
= OUString("10");
1438 else if (nSel
== SC_AUTOFILTER_EMPTY
)
1440 rNewEntry
.SetQueryByEmpty();
1442 else if (nSel
== SC_AUTOFILTER_NOTEMPTY
)
1444 rNewEntry
.SetQueryByNonEmpty();
1448 rNewEntry
.eOp
= SC_EQUAL
;
1449 rItem
.maString
= aValue
;
1452 rNewEntry
.eConnect
= SC_AND
;
1457 aParam
.RemoveEntryByField(nCol
);
1460 // end edit mode - like in ScCellShell::ExecuteDB
1461 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1463 SC_MOD()->InputEnterHandler();
1464 pViewData
->GetViewShell()->UpdateInputHandler();
1467 pViewData
->GetView()->Query( aParam
, NULL
, true );
1468 pDBData
->SetQueryParam( aParam
); // speichern
1470 else // "Zuviele Bedingungen"
1471 pViewData
->GetView()->ErrorMessage( STR_FILTER_TOOMANY
);
1476 OSL_FAIL("Wo ist der Datenbankbereich?");
1480 void ScGridWindow::SetPointer( const Pointer
& rPointer
)
1482 nCurrentPointer
= 0;
1483 Window::SetPointer( rPointer
);
1486 void ScGridWindow::MoveMouseStatus( ScGridWindow
& rDestWin
)
1490 rDestWin
.nButtonDown
= nButtonDown
;
1491 rDestWin
.nMouseStatus
= nMouseStatus
;
1496 rDestWin
.bRFMouse
= bRFMouse
;
1497 rDestWin
.bRFSize
= bRFSize
;
1498 rDestWin
.nRFIndex
= nRFIndex
;
1499 rDestWin
.nRFAddX
= nRFAddX
;
1500 rDestWin
.nRFAddY
= nRFAddY
;
1504 if (nPagebreakMouse
)
1506 rDestWin
.nPagebreakMouse
= nPagebreakMouse
;
1507 rDestWin
.nPagebreakBreak
= nPagebreakBreak
;
1508 rDestWin
.nPagebreakPrev
= nPagebreakPrev
;
1509 rDestWin
.aPagebreakSource
= aPagebreakSource
;
1510 rDestWin
.aPagebreakDrag
= aPagebreakDrag
;
1511 nPagebreakMouse
= SC_PD_NONE
;
1515 bool ScGridWindow::TestMouse( const MouseEvent
& rMEvt
, bool bAction
)
1517 // MouseEvent buttons must only be checked if bAction==TRUE
1518 // to allow changing the mouse pointer in MouseMove,
1519 // but not start AutoFill with right button (#74229#).
1520 // with bAction==sal_True, SetFillMode / SetDragMode is called
1522 if ( bAction
&& !rMEvt
.IsLeft() )
1525 bool bNewPointer
= false;
1527 SfxInPlaceClient
* pClient
= pViewData
->GetViewShell()->GetIPClient();
1528 bool bOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
1530 if ( pViewData
->IsActive() && !bOleActive
)
1532 ScDocument
* pDoc
= pViewData
->GetDocument();
1533 SCTAB nTab
= pViewData
->GetTabNo();
1534 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1539 if (pViewData
->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
)
1541 if (aMarkRange
.aStart
.Tab() == pViewData
->GetTabNo() && mpAutoFillRect
)
1543 Point aMousePos
= rMEvt
.GetPosPixel();
1544 if (mpAutoFillRect
->IsInside(aMousePos
))
1546 SetPointer( Pointer( POINTER_CROSS
) ); //! dickeres Kreuz ?
1549 SCCOL nX
= aMarkRange
.aEnd
.Col();
1550 SCROW nY
= aMarkRange
.aEnd
.Row();
1552 if ( lcl_IsEditableMatrix( pViewData
->GetDocument(), aMarkRange
) )
1553 pViewData
->SetDragMode(
1554 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
, SC_FILL_MATRIX
);
1556 pViewData
->SetFillMode(
1557 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
);
1559 // The simple selection must also be recognized when dragging,
1560 // where the Marking flag is set and MarkToSimple won't work anymore.
1561 pViewData
->GetMarkData().MarkToSimple();
1568 // Embedded-Rechteck
1570 if (pDoc
->IsEmbedded())
1573 pDoc
->GetEmbedded( aRange
);
1574 if ( pViewData
->GetTabNo() == aRange
.aStart
.Tab() )
1576 Point aStartPos
= pViewData
->GetScrPos( aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
);
1577 Point aEndPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
);
1578 Point aMousePos
= rMEvt
.GetPosPixel();
1584 bool bTop
= ( aMousePos
.X() >= aStartPos
.X()-3 && aMousePos
.X() <= aStartPos
.X()+1 &&
1585 aMousePos
.Y() >= aStartPos
.Y()-3 && aMousePos
.Y() <= aStartPos
.Y()+1 );
1586 bool bBottom
= ( aMousePos
.X() >= aEndPos
.X()-3 && aMousePos
.X() <= aEndPos
.X()+1 &&
1587 aMousePos
.Y() >= aEndPos
.Y()-3 && aMousePos
.Y() <= aEndPos
.Y()+1 );
1588 if ( bTop
|| bBottom
)
1590 SetPointer( Pointer( POINTER_CROSS
) );
1593 sal_uInt8 nMode
= bTop
? SC_FILL_EMBED_LT
: SC_FILL_EMBED_RB
;
1594 pViewData
->SetDragMode(
1595 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1596 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nMode
);
1604 if (!bNewPointer
&& bAction
)
1606 pViewData
->ResetFillMode();
1612 void ScGridWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1614 nNestedButtonState
= SC_NESTEDBUTTON_DOWN
;
1616 MouseEventState aState
;
1617 HandleMouseButtonDown(rMEvt
, aState
);
1618 if (aState
.mbActivatePart
)
1619 pViewData
->GetView()->ActivatePart(eWhich
);
1621 if ( nNestedButtonState
== SC_NESTEDBUTTON_UP
)
1623 // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1624 // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1625 // simulate another MouseButtonUp call, so the selection state is consistent.
1627 nButtonDown
= rMEvt
.GetButtons();
1631 EndTracking(); // normally done in VCL as part of MouseButtonUp handling
1633 nNestedButtonState
= SC_NESTEDBUTTON_NONE
;
1636 void ScGridWindow::HandleMouseButtonDown( const MouseEvent
& rMEvt
, MouseEventState
& rState
)
1638 // We have to check if a context menu is shown and we have an UI
1639 // active inplace client. In that case we have to ignore the event.
1640 // Otherwise we would crash (context menu has been
1641 // opened by inplace client and we would deactivate the inplace client,
1642 // the contex menu is closed by VCL asynchronously which in the end
1643 // would work on deleted objects or the context menu has no parent anymore)
1644 SfxViewShell
* pViewSh
= pViewData
->GetViewShell();
1645 SfxInPlaceClient
* pClient
= pViewSh
->GetIPClient();
1647 pClient
->IsObjectInPlaceActive() &&
1648 PopupMenu::IsInExecute() )
1651 aCurMousePos
= rMEvt
.GetPosPixel();
1653 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1654 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1655 ClickExtern(); // loescht FilterBox, wenn vorhanden
1657 HideNoteMarker(); // Notiz-Anzeige
1661 ScModule
* pScMod
= SC_MOD();
1662 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1665 pScActiveViewShell
= pViewData
->GetViewShell(); // falls auf Link geklickt wird
1666 nScClickMouseModifier
= rMEvt
.GetModifier(); // um Control-Klick immer zu erkennen
1668 sal_Bool bDetective
= pViewData
->GetViewShell()->IsAuditShell();
1669 sal_Bool bRefMode
= pViewData
->IsRefMode(); // Referenz angefangen
1670 sal_Bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
1671 sal_Bool bEditMode
= pViewData
->HasEditView(eWhich
); // auch bei Mode==SC_INPUT_TYPE
1672 sal_Bool bDouble
= (rMEvt
.GetClicks() == 2);
1674 // DeactivateIP passiert nur noch bei MarkListHasChanged
1676 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1677 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1679 if ( !nButtonDown
|| !bDouble
) // single (first) click is always valid
1680 nButtonDown
= rMEvt
.GetButtons(); // set nButtonDown first, so StopMarking works
1682 if ( ( bEditMode
&& pViewData
->GetActivePart() == eWhich
) || !bFormulaMode
)
1685 // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1686 // but a single (first) click is always valid
1687 if ( nMouseStatus
== SC_GM_IGNORE
&& bDouble
)
1690 nMouseStatus
= SC_GM_NONE
;
1694 if ( bDetective
) // Detektiv-Fuell-Modus
1696 if ( rMEvt
.IsLeft() && !rMEvt
.GetModifier() )
1698 Point aPos
= rMEvt
.GetPosPixel();
1701 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1703 SfxInt16Item
aPosXItem( SID_RANGE_COL
, nPosX
);
1704 SfxInt32Item
aPosYItem( SID_RANGE_ROW
, nPosY
);
1705 pViewData
->GetDispatcher().Execute( SID_FILL_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
1706 &aPosXItem
, &aPosYItem
, (void*)0L );
1710 nMouseStatus
= SC_GM_NONE
;
1715 nMouseStatus
= SC_GM_NONE
;
1717 rState
.mbActivatePart
= !bFormulaMode
; // Don't activate when in formula mode.
1721 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1722 pSelEng
->SetWindow(this);
1723 pSelEng
->SetWhich(eWhich
);
1724 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1727 if (bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()))
1729 Point aPos
= rMEvt
.GetPosPixel();
1732 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1734 EditView
* pEditView
;
1737 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1738 SCCOL nEndCol
= pViewData
->GetEditEndCol();
1739 SCROW nEndRow
= pViewData
->GetEditEndRow();
1741 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
1742 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
1744 // beim Klick in die Tabellen-EditView immer den Focus umsetzen
1745 if (bFormulaMode
) // sonst ist es oben schon passiert
1748 pScMod
->SetInputMode( SC_INPUT_TABLE
);
1750 bEditMode
= pEditView
->MouseButtonDown( rMEvt
);
1755 if (pScMod
->GetIsWaterCan())
1757 //! was is mit'm Mac ???
1758 if ( rMEvt
.GetModifier() + rMEvt
.GetButtons() == MOUSE_RIGHT
)
1760 nMouseStatus
= SC_GM_WATERUNDO
;
1765 // Reihenfolge passend zum angezeigten Cursor:
1766 // RangeFinder, AutoFill, PageBreak, Drawing
1769 bool bFound
= HitRangeFinder(rMEvt
.GetPosPixel(), bCorner
, &nRFIndex
, &nRFAddX
, &nRFAddY
);
1773 bRFMouse
= true; // die anderen Variablen sind oben initialisiert
1775 rState
.mbActivatePart
= true; // always activate ?
1780 sal_Bool bCrossPointer
= TestMouse( rMEvt
, sal_True
);
1781 if ( bCrossPointer
)
1784 pViewData
->GetView()->FillCrossDblClick();
1786 pScMod
->InputEnterHandler(); // Autofill etc.
1789 if ( !bCrossPointer
)
1791 nPagebreakMouse
= HitPageBreak( rMEvt
.GetPosPixel(), &aPagebreakSource
,
1792 &nPagebreakBreak
, &nPagebreakPrev
);
1793 if (nPagebreakMouse
)
1795 bPagebreakDrawn
= false;
1797 PagebreakMove( rMEvt
, false );
1802 if (!bFormulaMode
&& !bEditMode
&& rMEvt
.IsLeft())
1804 if ( !bCrossPointer
&& DrawMouseButtonDown(rMEvt
) )
1809 pViewData
->GetViewShell()->SetDrawShell( false ); // kein Draw-Objekt selektiert
1811 // TestMouse schon oben passiert
1814 Point aPos
= rMEvt
.GetPosPixel();
1817 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1818 SCTAB nTab
= pViewData
->GetTabNo();
1819 ScDocument
* pDoc
= pViewData
->GetDocument();
1821 // Auto filter / pivot table / data select popup. This shouldn't activate the part.
1823 if ( !bDouble
&& !bFormulaMode
&& rMEvt
.IsLeft() )
1827 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nRealPosX
, nRealPosY
, false );//the real row/col
1828 ScMergeFlagAttr
* pRealPosAttr
= (ScMergeFlagAttr
*)
1829 pDoc
->GetAttr( nRealPosX
, nRealPosY
, nTab
, ATTR_MERGE_FLAG
);
1830 ScMergeFlagAttr
* pAttr
= (ScMergeFlagAttr
*)
1831 pDoc
->GetAttr( nPosX
, nPosY
, nTab
, ATTR_MERGE_FLAG
);
1832 if( pRealPosAttr
->HasAutoFilter() )
1834 SC_MOD()->InputEnterHandler();
1835 if (DoAutoFilterButton( nRealPosX
, nRealPosY
, rMEvt
))
1838 if (pAttr
->HasAutoFilter())
1840 if (DoAutoFilterButton(nPosX
, nPosY
, rMEvt
))
1842 rState
.mbActivatePart
= false;
1847 if (pAttr
->HasPivotButton() || pAttr
->HasPivotPopupButton())
1849 DoPushPivotButton(nPosX
, nPosY
, rMEvt
, pAttr
->HasPivotButton(), pAttr
->HasPivotPopupButton());
1850 rState
.mbActivatePart
= false;
1854 // List Validity drop-down button
1856 if ( bListValButton
)
1858 Rectangle aButtonRect
= GetListValButtonRect( aListValPos
);
1859 if ( aButtonRect
.IsInside( aPos
) )
1861 LaunchDataSelectMenu( aListValPos
.Col(), aListValPos
.Row(), true );
1863 nMouseStatus
= SC_GM_FILTER
; // not set in DoAutoFilterMenue for bDataSelect
1865 rState
.mbActivatePart
= false;
1872 // scenario selection
1876 if ( rMEvt
.IsLeft() && HasScenarioButton( aPos
, aScenRange
) )
1878 DoScenarioMenu( aScenRange
);
1883 // Doppelklick angefangen ?
1886 // StopMarking kann aus DrawMouseButtonDown gerufen werden
1888 if ( nMouseStatus
!= SC_GM_IGNORE
&& !bRefMode
)
1890 if ( bDouble
&& !bCrossPointer
)
1892 if (nMouseStatus
== SC_GM_TABDOWN
)
1893 nMouseStatus
= SC_GM_DBLDOWN
;
1896 nMouseStatus
= SC_GM_TABDOWN
;
1900 // Links in Edit-Zellen
1903 sal_Bool bAlt
= rMEvt
.IsMod2();
1904 if ( !bAlt
&& rMEvt
.IsLeft() &&
1905 GetEditUrl(rMEvt
.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
1907 SetPointer( Pointer( POINTER_REFHAND
) );
1908 nMouseStatus
= SC_GM_URLDOWN
; // auch nur dann beim ButtonUp ausfuehren
1913 // Gridwin - SelectionEngine
1916 if ( rMEvt
.IsLeft() )
1918 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1919 pSelEng
->SetWindow(this);
1920 pSelEng
->SetWhich(eWhich
);
1921 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1923 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1924 if ( pViewData
->GetView()->SelMouseButtonDown( rMEvt
) )
1926 if (IsMouseCaptured())
1928 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1929 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1933 pViewData
->GetMarkData().SetMarking(sal_True
);
1939 void ScGridWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
1941 aCurMousePos
= rMEvt
.GetPosPixel();
1942 ScDocument
* pDoc
= pViewData
->GetDocument();
1943 ScMarkData
& rMark
= pViewData
->GetMarkData();
1945 // #i41690# detect a MouseButtonUp call from within MouseButtonDown
1946 // (possible through Reschedule from storing an OLE object that is deselected)
1948 if ( nNestedButtonState
== SC_NESTEDBUTTON_DOWN
)
1949 nNestedButtonState
= SC_NESTEDBUTTON_UP
;
1951 if (nButtonDown
!= rMEvt
.GetButtons())
1952 nMouseStatus
= SC_GM_IGNORE
; // reset und return
1956 if (nMouseStatus
== SC_GM_IGNORE
)
1958 nMouseStatus
= SC_GM_NONE
;
1959 // Selection-Engine: Markieren abbrechen
1960 pViewData
->GetView()->GetSelEngine()->Reset();
1961 rMark
.SetMarking(false);
1962 if (pViewData
->IsAnyFillMode())
1964 pViewData
->GetView()->StopRefMode();
1965 pViewData
->ResetFillMode();
1968 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
1973 if (nMouseStatus
== SC_GM_FILTER
)
1975 nMouseStatus
= SC_GM_NONE
;
1977 return; // da muss nix mehr passieren
1980 ScModule
* pScMod
= SC_MOD();
1981 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1984 SfxBindings
& rBindings
= pViewData
->GetBindings();
1985 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
1987 EditView
* pEditView
;
1990 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1991 pEditView
->MouseButtonUp( rMEvt
);
1993 if ( rMEvt
.IsMiddle() &&
1994 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
1996 // EditView may have pasted from selection
1997 pScMod
->InputChanged( pEditView
);
2000 pScMod
->InputSelection( pEditView
); // parentheses etc.
2002 pViewData
->GetView()->InvalidateAttribs();
2003 rBindings
.Invalidate( SID_HYPERLINK_GETLINK
);
2010 DPMouseButtonUp( rMEvt
); // resets bDPMouse
2016 RFMouseMove( rMEvt
, sal_True
); // Range wieder richtigherum
2018 SetPointer( Pointer( POINTER_ARROW
) );
2023 if (nPagebreakMouse
)
2025 PagebreakMove( rMEvt
, sal_True
);
2026 nPagebreakMouse
= SC_PD_NONE
;
2027 SetPointer( Pointer( POINTER_ARROW
) );
2032 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus
2034 ::svl::IUndoManager
* pMgr
= pViewData
->GetDocShell()->GetUndoManager();
2035 if ( pMgr
->GetUndoActionCount() && pMgr
->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE
)
2040 if (DrawMouseButtonUp(rMEvt
)) // includes format paint brush handling for drawing objects
2042 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
2043 SfxBindings
& rFrmBindings
=pViewShell
->GetViewFrame()->GetBindings();
2044 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_WIDTH
);
2045 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_HEIGHT
);
2046 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_X
);
2047 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_Y
);
2048 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ANGLE
);
2049 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ROT_X
);
2050 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ROT_Y
);
2051 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_AUTOWIDTH
);
2052 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_AUTOHEIGHT
);
2056 rMark
.SetMarking(false);
2058 SetPointer( Pointer( POINTER_ARROW
) );
2060 if (pViewData
->IsFillMode() ||
2061 ( pViewData
->GetFillMode() == SC_FILL_MATRIX
&& rMEvt
.IsMod1() ))
2063 nScFillModeMouseModifier
= rMEvt
.GetModifier();
2068 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2070 sal_Bool bIsDel
= pViewData
->GetDelMark( aDelRange
);
2072 ScViewFunc
* pView
= pViewData
->GetView();
2073 pView
->StopRefMode();
2074 pViewData
->ResetFillMode();
2075 pView
->GetFunctionSet()->SetAnchorFlag( false ); // #i5819# don't use AutoFill anchor flag for selection
2079 pView
->MarkRange( aDelRange
, false );
2080 pView
->DeleteContents( IDF_CONTENTS
);
2081 SCTAB nTab
= pViewData
->GetTabNo();
2082 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2083 if ( aBlockRange
!= aDelRange
)
2085 if ( aDelRange
.aStart
.Row() == nStartRow
)
2086 aBlockRange
.aEnd
.SetCol( aDelRange
.aStart
.Col() - 1 );
2088 aBlockRange
.aEnd
.SetRow( aDelRange
.aStart
.Row() - 1 );
2089 pView
->MarkRange( aBlockRange
, false );
2093 pViewData
->GetDispatcher().Execute( FID_FILL_AUTO
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2095 else if (pViewData
->GetFillMode() == SC_FILL_MATRIX
)
2097 SCTAB nTab
= pViewData
->GetTabNo();
2102 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2103 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2104 SCCOL nFillCol
= pViewData
->GetRefEndX();
2105 SCROW nFillRow
= pViewData
->GetRefEndY();
2106 ScAddress
aEndPos( nFillCol
, nFillRow
, nTab
);
2108 ScTabView
* pView
= pViewData
->GetView();
2109 pView
->StopRefMode();
2110 pViewData
->ResetFillMode();
2111 pView
->GetFunctionSet()->SetAnchorFlag( false );
2113 if ( aEndPos
!= aBlockRange
.aEnd
)
2115 pViewData
->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange
, aEndPos
, false );
2116 pViewData
->GetView()->MarkRange( ScRange( aBlockRange
.aStart
, aEndPos
) );
2119 else if (pViewData
->IsAnyFillMode())
2121 // Embedded-Area has been changed
2122 ScTabView
* pView
= pViewData
->GetView();
2123 pView
->StopRefMode();
2124 pViewData
->ResetFillMode();
2125 pView
->GetFunctionSet()->SetAnchorFlag( false );
2126 pViewData
->GetDocShell()->UpdateOle(pViewData
);
2129 sal_Bool bRefMode
= pViewData
->IsRefMode();
2131 pScMod
->EndReference();
2134 // Giesskannen-Modus (Gestalter)
2137 if (pScMod
->GetIsWaterCan())
2139 // Abfrage auf Undo schon oben
2141 ScStyleSheetPool
* pStylePool
= (ScStyleSheetPool
*)
2142 (pViewData
->GetDocument()->
2143 GetStyleSheetPool());
2146 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)
2147 pStylePool
->GetActualStyleSheet();
2151 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
2155 case SFX_STYLE_FAMILY_PARA
:
2156 pViewData
->GetView()->SetStyleSheetToMarked( pStyleSheet
);
2157 pViewData
->GetView()->DoneBlockMode();
2160 case SFX_STYLE_FAMILY_PAGE
:
2161 pViewData
->GetDocument()->SetPageStyle( pViewData
->GetTabNo(),
2162 pStyleSheet
->GetName() );
2164 ScPrintFunc( pViewData
->GetDocShell(),
2165 pViewData
->GetViewShell()->GetPrinter(sal_True
),
2166 pViewData
->GetTabNo() ).UpdatePages();
2168 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
2178 ScDBFunc
* pView
= pViewData
->GetView();
2179 ScDocument
* pBrushDoc
= pView
->GetBrushDocument();
2182 pView
->PasteFromClip( IDF_ATTRIB
, pBrushDoc
);
2183 if ( !pView
->IsPaintBrushLocked() )
2184 pView
->ResetBrushDocument(); // invalidates pBrushDoc pointer
2188 // double click (only left button)
2191 sal_Bool bDouble
= ( rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() );
2192 if ( bDouble
&& !bRefMode
&& nMouseStatus
== SC_GM_DBLDOWN
&& !pScMod
->IsRefDialogOpen() )
2195 Point aPos
= rMEvt
.GetPosPixel();
2198 SCTAB nTab
= pViewData
->GetTabNo();
2199 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2200 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor( nPosX
, nPosY
, nTab
);
2201 if ( pDPObj
&& pDPObj
->GetSaveData()->GetDrillDown() )
2203 ScAddress
aCellPos( nPosX
, nPosY
, pViewData
->GetTabNo() );
2205 // Check for header drill-down first.
2206 sheet::DataPilotTableHeaderData aData
;
2207 pDPObj
->GetHeaderPositionData(aCellPos
, aData
);
2209 if ( ( aData
.Flags
& sheet::MemberResultFlags::HASMEMBER
) &&
2210 ! ( aData
.Flags
& sheet::MemberResultFlags::SUBTOTAL
) )
2213 if ( pView
->HasSelectionForDrillDown( nDummy
) )
2215 // execute slot to show dialog
2216 pViewData
->GetDispatcher().Execute( SID_OUTLINE_SHOW
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2220 // toggle single entry
2221 ScDPObject
aNewObj( *pDPObj
);
2222 pDPObj
->ToggleDetails( aData
, &aNewObj
);
2223 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
2224 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, sal_True
, false );
2225 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
2230 // Check if the data area is double-clicked.
2232 Sequence
<sheet::DataPilotFieldFilter
> aFilters
;
2233 if ( pDPObj
->GetDataFieldPositionData(aCellPos
, aFilters
) )
2234 pViewData
->GetView()->ShowDataPilotSourceData( *pDPObj
, aFilters
);
2240 // Check for cell protection attribute.
2241 ScTableProtection
* pProtect
= pDoc
->GetTabProtection( nTab
);
2242 bool bEditAllowed
= true;
2243 if ( pProtect
&& pProtect
->isProtected() )
2245 bool bCellProtected
= pDoc
->HasAttrib(nPosX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_PROTECTED
);
2246 bool bSkipProtected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2247 bool bSkipUnprotected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2249 if ( bSkipProtected
&& bSkipUnprotected
)
2250 bEditAllowed
= false;
2251 else if ( (bCellProtected
&& bSkipProtected
) || (!bCellProtected
&& bSkipUnprotected
) )
2252 bEditAllowed
= false;
2257 // edit cell contents
2258 pViewData
->GetViewShell()->UpdateInputHandler();
2259 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2260 if (pViewData
->HasEditView(eWhich
))
2262 // Text-Cursor gleich an die geklickte Stelle setzen
2263 EditView
* pEditView
= pViewData
->GetEditView( eWhich
);
2264 MouseEvent
aEditEvt( rMEvt
.GetPosPixel(), 1, MOUSE_SYNTHETIC
, MOUSE_LEFT
, 0 );
2265 pEditView
->MouseButtonDown( aEditEvt
);
2266 pEditView
->MouseButtonUp( aEditEvt
);
2273 // Links in edit cells
2276 sal_Bool bAlt
= rMEvt
.IsMod2();
2277 if ( !bAlt
&& !bRefMode
&& !bDouble
&& nMouseStatus
== SC_GM_URLDOWN
)
2279 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2281 String aName
, aUrl
, aTarget
;
2282 if ( GetEditUrl( rMEvt
.GetPosPixel(), &aName
, &aUrl
, &aTarget
) )
2284 nMouseStatus
= SC_GM_NONE
; // keinen Doppelklick anfangen
2286 // ScGlobal::OpenURL() only understands Calc A1 style syntax.
2287 // Convert it to Calc A1 before calling OpenURL().
2289 if (pDoc
->GetAddressConvention() == formula::FormulaGrammar::CONV_OOO
)
2290 ScGlobal::OpenURL(aUrl
, aTarget
);
2293 ScAddress aTempAddr
;
2294 ScAddress::ExternalInfo aExtInfo
;
2295 sal_uInt16 nRes
= aTempAddr
.Parse(aUrl
, pDoc
, pDoc
->GetAddressConvention(), &aExtInfo
);
2296 if (!(nRes
& SCA_VALID
))
2298 // Not a reference string. Pass it through unmodified.
2299 ScGlobal::OpenURL(aUrl
, aTarget
);
2303 OUStringBuffer aBuf
;
2304 if (aExtInfo
.mbExternal
)
2306 // External reference.
2307 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
2308 const OUString
* pStr
= pRefMgr
->getExternalFileName(aExtInfo
.mnFileId
);
2313 aBuf
.append(aExtInfo
.maTabName
);
2315 OUString aRefCalcA1
;
2316 aTempAddr
.Format(aRefCalcA1
, SCA_ABS
, NULL
, formula::FormulaGrammar::CONV_OOO
);
2317 aBuf
.append(aRefCalcA1
);
2318 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2322 // Internal reference.
2324 OUString aUrlCalcA1
;
2325 aTempAddr
.Format(aUrlCalcA1
, SCA_ABS_3D
, pDoc
, formula::FormulaGrammar::CONV_OOO
);
2326 aBuf
.append(aUrlCalcA1
);
2327 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2331 // fire worksheet_followhyperlink event
2332 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents
= pDoc
->GetVbaEventProcessor();
2333 if( xVbaEvents
.is() ) try
2335 Point aPos
= rMEvt
.GetPosPixel();
2338 SCTAB nTab
= pViewData
->GetTabNo();
2339 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2341 ScRefCellValue aCell
;
2342 if (lcl_GetHyperlinkCell(pDoc
, nPosX
, nPosY
, nTab
, aCell
, sURL
))
2344 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
2345 uno::Reference
< table::XCell
> xCell( new ScCellObj( pViewData
->GetDocShell(), aCellPos
) );
2346 uno::Sequence
< uno::Any
> aArgs(1);
2348 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK
, aArgs
);
2351 catch( uno::Exception
& )
2360 // Gridwin - SelectionEngine
2363 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2364 // sal_True for any call, so IsLeft must be checked here, too.
2366 if ( rMEvt
.IsLeft() && pViewData
->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt
) )
2368 pViewData
->GetView()->SelectionChanged();
2370 SfxDispatcher
* pDisp
= pViewData
->GetViewShell()->GetDispatcher();
2371 sal_Bool bFormulaMode
= pScMod
->IsFormulaMode();
2372 OSL_ENSURE( pDisp
|| bFormulaMode
, "Cursor auf nicht aktiver View bewegen ?" );
2374 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2375 // multiple selection, so the argument string completely describes the selection,
2376 // and executing the slot won't change the existing selection (executing the slot
2377 // here and from a recorded macro is treated equally)
2379 if ( pDisp
&& !bFormulaMode
&& !rMark
.IsMultiMarked() )
2381 String aAddr
; // CurrentCell
2382 if( rMark
.IsMarked() )
2385 rMark
.GetMarkArea( aScRange
);
2386 aScRange
.Format( aAddr
, SCR_ABS
);
2387 if ( aScRange
.aStart
== aScRange
.aEnd
)
2389 // make sure there is a range selection string even for a single cell
2390 String aSingle
= aAddr
;
2391 aAddr
.Append( (sal_Char
) ':' );
2392 aAddr
.Append( aSingle
);
2395 //! SID_MARKAREA gibts nicht mehr ???
2396 //! was passiert beim Markieren mit dem Cursor ???
2398 else // nur Cursor bewegen
2400 ScAddress
aScAddress( pViewData
->GetCurX(), pViewData
->GetCurY(), 0 );
2401 aScAddress
.Format( aAddr
, SCA_ABS
);
2404 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
2405 // We don't want to align to the cursor position because if the
2406 // cell cursor isn't visible after making selection, it would jump
2407 // back to the origin of the selection where the cell cursor is.
2408 SfxBoolItem
aAlignCursorItem( FN_PARAM_2
, false );
2409 pDisp
->Execute( SID_CURRENTCELL
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
2410 &aPosItem
, &aAlignCursorItem
, (void*)0L );
2412 pViewData
->GetView()->InvalidateAttribs();
2418 void ScGridWindow::FakeButtonUp()
2422 MouseEvent
aEvent( aCurMousePos
); // nButtons = 0 -> ignore
2423 MouseButtonUp( aEvent
);
2427 void ScGridWindow::MouseMove( const MouseEvent
& rMEvt
)
2429 aCurMousePos
= rMEvt
.GetPosPixel();
2431 if ( rMEvt
.IsLeaveWindow() && pNoteMarker
&& !pNoteMarker
->IsByKeyboard() )
2434 ScModule
* pScMod
= SC_MOD();
2435 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2438 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2439 // nicht anders mit:
2441 if (bEEMouse
&& nButtonDown
&& !rMEvt
.GetButtons())
2445 nMouseStatus
= SC_GM_NONE
;
2449 if (nMouseStatus
== SC_GM_IGNORE
)
2452 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus -> nur auf Up warten
2455 if ( pViewData
->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2457 SetPointer( Pointer( POINTER_FILL
) );
2461 if (nMouseStatus
== SC_GM_FILTER
&& pFilterBox
)
2463 Point aRelPos
= pFilterBox
->ScreenToOutputPixel( OutputToScreenPixel( rMEvt
.GetPosPixel() ) );
2464 if ( Rectangle(Point(),pFilterBox
->GetOutputSizePixel()).IsInside(aRelPos
) )
2467 nMouseStatus
= SC_GM_NONE
;
2469 pFilterBox
->MouseButtonDown( MouseEvent( aRelPos
, 1, MOUSE_SIMPLECLICK
, MOUSE_LEFT
) );
2474 sal_Bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
2476 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2478 EditView
* pEditView
;
2481 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2482 pEditView
->MouseMove( rMEvt
);
2488 DPMouseMove( rMEvt
);
2494 RFMouseMove( rMEvt
, false );
2498 if (nPagebreakMouse
)
2500 PagebreakMove( rMEvt
, false );
2504 // anderen Mauszeiger anzeigen?
2506 sal_Bool bEditMode
= pViewData
->HasEditView(eWhich
);
2508 //! Testen ob RefMode-Dragging !!!
2509 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
2511 Point aPos
= rMEvt
.GetPosPixel();
2514 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2516 EditView
* pEditView
;
2519 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2520 SCCOL nEndCol
= pViewData
->GetEditEndCol();
2521 SCROW nEndRow
= pViewData
->GetEditEndRow();
2523 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
2524 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
2526 // Field can only be URL field
2527 sal_Bool bAlt
= rMEvt
.IsMod2();
2528 if ( !bAlt
&& !nButtonDown
&& pEditView
&& pEditView
->GetFieldUnderMousePointer() )
2529 SetPointer( Pointer( POINTER_REFHAND
) );
2530 else if ( pEditView
&& pEditView
->GetEditEngine()->IsVertical() )
2531 SetPointer( Pointer( POINTER_TEXT_VERTICAL
) );
2533 SetPointer( Pointer( POINTER_TEXT
) );
2538 sal_Bool bWater
= SC_MOD()->GetIsWaterCan() || pViewData
->GetView()->HasPaintBrush();
2540 SetPointer( Pointer(POINTER_FILL
) );
2544 sal_Bool bCross
= false;
2549 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bCorner
) )
2552 SetPointer( Pointer( POINTER_CROSS
) );
2554 SetPointer( Pointer( POINTER_HAND
) );
2560 sal_uInt16 nBreakType
;
2561 if ( !nButtonDown
&& pViewData
->IsPagebreakMode() &&
2562 ( nBreakType
= HitPageBreak( rMEvt
.GetPosPixel() ) ) != 0 )
2564 PointerStyle eNew
= POINTER_ARROW
;
2565 switch ( nBreakType
)
2570 eNew
= POINTER_ESIZE
;
2575 eNew
= POINTER_SSIZE
;
2577 case SC_PD_RANGE_TL
:
2578 case SC_PD_RANGE_BR
:
2579 eNew
= POINTER_SESIZE
;
2581 case SC_PD_RANGE_TR
:
2582 case SC_PD_RANGE_BL
:
2583 eNew
= POINTER_NESIZE
;
2586 SetPointer( Pointer( eNew
) );
2590 // Fill-Cursor anzeigen ?
2592 if ( !bFormulaMode
&& !nButtonDown
)
2593 if (TestMouse( rMEvt
, false ))
2596 if ( nButtonDown
&& pViewData
->IsAnyFillMode() )
2598 SetPointer( Pointer( POINTER_CROSS
) );
2600 nScFillModeMouseModifier
= rMEvt
.GetModifier(); // ausgewertet bei AutoFill und Matrix
2605 sal_Bool bAlt
= rMEvt
.IsMod2();
2607 if (bEditMode
) // Edit-Mode muss zuerst kommen!
2608 SetPointer( Pointer( POINTER_ARROW
) );
2609 else if ( !bAlt
&& !nButtonDown
&&
2610 GetEditUrl(rMEvt
.GetPosPixel()) )
2611 SetPointer( Pointer( POINTER_REFHAND
) );
2612 else if ( DrawMouseMove(rMEvt
) ) // setzt Pointer um
2617 if ( pViewData
->GetView()->GetSelEngine()->SelMouseMove( rMEvt
) )
2621 static void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent
& rEvent
, const MouseEvent
& rEvt
)
2623 rEvent
.Modifiers
= 0;
2624 if ( rEvt
.IsShift() )
2625 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::SHIFT
;
2626 if ( rEvt
.IsMod1() )
2627 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD1
;
2628 if ( rEvt
.IsMod2() )
2629 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD2
;
2630 if ( rEvt
.IsMod3() )
2631 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD3
;
2634 if ( rEvt
.IsLeft() )
2635 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::LEFT
;
2636 if ( rEvt
.IsRight() )
2637 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::RIGHT
;
2638 if ( rEvt
.IsMiddle() )
2639 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::MIDDLE
;
2641 rEvent
.X
= rEvt
.GetPosPixel().X();
2642 rEvent
.Y
= rEvt
.GetPosPixel().Y();
2643 rEvent
.ClickCount
= rEvt
.GetClicks();
2644 rEvent
.PopupTrigger
= false;
2647 long ScGridWindow::PreNotify( NotifyEvent
& rNEvt
)
2650 sal_uInt16 nType
= rNEvt
.GetType();
2651 if ( nType
== EVENT_MOUSEBUTTONUP
|| nType
== EVENT_MOUSEBUTTONDOWN
)
2653 Window
* pWindow
= rNEvt
.GetWindow();
2654 if (pWindow
== this && pViewData
)
2656 SfxViewFrame
* pViewFrame
= pViewData
->GetViewShell()->GetViewFrame();
2659 com::sun::star::uno::Reference
<com::sun::star::frame::XController
> xController
= pViewFrame
->GetFrame().GetController();
2660 if (xController
.is())
2662 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
2663 if (pImp
&& pImp
->IsMouseListening())
2665 ::com::sun::star::awt::MouseEvent aEvent
;
2666 lcl_InitMouseEvent( aEvent
, *rNEvt
.GetMouseEvent() );
2667 if ( rNEvt
.GetWindow() )
2668 aEvent
.Source
= rNEvt
.GetWindow()->GetComponentInterface();
2669 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2670 bDone
= pImp
->MousePressed( aEvent
);
2672 bDone
= pImp
->MouseReleased( aEvent
);
2678 if (bDone
) // event consumed by a listener
2680 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2682 const MouseEvent
* pMouseEvent
= rNEvt
.GetMouseEvent();
2683 if ( pMouseEvent
->IsRight() && pMouseEvent
->GetClicks() == 1 )
2685 // If a listener returned true for a right-click call, also prevent opening the context menu
2686 // (this works only if the context menu is opened on mouse-down)
2687 nMouseStatus
= SC_GM_IGNORE
;
2694 return Window::PreNotify( rNEvt
);
2697 void ScGridWindow::Tracking( const TrackingEvent
& rTEvt
)
2699 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2700 // die verschiedenen MouseHandler verteilen...
2702 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
2704 if ( rTEvt
.IsTrackingCanceled() ) // alles abbrechen...
2706 if (!pViewData
->GetView()->IsInActivatePart() && !SC_MOD()->IsRefDialogOpen())
2709 bDPMouse
= false; // gezeichnet wird per bDragRect
2712 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2714 UpdateDragRectOverlay();
2718 RFMouseMove( rMEvt
, true ); // richtig abbrechen geht dabei nicht...
2721 if (nPagebreakMouse
)
2723 // if (bPagebreakDrawn)
2724 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2725 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
2726 bPagebreakDrawn
= false;
2727 UpdateDragRectOverlay();
2728 nPagebreakMouse
= SC_PD_NONE
;
2731 SetPointer( Pointer( POINTER_ARROW
) );
2733 MouseButtonUp( rMEvt
); // mit Status SC_GM_IGNORE aus StopMarking
2735 sal_Bool bRefMode
= pViewData
->IsRefMode();
2737 SC_MOD()->EndReference(); // Dialog nicht verkleinert lassen
2740 else if ( rTEvt
.IsTrackingEnded() )
2742 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2743 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2744 // abgebrochen wurde.
2746 MouseEvent
aUpEvt( rMEvt
.GetPosPixel(), rMEvt
.GetClicks(),
2747 rMEvt
.GetMode(), nButtonDown
, rMEvt
.GetModifier() );
2748 MouseButtonUp( aUpEvt
);
2754 void ScGridWindow::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
2756 if ( pFilterBox
|| nPagebreakMouse
)
2761 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, sal_True
);
2763 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2765 EditView
* pEditView
;
2768 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2770 // don't remove the edit view while switching views
2771 ScModule
* pScMod
= SC_MOD();
2772 pScMod
->SetInEditCommand( sal_True
);
2774 pEditView
->Command( aDragEvent
);
2776 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2778 pHdl
->DataChanged();
2780 pScMod
->SetInEditCommand( false );
2781 if (!pViewData
->IsActive()) // dropped to different view?
2783 ScInputHandler
* pViewHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2784 if ( pViewHdl
&& pViewData
->HasEditView( eWhich
) )
2786 pViewHdl
->CancelHandler();
2787 ShowCursor(); // missing from KillEditView
2792 if ( !DrawCommand(aDragEvent
) )
2793 pViewData
->GetView()->GetSelEngine()->Command( aDragEvent
);
2796 static void lcl_SetTextCursorPos( ScViewData
* pViewData
, ScSplitPos eWhich
, Window
* pWin
)
2798 SCCOL nCol
= pViewData
->GetCurX();
2799 SCROW nRow
= pViewData
->GetCurY();
2800 Rectangle aEditArea
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, pWin
, NULL
, sal_True
);
2801 aEditArea
.Right() = aEditArea
.Left();
2802 aEditArea
= pWin
->PixelToLogic( aEditArea
);
2803 pWin
->SetCursorRect( &aEditArea
);
2806 void ScGridWindow::Command( const CommandEvent
& rCEvt
)
2808 // The command event is send to the window after a possible context
2809 // menu from an inplace client is closed. Now we have the chance to
2810 // deactivate the inplace client without any problem regarding parent
2811 // windows and code on the stack.
2812 sal_uInt16 nCmd
= rCEvt
.GetCommand();
2813 ScTabViewShell
* pTabViewSh
= pViewData
->GetViewShell();
2814 SfxInPlaceClient
* pClient
= pTabViewSh
->GetIPClient();
2816 pClient
->IsObjectInPlaceActive() &&
2817 nCmd
== COMMAND_CONTEXTMENU
)
2819 pTabViewSh
->DeactivateOle();
2823 ScModule
* pScMod
= SC_MOD();
2824 OSL_ENSURE( nCmd
!= COMMAND_STARTDRAG
, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2826 if ( nCmd
== COMMAND_STARTEXTTEXTINPUT
||
2827 nCmd
== COMMAND_ENDEXTTEXTINPUT
||
2828 nCmd
== COMMAND_EXTTEXTINPUT
||
2829 nCmd
== COMMAND_CURSORPOS
||
2830 nCmd
== COMMAND_QUERYCHARPOSITION
)
2832 sal_Bool bEditView
= pViewData
->HasEditView( eWhich
);
2835 // only if no cell editview is active, look at drawview
2836 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2839 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2840 if ( pOlView
&& pOlView
->GetWindow() == this )
2842 pOlView
->Command( rCEvt
);
2848 if ( nCmd
== COMMAND_CURSORPOS
&& !bEditView
)
2850 // CURSORPOS may be called without following text input,
2851 // to set the input method window position
2852 // -> input mode must not be started,
2853 // manually calculate text insert position if not in input mode
2855 lcl_SetTextCursorPos( pViewData
, eWhich
, this );
2859 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2862 pHdl
->InputCommand( rCEvt
, sal_True
);
2866 Window::Command( rCEvt
);
2870 if ( nCmd
== COMMAND_PASTESELECTION
)
2874 // EditEngine handles selection in MouseButtonUp - no action
2875 // needed in command handler
2879 PasteSelection( rCEvt
.GetMousePosPixel() );
2884 if ( nCmd
== COMMAND_INPUTLANGUAGECHANGE
)
2886 // #i55929# Font and font size state depends on input language if nothing is selected,
2887 // so the slots have to be invalidated when the input language is changed.
2889 SfxBindings
& rBindings
= pViewData
->GetBindings();
2890 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
2891 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
2895 if ( nCmd
== COMMAND_WHEEL
|| nCmd
== COMMAND_STARTAUTOSCROLL
|| nCmd
== COMMAND_AUTOSCROLL
)
2897 sal_Bool bDone
= pViewData
->GetView()->ScrollCommand( rCEvt
, eWhich
);
2899 Window::Command(rCEvt
);
2902 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2903 sal_Bool bDisable
= pScMod
->IsFormulaMode() ||
2904 pScMod
->IsModalMode(pViewData
->GetSfxDocShell());
2908 if ( nCmd
== COMMAND_CONTEXTMENU
&& !SC_MOD()->GetIsWaterCan() )
2910 sal_Bool bMouse
= rCEvt
.IsMouseEvent();
2911 if ( bMouse
&& nMouseStatus
== SC_GM_IGNORE
)
2914 if (pViewData
->IsAnyFillMode())
2916 pViewData
->GetView()->StopRefMode();
2917 pViewData
->ResetFillMode();
2922 Point aPosPixel
= rCEvt
.GetMousePosPixel();
2923 Point aMenuPos
= aPosPixel
;
2929 pViewData
->GetPosFromPixel(aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nCellX
, nCellY
);
2930 ScDocument
* pDoc
= pViewData
->GetDocument();
2931 SCTAB nTab
= pViewData
->GetTabNo();
2932 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
2933 bool bSelectAllowed
= true;
2934 if ( pProtect
&& pProtect
->isProtected() )
2936 // This sheet is protected. Check if a context menu is allowed on this cell.
2937 bool bCellProtected
= pDoc
->HasAttrib(nCellX
, nCellY
, nTab
, nCellX
, nCellY
, nTab
, HASATTR_PROTECTED
);
2938 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2939 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2942 bSelectAllowed
= bSelProtected
;
2944 bSelectAllowed
= bSelUnprotected
;
2946 if (!bSelectAllowed
)
2947 // Selecting this cell is not allowed, neither is context menu.
2950 // #i18735# First select the item under the mouse pointer.
2951 // This can change the selection, and the view state (edit mode, etc).
2952 SelectForContextMenu( aPosPixel
, nCellX
, nCellY
);
2955 sal_Bool bDone
= false;
2956 sal_Bool bEdit
= pViewData
->HasEditView(eWhich
);
2959 // Edit-Zelle mit Spelling-Errors ?
2960 if ( bMouse
&& GetEditUrlOrError( sal_True
, aPosPixel
) )
2962 // GetEditUrlOrError hat den Cursor schon bewegt
2964 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2965 bEdit
= pViewData
->HasEditView(eWhich
); // hat's geklappt ?
2967 OSL_ENSURE( bEdit
, "kann nicht in Edit-Modus schalten" );
2972 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2976 Cursor
* pCur
= pEditView
->GetCursor();
2979 Point aLogicPos
= pCur
->GetPos();
2980 // use the position right of the cursor (spell popup is opened if
2981 // the cursor is before the word, but not if behind it)
2982 aLogicPos
.X() += pCur
->GetWidth();
2983 aLogicPos
.Y() += pCur
->GetHeight() / 2; // center vertically
2984 aMenuPos
= LogicToPixel( aLogicPos
);
2988 // if edit mode was just started above, online spelling may be incomplete
2989 pEditView
->GetEditEngine()->CompleteOnlineSpelling();
2991 // IsCursorAtWrongSpelledWord could be used for !bMouse
2992 // if there was a corresponding ExecuteSpellPopup call
2994 if( pEditView
->IsWrongSpelledWordAtPos( aMenuPos
) )
2996 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
2997 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
2999 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
3001 pHdl
->SetModified();
3003 Link aLink
= LINK( this, ScGridWindow
, PopupSpellingHdl
);
3004 pEditView
->ExecuteSpellPopup( aMenuPos
, &aLink
);
3011 // non-edit menu by keyboard -> use lower right of cell cursor position
3012 ScDocument
* aDoc
= pViewData
->GetDocument();
3013 SCTAB nTabNo
= pViewData
->GetTabNo();
3014 sal_Bool bLayoutIsRTL
= aDoc
->IsLayoutRTL(nTabNo
);
3016 SCCOL nCurX
= pViewData
->GetCurX();
3017 SCROW nCurY
= pViewData
->GetCurY();
3018 aMenuPos
= pViewData
->GetScrPos( nCurX
, nCurY
, eWhich
, sal_True
);
3021 pViewData
->GetMergeSizePixel( nCurX
, nCurY
, nSizeXPix
, nSizeYPix
);
3022 // fdo#55432 take the correct position for RTL sheet
3023 aMenuPos
.X() += bLayoutIsRTL
? -nSizeXPix
: nSizeXPix
;
3024 aMenuPos
.Y() += nSizeYPix
;
3028 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3031 // Is a draw object selected?
3033 SdrView
* pDrawView
= pViewSh
->GetSdrView();
3034 if (pDrawView
&& pDrawView
->AreObjectsMarked())
3036 // #100442#; the conext menu should open in the middle of the selected objects
3037 Rectangle
aSelectRect(LogicToPixel(pDrawView
->GetAllMarkedBoundRect()));
3038 aMenuPos
= aSelectRect
.Center();
3046 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos
);
3051 void ScGridWindow::SelectForContextMenu( const Point
& rPosPixel
, SCsCOL nCellX
, SCsROW nCellY
)
3053 // #i18735# if the click was outside of the current selection,
3054 // the cursor is moved or an object at the click position selected.
3055 // (see SwEditWin::SelectMenuPosition in Writer)
3057 ScTabView
* pView
= pViewData
->GetView();
3058 ScDrawView
* pDrawView
= pView
->GetScDrawView();
3060 // check cell edit mode
3062 if ( pViewData
->HasEditView(eWhich
) )
3064 ScModule
* pScMod
= SC_MOD();
3065 SCCOL nEditStartCol
= pViewData
->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
3066 SCROW nEditStartRow
= pViewData
->GetEditViewRow();
3067 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
3068 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
3070 if ( nCellX
>= (SCsCOL
) nEditStartCol
&& nCellX
<= (SCsCOL
) nEditEndCol
&&
3071 nCellY
>= (SCsROW
) nEditStartRow
&& nCellY
<= (SCsROW
) nEditEndRow
)
3073 // handle selection within the EditView
3075 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // not NULL (HasEditView)
3076 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
3077 Rectangle aOutputArea
= pEditView
->GetOutputArea();
3078 Rectangle aVisArea
= pEditView
->GetVisArea();
3080 Point aTextPos
= PixelToLogic( rPosPixel
);
3081 if ( pEditEngine
->IsVertical() ) // have to manually transform position
3083 aTextPos
-= aOutputArea
.TopRight();
3084 long nTemp
= -aTextPos
.X();
3085 aTextPos
.X() = aTextPos
.Y();
3086 aTextPos
.Y() = nTemp
;
3089 aTextPos
-= aOutputArea
.TopLeft();
3090 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3092 EPosition aDocPosition
= pEditEngine
->FindDocPosition(aTextPos
);
3093 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3094 ESelection aSelection
= pEditView
->GetSelection();
3095 aSelection
.Adjust(); // needed for IsLess/IsGreater
3096 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3098 // clicked outside the selected text - deselect and move text cursor
3099 MouseEvent
aEvent( rPosPixel
);
3100 pEditView
->MouseButtonDown( aEvent
);
3101 pEditView
->MouseButtonUp( aEvent
);
3102 pScMod
->InputSelection( pEditView
);
3105 return; // clicked within the edit view - keep edit mode
3109 // outside of the edit view - end edit mode, regardless of cell selection, then continue
3110 pScMod
->InputEnterHandler();
3114 // check draw text edit mode
3116 Point aLogicPos
= PixelToLogic( rPosPixel
); // after cell edit mode is ended
3117 if ( pDrawView
&& pDrawView
->GetTextEditObject() && pDrawView
->GetTextEditOutlinerView() )
3119 OutlinerView
* pOlView
= pDrawView
->GetTextEditOutlinerView();
3120 Rectangle aOutputArea
= pOlView
->GetOutputArea();
3121 if ( aOutputArea
.IsInside( aLogicPos
) )
3123 // handle selection within the OutlinerView
3125 Outliner
* pOutliner
= pOlView
->GetOutliner();
3126 const EditEngine
& rEditEngine
= pOutliner
->GetEditEngine();
3127 Rectangle aVisArea
= pOlView
->GetVisArea();
3129 Point aTextPos
= aLogicPos
;
3130 if ( pOutliner
->IsVertical() ) // have to manually transform position
3132 aTextPos
-= aOutputArea
.TopRight();
3133 long nTemp
= -aTextPos
.X();
3134 aTextPos
.X() = aTextPos
.Y();
3135 aTextPos
.Y() = nTemp
;
3138 aTextPos
-= aOutputArea
.TopLeft();
3139 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3141 EPosition aDocPosition
= rEditEngine
.FindDocPosition(aTextPos
);
3142 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3143 ESelection aSelection
= pOlView
->GetSelection();
3144 aSelection
.Adjust(); // needed for IsLess/IsGreater
3145 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3147 // clicked outside the selected text - deselect and move text cursor
3148 // use DrawView to allow extra handling there (none currently)
3149 MouseEvent
aEvent( rPosPixel
);
3150 pDrawView
->MouseButtonDown( aEvent
, this );
3151 pDrawView
->MouseButtonUp( aEvent
, this );
3154 return; // clicked within the edit area - keep edit mode
3158 // Outside of the edit area - end text edit mode, then continue.
3159 // DrawDeselectAll also ends text edit mode and updates the shells.
3160 // If the click was on the edited object, it will be selected again below.
3161 pView
->DrawDeselectAll();
3165 // look for existing selection
3167 sal_Bool bHitSelected
= false;
3168 if ( pDrawView
&& pDrawView
->IsMarkedObjHit( aLogicPos
) )
3170 // clicked on selected object -> don't change anything
3171 bHitSelected
= sal_True
;
3173 else if ( pViewData
->GetMarkData().IsCellMarked(nCellX
, nCellY
) )
3175 // clicked on selected cell -> don't change anything
3176 bHitSelected
= sal_True
;
3179 // select drawing object or move cell cursor
3181 if ( !bHitSelected
)
3183 sal_Bool bWasDraw
= ( pDrawView
&& pDrawView
->AreObjectsMarked() );
3184 sal_Bool bHitDraw
= false;
3187 pDrawView
->UnmarkAllObj();
3188 // Unlock the Internal Layer in order to activate the context menu.
3189 // re-lock in ScDrawView::MarkListHasChanged()
3190 lcl_UnLockComment( pDrawView
, pDrawView
->GetSdrPageView(), pDrawView
->GetModel(), aLogicPos
,pViewData
);
3191 bHitDraw
= pDrawView
->MarkObj( aLogicPos
);
3192 // draw shell is activated in MarkListHasChanged
3197 pView
->SetCursor(nCellX
, nCellY
);
3199 pViewData
->GetViewShell()->SetDrawShell( false ); // switch shells
3204 void ScGridWindow::KeyInput(const KeyEvent
& rKEvt
)
3206 // Cursor control for ref input dialog
3207 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
3208 if( SC_MOD()->IsRefDialogOpen() )
3210 if( !rKeyCode
.GetModifier() && (rKeyCode
.GetCode() == KEY_F2
) )
3212 SC_MOD()->EndReference();
3215 else if( pViewData
->GetViewShell()->MoveCursorKeyInput( rKEvt
) )
3218 pViewData
->GetRefStartX(), pViewData
->GetRefStartY(), pViewData
->GetRefStartZ(),
3219 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(), pViewData
->GetRefEndZ() );
3220 SC_MOD()->SetReference( aRef
, pViewData
->GetDocument() );
3224 else if( rKeyCode
.GetCode() == KEY_RETURN
&& pViewData
->IsPasteMode() )
3226 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
3227 ScClipUtil::PasteFromClipboard( pViewData
, pTabViewShell
, false );
3229 // Clear clipboard content.
3230 uno::Reference
<datatransfer::clipboard::XClipboard
> xSystemClipboard
=
3231 TransferableHelper::GetSystemClipboard();
3232 if (xSystemClipboard
.is())
3234 xSystemClipboard
->setContents(
3235 uno::Reference
<datatransfer::XTransferable
>(),
3236 uno::Reference
<datatransfer::clipboard::XClipboardOwner
>());
3239 // hide the border around the copy source
3240 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3241 UpdateCopySourceOverlay();
3244 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3245 else if( !pViewData
->IsAnyFillMode() )
3247 if (rKeyCode
.GetCode() == KEY_ESCAPE
)
3249 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3250 UpdateCopySourceOverlay();
3252 // query for existing note marker before calling ViewShell's keyboard handling
3253 // which may remove the marker
3254 sal_Bool bHadKeyMarker
= ( pNoteMarker
&& pNoteMarker
->IsByKeyboard() );
3255 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3257 if (pViewData
->GetDocShell()->GetProgress())
3260 if (DrawKeyInput(rKEvt
))
3262 const KeyCode
& rLclKeyCode
= rKEvt
.GetKeyCode();
3263 if (rLclKeyCode
.GetCode() == KEY_DOWN
3264 || rLclKeyCode
.GetCode() == KEY_UP
3265 || rLclKeyCode
.GetCode() == KEY_LEFT
3266 || rLclKeyCode
.GetCode() == KEY_RIGHT
)
3268 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
3269 SfxBindings
& rBindings
= pViewShell
->GetViewFrame()->GetBindings();
3270 rBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_X
);
3271 rBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_Y
);
3276 if (!pViewData
->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3277 { //! DrawShell abfragen !!!
3278 if (pViewSh
->TabKeyInput(rKEvt
))
3282 if (pViewSh
->SfxViewShell::KeyInput(rKEvt
)) // von SfxViewShell
3285 KeyCode aCode
= rKEvt
.GetKeyCode();
3286 if ( aCode
.GetCode() == KEY_ESCAPE
&& aCode
.GetModifier() == 0 )
3288 if ( bHadKeyMarker
)
3294 if ( aCode
.GetCode() == KEY_F1
&& aCode
.GetModifier() == KEY_MOD1
)
3296 // ctrl-F1 shows or hides the note or redlining info for the cursor position
3297 // (hard-coded because F1 can't be configured)
3299 if ( bHadKeyMarker
)
3300 HideNoteMarker(); // hide when previously visible
3302 ShowNoteMarker( pViewData
->GetCurX(), pViewData
->GetCurY(), sal_True
);
3305 if (aCode
.GetCode() == KEY_BRACKETLEFT
&& aCode
.GetModifier() == KEY_MOD1
)
3307 pViewSh
->DetectiveMarkPred();
3310 if (aCode
.GetCode() == KEY_BRACKETRIGHT
&& aCode
.GetModifier() == KEY_MOD1
)
3312 pViewSh
->DetectiveMarkSucc();
3318 Window::KeyInput(rKEvt
);
3321 void ScGridWindow::StopMarking()
3323 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3327 pViewData
->GetMarkData().SetMarking(false);
3328 nMouseStatus
= SC_GM_IGNORE
;
3332 void ScGridWindow::UpdateInputContext()
3334 sal_Bool bReadOnly
= pViewData
->GetDocShell()->IsReadOnly();
3335 sal_uLong nOptions
= bReadOnly
? 0 : ( INPUTCONTEXT_TEXT
| INPUTCONTEXT_EXTTEXTINPUT
);
3337 // when font from InputContext is used,
3338 // it must be taken from the cursor position's cell attributes
3340 InputContext aContext
;
3341 aContext
.SetOptions( nOptions
);
3342 SetInputContext( aContext
);
3345 //--------------------------------------------------------
3347 // sensitiver Bereich (Pixel)
3348 #define SCROLL_SENSITIVE 20
3350 bool ScGridWindow::DropScroll( const Point
& rMousePos
)
3354 Size aSize
= GetOutputSizePixel();
3356 if (aSize
.Width() > SCROLL_SENSITIVE
* 3)
3358 if ( rMousePos
.X() < SCROLL_SENSITIVE
&& pViewData
->GetPosX(WhichH(eWhich
)) > 0 )
3360 if ( rMousePos
.X() >= aSize
.Width() - SCROLL_SENSITIVE
3361 && pViewData
->GetPosX(WhichH(eWhich
)) < MAXCOL
)
3364 if (aSize
.Height() > SCROLL_SENSITIVE
* 3)
3366 if ( rMousePos
.Y() < SCROLL_SENSITIVE
&& pViewData
->GetPosY(WhichV(eWhich
)) > 0 )
3368 if ( rMousePos
.Y() >= aSize
.Height() - SCROLL_SENSITIVE
3369 && pViewData
->GetPosY(WhichV(eWhich
)) < MAXROW
)
3373 if ( nDx
!= 0 || nDy
!= 0 )
3376 pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
3378 pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
3384 static sal_Bool
lcl_TestScenarioRedliningDrop( ScDocument
* pDoc
, const ScRange
& aDragRange
)
3386 // Testet, ob bei eingeschalteten RedLining,
3387 // bei einem Drop ein Scenario betroffen ist.
3389 sal_Bool bReturn
= false;
3390 SCTAB nTab
= aDragRange
.aStart
.Tab();
3391 SCTAB nTabCount
= pDoc
->GetTableCount();
3393 if(pDoc
->GetChangeTrack()!=NULL
)
3395 if( pDoc
->IsScenario(nTab
) && pDoc
->HasScenarioRange(nTab
, aDragRange
))
3401 for(SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
3403 if(pDoc
->HasScenarioRange(i
, aDragRange
))
3414 static ScRange
lcl_MakeDropRange( SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
, const ScRange
& rSource
)
3416 SCCOL nCol1
= nPosX
;
3417 SCCOL nCol2
= nCol1
+ ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
3418 if ( nCol2
> MAXCOL
)
3420 nCol1
-= nCol2
- MAXCOL
;
3423 SCROW nRow1
= nPosY
;
3424 SCROW nRow2
= nRow1
+ ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
3425 if ( nRow2
> MAXROW
)
3427 nRow1
-= nRow2
- MAXROW
;
3431 return ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
3434 //--------------------------------------------------------
3436 extern sal_Bool bPasteIsDrop
; // viewfun4 -> move to header
3437 extern sal_Bool bPasteIsMove
; // viewfun7 -> move to header
3439 //--------------------------------------------------------
3441 sal_Int8
ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent
& rEvt
)
3443 if ( rEvt
.mbLeaving
)
3446 UpdateDragRectOverlay();
3447 return rEvt
.mnAction
;
3450 const ScDragData
& rData
= SC_MOD()->GetDragData();
3451 if ( rData
.pCellTransfer
)
3453 // Don't move source that would include filtered rows.
3454 if ((rEvt
.mnAction
& DND_ACTION_MOVE
) && rData
.pCellTransfer
->HasFilteredRows())
3459 UpdateDragRectOverlay();
3461 return DND_ACTION_NONE
;
3464 Point aPos
= rEvt
.maPosPixel
;
3466 ScDocument
* pSourceDoc
= rData
.pCellTransfer
->GetSourceDocument();
3467 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3468 if (pSourceDoc
== pThisDoc
)
3471 if ( pThisDoc
->HasChartAtPoint(pViewData
->GetTabNo(), PixelToLogic(aPos
), aName
))
3473 if (bDragRect
) // Rechteck loeschen
3476 UpdateDragRectOverlay();
3479 //! highlight chart? (selection border?)
3481 sal_Int8 nRet
= rEvt
.mnAction
;
3486 if ( rData
.pCellTransfer
->GetDragSourceFlags() & SC_DROP_TABLE
) // whole sheet?
3488 sal_Bool bOk
= pThisDoc
->IsDocEditable();
3489 return bOk
? rEvt
.mnAction
: 0; // don't draw selection frame
3494 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3496 ScRange aSourceRange
= rData
.pCellTransfer
->GetRange();
3497 SCCOL nSourceStartX
= aSourceRange
.aStart
.Col();
3498 SCROW nSourceStartY
= aSourceRange
.aStart
.Row();
3499 SCCOL nSourceEndX
= aSourceRange
.aEnd
.Col();
3500 SCROW nSourceEndY
= aSourceRange
.aEnd
.Row();
3501 SCCOL nSizeX
= nSourceEndX
- nSourceStartX
+ 1;
3502 SCROW nSizeY
= nSourceEndY
- nSourceStartY
+ 1;
3504 if ( rEvt
.mnAction
!= DND_ACTION_MOVE
)
3505 nSizeY
= rData
.pCellTransfer
->GetNonFilteredRows(); // copy/link: no filtered rows
3507 SCsCOL nNewDragX
= nPosX
- rData
.pCellTransfer
->GetDragHandleX();
3508 if (nNewDragX
<0) nNewDragX
=0;
3509 if (nNewDragX
+(nSizeX
-1) > MAXCOL
)
3510 nNewDragX
= MAXCOL
-(nSizeX
-1);
3511 SCsROW nNewDragY
= nPosY
- rData
.pCellTransfer
->GetDragHandleY();
3512 if (nNewDragY
<0) nNewDragY
=0;
3513 if (nNewDragY
+(nSizeY
-1) > MAXROW
)
3514 nNewDragY
= MAXROW
-(nSizeY
-1);
3516 // don't break scenario ranges, don't drop on filtered
3517 SCTAB nTab
= pViewData
->GetTabNo();
3518 ScRange aDropRange
= lcl_MakeDropRange( nNewDragX
, nNewDragY
, nTab
, aSourceRange
);
3519 if ( lcl_TestScenarioRedliningDrop( pThisDoc
, aDropRange
) ||
3520 lcl_TestScenarioRedliningDrop( pSourceDoc
, aSourceRange
) ||
3521 ScViewUtil::HasFiltered( aDropRange
, pThisDoc
) )
3526 UpdateDragRectOverlay();
3528 return DND_ACTION_NONE
;
3531 InsCellCmd eDragInsertMode
= INS_NONE
;
3532 Window::PointerState aState
= GetPointerState();
3534 // check for datapilot item sorting
3535 ScDPObject
* pDPObj
= NULL
;
3536 if ( pThisDoc
== pSourceDoc
&& ( pDPObj
= pThisDoc
->GetDPAtCursor( nNewDragX
, nNewDragY
, nTab
) ) != NULL
)
3538 // drop on DataPilot table: sort or nothing
3540 bool bDPSort
= false;
3541 if ( pThisDoc
->GetDPAtCursor( nSourceStartX
, nSourceStartY
, aSourceRange
.aStart
.Tab() ) == pDPObj
)
3543 sheet::DataPilotTableHeaderData aDestData
;
3544 pDPObj
->GetHeaderPositionData( ScAddress(nNewDragX
, nNewDragY
, nTab
), aDestData
);
3545 bool bValid
= ( aDestData
.Dimension
>= 0 ); // dropping onto a field
3547 // look through the source range
3548 for (SCROW nRow
= aSourceRange
.aStart
.Row(); bValid
&& nRow
<= aSourceRange
.aEnd
.Row(); ++nRow
)
3549 for (SCCOL nCol
= aSourceRange
.aStart
.Col(); bValid
&& nCol
<= aSourceRange
.aEnd
.Col(); ++nCol
)
3551 sheet::DataPilotTableHeaderData aSourceData
;
3552 pDPObj
->GetHeaderPositionData( ScAddress( nCol
, nRow
, aSourceRange
.aStart
.Tab() ), aSourceData
);
3553 if ( aSourceData
.Dimension
!= aDestData
.Dimension
|| aSourceData
.MemberName
.isEmpty() )
3554 bValid
= false; // empty (subtotal) or different field
3560 OUString aDimName
= pDPObj
->GetDimName( aDestData
.Dimension
, bIsDataLayout
);
3561 const ScDPSaveDimension
* pDim
= pDPObj
->GetSaveData()->GetExistingDimensionByName( aDimName
);
3564 ScRange aOutRange
= pDPObj
->GetOutRange();
3566 sal_uInt16 nOrient
= pDim
->GetOrientation();
3567 if ( nOrient
== sheet::DataPilotFieldOrientation_COLUMN
)
3569 eDragInsertMode
= INS_CELLSRIGHT
;
3570 nSizeY
= aOutRange
.aEnd
.Row() - nNewDragY
+ 1;
3573 else if ( nOrient
== sheet::DataPilotFieldOrientation_ROW
)
3575 eDragInsertMode
= INS_CELLSDOWN
;
3576 nSizeX
= aOutRange
.aEnd
.Col() - nNewDragX
+ 1;
3585 // no valid sorting in a DataPilot table -> disallow
3589 UpdateDragRectOverlay();
3591 return DND_ACTION_NONE
;
3594 else if ( aState
.mnState
& KEY_MOD2
)
3596 if ( pThisDoc
== pSourceDoc
&& nTab
== aSourceRange
.aStart
.Tab() )
3598 long nDeltaX
= labs( static_cast< long >( nNewDragX
- nSourceStartX
) );
3599 long nDeltaY
= labs( static_cast< long >( nNewDragY
- nSourceStartY
) );
3600 if ( nDeltaX
<= nDeltaY
)
3602 eDragInsertMode
= INS_CELLSDOWN
;
3606 eDragInsertMode
= INS_CELLSRIGHT
;
3609 if ( ( eDragInsertMode
== INS_CELLSDOWN
&& nNewDragY
<= nSourceEndY
&&
3610 ( nNewDragX
+ nSizeX
- 1 ) >= nSourceStartX
&& nNewDragX
<= nSourceEndX
&&
3611 ( nNewDragX
!= nSourceStartX
|| nNewDragY
>= nSourceStartY
) ) ||
3612 ( eDragInsertMode
== INS_CELLSRIGHT
&& nNewDragX
<= nSourceEndX
&&
3613 ( nNewDragY
+ nSizeY
- 1 ) >= nSourceStartY
&& nNewDragY
<= nSourceEndY
&&
3614 ( nNewDragY
!= nSourceStartY
|| nNewDragX
>= nSourceStartX
) ) )
3619 UpdateDragRectOverlay();
3621 return DND_ACTION_NONE
;
3626 if ( static_cast< long >( nSizeX
) >= static_cast< long >( nSizeY
) )
3628 eDragInsertMode
= INS_CELLSDOWN
;
3633 eDragInsertMode
= INS_CELLSRIGHT
;
3638 if ( nNewDragX
!= (SCsCOL
) nDragStartX
|| nNewDragY
!= (SCsROW
) nDragStartY
||
3639 nDragStartX
+nSizeX
-1 != nDragEndX
|| nDragStartY
+nSizeY
-1 != nDragEndY
||
3640 !bDragRect
|| eDragInsertMode
!= meDragInsertMode
)
3642 nDragStartX
= nNewDragX
;
3643 nDragStartY
= nNewDragY
;
3644 nDragEndX
= nDragStartX
+nSizeX
-1;
3645 nDragEndY
= nDragStartY
+nSizeY
-1;
3647 meDragInsertMode
= eDragInsertMode
;
3649 UpdateDragRectOverlay();
3653 return rEvt
.mnAction
;
3656 sal_Int8
ScGridWindow::AcceptDrop( const AcceptDropEvent
& rEvt
)
3658 const ScDragData
& rData
= SC_MOD()->GetDragData();
3659 if ( rEvt
.mbLeaving
)
3661 DrawMarkDropObj( NULL
);
3662 if ( rData
.pCellTransfer
)
3663 return AcceptPrivateDrop( rEvt
); // hide drop marker for internal D&D
3665 return rEvt
.mnAction
;
3668 if ( pViewData
->GetDocShell()->IsReadOnly() )
3669 return DND_ACTION_NONE
;
3672 sal_Int8 nRet
= DND_ACTION_NONE
;
3674 if (rData
.pCellTransfer
)
3676 ScRange aSource
= rData
.pCellTransfer
->GetRange();
3677 if ( aSource
.aStart
.Col() != 0 || aSource
.aEnd
.Col() != MAXCOL
||
3678 aSource
.aStart
.Row() != 0 || aSource
.aEnd
.Row() != MAXROW
)
3679 DropScroll( rEvt
.maPosPixel
);
3681 nRet
= AcceptPrivateDrop( rEvt
);
3685 if ( !rData
.aLinkDoc
.isEmpty() )
3688 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3689 if (pDocSh
&& pDocSh
->HasName())
3690 aThisName
= pDocSh
->GetMedium()->GetName();
3692 if ( !rData
.aLinkDoc
.equals(aThisName
) )
3693 nRet
= rEvt
.mnAction
;
3695 else if (!rData
.aJumpTarget
.isEmpty())
3697 // internal bookmarks (from Navigator)
3698 // local jumps from an unnamed document are possible only within a document
3700 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
3701 nRet
= rEvt
.mnAction
;
3705 sal_Int8 nMyAction
= rEvt
.mnAction
;
3707 if ( !rData
.pDrawTransfer
||
3708 !IsMyModel(rData
.pDrawTransfer
->GetDragSourceView()) ) // drawing within the document
3709 if ( rEvt
.mbDefault
&& nMyAction
== DND_ACTION_MOVE
)
3710 nMyAction
= DND_ACTION_COPY
;
3712 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3713 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint(
3714 pViewData
->GetTabNo(), PixelToLogic(rEvt
.maPosPixel
) );
3715 if ( pHitObj
&& nMyAction
== DND_ACTION_LINK
&& !rData
.pDrawTransfer
)
3717 if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB
)
3718 || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE
)
3719 || IsDropFormatSupported(SOT_FORMAT_BITMAP
) )
3721 // graphic dragged onto drawing object
3722 DrawMarkDropObj( pHitObj
);
3727 DrawMarkDropObj( NULL
);
3731 switch ( nMyAction
)
3733 case DND_ACTION_COPY
:
3734 case DND_ACTION_MOVE
:
3735 case DND_ACTION_COPYMOVE
:
3737 sal_Bool bMove
= ( nMyAction
== DND_ACTION_MOVE
);
3738 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE
) ||
3739 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3740 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) ||
3741 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3742 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) ||
3743 IsDropFormatSupported( SOT_FORMAT_STRING
) ||
3744 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK
) ||
3745 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3746 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML
) ||
3747 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE
) ||
3748 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF
) ||
3749 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING
) ||
3750 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB
) ||
3751 IsDropFormatSupported( SOT_FORMAT_RTF
) ||
3752 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE
) ||
3753 IsDropFormatSupported( SOT_FORMAT_BITMAP
) ||
3754 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) ||
3755 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) ||
3757 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3758 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3759 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3760 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3761 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3762 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) ) ) )
3768 case DND_ACTION_LINK
:
3769 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3770 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3771 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3772 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3773 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3774 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3775 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3776 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3777 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3786 // Simple check for protection: It's not known here if the drop will result
3787 // in cells or drawing objects (some formats can be both) and how many cells
3788 // the result will be. But if IsFormatEditable for the drop cell position
3789 // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
3790 // can already be rejected here.
3792 Point aPos
= rEvt
.maPosPixel
;
3795 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3796 SCTAB nTab
= pViewData
->GetTabNo();
3797 ScDocument
* pDoc
= pViewData
->GetDocument();
3799 ScEditableTester
aTester( pDoc
, nTab
, nPosX
,nPosY
, nPosX
,nPosY
);
3800 if ( !aTester
.IsFormatEditable() )
3801 nRet
= DND_ACTION_NONE
; // forbidden
3806 // scroll only for accepted formats
3808 DropScroll( rEvt
.maPosPixel
);
3814 static sal_uLong
lcl_GetDropFormatId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
, bool bPreferText
= false )
3816 TransferableDataHelper
aDataHelper( xTransfer
);
3818 if ( !aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3820 // use bookmark formats if no sba is present
3822 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3823 return SOT_FORMATSTR_ID_SOLK
;
3824 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3825 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3826 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3827 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3828 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3829 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3832 sal_uLong nFormatId
= 0;
3833 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
) )
3834 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
3835 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
3836 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
3837 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
) )
3839 // If it's a Writer object, insert RTF instead of OLE
3841 sal_Bool bDoRtf
= false;
3842 SotStorageStreamRef xStm
;
3843 TransferableObjectDescriptor aObjDesc
;
3844 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) &&
3845 aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE
, xStm
) )
3847 SotStorageRef
xStore( new SotStorage( *xStm
) );
3848 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
3849 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
3850 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
3853 nFormatId
= FORMAT_RTF
;
3855 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
3857 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3858 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3859 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3860 nFormatId
= SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
;
3861 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) )
3862 nFormatId
= SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
;
3863 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_8
) )
3864 nFormatId
= SOT_FORMATSTR_ID_BIFF_8
;
3865 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_5
) )
3866 nFormatId
= SOT_FORMATSTR_ID_BIFF_5
;
3867 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) )
3868 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
3869 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) )
3870 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
3871 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3872 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3873 else if ( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
3874 nFormatId
= SOT_FORMAT_RTF
;
3875 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML
) )
3876 nFormatId
= SOT_FORMATSTR_ID_HTML
;
3877 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE
) )
3878 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
3879 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
) )
3880 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
3881 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3882 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3883 else if ( bPreferText
&& aDataHelper
.HasFormat( SOT_FORMAT_STRING
) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3884 nFormatId
= SOT_FORMAT_STRING
;
3885 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3886 nFormatId
= SOT_FORMAT_FILE_LIST
;
3887 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3888 nFormatId
= SOT_FORMAT_FILE
;
3889 else if ( aDataHelper
.HasFormat( SOT_FORMAT_STRING
) )
3890 nFormatId
= SOT_FORMAT_STRING
;
3891 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
3892 nFormatId
= SOT_FORMAT_GDIMETAFILE
;
3893 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) )
3894 nFormatId
= SOT_FORMAT_BITMAP
;
3899 static sal_uLong
lcl_GetDropLinkId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
)
3901 TransferableDataHelper
aDataHelper( xTransfer
);
3903 sal_uLong nFormatId
= 0;
3904 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3905 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3906 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3907 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3908 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3909 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3910 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3911 nFormatId
= SOT_FORMAT_FILE_LIST
;
3912 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) )
3913 nFormatId
= SOT_FORMAT_FILE
;
3914 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3915 nFormatId
= SOT_FORMATSTR_ID_SOLK
;
3916 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3917 nFormatId
= SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3918 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3919 nFormatId
= SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3920 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3921 nFormatId
= SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3927 sal_Int8
ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent
& rEvt
)
3931 UpdateDragRectOverlay();
3933 ScModule
* pScMod
= SC_MOD();
3934 const ScDragData
& rData
= pScMod
->GetDragData();
3936 return DropTransferObj( rData
.pCellTransfer
, nDragStartX
, nDragStartY
,
3937 PixelToLogic(rEvt
.maPosPixel
), rEvt
.mnAction
);
3940 sal_Int8
ScGridWindow::DropTransferObj( ScTransferObj
* pTransObj
, SCCOL nDestPosX
, SCROW nDestPosY
,
3941 const Point
& rLogicPos
, sal_Int8 nDndAction
)
3946 ScDocument
* pSourceDoc
= pTransObj
->GetSourceDocument();
3947 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3948 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3949 ScViewFunc
* pView
= pViewData
->GetView();
3950 SCTAB nThisTab
= pViewData
->GetTabNo();
3951 sal_uInt16 nFlags
= pTransObj
->GetDragSourceFlags();
3953 sal_Bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
3954 sal_Bool bIsMove
= ( nDndAction
== DND_ACTION_MOVE
&& !bIsNavi
);
3956 // workaround for wrong nDndAction on Windows when pressing solely
3957 // the Alt key during drag and drop;
3958 // can be removed after #i79215# has been fixed
3959 if ( meDragInsertMode
!= INS_NONE
)
3961 bIsMove
= ( nDndAction
& DND_ACTION_MOVE
&& !bIsNavi
);
3964 sal_Bool bIsLink
= ( nDndAction
== DND_ACTION_LINK
);
3966 ScRange aSource
= pTransObj
->GetRange();
3968 // only use visible tab from source range - when dragging within one table,
3969 // all selected tables at the time of dropping are used (handled in MoveBlockTo)
3970 SCTAB nSourceTab
= pTransObj
->GetVisibleTab();
3971 aSource
.aStart
.SetTab( nSourceTab
);
3972 aSource
.aEnd
.SetTab( nSourceTab
);
3974 SCCOL nSizeX
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
3975 SCROW nSizeY
= (bIsMove
? (aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1) :
3976 pTransObj
->GetNonFilteredRows()); // copy/link: no filtered rows
3977 ScRange
aDest( nDestPosX
, nDestPosY
, nThisTab
,
3978 nDestPosX
+ nSizeX
- 1, nDestPosY
+ nSizeY
- 1, nThisTab
);
3981 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3982 * dragging and adapted drawing of the selection frame. We check here
3983 * (again) because this may actually also be called from PasteSelection(),
3984 * we would have to duplicate determination of flags and destination range
3985 * and would lose the context of the "filtered destination is OK" cases
3986 * below, which is already awkward enough as is. */
3988 // Don't move filtered source.
3989 bool bFiltered
= (bIsMove
&& pTransObj
->HasFilteredRows());
3992 if (pSourceDoc
!= pThisDoc
&& ((nFlags
& SC_DROP_TABLE
) ||
3993 (!bIsLink
&& meDragInsertMode
== INS_NONE
)))
3995 // Nothing. Either entire sheet to be dropped, or the one case
3996 // where PasteFromClip() is to be called that handles a filtered
3997 // destination itself. Drag-copy from another document without
4001 // Don't copy or move to filtered destination.
4002 bFiltered
= ScViewUtil::HasFiltered( aDest
, pThisDoc
);
4005 sal_Bool bDone
= false;
4007 if (!bFiltered
&& pSourceDoc
== pThisDoc
)
4009 if ( nFlags
& SC_DROP_TABLE
) // whole sheet?
4011 if ( pThisDoc
->IsDocEditable() )
4013 SCTAB nSrcTab
= aSource
.aStart
.Tab();
4014 pViewData
->GetDocShell()->MoveTable( nSrcTab
, nThisTab
, !bIsMove
, sal_True
); // with Undo
4015 pView
->SetTabNo( nThisTab
, sal_True
);
4019 else // move/copy block
4021 OUString aChartName
;
4022 if (pThisDoc
->HasChartAtPoint( nThisTab
, rLogicPos
, aChartName
))
4025 aSource
.Format( aRangeName
, SCR_ABS_3D
, pThisDoc
);
4026 SfxStringItem
aNameItem( SID_CHART_NAME
, aChartName
);
4027 SfxStringItem
aRangeItem( SID_CHART_SOURCE
, aRangeName
);
4028 sal_uInt16 nId
= bIsMove
? SID_CHART_SOURCE
: SID_CHART_ADDSOURCE
;
4029 pViewData
->GetDispatcher().Execute( nId
, SFX_CALLMODE_ASYNCHRON
| SFX_CALLMODE_RECORD
,
4030 &aRangeItem
, &aNameItem
, (void*) NULL
);
4033 else if ( pThisDoc
->GetDPAtCursor( nDestPosX
, nDestPosY
, nThisTab
) )
4035 // drop on DataPilot table: try to sort, fail if that isn't possible
4037 ScAddress
aDestPos( nDestPosX
, nDestPosY
, nThisTab
);
4038 if ( aDestPos
!= aSource
.aStart
)
4039 bDone
= pViewData
->GetView()->DataPilotMove( aSource
, aDestPos
);
4041 bDone
= sal_True
; // same position: nothing
4043 else if ( nDestPosX
!= aSource
.aStart
.Col() || nDestPosY
!= aSource
.aStart
.Row() ||
4044 nSourceTab
!= nThisTab
)
4046 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4047 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4049 SCsCOL nCorrectCursorPosCol
= 0;
4050 SCsROW nCorrectCursorPosRow
= 0;
4053 if ( meDragInsertMode
!= INS_NONE
)
4055 // call with bApi = sal_True to avoid error messages in drop handler
4056 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, sal_True
/*bRecord*/, sal_True
/*bApi*/, sal_True
/*bPartOfPaste*/ );
4059 if ( nThisTab
== nSourceTab
)
4061 if ( meDragInsertMode
== INS_CELLSDOWN
&&
4062 nDestPosX
== aSource
.aStart
.Col() && nDestPosY
< aSource
.aStart
.Row() )
4064 bDone
= aSource
.Move( 0, nSizeY
, 0, pSourceDoc
);
4065 nCorrectCursorPosRow
= nSizeY
;
4067 else if ( meDragInsertMode
== INS_CELLSRIGHT
&&
4068 nDestPosY
== aSource
.aStart
.Row() && nDestPosX
< aSource
.aStart
.Col() )
4070 bDone
= aSource
.Move( nSizeX
, 0, 0, pSourceDoc
);
4071 nCorrectCursorPosCol
= nSizeX
;
4074 pDocSh
->UpdateOle( pViewData
);
4075 pView
->CellContentChanged();
4083 // call with bApi = sal_True to avoid error messages in drop handler
4084 bDone
= pView
->LinkBlock( aSource
, aDest
.aStart
, sal_True
/*bApi*/ );
4088 // call with bApi = sal_True to avoid error messages in drop handler
4089 bDone
= pView
->MoveBlockTo( aSource
, aDest
.aStart
, bIsMove
, sal_True
/*bRecord*/, sal_True
/*bPaint*/, sal_True
/*bApi*/ );
4093 if ( bDone
&& meDragInsertMode
!= INS_NONE
&& bIsMove
&& nThisTab
== nSourceTab
)
4095 DelCellCmd eCmd
= DEL_NONE
;
4096 if ( meDragInsertMode
== INS_CELLSDOWN
)
4100 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
4102 eCmd
= DEL_CELLSLEFT
;
4105 if ( ( eCmd
== DEL_CELLSUP
&& nDestPosX
== aSource
.aStart
.Col() ) ||
4106 ( eCmd
== DEL_CELLSLEFT
&& nDestPosY
== aSource
.aStart
.Row() ) )
4108 // call with bApi = sal_True to avoid error messages in drop handler
4109 bDone
= pDocSh
->GetDocFunc().DeleteCells( aSource
, NULL
, eCmd
, sal_True
/*bRecord*/, sal_True
/*bApi*/ );
4112 if ( eCmd
== DEL_CELLSUP
&& nDestPosY
> aSource
.aEnd
.Row() )
4114 bDone
= aDest
.Move( 0, -nSizeY
, 0, pThisDoc
);
4116 else if ( eCmd
== DEL_CELLSLEFT
&& nDestPosX
> aSource
.aEnd
.Col() )
4118 bDone
= aDest
.Move( -nSizeX
, 0, 0, pThisDoc
);
4120 pDocSh
->UpdateOle( pViewData
);
4121 pView
->CellContentChanged();
4128 pView
->MarkRange( aDest
, false, false );
4130 SCCOL nDCol
= pViewData
->GetCurX() - aSource
.aStart
.Col() + nCorrectCursorPosCol
;
4131 SCROW nDRow
= pViewData
->GetCurY() - aSource
.aStart
.Row() + nCorrectCursorPosRow
;
4132 pView
->SetCursor( aDest
.aStart
.Col() + nDCol
, aDest
.aStart
.Row() + nDRow
);
4135 pDocSh
->GetUndoManager()->LeaveListAction();
4139 bDone
= sal_True
; // nothing to do
4143 pTransObj
->SetDragWasInternal(); // don't delete source in DragFinished
4145 else if ( !bFiltered
&& pSourceDoc
) // between documents
4147 if ( nFlags
& SC_DROP_TABLE
) // copy/link sheets between documents
4149 if ( pThisDoc
->IsDocEditable() )
4151 ScDocShell
* pSrcShell
= pTransObj
->GetSourceDocShell();
4153 std::vector
<SCTAB
> nTabs
;
4155 ScMarkData aMark
= pTransObj
->GetSourceMarkData();
4156 SCTAB nTabCount
= pSourceDoc
->GetTableCount();
4158 for(SCTAB i
=0; i
<nTabCount
; i
++)
4160 if(aMark
.GetTableSelect(i
))
4163 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
4165 if((!pSourceDoc
->IsVisible(j
))&&(pSourceDoc
->IsScenario(j
)))
4167 nTabs
.push_back( j
);
4175 pView
->ImportTables( pSrcShell
,static_cast<SCTAB
>(nTabs
.size()), &nTabs
[0], bIsLink
, nThisTab
);
4182 // (external references might be used instead?)
4184 SfxObjectShell
* pSourceSh
= pSourceDoc
->GetDocumentShell();
4185 OSL_ENSURE(pSourceSh
, "drag document has no shell");
4188 String aUndo
= ScGlobal::GetRscString( STR_UNDO_COPY
);
4189 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4192 if ( meDragInsertMode
!= INS_NONE
)
4194 // call with bApi = sal_True to avoid error messages in drop handler
4195 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, sal_True
/*bRecord*/, sal_True
/*bApi*/, sal_True
/*bPartOfPaste*/ );
4198 pDocSh
->UpdateOle( pViewData
);
4199 pView
->CellContentChanged();
4205 String aApp
= Application::GetAppName();
4206 String aTopic
= pSourceSh
->GetTitle( SFX_TITLE_FULLNAME
);
4208 aSource
.Format( aItem
, SCA_VALID
| SCA_TAB_3D
, pSourceDoc
);
4210 // TODO: we could define ocQuote for "
4211 const OUString
aQuote('"');
4212 const String
& sSep
= ScCompiler::GetNativeSymbol( ocSep
);
4213 OUStringBuffer aFormula
;
4214 aFormula
.append('=');
4215 aFormula
.append(ScCompiler::GetNativeSymbol(ocDde
));
4216 aFormula
.append(ScCompiler::GetNativeSymbol(ocOpen
));
4217 aFormula
.append(aQuote
);
4218 aFormula
.append(aApp
);
4219 aFormula
.append(aQuote
);
4220 aFormula
.append(sSep
);
4221 aFormula
.append(aQuote
);
4222 aFormula
.append(aTopic
);
4223 aFormula
.append(aQuote
);
4224 aFormula
.append(sSep
);
4225 aFormula
.append(aQuote
);
4226 aFormula
.append(aItem
);
4227 aFormula
.append(aQuote
);
4228 aFormula
.append(ScCompiler::GetNativeSymbol(ocClose
));
4230 pView
->DoneBlockMode();
4231 pView
->InitBlockMode( nDestPosX
, nDestPosY
, nThisTab
);
4232 pView
->MarkCursor( nDestPosX
+ nSizeX
- 1,
4233 nDestPosY
+ nSizeY
- 1, nThisTab
);
4235 pView
->EnterMatrix( aFormula
.makeStringAndClear(), ::formula::FormulaGrammar::GRAM_NATIVE
);
4237 pView
->MarkRange( aDest
, false, false );
4238 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4241 pDocSh
->GetUndoManager()->LeaveListAction();
4246 //! HasSelectedBlockMatrixFragment without selected sheet?
4247 //! or don't start dragging on a part of a matrix
4249 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4250 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4253 if ( meDragInsertMode
!= INS_NONE
)
4255 // call with bApi = sal_True to avoid error messages in drop handler
4256 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, sal_True
/*bRecord*/, sal_True
/*bApi*/, sal_True
/*bPartOfPaste*/ );
4259 pDocSh
->UpdateOle( pViewData
);
4260 pView
->CellContentChanged();
4266 pView
->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4267 pView
->SetCursor( nDestPosX
, nDestPosY
);
4268 bDone
= pView
->PasteFromClip( IDF_ALL
, pTransObj
->GetDocument() ); // clip-doc
4271 pView
->MarkRange( aDest
, false, false );
4272 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4276 pDocSh
->GetUndoManager()->LeaveListAction();
4278 // no longer call ResetMark here - the inserted block has been selected
4279 // and may have been copied to primary selection
4283 sal_Int8 nRet
= bDone
? nDndAction
: DND_ACTION_NONE
;
4287 sal_Int8
ScGridWindow::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
4289 DrawMarkDropObj( NULL
); // drawing layer
4291 ScModule
* pScMod
= SC_MOD();
4292 const ScDragData
& rData
= pScMod
->GetDragData();
4293 if (rData
.pCellTransfer
)
4294 return ExecutePrivateDrop( rEvt
);
4296 Point aPos
= rEvt
.maPosPixel
;
4298 if ( !rData
.aLinkDoc
.isEmpty() )
4300 // try to insert a link
4304 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4305 if (pDocSh
&& pDocSh
->HasName())
4306 aThisName
= pDocSh
->GetMedium()->GetName();
4308 if ( rData
.aLinkDoc
.equals(aThisName
) ) // error - no link within a document
4312 ScViewFunc
* pView
= pViewData
->GetView();
4313 if ( !rData
.aLinkTable
.isEmpty() )
4314 pView
->InsertTableLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4316 else if ( !rData
.aLinkArea
.isEmpty() )
4320 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4321 pView
->MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, false, false );
4323 pView
->InsertAreaLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4324 rData
.aLinkArea
, 0 );
4328 OSL_FAIL("drop with link: no sheet nor area");
4333 return bOk
? rEvt
.mnAction
: DND_ACTION_NONE
; // don't try anything else
4336 Point aLogicPos
= PixelToLogic(aPos
);
4338 if (rData
.pDrawTransfer
)
4340 sal_uInt16 nFlags
= rData
.pDrawTransfer
->GetDragSourceFlags();
4342 sal_Bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4343 sal_Bool bIsMove
= ( rEvt
.mnAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4345 bPasteIsMove
= bIsMove
;
4347 pViewData
->GetView()->PasteDraw( aLogicPos
, rData
.pDrawTransfer
->GetModel() );
4350 rData
.pDrawTransfer
->SetDragWasInternal();
4351 bPasteIsMove
= false;
4353 return rEvt
.mnAction
;
4359 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4361 if (!rData
.aJumpTarget
.isEmpty())
4363 // internal bookmark (from Navigator)
4364 // bookmark clipboard formats are in PasteScDataObject
4366 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
4368 pViewData
->GetViewShell()->InsertBookmark( rData
.aJumpText
, rData
.aJumpTarget
,
4370 return rEvt
.mnAction
;
4374 sal_Bool bIsLink
= ( rEvt
.mnAction
== DND_ACTION_LINK
);
4376 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4377 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint( pViewData
->GetTabNo(), PixelToLogic(aPos
) );
4378 if ( pHitObj
&& bIsLink
)
4380 // dropped on drawing object
4381 // PasteOnDrawObject checks for valid formats
4382 if ( pViewData
->GetView()->PasteOnDrawObject( rEvt
.maDropEvent
.Transferable
, pHitObj
, sal_True
) )
4383 return rEvt
.mnAction
;
4386 sal_Bool bDone
= false;
4388 sal_uLong nFormatId
= bIsLink
?
4389 lcl_GetDropLinkId( rEvt
.maDropEvent
.Transferable
) :
4390 lcl_GetDropFormatId( rEvt
.maDropEvent
.Transferable
);
4393 pScMod
->SetInExecuteDrop( sal_True
); // #i28468# prevent error messages from PasteDataFormat
4394 bPasteIsDrop
= sal_True
;
4395 bDone
= pViewData
->GetView()->PasteDataFormat(
4396 nFormatId
, rEvt
.maDropEvent
.Transferable
, nPosX
, nPosY
, &aLogicPos
, bIsLink
);
4397 bPasteIsDrop
= false;
4398 pScMod
->SetInExecuteDrop( false );
4401 sal_Int8 nRet
= bDone
? rEvt
.mnAction
: DND_ACTION_NONE
;
4405 //--------------------------------------------------------
4407 void ScGridWindow::PasteSelection( const Point
& rPosPixel
)
4409 Point aLogicPos
= PixelToLogic( rPosPixel
);
4413 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
4415 // If the mouse down was inside a visible note window, ignore it and
4416 // leave it up to the ScPostIt to handle it
4417 SdrView
* pDrawView
= pViewData
->GetViewShell()->GetSdrView();
4420 sal_uLong nCount
= pDrawView
->GetMarkedObjectCount();
4421 for (sal_uLong i
= 0; i
< nCount
; ++i
)
4423 SdrObject
* pObj
= pDrawView
->GetMarkedObjectByIndex(i
);
4424 if (pObj
&& pObj
->GetLogicRect().IsInside(aLogicPos
))
4426 // Inside an active drawing object. Bail out.
4432 ScSelectionTransferObj
* pOwnSelection
= SC_MOD()->GetSelectionTransfer();
4433 if ( pOwnSelection
)
4437 ScTransferObj
* pCellTransfer
= pOwnSelection
->GetCellData();
4438 if ( pCellTransfer
)
4440 // keep a reference to the data in case the selection is changed during paste
4441 uno::Reference
<datatransfer::XTransferable
> xRef( pCellTransfer
);
4442 DropTransferObj( pCellTransfer
, nPosX
, nPosY
, aLogicPos
, DND_ACTION_COPY
);
4446 ScDrawTransferObj
* pDrawTransfer
= pOwnSelection
->GetDrawData();
4447 if ( pDrawTransfer
)
4449 // keep a reference to the data in case the selection is changed during paste
4450 uno::Reference
<datatransfer::XTransferable
> xRef( pDrawTransfer
);
4452 // bSameDocClipboard argument for PasteDraw is needed
4453 // because only DragData is checked directly inside PasteDraw
4454 pViewData
->GetView()->PasteDraw( aLogicPos
, pDrawTransfer
->GetModel(), false,
4455 pDrawTransfer
->GetSourceDocID() == pViewData
->GetDocument()->GetDocumentID() );
4461 // get selection from system
4463 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4464 uno::Reference
<datatransfer::XTransferable
> xTransferable
= aDataHelper
.GetTransferable();
4465 if ( xTransferable
.is() )
4467 sal_uLong nFormatId
= lcl_GetDropFormatId( xTransferable
, true );
4470 bPasteIsDrop
= sal_True
;
4471 pViewData
->GetView()->PasteDataFormat( nFormatId
, xTransferable
, nPosX
, nPosY
, &aLogicPos
);
4472 bPasteIsDrop
= false;
4478 //--------------------------------------------------------
4480 void ScGridWindow::UpdateEditViewPos()
4482 if (pViewData
->HasEditView(eWhich
))
4487 pViewData
->GetEditView( eWhich
, pView
, nCol
, nRow
);
4488 SCCOL nEndCol
= pViewData
->GetEditEndCol();
4489 SCROW nEndRow
= pViewData
->GetEditEndRow();
4493 sal_Bool bHide
= ( nEndCol
<pViewData
->GetPosX(eHWhich
) || nEndRow
<pViewData
->GetPosY(eVWhich
) );
4494 if ( SC_MOD()->IsFormulaMode() )
4495 if ( pViewData
->GetTabNo() != pViewData
->GetRefTabNo() )
4500 Rectangle aRect
= pView
->GetOutputArea();
4501 long nHeight
= aRect
.Bottom() - aRect
.Top();
4502 aRect
.Top() = PixelToLogic(GetOutputSizePixel(), pViewData
->GetLogicMode()).
4504 aRect
.Bottom() = aRect
.Top() + nHeight
;
4505 pView
->SetOutputArea( aRect
);
4506 pView
->HideCursor();
4510 // bForceToTop = sal_True for editing
4511 Rectangle aPixRect
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, this, NULL
, sal_True
);
4512 Point aScrPos
= PixelToLogic( aPixRect
.TopLeft(), pViewData
->GetLogicMode() );
4514 Rectangle aRect
= pView
->GetOutputArea();
4515 aRect
.SetPos( aScrPos
);
4516 pView
->SetOutputArea( aRect
);
4517 pView
->ShowCursor();
4522 void ScGridWindow::ScrollPixel( long nDifX
, long nDifY
)
4529 SetMapMode(MAP_PIXEL
);
4530 Scroll( nDifX
, nDifY
, SCROLL_CHILDREN
);
4531 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4533 UpdateEditViewPos();
4536 bIsInScroll
= false;
4539 // Formeln neu zeichnen -------------------------------------------------
4541 void ScGridWindow::UpdateFormulas()
4543 if (pViewData
->GetView()->IsMinimized())
4548 // nicht anfangen, verschachtelt zu painten
4549 // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4551 bNeedsRepaint
= true; // -> am Ende vom Paint nochmal Invalidate auf alles
4552 aRepaintPixel
= Rectangle(); // alles
4556 SCCOL nX1
= pViewData
->GetPosX( eHWhich
);
4557 SCROW nY1
= pViewData
->GetPosY( eVWhich
);
4558 SCCOL nX2
= nX1
+ pViewData
->VisibleCellsX( eHWhich
);
4559 SCROW nY2
= nY1
+ pViewData
->VisibleCellsY( eVWhich
);
4561 if (nX2
> MAXCOL
) nX2
= MAXCOL
;
4562 if (nY2
> MAXROW
) nY2
= MAXROW
;
4564 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4566 // don't draw directly - instead use OutputData to find changed area and invalidate
4570 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4571 ScDocument
* pDoc
= pDocSh
->GetDocument();
4572 SCTAB nTab
= pViewData
->GetTabNo();
4574 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
4576 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
4577 long nMirrorWidth
= GetSizePixel().Width();
4578 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4581 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
4582 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
4583 aScrPos
.X() = nEndPixel
+ 1;
4586 long nScrX
= aScrPos
.X();
4587 long nScrY
= aScrPos
.Y();
4589 double nPPTX
= pViewData
->GetPPTX();
4590 double nPPTY
= pViewData
->GetPPTY();
4592 ScTableInfo aTabInfo
;
4593 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
, nPPTX
, nPPTY
, false, false );
4595 Fraction aZoomX
= pViewData
->GetZoomX();
4596 Fraction aZoomY
= pViewData
->GetZoomY();
4597 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
4598 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
4600 aOutputData
.SetMirrorWidth( nMirrorWidth
);
4602 aOutputData
.FindChanged();
4604 PolyPolygon
aChangedPoly( aOutputData
.GetChangedArea() ); // logic (PixelToLogic)
4605 if ( aChangedPoly
.Count() )
4607 Invalidate(Region(aChangedPoly
));
4610 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4613 void ScGridWindow::UpdateAutoFillMark(bool bMarked
, const ScRange
& rMarkRange
)
4615 if ( bMarked
!= bAutoMarkVisible
|| ( bMarked
&& rMarkRange
.aEnd
!= aAutoMarkPos
) )
4617 bAutoMarkVisible
= bMarked
;
4619 aAutoMarkPos
= rMarkRange
.aEnd
;
4621 UpdateAutoFillOverlay();
4625 void ScGridWindow::UpdateListValPos( bool bVisible
, const ScAddress
& rPos
)
4627 bool bOldButton
= bListValButton
;
4628 ScAddress aOldPos
= aListValPos
;
4630 bListValButton
= bVisible
;
4633 if ( bListValButton
)
4635 if ( !bOldButton
|| aListValPos
!= aOldPos
)
4637 // paint area of new button
4638 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos
) ) );
4643 if ( !bListValButton
|| aListValPos
!= aOldPos
)
4645 // paint area of old button
4646 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos
) ) );
4651 void ScGridWindow::HideCursor()
4656 void ScGridWindow::ShowCursor()
4661 void ScGridWindow::GetFocus()
4663 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4664 pViewShell
->GotFocus();
4665 pViewShell
->SetFormShellAtTop( false ); // focus in GridWindow -> FormShell no longer on top
4667 if (pViewShell
->HasAccessibilityObjects())
4668 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich
, GetAccessible()));
4671 if ( !SC_MOD()->IsFormulaMode() )
4673 pViewShell
->UpdateInputHandler();
4674 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4675 // MO: nur wenn nicht im RefInput-Modus
4676 // -> GetFocus/MouseButtonDown-Reihenfolge
4680 pViewData
->GetDocShell()->CheckConfigOptions();
4684 void ScGridWindow::LoseFocus()
4686 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4687 pViewShell
->LostFocus();
4689 if (pViewShell
->HasAccessibilityObjects())
4690 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich
, GetAccessible()));
4692 Window::LoseFocus();
4695 Point
ScGridWindow::GetMousePosPixel() const { return aCurMousePos
; }
4697 //------------------------------------------------------------------------
4699 bool ScGridWindow::HitRangeFinder( const Point
& rMouse
, bool& rCorner
,
4700 sal_uInt16
* pIndex
, SCsCOL
* pAddX
, SCsROW
* pAddY
)
4702 bool bFound
= false;
4703 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4706 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4707 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
4708 pRangeFinder
->GetDocName() == pViewData
->GetDocShell()->GetTitle() )
4710 ScDocument
* pDoc
= pViewData
->GetDocument();
4711 SCTAB nTab
= pViewData
->GetTabNo();
4712 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4713 long nLayoutSign
= bLayoutRTL
? -1 : 1;
4717 pViewData
->GetPosFromPixel( rMouse
.X(), rMouse
.Y(), eWhich
, nPosX
, nPosY
);
4718 // zusammengefasste (einzeln/Bereich) ???
4719 ScAddress
aAddr( nPosX
, nPosY
, nTab
);
4721 Point aNext
= pViewData
->GetScrPos( nPosX
, nPosY
, eWhich
, true );
4724 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeXPix
, nSizeYPix
);
4725 aNext
.X() += nSizeXPix
* nLayoutSign
;
4726 aNext
.Y() += nSizeYPix
;
4730 bCornerHor
= ( rMouse
.X() >= aNext
.X() && rMouse
.X() <= aNext
.X() + 8 );
4732 bCornerHor
= ( rMouse
.X() >= aNext
.X() - 8 && rMouse
.X() <= aNext
.X() );
4734 bool bCellCorner
= ( bCornerHor
&&
4735 rMouse
.Y() >= aNext
.Y() - 8 && rMouse
.Y() <= aNext
.Y() );
4736 // corner is hit only if the mouse is within the cell
4738 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
4739 for (sal_uInt16 i
=nCount
; i
;)
4741 // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4743 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
4744 if ( pData
->aRef
.In(aAddr
) )
4746 if (pIndex
) *pIndex
= i
;
4747 if (pAddX
) *pAddX
= nPosX
- pData
->aRef
.aStart
.Col();
4748 if (pAddY
) *pAddY
= nPosY
- pData
->aRef
.aStart
.Row();
4750 rCorner
= ( bCellCorner
&& aAddr
== pData
->aRef
.aEnd
);
4760 #define SCE_BOTTOM 2
4765 static void lcl_PaintOneRange( ScDocShell
* pDocSh
, const ScRange
& rRange
, sal_uInt16 nEdges
)
4767 // der Range ist immer richtigherum
4769 SCCOL nCol1
= rRange
.aStart
.Col();
4770 SCROW nRow1
= rRange
.aStart
.Row();
4771 SCTAB nTab1
= rRange
.aStart
.Tab();
4772 SCCOL nCol2
= rRange
.aEnd
.Col();
4773 SCROW nRow2
= rRange
.aEnd
.Row();
4774 SCTAB nTab2
= rRange
.aEnd
.Tab();
4775 sal_Bool bHiddenEdge
= false;
4778 ScDocument
* pDoc
= pDocSh
->GetDocument();
4779 while ( nCol1
> 0 && pDoc
->ColHidden(nCol1
, nTab1
) )
4782 bHiddenEdge
= sal_True
;
4784 while ( nCol2
< MAXCOL
&& pDoc
->ColHidden(nCol2
, nTab1
) )
4787 bHiddenEdge
= sal_True
;
4789 nTmp
= pDoc
->FirstVisibleRow(0, nRow1
, nTab1
);
4790 if (!ValidRow(nTmp
))
4795 bHiddenEdge
= sal_True
;
4797 nTmp
= pDoc
->FirstVisibleRow(nRow2
, MAXROW
, nTab1
);
4798 if (!ValidRow(nTmp
))
4803 bHiddenEdge
= sal_True
;
4806 if ( nCol2
> nCol1
+ 1 && nRow2
> nRow1
+ 1 && !bHiddenEdge
)
4808 // nur an den Raendern entlang
4809 // (die Ecken werden evtl. zweimal getroffen)
4811 if ( nEdges
& SCE_TOP
)
4812 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow1
, nTab2
, PAINT_MARKS
);
4813 if ( nEdges
& SCE_LEFT
)
4814 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol1
, nRow2
, nTab2
, PAINT_MARKS
);
4815 if ( nEdges
& SCE_RIGHT
)
4816 pDocSh
->PostPaint( nCol2
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4817 if ( nEdges
& SCE_BOTTOM
)
4818 pDocSh
->PostPaint( nCol1
, nRow2
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4820 else // everything in one call
4821 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4824 static void lcl_PaintRefChanged( ScDocShell
* pDocSh
, const ScRange
& rOldUn
, const ScRange
& rNewUn
)
4826 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4828 ScRange aOld
= rOldUn
;
4829 ScRange aNew
= rNewUn
;
4833 if ( aOld
.aStart
== aOld
.aEnd
) //! Tab ignorieren?
4834 pDocSh
->GetDocument()->ExtendMerge(aOld
);
4835 if ( aNew
.aStart
== aNew
.aEnd
) //! Tab ignorieren?
4836 pDocSh
->GetDocument()->ExtendMerge(aNew
);
4838 SCCOL nOldCol1
= aOld
.aStart
.Col();
4839 SCROW nOldRow1
= aOld
.aStart
.Row();
4840 SCCOL nOldCol2
= aOld
.aEnd
.Col();
4841 SCROW nOldRow2
= aOld
.aEnd
.Row();
4842 SCCOL nNewCol1
= aNew
.aStart
.Col();
4843 SCROW nNewRow1
= aNew
.aStart
.Row();
4844 SCCOL nNewCol2
= aNew
.aEnd
.Col();
4845 SCROW nNewRow2
= aNew
.aEnd
.Row();
4846 SCTAB nTab1
= aOld
.aStart
.Tab(); // Tab aendert sich nicht
4847 SCTAB nTab2
= aOld
.aEnd
.Tab();
4849 if ( nNewRow2
< nOldRow1
|| nNewRow1
> nOldRow2
||
4850 nNewCol2
< nOldCol1
|| nNewCol1
> nOldCol2
||
4851 ( nNewCol1
!= nOldCol1
&& nNewRow1
!= nOldRow1
&&
4852 nNewCol2
!= nOldCol2
&& nNewRow2
!= nOldRow2
) )
4854 // komplett weggeschoben oder alle Seiten veraendert
4855 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4857 lcl_PaintOneRange( pDocSh
, aOld
, SCE_ALL
);
4859 else // alle vier Kanten einzeln testen
4862 if ( nNewRow1
< nOldRow1
) // nur obere Linie loeschen
4863 lcl_PaintOneRange( pDocSh
, ScRange(
4864 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nOldRow1
, nTab2
), SCE_ALL
);
4865 else if ( nNewRow1
> nOldRow1
) // den Teil, der oben wegkommt
4866 lcl_PaintOneRange( pDocSh
, ScRange(
4867 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nNewRow1
-1, nTab2
),
4868 SCE_ALL
&~ SCE_BOTTOM
);
4871 if ( nNewRow2
> nOldRow2
) // nur untere Linie loeschen
4872 lcl_PaintOneRange( pDocSh
, ScRange(
4873 nOldCol1
, nOldRow2
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4874 else if ( nNewRow2
< nOldRow2
) // den Teil, der unten wegkommt
4875 lcl_PaintOneRange( pDocSh
, ScRange(
4876 nOldCol1
, nNewRow2
+1, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4877 SCE_ALL
&~ SCE_TOP
);
4880 if ( nNewCol1
< nOldCol1
) // nur linke Linie loeschen
4881 lcl_PaintOneRange( pDocSh
, ScRange(
4882 nOldCol1
, nOldRow1
, nTab1
, nOldCol1
, nOldRow2
, nTab2
), SCE_ALL
);
4883 else if ( nNewCol1
> nOldCol1
) // den Teil, der links wegkommt
4884 lcl_PaintOneRange( pDocSh
, ScRange(
4885 nOldCol1
, nOldRow1
, nTab1
, nNewCol1
-1, nOldRow2
, nTab2
),
4886 SCE_ALL
&~ SCE_RIGHT
);
4889 if ( nNewCol2
> nOldCol2
) // nur rechte Linie loeschen
4890 lcl_PaintOneRange( pDocSh
, ScRange(
4891 nOldCol2
, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4892 else if ( nNewCol2
< nOldCol2
) // den Teil, der rechts wegkommt
4893 lcl_PaintOneRange( pDocSh
, ScRange(
4894 nNewCol2
+1, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4895 SCE_ALL
&~ SCE_LEFT
);
4899 void ScGridWindow::RFMouseMove( const MouseEvent
& rMEvt
, sal_Bool bUp
)
4901 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4904 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4905 if (!pRangeFinder
|| nRFIndex
>= pRangeFinder
->Count())
4907 ScRangeFindData
* pData
= pRangeFinder
->GetObject( nRFIndex
);
4912 SetPointer( Pointer( POINTER_CROSS
) );
4914 SetPointer( Pointer( POINTER_HAND
) );
4918 sal_Bool bTimer
= false;
4919 Point aPos
= rMEvt
.GetPosPixel();
4922 if ( aPos
.X() < 0 ) nDx
= -1;
4923 if ( aPos
.Y() < 0 ) nDy
= -1;
4924 Size aSize
= GetOutputSizePixel();
4925 if ( aPos
.X() >= aSize
.Width() )
4927 if ( aPos
.Y() >= aSize
.Height() )
4929 if ( nDx
!= 0 || nDy
!= 0 )
4931 if ( nDx
!= 0) pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
4932 if ( nDy
!= 0 ) pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
4936 // Umschalten bei Fixierung (damit Scrolling funktioniert)
4938 if ( eWhich
== pViewData
->GetActivePart() ) //??
4940 if ( pViewData
->GetHSplitMode() == SC_SPLIT_FIX
)
4943 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4944 pViewData
->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT
);
4945 else if ( eWhich
== SC_SPLIT_BOTTOMLEFT
)
4946 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4949 if ( pViewData
->GetVSplitMode() == SC_SPLIT_FIX
)
4952 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4953 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT
);
4954 else if ( eWhich
== SC_SPLIT_TOPRIGHT
)
4955 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4963 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4965 ScRange aOld
= pData
->aRef
;
4966 ScRange aNew
= aOld
;
4969 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
4970 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
4974 long nStartX
= nPosX
- nRFAddX
;
4975 if ( nStartX
< 0 ) nStartX
= 0;
4976 long nStartY
= nPosY
- nRFAddY
;
4977 if ( nStartY
< 0 ) nStartY
= 0;
4978 long nEndX
= nStartX
+ aOld
.aEnd
.Col() - aOld
.aStart
.Col();
4979 if ( nEndX
> MAXCOL
)
4981 nStartX
-= ( nEndX
- MAXROW
);
4984 long nEndY
= nStartY
+ aOld
.aEnd
.Row() - aOld
.aStart
.Row();
4985 if ( nEndY
> MAXROW
)
4987 nStartY
-= ( nEndY
- MAXROW
);
4991 aNew
.aStart
.SetCol((SCCOL
)nStartX
);
4992 aNew
.aStart
.SetRow((SCROW
)nStartY
);
4993 aNew
.aEnd
.SetCol((SCCOL
)nEndX
);
4994 aNew
.aEnd
.SetRow((SCROW
)nEndY
);
4998 aNew
.Justify(); // beim ButtonUp wieder richtigherum
5002 pHdl
->UpdateRange( nRFIndex
, aNew
);
5004 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5006 // nur das neuzeichnen, was sich veraendert hat...
5007 lcl_PaintRefChanged( pDocSh
, aOld
, aNew
);
5009 // neuen Rahmen nur drueberzeichnen (synchron)
5010 pDocSh
->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER
, nRFIndex
) );
5012 Update(); // was man bewegt, will man auch sofort sehen
5015 // Timer fuer Scrolling
5018 pViewData
->GetView()->SetTimer( this, rMEvt
); // Event wiederholen
5020 pViewData
->GetView()->ResetTimer();
5023 //------------------------------------------------------------------------
5025 bool ScGridWindow::GetEditUrl( const Point
& rPos
,
5026 String
* pName
, String
* pUrl
, String
* pTarget
)
5028 return GetEditUrlOrError( false, rPos
, pName
, pUrl
, pTarget
);
5031 bool ScGridWindow::GetEditUrlOrError( bool bSpellErr
, const Point
& rPos
,
5032 String
* pName
, String
* pUrl
, String
* pTarget
)
5034 //! nPosX/Y mit uebergeben?
5037 pViewData
->GetPosFromPixel( rPos
.X(), rPos
.Y(), eWhich
, nPosX
, nPosY
);
5039 SCTAB nTab
= pViewData
->GetTabNo();
5040 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5041 ScDocument
* pDoc
= pDocSh
->GetDocument();
5043 ScRefCellValue aCell
;
5044 bool bFound
= lcl_GetHyperlinkCell(pDoc
, nPosX
, nPosY
, nTab
, aCell
, sURL
);
5048 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
5049 // bForceToTop = sal_False, use the cell's real position
5050 Rectangle aEditRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, false );
5051 if (rPos
.Y() < aEditRect
.Top())
5054 // vertikal kann (noch) nicht angeklickt werden:
5056 if (pPattern
->GetCellOrientation() != SVX_ORIENTATION_STANDARD
)
5059 sal_Bool bBreak
= ((SfxBoolItem
&)pPattern
->GetItem(ATTR_LINEBREAK
)).GetValue() ||
5060 ((SvxCellHorJustify
)((const SvxHorJustifyItem
&)pPattern
->
5061 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
);
5062 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)((SvxHorJustifyItem
&)pPattern
->
5063 GetItem(ATTR_HOR_JUSTIFY
)).GetValue();
5067 ScFieldEditEngine
aEngine(pDoc
, pDoc
->GetEditPool());
5068 ScSizeDeviceProvider
aProv(pDocSh
);
5069 aEngine
.SetRefDevice( aProv
.GetDevice() );
5070 aEngine
.SetRefMapMode( MAP_100TH_MM
);
5071 SfxItemSet
aDefault( aEngine
.GetEmptyItemSet() );
5072 pPattern
->FillEditItemSet( &aDefault
);
5073 SvxAdjust eSvxAdjust
= SVX_ADJUST_LEFT
;
5076 case SVX_HOR_JUSTIFY_LEFT
:
5077 case SVX_HOR_JUSTIFY_REPEAT
: // nicht implementiert
5078 case SVX_HOR_JUSTIFY_STANDARD
: // always Text if an EditCell type
5079 eSvxAdjust
= SVX_ADJUST_LEFT
;
5081 case SVX_HOR_JUSTIFY_RIGHT
:
5082 eSvxAdjust
= SVX_ADJUST_RIGHT
;
5084 case SVX_HOR_JUSTIFY_CENTER
:
5085 eSvxAdjust
= SVX_ADJUST_CENTER
;
5087 case SVX_HOR_JUSTIFY_BLOCK
:
5088 eSvxAdjust
= SVX_ADJUST_BLOCK
;
5091 aDefault
.Put( SvxAdjustItem( eSvxAdjust
, EE_PARA_JUST
) );
5092 aEngine
.SetDefaults( aDefault
);
5094 aEngine
.SetControlWord( aEngine
.GetControlWord() | EE_CNTRL_ONLINESPELLING
);
5096 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
); // ohne Drawing-Skalierung
5097 Rectangle aLogicEdit
= PixelToLogic( aEditRect
, aEditMode
);
5098 long nThisColLogic
= aLogicEdit
.Right() - aLogicEdit
.Left() + 1;
5099 Size aPaperSize
= Size( 1000000, 1000000 );
5100 if (aCell
.meType
== CELLTYPE_FORMULA
)
5104 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
5105 aPaperSize
= Size(nSizeX
, nSizeY
);
5106 aPaperSize
= PixelToLogic(aPaperSize
);
5110 aPaperSize
.Width() = nThisColLogic
;
5111 aEngine
.SetPaperSize( aPaperSize
);
5113 boost::scoped_ptr
<EditTextObject
> pTextObj
;
5114 if (aCell
.meType
== CELLTYPE_EDIT
)
5116 if (aCell
.mpEditText
)
5117 aEngine
.SetText(*aCell
.mpEditText
);
5119 else // Not an Edit cell and is a formula cell with 'Hyperlink'
5120 // function if we have no URL, otherwise it could be a formula
5121 // cell ( or other type ? ) with a hyperlink associated with it.
5124 pTextObj
.reset(aCell
.mpFormula
->CreateURLObject());
5126 pTextObj
.reset(ScEditUtil::CreateURLObjectFromURL(*pDoc
, sURL
, sURL
));
5129 aEngine
.SetText(*pTextObj
);
5132 long nStartX
= aLogicEdit
.Left();
5134 long nTextWidth
= aEngine
.CalcTextWidth();
5135 long nTextHeight
= aEngine
.GetTextHeight();
5136 if ( nTextWidth
< nThisColLogic
)
5138 if (eHorJust
== SVX_HOR_JUSTIFY_RIGHT
)
5139 nStartX
+= nThisColLogic
- nTextWidth
;
5140 else if (eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
5141 nStartX
+= (nThisColLogic
- nTextWidth
) / 2;
5144 aLogicEdit
.Left() = nStartX
;
5146 aLogicEdit
.Right() = nStartX
+ nTextWidth
;
5148 // There is one glitch when dealing with a hyperlink cell and
5149 // the cell content is NUMERIC. This defaults to right aligned and
5150 // we need to adjust accordingly.
5151 if (aCell
.meType
== CELLTYPE_FORMULA
&& aCell
.mpFormula
->IsValue() &&
5152 eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
5154 aLogicEdit
.Right() = aLogicEdit
.Left() + nThisColLogic
- 1;
5155 aLogicEdit
.Left() = aLogicEdit
.Right() - nTextWidth
;
5157 aLogicEdit
.Bottom() = aLogicEdit
.Top() + nTextHeight
;
5160 Point aLogicClick
= PixelToLogic(rPos
,aEditMode
);
5161 if ( aLogicEdit
.IsInside(aLogicClick
) )
5163 EditView
aTempView( &aEngine
, this );
5164 aTempView
.SetOutputArea( aLogicEdit
);
5166 sal_Bool bRet
= false;
5167 MapMode aOld
= GetMapMode();
5168 SetMapMode(aEditMode
); // kein return mehr
5170 if (bSpellErr
) // Spelling-Fehler suchen
5172 bRet
= aTempView
.IsWrongSpelledWordAtPos( rPos
);
5174 pViewData
->GetView()->SetCursor( nPosX
, nPosY
); // Cursor setzen
5178 const SvxFieldItem
* pFieldItem
= aTempView
.GetFieldUnderMousePointer();
5182 const SvxFieldData
* pField
= pFieldItem
->GetField();
5183 if ( pField
&& pField
->ISA(SvxURLField
) )
5185 if ( pName
|| pUrl
|| pTarget
)
5187 const SvxURLField
* pURLField
= (const SvxURLField
*)pField
;
5189 *pName
= pURLField
->GetRepresentation();
5191 *pUrl
= pURLField
->GetURL();
5193 *pTarget
= pURLField
->GetTargetFrame();
5207 bool ScGridWindow::HasScenarioButton( const Point
& rPosPixel
, ScRange
& rScenRange
)
5209 ScDocument
* pDoc
= pViewData
->GetDocument();
5210 SCTAB nTab
= pViewData
->GetTabNo();
5211 SCTAB nTabCount
= pDoc
->GetTableCount();
5212 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
5214 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5216 Size aButSize
= pViewData
->GetScenButSize();
5217 long nBWidth
= aButSize
.Width();
5219 return false; // noch kein Button gezeichnet -> da ist auch keiner
5220 long nBHeight
= aButSize
.Height();
5221 long nHSpace
= (long)( SC_SCENARIO_HSPACE
* pViewData
->GetPPTX() );
5223 //! Ranges an der Table cachen!!!!
5226 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
5227 pDoc
->MarkScenario( i
, nTab
, aMarks
, false, SC_SCENARIO_SHOWFRAME
);
5228 ScRangeList aRanges
;
5229 aMarks
.FillRangeListWithMarks( &aRanges
, false );
5232 size_t nRangeCount
= aRanges
.size();
5233 for (size_t j
=0; j
< nRangeCount
; ++j
)
5235 ScRange aRange
= *aRanges
[j
];
5236 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5237 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5238 pDoc
->ExtendTotalMerge( aRange
);
5240 bool bTextBelow
= ( aRange
.aStart
.Row() == 0 );
5245 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1,
5250 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aStart
.Row(),
5252 aButtonPos
.Y() -= nBHeight
;
5255 aButtonPos
.X() -= nHSpace
- 1;
5257 aButtonPos
.X() -= nBWidth
- nHSpace
; // same for top or bottom
5259 Rectangle
aButRect( aButtonPos
, Size(nBWidth
,nBHeight
) );
5260 if ( aButRect
.IsInside( rPosPixel
) )
5262 rScenRange
= aRange
;
5272 void ScGridWindow::DrawLayerCreated()
5274 SetMapMode( GetDrawMapMode() );
5276 // initially create overlay objects
5277 ImpCreateOverlayObjects();
5281 void ScGridWindow::CursorChanged()
5283 // here the created OverlayObjects may be transformed in later versions. For
5284 // now, just re-create them
5286 UpdateCursorOverlay();
5290 void ScGridWindow::ImpCreateOverlayObjects()
5292 UpdateCursorOverlay();
5293 UpdateCopySourceOverlay();
5294 UpdateSelectionOverlay();
5295 UpdateAutoFillOverlay();
5296 UpdateDragRectOverlay();
5297 UpdateHeaderOverlay();
5298 UpdateShrinkOverlay();
5302 void ScGridWindow::ImpDestroyOverlayObjects()
5304 DeleteCursorOverlay();
5305 DeleteCopySourceOverlay();
5306 DeleteSelectionOverlay();
5307 DeleteAutoFillOverlay();
5308 DeleteDragRectOverlay();
5309 DeleteHeaderOverlay();
5310 DeleteShrinkOverlay();
5313 void ScGridWindow::UpdateAllOverlays()
5315 // delete and re-allocate all overlay objects
5317 ImpDestroyOverlayObjects();
5318 ImpCreateOverlayObjects();
5321 void ScGridWindow::DeleteCursorOverlay()
5323 DELETEZ( mpOOCursors
);
5326 void ScGridWindow::DeleteCopySourceOverlay()
5328 DELETEZ( mpOOSelectionBorder
);
5331 void ScGridWindow::UpdateCopySourceOverlay()
5333 MapMode aDrawMode
= GetDrawMapMode();
5334 MapMode aOldMode
= GetMapMode();
5335 if ( aOldMode
!= aDrawMode
)
5336 SetMapMode( aDrawMode
);
5338 DeleteCopySourceOverlay();
5340 if (!pViewData
->ShowPasteSource())
5342 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5343 if (!xOverlayManager
.is())
5345 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard( pViewData
->GetActiveWin() );
5348 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
5352 SCTAB nCurTab
= pViewData
->GetCurPos().Tab();
5354 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
5355 mpOOSelectionBorder
= new ::sdr::overlay::OverlayObjectList
;
5356 for ( size_t i
= 0; i
< rClipParam
.maRanges
.size(); ++i
)
5358 ScRange
* p
= rClipParam
.maRanges
[i
];
5359 if (p
->aStart
.Tab() != nCurTab
)
5362 SCCOL nClipStartX
= p
->aStart
.Col();
5363 SCROW nClipStartY
= p
->aStart
.Row();
5364 SCCOL nClipEndX
= p
->aEnd
.Col();
5365 SCROW nClipEndY
= p
->aEnd
.Row();
5367 Point aClipStartScrPos
= pViewData
->GetScrPos( nClipStartX
, nClipStartY
, eWhich
);
5368 Point aClipEndScrPos
= pViewData
->GetScrPos( nClipEndX
+ 1, nClipEndY
+ 1, eWhich
);
5369 aClipStartScrPos
-= Point(1, 1);
5370 long nSizeXPix
= aClipEndScrPos
.X() - aClipStartScrPos
.X();
5371 long nSizeYPix
= aClipEndScrPos
.Y() - aClipStartScrPos
.Y();
5373 Rectangle
aRect( aClipStartScrPos
, Size(nSizeXPix
, nSizeYPix
) );
5376 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5378 Rectangle aLogic
= PixelToLogic(aRect
, aDrawMode
);
5379 ::basegfx::B2DRange
aRange(aLogic
.Left(), aLogic
.Top(), aLogic
.Right(), aLogic
.Bottom());
5380 ScOverlayDashedBorder
* pDashedBorder
= new ScOverlayDashedBorder(aRange
, aHighlight
);
5381 xOverlayManager
->add(*pDashedBorder
);
5382 mpOOSelectionBorder
->append(*pDashedBorder
);
5385 if ( aOldMode
!= aDrawMode
)
5386 SetMapMode( aOldMode
);
5389 void ScGridWindow::UpdateCursorOverlay()
5391 MapMode aDrawMode
= GetDrawMapMode();
5392 MapMode aOldMode
= GetMapMode();
5393 if ( aOldMode
!= aDrawMode
)
5394 SetMapMode( aDrawMode
);
5396 // Existing OverlayObjects may be transformed in later versions.
5397 // For now, just re-create them.
5399 DeleteCursorOverlay();
5401 std::vector
<Rectangle
> aPixelRects
;
5404 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5407 SCTAB nTab
= pViewData
->GetTabNo();
5408 SCCOL nX
= pViewData
->GetCurX();
5409 SCROW nY
= pViewData
->GetCurY();
5411 if (!maVisibleRange
.isInside(nX
, nY
))
5414 // don't show the cursor in overlapped cells
5416 ScDocument
* pDoc
= pViewData
->GetDocument();
5417 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nX
,nY
,nTab
);
5418 const ScMergeFlagAttr
& rMergeFlag
= (const ScMergeFlagAttr
&) pPattern
->GetItem(ATTR_MERGE_FLAG
);
5419 sal_Bool bOverlapped
= rMergeFlag
.IsOverlapped();
5421 // left or above of the screen?
5423 sal_Bool bVis
= ( nX
>=pViewData
->GetPosX(eHWhich
) && nY
>=pViewData
->GetPosY(eVWhich
) );
5428 const ScMergeAttr
& rMerge
= (const ScMergeAttr
&) pPattern
->GetItem(ATTR_MERGE
);
5429 if (rMerge
.GetColMerge() > 1)
5430 nEndX
+= rMerge
.GetColMerge()-1;
5431 if (rMerge
.GetRowMerge() > 1)
5432 nEndY
+= rMerge
.GetRowMerge()-1;
5433 bVis
= ( nEndX
>=pViewData
->GetPosX(eHWhich
) && nEndY
>=pViewData
->GetPosY(eVWhich
) );
5436 if ( bVis
&& !bOverlapped
&& !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5438 Point aScrPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, sal_True
);
5439 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5441 // completely right of/below the screen?
5442 // (test with logical start position in aScrPos)
5443 sal_Bool bMaybeVisible
;
5445 bMaybeVisible
= ( aScrPos
.X() >= -2 && aScrPos
.Y() >= -2 );
5448 Size aOutSize
= GetOutputSizePixel();
5449 bMaybeVisible
= ( aScrPos
.X() <= aOutSize
.Width() + 2 && aScrPos
.Y() <= aOutSize
.Height() + 2 );
5451 if ( bMaybeVisible
)
5455 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5458 aScrPos
.X() -= nSizeXPix
- 2; // move instead of mirroring
5460 // Now, draw the cursor.
5464 Rectangle
aRect( aScrPos
, Size( nSizeXPix
+ 3, nSizeYPix
+ 3 ) );
5466 aPixelRects
.push_back(Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ));
5467 aPixelRects
.push_back(Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ));
5468 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ));
5469 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ));
5473 if ( !aPixelRects
.empty() )
5475 // #i70788# get the OverlayManager safely
5476 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5478 if (xOverlayManager
.is())
5480 Color
aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5481 if (pViewData
->GetActivePart() != eWhich
)
5482 // non-active pane uses a different color.
5483 aCursorColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5484 std::vector
< basegfx::B2DRange
> aRanges
;
5485 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5487 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5489 const Rectangle
aRA(aPixelRects
[a
]);
5490 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5491 aRB
.transform(aTransform
);
5492 aRanges
.push_back(aRB
);
5495 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5496 sdr::overlay::OVERLAY_SOLID
,
5501 xOverlayManager
->add(*pOverlay
);
5502 mpOOCursors
= new ::sdr::overlay::OverlayObjectList
;
5503 mpOOCursors
->append(*pOverlay
);
5507 if ( aOldMode
!= aDrawMode
)
5508 SetMapMode( aOldMode
);
5511 void ScGridWindow::DeleteSelectionOverlay()
5513 DELETEZ( mpOOSelection
);
5516 void ScGridWindow::UpdateSelectionOverlay()
5518 MapMode aDrawMode
= GetDrawMapMode();
5519 MapMode aOldMode
= GetMapMode();
5520 if ( aOldMode
!= aDrawMode
)
5521 SetMapMode( aDrawMode
);
5523 DeleteSelectionOverlay();
5524 std::vector
<Rectangle
> aPixelRects
;
5525 GetSelectionRects( aPixelRects
);
5527 if ( aPixelRects
.size() && pViewData
->IsActive() )
5529 // #i70788# get the OverlayManager safely
5530 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5532 if (xOverlayManager
.is())
5534 std::vector
< basegfx::B2DRange
> aRanges
;
5535 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5537 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5539 const Rectangle
aRA(aPixelRects
[a
]);
5540 basegfx::B2DRange
aRB(aRA
.Left() - 1, aRA
.Top() - 1, aRA
.Right(), aRA
.Bottom());
5541 aRB
.transform(aTransform
);
5542 aRanges
.push_back(aRB
);
5545 // #i97672# get the system's hilight color and limit it to the maximum
5546 // allowed luminance. This is needed to react on too bright hilight colors
5547 // which would otherwise vive a bad visualisation
5548 Color
aHighlight(GetSettings().GetStyleSettings().GetHighlightColor());
5549 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
5550 const basegfx::BColor
aSelection(aHighlight
.getBColor());
5551 const double fLuminance(aSelection
.luminance());
5552 const double fMaxLum(aSvtOptionsDrawinglayer
.GetSelectionMaximumLuminancePercent() / 100.0);
5554 if(fLuminance
> fMaxLum
)
5556 const double fFactor(fMaxLum
/ fLuminance
);
5557 const basegfx::BColor
aNewSelection(
5558 aSelection
.getRed() * fFactor
,
5559 aSelection
.getGreen() * fFactor
,
5560 aSelection
.getBlue() * fFactor
);
5562 aHighlight
= Color(aNewSelection
);
5565 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5566 sdr::overlay::OVERLAY_TRANSPARENT
,
5571 xOverlayManager
->add(*pOverlay
);
5572 mpOOSelection
= new ::sdr::overlay::OverlayObjectList
;
5573 mpOOSelection
->append(*pOverlay
);
5577 if ( aOldMode
!= aDrawMode
)
5578 SetMapMode( aOldMode
);
5581 void ScGridWindow::DeleteAutoFillOverlay()
5583 DELETEZ( mpOOAutoFill
);
5584 mpAutoFillRect
.reset();
5587 void ScGridWindow::UpdateAutoFillOverlay()
5589 MapMode aDrawMode
= GetDrawMapMode();
5590 MapMode aOldMode
= GetMapMode();
5591 if ( aOldMode
!= aDrawMode
)
5592 SetMapMode( aDrawMode
);
5594 DeleteAutoFillOverlay();
5597 // get the AutoFill handle rectangle in pixels
5600 if ( bAutoMarkVisible
&& aAutoMarkPos
.Tab() == pViewData
->GetTabNo() &&
5601 !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5603 SCCOL nX
= aAutoMarkPos
.Col();
5604 SCROW nY
= aAutoMarkPos
.Row();
5606 if (!maVisibleRange
.isInside(nX
, nY
))
5607 // Autofill mark is not visible. Bail out.
5610 SCTAB nTab
= pViewData
->GetTabNo();
5611 ScDocument
* pDoc
= pViewData
->GetDocument();
5612 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5614 Point aFillPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, sal_True
);
5617 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5619 aFillPos
.X() -= nSizeXPix
+ 3;
5621 aFillPos
.X() += nSizeXPix
- 2;
5623 aFillPos
.Y() += nSizeYPix
;
5625 mpAutoFillRect
.reset(new Rectangle(aFillPos
, Size(6, 6)));
5627 // #i70788# get the OverlayManager safely
5628 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5630 if (xOverlayManager
.is())
5632 Color
aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5633 if (pViewData
->GetActivePart() != eWhich
)
5634 // non-active pane uses a different color.
5635 aHandleColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5636 std::vector
< basegfx::B2DRange
> aRanges
;
5637 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5638 basegfx::B2DRange
aRB(mpAutoFillRect
->Left(), mpAutoFillRect
->Top(), mpAutoFillRect
->Right() + 1, mpAutoFillRect
->Bottom() + 1);
5640 aRB
.transform(aTransform
);
5641 aRanges
.push_back(aRB
);
5643 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5644 sdr::overlay::OVERLAY_SOLID
,
5649 xOverlayManager
->add(*pOverlay
);
5650 mpOOAutoFill
= new ::sdr::overlay::OverlayObjectList
;
5651 mpOOAutoFill
->append(*pOverlay
);
5654 if ( aOldMode
!= aDrawMode
)
5655 SetMapMode( aOldMode
);
5659 void ScGridWindow::DeleteDragRectOverlay()
5661 DELETEZ( mpOODragRect
);
5664 void ScGridWindow::UpdateDragRectOverlay()
5666 MapMode aDrawMode
= GetDrawMapMode();
5667 MapMode aOldMode
= GetMapMode();
5668 if ( aOldMode
!= aDrawMode
)
5669 SetMapMode( aDrawMode
);
5671 DeleteDragRectOverlay();
5674 // get the rectangles in pixels (moved from DrawDragRect)
5677 if ( bDragRect
|| bPagebreakDrawn
)
5679 std::vector
<Rectangle
> aPixelRects
;
5681 SCCOL nX1
= bDragRect
? nDragStartX
: aPagebreakDrag
.aStart
.Col();
5682 SCROW nY1
= bDragRect
? nDragStartY
: aPagebreakDrag
.aStart
.Row();
5683 SCCOL nX2
= bDragRect
? nDragEndX
: aPagebreakDrag
.aEnd
.Col();
5684 SCROW nY2
= bDragRect
? nDragEndY
: aPagebreakDrag
.aEnd
.Row();
5686 SCTAB nTab
= pViewData
->GetTabNo();
5688 SCCOL nPosX
= pViewData
->GetPosX(WhichH(eWhich
));
5689 SCROW nPosY
= pViewData
->GetPosY(WhichV(eWhich
));
5690 if (nX1
< nPosX
) nX1
= nPosX
;
5691 if (nX2
< nPosX
) nX2
= nPosX
;
5692 if (nY1
< nPosY
) nY1
= nPosY
;
5693 if (nY2
< nPosY
) nY2
= nPosY
;
5695 Point
aScrPos( pViewData
->GetScrPos( nX1
, nY1
, eWhich
) );
5699 ScDocument
* pDoc
= pViewData
->GetDocument();
5700 double nPPTX
= pViewData
->GetPPTX();
5701 double nPPTY
= pViewData
->GetPPTY();
5704 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5705 long nLayoutSign
= bLayoutRTL
? -1 : 1;
5707 if (ValidCol(nX2
) && nX2
>=nX1
)
5708 for (i
=nX1
; i
<=nX2
; i
++)
5709 nSizeXPix
+= ScViewData::ToPixel( pDoc
->GetColWidth( static_cast<SCCOL
>(i
), nTab
), nPPTX
);
5712 aScrPos
.X() -= nLayoutSign
;
5716 if (ValidRow(nY2
) && nY2
>=nY1
)
5717 for (i
=nY1
; i
<=nY2
; i
++)
5718 nSizeYPix
+= ScViewData::ToPixel( pDoc
->GetRowHeight( i
, nTab
), nPPTY
);
5725 aScrPos
.X() -= 2 * nLayoutSign
;
5727 Rectangle
aRect( aScrPos
.X(), aScrPos
.Y(),
5728 aScrPos
.X() + ( nSizeXPix
+ 2 ) * nLayoutSign
, aScrPos
.Y() + nSizeYPix
+ 2 );
5731 aRect
.Left() = aRect
.Right(); // end position is left
5732 aRect
.Right() = aScrPos
.X();
5735 if ( meDragInsertMode
== INS_CELLSDOWN
)
5737 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top()+3, aRect
.Left()+1, aRect
.Bottom()-2 ) );
5738 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+3, aRect
.Right()-1, aRect
.Bottom()-2 ) );
5739 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top(), aRect
.Right()-1, aRect
.Top()+2 ) );
5740 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Bottom()-1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5742 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
5744 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top()+1, aRect
.Left()+2, aRect
.Bottom()-1 ) );
5745 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5746 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top()+1, aRect
.Right()-2, aRect
.Top()+1 ) );
5747 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-1, aRect
.Right()-2, aRect
.Bottom()-1 ) );
5751 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ) );
5752 aPixelRects
.push_back( Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ) );
5753 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ) );
5754 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ) );
5757 // #i70788# get the OverlayManager safely
5758 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5760 if (xOverlayManager
.is())
5762 std::vector
< basegfx::B2DRange
> aRanges
;
5763 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5765 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5767 const Rectangle
aRA(aPixelRects
[a
]);
5768 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5769 aRB
.transform(aTransform
);
5770 aRanges
.push_back(aRB
);
5773 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5774 sdr::overlay::OVERLAY_INVERT
,
5779 xOverlayManager
->add(*pOverlay
);
5780 mpOODragRect
= new ::sdr::overlay::OverlayObjectList
;
5781 mpOODragRect
->append(*pOverlay
);
5785 if ( aOldMode
!= aDrawMode
)
5786 SetMapMode( aOldMode
);
5789 void ScGridWindow::DeleteHeaderOverlay()
5791 DELETEZ( mpOOHeader
);
5794 void ScGridWindow::UpdateHeaderOverlay()
5796 MapMode aDrawMode
= GetDrawMapMode();
5797 MapMode aOldMode
= GetMapMode();
5798 if ( aOldMode
!= aDrawMode
)
5799 SetMapMode( aDrawMode
);
5801 DeleteHeaderOverlay();
5803 // Pixel rectangle is in aInvertRect
5804 if ( !aInvertRect
.IsEmpty() )
5806 // #i70788# get the OverlayManager safely
5807 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5809 if (xOverlayManager
.is())
5811 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5812 std::vector
< basegfx::B2DRange
> aRanges
;
5813 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5814 basegfx::B2DRange
aRB(aInvertRect
.Left(), aInvertRect
.Top(), aInvertRect
.Right() + 1, aInvertRect
.Bottom() + 1);
5816 aRB
.transform(aTransform
);
5817 aRanges
.push_back(aRB
);
5819 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5820 sdr::overlay::OVERLAY_INVERT
,
5825 xOverlayManager
->add(*pOverlay
);
5826 mpOOHeader
= new ::sdr::overlay::OverlayObjectList
;
5827 mpOOHeader
->append(*pOverlay
);
5831 if ( aOldMode
!= aDrawMode
)
5832 SetMapMode( aOldMode
);
5835 void ScGridWindow::DeleteShrinkOverlay()
5837 DELETEZ( mpOOShrink
);
5840 void ScGridWindow::UpdateShrinkOverlay()
5842 MapMode aDrawMode
= GetDrawMapMode();
5843 MapMode aOldMode
= GetMapMode();
5844 if ( aOldMode
!= aDrawMode
)
5845 SetMapMode( aDrawMode
);
5847 DeleteShrinkOverlay();
5850 // get the rectangle in pixels
5855 SCTAB nTab
= pViewData
->GetTabNo();
5856 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() &&
5857 pViewData
->GetDelMark( aRange
) )
5859 //! limit to visible area
5860 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
5861 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
5863 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
5864 aRange
.aStart
.Row(), eWhich
);
5865 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
5866 aRange
.aEnd
.Row()+1, eWhich
);
5870 aPixRect
= Rectangle( aStart
,aEnd
);
5874 if ( !aPixRect
.IsEmpty() )
5876 // #i70788# get the OverlayManager safely
5877 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5879 if (xOverlayManager
.is())
5881 std::vector
< basegfx::B2DRange
> aRanges
;
5882 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5883 basegfx::B2DRange
aRB(aPixRect
.Left(), aPixRect
.Top(), aPixRect
.Right() + 1, aPixRect
.Bottom() + 1);
5885 aRB
.transform(aTransform
);
5886 aRanges
.push_back(aRB
);
5888 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5889 sdr::overlay::OVERLAY_INVERT
,
5894 xOverlayManager
->add(*pOverlay
);
5895 mpOOShrink
= new ::sdr::overlay::OverlayObjectList
;
5896 mpOOShrink
->append(*pOverlay
);
5900 if ( aOldMode
!= aDrawMode
)
5901 SetMapMode( aOldMode
);
5904 // #i70788# central method to get the OverlayManager safely
5905 rtl::Reference
<sdr::overlay::OverlayManager
> ScGridWindow::getOverlayManager()
5907 SdrPageView
* pPV
= pViewData
->GetView()->GetScDrawView()->GetSdrPageView();
5911 SdrPageWindow
* pPageWin
= pPV
->FindPageWindow( *this );
5915 return (pPageWin
->GetOverlayManager());
5919 return rtl::Reference
<sdr::overlay::OverlayManager
>();
5922 void ScGridWindow::flushOverlayManager()
5924 // #i70788# get the OverlayManager safely
5925 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5927 if (xOverlayManager
.is())
5928 xOverlayManager
->flush();
5931 void ScGridWindow::SetInRefMode( bool bInRefMode
)
5933 WinBits nBits
= GetStyle();
5935 nBits
|= WB_REFMODE
;
5937 nBits
&= ~WB_REFMODE
;
5942 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */