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 .
20 #include "scitems.hxx"
23 #include <editeng/adjustitem.hxx>
24 #include <sot/storage.hxx>
25 #include <svx/algitem.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/editstat.hxx>
28 #include <editeng/flditem.hxx>
29 #include <editeng/justifyitem.hxx>
30 #include <editeng/unolingu.hxx>
31 #include <editeng/langitem.hxx>
32 #include <editeng/misspellrange.hxx>
33 #include <svx/svdetc.hxx>
34 #include <editeng/editobj.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <svl/stritem.hxx>
39 #include <svtools/svtabbx.hxx>
40 #include <svl/urlbmk.hxx>
41 #include <svl/sharedstringpool.hxx>
42 #include <vcl/cursor.hxx>
43 #include <vcl/graph.hxx>
44 #include <vcl/hatch.hxx>
45 #include <vcl/settings.hxx>
46 #include <sot/formats.hxx>
47 #include <comphelper/classids.hxx>
48 #include <sal/macros.h>
50 #include <svx/svdview.hxx>
51 #include <editeng/outliner.hxx>
52 #include <svx/svditer.hxx>
53 #include <svx/svdocapt.hxx>
54 #include <svx/svdpagv.hxx>
56 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
57 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
58 #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
59 #include <com/sun/star/sheet/DataPilotTableResultData.hpp>
60 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
61 #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
62 #include <com/sun/star/sheet/MemberResultFlags.hpp>
63 #include <com/sun/star/awt/KeyModifier.hpp>
64 #include <com/sun/star/awt/MouseButton.hpp>
65 #include <com/sun/star/script/vba/VBAEventId.hpp>
66 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
67 #include <com/sun/star/text/textfield/Type.hpp>
69 #include "gridwin.hxx"
70 #include "tabvwsh.hxx"
72 #include "viewdata.hxx"
73 #include "tabview.hxx"
76 #include "document.hxx"
79 #include "stlpool.hxx"
80 #include "printfun.hxx"
81 #include "cbutton.hxx"
83 #include "globstr.hrc"
84 #include "editutil.hxx"
85 #include "scresid.hxx"
86 #include "inputhdl.hxx"
87 #include "uiitems.hxx"
88 #include "filtdlg.hxx"
90 #include "formulacell.hxx"
91 #include "patattr.hxx"
92 #include "notemark.hxx"
93 #include "rfindlst.hxx"
94 #include "docpool.hxx"
96 #include "docfunc.hxx"
97 #include "dbdocfun.hxx"
98 #include "dpobject.hxx"
99 #include "dpoutput.hxx"
100 #include "transobj.hxx"
101 #include "drwtrans.hxx"
102 #include "seltrans.hxx"
103 #include "sizedev.hxx"
104 #include "AccessibilityHints.hxx"
105 #include "dpsave.hxx"
106 #include "viewuno.hxx"
107 #include "compiler.hxx"
108 #include "editable.hxx"
109 #include "fillinfo.hxx"
110 #include "userdat.hxx"
111 #include "drwlayer.hxx"
112 #include "validat.hxx"
113 #include "tabprotection.hxx"
114 #include "postit.hxx"
115 #include "dpcontrol.hxx"
116 #include "checklistmenu.hxx"
117 #include "clipparam.hxx"
118 #include "cellsh.hxx"
119 #include "overlayobject.hxx"
120 #include "cellsuno.hxx"
121 #include "drawview.hxx"
122 #include "dragdata.hxx"
123 #include "cliputil.hxx"
124 #include "queryentry.hxx"
125 #include "markdata.hxx"
126 #include "checklistmenu.hrc"
127 #include "strload.hxx"
128 #include "externalrefmgr.hxx"
129 #include "dociter.hxx"
131 #include "spellcheckcontext.hxx"
133 #include <svx/sdrpagewindow.hxx>
134 #include <svx/sdr/overlay/overlaymanager.hxx>
135 #include <vcl/svapp.hxx>
136 #include <svx/sdr/overlay/overlayselection.hxx>
138 #define LOK_USE_UNSTABLE_API
139 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
142 #include <boost/shared_ptr.hpp>
145 using namespace css::uno
;
147 const sal_uInt8 SC_NESTEDBUTTON_NONE
= 0;
148 const sal_uInt8 SC_NESTEDBUTTON_DOWN
= 1;
149 const sal_uInt8 SC_NESTEDBUTTON_UP
= 2;
151 #define SC_AUTOFILTER_ALL 0
152 #define SC_AUTOFILTER_TOP10 1
153 #define SC_AUTOFILTER_CUSTOM 2
154 #define SC_AUTOFILTER_EMPTY 3
155 #define SC_AUTOFILTER_NOTEMPTY 4
157 // Modi fuer die FilterListBox
161 SC_FILTERBOX_DATASELECT
,
162 SC_FILTERBOX_SCENARIO
,
163 SC_FILTERBOX_PAGEFIELD
166 extern SfxViewShell
* pScActiveViewShell
; // global.cxx
167 extern sal_uInt16 nScClickMouseModifier
; // global.cxx
168 extern sal_uInt16 nScFillModeMouseModifier
; // global.cxx
170 struct ScGridWindow::MouseEventState
175 mbActivatePart(false)
179 #define SC_FILTERLISTBOX_LINES 12
181 ScGridWindow::VisibleRange::VisibleRange()
189 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol
, SCROW nRow
) const
191 return mnCol1
<= nCol
&& nCol
<= mnCol2
&& mnRow1
<= nRow
&& nRow
<= mnRow2
;
194 bool ScGridWindow::VisibleRange::set(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
196 bool bChanged
= mnCol1
!= nCol1
|| mnRow1
!= nRow1
|| mnCol2
!= nCol2
|| mnRow2
!= nRow2
;
206 class ScFilterListBox
: public ListBox
209 VclPtr
<ScGridWindow
> pGridWin
;
218 ScFilterBoxMode eMode
;
221 virtual void LoseFocus() SAL_OVERRIDE
;
225 ScFilterListBox( vcl::Window
* pParent
, ScGridWindow
* pGrid
,
226 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
);
227 virtual ~ScFilterListBox();
228 virtual void dispose() SAL_OVERRIDE
;
230 virtual bool PreNotify( NotifyEvent
& rNEvt
) SAL_OVERRIDE
;
231 virtual void Select() SAL_OVERRIDE
;
233 SCCOL
GetCol() const { return nCol
; }
234 SCROW
GetRow() const { return nRow
; }
235 ScFilterBoxMode
GetMode() const { return eMode
; }
237 bool IsInInit() const { return bInit
; }
238 void SetCancelled() { bCancelled
= true; }
239 bool IsInSelect() const { return bInSelect
; }
240 void SetListHasDates(bool b
) { mbListHasDates
= b
; }
241 bool HasDates() const { return mbListHasDates
; }
244 // ListBox in einem FloatingWindow (pParent)
245 ScFilterListBox::ScFilterListBox( vcl::Window
* pParent
, ScGridWindow
* pGrid
,
246 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
) :
247 ListBox( pParent
, WB_AUTOHSCROLL
),
251 bButtonDown( false ),
255 mbListHasDates(false),
261 ScFilterListBox::~ScFilterListBox()
266 void ScFilterListBox::dispose()
268 if (IsMouseCaptured())
274 void ScFilterListBox::EndInit()
276 sal_Int32 nPos
= GetSelectEntryPos();
277 if ( LISTBOX_ENTRY_NOTFOUND
== nPos
)
285 void ScFilterListBox::LoseFocus()
290 vcl::Window::LoseFocus();
293 bool ScFilterListBox::PreNotify( NotifyEvent
& rNEvt
)
296 if ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
298 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
299 vcl::KeyCode aCode
= aKeyEvt
.GetKeyCode();
300 if ( !aCode
.GetModifier() ) // no modifiers
302 sal_uInt16 nKey
= aCode
.GetCode();
303 if ( nKey
== KEY_RETURN
)
305 SelectHdl(); // select
308 else if ( nKey
== KEY_ESCAPE
)
310 pGridWin
->ClickExtern(); // clears the listbox
316 return nDone
|| ListBox::PreNotify( rNEvt
);
319 void ScFilterListBox::Select()
325 void ScFilterListBox::SelectHdl()
327 if ( !IsTravelSelect() && !bInit
&& !bCancelled
)
329 sal_Int32 nPos
= GetSelectEntryPos();
330 if ( LISTBOX_ENTRY_NOTFOUND
!= nPos
)
335 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
337 pGridWin
->FilterSelect( nSel
);
344 // use a System floating window for the above filter listbox
345 class ScFilterFloatingWindow
: public FloatingWindow
348 ScFilterFloatingWindow( vcl::Window
* pParent
, WinBits nStyle
= WB_STDFLOATWIN
);
349 virtual ~ScFilterFloatingWindow();
350 virtual void dispose() SAL_OVERRIDE
;
351 // required for System FloatingWindows that will not process KeyInput by themselves
352 virtual vcl::Window
* GetPreferredKeyInputWindow() SAL_OVERRIDE
;
355 ScFilterFloatingWindow::ScFilterFloatingWindow( vcl::Window
* pParent
, WinBits nStyle
) :
356 FloatingWindow( pParent
, nStyle
|WB_SYSTEMWINDOW
) // make it a system floater
359 ScFilterFloatingWindow::~ScFilterFloatingWindow()
364 void ScFilterFloatingWindow::dispose()
367 FloatingWindow::dispose();
370 vcl::Window
* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
372 // redirect keyinput in the child window
373 return GetWindow(GetWindowType::FirstChild
) ? GetWindow(GetWindowType::FirstChild
)->GetPreferredKeyInputWindow() : NULL
; // will be the FilterBox
376 static bool lcl_IsEditableMatrix( ScDocument
* pDoc
, const ScRange
& rRange
)
378 // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
379 // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
380 //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
382 if ( !pDoc
->IsBlockEditable( rRange
.aStart
.Tab(), rRange
.aStart
.Col(),rRange
.aStart
.Row(),
383 rRange
.aEnd
.Col(),rRange
.aEnd
.Row() ) )
386 ScRefCellValue aCell
;
387 aCell
.assign(*pDoc
, rRange
.aEnd
);
389 return (aCell
.meType
== CELLTYPE_FORMULA
&& aCell
.mpFormula
->GetMatrixOrigin(aPos
) && aPos
== rRange
.aStart
);
392 static void lcl_UnLockComment( ScDrawView
* pView
, const Point
& rPos
, ScViewData
* pViewData
)
394 if (!pView
|| !pViewData
)
397 ScDocument
& rDoc
= *pViewData
->GetDocument();
398 ScAddress
aCellPos( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
399 ScPostIt
* pNote
= rDoc
.GetNote( aCellPos
);
400 SdrObject
* pObj
= pNote
? pNote
->GetCaption() : 0;
401 if( pObj
&& pObj
->GetLogicRect().IsInside( rPos
) && ScDrawLayer::IsNoteCaption( pObj
) )
403 const ScProtectionAttr
* pProtAttr
= static_cast< const ScProtectionAttr
* > (rDoc
.GetAttr( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab(), ATTR_PROTECTION
) );
404 bool bProtectAttr
= pProtAttr
->GetProtection() || pProtAttr
->GetHideCell() ;
405 bool bProtectDoc
= rDoc
.IsTabProtected( aCellPos
.Tab() ) || pViewData
->GetSfxDocShell()->IsReadOnly() ;
406 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
407 pView
->LockInternalLayer( bProtectDoc
&& bProtectAttr
);
411 static bool lcl_GetHyperlinkCell(
412 ScDocument
* pDoc
, SCCOL
& rPosX
, SCROW
& rPosY
, SCTAB nTab
, ScRefCellValue
& rCell
, OUString
& rURL
)
417 ScAddress
aPos(rPosX
, rPosY
, nTab
);
418 rCell
.assign(*pDoc
, aPos
);
422 return false; // alles leer bis links
424 --rPosX
; // weitersuchen
428 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(aPos
);
429 if ( !static_cast<const SfxStringItem
&>(pPattern
->GetItem(ATTR_HYPERLINK
)).GetValue().isEmpty() )
431 rURL
= static_cast<const SfxStringItem
&>(pPattern
->GetItem(ATTR_HYPERLINK
)).GetValue();
434 else if (rCell
.meType
== CELLTYPE_EDIT
)
436 else if (rCell
.meType
== CELLTYPE_FORMULA
&& rCell
.mpFormula
->IsHyperLinkCell())
439 return false; // andere Zelle
447 // WB_DIALOGCONTROL noetig fuer UNO-Controls
448 ScGridWindow::ScGridWindow( vcl::Window
* pParent
, ScViewData
* pData
, ScSplitPos eWhichPos
)
449 : Window( pParent
, WB_CLIPCHILDREN
| WB_DIALOGCONTROL
),
450 DropTargetHelper( this ),
451 DragSourceHelper( this ),
454 mpOOSelectionBorder(),
459 mpAutoFillRect(static_cast<Rectangle
*>(NULL
)),
468 nCursorHideCount( 0 ),
470 nMouseStatus( SC_GM_NONE
),
471 nNestedButtonState( SC_NESTEDBUTTON_NONE
),
477 nPagebreakMouse( SC_PD_NONE
),
478 nPagebreakBreak( 0 ),
480 nPageScript( SvtScriptType::NONE
),
487 meDragInsertMode( INS_NONE
),
488 nCurrentPointer( 0 ),
489 aComboButton( this ),
492 aRFSelectedCorned( NONE
),
497 bPagebreakDrawn( false ),
499 bIsInScroll( false ),
501 bNeedsRepaint( false ),
502 bAutoMarkVisible( false ),
503 bListValButton( false )
507 case SC_SPLIT_TOPLEFT
:
508 eHWhich
= SC_SPLIT_LEFT
;
509 eVWhich
= SC_SPLIT_TOP
;
511 case SC_SPLIT_TOPRIGHT
:
512 eHWhich
= SC_SPLIT_RIGHT
;
513 eVWhich
= SC_SPLIT_TOP
;
515 case SC_SPLIT_BOTTOMLEFT
:
516 eHWhich
= SC_SPLIT_LEFT
;
517 eVWhich
= SC_SPLIT_BOTTOM
;
519 case SC_SPLIT_BOTTOMRIGHT
:
520 eHWhich
= SC_SPLIT_RIGHT
;
521 eVWhich
= SC_SPLIT_BOTTOM
;
524 OSL_FAIL("GridWindow: falsche Position");
529 SetMapMode(pViewData
->GetLogicMode(eWhich
));
530 EnableChildTransparentMode();
531 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN
| WINDOW_DLGCTRL_WANTFOCUS
);
533 SetHelpId( HID_SC_WIN_GRIDWIN
);
534 SetUniqueId( HID_SC_WIN_GRIDWIN
);
536 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
540 ScGridWindow::~ScGridWindow()
545 void ScGridWindow::dispose()
548 ImpDestroyOverlayObjects();
550 mpFilterBox
.disposeAndClear();
551 mpFilterFloat
.disposeAndClear();
552 mpNoteMarker
.reset();
553 mpAutoFilterPopup
.disposeAndClear();
554 mpDPFieldPopup
.disposeAndClear();
556 vcl::Window::dispose();
559 void ScGridWindow::ClickExtern()
563 // #i81298# don't delete the filter box when called from its select handler
564 // (possible through row header size update)
565 // #i84277# when initializing the filter box, a Basic error can deactivate the view
566 if (mpFilterBox
&& (mpFilterBox
->IsInSelect() || mpFilterBox
->IsInInit()))
570 mpFilterBox
.disposeAndClear();
571 mpFilterFloat
.disposeAndClear();
577 mpDPFieldPopup
->close(false);
578 mpDPFieldPopup
.disposeAndClear();
582 IMPL_LINK_NOARG(ScGridWindow
, PopupModeEndHdl
)
585 mpFilterBox
->SetCancelled(); // nicht mehr auswaehlen
590 IMPL_LINK( ScGridWindow
, PopupSpellingHdl
, SpellCallbackInfo
*, pInfo
)
592 if( pInfo
->nCommand
== SpellCallbackCommand::STARTSPELLDLG
)
593 pViewData
->GetDispatcher().Execute( SID_SPELL_DIALOG
, SfxCallMode::ASYNCHRON
);
597 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol
, SCROW nRow
, bool bHasSelection
, const OUString
& rStr
)
601 ScDocument
* pDoc
= pViewData
->GetDocument();
602 SCTAB nTab
= pViewData
->GetTabNo();
603 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
604 if ( pDPObj
&& nCol
> 0 )
606 // look for the dimension header left of the drop-down arrow
607 sal_uInt16 nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
608 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
609 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
611 ScDPSaveData
aSaveData( *pDPObj
->GetSaveData() );
614 OUString aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
615 if ( !bIsDataLayout
)
617 ScDPSaveDimension
* pDim
= aSaveData
.GetDimensionByName(aDimName
);
621 const OUString aName
= rStr
;
622 pDim
->SetCurrentPage( &aName
);
625 pDim
->SetCurrentPage( NULL
);
627 ScDPObject
aNewObj( *pDPObj
);
628 aNewObj
.SetSaveData( aSaveData
);
629 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
630 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, true, false );
631 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
639 struct AutoFilterData
: public ScCheckListMenuWindow::ExtendedData
645 class AutoFilterAction
: public ScMenuFloatingWindow::Action
647 VclPtr
<ScGridWindow
> mpWindow
;
648 ScGridWindow::AutoFilterMode meMode
;
650 AutoFilterAction(ScGridWindow
* p
, ScGridWindow::AutoFilterMode eMode
) :
651 mpWindow(p
), meMode(eMode
) {}
652 virtual void execute() SAL_OVERRIDE
654 mpWindow
->UpdateAutoFilterFromMenu(meMode
);
658 class AutoFilterPopupEndAction
: public ScMenuFloatingWindow::Action
660 VclPtr
<ScGridWindow
> mpWindow
;
663 AutoFilterPopupEndAction(ScGridWindow
* p
, const ScAddress
& rPos
) :
664 mpWindow(p
), maPos(rPos
) {}
665 virtual void execute() SAL_OVERRIDE
667 mpWindow
->RefreshAutoFilterButton(maPos
);
671 class AddItemToEntry
: public std::unary_function
<OUString
, void>
673 ScQueryEntry::QueryItemsType
& mrItems
;
674 svl::SharedStringPool
& mrPool
;
676 AddItemToEntry(ScQueryEntry::QueryItemsType
& rItems
, svl::SharedStringPool
& rPool
) :
677 mrItems(rItems
), mrPool(rPool
) {}
678 void operator() (const OUString
& rSelected
)
680 ScQueryEntry::Item aNew
;
681 aNew
.maString
= mrPool
.intern(rSelected
);
682 aNew
.meType
= ScQueryEntry::ByString
;
684 mrItems
.push_back(aNew
);
688 class AddSelectedItemString
: public std::unary_function
<ScQueryEntry::Item
, void>
690 std::unordered_set
<OUString
, OUStringHash
>& mrSet
;
692 AddSelectedItemString(std::unordered_set
<OUString
, OUStringHash
>& r
) :
695 void operator() (const ScQueryEntry::Item
& rItem
)
697 mrSet
.insert(rItem
.maString
.getString());
703 void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol
, SCROW nRow
)
705 SCTAB nTab
= pViewData
->GetTabNo();
706 ScDocument
* pDoc
= pViewData
->GetDocument();
708 mpAutoFilterPopup
.disposeAndClear();
709 mpAutoFilterPopup
.reset(VclPtr
<ScCheckListMenuWindow
>::Create(this, pDoc
));
710 mpAutoFilterPopup
->setOKAction(new AutoFilterAction(this, Normal
));
711 mpAutoFilterPopup
->setPopupEndAction(
712 new AutoFilterPopupEndAction(this, ScAddress(nCol
, nRow
, nTab
)));
713 std::unique_ptr
<AutoFilterData
> pData(new AutoFilterData
);
714 pData
->maPos
= ScAddress(nCol
, nRow
, nTab
);
716 Point aPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
719 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
720 Rectangle
aCellRect(OutputToScreenPixel(aPos
), Size(nSizeX
, nSizeY
));
722 ScDBData
* pDBData
= pDoc
->GetDBAtCursor(nCol
, nRow
, nTab
);
726 pData
->mpData
= pDBData
;
727 mpAutoFilterPopup
->setExtendedData(pData
.release());
730 pDBData
->GetQueryParam(aParam
);
731 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(nCol
, false);
732 std::unordered_set
<OUString
, OUStringHash
> aSelected
;
733 if (pEntry
&& pEntry
->bDoQuery
)
735 if (pEntry
->eOp
== SC_EQUAL
)
737 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
738 std::for_each(rItems
.begin(), rItems
.end(), AddSelectedItemString(aSelected
));
742 // Populate the check box list.
743 bool bHasDates
= false;
744 std::vector
<ScTypedStrData
> aStrings
;
745 pDoc
->GetFilterEntries(nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
747 mpAutoFilterPopup
->setMemberSize(aStrings
.size());
748 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
749 for (; it
!= itEnd
; ++it
)
751 const OUString
& aVal
= it
->GetString();
752 bool bSelected
= true;
753 if (!aSelected
.empty())
754 bSelected
= aSelected
.count(aVal
) > 0;
756 mpAutoFilterPopup
->addDateMember( aVal
, it
->GetValue(), bSelected
);
758 mpAutoFilterPopup
->addMember(aVal
, bSelected
);
760 mpAutoFilterPopup
->initMembers();
762 // Populate the menu.
763 mpAutoFilterPopup
->addMenuItem(
764 SC_STRLOAD(RID_POPUP_FILTER
, STR_MENU_SORT_ASC
),
765 true, new AutoFilterAction(this, SortAscending
));
766 mpAutoFilterPopup
->addMenuItem(
767 SC_STRLOAD(RID_POPUP_FILTER
, STR_MENU_SORT_DESC
),
768 true, new AutoFilterAction(this, SortDescending
));
769 mpAutoFilterPopup
->addSeparator();
770 mpAutoFilterPopup
->addMenuItem(
771 SC_RESSTR(SCSTR_TOP10FILTER
), true, new AutoFilterAction(this, Top10
));
772 mpAutoFilterPopup
->addMenuItem(
773 SC_RESSTR(SCSTR_FILTER_EMPTY
), true, new AutoFilterAction(this, Empty
));
774 mpAutoFilterPopup
->addMenuItem(
775 SC_RESSTR(SCSTR_FILTER_NOTEMPTY
), true, new AutoFilterAction(this, NonEmpty
));
776 mpAutoFilterPopup
->addSeparator();
777 mpAutoFilterPopup
->addMenuItem(
778 SC_RESSTR(SCSTR_STDFILTER
), true, new AutoFilterAction(this, Custom
));
780 ScCheckListMenuWindow::Config aConfig
;
781 aConfig
.mbAllowEmptySet
= false;
782 aConfig
.mbRTL
= pViewData
->GetDocument()->IsLayoutRTL(pViewData
->GetTabNo());
783 mpAutoFilterPopup
->setConfig(aConfig
);
784 mpAutoFilterPopup
->launch(aCellRect
);
787 void ScGridWindow::RefreshAutoFilterButton(const ScAddress
& rPos
)
791 bool bFilterActive
= IsAutoFilterActive(rPos
.Col(), rPos
.Row(), rPos
.Tab());
792 mpFilterButton
->setHasHiddenMember(bFilterActive
);
793 mpFilterButton
->setPopupPressed(false);
794 mpFilterButton
->draw();
798 void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode
)
800 const AutoFilterData
* pData
=
801 static_cast<const AutoFilterData
*>(mpAutoFilterPopup
->getExtendedData());
806 const ScAddress
& rPos
= pData
->maPos
;
807 ScDBData
* pDBData
= pData
->mpData
;
811 ScDocument
* pDoc
= pViewData
->GetDocument();
812 svl::SharedStringPool
& rPool
= pDoc
->GetSharedStringPool();
818 SCCOL nCol
= rPos
.Col();
819 ScSortParam aSortParam
;
820 pDBData
->GetSortParam(aSortParam
);
821 if (nCol
< aSortParam
.nCol1
|| nCol
> aSortParam
.nCol2
)
825 bool bHasHeader
= pDBData
->HasHeader();
827 aSortParam
.bHasHeader
= bHasHeader
;
828 aSortParam
.bByRow
= true;
829 aSortParam
.bCaseSens
= false;
830 aSortParam
.bNaturalSort
= false;
831 aSortParam
.bIncludePattern
= true;
832 aSortParam
.bInplace
= true;
833 aSortParam
.maKeyState
[0].bDoSort
= true;
834 aSortParam
.maKeyState
[0].nField
= nCol
;
835 aSortParam
.maKeyState
[0].bAscending
= (eMode
== SortAscending
);
837 for (size_t i
= 1; i
< aSortParam
.GetSortKeyCount(); ++i
)
838 aSortParam
.maKeyState
[i
].bDoSort
= false;
840 pViewData
->GetViewShell()->UISort(aSortParam
);
850 pDBData
->GetArea(aRange
);
851 pViewData
->GetView()->MarkRange(aRange
);
852 pViewData
->GetView()->SetCursor(rPos
.Col(), rPos
.Row());
853 pViewData
->GetDispatcher().Execute(SID_FILTER
, SfxCallMode::SLOT
|SfxCallMode::RECORD
);
858 pDBData
->GetQueryParam(aParam
);
860 if (eMode
== Normal
&& mpAutoFilterPopup
->isAllSelected())
862 // Remove this entry.
863 aParam
.RemoveEntryByField(rPos
.Col());
867 // Try to use the existing entry for the column (if one exists).
868 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(rPos
.Col(), true);
871 // Something went terribly wrong!
874 pEntry
->bDoQuery
= true;
875 pEntry
->nField
= rPos
.Col();
876 pEntry
->eConnect
= SC_AND
;
882 pEntry
->eOp
= SC_EQUAL
;
884 ScCheckListMenuWindow::ResultType aResult
;
885 mpAutoFilterPopup
->getResult(aResult
);
886 std::vector
<OUString
> aSelected
;
887 ScCheckListMenuWindow::ResultType::const_iterator itr
= aResult
.begin(), itrEnd
= aResult
.end();
888 for (; itr
!= itrEnd
; ++itr
)
891 aSelected
.push_back(itr
->first
);
894 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
896 std::for_each(aSelected
.begin(), aSelected
.end(), AddItemToEntry(rItems
, rPool
));
900 pEntry
->eOp
= SC_TOPVAL
;
901 pEntry
->GetQueryItem().meType
= ScQueryEntry::ByString
;
902 pEntry
->GetQueryItem().maString
= rPool
.intern("10");
905 pEntry
->SetQueryByEmpty();
908 pEntry
->SetQueryByNonEmpty();
911 // We don't know how to handle this!
916 pViewData
->GetView()->Query(aParam
, NULL
, true);
917 pDBData
->SetQueryParam(aParam
);
922 void getCellGeometry(Point
& rScrPos
, Size
& rScrSize
, const ScViewData
* pViewData
, SCCOL nCol
, SCROW nRow
, ScSplitPos eWhich
)
924 // Get the screen position of the cell.
925 rScrPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
927 // Get the screen size of the cell.
929 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
930 rScrSize
= Size(nSizeX
-1, nSizeY
-1);
935 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol
, SCROW nRow
)
938 // We assume that the page field button is located in cell to the immediate left.
941 SCTAB nTab
= pViewData
->GetTabNo();
942 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
948 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
949 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
-1, nRow
, nTab
), pDPObj
);
952 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol
, SCROW nRow
)
954 SCTAB nTab
= pViewData
->GetTabNo();
955 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
961 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
962 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
, nRow
, nTab
), pDPObj
);
965 void ScGridWindow::DoScenarioMenu( const ScRange
& rScenRange
)
967 mpFilterBox
.disposeAndClear();
968 mpFilterFloat
.disposeAndClear();
970 SCCOL nCol
= rScenRange
.aEnd
.Col(); // Zelle unterhalb des Buttons
971 SCROW nRow
= rScenRange
.aStart
.Row();
974 nRow
= rScenRange
.aEnd
.Row() + 1; // Bereich ganz oben -> Button unterhalb
975 if (nRow
>MAXROW
) nRow
= MAXROW
;
976 //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
979 ScDocument
* pDoc
= pViewData
->GetDocument();
980 SCTAB nTab
= pViewData
->GetTabNo();
981 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
986 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
987 // The button height should not use the merged cell height, should still use single row height
988 nSizeY
= ScViewData::ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
989 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
992 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
993 aCellRect
.Top() -= nSizeY
;
994 aCellRect
.Bottom() -= nSizeY
- 1;
995 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
996 // (wenn die Linie verdeckt wird, sieht es komisch aus...)
998 mpFilterFloat
.reset(VclPtr
<ScFilterFloatingWindow
>::Create(this, WinBits(WB_BORDER
)));
999 mpFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
1000 mpFilterBox
.reset(VclPtr
<ScFilterListBox
>::Create(mpFilterFloat
.get(), this, nCol
, nRow
, SC_FILTERBOX_SCENARIO
));
1002 mpFilterBox
->EnableMirroring();
1007 vcl::Font aOldFont
= GetFont();
1008 SetFont(mpFilterBox
->GetFont());
1009 MapMode aOldMode
= GetMapMode();
1010 SetMapMode( MAP_PIXEL
);
1012 nHeight
= GetTextHeight();
1013 nHeight
*= SC_FILTERLISTBOX_LINES
;
1015 SetMapMode( aOldMode
);
1016 SetFont( aOldFont
);
1021 // ParentSize Abfrage fehlt
1022 Size
aSize( nSizeX
, nHeight
);
1023 mpFilterBox
->SetSizePixel( aSize
);
1024 mpFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1025 mpFilterBox
->SetUpdateMode(false);
1027 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
1034 SCTAB nTabCount
= pDoc
->GetTableCount();
1035 SCTAB nEntryCount
= 0;
1036 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
1038 if (pDoc
->HasScenarioRange( i
, rScenRange
))
1039 if (pDoc
->GetName( i
, aTabName
))
1041 mpFilterBox
->InsertEntry(aTabName
);
1042 if (pDoc
->IsActiveScenario(i
))
1043 aCurrent
= aTabName
;
1044 long nTextWidth
= mpFilterBox
->GetTextWidth(aTabName
);
1045 if ( nTextWidth
> nMaxText
)
1046 nMaxText
= nTextWidth
;
1050 if (nEntryCount
> SC_FILTERLISTBOX_LINES
)
1051 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
1052 nMaxText
+= 4; // fuer Rand
1053 if ( nMaxText
> 300 )
1054 nMaxText
= 300; // auch nicht uebertreiben (Pixel)
1056 if (nMaxText
> nSizeX
) // Groesse auf benoetigte Groesse anpassen
1058 long nDiff
= nMaxText
- nSizeX
;
1059 aSize
= Size( nMaxText
, nHeight
);
1060 mpFilterBox
->SetSizePixel(aSize
);
1061 mpFilterFloat
->SetOutputSizePixel(aSize
);
1065 // also move popup position
1066 long nNewX
= aCellRect
.Left() - nDiff
;
1069 aCellRect
.Left() = nNewX
;
1073 mpFilterFloat
->SetOutputSizePixel( aSize
);
1074 mpFilterFloat
->StartPopupMode( aCellRect
, FloatWinPopupFlags::Down
|FloatWinPopupFlags::GrabFocus
);
1076 mpFilterBox
->SetUpdateMode(true);
1077 mpFilterBox
->GrabFocus();
1079 sal_Int32 nPos
= LISTBOX_ENTRY_NOTFOUND
;
1080 if (!aCurrent
.isEmpty())
1082 nPos
= mpFilterBox
->GetEntryPos(aCurrent
);
1084 if (LISTBOX_ENTRY_NOTFOUND
== nPos
&& mpFilterBox
->GetEntryCount() > 0 )
1088 if (LISTBOX_ENTRY_NOTFOUND
!= nPos
)
1090 mpFilterBox
->SelectEntryPos(nPos
);
1092 mpFilterBox
->EndInit();
1094 // Szenario-Auswahl kommt aus MouseButtonDown:
1095 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1097 nMouseStatus
= SC_GM_FILTER
;
1101 void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol
, SCROW nRow
, bool bDataSelect
)
1103 mpFilterBox
.disposeAndClear();
1104 mpFilterFloat
.disposeAndClear();
1107 ScDocument
* pDoc
= pViewData
->GetDocument();
1108 SCTAB nTab
= pViewData
->GetTabNo();
1109 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1114 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1115 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1119 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
1122 aPos
.Y() += nSizeY
- 1;
1124 mpFilterFloat
.reset(VclPtr
<ScFilterFloatingWindow
>::Create(this, WinBits(WB_BORDER
)));
1125 mpFilterFloat
->SetPopupModeEndHdl(LINK( this, ScGridWindow
, PopupModeEndHdl
));
1126 ScFilterBoxMode eFilterMode
= bDataSelect
? SC_FILTERBOX_DATASELECT
: SC_FILTERBOX_FILTER
;
1127 mpFilterBox
.reset(VclPtr
<ScFilterListBox
>::Create(mpFilterFloat
.get(), this, nCol
, nRow
, eFilterMode
));
1128 // Fix for bug fdo#44925
1129 if (AllSettings::GetLayoutRTL() != bLayoutRTL
)
1130 mpFilterBox
->EnableMirroring();
1135 vcl::Font aOldFont
= GetFont();
1136 SetFont(mpFilterBox
->GetFont());
1137 MapMode aOldMode
= GetMapMode();
1138 SetMapMode(MAP_PIXEL
);
1140 nHeight
= GetTextHeight();
1141 nHeight
*= SC_FILTERLISTBOX_LINES
;
1143 SetMapMode( aOldMode
);
1144 SetFont( aOldFont
);
1149 bool bEmpty
= false;
1150 std::vector
<ScTypedStrData
> aStrings
; // case sensitive
1151 if ( bDataSelect
) // Auswahl-Liste
1154 pDoc
->GetDataEntries(nCol
, nRow
, nTab
, true, aStrings
);
1155 if (aStrings
.empty())
1160 //! wird der Titel ueberhaupt ausgewertet ???
1161 OUString aString
= pDoc
->GetString(nCol
, nRow
, nTab
);
1162 mpFilterBox
->SetText(aString
);
1167 static const sal_uInt16 nDefIDs
[] = { SCSTR_TOP10FILTER
, SCSTR_STDFILTER
, SCSTR_FILTER_EMPTY
, SCSTR_FILTER_NOTEMPTY
};
1168 const size_t nDefCount
= SAL_N_ELEMENTS(nDefIDs
);
1169 for (i
=0; i
<nDefCount
; i
++)
1171 OUString
aEntry( static_cast<ScResId
>(nDefIDs
[i
]) );
1172 mpFilterBox
->InsertEntry(aEntry
);
1173 long nTextWidth
= mpFilterBox
->GetTextWidth(aEntry
);
1174 if ( nTextWidth
> nMaxText
)
1175 nMaxText
= nTextWidth
;
1177 mpFilterBox
->SetSeparatorPos(nDefCount
- 1);
1180 bool bHasDates
= false;
1181 pDoc
->GetFilterEntries( nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
1182 mpFilterBox
->SetListHasDates(bHasDates
);
1184 // check widths of numerical entries (string entries are not included)
1185 // so all numbers are completely visible
1186 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1187 for (; it
!= itEnd
; ++it
)
1189 if (!it
->IsStrData()) // only numerical entries
1191 long nTextWidth
= mpFilterBox
->GetTextWidth(it
->GetString());
1192 if ( nTextWidth
> nMaxText
)
1193 nMaxText
= nTextWidth
;
1197 // add scrollbar width if needed (string entries are counted here)
1198 // (scrollbar is shown if the box is exactly full?)
1199 if (aStrings
.size() + nDefCount
>= SC_FILTERLISTBOX_LINES
)
1200 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
1202 nMaxText
+= 4; // for borders
1204 if ( nMaxText
> nSizeX
)
1205 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
1210 // Position und Groesse an Fenster anpassen
1211 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
1213 Size aParentSize
= GetParent()->GetOutputSizePixel();
1214 Size
aSize( nSizeX
, nHeight
);
1216 if ( aSize
.Height() > aParentSize
.Height() )
1217 aSize
.Height() = aParentSize
.Height();
1218 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
1219 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
1221 mpFilterBox
->SetSizePixel(aSize
);
1222 mpFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1223 mpFilterBox
->SetUpdateMode(false);
1225 mpFilterFloat
->SetOutputSizePixel(aSize
);
1226 mpFilterFloat
->StartPopupMode(aCellRect
, FloatWinPopupFlags::Down
| FloatWinPopupFlags::GrabFocus
);
1229 bool bWait
= aStrings
.size() > 100;
1234 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1235 for (; it
!= itEnd
; ++it
)
1236 mpFilterBox
->InsertEntry(it
->GetString());
1241 mpFilterBox
->SetUpdateMode(true);
1244 sal_Int32 nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
1246 if (!bDataSelect
) // AutoFilter: aktiven Eintrag selektieren
1248 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1251 ScQueryParam aParam
;
1252 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1255 SCSIZE nCount
= aParam
.GetEntryCount();
1256 for (SCSIZE j
= 0; j
< nCount
&& bValid
; ++j
) // bisherige Filter-Einstellungen
1257 if (aParam
.GetEntry(j
).bDoQuery
)
1259 //! Abfrage mit DrawButtons zusammenfassen!
1261 ScQueryEntry
& rEntry
= aParam
.GetEntry(j
);
1263 if (rEntry
.eConnect
!= SC_AND
)
1265 if (rEntry
.nField
== nCol
)
1267 OUString aQueryStr
= rEntry
.GetQueryItem().maString
.getString();
1268 if (rEntry
.eOp
== SC_EQUAL
)
1270 if (!aQueryStr
.isEmpty())
1272 nSelPos
= mpFilterBox
->GetEntryPos(aQueryStr
);
1275 else if ( rEntry
.eOp
== SC_TOPVAL
&& aQueryStr
== "10" )
1276 nSelPos
= SC_AUTOFILTER_TOP10
;
1278 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1283 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1289 sal_uLong nIndex
= static_cast<const SfxUInt32Item
*>(pDoc
->GetAttr(
1290 nCol
, nRow
, nTab
, ATTR_VALIDDATA
))->GetValue();
1293 const ScValidationData
* pData
= pDoc
->GetValidationEntry( nIndex
);
1296 std::unique_ptr
<ScTypedStrData
> pNew
;
1297 OUString aDocStr
= pDoc
->GetString(nCol
, nRow
, nTab
);
1298 if ( pDoc
->HasValueData( nCol
, nRow
, nTab
) )
1300 double fVal
= pDoc
->GetValue(ScAddress(nCol
, nRow
, nTab
));
1301 pNew
.reset(new ScTypedStrData(aDocStr
, fVal
, ScTypedStrData::Value
));
1304 pNew
.reset(new ScTypedStrData(aDocStr
, 0.0, ScTypedStrData::Standard
));
1306 bool bSortList
= ( pData
->GetListType() == css::sheet::TableValidationVisibility::SORTEDASCENDING
);
1309 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1310 std::vector
<ScTypedStrData
>::const_iterator it
=
1311 std::find_if(itBeg
, itEnd
, FindTypedStrData(*pNew
, true));
1314 nSelPos
= std::distance(itBeg
, it
);
1318 ScTypedStrData::EqualCaseSensitive aHdl
;
1319 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1320 std::vector
<ScTypedStrData
>::const_iterator it
= itBeg
;
1321 for (; it
!= itEnd
&& LISTBOX_ENTRY_NOTFOUND
== nSelPos
; ++it
)
1323 if (aHdl(*it
, *pNew
))
1324 nSelPos
= std::distance(itBeg
, it
);
1331 // neu (309): irgendwas muss immer selektiert sein:
1332 if (LISTBOX_ENTRY_NOTFOUND
== nSelPos
&& mpFilterBox
->GetEntryCount() > 0 && !bDataSelect
)
1335 // keine leere Auswahl-Liste anzeigen:
1339 mpFilterBox
.disposeAndClear();
1340 mpFilterFloat
.disposeAndClear();
1344 mpFilterBox
->GrabFocus();
1346 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1347 if ( LISTBOX_ENTRY_NOTFOUND
!= nSelPos
)
1348 mpFilterBox
->SelectEntryPos(nSelPos
);
1352 mpFilterBox
->SetNoSelection();
1355 mpFilterBox
->EndInit();
1359 // AutoFilter (aus MouseButtonDown):
1360 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1362 nMouseStatus
= SC_GM_FILTER
;
1368 void ScGridWindow::FilterSelect( sal_uLong nSel
)
1370 OUString aString
= mpFilterBox
->GetEntry(static_cast<sal_Int32
>(nSel
));
1372 SCCOL nCol
= mpFilterBox
->GetCol();
1373 SCROW nRow
= mpFilterBox
->GetRow();
1374 switch (mpFilterBox
->GetMode())
1376 case SC_FILTERBOX_DATASELECT
:
1377 ExecDataSelect(nCol
, nRow
, aString
);
1379 case SC_FILTERBOX_FILTER
:
1380 ExecFilter(nSel
, nCol
, nRow
, aString
, mpFilterBox
->HasDates());
1382 case SC_FILTERBOX_SCENARIO
:
1383 pViewData
->GetView()->UseScenario(aString
);
1385 case SC_FILTERBOX_PAGEFIELD
:
1386 // first entry is "all"
1387 ExecPageFieldSelect( nCol
, nRow
, (nSel
!= 0), aString
);
1392 mpFilterFloat
->EndPopupMode();
1394 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1397 void ScGridWindow::ExecDataSelect( SCCOL nCol
, SCROW nRow
, const OUString
& rStr
)
1399 if ( !rStr
.isEmpty() )
1401 SCTAB nTab
= pViewData
->GetTabNo();
1402 ScViewFunc
* pView
= pViewData
->GetView();
1403 pView
->EnterData( nCol
, nRow
, nTab
, rStr
);
1405 // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1406 // if the cursor is moved afterwards.
1407 pView
->CellContentChanged();
1411 void ScGridWindow::ExecFilter( sal_uLong nSel
,
1412 SCCOL nCol
, SCROW nRow
,
1413 const OUString
& aValue
, bool bCheckForDates
)
1415 SCTAB nTab
= pViewData
->GetTabNo();
1416 ScDocument
* pDoc
= pViewData
->GetDocument();
1417 svl::SharedStringPool
& rPool
= pDoc
->GetSharedStringPool();
1419 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1422 ScQueryParam aParam
;
1423 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1425 if (SC_AUTOFILTER_CUSTOM
== nSel
)
1432 pDBData
->GetArea( nAreaTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
);
1433 pViewData
->GetView()->MarkRange( ScRange( nStartCol
,nStartRow
,nAreaTab
,nEndCol
,nEndRow
,nAreaTab
));
1434 pViewData
->GetView()->SetCursor(nCol
,nRow
); //! auch ueber Slot ??
1435 pViewData
->GetDispatcher().Execute( SID_FILTER
, SfxCallMode::SLOT
| SfxCallMode::RECORD
);
1439 bool bDeleteOld
= false;
1440 SCSIZE nQueryPos
= 0;
1441 bool bFound
= false;
1442 if (!aParam
.bInplace
)
1446 SCSIZE nCount
= aParam
.GetEntryCount();
1447 for (SCSIZE i
= 0; i
< nCount
&& !bDeleteOld
; ++i
) // bisherige Filter-Einstellungen
1448 if (aParam
.GetEntry(i
).bDoQuery
)
1450 //! Abfrage mit DrawButtons zusammenfassen!
1452 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1454 if (rEntry
.eConnect
!= SC_AND
)
1457 if (rEntry
.nField
== nCol
)
1459 if (bFound
) // diese Spalte zweimal?
1470 SCSIZE nEC
= aParam
.GetEntryCount();
1471 for (SCSIZE i
=0; i
<nEC
; i
++)
1472 aParam
.GetEntry(i
).Clear();
1474 aParam
.bInplace
= true;
1475 aParam
.bRegExp
= false;
1478 if ( nQueryPos
< nCount
|| SC_AUTOFILTER_ALL
== nSel
) // loeschen geht immer
1482 ScQueryEntry
& rNewEntry
= aParam
.GetEntry(nQueryPos
);
1483 ScQueryEntry::Item
& rItem
= rNewEntry
.GetQueryItem();
1484 rNewEntry
.bDoQuery
= true;
1485 rNewEntry
.nField
= nCol
;
1486 rItem
.meType
= bCheckForDates
? ScQueryEntry::ByDate
: ScQueryEntry::ByString
;
1488 if ( nSel
== SC_AUTOFILTER_TOP10
)
1490 rNewEntry
.eOp
= SC_TOPVAL
;
1491 rItem
.maString
= rPool
.intern("10");
1493 else if (nSel
== SC_AUTOFILTER_EMPTY
)
1495 rNewEntry
.SetQueryByEmpty();
1497 else if (nSel
== SC_AUTOFILTER_NOTEMPTY
)
1499 rNewEntry
.SetQueryByNonEmpty();
1503 rNewEntry
.eOp
= SC_EQUAL
;
1504 rItem
.maString
= rPool
.intern(aValue
);
1507 rNewEntry
.eConnect
= SC_AND
;
1512 aParam
.RemoveEntryByField(nCol
);
1515 // end edit mode - like in ScCellShell::ExecuteDB
1516 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1518 SC_MOD()->InputEnterHandler();
1519 pViewData
->GetViewShell()->UpdateInputHandler();
1522 pViewData
->GetView()->Query( aParam
, NULL
, true );
1523 pDBData
->SetQueryParam( aParam
); // speichern
1525 else // "Zuviele Bedingungen"
1526 pViewData
->GetView()->ErrorMessage( STR_FILTER_TOOMANY
);
1531 OSL_FAIL("Wo ist der Datenbankbereich?");
1535 void ScGridWindow::SetPointer( const Pointer
& rPointer
)
1537 nCurrentPointer
= 0;
1538 Window::SetPointer( rPointer
);
1541 void ScGridWindow::MoveMouseStatus( ScGridWindow
& rDestWin
)
1545 rDestWin
.nButtonDown
= nButtonDown
;
1546 rDestWin
.nMouseStatus
= nMouseStatus
;
1551 rDestWin
.bRFMouse
= bRFMouse
;
1552 rDestWin
.bRFSize
= bRFSize
;
1553 rDestWin
.nRFIndex
= nRFIndex
;
1554 rDestWin
.nRFAddX
= nRFAddX
;
1555 rDestWin
.nRFAddY
= nRFAddY
;
1559 if (nPagebreakMouse
)
1561 rDestWin
.nPagebreakMouse
= nPagebreakMouse
;
1562 rDestWin
.nPagebreakBreak
= nPagebreakBreak
;
1563 rDestWin
.nPagebreakPrev
= nPagebreakPrev
;
1564 rDestWin
.aPagebreakSource
= aPagebreakSource
;
1565 rDestWin
.aPagebreakDrag
= aPagebreakDrag
;
1566 nPagebreakMouse
= SC_PD_NONE
;
1570 bool ScGridWindow::TestMouse( const MouseEvent
& rMEvt
, bool bAction
)
1572 // MouseEvent buttons must only be checked if bAction==TRUE
1573 // to allow changing the mouse pointer in MouseMove,
1574 // but not start AutoFill with right button (#74229#).
1575 // with bAction==sal_True, SetFillMode / SetDragMode is called
1577 if ( bAction
&& !rMEvt
.IsLeft() )
1580 bool bNewPointer
= false;
1582 SfxInPlaceClient
* pClient
= pViewData
->GetViewShell()->GetIPClient();
1583 bool bOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
1585 if ( pViewData
->IsActive() && !bOleActive
)
1587 ScDocument
* pDoc
= pViewData
->GetDocument();
1588 SCTAB nTab
= pViewData
->GetTabNo();
1589 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1594 if (pViewData
->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
)
1596 if (aMarkRange
.aStart
.Tab() == pViewData
->GetTabNo() && mpAutoFillRect
)
1598 Point aMousePos
= rMEvt
.GetPosPixel();
1599 if (mpAutoFillRect
->IsInside(aMousePos
))
1601 SetPointer( Pointer( PointerStyle::Cross
) ); //! dickeres Kreuz ?
1604 SCCOL nX
= aMarkRange
.aEnd
.Col();
1605 SCROW nY
= aMarkRange
.aEnd
.Row();
1607 if ( lcl_IsEditableMatrix( pViewData
->GetDocument(), aMarkRange
) )
1608 pViewData
->SetDragMode(
1609 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
, SC_FILL_MATRIX
);
1611 pViewData
->SetFillMode(
1612 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
);
1614 // The simple selection must also be recognized when dragging,
1615 // where the Marking flag is set and MarkToSimple won't work anymore.
1616 pViewData
->GetMarkData().MarkToSimple();
1623 // Embedded-Rechteck
1625 if (pDoc
->IsEmbedded())
1628 pDoc
->GetEmbedded( aRange
);
1629 if ( pViewData
->GetTabNo() == aRange
.aStart
.Tab() )
1631 Point aStartPos
= pViewData
->GetScrPos( aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
);
1632 Point aEndPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
);
1633 Point aMousePos
= rMEvt
.GetPosPixel();
1639 bool bTop
= ( aMousePos
.X() >= aStartPos
.X()-3 && aMousePos
.X() <= aStartPos
.X()+1 &&
1640 aMousePos
.Y() >= aStartPos
.Y()-3 && aMousePos
.Y() <= aStartPos
.Y()+1 );
1641 bool bBottom
= ( aMousePos
.X() >= aEndPos
.X()-3 && aMousePos
.X() <= aEndPos
.X()+1 &&
1642 aMousePos
.Y() >= aEndPos
.Y()-3 && aMousePos
.Y() <= aEndPos
.Y()+1 );
1643 if ( bTop
|| bBottom
)
1645 SetPointer( Pointer( PointerStyle::Cross
) );
1648 sal_uInt8 nMode
= bTop
? SC_FILL_EMBED_LT
: SC_FILL_EMBED_RB
;
1649 pViewData
->SetDragMode(
1650 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1651 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nMode
);
1659 if (!bNewPointer
&& bAction
)
1661 pViewData
->ResetFillMode();
1667 void ScGridWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1669 nNestedButtonState
= SC_NESTEDBUTTON_DOWN
;
1671 MouseEventState aState
;
1672 HandleMouseButtonDown(rMEvt
, aState
);
1673 if (aState
.mbActivatePart
)
1674 pViewData
->GetView()->ActivatePart(eWhich
);
1676 if ( nNestedButtonState
== SC_NESTEDBUTTON_UP
)
1678 // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1679 // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1680 // simulate another MouseButtonUp call, so the selection state is consistent.
1682 nButtonDown
= rMEvt
.GetButtons();
1686 EndTracking(); // normally done in VCL as part of MouseButtonUp handling
1688 nNestedButtonState
= SC_NESTEDBUTTON_NONE
;
1691 bool ScGridWindow::IsCellCoveredByText(SCsCOL nPosX
, SCsROW nPosY
, SCTAB nTab
, SCsCOL
&rTextStartPosX
)
1693 ScDocument
* pDoc
= pViewData
->GetDocument();
1695 // find the first non-empty cell (this, or to the left)
1696 ScRefCellValue aCell
;
1697 SCsCOL nNonEmptyX
= nPosX
;
1698 for (; nNonEmptyX
>= 0; --nNonEmptyX
)
1700 aCell
.assign(*pDoc
, ScAddress(nNonEmptyX
, nPosY
, nTab
));
1701 if (!aCell
.isEmpty())
1705 // the inital cell already contains text
1706 if (nNonEmptyX
== nPosX
)
1708 rTextStartPosX
= nNonEmptyX
;
1712 // to the left, there is no cell that would contain (potentially
1713 // overrunning) text
1714 if (nNonEmptyX
< 0 || pDoc
->HasAttrib(nNonEmptyX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_MERGED
| HASATTR_OVERLAPPED
))
1717 double nPPTX
= pViewData
->GetPPTX();
1718 double nPPTY
= pViewData
->GetPPTY();
1720 ScTableInfo aTabInfo
;
1721 pDoc
->FillInfo(aTabInfo
, 0, nPosY
, nPosX
, nPosY
, nTab
, nPPTX
, nPPTY
, false, false);
1723 Fraction aZoomX
= pViewData
->GetZoomX();
1724 Fraction aZoomY
= pViewData
->GetZoomY();
1725 ScOutputData
aOutputData(this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
1726 0, 0, 0, nPosY
, nPosX
, nPosY
, nPPTX
, nPPTY
,
1729 MapMode
aCurrentMapMode(GetMapMode());
1730 SetMapMode(MAP_PIXEL
);
1732 // obtain the bounding box of the text in first non-empty cell
1734 Rectangle
aRect(aOutputData
.LayoutStrings(false, false, ScAddress(nNonEmptyX
, nPosY
, nTab
)));
1736 SetMapMode(aCurrentMapMode
);
1738 // the text does not overrun from the cell
1739 if (aRect
.IsEmpty())
1745 // test the rightmost position of the text bounding box
1746 long nMiddle
= (aRect
.Top() + aRect
.Bottom()) / 2;
1747 pViewData
->GetPosFromPixel(aRect
.Right(), nMiddle
, eWhich
, nTextEndX
, nTextEndY
);
1748 if (nTextEndX
>= nPosX
)
1750 rTextStartPosX
= nNonEmptyX
;
1757 void ScGridWindow::HandleMouseButtonDown( const MouseEvent
& rMEvt
, MouseEventState
& rState
)
1759 // We have to check if a context menu is shown and we have an UI
1760 // active inplace client. In that case we have to ignore the event.
1761 // Otherwise we would crash (context menu has been
1762 // opened by inplace client and we would deactivate the inplace client,
1763 // the contex menu is closed by VCL asynchronously which in the end
1764 // would work on deleted objects or the context menu has no parent anymore)
1765 SfxViewShell
* pViewSh
= pViewData
->GetViewShell();
1766 SfxInPlaceClient
* pClient
= pViewSh
->GetIPClient();
1768 pClient
->IsObjectInPlaceActive() &&
1769 PopupMenu::IsInExecute() )
1772 aCurMousePos
= rMEvt
.GetPosPixel();
1774 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1775 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1776 ClickExtern(); // loescht FilterBox, wenn vorhanden
1778 HideNoteMarker(); // Notiz-Anzeige
1782 ScModule
* pScMod
= SC_MOD();
1783 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1786 pScActiveViewShell
= pViewData
->GetViewShell(); // falls auf Link geklickt wird
1787 nScClickMouseModifier
= rMEvt
.GetModifier(); // um Control-Klick immer zu erkennen
1789 bool bDetective
= pViewData
->GetViewShell()->IsAuditShell();
1790 bool bRefMode
= pViewData
->IsRefMode(); // Referenz angefangen
1791 bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
1792 bool bEditMode
= pViewData
->HasEditView(eWhich
); // auch bei Mode==SC_INPUT_TYPE
1793 bool bDouble
= (rMEvt
.GetClicks() == 2);
1794 ScDocument
* pDoc
= pViewData
->GetDocument();
1795 bool bIsTiledRendering
= pDoc
->GetDrawLayer()->isTiledRendering();
1797 // DeactivateIP passiert nur noch bei MarkListHasChanged
1799 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1800 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1802 if ( !nButtonDown
|| !bDouble
) // single (first) click is always valid
1803 nButtonDown
= rMEvt
.GetButtons(); // set nButtonDown first, so StopMarking works
1805 // special handling of empty cells with tiled rendering
1806 if (bIsTiledRendering
)
1808 Point
aPos(rMEvt
.GetPosPixel());
1809 SCsCOL nPosX
, nNonEmptyX(0);
1811 SCTAB nTab
= pViewData
->GetTabNo();
1812 pViewData
->GetPosFromPixel(aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1814 ScRefCellValue aCell
;
1815 aCell
.assign(*pDoc
, ScAddress(nPosX
, nPosY
, nTab
));
1816 bool bIsEmpty
= aCell
.isEmpty();
1817 bool bIsCoveredByText
= bIsEmpty
&& IsCellCoveredByText(nPosX
, nPosY
, nTab
, nNonEmptyX
);
1819 if (bIsCoveredByText
)
1821 // if there's any text flowing to this cell, activate the
1822 // editengine, so that the text actually gets the events
1825 ScViewFunc
* pView
= pViewData
->GetView();
1827 pView
->SetCursor(nNonEmptyX
, nPosY
);
1828 SC_MOD()->SetInputMode(SC_INPUT_TABLE
);
1830 bEditMode
= pViewData
->HasEditView(eWhich
);
1833 // synthesize the 1st click
1834 EditView
* pEditView
= pViewData
->GetEditView(eWhich
);
1835 MouseEvent
aEditEvt(rMEvt
.GetPosPixel(), 1, MouseEventModifiers::SYNTHETIC
, MOUSE_LEFT
, 0);
1836 pEditView
->MouseButtonDown(aEditEvt
);
1837 pEditView
->MouseButtonUp(aEditEvt
);
1840 else if (bIsEmpty
&& bEditMode
&& bDouble
)
1842 // double-click in an empty cell: the entire cell is selected
1843 SetCellSelectionPixel(LOK_SETTEXTSELECTION_START
, aPos
.X(), aPos
.Y());
1844 SetCellSelectionPixel(LOK_SETTEXTSELECTION_END
, aPos
.X(), aPos
.Y());
1849 if ( ( bEditMode
&& pViewData
->GetActivePart() == eWhich
) || !bFormulaMode
)
1852 // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1853 // but a single (first) click is always valid
1854 if ( nMouseStatus
== SC_GM_IGNORE
&& bDouble
)
1857 nMouseStatus
= SC_GM_NONE
;
1861 if ( bDetective
) // Detektiv-Fuell-Modus
1863 if ( rMEvt
.IsLeft() && !rMEvt
.GetModifier() )
1865 Point aPos
= rMEvt
.GetPosPixel();
1868 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1870 SfxInt16Item
aPosXItem( SID_RANGE_COL
, nPosX
);
1871 SfxInt32Item
aPosYItem( SID_RANGE_ROW
, nPosY
);
1872 pViewData
->GetDispatcher().Execute( SID_FILL_SELECT
, SfxCallMode::SLOT
| SfxCallMode::RECORD
,
1873 &aPosXItem
, &aPosYItem
, (void*)0L );
1877 nMouseStatus
= SC_GM_NONE
;
1882 nMouseStatus
= SC_GM_NONE
;
1884 rState
.mbActivatePart
= !bFormulaMode
; // Don't activate when in formula mode.
1888 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1889 pSelEng
->SetWindow(this);
1890 pSelEng
->SetWhich(eWhich
);
1891 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1894 if (bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()))
1896 Point aPos
= rMEvt
.GetPosPixel();
1899 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1901 EditView
* pEditView
;
1904 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1905 SCCOL nEndCol
= pViewData
->GetEditEndCol();
1906 SCROW nEndRow
= pViewData
->GetEditEndRow();
1908 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
1909 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
1911 // beim Klick in die Tabellen-EditView immer den Focus umsetzen
1912 if (bFormulaMode
) // sonst ist es oben schon passiert
1915 pScMod
->SetInputMode( SC_INPUT_TABLE
);
1917 bEditMode
= pEditView
->MouseButtonDown( rMEvt
);
1922 if (pScMod
->GetIsWaterCan())
1924 //! was is mit'm Mac ???
1925 if ( rMEvt
.GetModifier() + rMEvt
.GetButtons() == MOUSE_RIGHT
)
1927 nMouseStatus
= SC_GM_WATERUNDO
;
1932 // Reihenfolge passend zum angezeigten Cursor:
1933 // RangeFinder, AutoFill, PageBreak, Drawing
1935 RfCorner rCorner
= NONE
;
1936 bool bFound
= HitRangeFinder(rMEvt
.GetPosPixel(), rCorner
, &nRFIndex
, &nRFAddX
, &nRFAddY
);
1937 bRFSize
= (rCorner
!= NONE
);
1938 aRFSelectedCorned
= rCorner
;
1942 bRFMouse
= true; // die anderen Variablen sind oben initialisiert
1944 rState
.mbActivatePart
= true; // always activate ?
1949 bool bCrossPointer
= TestMouse( rMEvt
, true );
1950 if ( bCrossPointer
)
1953 pViewData
->GetView()->FillCrossDblClick();
1955 pScMod
->InputEnterHandler(); // Autofill etc.
1958 if ( !bCrossPointer
)
1960 nPagebreakMouse
= HitPageBreak( rMEvt
.GetPosPixel(), &aPagebreakSource
,
1961 &nPagebreakBreak
, &nPagebreakPrev
);
1962 if (nPagebreakMouse
)
1964 bPagebreakDrawn
= false;
1966 PagebreakMove( rMEvt
, false );
1971 // in the tiled rendering case, single clicks into drawing objects take
1972 // precedence over bEditMode
1973 if (((!bFormulaMode
&& !bEditMode
) || bIsTiledRendering
) && rMEvt
.IsLeft())
1975 if ( !bCrossPointer
&& DrawMouseButtonDown(rMEvt
) )
1980 pViewData
->GetViewShell()->SetDrawShell( false ); // kein Draw-Objekt selektiert
1982 // TestMouse schon oben passiert
1985 Point aPos
= rMEvt
.GetPosPixel();
1988 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1989 SCTAB nTab
= pViewData
->GetTabNo();
1991 // Auto filter / pivot table / data select popup. This shouldn't activate the part.
1993 if ( !bDouble
&& !bFormulaMode
&& rMEvt
.IsLeft() )
1997 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nRealPosX
, nRealPosY
, false );//the real row/col
1998 const ScMergeFlagAttr
* pRealPosAttr
= static_cast<const ScMergeFlagAttr
*>(
1999 pDoc
->GetAttr( nRealPosX
, nRealPosY
, nTab
, ATTR_MERGE_FLAG
));
2000 const ScMergeFlagAttr
* pAttr
= static_cast<const ScMergeFlagAttr
*>(
2001 pDoc
->GetAttr( nPosX
, nPosY
, nTab
, ATTR_MERGE_FLAG
));
2002 if( pRealPosAttr
->HasAutoFilter() )
2004 SC_MOD()->InputEnterHandler();
2005 if (DoAutoFilterButton( nRealPosX
, nRealPosY
, rMEvt
))
2008 if (pAttr
->HasAutoFilter())
2010 if (DoAutoFilterButton(nPosX
, nPosY
, rMEvt
))
2012 rState
.mbActivatePart
= false;
2017 if (pAttr
->HasPivotButton() || pAttr
->HasPivotPopupButton())
2019 DoPushPivotButton(nPosX
, nPosY
, rMEvt
, pAttr
->HasPivotButton(), pAttr
->HasPivotPopupButton());
2020 rState
.mbActivatePart
= false;
2024 // List Validity drop-down button
2026 if ( bListValButton
)
2028 Rectangle aButtonRect
= GetListValButtonRect( aListValPos
);
2029 if ( aButtonRect
.IsInside( aPos
) )
2031 LaunchDataSelectMenu( aListValPos
.Col(), aListValPos
.Row(), true );
2033 nMouseStatus
= SC_GM_FILTER
; // not set in DoAutoFilterMenue for bDataSelect
2035 rState
.mbActivatePart
= false;
2041 // scenario selection
2044 if ( rMEvt
.IsLeft() && HasScenarioButton( aPos
, aScenRange
) )
2046 DoScenarioMenu( aScenRange
);
2050 // Doppelklick angefangen ?
2052 // StopMarking kann aus DrawMouseButtonDown gerufen werden
2054 if ( nMouseStatus
!= SC_GM_IGNORE
&& !bRefMode
)
2056 if ( bDouble
&& !bCrossPointer
)
2058 if (nMouseStatus
== SC_GM_TABDOWN
)
2059 nMouseStatus
= SC_GM_DBLDOWN
;
2062 nMouseStatus
= SC_GM_TABDOWN
;
2065 // Links in Edit-Zellen
2067 bool bAlt
= rMEvt
.IsMod2();
2068 if ( !bAlt
&& rMEvt
.IsLeft() &&
2069 GetEditUrl(rMEvt
.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
2071 SetPointer( Pointer( PointerStyle::RefHand
) );
2072 nMouseStatus
= SC_GM_URLDOWN
; // auch nur dann beim ButtonUp ausfuehren
2076 // Gridwin - SelectionEngine
2078 if ( rMEvt
.IsLeft() )
2080 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
2081 pSelEng
->SetWindow(this);
2082 pSelEng
->SetWhich(eWhich
);
2083 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
2085 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
2086 if ( pViewData
->GetView()->SelMouseButtonDown( rMEvt
) )
2088 if (IsMouseCaptured())
2090 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
2091 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
2095 pViewData
->GetMarkData().SetMarking(true);
2101 void ScGridWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
2103 aCurMousePos
= rMEvt
.GetPosPixel();
2104 ScDocument
* pDoc
= pViewData
->GetDocument();
2105 ScMarkData
& rMark
= pViewData
->GetMarkData();
2107 // #i41690# detect a MouseButtonUp call from within MouseButtonDown
2108 // (possible through Reschedule from storing an OLE object that is deselected)
2110 if ( nNestedButtonState
== SC_NESTEDBUTTON_DOWN
)
2111 nNestedButtonState
= SC_NESTEDBUTTON_UP
;
2113 if (nButtonDown
!= rMEvt
.GetButtons())
2114 nMouseStatus
= SC_GM_IGNORE
; // reset und return
2118 if (nMouseStatus
== SC_GM_IGNORE
)
2120 nMouseStatus
= SC_GM_NONE
;
2121 // Selection-Engine: Markieren abbrechen
2122 pViewData
->GetView()->GetSelEngine()->Reset();
2123 rMark
.SetMarking(false);
2124 if (pViewData
->IsAnyFillMode())
2126 pViewData
->GetView()->StopRefMode();
2127 pViewData
->ResetFillMode();
2130 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
2135 if (nMouseStatus
== SC_GM_FILTER
)
2137 nMouseStatus
= SC_GM_NONE
;
2139 return; // da muss nix mehr passieren
2142 ScModule
* pScMod
= SC_MOD();
2143 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2146 SfxBindings
& rBindings
= pViewData
->GetBindings();
2147 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2149 EditView
* pEditView
;
2152 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2153 pEditView
->MouseButtonUp( rMEvt
);
2155 if ( rMEvt
.IsMiddle() &&
2156 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MouseMiddleButtonAction::PasteSelection
)
2158 // EditView may have pasted from selection
2159 pScMod
->InputChanged( pEditView
);
2162 pScMod
->InputSelection( pEditView
); // parentheses etc.
2164 pViewData
->GetView()->InvalidateAttribs();
2165 rBindings
.Invalidate( SID_HYPERLINK_GETLINK
);
2172 DPMouseButtonUp( rMEvt
); // resets bDPMouse
2178 RFMouseMove( rMEvt
, true ); // Range wieder richtigherum
2180 SetPointer( Pointer( PointerStyle::Arrow
) );
2185 if (nPagebreakMouse
)
2187 PagebreakMove( rMEvt
, true );
2188 nPagebreakMouse
= SC_PD_NONE
;
2189 SetPointer( Pointer( PointerStyle::Arrow
) );
2194 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus
2196 ::svl::IUndoManager
* pMgr
= pViewData
->GetDocShell()->GetUndoManager();
2197 if ( pMgr
->GetUndoActionCount() && pMgr
->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE
)
2202 if (DrawMouseButtonUp(rMEvt
)) // includes format paint brush handling for drawing objects
2204 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
2205 SfxBindings
& rFrmBindings
=pViewShell
->GetViewFrame()->GetBindings();
2206 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_WIDTH
);
2207 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_HEIGHT
);
2208 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_X
);
2209 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_Y
);
2210 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ANGLE
);
2211 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ROT_X
);
2212 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ROT_Y
);
2213 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_AUTOWIDTH
);
2214 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_AUTOHEIGHT
);
2218 rMark
.SetMarking(false);
2220 SetPointer( Pointer( PointerStyle::Arrow
) );
2222 if (pViewData
->IsFillMode() ||
2223 ( pViewData
->GetFillMode() == SC_FILL_MATRIX
&& rMEvt
.IsMod1() ))
2225 nScFillModeMouseModifier
= rMEvt
.GetModifier();
2230 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2232 bool bIsDel
= pViewData
->GetDelMark( aDelRange
);
2234 ScViewFunc
* pView
= pViewData
->GetView();
2235 pView
->StopRefMode();
2236 pViewData
->ResetFillMode();
2237 pView
->GetFunctionSet().SetAnchorFlag( false ); // #i5819# don't use AutoFill anchor flag for selection
2241 pView
->MarkRange( aDelRange
, false );
2242 pView
->DeleteContents( IDF_CONTENTS
);
2243 SCTAB nTab
= pViewData
->GetTabNo();
2244 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2245 if ( aBlockRange
!= aDelRange
)
2247 if ( aDelRange
.aStart
.Row() == nStartRow
)
2248 aBlockRange
.aEnd
.SetCol( aDelRange
.aStart
.Col() - 1 );
2250 aBlockRange
.aEnd
.SetRow( aDelRange
.aStart
.Row() - 1 );
2251 pView
->MarkRange( aBlockRange
, false );
2255 pViewData
->GetDispatcher().Execute( FID_FILL_AUTO
, SfxCallMode::SLOT
| SfxCallMode::RECORD
);
2257 else if (pViewData
->GetFillMode() == SC_FILL_MATRIX
)
2259 SCTAB nTab
= pViewData
->GetTabNo();
2264 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2265 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2266 SCCOL nFillCol
= pViewData
->GetRefEndX();
2267 SCROW nFillRow
= pViewData
->GetRefEndY();
2268 ScAddress
aEndPos( nFillCol
, nFillRow
, nTab
);
2270 ScTabView
* pView
= pViewData
->GetView();
2271 pView
->StopRefMode();
2272 pViewData
->ResetFillMode();
2273 pView
->GetFunctionSet().SetAnchorFlag( false );
2275 if ( aEndPos
!= aBlockRange
.aEnd
)
2277 pViewData
->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange
, aEndPos
, false );
2278 pViewData
->GetView()->MarkRange( ScRange( aBlockRange
.aStart
, aEndPos
) );
2281 else if (pViewData
->IsAnyFillMode())
2283 // Embedded-Area has been changed
2284 ScTabView
* pView
= pViewData
->GetView();
2285 pView
->StopRefMode();
2286 pViewData
->ResetFillMode();
2287 pView
->GetFunctionSet().SetAnchorFlag( false );
2288 pViewData
->GetDocShell()->UpdateOle(pViewData
);
2291 bool bRefMode
= pViewData
->IsRefMode();
2293 pScMod
->EndReference();
2295 // Giesskannen-Modus (Gestalter)
2297 if (pScMod
->GetIsWaterCan())
2299 // Abfrage auf Undo schon oben
2301 ScStyleSheetPool
* pStylePool
= (pViewData
->GetDocument()->
2302 GetStyleSheetPool());
2305 SfxStyleSheet
* pStyleSheet
= static_cast<SfxStyleSheet
*>(
2306 pStylePool
->GetActualStyleSheet());
2310 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
2314 case SFX_STYLE_FAMILY_PARA
:
2315 pViewData
->GetView()->SetStyleSheetToMarked( pStyleSheet
);
2316 pViewData
->GetView()->DoneBlockMode();
2319 case SFX_STYLE_FAMILY_PAGE
:
2320 pViewData
->GetDocument()->SetPageStyle( pViewData
->GetTabNo(),
2321 pStyleSheet
->GetName() );
2323 ScPrintFunc( pViewData
->GetDocShell(),
2324 pViewData
->GetViewShell()->GetPrinter(true),
2325 pViewData
->GetTabNo() ).UpdatePages();
2327 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
2337 ScDBFunc
* pView
= pViewData
->GetView();
2338 ScDocument
* pBrushDoc
= pView
->GetBrushDocument();
2341 pView
->PasteFromClip( IDF_ATTRIB
, pBrushDoc
);
2342 if ( !pView
->IsPaintBrushLocked() )
2343 pView
->ResetBrushDocument(); // invalidates pBrushDoc pointer
2346 // double click (only left button)
2347 // in the tiled rendering case, single click works this way too
2349 bool bIsTiledRendering
= pViewData
->GetDocument()->GetDrawLayer()->isTiledRendering();
2350 bool bDouble
= ( rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() );
2351 if ((bDouble
|| bIsTiledRendering
) && !bRefMode
&& (nMouseStatus
== SC_GM_DBLDOWN
|| bIsTiledRendering
) && !pScMod
->IsRefDialogOpen())
2354 Point aPos
= rMEvt
.GetPosPixel();
2357 SCTAB nTab
= pViewData
->GetTabNo();
2358 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2359 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor( nPosX
, nPosY
, nTab
);
2360 if ( pDPObj
&& pDPObj
->GetSaveData()->GetDrillDown() )
2362 ScAddress
aCellPos( nPosX
, nPosY
, pViewData
->GetTabNo() );
2364 // Check for header drill-down first.
2365 sheet::DataPilotTableHeaderData aData
;
2366 pDPObj
->GetHeaderPositionData(aCellPos
, aData
);
2368 if ( ( aData
.Flags
& sheet::MemberResultFlags::HASMEMBER
) &&
2369 ! ( aData
.Flags
& sheet::MemberResultFlags::SUBTOTAL
) )
2372 if ( pView
->HasSelectionForDrillDown( nDummy
) )
2374 // execute slot to show dialog
2375 pViewData
->GetDispatcher().Execute( SID_OUTLINE_SHOW
, SfxCallMode::SLOT
| SfxCallMode::RECORD
);
2379 // toggle single entry
2380 ScDPObject
aNewObj( *pDPObj
);
2381 pDPObj
->ToggleDetails( aData
, &aNewObj
);
2382 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
2383 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, true, false );
2384 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
2389 // Check if the data area is double-clicked.
2391 Sequence
<sheet::DataPilotFieldFilter
> aFilters
;
2392 if ( pDPObj
->GetDataFieldPositionData(aCellPos
, aFilters
) )
2393 pViewData
->GetView()->ShowDataPilotSourceData( *pDPObj
, aFilters
);
2399 // Check for cell protection attribute.
2400 ScTableProtection
* pProtect
= pDoc
->GetTabProtection( nTab
);
2401 bool bEditAllowed
= true;
2402 if ( pProtect
&& pProtect
->isProtected() )
2404 bool bCellProtected
= pDoc
->HasAttrib(nPosX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_PROTECTED
);
2405 bool bSkipProtected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2406 bool bSkipUnprotected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2408 if ( bSkipProtected
&& bSkipUnprotected
)
2409 bEditAllowed
= false;
2410 else if ( (bCellProtected
&& bSkipProtected
) || (!bCellProtected
&& bSkipUnprotected
) )
2411 bEditAllowed
= false;
2416 // don't forward the event to an empty cell, causes deselection in
2417 // case we used the double-click to select the empty cell
2418 if (bIsTiledRendering
&& bDouble
)
2420 ScRefCellValue aCell
;
2421 aCell
.assign(*pViewData
->GetDocument(), ScAddress(nPosX
, nPosY
, nTab
));
2422 if (aCell
.isEmpty())
2426 // edit cell contents
2427 pViewData
->GetViewShell()->UpdateInputHandler();
2428 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2429 if (pViewData
->HasEditView(eWhich
))
2431 // Text-Cursor gleich an die geklickte Stelle setzen
2432 EditView
* pEditView
= pViewData
->GetEditView( eWhich
);
2433 MouseEvent
aEditEvt( rMEvt
.GetPosPixel(), 1, MouseEventModifiers::SYNTHETIC
, MOUSE_LEFT
, 0 );
2434 pEditView
->MouseButtonDown( aEditEvt
);
2435 pEditView
->MouseButtonUp( aEditEvt
);
2441 // Links in edit cells
2443 bool bAlt
= rMEvt
.IsMod2();
2444 if ( !bAlt
&& !bRefMode
&& !bDouble
&& nMouseStatus
== SC_GM_URLDOWN
)
2446 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2448 OUString aName
, aUrl
, aTarget
;
2449 if ( GetEditUrl( rMEvt
.GetPosPixel(), &aName
, &aUrl
, &aTarget
) )
2451 nMouseStatus
= SC_GM_NONE
; // keinen Doppelklick anfangen
2453 // ScGlobal::OpenURL() only understands Calc A1 style syntax.
2454 // Convert it to Calc A1 before calling OpenURL().
2455 if (pDoc
->GetAddressConvention() == formula::FormulaGrammar::CONV_OOO
)
2456 ScGlobal::OpenURL(aUrl
, aTarget
, pViewData
->GetDocument()->GetDrawLayer());
2459 ScAddress aTempAddr
;
2460 ScAddress::ExternalInfo aExtInfo
;
2461 sal_uInt16 nRes
= aTempAddr
.Parse(aUrl
, pDoc
, pDoc
->GetAddressConvention(), &aExtInfo
);
2462 if (!(nRes
& SCA_VALID
))
2464 // Not a reference string. Pass it through unmodified.
2465 ScGlobal::OpenURL(aUrl
, aTarget
);
2469 OUStringBuffer aBuf
;
2470 if (aExtInfo
.mbExternal
)
2472 // External reference.
2473 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
2474 const OUString
* pStr
= pRefMgr
->getExternalFileName(aExtInfo
.mnFileId
);
2479 aBuf
.append(aExtInfo
.maTabName
);
2481 OUString
aRefCalcA1(aTempAddr
.Format(SCA_ABS
, NULL
, formula::FormulaGrammar::CONV_OOO
));
2482 aBuf
.append(aRefCalcA1
);
2483 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2487 // Internal reference.
2489 OUString
aUrlCalcA1(aTempAddr
.Format(SCA_ABS_3D
, pDoc
, formula::FormulaGrammar::CONV_OOO
));
2490 aBuf
.append(aUrlCalcA1
);
2491 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2495 // fire worksheet_followhyperlink event
2496 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents
= pDoc
->GetVbaEventProcessor();
2497 if( xVbaEvents
.is() ) try
2499 Point aPos
= rMEvt
.GetPosPixel();
2502 SCTAB nTab
= pViewData
->GetTabNo();
2503 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2505 ScRefCellValue aCell
;
2506 if (lcl_GetHyperlinkCell(pDoc
, nPosX
, nPosY
, nTab
, aCell
, sURL
))
2508 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
2509 uno::Reference
< table::XCell
> xCell( new ScCellObj( pViewData
->GetDocShell(), aCellPos
) );
2510 uno::Sequence
< uno::Any
> aArgs(1);
2512 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK
, aArgs
);
2515 catch( uno::Exception
& )
2523 // Gridwin - SelectionEngine
2525 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2526 // sal_True for any call, so IsLeft must be checked here, too.
2528 if ( rMEvt
.IsLeft() && pViewData
->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt
) )
2530 pViewData
->GetView()->SelectionChanged();
2532 SfxDispatcher
* pDisp
= pViewData
->GetViewShell()->GetDispatcher();
2533 bool bFormulaMode
= pScMod
->IsFormulaMode();
2534 OSL_ENSURE( pDisp
|| bFormulaMode
, "Cursor auf nicht aktiver View bewegen ?" );
2536 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2537 // multiple selection, so the argument string completely describes the selection,
2538 // and executing the slot won't change the existing selection (executing the slot
2539 // here and from a recorded macro is treated equally)
2541 if ( pDisp
&& !bFormulaMode
&& !rMark
.IsMultiMarked() )
2543 OUString aAddr
; // CurrentCell
2544 if( rMark
.IsMarked() )
2547 rMark
.GetMarkArea( aScRange
);
2548 aAddr
= aScRange
.Format(SCR_ABS
);
2549 if ( aScRange
.aStart
== aScRange
.aEnd
)
2551 // make sure there is a range selection string even for a single cell
2552 aAddr
= aAddr
+ ":" + aAddr
;
2555 //! SID_MARKAREA gibts nicht mehr ???
2556 //! was passiert beim Markieren mit dem Cursor ???
2558 else // nur Cursor bewegen
2560 ScAddress
aScAddress( pViewData
->GetCurX(), pViewData
->GetCurY(), 0 );
2561 aAddr
= aScAddress
.Format(SCA_ABS
);
2564 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
2565 // We don't want to align to the cursor position because if the
2566 // cell cursor isn't visible after making selection, it would jump
2567 // back to the origin of the selection where the cell cursor is.
2568 SfxBoolItem
aAlignCursorItem( FN_PARAM_2
, false );
2569 pDisp
->Execute( SID_CURRENTCELL
, SfxCallMode::SLOT
| SfxCallMode::RECORD
,
2570 &aPosItem
, &aAlignCursorItem
, (void*)0L );
2572 pViewData
->GetView()->InvalidateAttribs();
2574 pViewData
->GetViewShell()->SelectionChanged();
2579 void ScGridWindow::FakeButtonUp()
2583 MouseEvent
aEvent( aCurMousePos
); // nButtons = 0 -> ignore
2584 MouseButtonUp( aEvent
);
2588 void ScGridWindow::MouseMove( const MouseEvent
& rMEvt
)
2590 aCurMousePos
= rMEvt
.GetPosPixel();
2592 if (rMEvt
.IsLeaveWindow() && mpNoteMarker
&& !mpNoteMarker
->IsByKeyboard())
2595 ScModule
* pScMod
= SC_MOD();
2596 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2599 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2600 // nicht anders mit:
2602 if (bEEMouse
&& nButtonDown
&& !rMEvt
.GetButtons())
2606 nMouseStatus
= SC_GM_NONE
;
2610 if (nMouseStatus
== SC_GM_IGNORE
)
2613 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus -> nur auf Up warten
2616 if ( pViewData
->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2618 SetPointer( Pointer( PointerStyle::Fill
) );
2622 if (nMouseStatus
== SC_GM_FILTER
&& mpFilterBox
)
2624 Point aRelPos
= mpFilterBox
->ScreenToOutputPixel( OutputToScreenPixel( rMEvt
.GetPosPixel() ) );
2625 if ( Rectangle(Point(), mpFilterBox
->GetOutputSizePixel()).IsInside(aRelPos
) )
2628 nMouseStatus
= SC_GM_NONE
;
2630 mpFilterBox
->MouseButtonDown( MouseEvent( aRelPos
, 1, MouseEventModifiers::SIMPLECLICK
, MOUSE_LEFT
) );
2635 bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
2637 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2639 EditView
* pEditView
;
2642 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2643 pEditView
->MouseMove( rMEvt
);
2649 DPMouseMove( rMEvt
);
2655 RFMouseMove( rMEvt
, false );
2659 if (nPagebreakMouse
)
2661 PagebreakMove( rMEvt
, false );
2665 // anderen Mauszeiger anzeigen?
2667 bool bEditMode
= pViewData
->HasEditView(eWhich
);
2669 //! Testen ob RefMode-Dragging !!!
2670 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
2672 Point aPos
= rMEvt
.GetPosPixel();
2675 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2677 EditView
* pEditView
;
2680 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2681 SCCOL nEndCol
= pViewData
->GetEditEndCol();
2682 SCROW nEndRow
= pViewData
->GetEditEndRow();
2684 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
2685 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
2687 // Field can only be URL field
2688 bool bAlt
= rMEvt
.IsMod2();
2689 if ( !bAlt
&& !nButtonDown
&& pEditView
&& pEditView
->GetFieldUnderMousePointer() )
2690 SetPointer( Pointer( PointerStyle::RefHand
) );
2691 else if ( pEditView
&& pEditView
->GetEditEngine()->IsVertical() )
2692 SetPointer( Pointer( PointerStyle::TextVertical
) );
2694 SetPointer( Pointer( PointerStyle::Text
) );
2699 bool bWater
= SC_MOD()->GetIsWaterCan() || pViewData
->GetView()->HasPaintBrush();
2701 SetPointer( Pointer(PointerStyle::Fill
) );
2705 bool bCross
= false;
2709 RfCorner rCorner
= NONE
;
2710 if ( HitRangeFinder( rMEvt
.GetPosPixel(), rCorner
) )
2712 if (rCorner
!= NONE
)
2713 SetPointer( Pointer( PointerStyle::Cross
) );
2715 SetPointer( Pointer( PointerStyle::Hand
) );
2721 sal_uInt16 nBreakType
;
2722 if ( !nButtonDown
&& pViewData
->IsPagebreakMode() &&
2723 ( nBreakType
= HitPageBreak( rMEvt
.GetPosPixel() ) ) != 0 )
2725 PointerStyle eNew
= PointerStyle::Arrow
;
2726 switch ( nBreakType
)
2731 eNew
= PointerStyle::ESize
;
2736 eNew
= PointerStyle::SSize
;
2738 case SC_PD_RANGE_TL
:
2739 case SC_PD_RANGE_BR
:
2740 eNew
= PointerStyle::SESize
;
2742 case SC_PD_RANGE_TR
:
2743 case SC_PD_RANGE_BL
:
2744 eNew
= PointerStyle::NESize
;
2747 SetPointer( Pointer( eNew
) );
2751 // Fill-Cursor anzeigen ?
2753 if ( !bFormulaMode
&& !nButtonDown
)
2754 if (TestMouse( rMEvt
, false ))
2757 if ( nButtonDown
&& pViewData
->IsAnyFillMode() )
2759 SetPointer( Pointer( PointerStyle::Cross
) );
2761 nScFillModeMouseModifier
= rMEvt
.GetModifier(); // ausgewertet bei AutoFill und Matrix
2766 bool bAlt
= rMEvt
.IsMod2();
2768 if (bEditMode
) // Edit-Mode muss zuerst kommen!
2769 SetPointer( Pointer( PointerStyle::Arrow
) );
2770 else if ( !bAlt
&& !nButtonDown
&&
2771 GetEditUrl(rMEvt
.GetPosPixel()) )
2772 SetPointer( Pointer( PointerStyle::RefHand
) );
2773 else if ( DrawMouseMove(rMEvt
) ) // setzt Pointer um
2778 if ( pViewData
->GetView()->GetSelEngine()->SelMouseMove( rMEvt
) )
2782 static void lcl_InitMouseEvent(css::awt::MouseEvent
& rEvent
, const MouseEvent
& rEvt
)
2784 rEvent
.Modifiers
= 0;
2785 if ( rEvt
.IsShift() )
2786 rEvent
.Modifiers
|= css::awt::KeyModifier::SHIFT
;
2787 if ( rEvt
.IsMod1() )
2788 rEvent
.Modifiers
|= css::awt::KeyModifier::MOD1
;
2789 if ( rEvt
.IsMod2() )
2790 rEvent
.Modifiers
|= css::awt::KeyModifier::MOD2
;
2791 if ( rEvt
.IsMod3() )
2792 rEvent
.Modifiers
|= css::awt::KeyModifier::MOD3
;
2795 if ( rEvt
.IsLeft() )
2796 rEvent
.Buttons
|= css::awt::MouseButton::LEFT
;
2797 if ( rEvt
.IsRight() )
2798 rEvent
.Buttons
|= css::awt::MouseButton::RIGHT
;
2799 if ( rEvt
.IsMiddle() )
2800 rEvent
.Buttons
|= css::awt::MouseButton::MIDDLE
;
2802 rEvent
.X
= rEvt
.GetPosPixel().X();
2803 rEvent
.Y
= rEvt
.GetPosPixel().Y();
2804 rEvent
.ClickCount
= rEvt
.GetClicks();
2805 rEvent
.PopupTrigger
= false;
2808 bool ScGridWindow::PreNotify( NotifyEvent
& rNEvt
)
2811 MouseNotifyEvent nType
= rNEvt
.GetType();
2812 if ( nType
== MouseNotifyEvent::MOUSEBUTTONUP
|| nType
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
2814 vcl::Window
* pWindow
= rNEvt
.GetWindow();
2815 if (pWindow
== this && pViewData
)
2817 SfxViewFrame
* pViewFrame
= pViewData
->GetViewShell()->GetViewFrame();
2820 com::sun::star::uno::Reference
<com::sun::star::frame::XController
> xController
= pViewFrame
->GetFrame().GetController();
2821 if (xController
.is())
2823 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
2824 if (pImp
&& pImp
->IsMouseListening())
2826 ::com::sun::star::awt::MouseEvent aEvent
;
2827 lcl_InitMouseEvent( aEvent
, *rNEvt
.GetMouseEvent() );
2828 if ( rNEvt
.GetWindow() )
2829 aEvent
.Source
= rNEvt
.GetWindow()->GetComponentInterface();
2830 if ( nType
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
2831 bDone
= pImp
->MousePressed( aEvent
);
2833 bDone
= pImp
->MouseReleased( aEvent
);
2839 if (bDone
) // event consumed by a listener
2841 if ( nType
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
2843 const MouseEvent
* pMouseEvent
= rNEvt
.GetMouseEvent();
2844 if ( pMouseEvent
->IsRight() && pMouseEvent
->GetClicks() == 1 )
2846 // If a listener returned true for a right-click call, also prevent opening the context menu
2847 // (this works only if the context menu is opened on mouse-down)
2848 nMouseStatus
= SC_GM_IGNORE
;
2855 return Window::PreNotify( rNEvt
);
2858 void ScGridWindow::Tracking( const TrackingEvent
& rTEvt
)
2860 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2861 // die verschiedenen MouseHandler verteilen...
2863 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
2865 if ( rTEvt
.IsTrackingCanceled() ) // alles abbrechen...
2867 if (!pViewData
->GetView()->IsInActivatePart() && !SC_MOD()->IsRefDialogOpen())
2870 bDPMouse
= false; // gezeichnet wird per bDragRect
2873 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2875 UpdateDragRectOverlay();
2879 RFMouseMove( rMEvt
, true ); // richtig abbrechen geht dabei nicht...
2882 if (nPagebreakMouse
)
2884 // if (bPagebreakDrawn)
2885 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2886 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
2887 bPagebreakDrawn
= false;
2888 UpdateDragRectOverlay();
2889 nPagebreakMouse
= SC_PD_NONE
;
2892 SetPointer( Pointer( PointerStyle::Arrow
) );
2894 MouseButtonUp( rMEvt
); // mit Status SC_GM_IGNORE aus StopMarking
2896 bool bRefMode
= pViewData
->IsRefMode();
2898 SC_MOD()->EndReference(); // Dialog nicht verkleinert lassen
2901 else if ( rTEvt
.IsTrackingEnded() )
2903 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2904 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2905 // abgebrochen wurde.
2907 MouseEvent
aUpEvt( rMEvt
.GetPosPixel(), rMEvt
.GetClicks(),
2908 rMEvt
.GetMode(), nButtonDown
, rMEvt
.GetModifier() );
2909 MouseButtonUp( aUpEvt
);
2915 void ScGridWindow::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
2917 if (mpFilterBox
|| nPagebreakMouse
)
2922 CommandEvent
aDragEvent( rPosPixel
, CommandEventId::StartDrag
, true );
2924 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2926 EditView
* pEditView
;
2929 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2931 // don't remove the edit view while switching views
2932 ScModule
* pScMod
= SC_MOD();
2933 pScMod
->SetInEditCommand( true );
2935 pEditView
->Command( aDragEvent
);
2937 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2939 pHdl
->DataChanged();
2941 pScMod
->SetInEditCommand( false );
2942 if (!pViewData
->IsActive()) // dropped to different view?
2944 ScInputHandler
* pViewHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2945 if ( pViewHdl
&& pViewData
->HasEditView( eWhich
) )
2947 pViewHdl
->CancelHandler();
2948 ShowCursor(); // missing from KillEditView
2953 if ( !DrawCommand(aDragEvent
) )
2954 pViewData
->GetView()->GetSelEngine()->Command( aDragEvent
);
2957 static void lcl_SetTextCursorPos( ScViewData
* pViewData
, ScSplitPos eWhich
, vcl::Window
* pWin
)
2959 SCCOL nCol
= pViewData
->GetCurX();
2960 SCROW nRow
= pViewData
->GetCurY();
2961 Rectangle aEditArea
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, pWin
, NULL
, true );
2962 aEditArea
.Right() = aEditArea
.Left();
2963 aEditArea
= pWin
->PixelToLogic( aEditArea
);
2964 pWin
->SetCursorRect( &aEditArea
);
2967 void ScGridWindow::Command( const CommandEvent
& rCEvt
)
2969 // The command event is send to the window after a possible context
2970 // menu from an inplace client is closed. Now we have the chance to
2971 // deactivate the inplace client without any problem regarding parent
2972 // windows and code on the stack.
2973 CommandEventId nCmd
= rCEvt
.GetCommand();
2974 ScTabViewShell
* pTabViewSh
= pViewData
->GetViewShell();
2975 SfxInPlaceClient
* pClient
= pTabViewSh
->GetIPClient();
2977 pClient
->IsObjectInPlaceActive() &&
2978 nCmd
== CommandEventId::ContextMenu
)
2980 pTabViewSh
->DeactivateOle();
2984 ScModule
* pScMod
= SC_MOD();
2985 OSL_ENSURE( nCmd
!= CommandEventId::StartDrag
, "ScGridWindow::Command called with CommandEventId::StartDrag" );
2987 if ( nCmd
== CommandEventId::StartExtTextInput
||
2988 nCmd
== CommandEventId::EndExtTextInput
||
2989 nCmd
== CommandEventId::ExtTextInput
||
2990 nCmd
== CommandEventId::CursorPos
||
2991 nCmd
== CommandEventId::QueryCharPosition
)
2993 bool bEditView
= pViewData
->HasEditView( eWhich
);
2996 // only if no cell editview is active, look at drawview
2997 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
3000 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
3001 if ( pOlView
&& pOlView
->GetWindow() == this )
3003 pOlView
->Command( rCEvt
);
3009 if ( nCmd
== CommandEventId::CursorPos
&& !bEditView
)
3011 // CURSORPOS may be called without following text input,
3012 // to set the input method window position
3013 // -> input mode must not be started,
3014 // manually calculate text insert position if not in input mode
3016 lcl_SetTextCursorPos( pViewData
, eWhich
, this );
3020 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
3023 pHdl
->InputCommand( rCEvt
, true );
3027 Window::Command( rCEvt
);
3031 if ( nCmd
== CommandEventId::PasteSelection
)
3035 // EditEngine handles selection in MouseButtonUp - no action
3036 // needed in command handler
3040 PasteSelection( rCEvt
.GetMousePosPixel() );
3045 if ( nCmd
== CommandEventId::InputLanguageChange
)
3047 // #i55929# Font and font size state depends on input language if nothing is selected,
3048 // so the slots have to be invalidated when the input language is changed.
3050 SfxBindings
& rBindings
= pViewData
->GetBindings();
3051 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
3052 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
3056 if ( nCmd
== CommandEventId::Wheel
|| nCmd
== CommandEventId::StartAutoScroll
|| nCmd
== CommandEventId::AutoScroll
)
3058 bool bDone
= pViewData
->GetView()->ScrollCommand( rCEvt
, eWhich
);
3060 Window::Command(rCEvt
);
3063 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
3064 bool bDisable
= pScMod
->IsFormulaMode() ||
3065 pScMod
->IsModalMode(pViewData
->GetSfxDocShell());
3069 if ( nCmd
== CommandEventId::ContextMenu
&& !SC_MOD()->GetIsWaterCan() )
3071 bool bMouse
= rCEvt
.IsMouseEvent();
3072 if ( bMouse
&& nMouseStatus
== SC_GM_IGNORE
)
3075 if (pViewData
->IsAnyFillMode())
3077 pViewData
->GetView()->StopRefMode();
3078 pViewData
->ResetFillMode();
3083 Point aPosPixel
= rCEvt
.GetMousePosPixel();
3084 Point aMenuPos
= aPosPixel
;
3088 pViewData
->GetPosFromPixel(aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nCellX
, nCellY
);
3090 bool bSpellError
= false;
3091 SCCOL nColSpellError
= nCellX
;
3092 ScRefCellValue aSpellCheckCell
;
3096 ScDocument
* pDoc
= pViewData
->GetDocument();
3097 SCTAB nTab
= pViewData
->GetTabNo();
3098 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
3099 bool bSelectAllowed
= true;
3100 if ( pProtect
&& pProtect
->isProtected() )
3102 // This sheet is protected. Check if a context menu is allowed on this cell.
3103 bool bCellProtected
= pDoc
->HasAttrib(nCellX
, nCellY
, nTab
, nCellX
, nCellY
, nTab
, HASATTR_PROTECTED
);
3104 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
3105 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
3108 bSelectAllowed
= bSelProtected
;
3110 bSelectAllowed
= bSelUnprotected
;
3112 if (!bSelectAllowed
)
3113 // Selecting this cell is not allowed, neither is context menu.
3116 if (mpSpellCheckCxt
)
3118 // Find the first string to the left for spell checking in case the current cell is empty.
3119 ScAddress
aPos(nCellX
, nCellY
, nTab
);
3120 aSpellCheckCell
.assign(*pDoc
, aPos
);
3121 while (aSpellCheckCell
.meType
== CELLTYPE_NONE
)
3123 // Loop until we get the first non-empty cell in the row.
3128 aSpellCheckCell
.assign(*pDoc
, aPos
);
3131 if (aPos
.Col() >= 0 && (aSpellCheckCell
.meType
== CELLTYPE_STRING
|| aSpellCheckCell
.meType
== CELLTYPE_EDIT
))
3132 nColSpellError
= aPos
.Col();
3134 bSpellError
= (mpSpellCheckCxt
->isMisspelled(nColSpellError
, nCellY
));
3137 // Check and see if a misspelled word is under the mouse pointer.
3138 bSpellError
= IsSpellErrorAtPos(aPosPixel
, nColSpellError
, nCellY
);
3142 // #i18735# First select the item under the mouse pointer.
3143 // This can change the selection, and the view state (edit mode, etc).
3144 SelectForContextMenu(aPosPixel
, bSpellError
? nColSpellError
: nCellX
, nCellY
);
3148 bool bEdit
= pViewData
->HasEditView(eWhich
);
3152 // Edit-Zelle mit Spelling-Errors ?
3153 if (bMouse
&& (GetEditUrl(aPosPixel
) || bSpellError
))
3155 // GetEditUrlOrError hat den Cursor schon bewegt
3157 pScMod
->SetInputMode( SC_INPUT_TABLE
);
3158 bEdit
= pViewData
->HasEditView(eWhich
); // hat's geklappt ?
3160 OSL_ENSURE( bEdit
, "kann nicht in Edit-Modus schalten" );
3165 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
3169 vcl::Cursor
* pCur
= pEditView
->GetCursor();
3172 Point aLogicPos
= pCur
->GetPos();
3173 // use the position right of the cursor (spell popup is opened if
3174 // the cursor is before the word, but not if behind it)
3175 aLogicPos
.X() += pCur
->GetWidth();
3176 aLogicPos
.Y() += pCur
->GetHeight() / 2; // center vertically
3177 aMenuPos
= LogicToPixel( aLogicPos
);
3181 // if edit mode was just started above, online spelling may be incomplete
3182 pEditView
->GetEditEngine()->CompleteOnlineSpelling();
3184 // IsCursorAtWrongSpelledWord could be used for !bMouse
3185 // if there was a corresponding ExecuteSpellPopup call
3189 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
3190 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
3192 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
3194 pHdl
->SetModified();
3196 Link
<> aLink
= LINK( this, ScGridWindow
, PopupSpellingHdl
);
3197 pEditView
->ExecuteSpellPopup( aMenuPos
, &aLink
);
3204 // non-edit menu by keyboard -> use lower right of cell cursor position
3205 ScDocument
* aDoc
= pViewData
->GetDocument();
3206 SCTAB nTabNo
= pViewData
->GetTabNo();
3207 bool bLayoutIsRTL
= aDoc
->IsLayoutRTL(nTabNo
);
3209 SCCOL nCurX
= pViewData
->GetCurX();
3210 SCROW nCurY
= pViewData
->GetCurY();
3211 aMenuPos
= pViewData
->GetScrPos( nCurX
, nCurY
, eWhich
, true );
3214 pViewData
->GetMergeSizePixel( nCurX
, nCurY
, nSizeXPix
, nSizeYPix
);
3215 // fdo#55432 take the correct position for RTL sheet
3216 aMenuPos
.X() += bLayoutIsRTL
? -nSizeXPix
: nSizeXPix
;
3217 aMenuPos
.Y() += nSizeYPix
;
3219 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3222 // Is a draw object selected?
3224 SdrView
* pDrawView
= pViewSh
->GetSdrView();
3225 if (pDrawView
&& pDrawView
->AreObjectsMarked())
3227 // #100442#; the conext menu should open in the middle of the selected objects
3228 Rectangle
aSelectRect(LogicToPixel(pDrawView
->GetAllMarkedBoundRect()));
3229 aMenuPos
= aSelectRect
.Center();
3236 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos
);
3241 void ScGridWindow::SelectForContextMenu( const Point
& rPosPixel
, SCsCOL nCellX
, SCsROW nCellY
)
3243 // #i18735# if the click was outside of the current selection,
3244 // the cursor is moved or an object at the click position selected.
3245 // (see SwEditWin::SelectMenuPosition in Writer)
3247 ScTabView
* pView
= pViewData
->GetView();
3248 ScDrawView
* pDrawView
= pView
->GetScDrawView();
3250 // check cell edit mode
3252 if ( pViewData
->HasEditView(eWhich
) )
3254 ScModule
* pScMod
= SC_MOD();
3255 SCCOL nEditStartCol
= pViewData
->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
3256 SCROW nEditStartRow
= pViewData
->GetEditViewRow();
3257 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
3258 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
3260 if ( nCellX
>= (SCsCOL
) nEditStartCol
&& nCellX
<= (SCsCOL
) nEditEndCol
&&
3261 nCellY
>= (SCsROW
) nEditStartRow
&& nCellY
<= (SCsROW
) nEditEndRow
)
3263 // handle selection within the EditView
3265 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // not NULL (HasEditView)
3266 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
3267 Rectangle aOutputArea
= pEditView
->GetOutputArea();
3268 Rectangle aVisArea
= pEditView
->GetVisArea();
3270 Point aTextPos
= PixelToLogic( rPosPixel
);
3271 if ( pEditEngine
->IsVertical() ) // have to manually transform position
3273 aTextPos
-= aOutputArea
.TopRight();
3274 long nTemp
= -aTextPos
.X();
3275 aTextPos
.X() = aTextPos
.Y();
3276 aTextPos
.Y() = nTemp
;
3279 aTextPos
-= aOutputArea
.TopLeft();
3280 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3282 EPosition aDocPosition
= pEditEngine
->FindDocPosition(aTextPos
);
3283 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3284 ESelection aSelection
= pEditView
->GetSelection();
3285 aSelection
.Adjust(); // needed for IsLess/IsGreater
3286 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3288 // clicked outside the selected text - deselect and move text cursor
3289 MouseEvent
aEvent( rPosPixel
);
3290 pEditView
->MouseButtonDown( aEvent
);
3291 pEditView
->MouseButtonUp( aEvent
);
3292 pScMod
->InputSelection( pEditView
);
3295 return; // clicked within the edit view - keep edit mode
3299 // outside of the edit view - end edit mode, regardless of cell selection, then continue
3300 pScMod
->InputEnterHandler();
3304 // check draw text edit mode
3306 Point aLogicPos
= PixelToLogic( rPosPixel
); // after cell edit mode is ended
3307 if ( pDrawView
&& pDrawView
->GetTextEditObject() && pDrawView
->GetTextEditOutlinerView() )
3309 OutlinerView
* pOlView
= pDrawView
->GetTextEditOutlinerView();
3310 Rectangle aOutputArea
= pOlView
->GetOutputArea();
3311 if ( aOutputArea
.IsInside( aLogicPos
) )
3313 // handle selection within the OutlinerView
3315 Outliner
* pOutliner
= pOlView
->GetOutliner();
3316 const EditEngine
& rEditEngine
= pOutliner
->GetEditEngine();
3317 Rectangle aVisArea
= pOlView
->GetVisArea();
3319 Point aTextPos
= aLogicPos
;
3320 if ( pOutliner
->IsVertical() ) // have to manually transform position
3322 aTextPos
-= aOutputArea
.TopRight();
3323 long nTemp
= -aTextPos
.X();
3324 aTextPos
.X() = aTextPos
.Y();
3325 aTextPos
.Y() = nTemp
;
3328 aTextPos
-= aOutputArea
.TopLeft();
3329 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3331 EPosition aDocPosition
= rEditEngine
.FindDocPosition(aTextPos
);
3332 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3333 ESelection aSelection
= pOlView
->GetSelection();
3334 aSelection
.Adjust(); // needed for IsLess/IsGreater
3335 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3337 // clicked outside the selected text - deselect and move text cursor
3338 // use DrawView to allow extra handling there (none currently)
3339 MouseEvent
aEvent( rPosPixel
);
3340 pDrawView
->MouseButtonDown( aEvent
, this );
3341 pDrawView
->MouseButtonUp( aEvent
, this );
3344 return; // clicked within the edit area - keep edit mode
3348 // Outside of the edit area - end text edit mode, then continue.
3349 // DrawDeselectAll also ends text edit mode and updates the shells.
3350 // If the click was on the edited object, it will be selected again below.
3351 pView
->DrawDeselectAll();
3355 // look for existing selection
3357 bool bHitSelected
= false;
3358 if ( pDrawView
&& pDrawView
->IsMarkedObjHit( aLogicPos
) )
3360 // clicked on selected object -> don't change anything
3361 bHitSelected
= true;
3363 else if ( pViewData
->GetMarkData().IsCellMarked(nCellX
, nCellY
) )
3365 // clicked on selected cell -> don't change anything
3366 bHitSelected
= true;
3369 // select drawing object or move cell cursor
3371 if ( !bHitSelected
)
3373 bool bWasDraw
= ( pDrawView
&& pDrawView
->AreObjectsMarked() );
3374 bool bHitDraw
= false;
3377 pDrawView
->UnmarkAllObj();
3378 // Unlock the Internal Layer in order to activate the context menu.
3379 // re-lock in ScDrawView::MarkListHasChanged()
3380 lcl_UnLockComment( pDrawView
, aLogicPos
,pViewData
);
3381 bHitDraw
= pDrawView
->MarkObj( aLogicPos
);
3382 // draw shell is activated in MarkListHasChanged
3387 pView
->SetCursor(nCellX
, nCellY
);
3389 pViewData
->GetViewShell()->SetDrawShell( false ); // switch shells
3394 void ScGridWindow::KeyInput(const KeyEvent
& rKEvt
)
3396 // Cursor control for ref input dialog
3397 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
3398 if( SC_MOD()->IsRefDialogOpen() )
3400 if( !rKeyCode
.GetModifier() && (rKeyCode
.GetCode() == KEY_F2
) )
3402 SC_MOD()->EndReference();
3404 else if( pViewData
->GetViewShell()->MoveCursorKeyInput( rKEvt
) )
3407 pViewData
->GetRefStartX(), pViewData
->GetRefStartY(), pViewData
->GetRefStartZ(),
3408 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(), pViewData
->GetRefEndZ() );
3409 SC_MOD()->SetReference( aRef
, pViewData
->GetDocument() );
3411 pViewData
->GetViewShell()->SelectionChanged();
3414 else if( rKeyCode
.GetCode() == KEY_RETURN
&& pViewData
->IsPasteMode() )
3416 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
3417 ScClipUtil::PasteFromClipboard( pViewData
, pTabViewShell
, false );
3419 // Clear clipboard content.
3420 uno::Reference
<datatransfer::clipboard::XClipboard
> xSystemClipboard
=
3421 TransferableHelper::GetSystemClipboard();
3422 if (xSystemClipboard
.is())
3424 xSystemClipboard
->setContents(
3425 uno::Reference
<datatransfer::XTransferable
>(),
3426 uno::Reference
<datatransfer::clipboard::XClipboardOwner
>());
3429 // hide the border around the copy source
3430 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3431 // Clear CopySourceOverlay in each window of a split/frozen tabview
3432 pViewData
->GetView()->UpdateCopySourceOverlay();
3435 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3436 else if( !pViewData
->IsAnyFillMode() )
3438 if (rKeyCode
.GetCode() == KEY_ESCAPE
)
3440 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3441 // Clear CopySourceOverlay in each window of a split/frozen tabview
3442 pViewData
->GetView()->UpdateCopySourceOverlay();
3444 // query for existing note marker before calling ViewShell's keyboard handling
3445 // which may remove the marker
3446 bool bHadKeyMarker
= mpNoteMarker
&& mpNoteMarker
->IsByKeyboard();
3447 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3449 if (pViewData
->GetDocShell()->GetProgress())
3452 if (DrawKeyInput(rKEvt
))
3454 const vcl::KeyCode
& rLclKeyCode
= rKEvt
.GetKeyCode();
3455 if (rLclKeyCode
.GetCode() == KEY_DOWN
3456 || rLclKeyCode
.GetCode() == KEY_UP
3457 || rLclKeyCode
.GetCode() == KEY_LEFT
3458 || rLclKeyCode
.GetCode() == KEY_RIGHT
)
3460 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
3461 SfxBindings
& rBindings
= pViewShell
->GetViewFrame()->GetBindings();
3462 rBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_X
);
3463 rBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_Y
);
3468 if (!pViewData
->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3469 { //! DrawShell abfragen !!!
3470 if (pViewSh
->TabKeyInput(rKEvt
))
3474 if (pViewSh
->SfxViewShell::KeyInput(rKEvt
)) // von SfxViewShell
3477 vcl::KeyCode aCode
= rKEvt
.GetKeyCode();
3478 if ( aCode
.GetCode() == KEY_ESCAPE
&& aCode
.GetModifier() == 0 )
3480 if ( bHadKeyMarker
)
3486 if ( aCode
.GetCode() == KEY_F1
&& aCode
.GetModifier() == KEY_MOD1
)
3488 // ctrl-F1 shows or hides the note or redlining info for the cursor position
3489 // (hard-coded because F1 can't be configured)
3491 if ( bHadKeyMarker
)
3492 HideNoteMarker(); // hide when previously visible
3494 ShowNoteMarker( pViewData
->GetCurX(), pViewData
->GetCurY(), true );
3497 if (aCode
.GetCode() == KEY_BRACKETLEFT
&& aCode
.GetModifier() == KEY_MOD1
)
3499 pViewSh
->DetectiveMarkPred();
3502 if (aCode
.GetCode() == KEY_BRACKETRIGHT
&& aCode
.GetModifier() == KEY_MOD1
)
3504 pViewSh
->DetectiveMarkSucc();
3510 Window::KeyInput(rKEvt
);
3513 void ScGridWindow::StopMarking()
3515 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3519 pViewData
->GetMarkData().SetMarking(false);
3520 nMouseStatus
= SC_GM_IGNORE
;
3524 void ScGridWindow::UpdateInputContext()
3526 bool bReadOnly
= pViewData
->GetDocShell()->IsReadOnly();
3527 InputContextFlags nOptions
= bReadOnly
? InputContextFlags::NONE
: ( InputContextFlags::Text
| InputContextFlags::ExtText
);
3529 // when font from InputContext is used,
3530 // it must be taken from the cursor position's cell attributes
3532 InputContext aContext
;
3533 aContext
.SetOptions( nOptions
);
3534 SetInputContext( aContext
);
3537 // sensitiver Bereich (Pixel)
3538 #define SCROLL_SENSITIVE 20
3540 bool ScGridWindow::DropScroll( const Point
& rMousePos
)
3544 Size aSize
= GetOutputSizePixel();
3546 if (aSize
.Width() > SCROLL_SENSITIVE
* 3)
3548 if ( rMousePos
.X() < SCROLL_SENSITIVE
&& pViewData
->GetPosX(WhichH(eWhich
)) > 0 )
3550 if ( rMousePos
.X() >= aSize
.Width() - SCROLL_SENSITIVE
3551 && pViewData
->GetPosX(WhichH(eWhich
)) < MAXCOL
)
3554 if (aSize
.Height() > SCROLL_SENSITIVE
* 3)
3556 if ( rMousePos
.Y() < SCROLL_SENSITIVE
&& pViewData
->GetPosY(WhichV(eWhich
)) > 0 )
3558 if ( rMousePos
.Y() >= aSize
.Height() - SCROLL_SENSITIVE
3559 && pViewData
->GetPosY(WhichV(eWhich
)) < MAXROW
)
3563 if ( nDx
!= 0 || nDy
!= 0 )
3566 pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
3568 pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
3574 static bool lcl_TestScenarioRedliningDrop( ScDocument
* pDoc
, const ScRange
& aDragRange
)
3576 // Testet, ob bei eingeschalteten RedLining,
3577 // bei einem Drop ein Scenario betroffen ist.
3579 bool bReturn
= false;
3580 SCTAB nTab
= aDragRange
.aStart
.Tab();
3581 SCTAB nTabCount
= pDoc
->GetTableCount();
3583 if(pDoc
->GetChangeTrack()!=NULL
)
3585 if( pDoc
->IsScenario(nTab
) && pDoc
->HasScenarioRange(nTab
, aDragRange
))
3591 for(SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
3593 if(pDoc
->HasScenarioRange(i
, aDragRange
))
3604 static ScRange
lcl_MakeDropRange( SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
, const ScRange
& rSource
)
3606 SCCOL nCol1
= nPosX
;
3607 SCCOL nCol2
= nCol1
+ ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
3608 if ( nCol2
> MAXCOL
)
3610 nCol1
-= nCol2
- MAXCOL
;
3613 SCROW nRow1
= nPosY
;
3614 SCROW nRow2
= nRow1
+ ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
3615 if ( nRow2
> MAXROW
)
3617 nRow1
-= nRow2
- MAXROW
;
3621 return ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
3624 extern bool bPasteIsDrop
; // viewfun4 -> move to header
3625 extern bool bPasteIsMove
; // viewfun7 -> move to header
3627 sal_Int8
ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent
& rEvt
)
3629 if ( rEvt
.mbLeaving
)
3632 UpdateDragRectOverlay();
3633 return rEvt
.mnAction
;
3636 const ScDragData
& rData
= SC_MOD()->GetDragData();
3637 if ( rData
.pCellTransfer
)
3639 // Don't move source that would include filtered rows.
3640 if ((rEvt
.mnAction
& DND_ACTION_MOVE
) && rData
.pCellTransfer
->HasFilteredRows())
3645 UpdateDragRectOverlay();
3647 return DND_ACTION_NONE
;
3650 Point aPos
= rEvt
.maPosPixel
;
3652 ScDocument
* pSourceDoc
= rData
.pCellTransfer
->GetSourceDocument();
3653 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3654 if (pSourceDoc
== pThisDoc
)
3657 if ( pThisDoc
->HasChartAtPoint(pViewData
->GetTabNo(), PixelToLogic(aPos
), aName
))
3659 if (bDragRect
) // Rechteck loeschen
3662 UpdateDragRectOverlay();
3665 //! highlight chart? (selection border?)
3667 sal_Int8 nRet
= rEvt
.mnAction
;
3672 if ( rData
.pCellTransfer
->GetDragSourceFlags() & SC_DROP_TABLE
) // whole sheet?
3674 bool bOk
= pThisDoc
->IsDocEditable();
3675 return bOk
? rEvt
.mnAction
: 0; // don't draw selection frame
3680 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3682 ScRange aSourceRange
= rData
.pCellTransfer
->GetRange();
3683 SCCOL nSourceStartX
= aSourceRange
.aStart
.Col();
3684 SCROW nSourceStartY
= aSourceRange
.aStart
.Row();
3685 SCCOL nSourceEndX
= aSourceRange
.aEnd
.Col();
3686 SCROW nSourceEndY
= aSourceRange
.aEnd
.Row();
3687 SCCOL nSizeX
= nSourceEndX
- nSourceStartX
+ 1;
3688 SCROW nSizeY
= nSourceEndY
- nSourceStartY
+ 1;
3690 if ( rEvt
.mnAction
!= DND_ACTION_MOVE
)
3691 nSizeY
= rData
.pCellTransfer
->GetNonFilteredRows(); // copy/link: no filtered rows
3693 SCsCOL nNewDragX
= nPosX
- rData
.pCellTransfer
->GetDragHandleX();
3694 if (nNewDragX
<0) nNewDragX
=0;
3695 if (nNewDragX
+(nSizeX
-1) > MAXCOL
)
3696 nNewDragX
= MAXCOL
-(nSizeX
-1);
3697 SCsROW nNewDragY
= nPosY
- rData
.pCellTransfer
->GetDragHandleY();
3698 if (nNewDragY
<0) nNewDragY
=0;
3699 if (nNewDragY
+(nSizeY
-1) > MAXROW
)
3700 nNewDragY
= MAXROW
-(nSizeY
-1);
3702 // don't break scenario ranges, don't drop on filtered
3703 SCTAB nTab
= pViewData
->GetTabNo();
3704 ScRange aDropRange
= lcl_MakeDropRange( nNewDragX
, nNewDragY
, nTab
, aSourceRange
);
3705 if ( lcl_TestScenarioRedliningDrop( pThisDoc
, aDropRange
) ||
3706 lcl_TestScenarioRedliningDrop( pSourceDoc
, aSourceRange
) ||
3707 ScViewUtil::HasFiltered( aDropRange
, pThisDoc
) )
3712 UpdateDragRectOverlay();
3714 return DND_ACTION_NONE
;
3717 InsCellCmd eDragInsertMode
= INS_NONE
;
3718 Window::PointerState aState
= GetPointerState();
3720 // check for datapilot item sorting
3721 ScDPObject
* pDPObj
= NULL
;
3722 if ( pThisDoc
== pSourceDoc
&& ( pDPObj
= pThisDoc
->GetDPAtCursor( nNewDragX
, nNewDragY
, nTab
) ) != NULL
)
3724 // drop on DataPilot table: sort or nothing
3726 bool bDPSort
= false;
3727 if ( pThisDoc
->GetDPAtCursor( nSourceStartX
, nSourceStartY
, aSourceRange
.aStart
.Tab() ) == pDPObj
)
3729 sheet::DataPilotTableHeaderData aDestData
;
3730 pDPObj
->GetHeaderPositionData( ScAddress(nNewDragX
, nNewDragY
, nTab
), aDestData
);
3731 bool bValid
= ( aDestData
.Dimension
>= 0 ); // dropping onto a field
3733 // look through the source range
3734 for (SCROW nRow
= aSourceRange
.aStart
.Row(); bValid
&& nRow
<= aSourceRange
.aEnd
.Row(); ++nRow
)
3735 for (SCCOL nCol
= aSourceRange
.aStart
.Col(); bValid
&& nCol
<= aSourceRange
.aEnd
.Col(); ++nCol
)
3737 sheet::DataPilotTableHeaderData aSourceData
;
3738 pDPObj
->GetHeaderPositionData( ScAddress( nCol
, nRow
, aSourceRange
.aStart
.Tab() ), aSourceData
);
3739 if ( aSourceData
.Dimension
!= aDestData
.Dimension
|| aSourceData
.MemberName
.isEmpty() )
3740 bValid
= false; // empty (subtotal) or different field
3746 OUString aDimName
= pDPObj
->GetDimName( aDestData
.Dimension
, bIsDataLayout
);
3747 const ScDPSaveDimension
* pDim
= pDPObj
->GetSaveData()->GetExistingDimensionByName( aDimName
);
3750 ScRange aOutRange
= pDPObj
->GetOutRange();
3752 sal_uInt16 nOrient
= pDim
->GetOrientation();
3753 if ( nOrient
== sheet::DataPilotFieldOrientation_COLUMN
)
3755 eDragInsertMode
= INS_CELLSRIGHT
;
3756 nSizeY
= aOutRange
.aEnd
.Row() - nNewDragY
+ 1;
3759 else if ( nOrient
== sheet::DataPilotFieldOrientation_ROW
)
3761 eDragInsertMode
= INS_CELLSDOWN
;
3762 nSizeX
= aOutRange
.aEnd
.Col() - nNewDragX
+ 1;
3771 // no valid sorting in a DataPilot table -> disallow
3775 UpdateDragRectOverlay();
3777 return DND_ACTION_NONE
;
3780 else if ( aState
.mnState
& KEY_MOD2
)
3782 if ( pThisDoc
== pSourceDoc
&& nTab
== aSourceRange
.aStart
.Tab() )
3784 long nDeltaX
= labs( static_cast< long >( nNewDragX
- nSourceStartX
) );
3785 long nDeltaY
= labs( static_cast< long >( nNewDragY
- nSourceStartY
) );
3786 if ( nDeltaX
<= nDeltaY
)
3788 eDragInsertMode
= INS_CELLSDOWN
;
3792 eDragInsertMode
= INS_CELLSRIGHT
;
3795 if ( ( eDragInsertMode
== INS_CELLSDOWN
&& nNewDragY
<= nSourceEndY
&&
3796 ( nNewDragX
+ nSizeX
- 1 ) >= nSourceStartX
&& nNewDragX
<= nSourceEndX
&&
3797 ( nNewDragX
!= nSourceStartX
|| nNewDragY
>= nSourceStartY
) ) ||
3798 ( eDragInsertMode
== INS_CELLSRIGHT
&& nNewDragX
<= nSourceEndX
&&
3799 ( nNewDragY
+ nSizeY
- 1 ) >= nSourceStartY
&& nNewDragY
<= nSourceEndY
&&
3800 ( nNewDragY
!= nSourceStartY
|| nNewDragX
>= nSourceStartX
) ) )
3805 UpdateDragRectOverlay();
3807 return DND_ACTION_NONE
;
3812 if ( static_cast< long >( nSizeX
) >= static_cast< long >( nSizeY
) )
3814 eDragInsertMode
= INS_CELLSDOWN
;
3819 eDragInsertMode
= INS_CELLSRIGHT
;
3824 if ( nNewDragX
!= (SCsCOL
) nDragStartX
|| nNewDragY
!= (SCsROW
) nDragStartY
||
3825 nDragStartX
+nSizeX
-1 != nDragEndX
|| nDragStartY
+nSizeY
-1 != nDragEndY
||
3826 !bDragRect
|| eDragInsertMode
!= meDragInsertMode
)
3828 nDragStartX
= nNewDragX
;
3829 nDragStartY
= nNewDragY
;
3830 nDragEndX
= nDragStartX
+nSizeX
-1;
3831 nDragEndY
= nDragStartY
+nSizeY
-1;
3833 meDragInsertMode
= eDragInsertMode
;
3835 UpdateDragRectOverlay();
3839 return rEvt
.mnAction
;
3842 sal_Int8
ScGridWindow::AcceptDrop( const AcceptDropEvent
& rEvt
)
3844 const ScDragData
& rData
= SC_MOD()->GetDragData();
3845 if ( rEvt
.mbLeaving
)
3847 DrawMarkDropObj( NULL
);
3848 if ( rData
.pCellTransfer
)
3849 return AcceptPrivateDrop( rEvt
); // hide drop marker for internal D&D
3851 return rEvt
.mnAction
;
3854 if ( pViewData
->GetDocShell()->IsReadOnly() )
3855 return DND_ACTION_NONE
;
3857 sal_Int8 nRet
= DND_ACTION_NONE
;
3859 if (rData
.pCellTransfer
)
3861 ScRange aSource
= rData
.pCellTransfer
->GetRange();
3862 if ( aSource
.aStart
.Col() != 0 || aSource
.aEnd
.Col() != MAXCOL
||
3863 aSource
.aStart
.Row() != 0 || aSource
.aEnd
.Row() != MAXROW
)
3864 DropScroll( rEvt
.maPosPixel
);
3866 nRet
= AcceptPrivateDrop( rEvt
);
3870 if ( !rData
.aLinkDoc
.isEmpty() )
3873 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3874 if (pDocSh
&& pDocSh
->HasName())
3875 aThisName
= pDocSh
->GetMedium()->GetName();
3877 if ( !rData
.aLinkDoc
.equals(aThisName
) )
3878 nRet
= rEvt
.mnAction
;
3880 else if (!rData
.aJumpTarget
.isEmpty())
3882 // internal bookmarks (from Navigator)
3883 // local jumps from an unnamed document are possible only within a document
3885 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
3886 nRet
= rEvt
.mnAction
;
3890 sal_Int8 nMyAction
= rEvt
.mnAction
;
3892 // clear DND_ACTION_LINK when other actions are set. The usage below cannot handle
3893 // multiple set values
3894 if((nMyAction
& DND_ACTION_LINK
) && (nMyAction
& (DND_ACTION_COPYMOVE
)))
3896 nMyAction
&= ~DND_ACTION_LINK
;
3899 if ( !rData
.pDrawTransfer
||
3900 !IsMyModel(rData
.pDrawTransfer
->GetDragSourceView()) ) // drawing within the document
3901 if ( rEvt
.mbDefault
&& nMyAction
== DND_ACTION_MOVE
)
3902 nMyAction
= DND_ACTION_COPY
;
3904 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3905 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint(
3906 pViewData
->GetTabNo(), PixelToLogic(rEvt
.maPosPixel
) );
3907 if ( pHitObj
&& nMyAction
== DND_ACTION_LINK
) // && !rData.pDrawTransfer )
3909 if ( IsDropFormatSupported(SotClipboardFormatId::SVXB
)
3910 || IsDropFormatSupported(SotClipboardFormatId::GDIMETAFILE
)
3911 || IsDropFormatSupported(SotClipboardFormatId::PNG
)
3912 || IsDropFormatSupported(SotClipboardFormatId::BITMAP
) )
3914 // graphic dragged onto drawing object
3915 DrawMarkDropObj( pHitObj
);
3920 DrawMarkDropObj( NULL
);
3924 switch ( nMyAction
)
3926 case DND_ACTION_COPY
:
3927 case DND_ACTION_MOVE
:
3928 case DND_ACTION_COPYMOVE
:
3930 bool bMove
= ( nMyAction
== DND_ACTION_MOVE
);
3931 if ( IsDropFormatSupported( SotClipboardFormatId::EMBED_SOURCE
) ||
3932 IsDropFormatSupported( SotClipboardFormatId::LINK_SOURCE
) ||
3933 IsDropFormatSupported( SotClipboardFormatId::EMBED_SOURCE_OLE
) ||
3934 IsDropFormatSupported( SotClipboardFormatId::LINK_SOURCE_OLE
) ||
3935 IsDropFormatSupported( SotClipboardFormatId::EMBEDDED_OBJ_OLE
) ||
3936 IsDropFormatSupported( SotClipboardFormatId::STRING
) ||
3937 IsDropFormatSupported( SotClipboardFormatId::SYLK
) ||
3938 IsDropFormatSupported( SotClipboardFormatId::LINK
) ||
3939 IsDropFormatSupported( SotClipboardFormatId::HTML
) ||
3940 IsDropFormatSupported( SotClipboardFormatId::HTML_SIMPLE
) ||
3941 IsDropFormatSupported( SotClipboardFormatId::DIF
) ||
3942 IsDropFormatSupported( SotClipboardFormatId::DRAWING
) ||
3943 IsDropFormatSupported( SotClipboardFormatId::SVXB
) ||
3944 IsDropFormatSupported( SotClipboardFormatId::RTF
) ||
3945 IsDropFormatSupported( SotClipboardFormatId::GDIMETAFILE
) ||
3946 IsDropFormatSupported( SotClipboardFormatId::PNG
) ||
3947 IsDropFormatSupported( SotClipboardFormatId::BITMAP
) ||
3948 IsDropFormatSupported( SotClipboardFormatId::SBA_DATAEXCHANGE
) ||
3949 IsDropFormatSupported( SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
) ||
3951 IsDropFormatSupported( SotClipboardFormatId::FILE_LIST
) ||
3952 IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE
) ||
3953 IsDropFormatSupported( SotClipboardFormatId::SOLK
) ||
3954 IsDropFormatSupported( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
) ||
3955 IsDropFormatSupported( SotClipboardFormatId::NETSCAPE_BOOKMARK
) ||
3956 IsDropFormatSupported( SotClipboardFormatId::FILEGRPDESCRIPTOR
) ) ) )
3962 case DND_ACTION_LINK
:
3963 if ( IsDropFormatSupported( SotClipboardFormatId::LINK_SOURCE
) ||
3964 IsDropFormatSupported( SotClipboardFormatId::LINK_SOURCE_OLE
) ||
3965 IsDropFormatSupported( SotClipboardFormatId::LINK
) ||
3966 IsDropFormatSupported( SotClipboardFormatId::FILE_LIST
) ||
3967 IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE
) ||
3968 IsDropFormatSupported( SotClipboardFormatId::SOLK
) ||
3969 IsDropFormatSupported( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
) ||
3970 IsDropFormatSupported( SotClipboardFormatId::NETSCAPE_BOOKMARK
) ||
3971 IsDropFormatSupported( SotClipboardFormatId::FILEGRPDESCRIPTOR
) )
3980 // Simple check for protection: It's not known here if the drop will result
3981 // in cells or drawing objects (some formats can be both) and how many cells
3982 // the result will be. But if IsFormatEditable for the drop cell position
3983 // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
3984 // can already be rejected here.
3986 Point aPos
= rEvt
.maPosPixel
;
3989 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3990 SCTAB nTab
= pViewData
->GetTabNo();
3991 ScDocument
* pDoc
= pViewData
->GetDocument();
3993 ScEditableTester
aTester( pDoc
, nTab
, nPosX
,nPosY
, nPosX
,nPosY
);
3994 if ( !aTester
.IsFormatEditable() )
3995 nRet
= DND_ACTION_NONE
; // forbidden
4000 // scroll only for accepted formats
4002 DropScroll( rEvt
.maPosPixel
);
4008 static SotClipboardFormatId
lcl_GetDropFormatId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
, bool bPreferText
= false )
4010 TransferableDataHelper
aDataHelper( xTransfer
);
4012 if ( !aDataHelper
.HasFormat( SotClipboardFormatId::SBA_DATAEXCHANGE
) )
4014 // use bookmark formats if no sba is present
4016 if ( aDataHelper
.HasFormat( SotClipboardFormatId::SOLK
) )
4017 return SotClipboardFormatId::SOLK
;
4018 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
) )
4019 return SotClipboardFormatId::UNIFORMRESOURCELOCATOR
;
4020 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK
) )
4021 return SotClipboardFormatId::NETSCAPE_BOOKMARK
;
4022 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR
) )
4023 return SotClipboardFormatId::FILEGRPDESCRIPTOR
;
4026 SotClipboardFormatId nFormatId
= SotClipboardFormatId::NONE
;
4027 if ( aDataHelper
.HasFormat( SotClipboardFormatId::DRAWING
) )
4028 nFormatId
= SotClipboardFormatId::DRAWING
;
4029 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::SVXB
) )
4030 nFormatId
= SotClipboardFormatId::SVXB
;
4031 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::EMBED_SOURCE
) )
4033 // If it's a Writer object, insert RTF instead of OLE
4035 bool bDoRtf
= false;
4036 tools::SvRef
<SotStorageStream
> xStm
;
4037 TransferableObjectDescriptor aObjDesc
;
4038 if( aDataHelper
.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR
, aObjDesc
) &&
4039 aDataHelper
.GetSotStorageStream( SotClipboardFormatId::EMBED_SOURCE
, xStm
) )
4041 tools::SvRef
<SotStorage
> xStore( new SotStorage( *xStm
) );
4042 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
4043 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
4044 && aDataHelper
.HasFormat( SotClipboardFormatId::RTF
) );
4047 nFormatId
= SotClipboardFormatId::RTF
;
4049 nFormatId
= SotClipboardFormatId::EMBED_SOURCE
;
4051 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE
) )
4052 nFormatId
= SotClipboardFormatId::LINK_SOURCE
;
4053 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::SBA_DATAEXCHANGE
) )
4054 nFormatId
= SotClipboardFormatId::SBA_DATAEXCHANGE
;
4055 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
) )
4056 nFormatId
= SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
;
4057 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::BIFF_8
) )
4058 nFormatId
= SotClipboardFormatId::BIFF_8
;
4059 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::BIFF_5
) )
4060 nFormatId
= SotClipboardFormatId::BIFF_5
;
4061 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE
) )
4062 nFormatId
= SotClipboardFormatId::EMBED_SOURCE_OLE
;
4063 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE
) )
4064 nFormatId
= SotClipboardFormatId::EMBEDDED_OBJ_OLE
;
4065 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE
) )
4066 nFormatId
= SotClipboardFormatId::LINK_SOURCE_OLE
;
4067 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::RTF
) )
4068 nFormatId
= SotClipboardFormatId::RTF
;
4069 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::HTML
) )
4070 nFormatId
= SotClipboardFormatId::HTML
;
4071 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::HTML_SIMPLE
) )
4072 nFormatId
= SotClipboardFormatId::HTML_SIMPLE
;
4073 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::SYLK
) )
4074 nFormatId
= SotClipboardFormatId::SYLK
;
4075 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::LINK
) )
4076 nFormatId
= SotClipboardFormatId::LINK
;
4077 else if ( bPreferText
&& aDataHelper
.HasFormat( SotClipboardFormatId::STRING
) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
4078 nFormatId
= SotClipboardFormatId::STRING
;
4079 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::FILE_LIST
) )
4080 nFormatId
= SotClipboardFormatId::FILE_LIST
;
4081 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::SIMPLE_FILE
) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
4082 nFormatId
= SotClipboardFormatId::SIMPLE_FILE
;
4083 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::STRING
) )
4084 nFormatId
= SotClipboardFormatId::STRING
;
4085 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::GDIMETAFILE
) )
4086 nFormatId
= SotClipboardFormatId::GDIMETAFILE
;
4087 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::PNG
) )
4088 nFormatId
= SotClipboardFormatId::PNG
;
4089 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::BITMAP
) )
4090 nFormatId
= SotClipboardFormatId::BITMAP
;
4095 static SotClipboardFormatId
lcl_GetDropLinkId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
)
4097 TransferableDataHelper
aDataHelper( xTransfer
);
4099 SotClipboardFormatId nFormatId
= SotClipboardFormatId::NONE
;
4100 if ( aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE
) )
4101 nFormatId
= SotClipboardFormatId::LINK_SOURCE
;
4102 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE
) )
4103 nFormatId
= SotClipboardFormatId::LINK_SOURCE_OLE
;
4104 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::LINK
) )
4105 nFormatId
= SotClipboardFormatId::LINK
;
4106 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::FILE_LIST
) )
4107 nFormatId
= SotClipboardFormatId::FILE_LIST
;
4108 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::SIMPLE_FILE
) )
4109 nFormatId
= SotClipboardFormatId::SIMPLE_FILE
;
4110 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::SOLK
) )
4111 nFormatId
= SotClipboardFormatId::SOLK
;
4112 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR
) )
4113 nFormatId
= SotClipboardFormatId::UNIFORMRESOURCELOCATOR
;
4114 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK
) )
4115 nFormatId
= SotClipboardFormatId::NETSCAPE_BOOKMARK
;
4116 else if ( aDataHelper
.HasFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR
) )
4117 nFormatId
= SotClipboardFormatId::FILEGRPDESCRIPTOR
;
4122 sal_Int8
ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent
& rEvt
)
4126 UpdateDragRectOverlay();
4128 ScModule
* pScMod
= SC_MOD();
4129 const ScDragData
& rData
= pScMod
->GetDragData();
4131 return DropTransferObj( rData
.pCellTransfer
, nDragStartX
, nDragStartY
,
4132 PixelToLogic(rEvt
.maPosPixel
), rEvt
.mnAction
);
4135 sal_Int8
ScGridWindow::DropTransferObj( ScTransferObj
* pTransObj
, SCCOL nDestPosX
, SCROW nDestPosY
,
4136 const Point
& rLogicPos
, sal_Int8 nDndAction
)
4141 ScDocument
* pSourceDoc
= pTransObj
->GetSourceDocument();
4142 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4143 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4144 ScViewFunc
* pView
= pViewData
->GetView();
4145 SCTAB nThisTab
= pViewData
->GetTabNo();
4146 sal_uInt16 nFlags
= pTransObj
->GetDragSourceFlags();
4148 bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4149 bool bIsMove
= ( nDndAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4151 // workaround for wrong nDndAction on Windows when pressing solely
4152 // the Alt key during drag and drop;
4153 // can be removed after #i79215# has been fixed
4154 if ( meDragInsertMode
!= INS_NONE
)
4156 bIsMove
= ( nDndAction
& DND_ACTION_MOVE
&& !bIsNavi
);
4159 bool bIsLink
= ( nDndAction
== DND_ACTION_LINK
);
4161 ScRange aSource
= pTransObj
->GetRange();
4163 // only use visible tab from source range - when dragging within one table,
4164 // all selected tables at the time of dropping are used (handled in MoveBlockTo)
4165 SCTAB nSourceTab
= pTransObj
->GetVisibleTab();
4166 aSource
.aStart
.SetTab( nSourceTab
);
4167 aSource
.aEnd
.SetTab( nSourceTab
);
4169 SCCOL nSizeX
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
4170 SCROW nSizeY
= (bIsMove
? (aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1) :
4171 pTransObj
->GetNonFilteredRows()); // copy/link: no filtered rows
4172 ScRange
aDest( nDestPosX
, nDestPosY
, nThisTab
,
4173 nDestPosX
+ nSizeX
- 1, nDestPosY
+ nSizeY
- 1, nThisTab
);
4175 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
4176 * dragging and adapted drawing of the selection frame. We check here
4177 * (again) because this may actually also be called from PasteSelection(),
4178 * we would have to duplicate determination of flags and destination range
4179 * and would lose the context of the "filtered destination is OK" cases
4180 * below, which is already awkward enough as is. */
4182 // Don't move filtered source.
4183 bool bFiltered
= (bIsMove
&& pTransObj
->HasFilteredRows());
4186 if (pSourceDoc
!= pThisDoc
&& ((nFlags
& SC_DROP_TABLE
) ||
4187 (!bIsLink
&& meDragInsertMode
== INS_NONE
)))
4189 // Nothing. Either entire sheet to be dropped, or the one case
4190 // where PasteFromClip() is to be called that handles a filtered
4191 // destination itself. Drag-copy from another document without
4195 // Don't copy or move to filtered destination.
4196 bFiltered
= ScViewUtil::HasFiltered( aDest
, pThisDoc
);
4201 if (!bFiltered
&& pSourceDoc
== pThisDoc
)
4203 if ( nFlags
& SC_DROP_TABLE
) // whole sheet?
4205 if ( pThisDoc
->IsDocEditable() )
4207 SCTAB nSrcTab
= aSource
.aStart
.Tab();
4208 pViewData
->GetDocShell()->MoveTable( nSrcTab
, nThisTab
, !bIsMove
, true ); // with Undo
4209 pView
->SetTabNo( nThisTab
, true );
4213 else // move/copy block
4215 OUString aChartName
;
4216 if (pThisDoc
->HasChartAtPoint( nThisTab
, rLogicPos
, aChartName
))
4218 OUString
aRangeName(aSource
.Format(SCR_ABS_3D
, pThisDoc
));
4219 SfxStringItem
aNameItem( SID_CHART_NAME
, aChartName
);
4220 SfxStringItem
aRangeItem( SID_CHART_SOURCE
, aRangeName
);
4221 sal_uInt16 nId
= bIsMove
? SID_CHART_SOURCE
: SID_CHART_ADDSOURCE
;
4222 pViewData
->GetDispatcher().Execute( nId
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
,
4223 &aRangeItem
, &aNameItem
, (void*) NULL
);
4226 else if ( pThisDoc
->GetDPAtCursor( nDestPosX
, nDestPosY
, nThisTab
) )
4228 // drop on DataPilot table: try to sort, fail if that isn't possible
4230 ScAddress
aDestPos( nDestPosX
, nDestPosY
, nThisTab
);
4231 if ( aDestPos
!= aSource
.aStart
)
4232 bDone
= pViewData
->GetView()->DataPilotMove( aSource
, aDestPos
);
4234 bDone
= true; // same position: nothing
4236 else if ( nDestPosX
!= aSource
.aStart
.Col() || nDestPosY
!= aSource
.aStart
.Row() ||
4237 nSourceTab
!= nThisTab
)
4239 OUString aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4240 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4242 SCsCOL nCorrectCursorPosCol
= 0;
4243 SCsROW nCorrectCursorPosRow
= 0;
4246 if ( meDragInsertMode
!= INS_NONE
)
4248 // call with bApi = sal_True to avoid error messages in drop handler
4249 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, true /*bRecord*/, true /*bApi*/, true /*bPartOfPaste*/ );
4252 if ( nThisTab
== nSourceTab
)
4254 if ( meDragInsertMode
== INS_CELLSDOWN
&&
4255 nDestPosX
== aSource
.aStart
.Col() && nDestPosY
< aSource
.aStart
.Row() )
4257 bDone
= aSource
.Move( 0, nSizeY
, 0, pSourceDoc
);
4258 nCorrectCursorPosRow
= nSizeY
;
4260 else if ( meDragInsertMode
== INS_CELLSRIGHT
&&
4261 nDestPosY
== aSource
.aStart
.Row() && nDestPosX
< aSource
.aStart
.Col() )
4263 bDone
= aSource
.Move( nSizeX
, 0, 0, pSourceDoc
);
4264 nCorrectCursorPosCol
= nSizeX
;
4267 pDocSh
->UpdateOle( pViewData
);
4268 pView
->CellContentChanged();
4276 // call with bApi = sal_True to avoid error messages in drop handler
4277 bDone
= pView
->LinkBlock( aSource
, aDest
.aStart
, true /*bApi*/ );
4281 // call with bApi = sal_True to avoid error messages in drop handler
4282 bDone
= pView
->MoveBlockTo( aSource
, aDest
.aStart
, bIsMove
, true /*bRecord*/, true /*bPaint*/, true /*bApi*/ );
4286 if ( bDone
&& meDragInsertMode
!= INS_NONE
&& bIsMove
&& nThisTab
== nSourceTab
)
4288 DelCellCmd eCmd
= DEL_NONE
;
4289 if ( meDragInsertMode
== INS_CELLSDOWN
)
4293 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
4295 eCmd
= DEL_CELLSLEFT
;
4298 if ( ( eCmd
== DEL_CELLSUP
&& nDestPosX
== aSource
.aStart
.Col() ) ||
4299 ( eCmd
== DEL_CELLSLEFT
&& nDestPosY
== aSource
.aStart
.Row() ) )
4301 // call with bApi = sal_True to avoid error messages in drop handler
4302 bDone
= pDocSh
->GetDocFunc().DeleteCells( aSource
, NULL
, eCmd
, true /*bRecord*/, true /*bApi*/ );
4305 if ( eCmd
== DEL_CELLSUP
&& nDestPosY
> aSource
.aEnd
.Row() )
4307 bDone
= aDest
.Move( 0, -nSizeY
, 0, pThisDoc
);
4309 else if ( eCmd
== DEL_CELLSLEFT
&& nDestPosX
> aSource
.aEnd
.Col() )
4311 bDone
= aDest
.Move( -nSizeX
, 0, 0, pThisDoc
);
4313 pDocSh
->UpdateOle( pViewData
);
4314 pView
->CellContentChanged();
4321 pView
->MarkRange( aDest
, false, false );
4323 SCCOL nDCol
= pViewData
->GetCurX() - aSource
.aStart
.Col() + nCorrectCursorPosCol
;
4324 SCROW nDRow
= pViewData
->GetCurY() - aSource
.aStart
.Row() + nCorrectCursorPosRow
;
4325 pView
->SetCursor( aDest
.aStart
.Col() + nDCol
, aDest
.aStart
.Row() + nDRow
);
4328 pDocSh
->GetUndoManager()->LeaveListAction();
4332 bDone
= true; // nothing to do
4336 pTransObj
->SetDragWasInternal(); // don't delete source in DragFinished
4338 else if ( !bFiltered
&& pSourceDoc
) // between documents
4340 if ( nFlags
& SC_DROP_TABLE
) // copy/link sheets between documents
4342 if ( pThisDoc
->IsDocEditable() )
4344 ScDocShell
* pSrcShell
= pTransObj
->GetSourceDocShell();
4346 std::vector
<SCTAB
> nTabs
;
4348 ScMarkData aMark
= pTransObj
->GetSourceMarkData();
4349 SCTAB nTabCount
= pSourceDoc
->GetTableCount();
4351 for(SCTAB i
=0; i
<nTabCount
; i
++)
4353 if(aMark
.GetTableSelect(i
))
4356 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
4358 if((!pSourceDoc
->IsVisible(j
))&&(pSourceDoc
->IsScenario(j
)))
4360 nTabs
.push_back( j
);
4368 pView
->ImportTables( pSrcShell
,static_cast<SCTAB
>(nTabs
.size()), &nTabs
[0], bIsLink
, nThisTab
);
4375 // (external references might be used instead?)
4377 SfxObjectShell
* pSourceSh
= pSourceDoc
->GetDocumentShell();
4378 OSL_ENSURE(pSourceSh
, "drag document has no shell");
4381 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_COPY
);
4382 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4385 if ( meDragInsertMode
!= INS_NONE
)
4387 // call with bApi = sal_True to avoid error messages in drop handler
4388 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, true /*bRecord*/, true /*bApi*/, true /*bPartOfPaste*/ );
4391 pDocSh
->UpdateOle( pViewData
);
4392 pView
->CellContentChanged();
4398 OUString aApp
= Application::GetAppName();
4399 OUString aTopic
= pSourceSh
->GetTitle( SFX_TITLE_FULLNAME
);
4400 OUString
aItem(aSource
.Format(SCA_VALID
| SCA_TAB_3D
, pSourceDoc
));
4402 // TODO: we could define ocQuote for "
4403 const OUString
aQuote('"');
4404 const OUString
& sSep
= ScCompiler::GetNativeSymbol( ocSep
);
4405 OUStringBuffer aFormula
;
4406 aFormula
.append('=');
4407 aFormula
.append(ScCompiler::GetNativeSymbol(ocDde
));
4408 aFormula
.append(ScCompiler::GetNativeSymbol(ocOpen
));
4409 aFormula
.append(aQuote
);
4410 aFormula
.append(aApp
);
4411 aFormula
.append(aQuote
);
4412 aFormula
.append(sSep
);
4413 aFormula
.append(aQuote
);
4414 aFormula
.append(aTopic
);
4415 aFormula
.append(aQuote
);
4416 aFormula
.append(sSep
);
4417 aFormula
.append(aQuote
);
4418 aFormula
.append(aItem
);
4419 aFormula
.append(aQuote
);
4420 aFormula
.append(ScCompiler::GetNativeSymbol(ocClose
));
4422 pView
->DoneBlockMode();
4423 pView
->InitBlockMode( nDestPosX
, nDestPosY
, nThisTab
);
4424 pView
->MarkCursor( nDestPosX
+ nSizeX
- 1,
4425 nDestPosY
+ nSizeY
- 1, nThisTab
);
4427 pView
->EnterMatrix( aFormula
.makeStringAndClear(), ::formula::FormulaGrammar::GRAM_NATIVE
);
4429 pView
->MarkRange( aDest
, false, false );
4430 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4433 pDocSh
->GetUndoManager()->LeaveListAction();
4438 //! HasSelectedBlockMatrixFragment without selected sheet?
4439 //! or don't start dragging on a part of a matrix
4441 OUString aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4442 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4445 if ( meDragInsertMode
!= INS_NONE
)
4447 // call with bApi = sal_True to avoid error messages in drop handler
4448 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, true /*bRecord*/, true /*bApi*/, true /*bPartOfPaste*/ );
4451 pDocSh
->UpdateOle( pViewData
);
4452 pView
->CellContentChanged();
4458 pView
->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4459 pView
->SetCursor( nDestPosX
, nDestPosY
);
4460 bDone
= pView
->PasteFromClip( IDF_ALL
, pTransObj
->GetDocument() ); // clip-doc
4463 pView
->MarkRange( aDest
, false, false );
4464 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4468 pDocSh
->GetUndoManager()->LeaveListAction();
4470 // no longer call ResetMark here - the inserted block has been selected
4471 // and may have been copied to primary selection
4475 sal_Int8 nRet
= bDone
? nDndAction
: DND_ACTION_NONE
;
4479 sal_Int8
ScGridWindow::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
4481 DrawMarkDropObj( NULL
); // drawing layer
4483 ScModule
* pScMod
= SC_MOD();
4484 const ScDragData
& rData
= pScMod
->GetDragData();
4485 if (rData
.pCellTransfer
)
4486 return ExecutePrivateDrop( rEvt
);
4488 Point aPos
= rEvt
.maPosPixel
;
4490 if ( !rData
.aLinkDoc
.isEmpty() )
4492 // try to insert a link
4496 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4497 if (pDocSh
&& pDocSh
->HasName())
4498 aThisName
= pDocSh
->GetMedium()->GetName();
4500 if ( rData
.aLinkDoc
.equals(aThisName
) ) // error - no link within a document
4504 ScViewFunc
* pView
= pViewData
->GetView();
4505 if ( !rData
.aLinkTable
.isEmpty() )
4506 pView
->InsertTableLink( rData
.aLinkDoc
, EMPTY_OUSTRING
, EMPTY_OUSTRING
,
4508 else if ( !rData
.aLinkArea
.isEmpty() )
4512 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4513 pView
->MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, false, false );
4515 pView
->InsertAreaLink( rData
.aLinkDoc
, EMPTY_OUSTRING
, EMPTY_OUSTRING
,
4516 rData
.aLinkArea
, 0 );
4520 OSL_FAIL("drop with link: no sheet nor area");
4525 return bOk
? rEvt
.mnAction
: DND_ACTION_NONE
; // don't try anything else
4528 Point aLogicPos
= PixelToLogic(aPos
);
4529 bool bIsLink
= ( rEvt
.mnAction
== DND_ACTION_LINK
);
4531 if (!bIsLink
&& rData
.pDrawTransfer
)
4533 sal_uInt16 nFlags
= rData
.pDrawTransfer
->GetDragSourceFlags();
4535 bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4536 bool bIsMove
= ( rEvt
.mnAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4538 bPasteIsMove
= bIsMove
;
4540 pViewData
->GetView()->PasteDraw(
4541 aLogicPos
, rData
.pDrawTransfer
->GetModel(), false, "A", "B");
4544 rData
.pDrawTransfer
->SetDragWasInternal();
4545 bPasteIsMove
= false;
4547 return rEvt
.mnAction
;
4552 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4554 if (!rData
.aJumpTarget
.isEmpty())
4556 // internal bookmark (from Navigator)
4557 // bookmark clipboard formats are in PasteScDataObject
4559 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
4561 pViewData
->GetViewShell()->InsertBookmark( rData
.aJumpText
, rData
.aJumpTarget
,
4563 return rEvt
.mnAction
;
4567 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4568 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint( pViewData
->GetTabNo(), PixelToLogic(aPos
) );
4569 if ( pHitObj
&& bIsLink
)
4571 // dropped on drawing object
4572 // PasteOnDrawObjectLinked checks for valid formats
4573 if ( pViewData
->GetView()->PasteOnDrawObjectLinked( rEvt
.maDropEvent
.Transferable
, *pHitObj
) )
4574 return rEvt
.mnAction
;
4579 SotClipboardFormatId nFormatId
= bIsLink
?
4580 lcl_GetDropLinkId( rEvt
.maDropEvent
.Transferable
) :
4581 lcl_GetDropFormatId( rEvt
.maDropEvent
.Transferable
);
4582 if ( nFormatId
!= SotClipboardFormatId::NONE
)
4584 pScMod
->SetInExecuteDrop( true ); // #i28468# prevent error messages from PasteDataFormat
4585 bPasteIsDrop
= true;
4586 bDone
= pViewData
->GetView()->PasteDataFormat(
4587 nFormatId
, rEvt
.maDropEvent
.Transferable
, nPosX
, nPosY
, &aLogicPos
, bIsLink
);
4588 bPasteIsDrop
= false;
4589 pScMod
->SetInExecuteDrop( false );
4592 sal_Int8 nRet
= bDone
? rEvt
.mnAction
: DND_ACTION_NONE
;
4596 void ScGridWindow::PasteSelection( const Point
& rPosPixel
)
4598 Point aLogicPos
= PixelToLogic( rPosPixel
);
4602 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
4604 // If the mouse down was inside a visible note window, ignore it and
4605 // leave it up to the ScPostIt to handle it
4606 SdrView
* pDrawView
= pViewData
->GetViewShell()->GetSdrView();
4609 const size_t nCount
= pDrawView
->GetMarkedObjectCount();
4610 for (size_t i
= 0; i
< nCount
; ++i
)
4612 SdrObject
* pObj
= pDrawView
->GetMarkedObjectByIndex(i
);
4613 if (pObj
&& pObj
->GetLogicRect().IsInside(aLogicPos
))
4615 // Inside an active drawing object. Bail out.
4621 ScSelectionTransferObj
* pOwnSelection
= SC_MOD()->GetSelectionTransfer();
4622 if ( pOwnSelection
)
4626 ScTransferObj
* pCellTransfer
= pOwnSelection
->GetCellData();
4627 if ( pCellTransfer
)
4629 // keep a reference to the data in case the selection is changed during paste
4630 uno::Reference
<datatransfer::XTransferable
> xRef( pCellTransfer
);
4631 DropTransferObj( pCellTransfer
, nPosX
, nPosY
, aLogicPos
, DND_ACTION_COPY
);
4635 ScDrawTransferObj
* pDrawTransfer
= pOwnSelection
->GetDrawData();
4636 if ( pDrawTransfer
)
4638 // keep a reference to the data in case the selection is changed during paste
4639 uno::Reference
<datatransfer::XTransferable
> xRef( pDrawTransfer
);
4641 // bSameDocClipboard argument for PasteDraw is needed
4642 // because only DragData is checked directly inside PasteDraw
4643 pViewData
->GetView()->PasteDraw(
4644 aLogicPos
, pDrawTransfer
->GetModel(), false,
4645 pDrawTransfer
->GetShellID(), SfxObjectShell::CreateShellID(pViewData
->GetDocShell()));
4651 // get selection from system
4653 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4654 uno::Reference
<datatransfer::XTransferable
> xTransferable
= aDataHelper
.GetTransferable();
4655 if ( xTransferable
.is() )
4657 SotClipboardFormatId nFormatId
= lcl_GetDropFormatId( xTransferable
, true );
4658 if ( nFormatId
!= SotClipboardFormatId::NONE
)
4660 bPasteIsDrop
= true;
4661 pViewData
->GetView()->PasteDataFormat( nFormatId
, xTransferable
, nPosX
, nPosY
, &aLogicPos
);
4662 bPasteIsDrop
= false;
4668 void ScGridWindow::UpdateEditViewPos()
4670 if (pViewData
->HasEditView(eWhich
))
4675 pViewData
->GetEditView( eWhich
, pView
, nCol
, nRow
);
4676 SCCOL nEndCol
= pViewData
->GetEditEndCol();
4677 SCROW nEndRow
= pViewData
->GetEditEndRow();
4681 bool bHide
= ( nEndCol
<pViewData
->GetPosX(eHWhich
) || nEndRow
<pViewData
->GetPosY(eVWhich
) );
4682 if ( SC_MOD()->IsFormulaMode() )
4683 if ( pViewData
->GetTabNo() != pViewData
->GetRefTabNo() )
4688 Rectangle aRect
= pView
->GetOutputArea();
4689 long nHeight
= aRect
.Bottom() - aRect
.Top();
4690 aRect
.Top() = PixelToLogic(GetOutputSizePixel(), pViewData
->GetLogicMode()).
4692 aRect
.Bottom() = aRect
.Top() + nHeight
;
4693 pView
->SetOutputArea( aRect
);
4694 pView
->HideCursor();
4698 // bForceToTop = sal_True for editing
4699 Rectangle aPixRect
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, this, NULL
, true );
4700 Point aScrPos
= PixelToLogic( aPixRect
.TopLeft(), pViewData
->GetLogicMode() );
4702 Rectangle aRect
= pView
->GetOutputArea();
4703 aRect
.SetPos( aScrPos
);
4704 pView
->SetOutputArea( aRect
);
4705 pView
->ShowCursor();
4710 void ScGridWindow::ScrollPixel( long nDifX
, long nDifY
)
4717 SetMapMode(MAP_PIXEL
);
4718 Scroll( nDifX
, nDifY
, SCROLL_CHILDREN
);
4719 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4721 UpdateEditViewPos();
4724 bIsInScroll
= false;
4727 // Formeln neu zeichnen -------------------------------------------------
4729 void ScGridWindow::UpdateFormulas()
4731 if (pViewData
->GetView()->IsMinimized())
4736 // nicht anfangen, verschachtelt zu painten
4737 // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4739 bNeedsRepaint
= true; // -> am Ende vom Paint nochmal Invalidate auf alles
4740 aRepaintPixel
= Rectangle(); // alles
4744 SCCOL nX1
= pViewData
->GetPosX( eHWhich
);
4745 SCROW nY1
= pViewData
->GetPosY( eVWhich
);
4746 SCCOL nX2
= nX1
+ pViewData
->VisibleCellsX( eHWhich
);
4747 SCROW nY2
= nY1
+ pViewData
->VisibleCellsY( eVWhich
);
4749 if (nX2
> MAXCOL
) nX2
= MAXCOL
;
4750 if (nY2
> MAXROW
) nY2
= MAXROW
;
4752 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4754 // don't draw directly - instead use OutputData to find changed area and invalidate
4758 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4759 ScDocument
& rDoc
= pDocSh
->GetDocument();
4760 SCTAB nTab
= pViewData
->GetTabNo();
4762 rDoc
.ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
4764 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
4765 long nMirrorWidth
= GetSizePixel().Width();
4766 bool bLayoutRTL
= rDoc
.IsLayoutRTL( nTab
);
4769 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
4770 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
4771 aScrPos
.X() = nEndPixel
+ 1;
4774 long nScrX
= aScrPos
.X();
4775 long nScrY
= aScrPos
.Y();
4777 double nPPTX
= pViewData
->GetPPTX();
4778 double nPPTY
= pViewData
->GetPPTY();
4780 ScTableInfo aTabInfo
;
4781 rDoc
.FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
, nPPTX
, nPPTY
, false, false );
4783 Fraction aZoomX
= pViewData
->GetZoomX();
4784 Fraction aZoomY
= pViewData
->GetZoomY();
4785 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, &rDoc
, nTab
,
4786 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
4788 aOutputData
.SetMirrorWidth( nMirrorWidth
);
4790 aOutputData
.FindChanged();
4792 // #i122149# do not use old GetChangedArea() which used polygon-based Regions, but use
4793 // the region-band based new version; anyways, only rectangles are added
4794 vcl::Region
aChangedRegion( aOutputData
.GetChangedAreaRegion() ); // logic (PixelToLogic)
4795 if(!aChangedRegion
.IsEmpty())
4797 Invalidate(aChangedRegion
);
4800 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4803 void ScGridWindow::UpdateAutoFillMark(bool bMarked
, const ScRange
& rMarkRange
)
4805 if ( bMarked
!= bAutoMarkVisible
|| ( bMarked
&& rMarkRange
.aEnd
!= aAutoMarkPos
) )
4807 bAutoMarkVisible
= bMarked
;
4809 aAutoMarkPos
= rMarkRange
.aEnd
;
4811 UpdateAutoFillOverlay();
4815 void ScGridWindow::UpdateListValPos( bool bVisible
, const ScAddress
& rPos
)
4817 bool bOldButton
= bListValButton
;
4818 ScAddress aOldPos
= aListValPos
;
4820 bListValButton
= bVisible
;
4823 if ( bListValButton
)
4825 if ( !bOldButton
|| aListValPos
!= aOldPos
)
4827 // paint area of new button
4828 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos
) ) );
4833 if ( !bListValButton
|| aListValPos
!= aOldPos
)
4835 // paint area of old button
4836 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos
) ) );
4841 void ScGridWindow::HideCursor()
4846 void ScGridWindow::ShowCursor()
4851 void ScGridWindow::GetFocus()
4853 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4854 pViewShell
->SetFormShellAtTop( false ); // focus in GridWindow -> FormShell no longer on top
4856 if (pViewShell
->HasAccessibilityObjects())
4857 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich
, GetAccessible()));
4859 if ( !SC_MOD()->IsFormulaMode() )
4861 pViewShell
->UpdateInputHandler();
4862 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4863 // MO: nur wenn nicht im RefInput-Modus
4864 // -> GetFocus/MouseButtonDown-Reihenfolge
4868 pViewData
->GetDocShell()->CheckConfigOptions();
4872 void ScGridWindow::LoseFocus()
4874 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4876 if (pViewShell
&& pViewShell
->HasAccessibilityObjects())
4877 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich
, GetAccessible()));
4879 Window::LoseFocus();
4882 bool ScGridWindow::HitRangeFinder( const Point
& rMouse
, RfCorner
& rCorner
,
4883 sal_uInt16
* pIndex
, SCsCOL
* pAddX
, SCsROW
* pAddY
)
4885 bool bFound
= false;
4886 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4889 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4890 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
4891 pRangeFinder
->GetDocName() == pViewData
->GetDocShell()->GetTitle() )
4893 ScDocument
* pDoc
= pViewData
->GetDocument();
4894 SCTAB nTab
= pViewData
->GetTabNo();
4895 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4896 long nLayoutSign
= bLayoutRTL
? -1 : 1;
4900 pViewData
->GetPosFromPixel( rMouse
.X(), rMouse
.Y(), eWhich
, nPosX
, nPosY
);
4901 // zusammengefasste (einzeln/Bereich) ???
4902 ScAddress
aAddr( nPosX
, nPosY
, nTab
);
4904 Point aCellStart
= pViewData
->GetScrPos( nPosX
, nPosY
, eWhich
, true );
4905 Point aCellEnd
= aCellStart
;
4908 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeXPix
, nSizeYPix
);
4910 aCellEnd
.X() += nSizeXPix
* nLayoutSign
;
4911 aCellEnd
.Y() += nSizeYPix
;
4913 bool bCornerHorizontalRight
;
4914 bool bCornerHorizontalLeft
;
4917 bCornerHorizontalRight
= ( rMouse
.X() >= aCellEnd
.X() && rMouse
.X() <= aCellEnd
.X() + 8 );
4918 bCornerHorizontalLeft
= ( rMouse
.X() >= aCellStart
.X() - 8 && rMouse
.X() <= aCellStart
.X() );
4922 bCornerHorizontalRight
= ( rMouse
.X() >= aCellEnd
.X() - 8 && rMouse
.X() <= aCellEnd
.X() );
4923 bCornerHorizontalLeft
= ( rMouse
.X() >= aCellStart
.X() && rMouse
.X() <= aCellStart
.X() + 8 );
4926 bool bCornerVerticalDown
= rMouse
.Y() >= aCellEnd
.Y() - 8 && rMouse
.Y() <= aCellEnd
.Y();
4927 bool bCornerVerticalUp
= rMouse
.Y() >= aCellStart
.Y() && rMouse
.Y() <= aCellStart
.Y() + 8;
4929 // corner is hit only if the mouse is within the cell
4930 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
4931 for (sal_uInt16 i
=nCount
; i
;)
4933 // search backwards so that the last repainted frame is found
4935 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
4936 if ( pData
->aRef
.In(aAddr
) )
4941 *pAddX
= nPosX
- pData
->aRef
.aStart
.Col();
4943 *pAddY
= nPosY
- pData
->aRef
.aStart
.Row();
4949 ScAddress aEnd
= pData
->aRef
.aEnd
;
4950 ScAddress aStart
= pData
->aRef
.aStart
;
4952 if ( bCornerHorizontalLeft
&& bCornerVerticalUp
&&
4957 else if (bCornerHorizontalRight
&& bCornerVerticalDown
&&
4960 rCorner
= RIGHT_DOWN
;
4962 else if (bCornerHorizontalRight
&& bCornerVerticalUp
&&
4963 aAddr
== ScAddress(aEnd
.Col(), aStart
.Row(), aStart
.Tab()))
4967 else if (bCornerHorizontalLeft
&& bCornerVerticalDown
&&
4968 aAddr
== ScAddress(aStart
.Col(), aEnd
.Row(), aStart
.Tab()))
4970 rCorner
= LEFT_DOWN
;
4981 #define SCE_BOTTOM 2
4986 static void lcl_PaintOneRange( ScDocShell
* pDocSh
, const ScRange
& rRange
, sal_uInt16 nEdges
)
4988 // der Range ist immer richtigherum
4990 SCCOL nCol1
= rRange
.aStart
.Col();
4991 SCROW nRow1
= rRange
.aStart
.Row();
4992 SCTAB nTab1
= rRange
.aStart
.Tab();
4993 SCCOL nCol2
= rRange
.aEnd
.Col();
4994 SCROW nRow2
= rRange
.aEnd
.Row();
4995 SCTAB nTab2
= rRange
.aEnd
.Tab();
4996 bool bHiddenEdge
= false;
4999 ScDocument
& rDoc
= pDocSh
->GetDocument();
5000 while ( nCol1
> 0 && rDoc
.ColHidden(nCol1
, nTab1
) )
5005 while ( nCol2
< MAXCOL
&& rDoc
.ColHidden(nCol2
, nTab1
) )
5010 nTmp
= rDoc
.FirstVisibleRow(0, nRow1
, nTab1
);
5011 if (!ValidRow(nTmp
))
5018 nTmp
= rDoc
.FirstVisibleRow(nRow2
, MAXROW
, nTab1
);
5019 if (!ValidRow(nTmp
))
5027 if ( nCol2
> nCol1
+ 1 && nRow2
> nRow1
+ 1 && !bHiddenEdge
)
5029 // nur an den Raendern entlang
5030 // (die Ecken werden evtl. zweimal getroffen)
5032 if ( nEdges
& SCE_TOP
)
5033 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow1
, nTab2
, PAINT_MARKS
);
5034 if ( nEdges
& SCE_LEFT
)
5035 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol1
, nRow2
, nTab2
, PAINT_MARKS
);
5036 if ( nEdges
& SCE_RIGHT
)
5037 pDocSh
->PostPaint( nCol2
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
5038 if ( nEdges
& SCE_BOTTOM
)
5039 pDocSh
->PostPaint( nCol1
, nRow2
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
5041 else // everything in one call
5042 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
5045 static void lcl_PaintRefChanged( ScDocShell
* pDocSh
, const ScRange
& rOldUn
, const ScRange
& rNewUn
)
5047 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
5049 ScRange aOld
= rOldUn
;
5050 ScRange aNew
= rNewUn
;
5054 if ( aOld
.aStart
== aOld
.aEnd
) //! Tab ignorieren?
5055 pDocSh
->GetDocument().ExtendMerge(aOld
);
5056 if ( aNew
.aStart
== aNew
.aEnd
) //! Tab ignorieren?
5057 pDocSh
->GetDocument().ExtendMerge(aNew
);
5059 SCCOL nOldCol1
= aOld
.aStart
.Col();
5060 SCROW nOldRow1
= aOld
.aStart
.Row();
5061 SCCOL nOldCol2
= aOld
.aEnd
.Col();
5062 SCROW nOldRow2
= aOld
.aEnd
.Row();
5063 SCCOL nNewCol1
= aNew
.aStart
.Col();
5064 SCROW nNewRow1
= aNew
.aStart
.Row();
5065 SCCOL nNewCol2
= aNew
.aEnd
.Col();
5066 SCROW nNewRow2
= aNew
.aEnd
.Row();
5067 SCTAB nTab1
= aOld
.aStart
.Tab(); // Tab aendert sich nicht
5068 SCTAB nTab2
= aOld
.aEnd
.Tab();
5070 if ( nNewRow2
< nOldRow1
|| nNewRow1
> nOldRow2
||
5071 nNewCol2
< nOldCol1
|| nNewCol1
> nOldCol2
||
5072 ( nNewCol1
!= nOldCol1
&& nNewRow1
!= nOldRow1
&&
5073 nNewCol2
!= nOldCol2
&& nNewRow2
!= nOldRow2
) )
5075 // komplett weggeschoben oder alle Seiten veraendert
5076 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
5078 lcl_PaintOneRange( pDocSh
, aOld
, SCE_ALL
);
5080 else // alle vier Kanten einzeln testen
5083 if ( nNewRow1
< nOldRow1
) // nur obere Linie loeschen
5084 lcl_PaintOneRange( pDocSh
, ScRange(
5085 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nOldRow1
, nTab2
), SCE_ALL
);
5086 else if ( nNewRow1
> nOldRow1
) // den Teil, der oben wegkommt
5087 lcl_PaintOneRange( pDocSh
, ScRange(
5088 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nNewRow1
-1, nTab2
),
5089 SCE_ALL
&~ SCE_BOTTOM
);
5092 if ( nNewRow2
> nOldRow2
) // nur untere Linie loeschen
5093 lcl_PaintOneRange( pDocSh
, ScRange(
5094 nOldCol1
, nOldRow2
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
5095 else if ( nNewRow2
< nOldRow2
) // den Teil, der unten wegkommt
5096 lcl_PaintOneRange( pDocSh
, ScRange(
5097 nOldCol1
, nNewRow2
+1, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
5098 SCE_ALL
&~ SCE_TOP
);
5101 if ( nNewCol1
< nOldCol1
) // nur linke Linie loeschen
5102 lcl_PaintOneRange( pDocSh
, ScRange(
5103 nOldCol1
, nOldRow1
, nTab1
, nOldCol1
, nOldRow2
, nTab2
), SCE_ALL
);
5104 else if ( nNewCol1
> nOldCol1
) // den Teil, der links wegkommt
5105 lcl_PaintOneRange( pDocSh
, ScRange(
5106 nOldCol1
, nOldRow1
, nTab1
, nNewCol1
-1, nOldRow2
, nTab2
),
5107 SCE_ALL
&~ SCE_RIGHT
);
5110 if ( nNewCol2
> nOldCol2
) // nur rechte Linie loeschen
5111 lcl_PaintOneRange( pDocSh
, ScRange(
5112 nOldCol2
, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
5113 else if ( nNewCol2
< nOldCol2
) // den Teil, der rechts wegkommt
5114 lcl_PaintOneRange( pDocSh
, ScRange(
5115 nNewCol2
+1, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
5116 SCE_ALL
&~ SCE_LEFT
);
5120 void ScGridWindow::RFMouseMove( const MouseEvent
& rMEvt
, bool bUp
)
5122 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
5125 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
5126 if (!pRangeFinder
|| nRFIndex
>= pRangeFinder
->Count())
5128 ScRangeFindData
* pData
= pRangeFinder
->GetObject( nRFIndex
);
5133 SetPointer( Pointer( PointerStyle::Cross
) );
5135 SetPointer( Pointer( PointerStyle::Hand
) );
5139 bool bTimer
= false;
5140 Point aPos
= rMEvt
.GetPosPixel();
5143 if ( aPos
.X() < 0 ) nDx
= -1;
5144 if ( aPos
.Y() < 0 ) nDy
= -1;
5145 Size aSize
= GetOutputSizePixel();
5146 if ( aPos
.X() >= aSize
.Width() )
5148 if ( aPos
.Y() >= aSize
.Height() )
5150 if ( nDx
!= 0 || nDy
!= 0 )
5152 if ( nDx
!= 0) pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
5153 if ( nDy
!= 0 ) pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
5157 // Umschalten bei Fixierung (damit Scrolling funktioniert)
5159 if ( eWhich
== pViewData
->GetActivePart() ) //??
5161 if ( pViewData
->GetHSplitMode() == SC_SPLIT_FIX
)
5164 if ( eWhich
== SC_SPLIT_TOPLEFT
)
5165 pViewData
->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT
);
5166 else if ( eWhich
== SC_SPLIT_BOTTOMLEFT
)
5167 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
5170 if ( pViewData
->GetVSplitMode() == SC_SPLIT_FIX
)
5173 if ( eWhich
== SC_SPLIT_TOPLEFT
)
5174 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT
);
5175 else if ( eWhich
== SC_SPLIT_TOPRIGHT
)
5176 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
5184 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
5186 ScRange aOld
= pData
->aRef
;
5187 ScRange aNew
= aOld
;
5190 switch (aRFSelectedCorned
)
5193 aNew
.aStart
.SetCol((SCCOL
)nPosX
);
5194 aNew
.aStart
.SetRow((SCROW
)nPosY
);
5197 aNew
.aStart
.SetCol((SCCOL
)nPosX
);
5198 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
5201 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
5202 aNew
.aStart
.SetRow((SCROW
)nPosY
);
5205 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
5206 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
5214 long nStartX
= nPosX
- nRFAddX
;
5215 if ( nStartX
< 0 ) nStartX
= 0;
5216 long nStartY
= nPosY
- nRFAddY
;
5217 if ( nStartY
< 0 ) nStartY
= 0;
5218 long nEndX
= nStartX
+ aOld
.aEnd
.Col() - aOld
.aStart
.Col();
5219 if ( nEndX
> MAXCOL
)
5221 nStartX
-= ( nEndX
- MAXROW
);
5224 long nEndY
= nStartY
+ aOld
.aEnd
.Row() - aOld
.aStart
.Row();
5225 if ( nEndY
> MAXROW
)
5227 nStartY
-= ( nEndY
- MAXROW
);
5231 aNew
.aStart
.SetCol((SCCOL
)nStartX
);
5232 aNew
.aStart
.SetRow((SCROW
)nStartY
);
5233 aNew
.aEnd
.SetCol((SCCOL
)nEndX
);
5234 aNew
.aEnd
.SetRow((SCROW
)nEndY
);
5238 aNew
.Justify(); // beim ButtonUp wieder richtigherum
5242 pHdl
->UpdateRange( nRFIndex
, aNew
);
5244 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5246 // nur das neuzeichnen, was sich veraendert hat...
5247 lcl_PaintRefChanged( pDocSh
, aOld
, aNew
);
5249 // neuen Rahmen nur drueberzeichnen (synchron)
5250 pDocSh
->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER
, nRFIndex
) );
5252 Update(); // was man bewegt, will man auch sofort sehen
5255 // Timer fuer Scrolling
5258 pViewData
->GetView()->SetTimer( this, rMEvt
); // Event wiederholen
5260 pViewData
->GetView()->ResetTimer();
5265 SvxAdjust
toSvxAdjust( const ScPatternAttr
& rPat
)
5267 SvxCellHorJustify eHorJust
=
5268 static_cast<SvxCellHorJustify
>(
5269 static_cast<const SvxHorJustifyItem
&>(rPat
.GetItem(ATTR_HOR_JUSTIFY
)).GetValue());
5271 SvxAdjust eSvxAdjust
= SVX_ADJUST_LEFT
;
5274 case SVX_HOR_JUSTIFY_LEFT
:
5275 case SVX_HOR_JUSTIFY_REPEAT
: // nicht implementiert
5276 case SVX_HOR_JUSTIFY_STANDARD
: // always Text if an EditCell type
5277 eSvxAdjust
= SVX_ADJUST_LEFT
;
5279 case SVX_HOR_JUSTIFY_RIGHT
:
5280 eSvxAdjust
= SVX_ADJUST_RIGHT
;
5282 case SVX_HOR_JUSTIFY_CENTER
:
5283 eSvxAdjust
= SVX_ADJUST_CENTER
;
5285 case SVX_HOR_JUSTIFY_BLOCK
:
5286 eSvxAdjust
= SVX_ADJUST_BLOCK
;
5293 boost::shared_ptr
<ScFieldEditEngine
> createEditEngine( ScDocShell
* pDocSh
, const ScPatternAttr
& rPat
)
5295 ScDocument
& rDoc
= pDocSh
->GetDocument();
5297 boost::shared_ptr
<ScFieldEditEngine
> pEngine(new ScFieldEditEngine(&rDoc
, rDoc
.GetEditPool()));
5298 ScSizeDeviceProvider
aProv(pDocSh
);
5299 pEngine
->SetRefDevice(aProv
.GetDevice());
5300 pEngine
->SetRefMapMode(MAP_100TH_MM
);
5301 SfxItemSet aDefault
= pEngine
->GetEmptyItemSet();
5302 rPat
.FillEditItemSet(&aDefault
);
5303 aDefault
.Put( SvxAdjustItem(toSvxAdjust(rPat
), EE_PARA_JUST
) );
5304 pEngine
->SetDefaults(aDefault
);
5309 bool extractURLInfo( const SvxFieldItem
* pFieldItem
, OUString
* pName
, OUString
* pUrl
, OUString
* pTarget
)
5314 const SvxFieldData
* pField
= pFieldItem
->GetField();
5315 if (pField
->GetClassId() != text::textfield::Type::URL
)
5318 const SvxURLField
* pURLField
= static_cast<const SvxURLField
*>(pField
);
5321 *pName
= pURLField
->GetRepresentation();
5323 *pUrl
= pURLField
->GetURL();
5325 *pTarget
= pURLField
->GetTargetFrame();
5332 bool ScGridWindow::GetEditUrl( const Point
& rPos
,
5333 OUString
* pName
, OUString
* pUrl
, OUString
* pTarget
)
5335 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
5336 ScInputHandler
* pInputHdl
= NULL
;
5338 pInputHdl
= pViewSh
->GetInputHandler();
5339 EditView
* pView
= (pInputHdl
&& pInputHdl
->IsInputMode()) ? pInputHdl
->GetTableView() : NULL
;
5341 return extractURLInfo(pView
->GetFieldUnderMousePointer(), pName
, pUrl
, pTarget
);
5343 //! nPosX/Y mit uebergeben?
5346 pViewData
->GetPosFromPixel( rPos
.X(), rPos
.Y(), eWhich
, nPosX
, nPosY
);
5348 SCTAB nTab
= pViewData
->GetTabNo();
5349 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5350 ScDocument
& rDoc
= pDocSh
->GetDocument();
5352 ScRefCellValue aCell
;
5353 bool bFound
= lcl_GetHyperlinkCell(&rDoc
, nPosX
, nPosY
, nTab
, aCell
, sURL
);
5357 const ScPatternAttr
* pPattern
= rDoc
.GetPattern( nPosX
, nPosY
, nTab
);
5358 // bForceToTop = sal_False, use the cell's real position
5359 Rectangle aEditRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, false );
5360 if (rPos
.Y() < aEditRect
.Top())
5363 // vertikal kann (noch) nicht angeklickt werden:
5365 if (pPattern
->GetCellOrientation() != SVX_ORIENTATION_STANDARD
)
5368 bool bBreak
= static_cast<const SfxBoolItem
&>(pPattern
->GetItem(ATTR_LINEBREAK
)).GetValue() ||
5369 ((SvxCellHorJustify
)static_cast<const SvxHorJustifyItem
&>(pPattern
->
5370 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
);
5371 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)static_cast<const SvxHorJustifyItem
&>(pPattern
->
5372 GetItem(ATTR_HOR_JUSTIFY
)).GetValue();
5376 boost::shared_ptr
<ScFieldEditEngine
> pEngine
= createEditEngine(pDocSh
, *pPattern
);
5378 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
); // ohne Drawing-Skalierung
5379 Rectangle aLogicEdit
= PixelToLogic( aEditRect
, aEditMode
);
5380 long nThisColLogic
= aLogicEdit
.Right() - aLogicEdit
.Left() + 1;
5381 Size aPaperSize
= Size( 1000000, 1000000 );
5382 if (aCell
.meType
== CELLTYPE_FORMULA
)
5386 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
5387 aPaperSize
= Size(nSizeX
, nSizeY
);
5388 aPaperSize
= PixelToLogic(aPaperSize
);
5392 aPaperSize
.Width() = nThisColLogic
;
5393 pEngine
->SetPaperSize( aPaperSize
);
5395 std::unique_ptr
<EditTextObject
> pTextObj
;
5396 if (aCell
.meType
== CELLTYPE_EDIT
)
5398 if (aCell
.mpEditText
)
5399 pEngine
->SetText(*aCell
.mpEditText
);
5401 else // Not an Edit cell and is a formula cell with 'Hyperlink'
5402 // function if we have no URL, otherwise it could be a formula
5403 // cell ( or other type ? ) with a hyperlink associated with it.
5406 pTextObj
.reset(aCell
.mpFormula
->CreateURLObject());
5408 pTextObj
.reset(ScEditUtil::CreateURLObjectFromURL(rDoc
, sURL
, sURL
));
5411 pEngine
->SetText(*pTextObj
);
5414 long nStartX
= aLogicEdit
.Left();
5416 long nTextWidth
= pEngine
->CalcTextWidth();
5417 long nTextHeight
= pEngine
->GetTextHeight();
5418 if ( nTextWidth
< nThisColLogic
)
5420 if (eHorJust
== SVX_HOR_JUSTIFY_RIGHT
)
5421 nStartX
+= nThisColLogic
- nTextWidth
;
5422 else if (eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
5423 nStartX
+= (nThisColLogic
- nTextWidth
) / 2;
5426 aLogicEdit
.Left() = nStartX
;
5428 aLogicEdit
.Right() = nStartX
+ nTextWidth
;
5430 // There is one glitch when dealing with a hyperlink cell and
5431 // the cell content is NUMERIC. This defaults to right aligned and
5432 // we need to adjust accordingly.
5433 if (aCell
.meType
== CELLTYPE_FORMULA
&& aCell
.mpFormula
->IsValue() &&
5434 eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
5436 aLogicEdit
.Right() = aLogicEdit
.Left() + nThisColLogic
- 1;
5437 aLogicEdit
.Left() = aLogicEdit
.Right() - nTextWidth
;
5439 aLogicEdit
.Bottom() = aLogicEdit
.Top() + nTextHeight
;
5441 Point aLogicClick
= PixelToLogic(rPos
,aEditMode
);
5442 if ( aLogicEdit
.IsInside(aLogicClick
) )
5444 EditView
aTempView(pEngine
.get(), this);
5445 aTempView
.SetOutputArea( aLogicEdit
);
5447 MapMode aOld
= GetMapMode();
5448 SetMapMode(aEditMode
); // kein return mehr
5449 bool bRet
= extractURLInfo(aTempView
.GetFieldUnderMousePointer(), pName
, pUrl
, pTarget
);
5457 bool ScGridWindow::IsSpellErrorAtPos( const Point
& rPos
, SCCOL nCol1
, SCROW nRow
)
5459 if (!mpSpellCheckCxt
)
5462 SCTAB nTab
= pViewData
->GetTabNo();
5463 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5464 ScDocument
& rDoc
= pDocSh
->GetDocument();
5466 ScAddress
aCellPos(nCol1
, nRow
, nTab
);
5467 ScRefCellValue aCell
;
5468 aCell
.assign(rDoc
, aCellPos
);
5469 if (aCell
.meType
!= CELLTYPE_STRING
&& aCell
.meType
!= CELLTYPE_EDIT
)
5472 const std::vector
<editeng::MisspellRanges
>* pRanges
= mpSpellCheckCxt
->getMisspellRanges(nCol1
, nRow
);
5476 const ScPatternAttr
* pPattern
= rDoc
.GetPattern(nCol1
, nRow
, nTab
);
5478 Rectangle aEditRect
= pViewData
->GetEditArea(eWhich
, nCol1
, nRow
, this, pPattern
, false);
5479 if (rPos
.Y() < aEditRect
.Top())
5482 boost::shared_ptr
<ScFieldEditEngine
> pEngine
= createEditEngine(pDocSh
, *pPattern
);
5484 Size aPaperSize
= Size(1000000, 1000000);
5485 pEngine
->SetPaperSize(aPaperSize
);
5487 if (aCell
.meType
== CELLTYPE_EDIT
)
5488 pEngine
->SetText(*aCell
.mpEditText
);
5490 pEngine
->SetText(aCell
.mpString
->getString());
5492 long nTextWidth
= static_cast<long>(pEngine
->CalcTextWidth());
5494 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
);
5495 Rectangle aLogicEdit
= PixelToLogic(aEditRect
, aEditMode
);
5496 Point aLogicClick
= PixelToLogic(rPos
, aEditMode
);
5498 aLogicEdit
.setWidth(nTextWidth
+ 1);
5500 if (!aLogicEdit
.IsInside(aLogicClick
))
5503 pEngine
->SetControlWord(pEngine
->GetControlWord() | EEControlBits::ONLINESPELLING
);
5504 pEngine
->SetAllMisspellRanges(*pRanges
);
5506 EditView
aTempView(pEngine
.get(), this);
5507 aTempView
.SetOutputArea(aLogicEdit
);
5509 return aTempView
.IsWrongSpelledWordAtPos(rPos
);
5512 bool ScGridWindow::HasScenarioButton( const Point
& rPosPixel
, ScRange
& rScenRange
)
5514 ScDocument
* pDoc
= pViewData
->GetDocument();
5515 SCTAB nTab
= pViewData
->GetTabNo();
5516 SCTAB nTabCount
= pDoc
->GetTableCount();
5517 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
5519 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5521 Size aButSize
= pViewData
->GetScenButSize();
5522 long nBWidth
= aButSize
.Width();
5524 return false; // noch kein Button gezeichnet -> da ist auch keiner
5525 long nBHeight
= aButSize
.Height();
5526 long nHSpace
= (long)( SC_SCENARIO_HSPACE
* pViewData
->GetPPTX() );
5528 //! Ranges an der Table cachen!!!!
5531 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
5532 pDoc
->MarkScenario( i
, nTab
, aMarks
, false, SC_SCENARIO_SHOWFRAME
);
5533 ScRangeList aRanges
;
5534 aMarks
.FillRangeListWithMarks( &aRanges
, false );
5536 size_t nRangeCount
= aRanges
.size();
5537 for (size_t j
=0; j
< nRangeCount
; ++j
)
5539 ScRange aRange
= *aRanges
[j
];
5540 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5541 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5542 pDoc
->ExtendTotalMerge( aRange
);
5544 bool bTextBelow
= ( aRange
.aStart
.Row() == 0 );
5549 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1,
5554 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aStart
.Row(),
5556 aButtonPos
.Y() -= nBHeight
;
5559 aButtonPos
.X() -= nHSpace
- 1;
5561 aButtonPos
.X() -= nBWidth
- nHSpace
; // same for top or bottom
5563 Rectangle
aButRect( aButtonPos
, Size(nBWidth
,nBHeight
) );
5564 if ( aButRect
.IsInside( rPosPixel
) )
5566 rScenRange
= aRange
;
5576 void ScGridWindow::DrawLayerCreated()
5578 SetMapMode( GetDrawMapMode() );
5580 // initially create overlay objects
5581 ImpCreateOverlayObjects();
5586 struct SpellCheckStatus
5590 SpellCheckStatus() : mbModified(false) {};
5592 DECL_LINK (EventHdl
, EditStatus
*);
5595 IMPL_LINK(SpellCheckStatus
, EventHdl
, EditStatus
*, pStatus
)
5597 EditStatusFlags nStatus
= pStatus
->GetStatusWord();
5598 if (nStatus
& EditStatusFlags::WRONGWORDCHANGED
)
5606 bool ScGridWindow::ContinueOnlineSpelling()
5608 if (!mpSpellCheckCxt
)
5611 if (!mpSpellCheckCxt
->maPos
.isValid())
5614 ScDocument
* pDoc
= pViewData
->GetDocument();
5615 ScDPCollection
* pDPs
= NULL
;
5616 if (pDoc
->HasPivotTable())
5617 pDPs
= pDoc
->GetDPCollection();
5619 SCTAB nTab
= pViewData
->GetTabNo();
5620 SpellCheckStatus aStatus
;
5622 ScHorizontalCellIterator
aIter(
5623 pDoc
, nTab
, maVisibleRange
.mnCol1
, mpSpellCheckCxt
->maPos
.mnRow
, maVisibleRange
.mnCol2
, maVisibleRange
.mnRow2
);
5625 ScRangeList aPivotRanges
;
5627 aPivotRanges
= pDPs
->GetAllTableRanges(nTab
);
5631 ScRefCellValue
* pCell
= aIter
.GetNext(nCol
, nRow
);
5632 while (pCell
&& nRow
< mpSpellCheckCxt
->maPos
.mnRow
)
5633 pCell
= aIter
.GetNext(nCol
, nRow
);
5635 while (pCell
&& nCol
< mpSpellCheckCxt
->maPos
.mnCol
)
5636 pCell
= aIter
.GetNext(nCol
, nRow
);
5638 std::unique_ptr
<ScTabEditEngine
> pEngine
;
5640 // Check only up to 256 cells at a time.
5641 size_t nTotalCellCount
= 0;
5642 size_t nTextCellCount
= 0;
5643 bool bSpellCheckPerformed
= false;
5649 if (aPivotRanges
.In(ScAddress(nCol
, nRow
, nTab
)))
5651 // Don't spell check within pivot tables.
5652 if (nTotalCellCount
>= 255)
5655 pCell
= aIter
.GetNext(nCol
, nRow
);
5659 CellType eType
= pCell
->meType
;
5660 if (eType
== CELLTYPE_STRING
|| eType
== CELLTYPE_EDIT
)
5666 // ScTabEditEngine is needed
5667 // because MapMode must be set for some old documents
5668 pEngine
.reset(new ScTabEditEngine(pDoc
));
5669 pEngine
->SetControlWord(
5670 pEngine
->GetControlWord() | (EEControlBits::ONLINESPELLING
| EEControlBits::ALLOWBIGOBJS
));
5671 pEngine
->SetStatusEventHdl(LINK(&aStatus
, SpellCheckStatus
, EventHdl
));
5672 // Delimiters hier wie in inputhdl.cxx !!!
5673 pEngine
->SetWordDelimiters(
5674 ScEditUtil::ModifyDelimiters(pEngine
->GetWordDelimiters()));
5676 uno::Reference
<linguistic2::XSpellChecker1
> xXSpellChecker1(LinguMgr::GetSpellChecker());
5677 pEngine
->SetSpeller(xXSpellChecker1
);
5680 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nCol
, nRow
, nTab
);
5681 sal_uInt16 nCellLang
=
5682 static_cast<const SvxLanguageItem
&>(pPattern
->GetItem(ATTR_FONT_LANGUAGE
)).GetValue();
5683 if (nCellLang
== LANGUAGE_SYSTEM
)
5684 nCellLang
= Application::GetSettings().GetLanguageTag().getLanguageType(); // never use SYSTEM for spelling
5685 pEngine
->SetDefaultLanguage(nCellLang
);
5687 if (eType
== CELLTYPE_STRING
)
5688 pEngine
->SetText(pCell
->mpString
->getString());
5690 pEngine
->SetText(*pCell
->mpEditText
);
5692 aStatus
.mbModified
= false;
5693 pEngine
->CompleteOnlineSpelling();
5694 if (aStatus
.mbModified
)
5696 std::vector
<editeng::MisspellRanges
> aRanges
;
5697 pEngine
->GetAllMisspellRanges(aRanges
);
5698 if (!aRanges
.empty())
5700 sc::SpellCheckContext::CellPos
aPos(nCol
, nRow
);
5701 mpSpellCheckCxt
->maMisspellCells
.insert(
5702 sc::SpellCheckContext::CellMapType::value_type(aPos
, aRanges
));
5705 // Broadcast for re-paint.
5706 ScPaintHint
aHint(ScRange(nCol
, nRow
, nTab
), PAINT_GRID
);
5707 aHint
.SetPrintFlag(false);
5708 pDoc
->GetDocumentShell()->Broadcast(aHint
);
5711 bSpellCheckPerformed
= true;
5714 if (nTotalCellCount
>= 255 || nTextCellCount
>= 1)
5717 pCell
= aIter
.GetNext(nCol
, nRow
);
5721 // Move to the next cell position for the next iteration.
5722 pCell
= aIter
.GetNext(nCol
, nRow
);
5726 // This will become the first cell position for the next time.
5727 mpSpellCheckCxt
->maPos
.mnCol
= nCol
;
5728 mpSpellCheckCxt
->maPos
.mnRow
= nRow
;
5732 // No more cells to spell check.
5733 mpSpellCheckCxt
->maPos
.setInvalid();
5736 return bSpellCheckPerformed
;
5739 void ScGridWindow::EnableAutoSpell( bool bEnable
)
5742 mpSpellCheckCxt
.reset(new sc::SpellCheckContext
);
5744 mpSpellCheckCxt
.reset();
5747 void ScGridWindow::ResetAutoSpell()
5749 if (mpSpellCheckCxt
)
5751 mpSpellCheckCxt
->reset();
5752 mpSpellCheckCxt
->maPos
.mnCol
= maVisibleRange
.mnCol1
;
5753 mpSpellCheckCxt
->maPos
.mnRow
= maVisibleRange
.mnRow1
;
5757 void ScGridWindow::SetAutoSpellData( SCCOL nPosX
, SCROW nPosY
, const std::vector
<editeng::MisspellRanges
>* pRanges
)
5759 if (!mpSpellCheckCxt
)
5762 if (!maVisibleRange
.isInside(nPosX
, nPosY
))
5765 mpSpellCheckCxt
->setMisspellRanges(nPosX
, nPosY
, pRanges
);
5768 const std::vector
<editeng::MisspellRanges
>* ScGridWindow::GetAutoSpellData( SCCOL nPosX
, SCROW nPosY
)
5770 if (!mpSpellCheckCxt
)
5773 if (!maVisibleRange
.isInside(nPosX
, nPosY
))
5776 return mpSpellCheckCxt
->getMisspellRanges(nPosX
, nPosY
);
5779 bool ScGridWindow::InsideVisibleRange( SCCOL nPosX
, SCROW nPosY
)
5781 return maVisibleRange
.isInside(nPosX
, nPosY
);
5785 void ScGridWindow::CursorChanged()
5787 // here the created OverlayObjects may be transformed in later versions. For
5788 // now, just re-create them
5790 UpdateCursorOverlay();
5794 void ScGridWindow::ImpCreateOverlayObjects()
5796 UpdateCursorOverlay();
5797 UpdateCopySourceOverlay();
5798 UpdateSelectionOverlay();
5799 UpdateAutoFillOverlay();
5800 UpdateDragRectOverlay();
5801 UpdateHeaderOverlay();
5802 UpdateShrinkOverlay();
5806 void ScGridWindow::ImpDestroyOverlayObjects()
5808 DeleteCursorOverlay();
5809 DeleteCopySourceOverlay();
5810 DeleteSelectionOverlay();
5811 DeleteAutoFillOverlay();
5812 DeleteDragRectOverlay();
5813 DeleteHeaderOverlay();
5814 DeleteShrinkOverlay();
5817 void ScGridWindow::UpdateAllOverlays()
5819 // delete and re-allocate all overlay objects
5821 ImpDestroyOverlayObjects();
5822 ImpCreateOverlayObjects();
5825 void ScGridWindow::DeleteCursorOverlay()
5827 mpOOCursors
.reset();
5830 void ScGridWindow::DeleteCopySourceOverlay()
5832 mpOOSelectionBorder
.reset();
5835 void ScGridWindow::UpdateCopySourceOverlay()
5837 MapMode aDrawMode
= GetDrawMapMode();
5838 MapMode aOldMode
= GetMapMode();
5839 if ( aOldMode
!= aDrawMode
)
5840 SetMapMode( aDrawMode
);
5842 DeleteCopySourceOverlay();
5844 if (!pViewData
->ShowPasteSource())
5846 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5847 if (!xOverlayManager
.is())
5849 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard( pViewData
->GetActiveWin() );
5852 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
5856 SCTAB nCurTab
= pViewData
->GetCurPos().Tab();
5858 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
5859 mpOOSelectionBorder
.reset(new sdr::overlay::OverlayObjectList
);
5860 for ( size_t i
= 0; i
< rClipParam
.maRanges
.size(); ++i
)
5862 ScRange
* p
= rClipParam
.maRanges
[i
];
5863 if (p
->aStart
.Tab() != nCurTab
)
5866 SCCOL nClipStartX
= p
->aStart
.Col();
5867 SCROW nClipStartY
= p
->aStart
.Row();
5868 SCCOL nClipEndX
= p
->aEnd
.Col();
5869 SCROW nClipEndY
= p
->aEnd
.Row();
5871 Point aClipStartScrPos
= pViewData
->GetScrPos( nClipStartX
, nClipStartY
, eWhich
);
5872 Point aClipEndScrPos
= pViewData
->GetScrPos( nClipEndX
+ 1, nClipEndY
+ 1, eWhich
);
5873 aClipStartScrPos
-= Point(1, 1);
5874 long nSizeXPix
= aClipEndScrPos
.X() - aClipStartScrPos
.X();
5875 long nSizeYPix
= aClipEndScrPos
.Y() - aClipStartScrPos
.Y();
5877 Rectangle
aRect( aClipStartScrPos
, Size(nSizeXPix
, nSizeYPix
) );
5879 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5881 Rectangle aLogic
= PixelToLogic(aRect
, aDrawMode
);
5882 ::basegfx::B2DRange
aRange(aLogic
.Left(), aLogic
.Top(), aLogic
.Right(), aLogic
.Bottom());
5883 ScOverlayDashedBorder
* pDashedBorder
= new ScOverlayDashedBorder(aRange
, aHighlight
);
5884 xOverlayManager
->add(*pDashedBorder
);
5885 mpOOSelectionBorder
->append(*pDashedBorder
);
5888 if ( aOldMode
!= aDrawMode
)
5889 SetMapMode( aOldMode
);
5892 /// Turn the selection ranges rRectangles into the LibreOfficeKit selection, and call the callback.
5893 static void updateLibreOfficeKitSelection(ScViewData
* pViewData
, ScDrawLayer
* pDrawLayer
, const std::vector
<Rectangle
>& rRectangles
)
5895 if (!pDrawLayer
->isTiledRendering())
5898 double nPPTX
= pViewData
->GetPPTX();
5899 double nPPTY
= pViewData
->GetPPTY();
5901 Rectangle aBoundingBox
;
5902 std::stringstream ss
;
5904 bool bIsFirst
= true;
5905 for (auto aRectangle
: rRectangles
)
5907 aRectangle
.Right() += 1;
5908 aRectangle
.Bottom() += 1;
5910 aBoundingBox
.Union(aRectangle
);
5917 Rectangle
aRect(aRectangle
.Left() / nPPTX
, aRectangle
.Top() / nPPTY
,
5918 aRectangle
.Right() / nPPTX
, aRectangle
.Bottom() / nPPTY
);
5919 ss
<< aRect
.toString().getStr();
5922 // selection start handle
5923 Rectangle
aStart(aBoundingBox
.Left() / nPPTX
, aBoundingBox
.Top() / nPPTY
,
5924 aBoundingBox
.Left() / nPPTX
, (aBoundingBox
.Top() / nPPTY
) + 256);
5925 pDrawLayer
->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_START
, aStart
.toString().getStr());
5927 // selection end handle
5928 Rectangle
aEnd(aBoundingBox
.Right() / nPPTX
, (aBoundingBox
.Bottom() / nPPTY
) - 256,
5929 aBoundingBox
.Right() / nPPTX
, aBoundingBox
.Bottom() / nPPTY
);
5930 pDrawLayer
->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_END
, aEnd
.toString().getStr());
5932 // the selection itself
5933 pDrawLayer
->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION
, ss
.str().c_str());
5936 void ScGridWindow::UpdateCursorOverlay()
5938 ScDocument
* pDoc
= pViewData
->GetDocument();
5940 // never show the cell cursor when the tiled rendering is going on; either
5941 // we want to show the editeng selection, or the cell selection, but not
5942 // the cell cursor by itself
5943 if (pDoc
->GetDrawLayer()->isTiledRendering())
5946 MapMode aDrawMode
= GetDrawMapMode();
5947 MapMode aOldMode
= GetMapMode();
5948 if ( aOldMode
!= aDrawMode
)
5949 SetMapMode( aDrawMode
);
5951 // Existing OverlayObjects may be transformed in later versions.
5952 // For now, just re-create them.
5954 DeleteCursorOverlay();
5956 std::vector
<Rectangle
> aPixelRects
;
5958 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5960 SCTAB nTab
= pViewData
->GetTabNo();
5961 SCCOL nX
= pViewData
->GetCurX();
5962 SCROW nY
= pViewData
->GetCurY();
5964 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nX
,nY
,nTab
);
5966 if (!maVisibleRange
.isInside(nX
, nY
))
5968 if (maVisibleRange
.mnCol2
< nX
|| maVisibleRange
.mnRow2
< nY
)
5969 return; // no further check needed, nothing visible
5971 // fdo#87382 Also display the cell cursor for the visible part of
5972 // merged cells if the view position is part of merged cells.
5973 const ScMergeAttr
& rMerge
= static_cast<const ScMergeAttr
&>(pPattern
->GetItem(ATTR_MERGE
));
5974 if (rMerge
.GetColMerge() <= 1 && rMerge
.GetRowMerge() <= 1)
5975 return; // not merged and invisible
5977 SCCOL nX2
= nX
+ rMerge
.GetColMerge() - 1;
5978 SCROW nY2
= nY
+ rMerge
.GetRowMerge() - 1;
5979 // Check if the middle or tail of the merged range is visible.
5980 if (!(maVisibleRange
.mnCol1
<= nX2
&& maVisibleRange
.mnRow1
<= nY2
))
5981 return; // no visible part
5984 // don't show the cursor in overlapped cells
5986 const ScMergeFlagAttr
& rMergeFlag
= static_cast<const ScMergeFlagAttr
&>( pPattern
->GetItem(ATTR_MERGE_FLAG
) );
5987 bool bOverlapped
= rMergeFlag
.IsOverlapped();
5989 // left or above of the screen?
5991 bool bVis
= ( nX
>=pViewData
->GetPosX(eHWhich
) && nY
>=pViewData
->GetPosY(eVWhich
) );
5996 const ScMergeAttr
& rMerge
= static_cast<const ScMergeAttr
&>( pPattern
->GetItem(ATTR_MERGE
) );
5997 if (rMerge
.GetColMerge() > 1)
5998 nEndX
+= rMerge
.GetColMerge()-1;
5999 if (rMerge
.GetRowMerge() > 1)
6000 nEndY
+= rMerge
.GetRowMerge()-1;
6001 bVis
= ( nEndX
>=pViewData
->GetPosX(eHWhich
) && nEndY
>=pViewData
->GetPosY(eVWhich
) );
6004 if ( bVis
&& !bOverlapped
&& !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
6006 Point aScrPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, true );
6007 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
6009 // completely right of/below the screen?
6010 // (test with logical start position in aScrPos)
6013 bMaybeVisible
= ( aScrPos
.X() >= -2 && aScrPos
.Y() >= -2 );
6016 Size aOutSize
= GetOutputSizePixel();
6017 bMaybeVisible
= ( aScrPos
.X() <= aOutSize
.Width() + 2 && aScrPos
.Y() <= aOutSize
.Height() + 2 );
6020 // in the tiled rendering case, don't limit to the screen size
6025 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
6028 aScrPos
.X() -= nSizeXPix
- 2; // move instead of mirroring
6030 // show the cursor as 4 (thin) rectangles
6031 Rectangle
aRect(aScrPos
, Size(nSizeXPix
- 1, nSizeYPix
- 1));
6033 sal_Int32 nScale
= GetDPIScaleFactor();
6035 long aCursorWidth
= 1 * nScale
;
6037 Rectangle aLeft
= Rectangle(aRect
);
6038 aLeft
.Top() -= aCursorWidth
;
6039 aLeft
.Bottom() += aCursorWidth
;
6040 aLeft
.Right() = aLeft
.Left();
6041 aLeft
.Left() -= aCursorWidth
;
6043 Rectangle aRight
= Rectangle(aRect
);
6044 aRight
.Top() -= aCursorWidth
;
6045 aRight
.Bottom() += aCursorWidth
;
6046 aRight
.Left() = aRight
.Right();
6047 aRight
.Right() += aCursorWidth
;
6049 Rectangle aTop
= Rectangle(aRect
);
6050 aTop
.Bottom() = aTop
.Top();
6051 aTop
.Top() -= aCursorWidth
;
6053 Rectangle aBottom
= Rectangle(aRect
);
6054 aBottom
.Top() = aBottom
.Bottom();
6055 aBottom
.Bottom() += aCursorWidth
;
6057 aPixelRects
.push_back(aLeft
);
6058 aPixelRects
.push_back(aRight
);
6059 aPixelRects
.push_back(aTop
);
6060 aPixelRects
.push_back(aBottom
);
6064 if ( !aPixelRects
.empty() )
6066 // #i70788# get the OverlayManager safely
6067 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6069 if (xOverlayManager
.is())
6071 Color
aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
6072 if (pViewData
->GetActivePart() != eWhich
)
6073 // non-active pane uses a different color.
6074 aCursorColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
6075 std::vector
< basegfx::B2DRange
> aRanges
;
6076 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6078 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
6080 const Rectangle
aRA(aPixelRects
[a
]);
6081 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
6082 aRB
.transform(aTransform
);
6083 aRanges
.push_back(aRB
);
6086 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6087 sdr::overlay::OVERLAY_SOLID
,
6092 xOverlayManager
->add(*pOverlay
);
6093 mpOOCursors
.reset(new sdr::overlay::OverlayObjectList
);
6094 mpOOCursors
->append(*pOverlay
);
6096 // notify the LibreOfficeKit too
6097 updateLibreOfficeKitSelection(pViewData
, pDoc
->GetDrawLayer(), aPixelRects
);
6101 if ( aOldMode
!= aDrawMode
)
6102 SetMapMode( aOldMode
);
6105 void ScGridWindow::DeleteSelectionOverlay()
6107 mpOOSelection
.reset();
6110 void ScGridWindow::UpdateSelectionOverlay()
6112 MapMode aDrawMode
= GetDrawMapMode();
6113 MapMode aOldMode
= GetMapMode();
6114 if ( aOldMode
!= aDrawMode
)
6115 SetMapMode( aDrawMode
);
6117 DeleteSelectionOverlay();
6118 std::vector
<Rectangle
> aPixelRects
;
6119 GetSelectionRects( aPixelRects
);
6121 if (!aPixelRects
.empty() && pViewData
->IsActive())
6123 // #i70788# get the OverlayManager safely
6124 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6126 if (xOverlayManager
.is())
6128 std::vector
< basegfx::B2DRange
> aRanges
;
6129 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6130 ScDocument
* pDoc
= pViewData
->GetDocument();
6131 SCTAB nTab
= pViewData
->GetTabNo();
6132 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
6134 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
6136 const Rectangle
aRA(aPixelRects
[a
]);
6139 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top() - 1, aRA
.Right() + 1, aRA
.Bottom());
6140 aRB
.transform(aTransform
);
6141 aRanges
.push_back(aRB
);
6145 basegfx::B2DRange
aRB(aRA
.Left() - 1, aRA
.Top() - 1, aRA
.Right(), aRA
.Bottom());
6146 aRB
.transform(aTransform
);
6147 aRanges
.push_back(aRB
);
6151 // get the system's highlight color
6152 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
6153 const Color
aHighlight(aSvtOptionsDrawinglayer
.getHilightColor());
6155 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6156 sdr::overlay::OVERLAY_TRANSPARENT
,
6161 xOverlayManager
->add(*pOverlay
);
6162 mpOOSelection
.reset(new sdr::overlay::OverlayObjectList
);
6163 mpOOSelection
->append(*pOverlay
);
6165 // notify the LibreOfficeKit too
6166 updateLibreOfficeKitSelection(pViewData
, pDoc
->GetDrawLayer(), aPixelRects
);
6170 if ( aOldMode
!= aDrawMode
)
6171 SetMapMode( aOldMode
);
6174 void ScGridWindow::DeleteAutoFillOverlay()
6176 mpOOAutoFill
.reset();
6177 mpAutoFillRect
.reset();
6180 void ScGridWindow::UpdateAutoFillOverlay()
6182 MapMode aDrawMode
= GetDrawMapMode();
6183 MapMode aOldMode
= GetMapMode();
6184 if ( aOldMode
!= aDrawMode
)
6185 SetMapMode( aDrawMode
);
6187 DeleteAutoFillOverlay();
6189 // get the AutoFill handle rectangle in pixels
6191 if ( bAutoMarkVisible
&& aAutoMarkPos
.Tab() == pViewData
->GetTabNo() &&
6192 !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
6194 SCCOL nX
= aAutoMarkPos
.Col();
6195 SCROW nY
= aAutoMarkPos
.Row();
6197 if (!maVisibleRange
.isInside(nX
, nY
))
6198 // Autofill mark is not visible. Bail out.
6201 SCTAB nTab
= pViewData
->GetTabNo();
6202 ScDocument
* pDoc
= pViewData
->GetDocument();
6203 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
6205 sal_Int32 nScale
= GetDPIScaleFactor();
6206 // Size should be even
6207 Size aFillHandleSize
= Size(6 * nScale
, 6 * nScale
);
6209 Point aFillPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, true );
6212 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
6215 aFillPos
.X() -= nSizeXPix
- 2 + (aFillHandleSize
.Width() / 2);
6217 aFillPos
.X() += nSizeXPix
- (aFillHandleSize
.Width() / 2);
6219 aFillPos
.Y() += nSizeYPix
;
6220 aFillPos
.Y() -= (aFillHandleSize
.Height() / 2);
6222 Rectangle
aFillRect(aFillPos
, aFillHandleSize
);
6224 // expand rect to increase hit area
6225 mpAutoFillRect
.reset(new Rectangle(aFillRect
.Left() - nScale
,
6226 aFillRect
.Top() - nScale
,
6227 aFillRect
.Right() + nScale
,
6228 aFillRect
.Bottom() + nScale
));
6230 // #i70788# get the OverlayManager safely
6231 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6233 if (xOverlayManager
.is())
6235 Color
aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
6236 if (pViewData
->GetActivePart() != eWhich
)
6237 // non-active pane uses a different color.
6238 aHandleColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
6239 std::vector
< basegfx::B2DRange
> aRanges
;
6240 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6241 basegfx::B2DRange
aRB(aFillRect
.Left(), aFillRect
.Top(), aFillRect
.Right(), aFillRect
.Bottom());
6243 aRB
.transform(aTransform
);
6244 aRanges
.push_back(aRB
);
6246 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6247 sdr::overlay::OVERLAY_SOLID
,
6252 xOverlayManager
->add(*pOverlay
);
6253 mpOOAutoFill
.reset(new sdr::overlay::OverlayObjectList
);
6254 mpOOAutoFill
->append(*pOverlay
);
6257 if ( aOldMode
!= aDrawMode
)
6258 SetMapMode( aOldMode
);
6262 void ScGridWindow::DeleteDragRectOverlay()
6264 mpOODragRect
.reset();
6267 void ScGridWindow::UpdateDragRectOverlay()
6269 MapMode aDrawMode
= GetDrawMapMode();
6270 MapMode aOldMode
= GetMapMode();
6271 if ( aOldMode
!= aDrawMode
)
6272 SetMapMode( aDrawMode
);
6274 DeleteDragRectOverlay();
6276 // get the rectangles in pixels (moved from DrawDragRect)
6278 if ( bDragRect
|| bPagebreakDrawn
)
6280 std::vector
<Rectangle
> aPixelRects
;
6282 SCCOL nX1
= bDragRect
? nDragStartX
: aPagebreakDrag
.aStart
.Col();
6283 SCROW nY1
= bDragRect
? nDragStartY
: aPagebreakDrag
.aStart
.Row();
6284 SCCOL nX2
= bDragRect
? nDragEndX
: aPagebreakDrag
.aEnd
.Col();
6285 SCROW nY2
= bDragRect
? nDragEndY
: aPagebreakDrag
.aEnd
.Row();
6287 SCTAB nTab
= pViewData
->GetTabNo();
6289 SCCOL nPosX
= pViewData
->GetPosX(WhichH(eWhich
));
6290 SCROW nPosY
= pViewData
->GetPosY(WhichV(eWhich
));
6291 if (nX1
< nPosX
) nX1
= nPosX
;
6292 if (nX2
< nPosX
) nX2
= nPosX
;
6293 if (nY1
< nPosY
) nY1
= nPosY
;
6294 if (nY2
< nPosY
) nY2
= nPosY
;
6296 Point
aScrPos( pViewData
->GetScrPos( nX1
, nY1
, eWhich
) );
6300 ScDocument
* pDoc
= pViewData
->GetDocument();
6301 double nPPTX
= pViewData
->GetPPTX();
6302 double nPPTY
= pViewData
->GetPPTY();
6305 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
6306 long nLayoutSign
= bLayoutRTL
? -1 : 1;
6308 if (ValidCol(nX2
) && nX2
>=nX1
)
6309 for (i
=nX1
; i
<=nX2
; i
++)
6310 nSizeXPix
+= ScViewData::ToPixel( pDoc
->GetColWidth( static_cast<SCCOL
>(i
), nTab
), nPPTX
);
6313 aScrPos
.X() -= nLayoutSign
;
6317 if (ValidRow(nY2
) && nY2
>=nY1
)
6318 for (i
=nY1
; i
<=nY2
; i
++)
6319 nSizeYPix
+= ScViewData::ToPixel( pDoc
->GetRowHeight( i
, nTab
), nPPTY
);
6326 aScrPos
.X() -= 2 * nLayoutSign
;
6328 Rectangle
aRect( aScrPos
.X(), aScrPos
.Y(),
6329 aScrPos
.X() + ( nSizeXPix
+ 2 ) * nLayoutSign
, aScrPos
.Y() + nSizeYPix
+ 2 );
6332 aRect
.Left() = aRect
.Right(); // end position is left
6333 aRect
.Right() = aScrPos
.X();
6336 if ( meDragInsertMode
== INS_CELLSDOWN
)
6338 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top()+3, aRect
.Left()+1, aRect
.Bottom()-2 ) );
6339 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+3, aRect
.Right()-1, aRect
.Bottom()-2 ) );
6340 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top(), aRect
.Right()-1, aRect
.Top()+2 ) );
6341 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Bottom()-1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
6343 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
6345 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top()+1, aRect
.Left()+2, aRect
.Bottom()-1 ) );
6346 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
6347 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top()+1, aRect
.Right()-2, aRect
.Top()+1 ) );
6348 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-1, aRect
.Right()-2, aRect
.Bottom()-1 ) );
6352 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ) );
6353 aPixelRects
.push_back( Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ) );
6354 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ) );
6355 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ) );
6358 // #i70788# get the OverlayManager safely
6359 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6361 if (xOverlayManager
.is())
6363 std::vector
< basegfx::B2DRange
> aRanges
;
6364 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6366 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
6368 const Rectangle
aRA(aPixelRects
[a
]);
6369 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
6370 aRB
.transform(aTransform
);
6371 aRanges
.push_back(aRB
);
6374 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6375 sdr::overlay::OVERLAY_INVERT
,
6380 xOverlayManager
->add(*pOverlay
);
6381 mpOODragRect
.reset(new sdr::overlay::OverlayObjectList
);
6382 mpOODragRect
->append(*pOverlay
);
6386 if ( aOldMode
!= aDrawMode
)
6387 SetMapMode( aOldMode
);
6390 void ScGridWindow::DeleteHeaderOverlay()
6395 void ScGridWindow::UpdateHeaderOverlay()
6397 MapMode aDrawMode
= GetDrawMapMode();
6398 MapMode aOldMode
= GetMapMode();
6399 if ( aOldMode
!= aDrawMode
)
6400 SetMapMode( aDrawMode
);
6402 DeleteHeaderOverlay();
6404 // Pixel rectangle is in aInvertRect
6405 if ( !aInvertRect
.IsEmpty() )
6407 // #i70788# get the OverlayManager safely
6408 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6410 if (xOverlayManager
.is())
6412 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
6413 std::vector
< basegfx::B2DRange
> aRanges
;
6414 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6415 basegfx::B2DRange
aRB(aInvertRect
.Left(), aInvertRect
.Top(), aInvertRect
.Right() + 1, aInvertRect
.Bottom() + 1);
6417 aRB
.transform(aTransform
);
6418 aRanges
.push_back(aRB
);
6420 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6421 sdr::overlay::OVERLAY_INVERT
,
6426 xOverlayManager
->add(*pOverlay
);
6427 mpOOHeader
.reset(new sdr::overlay::OverlayObjectList
);
6428 mpOOHeader
->append(*pOverlay
);
6432 if ( aOldMode
!= aDrawMode
)
6433 SetMapMode( aOldMode
);
6436 void ScGridWindow::DeleteShrinkOverlay()
6441 void ScGridWindow::UpdateShrinkOverlay()
6443 MapMode aDrawMode
= GetDrawMapMode();
6444 MapMode aOldMode
= GetMapMode();
6445 if ( aOldMode
!= aDrawMode
)
6446 SetMapMode( aDrawMode
);
6448 DeleteShrinkOverlay();
6450 // get the rectangle in pixels
6454 SCTAB nTab
= pViewData
->GetTabNo();
6455 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() &&
6456 pViewData
->GetDelMark( aRange
) )
6458 //! limit to visible area
6459 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
6460 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
6462 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
6463 aRange
.aStart
.Row(), eWhich
);
6464 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
6465 aRange
.aEnd
.Row()+1, eWhich
);
6469 aPixRect
= Rectangle( aStart
,aEnd
);
6473 if ( !aPixRect
.IsEmpty() )
6475 // #i70788# get the OverlayManager safely
6476 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6478 if (xOverlayManager
.is())
6480 std::vector
< basegfx::B2DRange
> aRanges
;
6481 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6482 basegfx::B2DRange
aRB(aPixRect
.Left(), aPixRect
.Top(), aPixRect
.Right() + 1, aPixRect
.Bottom() + 1);
6484 aRB
.transform(aTransform
);
6485 aRanges
.push_back(aRB
);
6487 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6488 sdr::overlay::OVERLAY_INVERT
,
6493 xOverlayManager
->add(*pOverlay
);
6494 mpOOShrink
.reset(new sdr::overlay::OverlayObjectList
);
6495 mpOOShrink
->append(*pOverlay
);
6499 if ( aOldMode
!= aDrawMode
)
6500 SetMapMode( aOldMode
);
6503 // #i70788# central method to get the OverlayManager safely
6504 rtl::Reference
<sdr::overlay::OverlayManager
> ScGridWindow::getOverlayManager()
6506 SdrPageView
* pPV
= pViewData
->GetView()->GetScDrawView()->GetSdrPageView();
6510 SdrPageWindow
* pPageWin
= pPV
->FindPageWindow( *this );
6514 return (pPageWin
->GetOverlayManager());
6518 return rtl::Reference
<sdr::overlay::OverlayManager
>();
6521 void ScGridWindow::flushOverlayManager()
6523 // #i70788# get the OverlayManager safely
6524 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6526 if (xOverlayManager
.is())
6527 xOverlayManager
->flush();
6530 void ScGridWindow::SetInRefMode( bool bInRefMode
)
6532 WinBits nBits
= GetStyle();
6534 nBits
|= WB_REFMODE
;
6536 nBits
&= ~WB_REFMODE
;
6541 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */