1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "scitems.hxx"
24 #include <editeng/adjustitem.hxx>
25 #include <svx/algitem.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/editstat.hxx>
28 #include <editeng/flditem.hxx>
29 #include <editeng/justifyitem.hxx>
30 #include <editeng/unolingu.hxx>
31 #include <editeng/langitem.hxx>
32 #include <editeng/misspellrange.hxx>
33 #include <svx/svdetc.hxx>
34 #include <editeng/editobj.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <svl/stritem.hxx>
39 #include <svtools/svtabbx.hxx>
40 #include <svl/urlbmk.hxx>
41 #include <svl/sharedstringpool.hxx>
42 #include <vcl/cursor.hxx>
43 #include <vcl/graph.hxx>
44 #include <vcl/hatch.hxx>
45 #include <vcl/settings.hxx>
46 #include <sot/formats.hxx>
47 #include <comphelper/classids.hxx>
48 #include <sal/macros.h>
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>
139 #include <boost/scoped_ptr.hpp>
140 #include <boost/shared_ptr.hpp>
142 using namespace com::sun::star
;
143 using ::com::sun::star::uno::Sequence
;
144 using ::com::sun::star::uno::Any
;
146 const sal_uInt8 SC_NESTEDBUTTON_NONE
= 0;
147 const sal_uInt8 SC_NESTEDBUTTON_DOWN
= 1;
148 const sal_uInt8 SC_NESTEDBUTTON_UP
= 2;
150 #define SC_AUTOFILTER_ALL 0
151 #define SC_AUTOFILTER_TOP10 1
152 #define SC_AUTOFILTER_CUSTOM 2
153 #define SC_AUTOFILTER_EMPTY 3
154 #define SC_AUTOFILTER_NOTEMPTY 4
156 // Modi fuer die FilterListBox
160 SC_FILTERBOX_DATASELECT
,
161 SC_FILTERBOX_SCENARIO
,
162 SC_FILTERBOX_PAGEFIELD
165 extern SfxViewShell
* pScActiveViewShell
; // global.cxx
166 extern sal_uInt16 nScClickMouseModifier
; // global.cxx
167 extern sal_uInt16 nScFillModeMouseModifier
; // global.cxx
169 struct ScGridWindow::MouseEventState
173 MouseEventState() : mbActivatePart(false) {}
176 #define SC_FILTERLISTBOX_LINES 12
178 ScGridWindow::VisibleRange::VisibleRange() :
179 mnCol1(0), mnCol2(MAXCOL
), mnRow1(0), mnRow2(MAXROW
)
183 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol
, SCROW nRow
) const
185 return mnCol1
<= nCol
&& nCol
<= mnCol2
&& mnRow1
<= nRow
&& nRow
<= mnRow2
;
188 bool ScGridWindow::VisibleRange::set(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
190 bool bChanged
= mnCol1
!= nCol1
|| mnRow1
!= nRow1
|| mnCol2
!= nCol2
|| mnRow2
!= nRow2
;
200 class ScFilterListBox
: public ListBox
203 ScGridWindow
* pGridWin
;
212 ScFilterBoxMode eMode
;
215 virtual void LoseFocus() SAL_OVERRIDE
;
219 ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
220 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
);
221 virtual ~ScFilterListBox();
223 virtual bool PreNotify( NotifyEvent
& rNEvt
) SAL_OVERRIDE
;
224 virtual void Select() SAL_OVERRIDE
;
226 SCCOL
GetCol() const { return nCol
; }
227 SCROW
GetRow() const { return nRow
; }
228 ScFilterBoxMode
GetMode() const { return eMode
; }
230 bool IsInInit() const { return bInit
; }
231 void SetCancelled() { bCancelled
= true; }
232 bool IsInSelect() const { return bInSelect
; }
233 void SetListHasDates(bool b
) { mbListHasDates
= b
; }
234 bool HasDates() const { return mbListHasDates
; }
237 // ListBox in einem FloatingWindow (pParent)
238 ScFilterListBox::ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
239 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
) :
240 ListBox( pParent
, WB_AUTOHSCROLL
),
244 bButtonDown( false ),
248 mbListHasDates(false),
254 ScFilterListBox::~ScFilterListBox()
256 if (IsMouseCaptured())
260 void ScFilterListBox::EndInit()
262 sal_Int32 nPos
= GetSelectEntryPos();
263 if ( LISTBOX_ENTRY_NOTFOUND
== nPos
)
271 void ScFilterListBox::LoseFocus()
278 bool ScFilterListBox::PreNotify( NotifyEvent
& rNEvt
)
281 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
283 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
284 KeyCode aCode
= aKeyEvt
.GetKeyCode();
285 if ( !aCode
.GetModifier() ) // ohne alle Modifiers
287 sal_uInt16 nKey
= aCode
.GetCode();
288 if ( nKey
== KEY_RETURN
)
290 SelectHdl(); // auswaehlen
293 else if ( nKey
== KEY_ESCAPE
)
295 pGridWin
->ClickExtern(); // loescht die List-Box !!!
301 return nDone
|| ListBox::PreNotify( rNEvt
);
304 void ScFilterListBox::Select()
310 void ScFilterListBox::SelectHdl()
312 if ( !IsTravelSelect() && !bInit
&& !bCancelled
)
314 sal_Int32 nPos
= GetSelectEntryPos();
315 if ( LISTBOX_ENTRY_NOTFOUND
!= nPos
)
320 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
322 pGridWin
->FilterSelect( nSel
);
329 // use a System floating window for the above filter listbox
330 class ScFilterFloatingWindow
: public FloatingWindow
333 ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
= WB_STDFLOATWIN
);
334 virtual ~ScFilterFloatingWindow();
335 // required for System FloatingWindows that will not process KeyInput by themselves
336 virtual Window
* GetPreferredKeyInputWindow() SAL_OVERRIDE
;
339 ScFilterFloatingWindow::ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
) :
340 FloatingWindow( pParent
, nStyle
|WB_SYSTEMWINDOW
) // make it a system floater
343 ScFilterFloatingWindow::~ScFilterFloatingWindow()
348 Window
* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
350 // redirect keyinput in the child window
351 return GetWindow(WINDOW_FIRSTCHILD
) ? GetWindow(WINDOW_FIRSTCHILD
)->GetPreferredKeyInputWindow() : NULL
; // will be the FilterBox
354 static bool lcl_IsEditableMatrix( ScDocument
* pDoc
, const ScRange
& rRange
)
356 // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
357 // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
358 //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
360 if ( !pDoc
->IsBlockEditable( rRange
.aStart
.Tab(), rRange
.aStart
.Col(),rRange
.aStart
.Row(),
361 rRange
.aEnd
.Col(),rRange
.aEnd
.Row() ) )
364 ScRefCellValue aCell
;
365 aCell
.assign(*pDoc
, rRange
.aEnd
);
367 return (aCell
.meType
== CELLTYPE_FORMULA
&& aCell
.mpFormula
->GetMatrixOrigin(aPos
) && aPos
== rRange
.aStart
);
370 static void lcl_UnLockComment( ScDrawView
* pView
, const Point
& rPos
, ScViewData
* pViewData
)
372 if (!pView
|| !pViewData
)
375 ScDocument
& rDoc
= *pViewData
->GetDocument();
376 ScAddress
aCellPos( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
377 ScPostIt
* pNote
= rDoc
.GetNote( aCellPos
);
378 SdrObject
* pObj
= pNote
? pNote
->GetCaption() : 0;
379 if( pObj
&& pObj
->GetLogicRect().IsInside( rPos
) && ScDrawLayer::IsNoteCaption( pObj
) )
381 const ScProtectionAttr
* pProtAttr
= static_cast< const ScProtectionAttr
* > (rDoc
.GetAttr( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab(), ATTR_PROTECTION
) );
382 bool bProtectAttr
= pProtAttr
->GetProtection() || pProtAttr
->GetHideCell() ;
383 bool bProtectDoc
= rDoc
.IsTabProtected( aCellPos
.Tab() ) || pViewData
->GetSfxDocShell()->IsReadOnly() ;
384 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
385 pView
->LockInternalLayer( bProtectDoc
&& bProtectAttr
);
389 static bool lcl_GetHyperlinkCell(
390 ScDocument
* pDoc
, SCCOL
& rPosX
, SCROW
& rPosY
, SCTAB nTab
, ScRefCellValue
& rCell
, OUString
& rURL
)
395 ScAddress
aPos(rPosX
, rPosY
, nTab
);
396 rCell
.assign(*pDoc
, aPos
);
400 return false; // alles leer bis links
402 --rPosX
; // weitersuchen
406 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(aPos
);
407 if ( !((SfxStringItem
&)pPattern
->GetItem(ATTR_HYPERLINK
)).GetValue().isEmpty() )
409 rURL
= ((SfxStringItem
&)pPattern
->GetItem(ATTR_HYPERLINK
)).GetValue();
412 else if (rCell
.meType
== CELLTYPE_EDIT
)
414 else if (rCell
.meType
== CELLTYPE_FORMULA
&& rCell
.mpFormula
->IsHyperLinkCell())
417 return false; // andere Zelle
426 // WB_DIALOGCONTROL noetig fuer UNO-Controls
427 ScGridWindow::ScGridWindow( Window
* pParent
, ScViewData
* pData
, ScSplitPos eWhichPos
)
428 : Window( pParent
, WB_CLIPCHILDREN
| WB_DIALOGCONTROL
),
429 DropTargetHelper( this ),
430 DragSourceHelper( this ),
432 mpOOSelection( NULL
),
433 mpOOSelectionBorder( NULL
),
434 mpOOAutoFill( NULL
),
435 mpOODragRect( NULL
),
438 mpAutoFillRect(static_cast<Rectangle
*>(NULL
)),
443 pFilterFloat( NULL
),
444 mpAutoFilterPopup(NULL
),
445 mpDPFieldPopup(NULL
),
446 mpFilterButton(NULL
),
447 nCursorHideCount( 0 ),
449 nMouseStatus( SC_GM_NONE
),
450 nNestedButtonState( SC_NESTEDBUTTON_NONE
),
456 nPagebreakMouse( SC_PD_NONE
),
457 nPagebreakBreak( 0 ),
466 meDragInsertMode( INS_NONE
),
467 nCurrentPointer( 0 ),
468 aComboButton( this ),
471 aRFSelectedCorned( NONE
),
476 bPagebreakDrawn( false ),
478 bIsInScroll( false ),
480 bNeedsRepaint( false ),
481 bAutoMarkVisible( false ),
482 bListValButton( false )
486 case SC_SPLIT_TOPLEFT
:
487 eHWhich
= SC_SPLIT_LEFT
;
488 eVWhich
= SC_SPLIT_TOP
;
490 case SC_SPLIT_TOPRIGHT
:
491 eHWhich
= SC_SPLIT_RIGHT
;
492 eVWhich
= SC_SPLIT_TOP
;
494 case SC_SPLIT_BOTTOMLEFT
:
495 eHWhich
= SC_SPLIT_LEFT
;
496 eVWhich
= SC_SPLIT_BOTTOM
;
498 case SC_SPLIT_BOTTOMRIGHT
:
499 eHWhich
= SC_SPLIT_RIGHT
;
500 eVWhich
= SC_SPLIT_BOTTOM
;
503 OSL_FAIL("GridWindow: falsche Position");
508 SetMapMode(pViewData
->GetLogicMode(eWhich
));
509 EnableChildTransparentMode();
510 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN
| WINDOW_DLGCTRL_WANTFOCUS
);
512 SetHelpId( HID_SC_WIN_GRIDWIN
);
513 SetUniqueId( HID_SC_WIN_GRIDWIN
);
515 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
519 ScGridWindow::~ScGridWindow()
522 ImpDestroyOverlayObjects();
529 void ScGridWindow::Resize( const Size
& )
534 void ScGridWindow::ClickExtern()
538 // #i81298# don't delete the filter box when called from its select handler
539 // (possible through row header size update)
540 // #i84277# when initializing the filter box, a Basic error can deactivate the view
541 if ( pFilterBox
&& ( pFilterBox
->IsInSelect() || pFilterBox
->IsInInit() ) )
547 DELETEZ(pFilterFloat
);
553 mpDPFieldPopup
->close(false);
554 mpDPFieldPopup
.reset();
558 IMPL_LINK_NOARG(ScGridWindow
, PopupModeEndHdl
)
561 pFilterBox
->SetCancelled(); // nicht mehr auswaehlen
566 IMPL_LINK( ScGridWindow
, PopupSpellingHdl
, SpellCallbackInfo
*, pInfo
)
568 if( pInfo
->nCommand
== SPELLCMD_STARTSPELLDLG
)
569 pViewData
->GetDispatcher().Execute( SID_SPELL_DIALOG
, SFX_CALLMODE_ASYNCHRON
);
573 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol
, SCROW nRow
, bool bHasSelection
, const OUString
& rStr
)
577 ScDocument
* pDoc
= pViewData
->GetDocument();
578 SCTAB nTab
= pViewData
->GetTabNo();
579 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
580 if ( pDPObj
&& nCol
> 0 )
582 // look for the dimension header left of the drop-down arrow
583 sal_uInt16 nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
584 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
585 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
587 ScDPSaveData
aSaveData( *pDPObj
->GetSaveData() );
590 OUString aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
591 if ( !bIsDataLayout
)
593 ScDPSaveDimension
* pDim
= aSaveData
.GetDimensionByName(aDimName
);
597 const OUString aName
= rStr
;
598 pDim
->SetCurrentPage( &aName
);
601 pDim
->SetCurrentPage( NULL
);
603 ScDPObject
aNewObj( *pDPObj
);
604 aNewObj
.SetSaveData( aSaveData
);
605 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
606 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, true, false );
607 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
615 struct AutoFilterData
: public ScCheckListMenuWindow::ExtendedData
621 class AutoFilterAction
: public ScMenuFloatingWindow::Action
623 ScGridWindow
* mpWindow
;
624 ScGridWindow::AutoFilterMode meMode
;
626 AutoFilterAction(ScGridWindow
* p
, ScGridWindow::AutoFilterMode eMode
) :
627 mpWindow(p
), meMode(eMode
) {}
628 virtual void execute() SAL_OVERRIDE
630 mpWindow
->UpdateAutoFilterFromMenu(meMode
);
634 class AutoFilterPopupEndAction
: public ScMenuFloatingWindow::Action
636 ScGridWindow
* mpWindow
;
639 AutoFilterPopupEndAction(ScGridWindow
* p
, const ScAddress
& rPos
) :
640 mpWindow(p
), maPos(rPos
) {}
641 virtual void execute() SAL_OVERRIDE
643 mpWindow
->RefreshAutoFilterButton(maPos
);
647 class AddItemToEntry
: public std::unary_function
<OUString
, void>
649 ScQueryEntry::QueryItemsType
& mrItems
;
650 svl::SharedStringPool
& mrPool
;
652 AddItemToEntry(ScQueryEntry::QueryItemsType
& rItems
, svl::SharedStringPool
& rPool
) :
653 mrItems(rItems
), mrPool(rPool
) {}
654 void operator() (const OUString
& rSelected
)
656 ScQueryEntry::Item aNew
;
657 aNew
.maString
= mrPool
.intern(rSelected
);
658 aNew
.meType
= ScQueryEntry::ByString
;
660 mrItems
.push_back(aNew
);
664 class AddSelectedItemString
: public std::unary_function
<ScQueryEntry::Item
, void>
666 boost::unordered_set
<OUString
, OUStringHash
>& mrSet
;
668 AddSelectedItemString(boost::unordered_set
<OUString
, OUStringHash
>& r
) :
671 void operator() (const ScQueryEntry::Item
& rItem
)
673 mrSet
.insert(rItem
.maString
.getString());
679 void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol
, SCROW nRow
)
681 SCTAB nTab
= pViewData
->GetTabNo();
682 ScDocument
* pDoc
= pViewData
->GetDocument();
684 mpAutoFilterPopup
.reset(new ScCheckListMenuWindow(this, pDoc
));
685 mpAutoFilterPopup
->setOKAction(new AutoFilterAction(this, Normal
));
686 mpAutoFilterPopup
->setPopupEndAction(
687 new AutoFilterPopupEndAction(this, ScAddress(nCol
, nRow
, nTab
)));
688 std::auto_ptr
<AutoFilterData
> pData(new AutoFilterData
);
689 pData
->maPos
= ScAddress(nCol
, nRow
, nTab
);
691 Point aPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
694 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
695 Rectangle
aCellRect(OutputToScreenPixel(aPos
), Size(nSizeX
, nSizeY
));
697 ScDBData
* pDBData
= pDoc
->GetDBAtCursor(nCol
, nRow
, nTab
);
701 pData
->mpData
= pDBData
;
702 mpAutoFilterPopup
->setExtendedData(pData
.release());
705 pDBData
->GetQueryParam(aParam
);
706 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(nCol
, false);
707 boost::unordered_set
<OUString
, OUStringHash
> aSelected
;
708 if (pEntry
&& pEntry
->bDoQuery
)
710 if (pEntry
->eOp
== SC_EQUAL
)
712 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
713 std::for_each(rItems
.begin(), rItems
.end(), AddSelectedItemString(aSelected
));
717 // Populate the check box list.
718 bool bHasDates
= false;
719 std::vector
<ScTypedStrData
> aStrings
;
720 pDoc
->GetFilterEntries(nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
722 mpAutoFilterPopup
->setMemberSize(aStrings
.size());
723 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
724 for (; it
!= itEnd
; ++it
)
726 const OUString
& aVal
= it
->GetString();
727 bool bSelected
= true;
728 if (!aSelected
.empty())
729 bSelected
= aSelected
.count(aVal
) > 0;
731 mpAutoFilterPopup
->addDateMember( aVal
, it
->GetValue(), bSelected
);
733 mpAutoFilterPopup
->addMember(aVal
, bSelected
);
735 mpAutoFilterPopup
->initMembers();
737 // Populate the menu.
738 mpAutoFilterPopup
->addMenuItem(
739 SC_STRLOAD(RID_POPUP_FILTER
, STR_MENU_SORT_ASC
),
740 true, new AutoFilterAction(this, SortAscending
));
741 mpAutoFilterPopup
->addMenuItem(
742 SC_STRLOAD(RID_POPUP_FILTER
, STR_MENU_SORT_DESC
),
743 true, new AutoFilterAction(this, SortDescending
));
744 mpAutoFilterPopup
->addSeparator();
745 mpAutoFilterPopup
->addMenuItem(
746 SC_RESSTR(SCSTR_TOP10FILTER
), true, new AutoFilterAction(this, Top10
));
747 mpAutoFilterPopup
->addMenuItem(
748 SC_RESSTR(SCSTR_FILTER_EMPTY
), true, new AutoFilterAction(this, Empty
));
749 mpAutoFilterPopup
->addMenuItem(
750 SC_RESSTR(SCSTR_FILTER_NOTEMPTY
), true, new AutoFilterAction(this, NonEmpty
));
751 mpAutoFilterPopup
->addSeparator();
752 mpAutoFilterPopup
->addMenuItem(
753 SC_RESSTR(SCSTR_STDFILTER
), true, new AutoFilterAction(this, Custom
));
755 ScCheckListMenuWindow::Config aConfig
;
756 aConfig
.mbAllowEmptySet
= false;
757 aConfig
.mbRTL
= pViewData
->GetDocument()->IsLayoutRTL(pViewData
->GetTabNo());
758 mpAutoFilterPopup
->setConfig(aConfig
);
759 mpAutoFilterPopup
->launch(aCellRect
);
762 void ScGridWindow::RefreshAutoFilterButton(const ScAddress
& rPos
)
766 bool bFilterActive
= IsAutoFilterActive(rPos
.Col(), rPos
.Row(), rPos
.Tab());
767 mpFilterButton
->setHasHiddenMember(bFilterActive
);
768 mpFilterButton
->setPopupPressed(false);
769 mpFilterButton
->draw();
773 void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode
)
775 const AutoFilterData
* pData
=
776 static_cast<const AutoFilterData
*>(mpAutoFilterPopup
->getExtendedData());
781 const ScAddress
& rPos
= pData
->maPos
;
782 ScDBData
* pDBData
= pData
->mpData
;
786 ScDocument
* pDoc
= pViewData
->GetDocument();
787 svl::SharedStringPool
& rPool
= pDoc
->GetSharedStringPool();
793 SCTAB nTab
= pViewData
->GetTabNo();
794 SCCOL nCol
= rPos
.Col();
795 ScSortParam aSortParam
;
796 pDBData
->GetSortParam(aSortParam
);
797 if (nCol
< aSortParam
.nCol1
|| nCol
> aSortParam
.nCol2
)
801 bool bHasHeader
= pDoc
->HasColHeader(
802 aSortParam
.nCol1
, aSortParam
.nRow1
, aSortParam
.nCol2
, aSortParam
.nRow2
, nTab
);
804 aSortParam
.bHasHeader
= bHasHeader
;
805 aSortParam
.bByRow
= true;
806 aSortParam
.bCaseSens
= false;
807 aSortParam
.bNaturalSort
= false;
808 aSortParam
.bIncludePattern
= true;
809 aSortParam
.bInplace
= true;
810 aSortParam
.maKeyState
[0].bDoSort
= true;
811 aSortParam
.maKeyState
[0].nField
= nCol
;
812 aSortParam
.maKeyState
[0].bAscending
= (eMode
== SortAscending
);
814 for (size_t i
= 1; i
< aSortParam
.GetSortKeyCount(); ++i
)
815 aSortParam
.maKeyState
[i
].bDoSort
= false;
817 pViewData
->GetViewShell()->UISort(aSortParam
);
827 pDBData
->GetArea(aRange
);
828 pViewData
->GetView()->MarkRange(aRange
);
829 pViewData
->GetView()->SetCursor(rPos
.Col(), rPos
.Row());
830 pViewData
->GetDispatcher().Execute(SID_FILTER
, SFX_CALLMODE_SLOT
|SFX_CALLMODE_RECORD
);
835 pDBData
->GetQueryParam(aParam
);
837 if (eMode
== Normal
&& mpAutoFilterPopup
->isAllSelected())
839 // Remove this entry.
840 aParam
.RemoveEntryByField(rPos
.Col());
844 // Try to use the existing entry for the column (if one exists).
845 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(rPos
.Col(), true);
848 // Something went terribly wrong!
851 pEntry
->bDoQuery
= true;
852 pEntry
->nField
= rPos
.Col();
853 pEntry
->eConnect
= SC_AND
;
859 pEntry
->eOp
= SC_EQUAL
;
861 ScCheckListMenuWindow::ResultType aResult
;
862 mpAutoFilterPopup
->getResult(aResult
);
863 std::vector
<OUString
> aSelected
;
864 ScCheckListMenuWindow::ResultType::const_iterator itr
= aResult
.begin(), itrEnd
= aResult
.end();
865 for (; itr
!= itrEnd
; ++itr
)
868 aSelected
.push_back(itr
->first
);
871 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
873 std::for_each(aSelected
.begin(), aSelected
.end(), AddItemToEntry(rItems
, rPool
));
877 pEntry
->eOp
= SC_TOPVAL
;
878 pEntry
->GetQueryItem().meType
= ScQueryEntry::ByString
;
879 pEntry
->GetQueryItem().maString
= rPool
.intern("10");
882 pEntry
->SetQueryByEmpty();
885 pEntry
->SetQueryByNonEmpty();
888 // We don't know how to handle this!
893 pViewData
->GetView()->Query(aParam
, NULL
, true);
894 pDBData
->SetQueryParam(aParam
);
899 void getCellGeometry(Point
& rScrPos
, Size
& rScrSize
, const ScViewData
* pViewData
, SCCOL nCol
, SCROW nRow
, ScSplitPos eWhich
)
901 // Get the screen position of the cell.
902 rScrPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
904 // Get the screen size of the cell.
906 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
907 rScrSize
= Size(nSizeX
-1, nSizeY
-1);
912 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol
, SCROW nRow
)
915 // We assume that the page field button is located in cell to the immediate left.
918 SCTAB nTab
= pViewData
->GetTabNo();
919 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
925 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
926 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
-1, nRow
, nTab
), pDPObj
);
929 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol
, SCROW nRow
)
931 SCTAB nTab
= pViewData
->GetTabNo();
932 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
938 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
939 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
, nRow
, nTab
), pDPObj
);
942 void ScGridWindow::DoScenarioMenu( const ScRange
& rScenRange
)
947 SCCOL nCol
= rScenRange
.aEnd
.Col(); // Zelle unterhalb des Buttons
948 SCROW nRow
= rScenRange
.aStart
.Row();
951 nRow
= rScenRange
.aEnd
.Row() + 1; // Bereich ganz oben -> Button unterhalb
952 if (nRow
>MAXROW
) nRow
= MAXROW
;
953 //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
956 ScDocument
* pDoc
= pViewData
->GetDocument();
957 SCTAB nTab
= pViewData
->GetTabNo();
958 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
963 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
964 // The button height should not use the merged cell height, should still use single row height
965 nSizeY
= pViewData
->ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
966 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
969 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
970 aCellRect
.Top() -= nSizeY
;
971 aCellRect
.Bottom() -= nSizeY
- 1;
972 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
973 // (wenn die Linie verdeckt wird, sieht es komisch aus...)
975 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
976 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
977 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_SCENARIO
);
979 pFilterBox
->EnableMirroring();
984 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
985 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
987 nHeight
= GetTextHeight();
988 nHeight
*= SC_FILTERLISTBOX_LINES
;
990 SetMapMode( aOldMode
);
996 // ParentSize Abfrage fehlt
997 Size
aSize( nSizeX
, nHeight
);
998 pFilterBox
->SetSizePixel( aSize
);
999 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1000 pFilterBox
->SetUpdateMode(false);
1002 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
1009 SCTAB nTabCount
= pDoc
->GetTableCount();
1010 SCTAB nEntryCount
= 0;
1011 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
1013 if (pDoc
->HasScenarioRange( i
, rScenRange
))
1014 if (pDoc
->GetName( i
, aTabName
))
1016 pFilterBox
->InsertEntry( aTabName
);
1017 if (pDoc
->IsActiveScenario(i
))
1018 aCurrent
= aTabName
;
1019 long nTextWidth
= pFilterBox
->GetTextWidth( aTabName
);
1020 if ( nTextWidth
> nMaxText
)
1021 nMaxText
= nTextWidth
;
1025 if (nEntryCount
> SC_FILTERLISTBOX_LINES
)
1026 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
1027 nMaxText
+= 4; // fuer Rand
1028 if ( nMaxText
> 300 )
1029 nMaxText
= 300; // auch nicht uebertreiben (Pixel)
1031 if (nMaxText
> nSizeX
) // Groesse auf benoetigte Groesse anpassen
1033 long nDiff
= nMaxText
- nSizeX
;
1034 aSize
= Size( nMaxText
, nHeight
);
1035 pFilterBox
->SetSizePixel( aSize
);
1036 pFilterFloat
->SetOutputSizePixel( aSize
);
1040 // also move popup position
1041 long nNewX
= aCellRect
.Left() - nDiff
;
1044 aCellRect
.Left() = nNewX
;
1048 pFilterFloat
->SetOutputSizePixel( aSize
);
1049 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1051 pFilterBox
->SetUpdateMode(true);
1052 pFilterBox
->GrabFocus();
1054 sal_Int32 nPos
= LISTBOX_ENTRY_NOTFOUND
;
1055 if (!aCurrent
.isEmpty())
1057 nPos
= pFilterBox
->GetEntryPos(aCurrent
);
1059 if (LISTBOX_ENTRY_NOTFOUND
== nPos
&& pFilterBox
->GetEntryCount() > 0 )
1061 if (LISTBOX_ENTRY_NOTFOUND
!= nPos
)
1062 pFilterBox
->SelectEntryPos(nPos
);
1064 pFilterBox
->EndInit();
1066 // Szenario-Auswahl kommt aus MouseButtonDown:
1067 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1069 nMouseStatus
= SC_GM_FILTER
;
1073 void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol
, SCROW nRow
, bool bDataSelect
)
1076 delete pFilterFloat
;
1079 ScDocument
* pDoc
= pViewData
->GetDocument();
1080 SCTAB nTab
= pViewData
->GetTabNo();
1081 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1086 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1087 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1091 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
1094 aPos
.Y() += nSizeY
- 1;
1096 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
1097 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
1098 pFilterBox
= new ScFilterListBox(
1099 pFilterFloat
, this, nCol
, nRow
, bDataSelect
? SC_FILTERBOX_DATASELECT
: SC_FILTERBOX_FILTER
);
1100 // Fix for bug fdo#44925
1101 if (Application::GetSettings().GetLayoutRTL() != bLayoutRTL
)
1102 pFilterBox
->EnableMirroring();
1107 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
1108 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
1110 nHeight
= GetTextHeight();
1111 nHeight
*= SC_FILTERLISTBOX_LINES
;
1113 SetMapMode( aOldMode
);
1114 SetFont( aOldFont
);
1119 bool bEmpty
= false;
1120 std::vector
<ScTypedStrData
> aStrings
; // case sensitive
1121 if ( bDataSelect
) // Auswahl-Liste
1124 pDoc
->GetDataEntries(nCol
, nRow
, nTab
, true, aStrings
);
1125 if (aStrings
.empty())
1130 //! wird der Titel ueberhaupt ausgewertet ???
1131 OUString aString
= pDoc
->GetString(nCol
, nRow
, nTab
);
1132 pFilterBox
->SetText( aString
);
1137 static const sal_uInt16 nDefIDs
[] = { SCSTR_TOP10FILTER
, SCSTR_STDFILTER
, SCSTR_FILTER_EMPTY
, SCSTR_FILTER_NOTEMPTY
};
1138 const size_t nDefCount
= SAL_N_ELEMENTS(nDefIDs
);
1139 for (i
=0; i
<nDefCount
; i
++)
1141 OUString
aEntry( (ScResId
) nDefIDs
[i
] );
1142 pFilterBox
->InsertEntry( aEntry
);
1143 long nTextWidth
= pFilterBox
->GetTextWidth( aEntry
);
1144 if ( nTextWidth
> nMaxText
)
1145 nMaxText
= nTextWidth
;
1147 pFilterBox
->SetSeparatorPos( nDefCount
- 1 );
1150 bool bHasDates
= false;
1151 pDoc
->GetFilterEntries( nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
1152 pFilterBox
->SetListHasDates(bHasDates
);
1154 // check widths of numerical entries (string entries are not included)
1155 // so all numbers are completely visible
1156 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1157 for (; it
!= itEnd
; ++it
)
1159 if (!it
->IsStrData()) // only numerical entries
1161 long nTextWidth
= pFilterBox
->GetTextWidth(it
->GetString());
1162 if ( nTextWidth
> nMaxText
)
1163 nMaxText
= nTextWidth
;
1167 // add scrollbar width if needed (string entries are counted here)
1168 // (scrollbar is shown if the box is exactly full?)
1169 if (aStrings
.size() + nDefCount
>= SC_FILTERLISTBOX_LINES
)
1170 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
1172 nMaxText
+= 4; // for borders
1174 if ( nMaxText
> nSizeX
)
1175 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
1180 // Position und Groesse an Fenster anpassen
1181 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
1183 Size aParentSize
= GetParent()->GetOutputSizePixel();
1184 Size
aSize( nSizeX
, nHeight
);
1186 if ( aSize
.Height() > aParentSize
.Height() )
1187 aSize
.Height() = aParentSize
.Height();
1188 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
1189 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
1191 pFilterBox
->SetSizePixel( aSize
);
1192 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1193 pFilterBox
->SetUpdateMode(false);
1195 pFilterFloat
->SetOutputSizePixel( aSize
);
1196 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1199 bool bWait
= aStrings
.size() > 100;
1204 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1205 for (; it
!= itEnd
; ++it
)
1206 pFilterBox
->InsertEntry(it
->GetString());
1211 pFilterBox
->SetUpdateMode(true);
1214 sal_Int32 nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
1216 if (!bDataSelect
) // AutoFilter: aktiven Eintrag selektieren
1218 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1221 ScQueryParam aParam
;
1222 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1225 SCSIZE nCount
= aParam
.GetEntryCount();
1226 for (SCSIZE j
= 0; j
< nCount
&& bValid
; ++j
) // bisherige Filter-Einstellungen
1227 if (aParam
.GetEntry(j
).bDoQuery
)
1229 //! Abfrage mit DrawButtons zusammenfassen!
1231 ScQueryEntry
& rEntry
= aParam
.GetEntry(j
);
1233 if (rEntry
.eConnect
!= SC_AND
)
1235 if (rEntry
.nField
== nCol
)
1237 OUString aQueryStr
= rEntry
.GetQueryItem().maString
.getString();
1238 if (rEntry
.eOp
== SC_EQUAL
)
1240 if (!aQueryStr
.isEmpty())
1242 nSelPos
= pFilterBox
->GetEntryPos(aQueryStr
);
1245 else if ( rEntry
.eOp
== SC_TOPVAL
&& aQueryStr
== "10" )
1246 nSelPos
= SC_AUTOFILTER_TOP10
;
1248 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1253 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1259 sal_uLong nIndex
= ((SfxUInt32Item
*)pDoc
->GetAttr(
1260 nCol
, nRow
, nTab
, ATTR_VALIDDATA
))->GetValue();
1263 const ScValidationData
* pData
= pDoc
->GetValidationEntry( nIndex
);
1266 boost::scoped_ptr
<ScTypedStrData
> pNew
;
1267 OUString aDocStr
= pDoc
->GetString(nCol
, nRow
, nTab
);
1268 if ( pDoc
->HasValueData( nCol
, nRow
, nTab
) )
1270 double fVal
= pDoc
->GetValue(ScAddress(nCol
, nRow
, nTab
));
1271 pNew
.reset(new ScTypedStrData(aDocStr
, fVal
, ScTypedStrData::Value
));
1274 pNew
.reset(new ScTypedStrData(aDocStr
, 0.0, ScTypedStrData::Standard
));
1276 bool bSortList
= ( pData
->GetListType() == ValidListType::SORTEDASCENDING
);
1279 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1280 std::vector
<ScTypedStrData
>::const_iterator it
=
1281 std::find_if(itBeg
, itEnd
, FindTypedStrData(*pNew
, true));
1284 nSelPos
= std::distance(itBeg
, it
);
1288 ScTypedStrData::EqualCaseSensitive aHdl
;
1289 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1290 std::vector
<ScTypedStrData
>::const_iterator it
= itBeg
;
1291 for (; it
!= itEnd
&& LISTBOX_ENTRY_NOTFOUND
== nSelPos
; ++it
)
1293 if (aHdl(*it
, *pNew
))
1294 nSelPos
= std::distance(itBeg
, it
);
1301 // neu (309): irgendwas muss immer selektiert sein:
1302 if ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
&& pFilterBox
->GetEntryCount() > 0 && !bDataSelect
)
1305 // keine leere Auswahl-Liste anzeigen:
1309 DELETEZ(pFilterBox
); // war nix
1310 DELETEZ(pFilterFloat
);
1314 pFilterBox
->GrabFocus();
1316 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1317 if ( LISTBOX_ENTRY_NOTFOUND
!= nSelPos
)
1318 pFilterBox
->SelectEntryPos( nSelPos
);
1322 pFilterBox
->SetNoSelection();
1325 pFilterBox
->EndInit();
1329 // AutoFilter (aus MouseButtonDown):
1330 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1332 nMouseStatus
= SC_GM_FILTER
;
1338 void ScGridWindow::FilterSelect( sal_uLong nSel
)
1340 OUString aString
= pFilterBox
->GetEntry( static_cast< sal_Int32
>( nSel
) );
1342 SCCOL nCol
= pFilterBox
->GetCol();
1343 SCROW nRow
= pFilterBox
->GetRow();
1344 switch ( pFilterBox
->GetMode() )
1346 case SC_FILTERBOX_DATASELECT
:
1347 ExecDataSelect( nCol
, nRow
, aString
);
1349 case SC_FILTERBOX_FILTER
:
1350 ExecFilter( nSel
, nCol
, nRow
, aString
, pFilterBox
->HasDates() );
1352 case SC_FILTERBOX_SCENARIO
:
1353 pViewData
->GetView()->UseScenario( aString
);
1355 case SC_FILTERBOX_PAGEFIELD
:
1356 // first entry is "all"
1357 ExecPageFieldSelect( nCol
, nRow
, (nSel
!= 0), aString
);
1362 pFilterFloat
->EndPopupMode();
1364 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1367 void ScGridWindow::ExecDataSelect( SCCOL nCol
, SCROW nRow
, const OUString
& rStr
)
1369 if ( !rStr
.isEmpty() )
1371 SCTAB nTab
= pViewData
->GetTabNo();
1372 ScViewFunc
* pView
= pViewData
->GetView();
1373 pView
->EnterData( nCol
, nRow
, nTab
, rStr
);
1375 // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1376 // if the cursor is moved afterwards.
1377 pView
->CellContentChanged();
1381 void ScGridWindow::ExecFilter( sal_uLong nSel
,
1382 SCCOL nCol
, SCROW nRow
,
1383 const OUString
& aValue
, bool bCheckForDates
)
1385 SCTAB nTab
= pViewData
->GetTabNo();
1386 ScDocument
* pDoc
= pViewData
->GetDocument();
1387 svl::SharedStringPool
& rPool
= pDoc
->GetSharedStringPool();
1389 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1392 ScQueryParam aParam
;
1393 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1395 if (SC_AUTOFILTER_CUSTOM
== nSel
)
1402 pDBData
->GetArea( nAreaTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
);
1403 pViewData
->GetView()->MarkRange( ScRange( nStartCol
,nStartRow
,nAreaTab
,nEndCol
,nEndRow
,nAreaTab
));
1404 pViewData
->GetView()->SetCursor(nCol
,nRow
); //! auch ueber Slot ??
1405 pViewData
->GetDispatcher().Execute( SID_FILTER
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1409 bool bDeleteOld
= false;
1410 SCSIZE nQueryPos
= 0;
1411 bool bFound
= false;
1412 if (!aParam
.bInplace
)
1416 SCSIZE nCount
= aParam
.GetEntryCount();
1417 for (SCSIZE i
= 0; i
< nCount
&& !bDeleteOld
; ++i
) // bisherige Filter-Einstellungen
1418 if (aParam
.GetEntry(i
).bDoQuery
)
1420 //! Abfrage mit DrawButtons zusammenfassen!
1422 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1424 if (rEntry
.eConnect
!= SC_AND
)
1427 if (rEntry
.nField
== nCol
)
1429 if (bFound
) // diese Spalte zweimal?
1440 SCSIZE nEC
= aParam
.GetEntryCount();
1441 for (SCSIZE i
=0; i
<nEC
; i
++)
1442 aParam
.GetEntry(i
).Clear();
1444 aParam
.bInplace
= true;
1445 aParam
.bRegExp
= false;
1448 if ( nQueryPos
< nCount
|| SC_AUTOFILTER_ALL
== nSel
) // loeschen geht immer
1452 ScQueryEntry
& rNewEntry
= aParam
.GetEntry(nQueryPos
);
1453 ScQueryEntry::Item
& rItem
= rNewEntry
.GetQueryItem();
1454 rNewEntry
.bDoQuery
= true;
1455 rNewEntry
.nField
= nCol
;
1456 rItem
.meType
= bCheckForDates
? ScQueryEntry::ByDate
: ScQueryEntry::ByString
;
1458 if ( nSel
== SC_AUTOFILTER_TOP10
)
1460 rNewEntry
.eOp
= SC_TOPVAL
;
1461 rItem
.maString
= rPool
.intern("10");
1463 else if (nSel
== SC_AUTOFILTER_EMPTY
)
1465 rNewEntry
.SetQueryByEmpty();
1467 else if (nSel
== SC_AUTOFILTER_NOTEMPTY
)
1469 rNewEntry
.SetQueryByNonEmpty();
1473 rNewEntry
.eOp
= SC_EQUAL
;
1474 rItem
.maString
= rPool
.intern(aValue
);
1477 rNewEntry
.eConnect
= SC_AND
;
1482 aParam
.RemoveEntryByField(nCol
);
1485 // end edit mode - like in ScCellShell::ExecuteDB
1486 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1488 SC_MOD()->InputEnterHandler();
1489 pViewData
->GetViewShell()->UpdateInputHandler();
1492 pViewData
->GetView()->Query( aParam
, NULL
, true );
1493 pDBData
->SetQueryParam( aParam
); // speichern
1495 else // "Zuviele Bedingungen"
1496 pViewData
->GetView()->ErrorMessage( STR_FILTER_TOOMANY
);
1501 OSL_FAIL("Wo ist der Datenbankbereich?");
1505 void ScGridWindow::SetPointer( const Pointer
& rPointer
)
1507 nCurrentPointer
= 0;
1508 Window::SetPointer( rPointer
);
1511 void ScGridWindow::MoveMouseStatus( ScGridWindow
& rDestWin
)
1515 rDestWin
.nButtonDown
= nButtonDown
;
1516 rDestWin
.nMouseStatus
= nMouseStatus
;
1521 rDestWin
.bRFMouse
= bRFMouse
;
1522 rDestWin
.bRFSize
= bRFSize
;
1523 rDestWin
.nRFIndex
= nRFIndex
;
1524 rDestWin
.nRFAddX
= nRFAddX
;
1525 rDestWin
.nRFAddY
= nRFAddY
;
1529 if (nPagebreakMouse
)
1531 rDestWin
.nPagebreakMouse
= nPagebreakMouse
;
1532 rDestWin
.nPagebreakBreak
= nPagebreakBreak
;
1533 rDestWin
.nPagebreakPrev
= nPagebreakPrev
;
1534 rDestWin
.aPagebreakSource
= aPagebreakSource
;
1535 rDestWin
.aPagebreakDrag
= aPagebreakDrag
;
1536 nPagebreakMouse
= SC_PD_NONE
;
1540 bool ScGridWindow::TestMouse( const MouseEvent
& rMEvt
, bool bAction
)
1542 // MouseEvent buttons must only be checked if bAction==TRUE
1543 // to allow changing the mouse pointer in MouseMove,
1544 // but not start AutoFill with right button (#74229#).
1545 // with bAction==sal_True, SetFillMode / SetDragMode is called
1547 if ( bAction
&& !rMEvt
.IsLeft() )
1550 bool bNewPointer
= false;
1552 SfxInPlaceClient
* pClient
= pViewData
->GetViewShell()->GetIPClient();
1553 bool bOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
1555 if ( pViewData
->IsActive() && !bOleActive
)
1557 ScDocument
* pDoc
= pViewData
->GetDocument();
1558 SCTAB nTab
= pViewData
->GetTabNo();
1559 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1564 if (pViewData
->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
)
1566 if (aMarkRange
.aStart
.Tab() == pViewData
->GetTabNo() && mpAutoFillRect
)
1568 Point aMousePos
= rMEvt
.GetPosPixel();
1569 if (mpAutoFillRect
->IsInside(aMousePos
))
1571 SetPointer( Pointer( POINTER_CROSS
) ); //! dickeres Kreuz ?
1574 SCCOL nX
= aMarkRange
.aEnd
.Col();
1575 SCROW nY
= aMarkRange
.aEnd
.Row();
1577 if ( lcl_IsEditableMatrix( pViewData
->GetDocument(), aMarkRange
) )
1578 pViewData
->SetDragMode(
1579 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
, SC_FILL_MATRIX
);
1581 pViewData
->SetFillMode(
1582 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
);
1584 // The simple selection must also be recognized when dragging,
1585 // where the Marking flag is set and MarkToSimple won't work anymore.
1586 pViewData
->GetMarkData().MarkToSimple();
1593 // Embedded-Rechteck
1595 if (pDoc
->IsEmbedded())
1598 pDoc
->GetEmbedded( aRange
);
1599 if ( pViewData
->GetTabNo() == aRange
.aStart
.Tab() )
1601 Point aStartPos
= pViewData
->GetScrPos( aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
);
1602 Point aEndPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
);
1603 Point aMousePos
= rMEvt
.GetPosPixel();
1609 bool bTop
= ( aMousePos
.X() >= aStartPos
.X()-3 && aMousePos
.X() <= aStartPos
.X()+1 &&
1610 aMousePos
.Y() >= aStartPos
.Y()-3 && aMousePos
.Y() <= aStartPos
.Y()+1 );
1611 bool bBottom
= ( aMousePos
.X() >= aEndPos
.X()-3 && aMousePos
.X() <= aEndPos
.X()+1 &&
1612 aMousePos
.Y() >= aEndPos
.Y()-3 && aMousePos
.Y() <= aEndPos
.Y()+1 );
1613 if ( bTop
|| bBottom
)
1615 SetPointer( Pointer( POINTER_CROSS
) );
1618 sal_uInt8 nMode
= bTop
? SC_FILL_EMBED_LT
: SC_FILL_EMBED_RB
;
1619 pViewData
->SetDragMode(
1620 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1621 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nMode
);
1629 if (!bNewPointer
&& bAction
)
1631 pViewData
->ResetFillMode();
1637 void ScGridWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1639 if(!maChildWindows
.empty())
1641 const Point
& rPos
= rMEvt
.GetPosPixel();
1642 for(boost::ptr_vector
<Window
>::iterator itr
= maChildWindows
.begin(),
1643 itrEnd
= maChildWindows
.end(); itr
!= itrEnd
; ++itr
)
1645 if(!itr
->IsVisible())
1648 Point aPoint
= itr
->GetPosPixel();
1649 Size aSize
= itr
->GetSizePixel();
1651 if(rPos
.X() >= aPoint
.X() && rPos
.X() <= (aPoint
.X() + aSize
.Width())
1652 && rPos
.Y() >= aPoint
.Y() && rPos
.Y() <= (aPoint
.Y() + aSize
.Height()))
1654 // we found a mouse event for the child window
1655 // we need to recalculate the position based on the child window
1657 Point aNewPos
= rPos
- aPoint
;
1658 sal_uInt16 nClicks
= rMEvt
.GetClicks();
1659 sal_uInt16 nMode
= rMEvt
.GetMode();
1660 sal_uInt16 nButtons
= rMEvt
.GetButtons();
1661 sal_uInt16 nModifier
= rMEvt
.GetModifier();
1663 MouseEvent
aEvent(aNewPos
, nClicks
, nMode
, nButtons
, nModifier
);
1664 itr
->MouseButtonDown(aEvent
);
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 void ScGridWindow::HandleMouseButtonDown( const MouseEvent
& rMEvt
, MouseEventState
& rState
)
1693 // We have to check if a context menu is shown and we have an UI
1694 // active inplace client. In that case we have to ignore the event.
1695 // Otherwise we would crash (context menu has been
1696 // opened by inplace client and we would deactivate the inplace client,
1697 // the contex menu is closed by VCL asynchronously which in the end
1698 // would work on deleted objects or the context menu has no parent anymore)
1699 SfxViewShell
* pViewSh
= pViewData
->GetViewShell();
1700 SfxInPlaceClient
* pClient
= pViewSh
->GetIPClient();
1702 pClient
->IsObjectInPlaceActive() &&
1703 PopupMenu::IsInExecute() )
1706 aCurMousePos
= rMEvt
.GetPosPixel();
1708 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1709 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1710 ClickExtern(); // loescht FilterBox, wenn vorhanden
1712 HideNoteMarker(); // Notiz-Anzeige
1716 ScModule
* pScMod
= SC_MOD();
1717 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1720 pScActiveViewShell
= pViewData
->GetViewShell(); // falls auf Link geklickt wird
1721 nScClickMouseModifier
= rMEvt
.GetModifier(); // um Control-Klick immer zu erkennen
1723 bool bDetective
= pViewData
->GetViewShell()->IsAuditShell();
1724 bool bRefMode
= pViewData
->IsRefMode(); // Referenz angefangen
1725 bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
1726 bool bEditMode
= pViewData
->HasEditView(eWhich
); // auch bei Mode==SC_INPUT_TYPE
1727 bool bDouble
= (rMEvt
.GetClicks() == 2);
1729 // DeactivateIP passiert nur noch bei MarkListHasChanged
1731 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1732 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1734 if ( !nButtonDown
|| !bDouble
) // single (first) click is always valid
1735 nButtonDown
= rMEvt
.GetButtons(); // set nButtonDown first, so StopMarking works
1737 if ( ( bEditMode
&& pViewData
->GetActivePart() == eWhich
) || !bFormulaMode
)
1740 // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1741 // but a single (first) click is always valid
1742 if ( nMouseStatus
== SC_GM_IGNORE
&& bDouble
)
1745 nMouseStatus
= SC_GM_NONE
;
1749 if ( bDetective
) // Detektiv-Fuell-Modus
1751 if ( rMEvt
.IsLeft() && !rMEvt
.GetModifier() )
1753 Point aPos
= rMEvt
.GetPosPixel();
1756 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1758 SfxInt16Item
aPosXItem( SID_RANGE_COL
, nPosX
);
1759 SfxInt32Item
aPosYItem( SID_RANGE_ROW
, nPosY
);
1760 pViewData
->GetDispatcher().Execute( SID_FILL_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
1761 &aPosXItem
, &aPosYItem
, (void*)0L );
1765 nMouseStatus
= SC_GM_NONE
;
1770 nMouseStatus
= SC_GM_NONE
;
1772 rState
.mbActivatePart
= !bFormulaMode
; // Don't activate when in formula mode.
1776 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1777 pSelEng
->SetWindow(this);
1778 pSelEng
->SetWhich(eWhich
);
1779 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1782 if (bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()))
1784 Point aPos
= rMEvt
.GetPosPixel();
1787 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1789 EditView
* pEditView
;
1792 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1793 SCCOL nEndCol
= pViewData
->GetEditEndCol();
1794 SCROW nEndRow
= pViewData
->GetEditEndRow();
1796 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
1797 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
1799 // beim Klick in die Tabellen-EditView immer den Focus umsetzen
1800 if (bFormulaMode
) // sonst ist es oben schon passiert
1803 pScMod
->SetInputMode( SC_INPUT_TABLE
);
1805 bEditMode
= pEditView
->MouseButtonDown( rMEvt
);
1810 if (pScMod
->GetIsWaterCan())
1812 //! was is mit'm Mac ???
1813 if ( rMEvt
.GetModifier() + rMEvt
.GetButtons() == MOUSE_RIGHT
)
1815 nMouseStatus
= SC_GM_WATERUNDO
;
1820 // Reihenfolge passend zum angezeigten Cursor:
1821 // RangeFinder, AutoFill, PageBreak, Drawing
1823 RfCorner rCorner
= NONE
;
1824 bool bFound
= HitRangeFinder(rMEvt
.GetPosPixel(), rCorner
, &nRFIndex
, &nRFAddX
, &nRFAddY
);
1825 bRFSize
= (rCorner
!= NONE
);
1826 aRFSelectedCorned
= rCorner
;
1830 bRFMouse
= true; // die anderen Variablen sind oben initialisiert
1832 rState
.mbActivatePart
= true; // always activate ?
1837 bool bCrossPointer
= TestMouse( rMEvt
, true );
1838 if ( bCrossPointer
)
1841 pViewData
->GetView()->FillCrossDblClick();
1843 pScMod
->InputEnterHandler(); // Autofill etc.
1846 if ( !bCrossPointer
)
1848 nPagebreakMouse
= HitPageBreak( rMEvt
.GetPosPixel(), &aPagebreakSource
,
1849 &nPagebreakBreak
, &nPagebreakPrev
);
1850 if (nPagebreakMouse
)
1852 bPagebreakDrawn
= false;
1854 PagebreakMove( rMEvt
, false );
1859 if (!bFormulaMode
&& !bEditMode
&& rMEvt
.IsLeft())
1861 if ( !bCrossPointer
&& DrawMouseButtonDown(rMEvt
) )
1866 pViewData
->GetViewShell()->SetDrawShell( false ); // kein Draw-Objekt selektiert
1868 // TestMouse schon oben passiert
1871 Point aPos
= rMEvt
.GetPosPixel();
1874 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1875 SCTAB nTab
= pViewData
->GetTabNo();
1876 ScDocument
* pDoc
= pViewData
->GetDocument();
1878 // Auto filter / pivot table / data select popup. This shouldn't activate the part.
1880 if ( !bDouble
&& !bFormulaMode
&& rMEvt
.IsLeft() )
1884 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nRealPosX
, nRealPosY
, false );//the real row/col
1885 ScMergeFlagAttr
* pRealPosAttr
= (ScMergeFlagAttr
*)
1886 pDoc
->GetAttr( nRealPosX
, nRealPosY
, nTab
, ATTR_MERGE_FLAG
);
1887 ScMergeFlagAttr
* pAttr
= (ScMergeFlagAttr
*)
1888 pDoc
->GetAttr( nPosX
, nPosY
, nTab
, ATTR_MERGE_FLAG
);
1889 if( pRealPosAttr
->HasAutoFilter() )
1891 SC_MOD()->InputEnterHandler();
1892 if (DoAutoFilterButton( nRealPosX
, nRealPosY
, rMEvt
))
1895 if (pAttr
->HasAutoFilter())
1897 if (DoAutoFilterButton(nPosX
, nPosY
, rMEvt
))
1899 rState
.mbActivatePart
= false;
1904 if (pAttr
->HasPivotButton() || pAttr
->HasPivotPopupButton())
1906 DoPushPivotButton(nPosX
, nPosY
, rMEvt
, pAttr
->HasPivotButton(), pAttr
->HasPivotPopupButton());
1907 rState
.mbActivatePart
= false;
1911 // List Validity drop-down button
1913 if ( bListValButton
)
1915 Rectangle aButtonRect
= GetListValButtonRect( aListValPos
);
1916 if ( aButtonRect
.IsInside( aPos
) )
1918 LaunchDataSelectMenu( aListValPos
.Col(), aListValPos
.Row(), true );
1920 nMouseStatus
= SC_GM_FILTER
; // not set in DoAutoFilterMenue for bDataSelect
1922 rState
.mbActivatePart
= false;
1929 // scenario selection
1933 if ( rMEvt
.IsLeft() && HasScenarioButton( aPos
, aScenRange
) )
1935 DoScenarioMenu( aScenRange
);
1940 // Doppelklick angefangen ?
1943 // StopMarking kann aus DrawMouseButtonDown gerufen werden
1945 if ( nMouseStatus
!= SC_GM_IGNORE
&& !bRefMode
)
1947 if ( bDouble
&& !bCrossPointer
)
1949 if (nMouseStatus
== SC_GM_TABDOWN
)
1950 nMouseStatus
= SC_GM_DBLDOWN
;
1953 nMouseStatus
= SC_GM_TABDOWN
;
1957 // Links in Edit-Zellen
1960 bool bAlt
= rMEvt
.IsMod2();
1961 if ( !bAlt
&& rMEvt
.IsLeft() &&
1962 GetEditUrl(rMEvt
.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
1964 SetPointer( Pointer( POINTER_REFHAND
) );
1965 nMouseStatus
= SC_GM_URLDOWN
; // auch nur dann beim ButtonUp ausfuehren
1970 // Gridwin - SelectionEngine
1973 if ( rMEvt
.IsLeft() )
1975 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1976 pSelEng
->SetWindow(this);
1977 pSelEng
->SetWhich(eWhich
);
1978 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1980 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1981 if ( pViewData
->GetView()->SelMouseButtonDown( rMEvt
) )
1983 if (IsMouseCaptured())
1985 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1986 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1990 pViewData
->GetMarkData().SetMarking(true);
1996 void ScGridWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
1998 aCurMousePos
= rMEvt
.GetPosPixel();
1999 ScDocument
* pDoc
= pViewData
->GetDocument();
2000 ScMarkData
& rMark
= pViewData
->GetMarkData();
2002 // #i41690# detect a MouseButtonUp call from within MouseButtonDown
2003 // (possible through Reschedule from storing an OLE object that is deselected)
2005 if ( nNestedButtonState
== SC_NESTEDBUTTON_DOWN
)
2006 nNestedButtonState
= SC_NESTEDBUTTON_UP
;
2008 if (nButtonDown
!= rMEvt
.GetButtons())
2009 nMouseStatus
= SC_GM_IGNORE
; // reset und return
2013 if (nMouseStatus
== SC_GM_IGNORE
)
2015 nMouseStatus
= SC_GM_NONE
;
2016 // Selection-Engine: Markieren abbrechen
2017 pViewData
->GetView()->GetSelEngine()->Reset();
2018 rMark
.SetMarking(false);
2019 if (pViewData
->IsAnyFillMode())
2021 pViewData
->GetView()->StopRefMode();
2022 pViewData
->ResetFillMode();
2025 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
2030 if (nMouseStatus
== SC_GM_FILTER
)
2032 nMouseStatus
= SC_GM_NONE
;
2034 return; // da muss nix mehr passieren
2037 ScModule
* pScMod
= SC_MOD();
2038 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2041 SfxBindings
& rBindings
= pViewData
->GetBindings();
2042 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2044 EditView
* pEditView
;
2047 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2048 pEditView
->MouseButtonUp( rMEvt
);
2050 if ( rMEvt
.IsMiddle() &&
2051 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
2053 // EditView may have pasted from selection
2054 pScMod
->InputChanged( pEditView
);
2057 pScMod
->InputSelection( pEditView
); // parentheses etc.
2059 pViewData
->GetView()->InvalidateAttribs();
2060 rBindings
.Invalidate( SID_HYPERLINK_GETLINK
);
2067 DPMouseButtonUp( rMEvt
); // resets bDPMouse
2073 RFMouseMove( rMEvt
, true ); // Range wieder richtigherum
2075 SetPointer( Pointer( POINTER_ARROW
) );
2080 if (nPagebreakMouse
)
2082 PagebreakMove( rMEvt
, true );
2083 nPagebreakMouse
= SC_PD_NONE
;
2084 SetPointer( Pointer( POINTER_ARROW
) );
2089 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus
2091 ::svl::IUndoManager
* pMgr
= pViewData
->GetDocShell()->GetUndoManager();
2092 if ( pMgr
->GetUndoActionCount() && pMgr
->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE
)
2097 if (DrawMouseButtonUp(rMEvt
)) // includes format paint brush handling for drawing objects
2099 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
2100 SfxBindings
& rFrmBindings
=pViewShell
->GetViewFrame()->GetBindings();
2101 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_WIDTH
);
2102 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_HEIGHT
);
2103 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_X
);
2104 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_Y
);
2105 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ANGLE
);
2106 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ROT_X
);
2107 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_ROT_Y
);
2108 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_AUTOWIDTH
);
2109 rFrmBindings
.Invalidate(SID_ATTR_TRANSFORM_AUTOHEIGHT
);
2113 rMark
.SetMarking(false);
2115 SetPointer( Pointer( POINTER_ARROW
) );
2117 if (pViewData
->IsFillMode() ||
2118 ( pViewData
->GetFillMode() == SC_FILL_MATRIX
&& rMEvt
.IsMod1() ))
2120 nScFillModeMouseModifier
= rMEvt
.GetModifier();
2125 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2127 bool bIsDel
= pViewData
->GetDelMark( aDelRange
);
2129 ScViewFunc
* pView
= pViewData
->GetView();
2130 pView
->StopRefMode();
2131 pViewData
->ResetFillMode();
2132 pView
->GetFunctionSet()->SetAnchorFlag( false ); // #i5819# don't use AutoFill anchor flag for selection
2136 pView
->MarkRange( aDelRange
, false );
2137 pView
->DeleteContents( IDF_CONTENTS
);
2138 SCTAB nTab
= pViewData
->GetTabNo();
2139 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2140 if ( aBlockRange
!= aDelRange
)
2142 if ( aDelRange
.aStart
.Row() == nStartRow
)
2143 aBlockRange
.aEnd
.SetCol( aDelRange
.aStart
.Col() - 1 );
2145 aBlockRange
.aEnd
.SetRow( aDelRange
.aStart
.Row() - 1 );
2146 pView
->MarkRange( aBlockRange
, false );
2150 pViewData
->GetDispatcher().Execute( FID_FILL_AUTO
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2152 else if (pViewData
->GetFillMode() == SC_FILL_MATRIX
)
2154 SCTAB nTab
= pViewData
->GetTabNo();
2159 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2160 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2161 SCCOL nFillCol
= pViewData
->GetRefEndX();
2162 SCROW nFillRow
= pViewData
->GetRefEndY();
2163 ScAddress
aEndPos( nFillCol
, nFillRow
, nTab
);
2165 ScTabView
* pView
= pViewData
->GetView();
2166 pView
->StopRefMode();
2167 pViewData
->ResetFillMode();
2168 pView
->GetFunctionSet()->SetAnchorFlag( false );
2170 if ( aEndPos
!= aBlockRange
.aEnd
)
2172 pViewData
->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange
, aEndPos
, false );
2173 pViewData
->GetView()->MarkRange( ScRange( aBlockRange
.aStart
, aEndPos
) );
2176 else if (pViewData
->IsAnyFillMode())
2178 // Embedded-Area has been changed
2179 ScTabView
* pView
= pViewData
->GetView();
2180 pView
->StopRefMode();
2181 pViewData
->ResetFillMode();
2182 pView
->GetFunctionSet()->SetAnchorFlag( false );
2183 pViewData
->GetDocShell()->UpdateOle(pViewData
);
2186 bool bRefMode
= pViewData
->IsRefMode();
2188 pScMod
->EndReference();
2191 // Giesskannen-Modus (Gestalter)
2194 if (pScMod
->GetIsWaterCan())
2196 // Abfrage auf Undo schon oben
2198 ScStyleSheetPool
* pStylePool
= (ScStyleSheetPool
*)
2199 (pViewData
->GetDocument()->
2200 GetStyleSheetPool());
2203 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)
2204 pStylePool
->GetActualStyleSheet();
2208 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
2212 case SFX_STYLE_FAMILY_PARA
:
2213 pViewData
->GetView()->SetStyleSheetToMarked( pStyleSheet
);
2214 pViewData
->GetView()->DoneBlockMode();
2217 case SFX_STYLE_FAMILY_PAGE
:
2218 pViewData
->GetDocument()->SetPageStyle( pViewData
->GetTabNo(),
2219 pStyleSheet
->GetName() );
2221 ScPrintFunc( pViewData
->GetDocShell(),
2222 pViewData
->GetViewShell()->GetPrinter(true),
2223 pViewData
->GetTabNo() ).UpdatePages();
2225 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
2235 ScDBFunc
* pView
= pViewData
->GetView();
2236 ScDocument
* pBrushDoc
= pView
->GetBrushDocument();
2239 pView
->PasteFromClip( IDF_ATTRIB
, pBrushDoc
);
2240 if ( !pView
->IsPaintBrushLocked() )
2241 pView
->ResetBrushDocument(); // invalidates pBrushDoc pointer
2245 // double click (only left button)
2248 bool bDouble
= ( rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() );
2249 if ( bDouble
&& !bRefMode
&& nMouseStatus
== SC_GM_DBLDOWN
&& !pScMod
->IsRefDialogOpen() )
2252 Point aPos
= rMEvt
.GetPosPixel();
2255 SCTAB nTab
= pViewData
->GetTabNo();
2256 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2257 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor( nPosX
, nPosY
, nTab
);
2258 if ( pDPObj
&& pDPObj
->GetSaveData()->GetDrillDown() )
2260 ScAddress
aCellPos( nPosX
, nPosY
, pViewData
->GetTabNo() );
2262 // Check for header drill-down first.
2263 sheet::DataPilotTableHeaderData aData
;
2264 pDPObj
->GetHeaderPositionData(aCellPos
, aData
);
2266 if ( ( aData
.Flags
& sheet::MemberResultFlags::HASMEMBER
) &&
2267 ! ( aData
.Flags
& sheet::MemberResultFlags::SUBTOTAL
) )
2270 if ( pView
->HasSelectionForDrillDown( nDummy
) )
2272 // execute slot to show dialog
2273 pViewData
->GetDispatcher().Execute( SID_OUTLINE_SHOW
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2277 // toggle single entry
2278 ScDPObject
aNewObj( *pDPObj
);
2279 pDPObj
->ToggleDetails( aData
, &aNewObj
);
2280 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
2281 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, true, false );
2282 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
2287 // Check if the data area is double-clicked.
2289 Sequence
<sheet::DataPilotFieldFilter
> aFilters
;
2290 if ( pDPObj
->GetDataFieldPositionData(aCellPos
, aFilters
) )
2291 pViewData
->GetView()->ShowDataPilotSourceData( *pDPObj
, aFilters
);
2297 // Check for cell protection attribute.
2298 ScTableProtection
* pProtect
= pDoc
->GetTabProtection( nTab
);
2299 bool bEditAllowed
= true;
2300 if ( pProtect
&& pProtect
->isProtected() )
2302 bool bCellProtected
= pDoc
->HasAttrib(nPosX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_PROTECTED
);
2303 bool bSkipProtected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2304 bool bSkipUnprotected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2306 if ( bSkipProtected
&& bSkipUnprotected
)
2307 bEditAllowed
= false;
2308 else if ( (bCellProtected
&& bSkipProtected
) || (!bCellProtected
&& bSkipUnprotected
) )
2309 bEditAllowed
= false;
2314 // edit cell contents
2315 pViewData
->GetViewShell()->UpdateInputHandler();
2316 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2317 if (pViewData
->HasEditView(eWhich
))
2319 // Text-Cursor gleich an die geklickte Stelle setzen
2320 EditView
* pEditView
= pViewData
->GetEditView( eWhich
);
2321 MouseEvent
aEditEvt( rMEvt
.GetPosPixel(), 1, MOUSE_SYNTHETIC
, MOUSE_LEFT
, 0 );
2322 pEditView
->MouseButtonDown( aEditEvt
);
2323 pEditView
->MouseButtonUp( aEditEvt
);
2330 // Links in edit cells
2333 bool bAlt
= rMEvt
.IsMod2();
2334 if ( !bAlt
&& !bRefMode
&& !bDouble
&& nMouseStatus
== SC_GM_URLDOWN
)
2336 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2338 OUString aName
, aUrl
, aTarget
;
2339 if ( GetEditUrl( rMEvt
.GetPosPixel(), &aName
, &aUrl
, &aTarget
) )
2341 nMouseStatus
= SC_GM_NONE
; // keinen Doppelklick anfangen
2343 // ScGlobal::OpenURL() only understands Calc A1 style syntax.
2344 // Convert it to Calc A1 before calling OpenURL().
2346 if (pDoc
->GetAddressConvention() == formula::FormulaGrammar::CONV_OOO
)
2347 ScGlobal::OpenURL(aUrl
, aTarget
);
2350 ScAddress aTempAddr
;
2351 ScAddress::ExternalInfo aExtInfo
;
2352 sal_uInt16 nRes
= aTempAddr
.Parse(aUrl
, pDoc
, pDoc
->GetAddressConvention(), &aExtInfo
);
2353 if (!(nRes
& SCA_VALID
))
2355 // Not a reference string. Pass it through unmodified.
2356 ScGlobal::OpenURL(aUrl
, aTarget
);
2360 OUStringBuffer aBuf
;
2361 if (aExtInfo
.mbExternal
)
2363 // External reference.
2364 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
2365 const OUString
* pStr
= pRefMgr
->getExternalFileName(aExtInfo
.mnFileId
);
2370 aBuf
.append(aExtInfo
.maTabName
);
2372 OUString
aRefCalcA1(aTempAddr
.Format(SCA_ABS
, NULL
, formula::FormulaGrammar::CONV_OOO
));
2373 aBuf
.append(aRefCalcA1
);
2374 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2378 // Internal reference.
2380 OUString
aUrlCalcA1(aTempAddr
.Format(SCA_ABS_3D
, pDoc
, formula::FormulaGrammar::CONV_OOO
));
2381 aBuf
.append(aUrlCalcA1
);
2382 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2386 // fire worksheet_followhyperlink event
2387 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents
= pDoc
->GetVbaEventProcessor();
2388 if( xVbaEvents
.is() ) try
2390 Point aPos
= rMEvt
.GetPosPixel();
2393 SCTAB nTab
= pViewData
->GetTabNo();
2394 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2396 ScRefCellValue aCell
;
2397 if (lcl_GetHyperlinkCell(pDoc
, nPosX
, nPosY
, nTab
, aCell
, sURL
))
2399 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
2400 uno::Reference
< table::XCell
> xCell( new ScCellObj( pViewData
->GetDocShell(), aCellPos
) );
2401 uno::Sequence
< uno::Any
> aArgs(1);
2403 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK
, aArgs
);
2406 catch( uno::Exception
& )
2415 // Gridwin - SelectionEngine
2418 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2419 // sal_True for any call, so IsLeft must be checked here, too.
2421 if ( rMEvt
.IsLeft() && pViewData
->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt
) )
2423 pViewData
->GetView()->SelectionChanged();
2425 SfxDispatcher
* pDisp
= pViewData
->GetViewShell()->GetDispatcher();
2426 bool bFormulaMode
= pScMod
->IsFormulaMode();
2427 OSL_ENSURE( pDisp
|| bFormulaMode
, "Cursor auf nicht aktiver View bewegen ?" );
2429 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2430 // multiple selection, so the argument string completely describes the selection,
2431 // and executing the slot won't change the existing selection (executing the slot
2432 // here and from a recorded macro is treated equally)
2434 if ( pDisp
&& !bFormulaMode
&& !rMark
.IsMultiMarked() )
2436 OUString aAddr
; // CurrentCell
2437 if( rMark
.IsMarked() )
2440 rMark
.GetMarkArea( aScRange
);
2441 aAddr
= aScRange
.Format(SCR_ABS
);
2442 if ( aScRange
.aStart
== aScRange
.aEnd
)
2444 // make sure there is a range selection string even for a single cell
2445 aAddr
= aAddr
+ ":" + aAddr
;
2448 //! SID_MARKAREA gibts nicht mehr ???
2449 //! was passiert beim Markieren mit dem Cursor ???
2451 else // nur Cursor bewegen
2453 ScAddress
aScAddress( pViewData
->GetCurX(), pViewData
->GetCurY(), 0 );
2454 aAddr
= aScAddress
.Format(SCA_ABS
);
2457 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
2458 // We don't want to align to the cursor position because if the
2459 // cell cursor isn't visible after making selection, it would jump
2460 // back to the origin of the selection where the cell cursor is.
2461 SfxBoolItem
aAlignCursorItem( FN_PARAM_2
, false );
2462 pDisp
->Execute( SID_CURRENTCELL
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
2463 &aPosItem
, &aAlignCursorItem
, (void*)0L );
2465 pViewData
->GetView()->InvalidateAttribs();
2467 pViewData
->GetViewShell()->SelectionChanged();
2472 void ScGridWindow::FakeButtonUp()
2476 MouseEvent
aEvent( aCurMousePos
); // nButtons = 0 -> ignore
2477 MouseButtonUp( aEvent
);
2481 void ScGridWindow::MouseMove( const MouseEvent
& rMEvt
)
2483 aCurMousePos
= rMEvt
.GetPosPixel();
2485 if ( rMEvt
.IsLeaveWindow() && pNoteMarker
&& !pNoteMarker
->IsByKeyboard() )
2488 ScModule
* pScMod
= SC_MOD();
2489 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2492 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2493 // nicht anders mit:
2495 if (bEEMouse
&& nButtonDown
&& !rMEvt
.GetButtons())
2499 nMouseStatus
= SC_GM_NONE
;
2503 if (nMouseStatus
== SC_GM_IGNORE
)
2506 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus -> nur auf Up warten
2509 if ( pViewData
->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2511 SetPointer( Pointer( POINTER_FILL
) );
2515 if (nMouseStatus
== SC_GM_FILTER
&& pFilterBox
)
2517 Point aRelPos
= pFilterBox
->ScreenToOutputPixel( OutputToScreenPixel( rMEvt
.GetPosPixel() ) );
2518 if ( Rectangle(Point(),pFilterBox
->GetOutputSizePixel()).IsInside(aRelPos
) )
2521 nMouseStatus
= SC_GM_NONE
;
2523 pFilterBox
->MouseButtonDown( MouseEvent( aRelPos
, 1, MOUSE_SIMPLECLICK
, MOUSE_LEFT
) );
2528 bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
2530 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2532 EditView
* pEditView
;
2535 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2536 pEditView
->MouseMove( rMEvt
);
2542 DPMouseMove( rMEvt
);
2548 RFMouseMove( rMEvt
, false );
2552 if (nPagebreakMouse
)
2554 PagebreakMove( rMEvt
, false );
2558 // anderen Mauszeiger anzeigen?
2560 bool bEditMode
= pViewData
->HasEditView(eWhich
);
2562 //! Testen ob RefMode-Dragging !!!
2563 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
2565 Point aPos
= rMEvt
.GetPosPixel();
2568 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2570 EditView
* pEditView
;
2573 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2574 SCCOL nEndCol
= pViewData
->GetEditEndCol();
2575 SCROW nEndRow
= pViewData
->GetEditEndRow();
2577 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
2578 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
2580 // Field can only be URL field
2581 bool bAlt
= rMEvt
.IsMod2();
2582 if ( !bAlt
&& !nButtonDown
&& pEditView
&& pEditView
->GetFieldUnderMousePointer() )
2583 SetPointer( Pointer( POINTER_REFHAND
) );
2584 else if ( pEditView
&& pEditView
->GetEditEngine()->IsVertical() )
2585 SetPointer( Pointer( POINTER_TEXT_VERTICAL
) );
2587 SetPointer( Pointer( POINTER_TEXT
) );
2592 bool bWater
= SC_MOD()->GetIsWaterCan() || pViewData
->GetView()->HasPaintBrush();
2594 SetPointer( Pointer(POINTER_FILL
) );
2598 bool bCross
= false;
2602 RfCorner rCorner
= NONE
;
2603 if ( HitRangeFinder( rMEvt
.GetPosPixel(), rCorner
) )
2605 if (rCorner
!= NONE
)
2606 SetPointer( Pointer( POINTER_CROSS
) );
2608 SetPointer( Pointer( POINTER_HAND
) );
2614 sal_uInt16 nBreakType
;
2615 if ( !nButtonDown
&& pViewData
->IsPagebreakMode() &&
2616 ( nBreakType
= HitPageBreak( rMEvt
.GetPosPixel() ) ) != 0 )
2618 PointerStyle eNew
= POINTER_ARROW
;
2619 switch ( nBreakType
)
2624 eNew
= POINTER_ESIZE
;
2629 eNew
= POINTER_SSIZE
;
2631 case SC_PD_RANGE_TL
:
2632 case SC_PD_RANGE_BR
:
2633 eNew
= POINTER_SESIZE
;
2635 case SC_PD_RANGE_TR
:
2636 case SC_PD_RANGE_BL
:
2637 eNew
= POINTER_NESIZE
;
2640 SetPointer( Pointer( eNew
) );
2644 // Fill-Cursor anzeigen ?
2646 if ( !bFormulaMode
&& !nButtonDown
)
2647 if (TestMouse( rMEvt
, false ))
2650 if ( nButtonDown
&& pViewData
->IsAnyFillMode() )
2652 SetPointer( Pointer( POINTER_CROSS
) );
2654 nScFillModeMouseModifier
= rMEvt
.GetModifier(); // ausgewertet bei AutoFill und Matrix
2659 bool bAlt
= rMEvt
.IsMod2();
2661 if (bEditMode
) // Edit-Mode muss zuerst kommen!
2662 SetPointer( Pointer( POINTER_ARROW
) );
2663 else if ( !bAlt
&& !nButtonDown
&&
2664 GetEditUrl(rMEvt
.GetPosPixel()) )
2665 SetPointer( Pointer( POINTER_REFHAND
) );
2666 else if ( DrawMouseMove(rMEvt
) ) // setzt Pointer um
2671 if ( pViewData
->GetView()->GetSelEngine()->SelMouseMove( rMEvt
) )
2675 static void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent
& rEvent
, const MouseEvent
& rEvt
)
2677 rEvent
.Modifiers
= 0;
2678 if ( rEvt
.IsShift() )
2679 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::SHIFT
;
2680 if ( rEvt
.IsMod1() )
2681 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD1
;
2682 if ( rEvt
.IsMod2() )
2683 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD2
;
2684 if ( rEvt
.IsMod3() )
2685 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD3
;
2688 if ( rEvt
.IsLeft() )
2689 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::LEFT
;
2690 if ( rEvt
.IsRight() )
2691 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::RIGHT
;
2692 if ( rEvt
.IsMiddle() )
2693 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::MIDDLE
;
2695 rEvent
.X
= rEvt
.GetPosPixel().X();
2696 rEvent
.Y
= rEvt
.GetPosPixel().Y();
2697 rEvent
.ClickCount
= rEvt
.GetClicks();
2698 rEvent
.PopupTrigger
= false;
2701 bool ScGridWindow::PreNotify( NotifyEvent
& rNEvt
)
2704 sal_uInt16 nType
= rNEvt
.GetType();
2705 if ( nType
== EVENT_MOUSEBUTTONUP
|| nType
== EVENT_MOUSEBUTTONDOWN
)
2707 Window
* pWindow
= rNEvt
.GetWindow();
2708 if (pWindow
== this && pViewData
)
2710 SfxViewFrame
* pViewFrame
= pViewData
->GetViewShell()->GetViewFrame();
2713 com::sun::star::uno::Reference
<com::sun::star::frame::XController
> xController
= pViewFrame
->GetFrame().GetController();
2714 if (xController
.is())
2716 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
2717 if (pImp
&& pImp
->IsMouseListening())
2719 ::com::sun::star::awt::MouseEvent aEvent
;
2720 lcl_InitMouseEvent( aEvent
, *rNEvt
.GetMouseEvent() );
2721 if ( rNEvt
.GetWindow() )
2722 aEvent
.Source
= rNEvt
.GetWindow()->GetComponentInterface();
2723 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2724 bDone
= pImp
->MousePressed( aEvent
);
2726 bDone
= pImp
->MouseReleased( aEvent
);
2732 if (bDone
) // event consumed by a listener
2734 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2736 const MouseEvent
* pMouseEvent
= rNEvt
.GetMouseEvent();
2737 if ( pMouseEvent
->IsRight() && pMouseEvent
->GetClicks() == 1 )
2739 // If a listener returned true for a right-click call, also prevent opening the context menu
2740 // (this works only if the context menu is opened on mouse-down)
2741 nMouseStatus
= SC_GM_IGNORE
;
2748 return Window::PreNotify( rNEvt
);
2751 void ScGridWindow::Tracking( const TrackingEvent
& rTEvt
)
2753 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2754 // die verschiedenen MouseHandler verteilen...
2756 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
2758 if ( rTEvt
.IsTrackingCanceled() ) // alles abbrechen...
2760 if (!pViewData
->GetView()->IsInActivatePart() && !SC_MOD()->IsRefDialogOpen())
2763 bDPMouse
= false; // gezeichnet wird per bDragRect
2766 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2768 UpdateDragRectOverlay();
2772 RFMouseMove( rMEvt
, true ); // richtig abbrechen geht dabei nicht...
2775 if (nPagebreakMouse
)
2777 // if (bPagebreakDrawn)
2778 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2779 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
2780 bPagebreakDrawn
= false;
2781 UpdateDragRectOverlay();
2782 nPagebreakMouse
= SC_PD_NONE
;
2785 SetPointer( Pointer( POINTER_ARROW
) );
2787 MouseButtonUp( rMEvt
); // mit Status SC_GM_IGNORE aus StopMarking
2789 bool bRefMode
= pViewData
->IsRefMode();
2791 SC_MOD()->EndReference(); // Dialog nicht verkleinert lassen
2794 else if ( rTEvt
.IsTrackingEnded() )
2796 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2797 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2798 // abgebrochen wurde.
2800 MouseEvent
aUpEvt( rMEvt
.GetPosPixel(), rMEvt
.GetClicks(),
2801 rMEvt
.GetMode(), nButtonDown
, rMEvt
.GetModifier() );
2802 MouseButtonUp( aUpEvt
);
2808 void ScGridWindow::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
2810 if ( pFilterBox
|| nPagebreakMouse
)
2815 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, true );
2817 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2819 EditView
* pEditView
;
2822 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2824 // don't remove the edit view while switching views
2825 ScModule
* pScMod
= SC_MOD();
2826 pScMod
->SetInEditCommand( true );
2828 pEditView
->Command( aDragEvent
);
2830 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2832 pHdl
->DataChanged();
2834 pScMod
->SetInEditCommand( false );
2835 if (!pViewData
->IsActive()) // dropped to different view?
2837 ScInputHandler
* pViewHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2838 if ( pViewHdl
&& pViewData
->HasEditView( eWhich
) )
2840 pViewHdl
->CancelHandler();
2841 ShowCursor(); // missing from KillEditView
2846 if ( !DrawCommand(aDragEvent
) )
2847 pViewData
->GetView()->GetSelEngine()->Command( aDragEvent
);
2850 static void lcl_SetTextCursorPos( ScViewData
* pViewData
, ScSplitPos eWhich
, Window
* pWin
)
2852 SCCOL nCol
= pViewData
->GetCurX();
2853 SCROW nRow
= pViewData
->GetCurY();
2854 Rectangle aEditArea
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, pWin
, NULL
, true );
2855 aEditArea
.Right() = aEditArea
.Left();
2856 aEditArea
= pWin
->PixelToLogic( aEditArea
);
2857 pWin
->SetCursorRect( &aEditArea
);
2860 void ScGridWindow::Command( const CommandEvent
& rCEvt
)
2862 // The command event is send to the window after a possible context
2863 // menu from an inplace client is closed. Now we have the chance to
2864 // deactivate the inplace client without any problem regarding parent
2865 // windows and code on the stack.
2866 sal_uInt16 nCmd
= rCEvt
.GetCommand();
2867 ScTabViewShell
* pTabViewSh
= pViewData
->GetViewShell();
2868 SfxInPlaceClient
* pClient
= pTabViewSh
->GetIPClient();
2870 pClient
->IsObjectInPlaceActive() &&
2871 nCmd
== COMMAND_CONTEXTMENU
)
2873 pTabViewSh
->DeactivateOle();
2877 ScModule
* pScMod
= SC_MOD();
2878 OSL_ENSURE( nCmd
!= COMMAND_STARTDRAG
, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2880 if ( nCmd
== COMMAND_STARTEXTTEXTINPUT
||
2881 nCmd
== COMMAND_ENDEXTTEXTINPUT
||
2882 nCmd
== COMMAND_EXTTEXTINPUT
||
2883 nCmd
== COMMAND_CURSORPOS
||
2884 nCmd
== COMMAND_QUERYCHARPOSITION
)
2886 bool bEditView
= pViewData
->HasEditView( eWhich
);
2889 // only if no cell editview is active, look at drawview
2890 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2893 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2894 if ( pOlView
&& pOlView
->GetWindow() == this )
2896 pOlView
->Command( rCEvt
);
2902 if ( nCmd
== COMMAND_CURSORPOS
&& !bEditView
)
2904 // CURSORPOS may be called without following text input,
2905 // to set the input method window position
2906 // -> input mode must not be started,
2907 // manually calculate text insert position if not in input mode
2909 lcl_SetTextCursorPos( pViewData
, eWhich
, this );
2913 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2916 pHdl
->InputCommand( rCEvt
, true );
2920 Window::Command( rCEvt
);
2924 if ( nCmd
== COMMAND_PASTESELECTION
)
2928 // EditEngine handles selection in MouseButtonUp - no action
2929 // needed in command handler
2933 PasteSelection( rCEvt
.GetMousePosPixel() );
2938 if ( nCmd
== COMMAND_INPUTLANGUAGECHANGE
)
2940 // #i55929# Font and font size state depends on input language if nothing is selected,
2941 // so the slots have to be invalidated when the input language is changed.
2943 SfxBindings
& rBindings
= pViewData
->GetBindings();
2944 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
2945 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
2949 if ( nCmd
== COMMAND_WHEEL
|| nCmd
== COMMAND_STARTAUTOSCROLL
|| nCmd
== COMMAND_AUTOSCROLL
)
2951 bool bDone
= pViewData
->GetView()->ScrollCommand( rCEvt
, eWhich
);
2953 Window::Command(rCEvt
);
2956 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2957 bool bDisable
= pScMod
->IsFormulaMode() ||
2958 pScMod
->IsModalMode(pViewData
->GetSfxDocShell());
2962 if ( nCmd
== COMMAND_CONTEXTMENU
&& !SC_MOD()->GetIsWaterCan() )
2964 bool bMouse
= rCEvt
.IsMouseEvent();
2965 if ( bMouse
&& nMouseStatus
== SC_GM_IGNORE
)
2968 if (pViewData
->IsAnyFillMode())
2970 pViewData
->GetView()->StopRefMode();
2971 pViewData
->ResetFillMode();
2976 Point aPosPixel
= rCEvt
.GetMousePosPixel();
2977 Point aMenuPos
= aPosPixel
;
2981 pViewData
->GetPosFromPixel(aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nCellX
, nCellY
);
2983 bool bSpellError
= false;
2984 SCCOL nColSpellError
= nCellX
;
2985 ScRefCellValue aSpellCheckCell
;
2989 ScDocument
* pDoc
= pViewData
->GetDocument();
2990 SCTAB nTab
= pViewData
->GetTabNo();
2991 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
2992 bool bSelectAllowed
= true;
2993 if ( pProtect
&& pProtect
->isProtected() )
2995 // This sheet is protected. Check if a context menu is allowed on this cell.
2996 bool bCellProtected
= pDoc
->HasAttrib(nCellX
, nCellY
, nTab
, nCellX
, nCellY
, nTab
, HASATTR_PROTECTED
);
2997 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2998 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
3001 bSelectAllowed
= bSelProtected
;
3003 bSelectAllowed
= bSelUnprotected
;
3005 if (!bSelectAllowed
)
3006 // Selecting this cell is not allowed, neither is context menu.
3009 if (mpSpellCheckCxt
)
3011 // Find the first string to the left for spell checking in case the current cell is empty.
3012 ScAddress
aPos(nCellX
, nCellY
, nTab
);
3013 aSpellCheckCell
.assign(*pDoc
, aPos
);
3014 while (aSpellCheckCell
.meType
== CELLTYPE_NONE
)
3016 // Loop until we get the first non-empty cell in the row.
3021 aSpellCheckCell
.assign(*pDoc
, aPos
);
3024 if (aPos
.Col() >= 0 && (aSpellCheckCell
.meType
== CELLTYPE_STRING
|| aSpellCheckCell
.meType
== CELLTYPE_EDIT
))
3025 nColSpellError
= aPos
.Col();
3027 bSpellError
= (mpSpellCheckCxt
->isMisspelled(nColSpellError
, nCellY
));
3030 // Check and see if a misspelled word is under the mouse pointer.
3031 bSpellError
= IsSpellErrorAtPos(aPosPixel
, nColSpellError
, nCellX
, nCellY
);
3035 // #i18735# First select the item under the mouse pointer.
3036 // This can change the selection, and the view state (edit mode, etc).
3037 SelectForContextMenu(aPosPixel
, bSpellError
? nColSpellError
: nCellX
, nCellY
);
3041 bool bEdit
= pViewData
->HasEditView(eWhich
);
3045 // Edit-Zelle mit Spelling-Errors ?
3046 if (bMouse
&& (GetEditUrl(aPosPixel
) || bSpellError
))
3048 // GetEditUrlOrError hat den Cursor schon bewegt
3050 pScMod
->SetInputMode( SC_INPUT_TABLE
);
3051 bEdit
= pViewData
->HasEditView(eWhich
); // hat's geklappt ?
3053 OSL_ENSURE( bEdit
, "kann nicht in Edit-Modus schalten" );
3058 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
3062 Cursor
* pCur
= pEditView
->GetCursor();
3065 Point aLogicPos
= pCur
->GetPos();
3066 // use the position right of the cursor (spell popup is opened if
3067 // the cursor is before the word, but not if behind it)
3068 aLogicPos
.X() += pCur
->GetWidth();
3069 aLogicPos
.Y() += pCur
->GetHeight() / 2; // center vertically
3070 aMenuPos
= LogicToPixel( aLogicPos
);
3074 // if edit mode was just started above, online spelling may be incomplete
3075 pEditView
->GetEditEngine()->CompleteOnlineSpelling();
3077 // IsCursorAtWrongSpelledWord could be used for !bMouse
3078 // if there was a corresponding ExecuteSpellPopup call
3082 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
3083 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
3085 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
3087 pHdl
->SetModified();
3089 Link aLink
= LINK( this, ScGridWindow
, PopupSpellingHdl
);
3090 pEditView
->ExecuteSpellPopup( aMenuPos
, &aLink
);
3097 // non-edit menu by keyboard -> use lower right of cell cursor position
3098 ScDocument
* aDoc
= pViewData
->GetDocument();
3099 SCTAB nTabNo
= pViewData
->GetTabNo();
3100 bool bLayoutIsRTL
= aDoc
->IsLayoutRTL(nTabNo
);
3102 SCCOL nCurX
= pViewData
->GetCurX();
3103 SCROW nCurY
= pViewData
->GetCurY();
3104 aMenuPos
= pViewData
->GetScrPos( nCurX
, nCurY
, eWhich
, true );
3107 pViewData
->GetMergeSizePixel( nCurX
, nCurY
, nSizeXPix
, nSizeYPix
);
3108 // fdo#55432 take the correct position for RTL sheet
3109 aMenuPos
.X() += bLayoutIsRTL
? -nSizeXPix
: nSizeXPix
;
3110 aMenuPos
.Y() += nSizeYPix
;
3112 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3115 // Is a draw object selected?
3117 SdrView
* pDrawView
= pViewSh
->GetSdrView();
3118 if (pDrawView
&& pDrawView
->AreObjectsMarked())
3120 // #100442#; the conext menu should open in the middle of the selected objects
3121 Rectangle
aSelectRect(LogicToPixel(pDrawView
->GetAllMarkedBoundRect()));
3122 aMenuPos
= aSelectRect
.Center();
3129 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos
);
3134 void ScGridWindow::SelectForContextMenu( const Point
& rPosPixel
, SCsCOL nCellX
, SCsROW nCellY
)
3136 // #i18735# if the click was outside of the current selection,
3137 // the cursor is moved or an object at the click position selected.
3138 // (see SwEditWin::SelectMenuPosition in Writer)
3140 ScTabView
* pView
= pViewData
->GetView();
3141 ScDrawView
* pDrawView
= pView
->GetScDrawView();
3143 // check cell edit mode
3145 if ( pViewData
->HasEditView(eWhich
) )
3147 ScModule
* pScMod
= SC_MOD();
3148 SCCOL nEditStartCol
= pViewData
->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
3149 SCROW nEditStartRow
= pViewData
->GetEditViewRow();
3150 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
3151 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
3153 if ( nCellX
>= (SCsCOL
) nEditStartCol
&& nCellX
<= (SCsCOL
) nEditEndCol
&&
3154 nCellY
>= (SCsROW
) nEditStartRow
&& nCellY
<= (SCsROW
) nEditEndRow
)
3156 // handle selection within the EditView
3158 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // not NULL (HasEditView)
3159 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
3160 Rectangle aOutputArea
= pEditView
->GetOutputArea();
3161 Rectangle aVisArea
= pEditView
->GetVisArea();
3163 Point aTextPos
= PixelToLogic( rPosPixel
);
3164 if ( pEditEngine
->IsVertical() ) // have to manually transform position
3166 aTextPos
-= aOutputArea
.TopRight();
3167 long nTemp
= -aTextPos
.X();
3168 aTextPos
.X() = aTextPos
.Y();
3169 aTextPos
.Y() = nTemp
;
3172 aTextPos
-= aOutputArea
.TopLeft();
3173 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3175 EPosition aDocPosition
= pEditEngine
->FindDocPosition(aTextPos
);
3176 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3177 ESelection aSelection
= pEditView
->GetSelection();
3178 aSelection
.Adjust(); // needed for IsLess/IsGreater
3179 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3181 // clicked outside the selected text - deselect and move text cursor
3182 MouseEvent
aEvent( rPosPixel
);
3183 pEditView
->MouseButtonDown( aEvent
);
3184 pEditView
->MouseButtonUp( aEvent
);
3185 pScMod
->InputSelection( pEditView
);
3188 return; // clicked within the edit view - keep edit mode
3192 // outside of the edit view - end edit mode, regardless of cell selection, then continue
3193 pScMod
->InputEnterHandler();
3197 // check draw text edit mode
3199 Point aLogicPos
= PixelToLogic( rPosPixel
); // after cell edit mode is ended
3200 if ( pDrawView
&& pDrawView
->GetTextEditObject() && pDrawView
->GetTextEditOutlinerView() )
3202 OutlinerView
* pOlView
= pDrawView
->GetTextEditOutlinerView();
3203 Rectangle aOutputArea
= pOlView
->GetOutputArea();
3204 if ( aOutputArea
.IsInside( aLogicPos
) )
3206 // handle selection within the OutlinerView
3208 Outliner
* pOutliner
= pOlView
->GetOutliner();
3209 const EditEngine
& rEditEngine
= pOutliner
->GetEditEngine();
3210 Rectangle aVisArea
= pOlView
->GetVisArea();
3212 Point aTextPos
= aLogicPos
;
3213 if ( pOutliner
->IsVertical() ) // have to manually transform position
3215 aTextPos
-= aOutputArea
.TopRight();
3216 long nTemp
= -aTextPos
.X();
3217 aTextPos
.X() = aTextPos
.Y();
3218 aTextPos
.Y() = nTemp
;
3221 aTextPos
-= aOutputArea
.TopLeft();
3222 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3224 EPosition aDocPosition
= rEditEngine
.FindDocPosition(aTextPos
);
3225 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3226 ESelection aSelection
= pOlView
->GetSelection();
3227 aSelection
.Adjust(); // needed for IsLess/IsGreater
3228 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3230 // clicked outside the selected text - deselect and move text cursor
3231 // use DrawView to allow extra handling there (none currently)
3232 MouseEvent
aEvent( rPosPixel
);
3233 pDrawView
->MouseButtonDown( aEvent
, this );
3234 pDrawView
->MouseButtonUp( aEvent
, this );
3237 return; // clicked within the edit area - keep edit mode
3241 // Outside of the edit area - end text edit mode, then continue.
3242 // DrawDeselectAll also ends text edit mode and updates the shells.
3243 // If the click was on the edited object, it will be selected again below.
3244 pView
->DrawDeselectAll();
3248 // look for existing selection
3250 bool bHitSelected
= false;
3251 if ( pDrawView
&& pDrawView
->IsMarkedObjHit( aLogicPos
) )
3253 // clicked on selected object -> don't change anything
3254 bHitSelected
= true;
3256 else if ( pViewData
->GetMarkData().IsCellMarked(nCellX
, nCellY
) )
3258 // clicked on selected cell -> don't change anything
3259 bHitSelected
= true;
3262 // select drawing object or move cell cursor
3264 if ( !bHitSelected
)
3266 bool bWasDraw
= ( pDrawView
&& pDrawView
->AreObjectsMarked() );
3267 bool bHitDraw
= false;
3270 pDrawView
->UnmarkAllObj();
3271 // Unlock the Internal Layer in order to activate the context menu.
3272 // re-lock in ScDrawView::MarkListHasChanged()
3273 lcl_UnLockComment( pDrawView
, aLogicPos
,pViewData
);
3274 bHitDraw
= pDrawView
->MarkObj( aLogicPos
);
3275 // draw shell is activated in MarkListHasChanged
3280 pView
->SetCursor(nCellX
, nCellY
);
3282 pViewData
->GetViewShell()->SetDrawShell( false ); // switch shells
3287 void ScGridWindow::KeyInput(const KeyEvent
& rKEvt
)
3289 // Cursor control for ref input dialog
3290 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
3291 if( SC_MOD()->IsRefDialogOpen() )
3293 if( !rKeyCode
.GetModifier() && (rKeyCode
.GetCode() == KEY_F2
) )
3295 SC_MOD()->EndReference();
3297 else if( pViewData
->GetViewShell()->MoveCursorKeyInput( rKEvt
) )
3300 pViewData
->GetRefStartX(), pViewData
->GetRefStartY(), pViewData
->GetRefStartZ(),
3301 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(), pViewData
->GetRefEndZ() );
3302 SC_MOD()->SetReference( aRef
, pViewData
->GetDocument() );
3304 pViewData
->GetViewShell()->SelectionChanged();
3307 else if( rKeyCode
.GetCode() == KEY_RETURN
&& pViewData
->IsPasteMode() )
3309 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
3310 ScClipUtil::PasteFromClipboard( pViewData
, pTabViewShell
, false );
3312 // Clear clipboard content.
3313 uno::Reference
<datatransfer::clipboard::XClipboard
> xSystemClipboard
=
3314 TransferableHelper::GetSystemClipboard();
3315 if (xSystemClipboard
.is())
3317 xSystemClipboard
->setContents(
3318 uno::Reference
<datatransfer::XTransferable
>(),
3319 uno::Reference
<datatransfer::clipboard::XClipboardOwner
>());
3322 // hide the border around the copy source
3323 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3324 // Clear CopySourceOverlay in each window of a split/frozen tabview
3325 pViewData
->GetView()->UpdateCopySourceOverlay();
3328 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3329 else if( !pViewData
->IsAnyFillMode() )
3331 if (rKeyCode
.GetCode() == KEY_ESCAPE
)
3333 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3334 // Clear CopySourceOverlay in each window of a split/frozen tabview
3335 pViewData
->GetView()->UpdateCopySourceOverlay();
3337 // query for existing note marker before calling ViewShell's keyboard handling
3338 // which may remove the marker
3339 bool bHadKeyMarker
= ( pNoteMarker
&& pNoteMarker
->IsByKeyboard() );
3340 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3342 if (pViewData
->GetDocShell()->GetProgress())
3345 if (DrawKeyInput(rKEvt
))
3347 const KeyCode
& rLclKeyCode
= rKEvt
.GetKeyCode();
3348 if (rLclKeyCode
.GetCode() == KEY_DOWN
3349 || rLclKeyCode
.GetCode() == KEY_UP
3350 || rLclKeyCode
.GetCode() == KEY_LEFT
3351 || rLclKeyCode
.GetCode() == KEY_RIGHT
)
3353 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
3354 SfxBindings
& rBindings
= pViewShell
->GetViewFrame()->GetBindings();
3355 rBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_X
);
3356 rBindings
.Invalidate(SID_ATTR_TRANSFORM_POS_Y
);
3361 if (!pViewData
->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3362 { //! DrawShell abfragen !!!
3363 if (pViewSh
->TabKeyInput(rKEvt
))
3367 if (pViewSh
->SfxViewShell::KeyInput(rKEvt
)) // von SfxViewShell
3370 KeyCode aCode
= rKEvt
.GetKeyCode();
3371 if ( aCode
.GetCode() == KEY_ESCAPE
&& aCode
.GetModifier() == 0 )
3373 if ( bHadKeyMarker
)
3379 if ( aCode
.GetCode() == KEY_F1
&& aCode
.GetModifier() == KEY_MOD1
)
3381 // ctrl-F1 shows or hides the note or redlining info for the cursor position
3382 // (hard-coded because F1 can't be configured)
3384 if ( bHadKeyMarker
)
3385 HideNoteMarker(); // hide when previously visible
3387 ShowNoteMarker( pViewData
->GetCurX(), pViewData
->GetCurY(), true );
3390 if (aCode
.GetCode() == KEY_BRACKETLEFT
&& aCode
.GetModifier() == KEY_MOD1
)
3392 pViewSh
->DetectiveMarkPred();
3395 if (aCode
.GetCode() == KEY_BRACKETRIGHT
&& aCode
.GetModifier() == KEY_MOD1
)
3397 pViewSh
->DetectiveMarkSucc();
3403 Window::KeyInput(rKEvt
);
3406 void ScGridWindow::StopMarking()
3408 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3412 pViewData
->GetMarkData().SetMarking(false);
3413 nMouseStatus
= SC_GM_IGNORE
;
3417 void ScGridWindow::UpdateInputContext()
3419 bool bReadOnly
= pViewData
->GetDocShell()->IsReadOnly();
3420 sal_uLong nOptions
= bReadOnly
? 0 : ( INPUTCONTEXT_TEXT
| INPUTCONTEXT_EXTTEXTINPUT
);
3422 // when font from InputContext is used,
3423 // it must be taken from the cursor position's cell attributes
3425 InputContext aContext
;
3426 aContext
.SetOptions( nOptions
);
3427 SetInputContext( aContext
);
3430 // sensitiver Bereich (Pixel)
3431 #define SCROLL_SENSITIVE 20
3433 bool ScGridWindow::DropScroll( const Point
& rMousePos
)
3437 Size aSize
= GetOutputSizePixel();
3439 if (aSize
.Width() > SCROLL_SENSITIVE
* 3)
3441 if ( rMousePos
.X() < SCROLL_SENSITIVE
&& pViewData
->GetPosX(WhichH(eWhich
)) > 0 )
3443 if ( rMousePos
.X() >= aSize
.Width() - SCROLL_SENSITIVE
3444 && pViewData
->GetPosX(WhichH(eWhich
)) < MAXCOL
)
3447 if (aSize
.Height() > SCROLL_SENSITIVE
* 3)
3449 if ( rMousePos
.Y() < SCROLL_SENSITIVE
&& pViewData
->GetPosY(WhichV(eWhich
)) > 0 )
3451 if ( rMousePos
.Y() >= aSize
.Height() - SCROLL_SENSITIVE
3452 && pViewData
->GetPosY(WhichV(eWhich
)) < MAXROW
)
3456 if ( nDx
!= 0 || nDy
!= 0 )
3459 pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
3461 pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
3467 static bool lcl_TestScenarioRedliningDrop( ScDocument
* pDoc
, const ScRange
& aDragRange
)
3469 // Testet, ob bei eingeschalteten RedLining,
3470 // bei einem Drop ein Scenario betroffen ist.
3472 bool bReturn
= false;
3473 SCTAB nTab
= aDragRange
.aStart
.Tab();
3474 SCTAB nTabCount
= pDoc
->GetTableCount();
3476 if(pDoc
->GetChangeTrack()!=NULL
)
3478 if( pDoc
->IsScenario(nTab
) && pDoc
->HasScenarioRange(nTab
, aDragRange
))
3484 for(SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
3486 if(pDoc
->HasScenarioRange(i
, aDragRange
))
3497 static ScRange
lcl_MakeDropRange( SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
, const ScRange
& rSource
)
3499 SCCOL nCol1
= nPosX
;
3500 SCCOL nCol2
= nCol1
+ ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
3501 if ( nCol2
> MAXCOL
)
3503 nCol1
-= nCol2
- MAXCOL
;
3506 SCROW nRow1
= nPosY
;
3507 SCROW nRow2
= nRow1
+ ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
3508 if ( nRow2
> MAXROW
)
3510 nRow1
-= nRow2
- MAXROW
;
3514 return ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
3517 extern bool bPasteIsDrop
; // viewfun4 -> move to header
3518 extern bool bPasteIsMove
; // viewfun7 -> move to header
3520 sal_Int8
ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent
& rEvt
)
3522 if ( rEvt
.mbLeaving
)
3525 UpdateDragRectOverlay();
3526 return rEvt
.mnAction
;
3529 const ScDragData
& rData
= SC_MOD()->GetDragData();
3530 if ( rData
.pCellTransfer
)
3532 // Don't move source that would include filtered rows.
3533 if ((rEvt
.mnAction
& DND_ACTION_MOVE
) && rData
.pCellTransfer
->HasFilteredRows())
3538 UpdateDragRectOverlay();
3540 return DND_ACTION_NONE
;
3543 Point aPos
= rEvt
.maPosPixel
;
3545 ScDocument
* pSourceDoc
= rData
.pCellTransfer
->GetSourceDocument();
3546 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3547 if (pSourceDoc
== pThisDoc
)
3550 if ( pThisDoc
->HasChartAtPoint(pViewData
->GetTabNo(), PixelToLogic(aPos
), aName
))
3552 if (bDragRect
) // Rechteck loeschen
3555 UpdateDragRectOverlay();
3558 //! highlight chart? (selection border?)
3560 sal_Int8 nRet
= rEvt
.mnAction
;
3565 if ( rData
.pCellTransfer
->GetDragSourceFlags() & SC_DROP_TABLE
) // whole sheet?
3567 bool bOk
= pThisDoc
->IsDocEditable();
3568 return bOk
? rEvt
.mnAction
: 0; // don't draw selection frame
3573 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3575 ScRange aSourceRange
= rData
.pCellTransfer
->GetRange();
3576 SCCOL nSourceStartX
= aSourceRange
.aStart
.Col();
3577 SCROW nSourceStartY
= aSourceRange
.aStart
.Row();
3578 SCCOL nSourceEndX
= aSourceRange
.aEnd
.Col();
3579 SCROW nSourceEndY
= aSourceRange
.aEnd
.Row();
3580 SCCOL nSizeX
= nSourceEndX
- nSourceStartX
+ 1;
3581 SCROW nSizeY
= nSourceEndY
- nSourceStartY
+ 1;
3583 if ( rEvt
.mnAction
!= DND_ACTION_MOVE
)
3584 nSizeY
= rData
.pCellTransfer
->GetNonFilteredRows(); // copy/link: no filtered rows
3586 SCsCOL nNewDragX
= nPosX
- rData
.pCellTransfer
->GetDragHandleX();
3587 if (nNewDragX
<0) nNewDragX
=0;
3588 if (nNewDragX
+(nSizeX
-1) > MAXCOL
)
3589 nNewDragX
= MAXCOL
-(nSizeX
-1);
3590 SCsROW nNewDragY
= nPosY
- rData
.pCellTransfer
->GetDragHandleY();
3591 if (nNewDragY
<0) nNewDragY
=0;
3592 if (nNewDragY
+(nSizeY
-1) > MAXROW
)
3593 nNewDragY
= MAXROW
-(nSizeY
-1);
3595 // don't break scenario ranges, don't drop on filtered
3596 SCTAB nTab
= pViewData
->GetTabNo();
3597 ScRange aDropRange
= lcl_MakeDropRange( nNewDragX
, nNewDragY
, nTab
, aSourceRange
);
3598 if ( lcl_TestScenarioRedliningDrop( pThisDoc
, aDropRange
) ||
3599 lcl_TestScenarioRedliningDrop( pSourceDoc
, aSourceRange
) ||
3600 ScViewUtil::HasFiltered( aDropRange
, pThisDoc
) )
3605 UpdateDragRectOverlay();
3607 return DND_ACTION_NONE
;
3610 InsCellCmd eDragInsertMode
= INS_NONE
;
3611 Window::PointerState aState
= GetPointerState();
3613 // check for datapilot item sorting
3614 ScDPObject
* pDPObj
= NULL
;
3615 if ( pThisDoc
== pSourceDoc
&& ( pDPObj
= pThisDoc
->GetDPAtCursor( nNewDragX
, nNewDragY
, nTab
) ) != NULL
)
3617 // drop on DataPilot table: sort or nothing
3619 bool bDPSort
= false;
3620 if ( pThisDoc
->GetDPAtCursor( nSourceStartX
, nSourceStartY
, aSourceRange
.aStart
.Tab() ) == pDPObj
)
3622 sheet::DataPilotTableHeaderData aDestData
;
3623 pDPObj
->GetHeaderPositionData( ScAddress(nNewDragX
, nNewDragY
, nTab
), aDestData
);
3624 bool bValid
= ( aDestData
.Dimension
>= 0 ); // dropping onto a field
3626 // look through the source range
3627 for (SCROW nRow
= aSourceRange
.aStart
.Row(); bValid
&& nRow
<= aSourceRange
.aEnd
.Row(); ++nRow
)
3628 for (SCCOL nCol
= aSourceRange
.aStart
.Col(); bValid
&& nCol
<= aSourceRange
.aEnd
.Col(); ++nCol
)
3630 sheet::DataPilotTableHeaderData aSourceData
;
3631 pDPObj
->GetHeaderPositionData( ScAddress( nCol
, nRow
, aSourceRange
.aStart
.Tab() ), aSourceData
);
3632 if ( aSourceData
.Dimension
!= aDestData
.Dimension
|| aSourceData
.MemberName
.isEmpty() )
3633 bValid
= false; // empty (subtotal) or different field
3639 OUString aDimName
= pDPObj
->GetDimName( aDestData
.Dimension
, bIsDataLayout
);
3640 const ScDPSaveDimension
* pDim
= pDPObj
->GetSaveData()->GetExistingDimensionByName( aDimName
);
3643 ScRange aOutRange
= pDPObj
->GetOutRange();
3645 sal_uInt16 nOrient
= pDim
->GetOrientation();
3646 if ( nOrient
== sheet::DataPilotFieldOrientation_COLUMN
)
3648 eDragInsertMode
= INS_CELLSRIGHT
;
3649 nSizeY
= aOutRange
.aEnd
.Row() - nNewDragY
+ 1;
3652 else if ( nOrient
== sheet::DataPilotFieldOrientation_ROW
)
3654 eDragInsertMode
= INS_CELLSDOWN
;
3655 nSizeX
= aOutRange
.aEnd
.Col() - nNewDragX
+ 1;
3664 // no valid sorting in a DataPilot table -> disallow
3668 UpdateDragRectOverlay();
3670 return DND_ACTION_NONE
;
3673 else if ( aState
.mnState
& KEY_MOD2
)
3675 if ( pThisDoc
== pSourceDoc
&& nTab
== aSourceRange
.aStart
.Tab() )
3677 long nDeltaX
= labs( static_cast< long >( nNewDragX
- nSourceStartX
) );
3678 long nDeltaY
= labs( static_cast< long >( nNewDragY
- nSourceStartY
) );
3679 if ( nDeltaX
<= nDeltaY
)
3681 eDragInsertMode
= INS_CELLSDOWN
;
3685 eDragInsertMode
= INS_CELLSRIGHT
;
3688 if ( ( eDragInsertMode
== INS_CELLSDOWN
&& nNewDragY
<= nSourceEndY
&&
3689 ( nNewDragX
+ nSizeX
- 1 ) >= nSourceStartX
&& nNewDragX
<= nSourceEndX
&&
3690 ( nNewDragX
!= nSourceStartX
|| nNewDragY
>= nSourceStartY
) ) ||
3691 ( eDragInsertMode
== INS_CELLSRIGHT
&& nNewDragX
<= nSourceEndX
&&
3692 ( nNewDragY
+ nSizeY
- 1 ) >= nSourceStartY
&& nNewDragY
<= nSourceEndY
&&
3693 ( nNewDragY
!= nSourceStartY
|| nNewDragX
>= nSourceStartX
) ) )
3698 UpdateDragRectOverlay();
3700 return DND_ACTION_NONE
;
3705 if ( static_cast< long >( nSizeX
) >= static_cast< long >( nSizeY
) )
3707 eDragInsertMode
= INS_CELLSDOWN
;
3712 eDragInsertMode
= INS_CELLSRIGHT
;
3717 if ( nNewDragX
!= (SCsCOL
) nDragStartX
|| nNewDragY
!= (SCsROW
) nDragStartY
||
3718 nDragStartX
+nSizeX
-1 != nDragEndX
|| nDragStartY
+nSizeY
-1 != nDragEndY
||
3719 !bDragRect
|| eDragInsertMode
!= meDragInsertMode
)
3721 nDragStartX
= nNewDragX
;
3722 nDragStartY
= nNewDragY
;
3723 nDragEndX
= nDragStartX
+nSizeX
-1;
3724 nDragEndY
= nDragStartY
+nSizeY
-1;
3726 meDragInsertMode
= eDragInsertMode
;
3728 UpdateDragRectOverlay();
3732 return rEvt
.mnAction
;
3735 sal_Int8
ScGridWindow::AcceptDrop( const AcceptDropEvent
& rEvt
)
3737 const ScDragData
& rData
= SC_MOD()->GetDragData();
3738 if ( rEvt
.mbLeaving
)
3740 DrawMarkDropObj( NULL
);
3741 if ( rData
.pCellTransfer
)
3742 return AcceptPrivateDrop( rEvt
); // hide drop marker for internal D&D
3744 return rEvt
.mnAction
;
3747 if ( pViewData
->GetDocShell()->IsReadOnly() )
3748 return DND_ACTION_NONE
;
3751 sal_Int8 nRet
= DND_ACTION_NONE
;
3753 if (rData
.pCellTransfer
)
3755 ScRange aSource
= rData
.pCellTransfer
->GetRange();
3756 if ( aSource
.aStart
.Col() != 0 || aSource
.aEnd
.Col() != MAXCOL
||
3757 aSource
.aStart
.Row() != 0 || aSource
.aEnd
.Row() != MAXROW
)
3758 DropScroll( rEvt
.maPosPixel
);
3760 nRet
= AcceptPrivateDrop( rEvt
);
3764 if ( !rData
.aLinkDoc
.isEmpty() )
3767 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3768 if (pDocSh
&& pDocSh
->HasName())
3769 aThisName
= pDocSh
->GetMedium()->GetName();
3771 if ( !rData
.aLinkDoc
.equals(aThisName
) )
3772 nRet
= rEvt
.mnAction
;
3774 else if (!rData
.aJumpTarget
.isEmpty())
3776 // internal bookmarks (from Navigator)
3777 // local jumps from an unnamed document are possible only within a document
3779 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
3780 nRet
= rEvt
.mnAction
;
3784 sal_Int8 nMyAction
= rEvt
.mnAction
;
3786 // clear DND_ACTION_LINK when other actions are set. The usage below cannot handle
3787 // multiple set values
3788 if((nMyAction
& DND_ACTION_LINK
) && (nMyAction
& (DND_ACTION_COPYMOVE
)))
3790 nMyAction
&= ~DND_ACTION_LINK
;
3793 if ( !rData
.pDrawTransfer
||
3794 !IsMyModel(rData
.pDrawTransfer
->GetDragSourceView()) ) // drawing within the document
3795 if ( rEvt
.mbDefault
&& nMyAction
== DND_ACTION_MOVE
)
3796 nMyAction
= DND_ACTION_COPY
;
3798 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3799 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint(
3800 pViewData
->GetTabNo(), PixelToLogic(rEvt
.maPosPixel
) );
3801 if ( pHitObj
&& nMyAction
== DND_ACTION_LINK
) // && !rData.pDrawTransfer )
3803 if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB
)
3804 || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE
)
3805 || IsDropFormatSupported(SOT_FORMATSTR_ID_PNG
)
3806 || IsDropFormatSupported(SOT_FORMAT_BITMAP
) )
3808 // graphic dragged onto drawing object
3809 DrawMarkDropObj( pHitObj
);
3814 DrawMarkDropObj( NULL
);
3818 switch ( nMyAction
)
3820 case DND_ACTION_COPY
:
3821 case DND_ACTION_MOVE
:
3822 case DND_ACTION_COPYMOVE
:
3824 bool bMove
= ( nMyAction
== DND_ACTION_MOVE
);
3825 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE
) ||
3826 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3827 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) ||
3828 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3829 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) ||
3830 IsDropFormatSupported( SOT_FORMAT_STRING
) ||
3831 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK
) ||
3832 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3833 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML
) ||
3834 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE
) ||
3835 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF
) ||
3836 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING
) ||
3837 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB
) ||
3838 IsDropFormatSupported( SOT_FORMAT_RTF
) ||
3839 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE
) ||
3840 IsDropFormatSupported( SOT_FORMATSTR_ID_PNG
) ||
3841 IsDropFormatSupported( SOT_FORMAT_BITMAP
) ||
3842 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) ||
3843 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) ||
3845 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3846 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3847 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3848 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3849 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3850 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) ) ) )
3856 case DND_ACTION_LINK
:
3857 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3858 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3859 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3860 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3861 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3862 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3863 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3864 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3865 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3874 // Simple check for protection: It's not known here if the drop will result
3875 // in cells or drawing objects (some formats can be both) and how many cells
3876 // the result will be. But if IsFormatEditable for the drop cell position
3877 // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
3878 // can already be rejected here.
3880 Point aPos
= rEvt
.maPosPixel
;
3883 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3884 SCTAB nTab
= pViewData
->GetTabNo();
3885 ScDocument
* pDoc
= pViewData
->GetDocument();
3887 ScEditableTester
aTester( pDoc
, nTab
, nPosX
,nPosY
, nPosX
,nPosY
);
3888 if ( !aTester
.IsFormatEditable() )
3889 nRet
= DND_ACTION_NONE
; // forbidden
3894 // scroll only for accepted formats
3896 DropScroll( rEvt
.maPosPixel
);
3902 static sal_uLong
lcl_GetDropFormatId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
, bool bPreferText
= false )
3904 TransferableDataHelper
aDataHelper( xTransfer
);
3906 if ( !aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3908 // use bookmark formats if no sba is present
3910 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3911 return SOT_FORMATSTR_ID_SOLK
;
3912 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3913 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3914 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3915 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3916 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3917 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3920 sal_uLong nFormatId
= 0;
3921 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
) )
3922 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
3923 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
3924 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
3925 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
) )
3927 // If it's a Writer object, insert RTF instead of OLE
3929 bool bDoRtf
= false;
3930 SotStorageStreamRef xStm
;
3931 TransferableObjectDescriptor aObjDesc
;
3932 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) &&
3933 aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE
, xStm
) )
3935 SotStorageRef
xStore( new SotStorage( *xStm
) );
3936 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
3937 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
3938 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
3941 nFormatId
= FORMAT_RTF
;
3943 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
3945 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3946 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3947 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3948 nFormatId
= SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
;
3949 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) )
3950 nFormatId
= SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
;
3951 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_8
) )
3952 nFormatId
= SOT_FORMATSTR_ID_BIFF_8
;
3953 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_5
) )
3954 nFormatId
= SOT_FORMATSTR_ID_BIFF_5
;
3955 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) )
3956 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
3957 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) )
3958 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
3959 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3960 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3961 else if ( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
3962 nFormatId
= SOT_FORMAT_RTF
;
3963 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML
) )
3964 nFormatId
= SOT_FORMATSTR_ID_HTML
;
3965 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE
) )
3966 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
3967 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
) )
3968 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
3969 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3970 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3971 else if ( bPreferText
&& aDataHelper
.HasFormat( SOT_FORMAT_STRING
) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3972 nFormatId
= SOT_FORMAT_STRING
;
3973 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3974 nFormatId
= SOT_FORMAT_FILE_LIST
;
3975 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3976 nFormatId
= SOT_FORMAT_FILE
;
3977 else if ( aDataHelper
.HasFormat( SOT_FORMAT_STRING
) )
3978 nFormatId
= SOT_FORMAT_STRING
;
3979 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
3980 nFormatId
= SOT_FORMAT_GDIMETAFILE
;
3981 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_PNG
) )
3982 nFormatId
= SOT_FORMATSTR_ID_PNG
;
3983 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) )
3984 nFormatId
= SOT_FORMAT_BITMAP
;
3989 static sal_uLong
lcl_GetDropLinkId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
)
3991 TransferableDataHelper
aDataHelper( xTransfer
);
3993 sal_uLong nFormatId
= 0;
3994 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3995 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3996 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3997 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3998 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3999 nFormatId
= SOT_FORMATSTR_ID_LINK
;
4000 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
4001 nFormatId
= SOT_FORMAT_FILE_LIST
;
4002 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) )
4003 nFormatId
= SOT_FORMAT_FILE
;
4004 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
4005 nFormatId
= SOT_FORMATSTR_ID_SOLK
;
4006 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
4007 nFormatId
= SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
4008 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
4009 nFormatId
= SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
4010 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
4011 nFormatId
= SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
4017 sal_Int8
ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent
& rEvt
)
4021 UpdateDragRectOverlay();
4023 ScModule
* pScMod
= SC_MOD();
4024 const ScDragData
& rData
= pScMod
->GetDragData();
4026 return DropTransferObj( rData
.pCellTransfer
, nDragStartX
, nDragStartY
,
4027 PixelToLogic(rEvt
.maPosPixel
), rEvt
.mnAction
);
4030 sal_Int8
ScGridWindow::DropTransferObj( ScTransferObj
* pTransObj
, SCCOL nDestPosX
, SCROW nDestPosY
,
4031 const Point
& rLogicPos
, sal_Int8 nDndAction
)
4036 ScDocument
* pSourceDoc
= pTransObj
->GetSourceDocument();
4037 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4038 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4039 ScViewFunc
* pView
= pViewData
->GetView();
4040 SCTAB nThisTab
= pViewData
->GetTabNo();
4041 sal_uInt16 nFlags
= pTransObj
->GetDragSourceFlags();
4043 bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4044 bool bIsMove
= ( nDndAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4046 // workaround for wrong nDndAction on Windows when pressing solely
4047 // the Alt key during drag and drop;
4048 // can be removed after #i79215# has been fixed
4049 if ( meDragInsertMode
!= INS_NONE
)
4051 bIsMove
= ( nDndAction
& DND_ACTION_MOVE
&& !bIsNavi
);
4054 bool bIsLink
= ( nDndAction
== DND_ACTION_LINK
);
4056 ScRange aSource
= pTransObj
->GetRange();
4058 // only use visible tab from source range - when dragging within one table,
4059 // all selected tables at the time of dropping are used (handled in MoveBlockTo)
4060 SCTAB nSourceTab
= pTransObj
->GetVisibleTab();
4061 aSource
.aStart
.SetTab( nSourceTab
);
4062 aSource
.aEnd
.SetTab( nSourceTab
);
4064 SCCOL nSizeX
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
4065 SCROW nSizeY
= (bIsMove
? (aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1) :
4066 pTransObj
->GetNonFilteredRows()); // copy/link: no filtered rows
4067 ScRange
aDest( nDestPosX
, nDestPosY
, nThisTab
,
4068 nDestPosX
+ nSizeX
- 1, nDestPosY
+ nSizeY
- 1, nThisTab
);
4071 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
4072 * dragging and adapted drawing of the selection frame. We check here
4073 * (again) because this may actually also be called from PasteSelection(),
4074 * we would have to duplicate determination of flags and destination range
4075 * and would lose the context of the "filtered destination is OK" cases
4076 * below, which is already awkward enough as is. */
4078 // Don't move filtered source.
4079 bool bFiltered
= (bIsMove
&& pTransObj
->HasFilteredRows());
4082 if (pSourceDoc
!= pThisDoc
&& ((nFlags
& SC_DROP_TABLE
) ||
4083 (!bIsLink
&& meDragInsertMode
== INS_NONE
)))
4085 // Nothing. Either entire sheet to be dropped, or the one case
4086 // where PasteFromClip() is to be called that handles a filtered
4087 // destination itself. Drag-copy from another document without
4091 // Don't copy or move to filtered destination.
4092 bFiltered
= ScViewUtil::HasFiltered( aDest
, pThisDoc
);
4097 if (!bFiltered
&& pSourceDoc
== pThisDoc
)
4099 if ( nFlags
& SC_DROP_TABLE
) // whole sheet?
4101 if ( pThisDoc
->IsDocEditable() )
4103 SCTAB nSrcTab
= aSource
.aStart
.Tab();
4104 pViewData
->GetDocShell()->MoveTable( nSrcTab
, nThisTab
, !bIsMove
, true ); // with Undo
4105 pView
->SetTabNo( nThisTab
, true );
4109 else // move/copy block
4111 OUString aChartName
;
4112 if (pThisDoc
->HasChartAtPoint( nThisTab
, rLogicPos
, aChartName
))
4114 OUString
aRangeName(aSource
.Format(SCR_ABS_3D
, pThisDoc
));
4115 SfxStringItem
aNameItem( SID_CHART_NAME
, aChartName
);
4116 SfxStringItem
aRangeItem( SID_CHART_SOURCE
, aRangeName
);
4117 sal_uInt16 nId
= bIsMove
? SID_CHART_SOURCE
: SID_CHART_ADDSOURCE
;
4118 pViewData
->GetDispatcher().Execute( nId
, SFX_CALLMODE_ASYNCHRON
| SFX_CALLMODE_RECORD
,
4119 &aRangeItem
, &aNameItem
, (void*) NULL
);
4122 else if ( pThisDoc
->GetDPAtCursor( nDestPosX
, nDestPosY
, nThisTab
) )
4124 // drop on DataPilot table: try to sort, fail if that isn't possible
4126 ScAddress
aDestPos( nDestPosX
, nDestPosY
, nThisTab
);
4127 if ( aDestPos
!= aSource
.aStart
)
4128 bDone
= pViewData
->GetView()->DataPilotMove( aSource
, aDestPos
);
4130 bDone
= true; // same position: nothing
4132 else if ( nDestPosX
!= aSource
.aStart
.Col() || nDestPosY
!= aSource
.aStart
.Row() ||
4133 nSourceTab
!= nThisTab
)
4135 OUString aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4136 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4138 SCsCOL nCorrectCursorPosCol
= 0;
4139 SCsROW nCorrectCursorPosRow
= 0;
4142 if ( meDragInsertMode
!= INS_NONE
)
4144 // call with bApi = sal_True to avoid error messages in drop handler
4145 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, true /*bRecord*/, true /*bApi*/, true /*bPartOfPaste*/ );
4148 if ( nThisTab
== nSourceTab
)
4150 if ( meDragInsertMode
== INS_CELLSDOWN
&&
4151 nDestPosX
== aSource
.aStart
.Col() && nDestPosY
< aSource
.aStart
.Row() )
4153 bDone
= aSource
.Move( 0, nSizeY
, 0, pSourceDoc
);
4154 nCorrectCursorPosRow
= nSizeY
;
4156 else if ( meDragInsertMode
== INS_CELLSRIGHT
&&
4157 nDestPosY
== aSource
.aStart
.Row() && nDestPosX
< aSource
.aStart
.Col() )
4159 bDone
= aSource
.Move( nSizeX
, 0, 0, pSourceDoc
);
4160 nCorrectCursorPosCol
= nSizeX
;
4163 pDocSh
->UpdateOle( pViewData
);
4164 pView
->CellContentChanged();
4172 // call with bApi = sal_True to avoid error messages in drop handler
4173 bDone
= pView
->LinkBlock( aSource
, aDest
.aStart
, true /*bApi*/ );
4177 // call with bApi = sal_True to avoid error messages in drop handler
4178 bDone
= pView
->MoveBlockTo( aSource
, aDest
.aStart
, bIsMove
, true /*bRecord*/, true /*bPaint*/, true /*bApi*/ );
4182 if ( bDone
&& meDragInsertMode
!= INS_NONE
&& bIsMove
&& nThisTab
== nSourceTab
)
4184 DelCellCmd eCmd
= DEL_NONE
;
4185 if ( meDragInsertMode
== INS_CELLSDOWN
)
4189 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
4191 eCmd
= DEL_CELLSLEFT
;
4194 if ( ( eCmd
== DEL_CELLSUP
&& nDestPosX
== aSource
.aStart
.Col() ) ||
4195 ( eCmd
== DEL_CELLSLEFT
&& nDestPosY
== aSource
.aStart
.Row() ) )
4197 // call with bApi = sal_True to avoid error messages in drop handler
4198 bDone
= pDocSh
->GetDocFunc().DeleteCells( aSource
, NULL
, eCmd
, true /*bRecord*/, true /*bApi*/ );
4201 if ( eCmd
== DEL_CELLSUP
&& nDestPosY
> aSource
.aEnd
.Row() )
4203 bDone
= aDest
.Move( 0, -nSizeY
, 0, pThisDoc
);
4205 else if ( eCmd
== DEL_CELLSLEFT
&& nDestPosX
> aSource
.aEnd
.Col() )
4207 bDone
= aDest
.Move( -nSizeX
, 0, 0, pThisDoc
);
4209 pDocSh
->UpdateOle( pViewData
);
4210 pView
->CellContentChanged();
4217 pView
->MarkRange( aDest
, false, false );
4219 SCCOL nDCol
= pViewData
->GetCurX() - aSource
.aStart
.Col() + nCorrectCursorPosCol
;
4220 SCROW nDRow
= pViewData
->GetCurY() - aSource
.aStart
.Row() + nCorrectCursorPosRow
;
4221 pView
->SetCursor( aDest
.aStart
.Col() + nDCol
, aDest
.aStart
.Row() + nDRow
);
4224 pDocSh
->GetUndoManager()->LeaveListAction();
4228 bDone
= true; // nothing to do
4232 pTransObj
->SetDragWasInternal(); // don't delete source in DragFinished
4234 else if ( !bFiltered
&& pSourceDoc
) // between documents
4236 if ( nFlags
& SC_DROP_TABLE
) // copy/link sheets between documents
4238 if ( pThisDoc
->IsDocEditable() )
4240 ScDocShell
* pSrcShell
= pTransObj
->GetSourceDocShell();
4242 std::vector
<SCTAB
> nTabs
;
4244 ScMarkData aMark
= pTransObj
->GetSourceMarkData();
4245 SCTAB nTabCount
= pSourceDoc
->GetTableCount();
4247 for(SCTAB i
=0; i
<nTabCount
; i
++)
4249 if(aMark
.GetTableSelect(i
))
4252 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
4254 if((!pSourceDoc
->IsVisible(j
))&&(pSourceDoc
->IsScenario(j
)))
4256 nTabs
.push_back( j
);
4264 pView
->ImportTables( pSrcShell
,static_cast<SCTAB
>(nTabs
.size()), &nTabs
[0], bIsLink
, nThisTab
);
4271 // (external references might be used instead?)
4273 SfxObjectShell
* pSourceSh
= pSourceDoc
->GetDocumentShell();
4274 OSL_ENSURE(pSourceSh
, "drag document has no shell");
4277 OUString aUndo
= ScGlobal::GetRscString( STR_UNDO_COPY
);
4278 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4281 if ( meDragInsertMode
!= INS_NONE
)
4283 // call with bApi = sal_True to avoid error messages in drop handler
4284 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, true /*bRecord*/, true /*bApi*/, true /*bPartOfPaste*/ );
4287 pDocSh
->UpdateOle( pViewData
);
4288 pView
->CellContentChanged();
4294 OUString aApp
= Application::GetAppName();
4295 OUString aTopic
= pSourceSh
->GetTitle( SFX_TITLE_FULLNAME
);
4296 OUString
aItem(aSource
.Format(SCA_VALID
| SCA_TAB_3D
, pSourceDoc
));
4298 // TODO: we could define ocQuote for "
4299 const OUString
aQuote('"');
4300 const OUString
& sSep
= ScCompiler::GetNativeSymbol( ocSep
);
4301 OUStringBuffer aFormula
;
4302 aFormula
.append('=');
4303 aFormula
.append(ScCompiler::GetNativeSymbol(ocDde
));
4304 aFormula
.append(ScCompiler::GetNativeSymbol(ocOpen
));
4305 aFormula
.append(aQuote
);
4306 aFormula
.append(aApp
);
4307 aFormula
.append(aQuote
);
4308 aFormula
.append(sSep
);
4309 aFormula
.append(aQuote
);
4310 aFormula
.append(aTopic
);
4311 aFormula
.append(aQuote
);
4312 aFormula
.append(sSep
);
4313 aFormula
.append(aQuote
);
4314 aFormula
.append(aItem
);
4315 aFormula
.append(aQuote
);
4316 aFormula
.append(ScCompiler::GetNativeSymbol(ocClose
));
4318 pView
->DoneBlockMode();
4319 pView
->InitBlockMode( nDestPosX
, nDestPosY
, nThisTab
);
4320 pView
->MarkCursor( nDestPosX
+ nSizeX
- 1,
4321 nDestPosY
+ nSizeY
- 1, nThisTab
);
4323 pView
->EnterMatrix( aFormula
.makeStringAndClear(), ::formula::FormulaGrammar::GRAM_NATIVE
);
4325 pView
->MarkRange( aDest
, false, false );
4326 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4329 pDocSh
->GetUndoManager()->LeaveListAction();
4334 //! HasSelectedBlockMatrixFragment without selected sheet?
4335 //! or don't start dragging on a part of a matrix
4337 OUString aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4338 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4341 if ( meDragInsertMode
!= INS_NONE
)
4343 // call with bApi = sal_True to avoid error messages in drop handler
4344 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, true /*bRecord*/, true /*bApi*/, true /*bPartOfPaste*/ );
4347 pDocSh
->UpdateOle( pViewData
);
4348 pView
->CellContentChanged();
4354 pView
->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4355 pView
->SetCursor( nDestPosX
, nDestPosY
);
4356 bDone
= pView
->PasteFromClip( IDF_ALL
, pTransObj
->GetDocument() ); // clip-doc
4359 pView
->MarkRange( aDest
, false, false );
4360 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4364 pDocSh
->GetUndoManager()->LeaveListAction();
4366 // no longer call ResetMark here - the inserted block has been selected
4367 // and may have been copied to primary selection
4371 sal_Int8 nRet
= bDone
? nDndAction
: DND_ACTION_NONE
;
4375 sal_Int8
ScGridWindow::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
4377 DrawMarkDropObj( NULL
); // drawing layer
4379 ScModule
* pScMod
= SC_MOD();
4380 const ScDragData
& rData
= pScMod
->GetDragData();
4381 if (rData
.pCellTransfer
)
4382 return ExecutePrivateDrop( rEvt
);
4384 Point aPos
= rEvt
.maPosPixel
;
4386 if ( !rData
.aLinkDoc
.isEmpty() )
4388 // try to insert a link
4392 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4393 if (pDocSh
&& pDocSh
->HasName())
4394 aThisName
= pDocSh
->GetMedium()->GetName();
4396 if ( rData
.aLinkDoc
.equals(aThisName
) ) // error - no link within a document
4400 ScViewFunc
* pView
= pViewData
->GetView();
4401 if ( !rData
.aLinkTable
.isEmpty() )
4402 pView
->InsertTableLink( rData
.aLinkDoc
, EMPTY_OUSTRING
, EMPTY_OUSTRING
,
4404 else if ( !rData
.aLinkArea
.isEmpty() )
4408 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4409 pView
->MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, false, false );
4411 pView
->InsertAreaLink( rData
.aLinkDoc
, EMPTY_OUSTRING
, EMPTY_OUSTRING
,
4412 rData
.aLinkArea
, 0 );
4416 OSL_FAIL("drop with link: no sheet nor area");
4421 return bOk
? rEvt
.mnAction
: DND_ACTION_NONE
; // don't try anything else
4424 Point aLogicPos
= PixelToLogic(aPos
);
4425 bool bIsLink
= ( rEvt
.mnAction
== DND_ACTION_LINK
);
4427 if (!bIsLink
&& rData
.pDrawTransfer
)
4429 sal_uInt16 nFlags
= rData
.pDrawTransfer
->GetDragSourceFlags();
4431 bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4432 bool bIsMove
= ( rEvt
.mnAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4434 bPasteIsMove
= bIsMove
;
4436 pViewData
->GetView()->PasteDraw(
4437 aLogicPos
, rData
.pDrawTransfer
->GetModel(), false, "A", "B");
4440 rData
.pDrawTransfer
->SetDragWasInternal();
4441 bPasteIsMove
= false;
4443 return rEvt
.mnAction
;
4449 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4451 if (!rData
.aJumpTarget
.isEmpty())
4453 // internal bookmark (from Navigator)
4454 // bookmark clipboard formats are in PasteScDataObject
4456 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
4458 pViewData
->GetViewShell()->InsertBookmark( rData
.aJumpText
, rData
.aJumpTarget
,
4460 return rEvt
.mnAction
;
4464 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4465 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint( pViewData
->GetTabNo(), PixelToLogic(aPos
) );
4466 if ( pHitObj
&& bIsLink
)
4468 // dropped on drawing object
4469 // PasteOnDrawObjectLinked checks for valid formats
4470 if ( pViewData
->GetView()->PasteOnDrawObjectLinked( rEvt
.maDropEvent
.Transferable
, *pHitObj
) )
4471 return rEvt
.mnAction
;
4476 sal_uLong nFormatId
= bIsLink
?
4477 lcl_GetDropLinkId( rEvt
.maDropEvent
.Transferable
) :
4478 lcl_GetDropFormatId( rEvt
.maDropEvent
.Transferable
);
4481 pScMod
->SetInExecuteDrop( true ); // #i28468# prevent error messages from PasteDataFormat
4482 bPasteIsDrop
= true;
4483 bDone
= pViewData
->GetView()->PasteDataFormat(
4484 nFormatId
, rEvt
.maDropEvent
.Transferable
, nPosX
, nPosY
, &aLogicPos
, bIsLink
);
4485 bPasteIsDrop
= false;
4486 pScMod
->SetInExecuteDrop( false );
4489 sal_Int8 nRet
= bDone
? rEvt
.mnAction
: DND_ACTION_NONE
;
4493 void ScGridWindow::PasteSelection( const Point
& rPosPixel
)
4495 Point aLogicPos
= PixelToLogic( rPosPixel
);
4499 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
4501 // If the mouse down was inside a visible note window, ignore it and
4502 // leave it up to the ScPostIt to handle it
4503 SdrView
* pDrawView
= pViewData
->GetViewShell()->GetSdrView();
4506 sal_uLong nCount
= pDrawView
->GetMarkedObjectCount();
4507 for (sal_uLong i
= 0; i
< nCount
; ++i
)
4509 SdrObject
* pObj
= pDrawView
->GetMarkedObjectByIndex(i
);
4510 if (pObj
&& pObj
->GetLogicRect().IsInside(aLogicPos
))
4512 // Inside an active drawing object. Bail out.
4518 ScSelectionTransferObj
* pOwnSelection
= SC_MOD()->GetSelectionTransfer();
4519 if ( pOwnSelection
)
4523 ScTransferObj
* pCellTransfer
= pOwnSelection
->GetCellData();
4524 if ( pCellTransfer
)
4526 // keep a reference to the data in case the selection is changed during paste
4527 uno::Reference
<datatransfer::XTransferable
> xRef( pCellTransfer
);
4528 DropTransferObj( pCellTransfer
, nPosX
, nPosY
, aLogicPos
, DND_ACTION_COPY
);
4532 ScDrawTransferObj
* pDrawTransfer
= pOwnSelection
->GetDrawData();
4533 if ( pDrawTransfer
)
4535 // keep a reference to the data in case the selection is changed during paste
4536 uno::Reference
<datatransfer::XTransferable
> xRef( pDrawTransfer
);
4538 // bSameDocClipboard argument for PasteDraw is needed
4539 // because only DragData is checked directly inside PasteDraw
4540 pViewData
->GetView()->PasteDraw(
4541 aLogicPos
, pDrawTransfer
->GetModel(), false,
4542 pDrawTransfer
->GetShellID(), SfxObjectShell::CreateShellID(pViewData
->GetDocShell()));
4548 // get selection from system
4550 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4551 uno::Reference
<datatransfer::XTransferable
> xTransferable
= aDataHelper
.GetTransferable();
4552 if ( xTransferable
.is() )
4554 sal_uLong nFormatId
= lcl_GetDropFormatId( xTransferable
, true );
4557 bPasteIsDrop
= true;
4558 pViewData
->GetView()->PasteDataFormat( nFormatId
, xTransferable
, nPosX
, nPosY
, &aLogicPos
);
4559 bPasteIsDrop
= false;
4565 void ScGridWindow::UpdateEditViewPos()
4567 if (pViewData
->HasEditView(eWhich
))
4572 pViewData
->GetEditView( eWhich
, pView
, nCol
, nRow
);
4573 SCCOL nEndCol
= pViewData
->GetEditEndCol();
4574 SCROW nEndRow
= pViewData
->GetEditEndRow();
4578 bool bHide
= ( nEndCol
<pViewData
->GetPosX(eHWhich
) || nEndRow
<pViewData
->GetPosY(eVWhich
) );
4579 if ( SC_MOD()->IsFormulaMode() )
4580 if ( pViewData
->GetTabNo() != pViewData
->GetRefTabNo() )
4585 Rectangle aRect
= pView
->GetOutputArea();
4586 long nHeight
= aRect
.Bottom() - aRect
.Top();
4587 aRect
.Top() = PixelToLogic(GetOutputSizePixel(), pViewData
->GetLogicMode()).
4589 aRect
.Bottom() = aRect
.Top() + nHeight
;
4590 pView
->SetOutputArea( aRect
);
4591 pView
->HideCursor();
4595 // bForceToTop = sal_True for editing
4596 Rectangle aPixRect
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, this, NULL
, true );
4597 Point aScrPos
= PixelToLogic( aPixRect
.TopLeft(), pViewData
->GetLogicMode() );
4599 Rectangle aRect
= pView
->GetOutputArea();
4600 aRect
.SetPos( aScrPos
);
4601 pView
->SetOutputArea( aRect
);
4602 pView
->ShowCursor();
4607 void ScGridWindow::ScrollPixel( long nDifX
, long nDifY
)
4614 SetMapMode(MAP_PIXEL
);
4615 Scroll( nDifX
, nDifY
, SCROLL_CHILDREN
);
4616 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4618 UpdateEditViewPos();
4621 bIsInScroll
= false;
4624 // Formeln neu zeichnen -------------------------------------------------
4626 void ScGridWindow::UpdateFormulas()
4628 if (pViewData
->GetView()->IsMinimized())
4633 // nicht anfangen, verschachtelt zu painten
4634 // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4636 bNeedsRepaint
= true; // -> am Ende vom Paint nochmal Invalidate auf alles
4637 aRepaintPixel
= Rectangle(); // alles
4641 SCCOL nX1
= pViewData
->GetPosX( eHWhich
);
4642 SCROW nY1
= pViewData
->GetPosY( eVWhich
);
4643 SCCOL nX2
= nX1
+ pViewData
->VisibleCellsX( eHWhich
);
4644 SCROW nY2
= nY1
+ pViewData
->VisibleCellsY( eVWhich
);
4646 if (nX2
> MAXCOL
) nX2
= MAXCOL
;
4647 if (nY2
> MAXROW
) nY2
= MAXROW
;
4649 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4651 // don't draw directly - instead use OutputData to find changed area and invalidate
4655 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4656 ScDocument
* pDoc
= pDocSh
->GetDocument();
4657 SCTAB nTab
= pViewData
->GetTabNo();
4659 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
4661 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
4662 long nMirrorWidth
= GetSizePixel().Width();
4663 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4666 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
4667 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
4668 aScrPos
.X() = nEndPixel
+ 1;
4671 long nScrX
= aScrPos
.X();
4672 long nScrY
= aScrPos
.Y();
4674 double nPPTX
= pViewData
->GetPPTX();
4675 double nPPTY
= pViewData
->GetPPTY();
4677 ScTableInfo aTabInfo
;
4678 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
, nPPTX
, nPPTY
, false, false );
4680 Fraction aZoomX
= pViewData
->GetZoomX();
4681 Fraction aZoomY
= pViewData
->GetZoomY();
4682 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
4683 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
4685 aOutputData
.SetMirrorWidth( nMirrorWidth
);
4687 aOutputData
.FindChanged();
4689 // #i122149# do not use old GetChangedArea() which used polygon-based Regions, but use
4690 // the region-band based new version; anyways, only rectangles are added
4691 Region
aChangedRegion( aOutputData
.GetChangedAreaRegion() ); // logic (PixelToLogic)
4692 if(!aChangedRegion
.IsEmpty())
4694 Invalidate(aChangedRegion
);
4697 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4700 void ScGridWindow::UpdateAutoFillMark(bool bMarked
, const ScRange
& rMarkRange
)
4702 if ( bMarked
!= bAutoMarkVisible
|| ( bMarked
&& rMarkRange
.aEnd
!= aAutoMarkPos
) )
4704 bAutoMarkVisible
= bMarked
;
4706 aAutoMarkPos
= rMarkRange
.aEnd
;
4708 UpdateAutoFillOverlay();
4712 void ScGridWindow::UpdateListValPos( bool bVisible
, const ScAddress
& rPos
)
4714 bool bOldButton
= bListValButton
;
4715 ScAddress aOldPos
= aListValPos
;
4717 bListValButton
= bVisible
;
4720 if ( bListValButton
)
4722 if ( !bOldButton
|| aListValPos
!= aOldPos
)
4724 // paint area of new button
4725 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos
) ) );
4730 if ( !bListValButton
|| aListValPos
!= aOldPos
)
4732 // paint area of old button
4733 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos
) ) );
4738 void ScGridWindow::HideCursor()
4743 void ScGridWindow::ShowCursor()
4748 void ScGridWindow::GetFocus()
4750 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4751 pViewShell
->GotFocus();
4752 pViewShell
->SetFormShellAtTop( false ); // focus in GridWindow -> FormShell no longer on top
4754 if (pViewShell
->HasAccessibilityObjects())
4755 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich
, GetAccessible()));
4758 if ( !SC_MOD()->IsFormulaMode() )
4760 pViewShell
->UpdateInputHandler();
4761 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4762 // MO: nur wenn nicht im RefInput-Modus
4763 // -> GetFocus/MouseButtonDown-Reihenfolge
4767 pViewData
->GetDocShell()->CheckConfigOptions();
4771 void ScGridWindow::LoseFocus()
4773 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4774 pViewShell
->LostFocus();
4776 if (pViewShell
->HasAccessibilityObjects())
4777 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich
, GetAccessible()));
4779 Window::LoseFocus();
4782 Point
ScGridWindow::GetMousePosPixel() const { return aCurMousePos
; }
4784 bool ScGridWindow::HitRangeFinder( const Point
& rMouse
, RfCorner
& rCorner
,
4785 sal_uInt16
* pIndex
, SCsCOL
* pAddX
, SCsROW
* pAddY
)
4787 bool bFound
= false;
4788 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4791 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4792 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
4793 pRangeFinder
->GetDocName() == pViewData
->GetDocShell()->GetTitle() )
4795 ScDocument
* pDoc
= pViewData
->GetDocument();
4796 SCTAB nTab
= pViewData
->GetTabNo();
4797 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4798 long nLayoutSign
= bLayoutRTL
? -1 : 1;
4802 pViewData
->GetPosFromPixel( rMouse
.X(), rMouse
.Y(), eWhich
, nPosX
, nPosY
);
4803 // zusammengefasste (einzeln/Bereich) ???
4804 ScAddress
aAddr( nPosX
, nPosY
, nTab
);
4806 Point aCellStart
= pViewData
->GetScrPos( nPosX
, nPosY
, eWhich
, true );
4807 Point aCellEnd
= aCellStart
;
4810 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeXPix
, nSizeYPix
);
4812 aCellEnd
.X() += nSizeXPix
* nLayoutSign
;
4813 aCellEnd
.Y() += nSizeYPix
;
4815 bool bCornerHorizontalRight
;
4816 bool bCornerHorizontalLeft
;
4819 bCornerHorizontalRight
= ( rMouse
.X() >= aCellEnd
.X() && rMouse
.X() <= aCellEnd
.X() + 8 );
4820 bCornerHorizontalLeft
= ( rMouse
.X() >= aCellStart
.X() - 8 && rMouse
.X() <= aCellStart
.X() );
4824 bCornerHorizontalRight
= ( rMouse
.X() >= aCellEnd
.X() - 8 && rMouse
.X() <= aCellEnd
.X() );
4825 bCornerHorizontalLeft
= ( rMouse
.X() >= aCellStart
.X() && rMouse
.X() <= aCellStart
.X() + 8 );
4828 bool bCornerVerticalDown
= rMouse
.Y() >= aCellEnd
.Y() - 8 && rMouse
.Y() <= aCellEnd
.Y();
4829 bool bCornerVerticalUp
= rMouse
.Y() >= aCellStart
.Y() && rMouse
.Y() <= aCellStart
.Y() + 8;
4831 // corner is hit only if the mouse is within the cell
4832 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
4833 for (sal_uInt16 i
=nCount
; i
;)
4835 // search backwards so that the last repainted frame is found
4837 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
4838 if ( pData
->aRef
.In(aAddr
) )
4843 *pAddX
= nPosX
- pData
->aRef
.aStart
.Col();
4845 *pAddY
= nPosY
- pData
->aRef
.aStart
.Row();
4851 ScAddress aEnd
= pData
->aRef
.aEnd
;
4852 ScAddress aStart
= pData
->aRef
.aStart
;
4854 if ( bCornerHorizontalLeft
&& bCornerVerticalUp
&&
4859 else if (bCornerHorizontalRight
&& bCornerVerticalDown
&&
4862 rCorner
= RIGHT_DOWN
;
4864 else if (bCornerHorizontalRight
&& bCornerVerticalUp
&&
4865 aAddr
== ScAddress(aEnd
.Col(), aStart
.Row(), aStart
.Tab()))
4869 else if (bCornerHorizontalLeft
&& bCornerVerticalDown
&&
4870 aAddr
== ScAddress(aStart
.Col(), aEnd
.Row(), aStart
.Tab()))
4872 rCorner
= LEFT_DOWN
;
4883 #define SCE_BOTTOM 2
4888 static void lcl_PaintOneRange( ScDocShell
* pDocSh
, const ScRange
& rRange
, sal_uInt16 nEdges
)
4890 // der Range ist immer richtigherum
4892 SCCOL nCol1
= rRange
.aStart
.Col();
4893 SCROW nRow1
= rRange
.aStart
.Row();
4894 SCTAB nTab1
= rRange
.aStart
.Tab();
4895 SCCOL nCol2
= rRange
.aEnd
.Col();
4896 SCROW nRow2
= rRange
.aEnd
.Row();
4897 SCTAB nTab2
= rRange
.aEnd
.Tab();
4898 bool bHiddenEdge
= false;
4901 ScDocument
* pDoc
= pDocSh
->GetDocument();
4902 while ( nCol1
> 0 && pDoc
->ColHidden(nCol1
, nTab1
) )
4907 while ( nCol2
< MAXCOL
&& pDoc
->ColHidden(nCol2
, nTab1
) )
4912 nTmp
= pDoc
->FirstVisibleRow(0, nRow1
, nTab1
);
4913 if (!ValidRow(nTmp
))
4920 nTmp
= pDoc
->FirstVisibleRow(nRow2
, MAXROW
, nTab1
);
4921 if (!ValidRow(nTmp
))
4929 if ( nCol2
> nCol1
+ 1 && nRow2
> nRow1
+ 1 && !bHiddenEdge
)
4931 // nur an den Raendern entlang
4932 // (die Ecken werden evtl. zweimal getroffen)
4934 if ( nEdges
& SCE_TOP
)
4935 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow1
, nTab2
, PAINT_MARKS
);
4936 if ( nEdges
& SCE_LEFT
)
4937 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol1
, nRow2
, nTab2
, PAINT_MARKS
);
4938 if ( nEdges
& SCE_RIGHT
)
4939 pDocSh
->PostPaint( nCol2
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4940 if ( nEdges
& SCE_BOTTOM
)
4941 pDocSh
->PostPaint( nCol1
, nRow2
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4943 else // everything in one call
4944 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4947 static void lcl_PaintRefChanged( ScDocShell
* pDocSh
, const ScRange
& rOldUn
, const ScRange
& rNewUn
)
4949 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4951 ScRange aOld
= rOldUn
;
4952 ScRange aNew
= rNewUn
;
4956 if ( aOld
.aStart
== aOld
.aEnd
) //! Tab ignorieren?
4957 pDocSh
->GetDocument()->ExtendMerge(aOld
);
4958 if ( aNew
.aStart
== aNew
.aEnd
) //! Tab ignorieren?
4959 pDocSh
->GetDocument()->ExtendMerge(aNew
);
4961 SCCOL nOldCol1
= aOld
.aStart
.Col();
4962 SCROW nOldRow1
= aOld
.aStart
.Row();
4963 SCCOL nOldCol2
= aOld
.aEnd
.Col();
4964 SCROW nOldRow2
= aOld
.aEnd
.Row();
4965 SCCOL nNewCol1
= aNew
.aStart
.Col();
4966 SCROW nNewRow1
= aNew
.aStart
.Row();
4967 SCCOL nNewCol2
= aNew
.aEnd
.Col();
4968 SCROW nNewRow2
= aNew
.aEnd
.Row();
4969 SCTAB nTab1
= aOld
.aStart
.Tab(); // Tab aendert sich nicht
4970 SCTAB nTab2
= aOld
.aEnd
.Tab();
4972 if ( nNewRow2
< nOldRow1
|| nNewRow1
> nOldRow2
||
4973 nNewCol2
< nOldCol1
|| nNewCol1
> nOldCol2
||
4974 ( nNewCol1
!= nOldCol1
&& nNewRow1
!= nOldRow1
&&
4975 nNewCol2
!= nOldCol2
&& nNewRow2
!= nOldRow2
) )
4977 // komplett weggeschoben oder alle Seiten veraendert
4978 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4980 lcl_PaintOneRange( pDocSh
, aOld
, SCE_ALL
);
4982 else // alle vier Kanten einzeln testen
4985 if ( nNewRow1
< nOldRow1
) // nur obere Linie loeschen
4986 lcl_PaintOneRange( pDocSh
, ScRange(
4987 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nOldRow1
, nTab2
), SCE_ALL
);
4988 else if ( nNewRow1
> nOldRow1
) // den Teil, der oben wegkommt
4989 lcl_PaintOneRange( pDocSh
, ScRange(
4990 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nNewRow1
-1, nTab2
),
4991 SCE_ALL
&~ SCE_BOTTOM
);
4994 if ( nNewRow2
> nOldRow2
) // nur untere Linie loeschen
4995 lcl_PaintOneRange( pDocSh
, ScRange(
4996 nOldCol1
, nOldRow2
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4997 else if ( nNewRow2
< nOldRow2
) // den Teil, der unten wegkommt
4998 lcl_PaintOneRange( pDocSh
, ScRange(
4999 nOldCol1
, nNewRow2
+1, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
5000 SCE_ALL
&~ SCE_TOP
);
5003 if ( nNewCol1
< nOldCol1
) // nur linke Linie loeschen
5004 lcl_PaintOneRange( pDocSh
, ScRange(
5005 nOldCol1
, nOldRow1
, nTab1
, nOldCol1
, nOldRow2
, nTab2
), SCE_ALL
);
5006 else if ( nNewCol1
> nOldCol1
) // den Teil, der links wegkommt
5007 lcl_PaintOneRange( pDocSh
, ScRange(
5008 nOldCol1
, nOldRow1
, nTab1
, nNewCol1
-1, nOldRow2
, nTab2
),
5009 SCE_ALL
&~ SCE_RIGHT
);
5012 if ( nNewCol2
> nOldCol2
) // nur rechte Linie loeschen
5013 lcl_PaintOneRange( pDocSh
, ScRange(
5014 nOldCol2
, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
5015 else if ( nNewCol2
< nOldCol2
) // den Teil, der rechts wegkommt
5016 lcl_PaintOneRange( pDocSh
, ScRange(
5017 nNewCol2
+1, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
5018 SCE_ALL
&~ SCE_LEFT
);
5022 void ScGridWindow::RFMouseMove( const MouseEvent
& rMEvt
, bool bUp
)
5024 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
5027 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
5028 if (!pRangeFinder
|| nRFIndex
>= pRangeFinder
->Count())
5030 ScRangeFindData
* pData
= pRangeFinder
->GetObject( nRFIndex
);
5035 SetPointer( Pointer( POINTER_CROSS
) );
5037 SetPointer( Pointer( POINTER_HAND
) );
5041 bool bTimer
= false;
5042 Point aPos
= rMEvt
.GetPosPixel();
5045 if ( aPos
.X() < 0 ) nDx
= -1;
5046 if ( aPos
.Y() < 0 ) nDy
= -1;
5047 Size aSize
= GetOutputSizePixel();
5048 if ( aPos
.X() >= aSize
.Width() )
5050 if ( aPos
.Y() >= aSize
.Height() )
5052 if ( nDx
!= 0 || nDy
!= 0 )
5054 if ( nDx
!= 0) pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
5055 if ( nDy
!= 0 ) pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
5059 // Umschalten bei Fixierung (damit Scrolling funktioniert)
5061 if ( eWhich
== pViewData
->GetActivePart() ) //??
5063 if ( pViewData
->GetHSplitMode() == SC_SPLIT_FIX
)
5066 if ( eWhich
== SC_SPLIT_TOPLEFT
)
5067 pViewData
->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT
);
5068 else if ( eWhich
== SC_SPLIT_BOTTOMLEFT
)
5069 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
5072 if ( pViewData
->GetVSplitMode() == SC_SPLIT_FIX
)
5075 if ( eWhich
== SC_SPLIT_TOPLEFT
)
5076 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT
);
5077 else if ( eWhich
== SC_SPLIT_TOPRIGHT
)
5078 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
5086 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
5088 ScRange aOld
= pData
->aRef
;
5089 ScRange aNew
= aOld
;
5092 switch (aRFSelectedCorned
)
5095 aNew
.aStart
.SetCol((SCCOL
)nPosX
);
5096 aNew
.aStart
.SetRow((SCROW
)nPosY
);
5099 aNew
.aStart
.SetCol((SCCOL
)nPosX
);
5100 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
5103 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
5104 aNew
.aStart
.SetRow((SCROW
)nPosY
);
5107 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
5108 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
5116 long nStartX
= nPosX
- nRFAddX
;
5117 if ( nStartX
< 0 ) nStartX
= 0;
5118 long nStartY
= nPosY
- nRFAddY
;
5119 if ( nStartY
< 0 ) nStartY
= 0;
5120 long nEndX
= nStartX
+ aOld
.aEnd
.Col() - aOld
.aStart
.Col();
5121 if ( nEndX
> MAXCOL
)
5123 nStartX
-= ( nEndX
- MAXROW
);
5126 long nEndY
= nStartY
+ aOld
.aEnd
.Row() - aOld
.aStart
.Row();
5127 if ( nEndY
> MAXROW
)
5129 nStartY
-= ( nEndY
- MAXROW
);
5133 aNew
.aStart
.SetCol((SCCOL
)nStartX
);
5134 aNew
.aStart
.SetRow((SCROW
)nStartY
);
5135 aNew
.aEnd
.SetCol((SCCOL
)nEndX
);
5136 aNew
.aEnd
.SetRow((SCROW
)nEndY
);
5140 aNew
.Justify(); // beim ButtonUp wieder richtigherum
5144 pHdl
->UpdateRange( nRFIndex
, aNew
);
5146 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5148 // nur das neuzeichnen, was sich veraendert hat...
5149 lcl_PaintRefChanged( pDocSh
, aOld
, aNew
);
5151 // neuen Rahmen nur drueberzeichnen (synchron)
5152 pDocSh
->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER
, nRFIndex
) );
5154 Update(); // was man bewegt, will man auch sofort sehen
5157 // Timer fuer Scrolling
5160 pViewData
->GetView()->SetTimer( this, rMEvt
); // Event wiederholen
5162 pViewData
->GetView()->ResetTimer();
5167 SvxAdjust
toSvxAdjust( const ScPatternAttr
& rPat
)
5169 SvxCellHorJustify eHorJust
=
5170 static_cast<SvxCellHorJustify
>(
5171 static_cast<const SvxHorJustifyItem
&>(rPat
.GetItem(ATTR_HOR_JUSTIFY
)).GetValue());
5173 SvxAdjust eSvxAdjust
= SVX_ADJUST_LEFT
;
5176 case SVX_HOR_JUSTIFY_LEFT
:
5177 case SVX_HOR_JUSTIFY_REPEAT
: // nicht implementiert
5178 case SVX_HOR_JUSTIFY_STANDARD
: // always Text if an EditCell type
5179 eSvxAdjust
= SVX_ADJUST_LEFT
;
5181 case SVX_HOR_JUSTIFY_RIGHT
:
5182 eSvxAdjust
= SVX_ADJUST_RIGHT
;
5184 case SVX_HOR_JUSTIFY_CENTER
:
5185 eSvxAdjust
= SVX_ADJUST_CENTER
;
5187 case SVX_HOR_JUSTIFY_BLOCK
:
5188 eSvxAdjust
= SVX_ADJUST_BLOCK
;
5195 boost::shared_ptr
<ScFieldEditEngine
> createEditEngine( ScDocShell
* pDocSh
, const ScPatternAttr
& rPat
)
5197 ScDocument
* pDoc
= pDocSh
->GetDocument();
5199 boost::shared_ptr
<ScFieldEditEngine
> pEngine(new ScFieldEditEngine(pDoc
, pDoc
->GetEditPool()));
5200 ScSizeDeviceProvider
aProv(pDocSh
);
5201 pEngine
->SetRefDevice(aProv
.GetDevice());
5202 pEngine
->SetRefMapMode(MAP_100TH_MM
);
5203 SfxItemSet aDefault
= pEngine
->GetEmptyItemSet();
5204 rPat
.FillEditItemSet(&aDefault
);
5205 aDefault
.Put( SvxAdjustItem(toSvxAdjust(rPat
), EE_PARA_JUST
) );
5206 pEngine
->SetDefaults(aDefault
);
5211 bool extractURLInfo( const SvxFieldItem
* pFieldItem
, OUString
* pName
, OUString
* pUrl
, OUString
* pTarget
)
5216 const SvxFieldData
* pField
= pFieldItem
->GetField();
5217 if (pField
->GetClassId() != text::textfield::Type::URL
)
5220 const SvxURLField
* pURLField
= static_cast<const SvxURLField
*>(pField
);
5223 *pName
= pURLField
->GetRepresentation();
5225 *pUrl
= pURLField
->GetURL();
5227 *pTarget
= pURLField
->GetTargetFrame();
5234 bool ScGridWindow::GetEditUrl( const Point
& rPos
,
5235 OUString
* pName
, OUString
* pUrl
, OUString
* pTarget
)
5237 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
5238 ScInputHandler
* pInputHdl
= NULL
;
5240 pInputHdl
= pViewSh
->GetInputHandler();
5241 EditView
* pView
= (pInputHdl
&& pInputHdl
->IsInputMode()) ? pInputHdl
->GetTableView() : NULL
;
5243 return extractURLInfo(pView
->GetFieldUnderMousePointer(), pName
, pUrl
, pTarget
);
5245 //! nPosX/Y mit uebergeben?
5248 pViewData
->GetPosFromPixel( rPos
.X(), rPos
.Y(), eWhich
, nPosX
, nPosY
);
5250 SCTAB nTab
= pViewData
->GetTabNo();
5251 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5252 ScDocument
* pDoc
= pDocSh
->GetDocument();
5254 ScRefCellValue aCell
;
5255 bool bFound
= lcl_GetHyperlinkCell(pDoc
, nPosX
, nPosY
, nTab
, aCell
, sURL
);
5259 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
5260 // bForceToTop = sal_False, use the cell's real position
5261 Rectangle aEditRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, false );
5262 if (rPos
.Y() < aEditRect
.Top())
5265 // vertikal kann (noch) nicht angeklickt werden:
5267 if (pPattern
->GetCellOrientation() != SVX_ORIENTATION_STANDARD
)
5270 bool bBreak
= ((SfxBoolItem
&)pPattern
->GetItem(ATTR_LINEBREAK
)).GetValue() ||
5271 ((SvxCellHorJustify
)((const SvxHorJustifyItem
&)pPattern
->
5272 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
);
5273 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)((SvxHorJustifyItem
&)pPattern
->
5274 GetItem(ATTR_HOR_JUSTIFY
)).GetValue();
5278 boost::shared_ptr
<ScFieldEditEngine
> pEngine
= createEditEngine(pDocSh
, *pPattern
);
5280 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
); // ohne Drawing-Skalierung
5281 Rectangle aLogicEdit
= PixelToLogic( aEditRect
, aEditMode
);
5282 long nThisColLogic
= aLogicEdit
.Right() - aLogicEdit
.Left() + 1;
5283 Size aPaperSize
= Size( 1000000, 1000000 );
5284 if (aCell
.meType
== CELLTYPE_FORMULA
)
5288 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
5289 aPaperSize
= Size(nSizeX
, nSizeY
);
5290 aPaperSize
= PixelToLogic(aPaperSize
);
5294 aPaperSize
.Width() = nThisColLogic
;
5295 pEngine
->SetPaperSize( aPaperSize
);
5297 boost::scoped_ptr
<EditTextObject
> pTextObj
;
5298 if (aCell
.meType
== CELLTYPE_EDIT
)
5300 if (aCell
.mpEditText
)
5301 pEngine
->SetText(*aCell
.mpEditText
);
5303 else // Not an Edit cell and is a formula cell with 'Hyperlink'
5304 // function if we have no URL, otherwise it could be a formula
5305 // cell ( or other type ? ) with a hyperlink associated with it.
5308 pTextObj
.reset(aCell
.mpFormula
->CreateURLObject());
5310 pTextObj
.reset(ScEditUtil::CreateURLObjectFromURL(*pDoc
, sURL
, sURL
));
5313 pEngine
->SetText(*pTextObj
);
5316 long nStartX
= aLogicEdit
.Left();
5318 long nTextWidth
= pEngine
->CalcTextWidth();
5319 long nTextHeight
= pEngine
->GetTextHeight();
5320 if ( nTextWidth
< nThisColLogic
)
5322 if (eHorJust
== SVX_HOR_JUSTIFY_RIGHT
)
5323 nStartX
+= nThisColLogic
- nTextWidth
;
5324 else if (eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
5325 nStartX
+= (nThisColLogic
- nTextWidth
) / 2;
5328 aLogicEdit
.Left() = nStartX
;
5330 aLogicEdit
.Right() = nStartX
+ nTextWidth
;
5332 // There is one glitch when dealing with a hyperlink cell and
5333 // the cell content is NUMERIC. This defaults to right aligned and
5334 // we need to adjust accordingly.
5335 if (aCell
.meType
== CELLTYPE_FORMULA
&& aCell
.mpFormula
->IsValue() &&
5336 eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
5338 aLogicEdit
.Right() = aLogicEdit
.Left() + nThisColLogic
- 1;
5339 aLogicEdit
.Left() = aLogicEdit
.Right() - nTextWidth
;
5341 aLogicEdit
.Bottom() = aLogicEdit
.Top() + nTextHeight
;
5344 Point aLogicClick
= PixelToLogic(rPos
,aEditMode
);
5345 if ( aLogicEdit
.IsInside(aLogicClick
) )
5347 EditView
aTempView(pEngine
.get(), this);
5348 aTempView
.SetOutputArea( aLogicEdit
);
5351 MapMode aOld
= GetMapMode();
5352 SetMapMode(aEditMode
); // kein return mehr
5353 bRet
= extractURLInfo(aTempView
.GetFieldUnderMousePointer(), pName
, pUrl
, pTarget
);
5361 bool ScGridWindow::IsSpellErrorAtPos( const Point
& rPos
, SCCOL nCol1
, SCCOL nCol2
, SCROW nRow
)
5363 if (!mpSpellCheckCxt
)
5366 SCTAB nTab
= pViewData
->GetTabNo();
5367 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5368 ScDocument
* pDoc
= pDocSh
->GetDocument();
5370 ScAddress
aCellPos(nCol1
, nRow
, nTab
);
5371 ScRefCellValue aCell
;
5372 aCell
.assign(*pDoc
, aCellPos
);
5373 if (aCell
.meType
!= CELLTYPE_STRING
&& aCell
.meType
!= CELLTYPE_EDIT
)
5376 const std::vector
<editeng::MisspellRanges
>* pRanges
= mpSpellCheckCxt
->getMisspellRanges(nCol1
, nRow
);
5380 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nCol1
, nRow
, nTab
);
5382 Rectangle aEditRect
= pViewData
->GetEditArea(eWhich
, nCol1
, nRow
, this, pPattern
, false);
5383 if (rPos
.Y() < aEditRect
.Top())
5386 Rectangle aEditRect2
= pViewData
->GetEditArea(eWhich
, nCol2
, nRow
, this, pPattern
, false);
5387 long nExt
= aEditRect2
.Left() - aEditRect
.Right() + aEditRect2
.GetWidth();
5388 aEditRect
.setWidth(aEditRect
.getWidth() + nExt
);
5390 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
);
5391 Rectangle aLogicEdit
= PixelToLogic(aEditRect
, aEditMode
);
5392 Point aLogicClick
= PixelToLogic(rPos
, aEditMode
);
5394 if (!aLogicEdit
.IsInside(aLogicClick
))
5397 boost::shared_ptr
<ScFieldEditEngine
> pEngine
= createEditEngine(pDocSh
, *pPattern
);
5399 Size aPaperSize
= Size(1000000, 1000000);
5400 pEngine
->SetPaperSize(aPaperSize
);
5402 if (aCell
.meType
== CELLTYPE_EDIT
)
5403 pEngine
->SetText(*aCell
.mpEditText
);
5405 pEngine
->SetText(aCell
.mpString
->getString());
5407 pEngine
->SetControlWord(pEngine
->GetControlWord() | EE_CNTRL_ONLINESPELLING
);
5408 pEngine
->SetAllMisspellRanges(*pRanges
);
5410 EditView
aTempView(pEngine
.get(), this);
5411 aTempView
.SetOutputArea(aLogicEdit
);
5413 return aTempView
.IsWrongSpelledWordAtPos(rPos
);
5416 bool ScGridWindow::HasScenarioButton( const Point
& rPosPixel
, ScRange
& rScenRange
)
5418 ScDocument
* pDoc
= pViewData
->GetDocument();
5419 SCTAB nTab
= pViewData
->GetTabNo();
5420 SCTAB nTabCount
= pDoc
->GetTableCount();
5421 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
5423 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5425 Size aButSize
= pViewData
->GetScenButSize();
5426 long nBWidth
= aButSize
.Width();
5428 return false; // noch kein Button gezeichnet -> da ist auch keiner
5429 long nBHeight
= aButSize
.Height();
5430 long nHSpace
= (long)( SC_SCENARIO_HSPACE
* pViewData
->GetPPTX() );
5432 //! Ranges an der Table cachen!!!!
5435 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
5436 pDoc
->MarkScenario( i
, nTab
, aMarks
, false, SC_SCENARIO_SHOWFRAME
);
5437 ScRangeList aRanges
;
5438 aMarks
.FillRangeListWithMarks( &aRanges
, false );
5441 size_t nRangeCount
= aRanges
.size();
5442 for (size_t j
=0; j
< nRangeCount
; ++j
)
5444 ScRange aRange
= *aRanges
[j
];
5445 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5446 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5447 pDoc
->ExtendTotalMerge( aRange
);
5449 bool bTextBelow
= ( aRange
.aStart
.Row() == 0 );
5454 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1,
5459 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aStart
.Row(),
5461 aButtonPos
.Y() -= nBHeight
;
5464 aButtonPos
.X() -= nHSpace
- 1;
5466 aButtonPos
.X() -= nBWidth
- nHSpace
; // same for top or bottom
5468 Rectangle
aButRect( aButtonPos
, Size(nBWidth
,nBHeight
) );
5469 if ( aButRect
.IsInside( rPosPixel
) )
5471 rScenRange
= aRange
;
5481 void ScGridWindow::DrawLayerCreated()
5483 SetMapMode( GetDrawMapMode() );
5485 // initially create overlay objects
5486 ImpCreateOverlayObjects();
5491 struct SpellCheckStatus
5495 SpellCheckStatus() : mbModified(false) {};
5497 DECL_LINK (EventHdl
, EditStatus
*);
5500 IMPL_LINK(SpellCheckStatus
, EventHdl
, EditStatus
*, pStatus
)
5502 sal_uLong nStatus
= pStatus
->GetStatusWord();
5503 if (nStatus
& EE_STAT_WRONGWORDCHANGED
)
5511 bool ScGridWindow::ContinueOnlineSpelling()
5513 if (!mpSpellCheckCxt
)
5516 if (!mpSpellCheckCxt
->maPos
.isValid())
5519 ScDocument
* pDoc
= pViewData
->GetDocument();
5520 ScDPCollection
* pDPs
= NULL
;
5521 if (pDoc
->HasPivotTable())
5522 pDPs
= pDoc
->GetDPCollection();
5524 SCTAB nTab
= pViewData
->GetTabNo();
5525 SpellCheckStatus aStatus
;
5527 ScHorizontalCellIterator
aIter(
5528 pDoc
, nTab
, maVisibleRange
.mnCol1
, mpSpellCheckCxt
->maPos
.mnRow
, maVisibleRange
.mnCol2
, maVisibleRange
.mnRow2
);
5530 ScRangeList aPivotRanges
;
5532 aPivotRanges
= pDPs
->GetAllTableRanges(nTab
);
5536 ScRefCellValue
* pCell
= aIter
.GetNext(nCol
, nRow
);
5537 while (pCell
&& nRow
< mpSpellCheckCxt
->maPos
.mnRow
)
5538 pCell
= aIter
.GetNext(nCol
, nRow
);
5540 while (pCell
&& nCol
< mpSpellCheckCxt
->maPos
.mnCol
)
5541 pCell
= aIter
.GetNext(nCol
, nRow
);
5543 boost::scoped_ptr
<ScTabEditEngine
> pEngine
;
5545 // Check only up to 256 cells at a time.
5546 size_t nTotalCellCount
= 0;
5547 size_t nTextCellCount
= 0;
5548 bool bSpellCheckPerformed
= false;
5554 if (aPivotRanges
.In(ScAddress(nCol
, nRow
, nTab
)))
5556 // Don't spell check within pivot tables.
5557 if (nTotalCellCount
>= 255)
5560 pCell
= aIter
.GetNext(nCol
, nRow
);
5564 CellType eType
= pCell
->meType
;
5565 if (eType
== CELLTYPE_STRING
|| eType
== CELLTYPE_EDIT
)
5571 // ScTabEditEngine is needed
5572 // because MapMode must be set for some old documents
5573 pEngine
.reset(new ScTabEditEngine(pDoc
));
5574 pEngine
->SetControlWord(
5575 pEngine
->GetControlWord() | (EE_CNTRL_ONLINESPELLING
| EE_CNTRL_ALLOWBIGOBJS
));
5576 pEngine
->SetStatusEventHdl(LINK(&aStatus
, SpellCheckStatus
, EventHdl
));
5577 // Delimiters hier wie in inputhdl.cxx !!!
5578 pEngine
->SetWordDelimiters(
5579 ScEditUtil::ModifyDelimiters(pEngine
->GetWordDelimiters()));
5581 uno::Reference
<linguistic2::XSpellChecker1
> xXSpellChecker1(LinguMgr::GetSpellChecker());
5582 pEngine
->SetSpeller(xXSpellChecker1
);
5585 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nCol
, nRow
, nTab
);
5586 sal_uInt16 nCellLang
=
5587 static_cast<const SvxLanguageItem
&>(pPattern
->GetItem(ATTR_FONT_LANGUAGE
)).GetValue();
5588 if (nCellLang
== LANGUAGE_SYSTEM
)
5589 nCellLang
= Application::GetSettings().GetLanguageTag().getLanguageType(); // never use SYSTEM for spelling
5590 pEngine
->SetDefaultLanguage(nCellLang
);
5592 if (eType
== CELLTYPE_STRING
)
5593 pEngine
->SetText(pCell
->mpString
->getString());
5595 pEngine
->SetText(*pCell
->mpEditText
);
5597 aStatus
.mbModified
= false;
5598 pEngine
->CompleteOnlineSpelling();
5599 if (aStatus
.mbModified
)
5601 std::vector
<editeng::MisspellRanges
> aRanges
;
5602 pEngine
->GetAllMisspellRanges(aRanges
);
5603 if (!aRanges
.empty())
5605 sc::SpellCheckContext::CellPos
aPos(nCol
, nRow
);
5606 mpSpellCheckCxt
->maMisspellCells
.insert(
5607 sc::SpellCheckContext::CellMapType::value_type(aPos
, aRanges
));
5610 // Broadcast for re-paint.
5611 ScPaintHint
aHint(ScRange(nCol
, nRow
, nTab
), PAINT_GRID
);
5612 aHint
.SetPrintFlag(false);
5613 pDoc
->GetDocumentShell()->Broadcast(aHint
);
5616 bSpellCheckPerformed
= true;
5619 if (nTotalCellCount
>= 255 || nTextCellCount
>= 1)
5622 pCell
= aIter
.GetNext(nCol
, nRow
);
5626 // Move to the next cell position for the next iteration.
5627 pCell
= aIter
.GetNext(nCol
, nRow
);
5631 // This will become the first cell position for the next time.
5632 mpSpellCheckCxt
->maPos
.mnCol
= nCol
;
5633 mpSpellCheckCxt
->maPos
.mnRow
= nRow
;
5637 // No more cells to spell check.
5638 mpSpellCheckCxt
->maPos
.setInvalid();
5641 return bSpellCheckPerformed
;
5644 void ScGridWindow::EnableAutoSpell( bool bEnable
)
5647 mpSpellCheckCxt
.reset(new sc::SpellCheckContext
);
5649 mpSpellCheckCxt
.reset();
5652 void ScGridWindow::ResetAutoSpell()
5654 if (mpSpellCheckCxt
)
5656 mpSpellCheckCxt
->reset();
5657 mpSpellCheckCxt
->maPos
.mnCol
= maVisibleRange
.mnCol1
;
5658 mpSpellCheckCxt
->maPos
.mnRow
= maVisibleRange
.mnRow1
;
5662 void ScGridWindow::SetAutoSpellData( SCCOL nPosX
, SCROW nPosY
, const std::vector
<editeng::MisspellRanges
>* pRanges
)
5664 if (!mpSpellCheckCxt
)
5667 if (!maVisibleRange
.isInside(nPosX
, nPosY
))
5670 mpSpellCheckCxt
->setMisspellRanges(nPosX
, nPosY
, pRanges
);
5674 void ScGridWindow::CursorChanged()
5676 // here the created OverlayObjects may be transformed in later versions. For
5677 // now, just re-create them
5679 UpdateCursorOverlay();
5683 void ScGridWindow::ImpCreateOverlayObjects()
5685 UpdateCursorOverlay();
5686 UpdateCopySourceOverlay();
5687 UpdateSelectionOverlay();
5688 UpdateAutoFillOverlay();
5689 UpdateDragRectOverlay();
5690 UpdateHeaderOverlay();
5691 UpdateShrinkOverlay();
5695 void ScGridWindow::ImpDestroyOverlayObjects()
5697 DeleteCursorOverlay();
5698 DeleteCopySourceOverlay();
5699 DeleteSelectionOverlay();
5700 DeleteAutoFillOverlay();
5701 DeleteDragRectOverlay();
5702 DeleteHeaderOverlay();
5703 DeleteShrinkOverlay();
5706 void ScGridWindow::UpdateAllOverlays()
5708 // delete and re-allocate all overlay objects
5710 ImpDestroyOverlayObjects();
5711 ImpCreateOverlayObjects();
5714 void ScGridWindow::DeleteCursorOverlay()
5716 DELETEZ( mpOOCursors
);
5719 void ScGridWindow::DeleteCopySourceOverlay()
5721 DELETEZ( mpOOSelectionBorder
);
5724 void ScGridWindow::UpdateCopySourceOverlay()
5726 MapMode aDrawMode
= GetDrawMapMode();
5727 MapMode aOldMode
= GetMapMode();
5728 if ( aOldMode
!= aDrawMode
)
5729 SetMapMode( aDrawMode
);
5731 DeleteCopySourceOverlay();
5733 if (!pViewData
->ShowPasteSource())
5735 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5736 if (!xOverlayManager
.is())
5738 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard( pViewData
->GetActiveWin() );
5741 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
5745 SCTAB nCurTab
= pViewData
->GetCurPos().Tab();
5747 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
5748 mpOOSelectionBorder
= new ::sdr::overlay::OverlayObjectList
;
5749 for ( size_t i
= 0; i
< rClipParam
.maRanges
.size(); ++i
)
5751 ScRange
* p
= rClipParam
.maRanges
[i
];
5752 if (p
->aStart
.Tab() != nCurTab
)
5755 SCCOL nClipStartX
= p
->aStart
.Col();
5756 SCROW nClipStartY
= p
->aStart
.Row();
5757 SCCOL nClipEndX
= p
->aEnd
.Col();
5758 SCROW nClipEndY
= p
->aEnd
.Row();
5760 Point aClipStartScrPos
= pViewData
->GetScrPos( nClipStartX
, nClipStartY
, eWhich
);
5761 Point aClipEndScrPos
= pViewData
->GetScrPos( nClipEndX
+ 1, nClipEndY
+ 1, eWhich
);
5762 aClipStartScrPos
-= Point(1, 1);
5763 long nSizeXPix
= aClipEndScrPos
.X() - aClipStartScrPos
.X();
5764 long nSizeYPix
= aClipEndScrPos
.Y() - aClipStartScrPos
.Y();
5766 Rectangle
aRect( aClipStartScrPos
, Size(nSizeXPix
, nSizeYPix
) );
5769 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5771 Rectangle aLogic
= PixelToLogic(aRect
, aDrawMode
);
5772 ::basegfx::B2DRange
aRange(aLogic
.Left(), aLogic
.Top(), aLogic
.Right(), aLogic
.Bottom());
5773 ScOverlayDashedBorder
* pDashedBorder
= new ScOverlayDashedBorder(aRange
, aHighlight
);
5774 xOverlayManager
->add(*pDashedBorder
);
5775 mpOOSelectionBorder
->append(*pDashedBorder
);
5778 if ( aOldMode
!= aDrawMode
)
5779 SetMapMode( aOldMode
);
5782 void ScGridWindow::UpdateCursorOverlay()
5784 MapMode aDrawMode
= GetDrawMapMode();
5785 MapMode aOldMode
= GetMapMode();
5786 if ( aOldMode
!= aDrawMode
)
5787 SetMapMode( aDrawMode
);
5789 // Existing OverlayObjects may be transformed in later versions.
5790 // For now, just re-create them.
5792 DeleteCursorOverlay();
5794 std::vector
<Rectangle
> aPixelRects
;
5797 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5800 SCTAB nTab
= pViewData
->GetTabNo();
5801 SCCOL nX
= pViewData
->GetCurX();
5802 SCROW nY
= pViewData
->GetCurY();
5804 if (!maVisibleRange
.isInside(nX
, nY
))
5807 // don't show the cursor in overlapped cells
5809 ScDocument
* pDoc
= pViewData
->GetDocument();
5810 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nX
,nY
,nTab
);
5811 const ScMergeFlagAttr
& rMergeFlag
= (const ScMergeFlagAttr
&) pPattern
->GetItem(ATTR_MERGE_FLAG
);
5812 bool bOverlapped
= rMergeFlag
.IsOverlapped();
5814 // left or above of the screen?
5816 bool bVis
= ( nX
>=pViewData
->GetPosX(eHWhich
) && nY
>=pViewData
->GetPosY(eVWhich
) );
5821 const ScMergeAttr
& rMerge
= (const ScMergeAttr
&) pPattern
->GetItem(ATTR_MERGE
);
5822 if (rMerge
.GetColMerge() > 1)
5823 nEndX
+= rMerge
.GetColMerge()-1;
5824 if (rMerge
.GetRowMerge() > 1)
5825 nEndY
+= rMerge
.GetRowMerge()-1;
5826 bVis
= ( nEndX
>=pViewData
->GetPosX(eHWhich
) && nEndY
>=pViewData
->GetPosY(eVWhich
) );
5829 if ( bVis
&& !bOverlapped
&& !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5831 Point aScrPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, true );
5832 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5834 // completely right of/below the screen?
5835 // (test with logical start position in aScrPos)
5838 bMaybeVisible
= ( aScrPos
.X() >= -2 && aScrPos
.Y() >= -2 );
5841 Size aOutSize
= GetOutputSizePixel();
5842 bMaybeVisible
= ( aScrPos
.X() <= aOutSize
.Width() + 2 && aScrPos
.Y() <= aOutSize
.Height() + 2 );
5844 if ( bMaybeVisible
)
5848 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5851 aScrPos
.X() -= nSizeXPix
- 2; // move instead of mirroring
5853 // Now, draw the cursor.
5857 Rectangle
aRect( aScrPos
, Size( nSizeXPix
+ 3, nSizeYPix
+ 3 ) );
5859 aPixelRects
.push_back(Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ));
5860 aPixelRects
.push_back(Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ));
5861 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ));
5862 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ));
5866 if ( !aPixelRects
.empty() )
5868 // #i70788# get the OverlayManager safely
5869 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5871 if (xOverlayManager
.is())
5873 Color
aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5874 if (pViewData
->GetActivePart() != eWhich
)
5875 // non-active pane uses a different color.
5876 aCursorColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5877 std::vector
< basegfx::B2DRange
> aRanges
;
5878 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5880 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5882 const Rectangle
aRA(aPixelRects
[a
]);
5883 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5884 aRB
.transform(aTransform
);
5885 aRanges
.push_back(aRB
);
5888 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5889 sdr::overlay::OVERLAY_SOLID
,
5894 xOverlayManager
->add(*pOverlay
);
5895 mpOOCursors
= new ::sdr::overlay::OverlayObjectList
;
5896 mpOOCursors
->append(*pOverlay
);
5900 if ( aOldMode
!= aDrawMode
)
5901 SetMapMode( aOldMode
);
5904 void ScGridWindow::DeleteSelectionOverlay()
5906 DELETEZ( mpOOSelection
);
5909 void ScGridWindow::UpdateSelectionOverlay()
5911 MapMode aDrawMode
= GetDrawMapMode();
5912 MapMode aOldMode
= GetMapMode();
5913 if ( aOldMode
!= aDrawMode
)
5914 SetMapMode( aDrawMode
);
5916 DeleteSelectionOverlay();
5917 std::vector
<Rectangle
> aPixelRects
;
5918 GetSelectionRects( aPixelRects
);
5920 if ( aPixelRects
.size() && pViewData
->IsActive() )
5922 // #i70788# get the OverlayManager safely
5923 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5925 if (xOverlayManager
.is())
5927 std::vector
< basegfx::B2DRange
> aRanges
;
5928 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5930 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5932 const Rectangle
aRA(aPixelRects
[a
]);
5933 basegfx::B2DRange
aRB(aRA
.Left() - 1, aRA
.Top() - 1, aRA
.Right(), aRA
.Bottom());
5934 aRB
.transform(aTransform
);
5935 aRanges
.push_back(aRB
);
5938 // get the system's highlight color
5939 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
5940 const Color
aHighlight(aSvtOptionsDrawinglayer
.getHilightColor());
5942 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5943 sdr::overlay::OVERLAY_TRANSPARENT
,
5948 xOverlayManager
->add(*pOverlay
);
5949 mpOOSelection
= new ::sdr::overlay::OverlayObjectList
;
5950 mpOOSelection
->append(*pOverlay
);
5954 if ( aOldMode
!= aDrawMode
)
5955 SetMapMode( aOldMode
);
5958 void ScGridWindow::DeleteAutoFillOverlay()
5960 DELETEZ( mpOOAutoFill
);
5961 mpAutoFillRect
.reset();
5964 void ScGridWindow::UpdateAutoFillOverlay()
5966 MapMode aDrawMode
= GetDrawMapMode();
5967 MapMode aOldMode
= GetMapMode();
5968 if ( aOldMode
!= aDrawMode
)
5969 SetMapMode( aDrawMode
);
5971 DeleteAutoFillOverlay();
5974 // get the AutoFill handle rectangle in pixels
5977 if ( bAutoMarkVisible
&& aAutoMarkPos
.Tab() == pViewData
->GetTabNo() &&
5978 !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5980 SCCOL nX
= aAutoMarkPos
.Col();
5981 SCROW nY
= aAutoMarkPos
.Row();
5983 if (!maVisibleRange
.isInside(nX
, nY
))
5984 // Autofill mark is not visible. Bail out.
5987 SCTAB nTab
= pViewData
->GetTabNo();
5988 ScDocument
* pDoc
= pViewData
->GetDocument();
5989 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5991 Point aFillPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, true );
5994 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5996 aFillPos
.X() -= nSizeXPix
+ 3;
5998 aFillPos
.X() += nSizeXPix
- 2;
6000 aFillPos
.Y() += nSizeYPix
;
6002 mpAutoFillRect
.reset(new Rectangle(aFillPos
, Size(6, 6)));
6004 // #i70788# get the OverlayManager safely
6005 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6007 if (xOverlayManager
.is())
6009 Color
aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
6010 if (pViewData
->GetActivePart() != eWhich
)
6011 // non-active pane uses a different color.
6012 aHandleColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
6013 std::vector
< basegfx::B2DRange
> aRanges
;
6014 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6015 basegfx::B2DRange
aRB(mpAutoFillRect
->Left(), mpAutoFillRect
->Top(), mpAutoFillRect
->Right() + 1, mpAutoFillRect
->Bottom() + 1);
6017 aRB
.transform(aTransform
);
6018 aRanges
.push_back(aRB
);
6020 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6021 sdr::overlay::OVERLAY_SOLID
,
6026 xOverlayManager
->add(*pOverlay
);
6027 mpOOAutoFill
= new ::sdr::overlay::OverlayObjectList
;
6028 mpOOAutoFill
->append(*pOverlay
);
6031 if ( aOldMode
!= aDrawMode
)
6032 SetMapMode( aOldMode
);
6036 void ScGridWindow::DeleteDragRectOverlay()
6038 DELETEZ( mpOODragRect
);
6041 void ScGridWindow::UpdateDragRectOverlay()
6043 MapMode aDrawMode
= GetDrawMapMode();
6044 MapMode aOldMode
= GetMapMode();
6045 if ( aOldMode
!= aDrawMode
)
6046 SetMapMode( aDrawMode
);
6048 DeleteDragRectOverlay();
6051 // get the rectangles in pixels (moved from DrawDragRect)
6054 if ( bDragRect
|| bPagebreakDrawn
)
6056 std::vector
<Rectangle
> aPixelRects
;
6058 SCCOL nX1
= bDragRect
? nDragStartX
: aPagebreakDrag
.aStart
.Col();
6059 SCROW nY1
= bDragRect
? nDragStartY
: aPagebreakDrag
.aStart
.Row();
6060 SCCOL nX2
= bDragRect
? nDragEndX
: aPagebreakDrag
.aEnd
.Col();
6061 SCROW nY2
= bDragRect
? nDragEndY
: aPagebreakDrag
.aEnd
.Row();
6063 SCTAB nTab
= pViewData
->GetTabNo();
6065 SCCOL nPosX
= pViewData
->GetPosX(WhichH(eWhich
));
6066 SCROW nPosY
= pViewData
->GetPosY(WhichV(eWhich
));
6067 if (nX1
< nPosX
) nX1
= nPosX
;
6068 if (nX2
< nPosX
) nX2
= nPosX
;
6069 if (nY1
< nPosY
) nY1
= nPosY
;
6070 if (nY2
< nPosY
) nY2
= nPosY
;
6072 Point
aScrPos( pViewData
->GetScrPos( nX1
, nY1
, eWhich
) );
6076 ScDocument
* pDoc
= pViewData
->GetDocument();
6077 double nPPTX
= pViewData
->GetPPTX();
6078 double nPPTY
= pViewData
->GetPPTY();
6081 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
6082 long nLayoutSign
= bLayoutRTL
? -1 : 1;
6084 if (ValidCol(nX2
) && nX2
>=nX1
)
6085 for (i
=nX1
; i
<=nX2
; i
++)
6086 nSizeXPix
+= ScViewData::ToPixel( pDoc
->GetColWidth( static_cast<SCCOL
>(i
), nTab
), nPPTX
);
6089 aScrPos
.X() -= nLayoutSign
;
6093 if (ValidRow(nY2
) && nY2
>=nY1
)
6094 for (i
=nY1
; i
<=nY2
; i
++)
6095 nSizeYPix
+= ScViewData::ToPixel( pDoc
->GetRowHeight( i
, nTab
), nPPTY
);
6102 aScrPos
.X() -= 2 * nLayoutSign
;
6104 Rectangle
aRect( aScrPos
.X(), aScrPos
.Y(),
6105 aScrPos
.X() + ( nSizeXPix
+ 2 ) * nLayoutSign
, aScrPos
.Y() + nSizeYPix
+ 2 );
6108 aRect
.Left() = aRect
.Right(); // end position is left
6109 aRect
.Right() = aScrPos
.X();
6112 if ( meDragInsertMode
== INS_CELLSDOWN
)
6114 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top()+3, aRect
.Left()+1, aRect
.Bottom()-2 ) );
6115 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+3, aRect
.Right()-1, aRect
.Bottom()-2 ) );
6116 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top(), aRect
.Right()-1, aRect
.Top()+2 ) );
6117 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Bottom()-1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
6119 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
6121 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top()+1, aRect
.Left()+2, aRect
.Bottom()-1 ) );
6122 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
6123 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top()+1, aRect
.Right()-2, aRect
.Top()+1 ) );
6124 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-1, aRect
.Right()-2, aRect
.Bottom()-1 ) );
6128 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ) );
6129 aPixelRects
.push_back( Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ) );
6130 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ) );
6131 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ) );
6134 // #i70788# get the OverlayManager safely
6135 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6137 if (xOverlayManager
.is())
6139 std::vector
< basegfx::B2DRange
> aRanges
;
6140 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6142 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
6144 const Rectangle
aRA(aPixelRects
[a
]);
6145 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
6146 aRB
.transform(aTransform
);
6147 aRanges
.push_back(aRB
);
6150 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6151 sdr::overlay::OVERLAY_INVERT
,
6156 xOverlayManager
->add(*pOverlay
);
6157 mpOODragRect
= new ::sdr::overlay::OverlayObjectList
;
6158 mpOODragRect
->append(*pOverlay
);
6162 if ( aOldMode
!= aDrawMode
)
6163 SetMapMode( aOldMode
);
6166 void ScGridWindow::DeleteHeaderOverlay()
6168 DELETEZ( mpOOHeader
);
6171 void ScGridWindow::UpdateHeaderOverlay()
6173 MapMode aDrawMode
= GetDrawMapMode();
6174 MapMode aOldMode
= GetMapMode();
6175 if ( aOldMode
!= aDrawMode
)
6176 SetMapMode( aDrawMode
);
6178 DeleteHeaderOverlay();
6180 // Pixel rectangle is in aInvertRect
6181 if ( !aInvertRect
.IsEmpty() )
6183 // #i70788# get the OverlayManager safely
6184 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6186 if (xOverlayManager
.is())
6188 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
6189 std::vector
< basegfx::B2DRange
> aRanges
;
6190 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6191 basegfx::B2DRange
aRB(aInvertRect
.Left(), aInvertRect
.Top(), aInvertRect
.Right() + 1, aInvertRect
.Bottom() + 1);
6193 aRB
.transform(aTransform
);
6194 aRanges
.push_back(aRB
);
6196 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6197 sdr::overlay::OVERLAY_INVERT
,
6202 xOverlayManager
->add(*pOverlay
);
6203 mpOOHeader
= new ::sdr::overlay::OverlayObjectList
;
6204 mpOOHeader
->append(*pOverlay
);
6208 if ( aOldMode
!= aDrawMode
)
6209 SetMapMode( aOldMode
);
6212 void ScGridWindow::DeleteShrinkOverlay()
6214 DELETEZ( mpOOShrink
);
6217 void ScGridWindow::UpdateShrinkOverlay()
6219 MapMode aDrawMode
= GetDrawMapMode();
6220 MapMode aOldMode
= GetMapMode();
6221 if ( aOldMode
!= aDrawMode
)
6222 SetMapMode( aDrawMode
);
6224 DeleteShrinkOverlay();
6227 // get the rectangle in pixels
6232 SCTAB nTab
= pViewData
->GetTabNo();
6233 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() &&
6234 pViewData
->GetDelMark( aRange
) )
6236 //! limit to visible area
6237 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
6238 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
6240 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
6241 aRange
.aStart
.Row(), eWhich
);
6242 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
6243 aRange
.aEnd
.Row()+1, eWhich
);
6247 aPixRect
= Rectangle( aStart
,aEnd
);
6251 if ( !aPixRect
.IsEmpty() )
6253 // #i70788# get the OverlayManager safely
6254 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6256 if (xOverlayManager
.is())
6258 std::vector
< basegfx::B2DRange
> aRanges
;
6259 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
6260 basegfx::B2DRange
aRB(aPixRect
.Left(), aPixRect
.Top(), aPixRect
.Right() + 1, aPixRect
.Bottom() + 1);
6262 aRB
.transform(aTransform
);
6263 aRanges
.push_back(aRB
);
6265 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
6266 sdr::overlay::OVERLAY_INVERT
,
6271 xOverlayManager
->add(*pOverlay
);
6272 mpOOShrink
= new ::sdr::overlay::OverlayObjectList
;
6273 mpOOShrink
->append(*pOverlay
);
6277 if ( aOldMode
!= aDrawMode
)
6278 SetMapMode( aOldMode
);
6281 // #i70788# central method to get the OverlayManager safely
6282 rtl::Reference
<sdr::overlay::OverlayManager
> ScGridWindow::getOverlayManager()
6284 SdrPageView
* pPV
= pViewData
->GetView()->GetScDrawView()->GetSdrPageView();
6288 SdrPageWindow
* pPageWin
= pPV
->FindPageWindow( *this );
6292 return (pPageWin
->GetOverlayManager());
6296 return rtl::Reference
<sdr::overlay::OverlayManager
>();
6299 void ScGridWindow::flushOverlayManager()
6301 // #i70788# get the OverlayManager safely
6302 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
6304 if (xOverlayManager
.is())
6305 xOverlayManager
->flush();
6308 void ScGridWindow::SetInRefMode( bool bInRefMode
)
6310 WinBits nBits
= GetStyle();
6312 nBits
|= WB_REFMODE
;
6314 nBits
&= ~WB_REFMODE
;
6319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */