1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "scitems.hxx"
23 #include <memory> //auto_ptr
24 #include <editeng/adjitem.hxx>
25 #include <svx/algitem.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/editstat.hxx>
28 #include <editeng/flditem.hxx>
29 #include <editeng/justifyitem.hxx>
30 #include <svx/svdetc.hxx>
31 #include <editeng/editobj.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/viewfrm.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <svl/stritem.hxx>
36 #include <svtools/svtabbx.hxx>
37 #include <svl/urlbmk.hxx>
38 #include <vcl/cursor.hxx>
39 #include <vcl/graph.hxx>
40 #include <vcl/hatch.hxx>
41 #include <sot/formats.hxx>
42 #include <sot/clsids.hxx>
43 #include <sal/macros.h>
45 #include <svx/svdview.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
46 #include <editeng/outliner.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
47 #include <svx/svditer.hxx>
48 #include <svx/svdocapt.hxx>
49 #include <svx/svdpagv.hxx>
51 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
52 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
53 #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
54 #include <com/sun/star/sheet/DataPilotTableResultData.hpp>
55 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
56 #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
57 #include <com/sun/star/sheet/MemberResultFlags.hpp>
58 #include <com/sun/star/awt/KeyModifier.hpp>
59 #include <com/sun/star/awt/MouseButton.hpp>
60 #include <com/sun/star/script/vba/VBAEventId.hpp>
61 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
63 #include "gridwin.hxx"
64 #include "tabvwsh.hxx"
66 #include "viewdata.hxx"
67 #include "tabview.hxx"
70 #include "document.hxx"
73 #include "stlpool.hxx"
74 #include "printfun.hxx"
75 #include "cbutton.hxx"
77 #include "globstr.hrc"
78 #include "editutil.hxx"
79 #include "scresid.hxx"
80 #include "inputhdl.hxx"
81 #include "uiitems.hxx" // Filter-Dialog - auslagern !!!
82 #include "filtdlg.hxx"
83 #include "impex.hxx" // Sylk-ID fuer CB
84 #include "cell.hxx" // fuer Edit-Felder
85 #include "patattr.hxx"
86 #include "notemark.hxx"
87 #include "rfindlst.hxx"
88 #include "docpool.hxx"
90 #include "docfunc.hxx"
91 #include "dbdocfun.hxx"
92 #include "dpobject.hxx"
93 #include "dpoutput.hxx"
94 #include "transobj.hxx"
95 #include "drwtrans.hxx"
96 #include "seltrans.hxx"
97 #include "sizedev.hxx"
98 #include "AccessibilityHints.hxx"
100 #include "viewuno.hxx"
101 #include "compiler.hxx"
102 #include "editable.hxx"
103 #include "fillinfo.hxx"
104 #include "userdat.hxx"
105 #include "drwlayer.hxx"
106 #include "validat.hxx"
107 #include "tabprotection.hxx"
108 #include "postit.hxx"
109 #include "dpcontrol.hxx"
110 #include "checklistmenu.hxx"
111 #include "clipparam.hxx"
112 #include "cellsh.hxx"
113 #include "overlayobject.hxx"
114 #include "cellsuno.hxx"
115 #include "drawview.hxx"
116 #include "dragdata.hxx"
117 #include "cliputil.hxx"
118 #include "queryentry.hxx"
119 #include "markdata.hxx"
120 #include "checklistmenu.hrc"
121 #include "strload.hxx"
122 #include "externalrefmgr.hxx"
124 #include <svx/sdrpagewindow.hxx>
125 #include <svx/sdr/overlay/overlaymanager.hxx>
126 #include <vcl/svapp.hxx>
127 #include <svx/sdr/overlay/overlayselection.hxx>
131 using namespace com::sun::star
;
132 using ::com::sun::star::uno::Sequence
;
133 using ::com::sun::star::uno::Any
;
134 using ::rtl::OUString
;
136 const sal_uInt8 SC_NESTEDBUTTON_NONE
= 0;
137 const sal_uInt8 SC_NESTEDBUTTON_DOWN
= 1;
138 const sal_uInt8 SC_NESTEDBUTTON_UP
= 2;
140 #define SC_AUTOFILTER_ALL 0
141 #define SC_AUTOFILTER_TOP10 1
142 #define SC_AUTOFILTER_CUSTOM 2
143 #define SC_AUTOFILTER_EMPTY 3
144 #define SC_AUTOFILTER_NOTEMPTY 4
146 // Modi fuer die FilterListBox
150 SC_FILTERBOX_DATASELECT
,
151 SC_FILTERBOX_SCENARIO
,
152 SC_FILTERBOX_PAGEFIELD
155 extern SfxViewShell
* pScActiveViewShell
; // global.cxx
156 extern sal_uInt16 nScClickMouseModifier
; // global.cxx
157 extern sal_uInt16 nScFillModeMouseModifier
; // global.cxx
159 struct ScGridWindow::MouseEventState
163 MouseEventState() : mbActivatePart(false) {}
166 #define SC_FILTERLISTBOX_LINES 12
168 // ============================================================================
170 ScGridWindow::VisibleRange::VisibleRange() :
171 mnCol1(0), mnCol2(MAXCOL
), mnRow1(0), mnRow2(MAXROW
)
175 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol
, SCROW nRow
) const
177 return mnCol1
<= nCol
&& nCol
<= mnCol2
&& mnRow1
<= nRow
&& nRow
<= mnRow2
;
180 // ============================================================================
182 class ScFilterListBox
: public ListBox
185 ScGridWindow
* pGridWin
;
188 sal_Bool bButtonDown
;
194 ScFilterBoxMode eMode
;
197 virtual void LoseFocus();
201 ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
202 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
);
205 virtual long PreNotify( NotifyEvent
& rNEvt
);
206 virtual void Select();
208 SCCOL
GetCol() const { return nCol
; }
209 SCROW
GetRow() const { return nRow
; }
210 ScFilterBoxMode
GetMode() const { return eMode
; }
211 sal_Bool
IsDataSelect() const { return (eMode
== SC_FILTERBOX_DATASELECT
); }
213 sal_Bool
IsInInit() const { return bInit
; }
214 void SetCancelled() { bCancelled
= sal_True
; }
215 sal_Bool
IsInSelect() const { return bInSelect
; }
216 void SetListHasDates(bool b
) { mbListHasDates
= b
; }
217 bool HasDates() const { return mbListHasDates
; }
220 //-------------------------------------------------------------------
222 // ListBox in einem FloatingWindow (pParent)
223 ScFilterListBox::ScFilterListBox( Window
* pParent
, ScGridWindow
* pGrid
,
224 SCCOL nNewCol
, SCROW nNewRow
, ScFilterBoxMode eNewMode
) :
225 ListBox( pParent
, WB_AUTOHSCROLL
),
229 bButtonDown( false ),
233 mbListHasDates(false),
239 ScFilterListBox::~ScFilterListBox()
241 if (IsMouseCaptured())
245 void ScFilterListBox::EndInit()
247 sal_uInt16 nPos
= GetSelectEntryPos();
248 if ( LISTBOX_ENTRY_NOTFOUND
== nPos
)
256 void ScFilterListBox::LoseFocus()
263 // -----------------------------------------------------------------------
265 long ScFilterListBox::PreNotify( NotifyEvent
& rNEvt
)
268 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
270 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
271 KeyCode aCode
= aKeyEvt
.GetKeyCode();
272 if ( !aCode
.GetModifier() ) // ohne alle Modifiers
274 sal_uInt16 nKey
= aCode
.GetCode();
275 if ( nKey
== KEY_RETURN
)
277 SelectHdl(); // auswaehlen
280 else if ( nKey
== KEY_ESCAPE
)
282 pGridWin
->ClickExtern(); // loescht die List-Box !!!
288 return nDone
? nDone
: ListBox::PreNotify( rNEvt
);
291 void ScFilterListBox::Select()
297 void ScFilterListBox::SelectHdl()
299 if ( !IsTravelSelect() && !bInit
&& !bCancelled
)
301 sal_uInt16 nPos
= GetSelectEntryPos();
302 if ( LISTBOX_ENTRY_NOTFOUND
!= nPos
)
307 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
308 bInSelect
= sal_True
;
309 pGridWin
->FilterSelect( nSel
);
316 // ============================================================================
318 // use a System floating window for the above filter listbox
319 class ScFilterFloatingWindow
: public FloatingWindow
322 ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
= WB_STDFLOATWIN
);
323 virtual ~ScFilterFloatingWindow();
324 // required for System FloatingWindows that will not process KeyInput by themselves
325 virtual Window
* GetPreferredKeyInputWindow();
328 ScFilterFloatingWindow::ScFilterFloatingWindow( Window
* pParent
, WinBits nStyle
) :
329 FloatingWindow( pParent
, nStyle
|WB_SYSTEMWINDOW
) // make it a system floater
332 ScFilterFloatingWindow::~ScFilterFloatingWindow()
337 Window
* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
339 // redirect keyinput in the child window
340 return GetWindow(WINDOW_FIRSTCHILD
) ? GetWindow(WINDOW_FIRSTCHILD
)->GetPreferredKeyInputWindow() : NULL
; // will be the FilterBox
343 // ============================================================================
345 static sal_Bool
lcl_IsEditableMatrix( ScDocument
* pDoc
, const ScRange
& rRange
)
347 // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
348 // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
349 //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
351 if ( !pDoc
->IsBlockEditable( rRange
.aStart
.Tab(), rRange
.aStart
.Col(),rRange
.aStart
.Row(),
352 rRange
.aEnd
.Col(),rRange
.aEnd
.Row() ) )
356 const ScBaseCell
* pCell
= pDoc
->GetCell( rRange
.aEnd
);
357 return ( pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
&&
358 ((ScFormulaCell
*)pCell
)->GetMatrixOrigin(aPos
) && aPos
== rRange
.aStart
);
362 static void lcl_UnLockComment( ScDrawView
* pView
, SdrPageView
* pPV
, SdrModel
* pDrDoc
, const Point
& rPos
, ScViewData
* pViewData
)
364 if (!pView
&& !pPV
&& !pDrDoc
&& !pViewData
)
367 ScDocument
& rDoc
= *pViewData
->GetDocument();
368 ScAddress
aCellPos( pViewData
->GetCurX(), pViewData
->GetCurY(), pViewData
->GetTabNo() );
369 ScPostIt
* pNote
= rDoc
.GetNotes( aCellPos
.Tab() )->findByAddress( aCellPos
);
370 SdrObject
* pObj
= pNote
? pNote
->GetCaption() : 0;
371 if( pObj
&& pObj
->GetLogicRect().IsInside( rPos
) && ScDrawLayer::IsNoteCaption( pObj
) )
373 const ScProtectionAttr
* pProtAttr
= static_cast< const ScProtectionAttr
* > (rDoc
.GetAttr( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab(), ATTR_PROTECTION
) );
374 bool bProtectAttr
= pProtAttr
->GetProtection() || pProtAttr
->GetHideCell() ;
375 bool bProtectDoc
= rDoc
.IsTabProtected( aCellPos
.Tab() ) || pViewData
->GetSfxDocShell()->IsReadOnly() ;
376 // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
377 pView
->LockInternalLayer( bProtectDoc
&& bProtectAttr
);
381 static sal_Bool
lcl_GetHyperlinkCell(ScDocument
* pDoc
, SCCOL
& rPosX
, SCROW
& rPosY
, SCTAB nTab
, ScBaseCell
*& rpCell
)
383 sal_Bool bFound
= false;
386 pDoc
->GetCell( rPosX
, rPosY
, nTab
, rpCell
);
387 if ( !rpCell
|| rpCell
->GetCellType() == CELLTYPE_NOTE
)
390 return false; // alles leer bis links
392 --rPosX
; // weitersuchen
394 else if ( rpCell
->GetCellType() == CELLTYPE_EDIT
)
396 else if (rpCell
->GetCellType() == CELLTYPE_FORMULA
&&
397 static_cast<ScFormulaCell
*>(rpCell
)->IsHyperLinkCell())
400 return false; // andere Zelle
407 // ---------------------------------------------------------------------------
408 // WB_DIALOGCONTROL noetig fuer UNO-Controls
409 ScGridWindow::ScGridWindow( Window
* pParent
, ScViewData
* pData
, ScSplitPos eWhichPos
)
410 : Window( pParent
, WB_CLIPCHILDREN
| WB_DIALOGCONTROL
),
411 DropTargetHelper( this ),
412 DragSourceHelper( this ),
414 mpOOSelection( NULL
),
415 mpOOSelectionBorder( NULL
),
416 mpOOAutoFill( NULL
),
417 mpOODragRect( NULL
),
420 mpAutoFillRect(static_cast<Rectangle
*>(NULL
)),
425 pFilterFloat( NULL
),
426 mpAutoFilterPopup(NULL
),
427 mpDPFieldPopup(NULL
),
428 mpFilterButton(NULL
),
429 nCursorHideCount( 0 ),
431 nMouseStatus( SC_GM_NONE
),
432 nNestedButtonState( SC_NESTEDBUTTON_NONE
),
433 nPagebreakMouse( SC_PD_NONE
),
439 meDragInsertMode( INS_NONE
),
440 nCurrentPointer( 0 ),
441 aComboButton( this ),
448 bPagebreakDrawn( false ),
450 bIsInScroll( false ),
452 bNeedsRepaint( false ),
453 bAutoMarkVisible( false ),
454 bListValButton( false )
458 case SC_SPLIT_TOPLEFT
:
459 eHWhich
= SC_SPLIT_LEFT
;
460 eVWhich
= SC_SPLIT_TOP
;
462 case SC_SPLIT_TOPRIGHT
:
463 eHWhich
= SC_SPLIT_RIGHT
;
464 eVWhich
= SC_SPLIT_TOP
;
466 case SC_SPLIT_BOTTOMLEFT
:
467 eHWhich
= SC_SPLIT_LEFT
;
468 eVWhich
= SC_SPLIT_BOTTOM
;
470 case SC_SPLIT_BOTTOMRIGHT
:
471 eHWhich
= SC_SPLIT_RIGHT
;
472 eVWhich
= SC_SPLIT_BOTTOM
;
475 OSL_FAIL("GridWindow: falsche Position");
480 SetMapMode(pViewData
->GetLogicMode(eWhich
));
481 EnableChildTransparentMode();
482 SetDialogControlFlags( WINDOW_DLGCTRL_RETURN
| WINDOW_DLGCTRL_WANTFOCUS
);
484 SetHelpId( HID_SC_WIN_GRIDWIN
);
485 SetUniqueId( HID_SC_WIN_GRIDWIN
);
487 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
491 ScGridWindow::~ScGridWindow()
494 ImpDestroyOverlayObjects();
501 void ScGridWindow::Resize( const Size
& )
506 void ScGridWindow::ClickExtern()
510 // #i81298# don't delete the filter box when called from its select handler
511 // (possible through row header size update)
512 // #i84277# when initializing the filter box, a Basic error can deactivate the view
513 if ( pFilterBox
&& ( pFilterBox
->IsInSelect() || pFilterBox
->IsInInit() ) )
519 DELETEZ(pFilterFloat
);
525 mpDPFieldPopup
->close(false);
526 mpDPFieldPopup
.reset();
530 IMPL_LINK_NOARG(ScGridWindow
, PopupModeEndHdl
)
533 pFilterBox
->SetCancelled(); // nicht mehr auswaehlen
538 IMPL_LINK( ScGridWindow
, PopupSpellingHdl
, SpellCallbackInfo
*, pInfo
)
540 if( pInfo
->nCommand
== SPELLCMD_STARTSPELLDLG
)
541 pViewData
->GetDispatcher().Execute( SID_SPELL_DIALOG
, SFX_CALLMODE_ASYNCHRON
);
545 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol
, SCROW nRow
, sal_Bool bHasSelection
, const String
& rStr
)
549 ScDocument
* pDoc
= pViewData
->GetDocument();
550 SCTAB nTab
= pViewData
->GetTabNo();
551 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor(nCol
, nRow
, nTab
);
552 if ( pDPObj
&& nCol
> 0 )
554 // look for the dimension header left of the drop-down arrow
555 sal_uInt16 nOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
556 long nField
= pDPObj
->GetHeaderDim( ScAddress( nCol
-1, nRow
, nTab
), nOrient
);
557 if ( nField
>= 0 && nOrient
== sheet::DataPilotFieldOrientation_PAGE
)
559 ScDPSaveData
aSaveData( *pDPObj
->GetSaveData() );
562 OUString aDimName
= pDPObj
->GetDimName( nField
, bIsDataLayout
);
563 if ( !bIsDataLayout
)
565 ScDPSaveDimension
* pDim
= aSaveData
.GetDimensionByName(aDimName
);
569 const ::rtl::OUString aName
= rStr
;
570 pDim
->SetCurrentPage( &aName
);
573 pDim
->SetCurrentPage( NULL
);
575 ScDPObject
aNewObj( *pDPObj
);
576 aNewObj
.SetSaveData( aSaveData
);
577 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
578 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, sal_True
, false );
579 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
587 struct AutoFilterData
: public ScCheckListMenuWindow::ExtendedData
593 class AutoFilterAction
: public ScMenuFloatingWindow::Action
595 ScGridWindow
* mpWindow
;
596 ScGridWindow::AutoFilterMode meMode
;
598 AutoFilterAction(ScGridWindow
* p
, ScGridWindow::AutoFilterMode eMode
) :
599 mpWindow(p
), meMode(eMode
) {}
600 virtual void execute()
602 mpWindow
->UpdateAutoFilterFromMenu(meMode
);
606 class AutoFilterPopupEndAction
: public ScMenuFloatingWindow::Action
608 ScGridWindow
* mpWindow
;
611 AutoFilterPopupEndAction(ScGridWindow
* p
, const ScAddress
& rPos
) :
612 mpWindow(p
), maPos(rPos
) {}
613 virtual void execute()
615 mpWindow
->RefreshAutoFilterButton(maPos
);
619 class AddItemToEntry
: public std::unary_function
<rtl::OUString
, void>
621 ScQueryEntry::QueryItemsType
& mrItems
;
623 AddItemToEntry(ScQueryEntry::QueryItemsType
& rItems
) : mrItems(rItems
) {}
624 void operator() (const rtl::OUString
& rSelected
)
626 ScQueryEntry::Item aNew
;
627 aNew
.maString
= rSelected
;
628 aNew
.meType
= ScQueryEntry::ByString
;
630 mrItems
.push_back(aNew
);
634 class AddSelectedItemString
: public std::unary_function
<ScQueryEntry::Item
, void>
636 boost::unordered_set
<rtl::OUString
, rtl::OUStringHash
>& mrSet
;
638 AddSelectedItemString(boost::unordered_set
<rtl::OUString
, rtl::OUStringHash
>& r
) :
641 void operator() (const ScQueryEntry::Item
& rItem
)
643 mrSet
.insert(rItem
.maString
);
649 void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol
, SCROW nRow
)
651 SCTAB nTab
= pViewData
->GetTabNo();
652 ScDocument
* pDoc
= pViewData
->GetDocument();
654 mpAutoFilterPopup
.reset(new ScCheckListMenuWindow(this, pDoc
));
655 mpAutoFilterPopup
->setOKAction(new AutoFilterAction(this, Normal
));
656 mpAutoFilterPopup
->setPopupEndAction(
657 new AutoFilterPopupEndAction(this, ScAddress(nCol
, nRow
, nTab
)));
658 std::auto_ptr
<AutoFilterData
> pData(new AutoFilterData
);
659 pData
->maPos
= ScAddress(nCol
, nRow
, nTab
);
661 Point aPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
664 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
665 Rectangle
aCellRect(OutputToScreenPixel(aPos
), Size(nSizeX
, nSizeY
));
667 ScDBData
* pDBData
= pDoc
->GetDBAtCursor(nCol
, nRow
, nTab
);
671 pData
->mpData
= pDBData
;
672 mpAutoFilterPopup
->setExtendedData(pData
.release());
675 pDBData
->GetQueryParam(aParam
);
676 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(nCol
, false);
677 boost::unordered_set
<rtl::OUString
, rtl::OUStringHash
> aSelected
;
678 if (pEntry
&& pEntry
->bDoQuery
)
680 if (pEntry
->eOp
== SC_EQUAL
)
682 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
683 std::for_each(rItems
.begin(), rItems
.end(), AddSelectedItemString(aSelected
));
687 // Populate the check box list.
688 bool bHasDates
= false;
689 std::vector
<ScTypedStrData
> aStrings
;
690 pDoc
->GetFilterEntries(nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
692 mpAutoFilterPopup
->setMemberSize(aStrings
.size());
693 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
694 for (; it
!= itEnd
; ++it
)
696 const rtl::OUString
& aVal
= it
->GetString();
697 bool bSelected
= true;
698 if (!aSelected
.empty())
699 bSelected
= aSelected
.count(aVal
) > 0;
700 mpAutoFilterPopup
->addMember(aVal
, bSelected
);
702 mpAutoFilterPopup
->initMembers();
704 // Populate the menu.
705 mpAutoFilterPopup
->addMenuItem(
706 ScRscStrLoader(RID_POPUP_FILTER
, STR_MENU_SORT_ASC
).GetString(),
707 true, new AutoFilterAction(this, SortAscending
));
708 mpAutoFilterPopup
->addMenuItem(
709 ScRscStrLoader(RID_POPUP_FILTER
, STR_MENU_SORT_DESC
).GetString(),
710 true, new AutoFilterAction(this, SortDescending
));
711 mpAutoFilterPopup
->addSeparator();
712 mpAutoFilterPopup
->addMenuItem(
713 SC_RESSTR(SCSTR_TOP10FILTER
), true, new AutoFilterAction(this, Top10
));
714 mpAutoFilterPopup
->addMenuItem(
715 SC_RESSTR(SCSTR_FILTER_EMPTY
), true, new AutoFilterAction(this, Empty
));
716 mpAutoFilterPopup
->addMenuItem(
717 SC_RESSTR(SCSTR_FILTER_NOTEMPTY
), true, new AutoFilterAction(this, NonEmpty
));
718 mpAutoFilterPopup
->addSeparator();
719 mpAutoFilterPopup
->addMenuItem(
720 SC_RESSTR(SCSTR_STDFILTER
), true, new AutoFilterAction(this, Custom
));
722 ScCheckListMenuWindow::Config aConfig
;
723 aConfig
.mbAllowEmptySet
= false;
724 aConfig
.mbRTL
= pViewData
->GetDocument()->IsLayoutRTL(pViewData
->GetTabNo());
725 mpAutoFilterPopup
->setConfig(aConfig
);
726 mpAutoFilterPopup
->launch(aCellRect
);
729 void ScGridWindow::RefreshAutoFilterButton(const ScAddress
& rPos
)
733 bool bFilterActive
= IsAutoFilterActive(rPos
.Col(), rPos
.Row(), rPos
.Tab());
734 mpFilterButton
->setHasHiddenMember(bFilterActive
);
735 mpFilterButton
->setPopupPressed(false);
736 mpFilterButton
->draw();
740 void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode
)
742 const AutoFilterData
* pData
=
743 static_cast<const AutoFilterData
*>(mpAutoFilterPopup
->getExtendedData());
748 const ScAddress
& rPos
= pData
->maPos
;
749 ScDBData
* pDBData
= pData
->mpData
;
758 ScDocument
* pDoc
= pViewData
->GetDocument();
759 SCTAB nTab
= pViewData
->GetTabNo();
760 SCCOL nCol
= rPos
.Col();
761 ScSortParam aSortParam
;
762 pDBData
->GetSortParam(aSortParam
);
763 if (nCol
< aSortParam
.nCol1
|| nCol
> aSortParam
.nCol2
)
767 bool bHasHeader
= pDoc
->HasColHeader(
768 aSortParam
.nCol1
, aSortParam
.nRow1
, aSortParam
.nCol2
, aSortParam
.nRow2
, nTab
);
770 aSortParam
.bHasHeader
= bHasHeader
;
771 aSortParam
.bByRow
= true;
772 aSortParam
.bCaseSens
= false;
773 aSortParam
.bNaturalSort
= false;
774 aSortParam
.bIncludePattern
= true;
775 aSortParam
.bInplace
= true;
776 aSortParam
.maKeyState
[0].bDoSort
= true;
777 aSortParam
.maKeyState
[0].nField
= nCol
;
778 aSortParam
.maKeyState
[0].bAscending
= (eMode
== SortAscending
);
780 for (size_t i
= 1; i
< aSortParam
.GetSortKeyCount(); ++i
)
781 aSortParam
.maKeyState
[i
].bDoSort
= false;
783 pViewData
->GetViewShell()->UISort(aSortParam
);
793 pDBData
->GetArea(aRange
);
794 pViewData
->GetView()->MarkRange(aRange
);
795 pViewData
->GetView()->SetCursor(rPos
.Col(), rPos
.Row());
796 pViewData
->GetDispatcher().Execute(SID_FILTER
, SFX_CALLMODE_SLOT
|SFX_CALLMODE_RECORD
);
801 pDBData
->GetQueryParam(aParam
);
803 if (eMode
== Normal
&& mpAutoFilterPopup
->isAllSelected())
805 // Remove this entry.
806 aParam
.RemoveEntryByField(rPos
.Col());
810 // Try to use the existing entry for the column (if one exists).
811 ScQueryEntry
* pEntry
= aParam
.FindEntryByField(rPos
.Col(), true);
814 // Something went terribly wrong!
817 pEntry
->bDoQuery
= true;
818 pEntry
->nField
= rPos
.Col();
819 pEntry
->eConnect
= SC_AND
;
825 pEntry
->eOp
= SC_EQUAL
;
827 ScCheckListMenuWindow::ResultType aResult
;
828 mpAutoFilterPopup
->getResult(aResult
);
829 std::vector
<rtl::OUString
> aSelected
;
830 ScCheckListMenuWindow::ResultType::const_iterator itr
= aResult
.begin(), itrEnd
= aResult
.end();
831 for (; itr
!= itrEnd
; ++itr
)
834 aSelected
.push_back(itr
->first
);
837 ScQueryEntry::QueryItemsType
& rItems
= pEntry
->GetQueryItems();
839 std::for_each(aSelected
.begin(), aSelected
.end(), AddItemToEntry(rItems
));
843 pEntry
->eOp
= SC_TOPVAL
;
844 pEntry
->GetQueryItem().meType
= ScQueryEntry::ByString
;
845 pEntry
->GetQueryItem().maString
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("10"));
848 pEntry
->SetQueryByEmpty();
851 pEntry
->SetQueryByNonEmpty();
854 // We don't know how to handle this!
859 pViewData
->GetView()->Query(aParam
, NULL
, true);
860 pDBData
->SetQueryParam(aParam
);
865 void getCellGeometry(Point
& rScrPos
, Size
& rScrSize
, const ScViewData
* pViewData
, SCCOL nCol
, SCROW nRow
, ScSplitPos eWhich
)
867 // Get the screen position of the cell.
868 rScrPos
= pViewData
->GetScrPos(nCol
, nRow
, eWhich
);
870 // Get the screen size of the cell.
872 pViewData
->GetMergeSizePixel(nCol
, nRow
, nSizeX
, nSizeY
);
873 rScrSize
= Size(nSizeX
-1, nSizeY
-1);
878 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol
, SCROW nRow
)
881 // We assume that the page field button is located in cell to the immediate left.
884 SCTAB nTab
= pViewData
->GetTabNo();
885 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
891 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
892 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
-1, nRow
, nTab
), pDPObj
);
895 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol
, SCROW nRow
)
897 SCTAB nTab
= pViewData
->GetTabNo();
898 ScDPObject
* pDPObj
= pViewData
->GetDocument()->GetDPAtCursor(nCol
, nRow
, nTab
);
904 getCellGeometry(aScrPos
, aScrSize
, pViewData
, nCol
, nRow
, eWhich
);
905 DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos
), aScrSize
, ScAddress(nCol
, nRow
, nTab
), pDPObj
);
908 void ScGridWindow::DoScenarioMenue( const ScRange
& rScenRange
)
913 SCCOL nCol
= rScenRange
.aEnd
.Col(); // Zelle unterhalb des Buttons
914 SCROW nRow
= rScenRange
.aStart
.Row();
917 nRow
= rScenRange
.aEnd
.Row() + 1; // Bereich ganz oben -> Button unterhalb
918 if (nRow
>MAXROW
) nRow
= MAXROW
;
919 //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
922 ScDocument
* pDoc
= pViewData
->GetDocument();
923 SCTAB nTab
= pViewData
->GetTabNo();
924 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
929 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
930 // The button height should not use the merged cell height, should still use single row height
931 nSizeY
= pViewData
->ToPixel(pDoc
->GetRowHeight(nRow
, nTab
), pViewData
->GetPPTY());
932 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
935 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
936 aCellRect
.Top() -= nSizeY
;
937 aCellRect
.Bottom() -= nSizeY
- 1;
938 // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
939 // (wenn die Linie verdeckt wird, sieht es komisch aus...)
941 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
942 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
943 pFilterBox
= new ScFilterListBox( pFilterFloat
, this, nCol
, nRow
, SC_FILTERBOX_SCENARIO
);
945 pFilterBox
->EnableMirroring();
950 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
951 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
953 nHeight
= GetTextHeight();
954 nHeight
*= SC_FILTERLISTBOX_LINES
;
956 SetMapMode( aOldMode
);
962 // ParentSize Abfrage fehlt
963 Size
aSize( nSizeX
, nHeight
);
964 pFilterBox
->SetSizePixel( aSize
);
965 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
966 pFilterBox
->SetUpdateMode(false);
968 // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
973 rtl::OUString aCurrent
;
974 rtl::OUString aTabName
;
975 SCTAB nTabCount
= pDoc
->GetTableCount();
976 SCTAB nEntryCount
= 0;
977 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
979 if (pDoc
->HasScenarioRange( i
, rScenRange
))
980 if (pDoc
->GetName( i
, aTabName
))
982 pFilterBox
->InsertEntry( aTabName
);
983 if (pDoc
->IsActiveScenario(i
))
985 long nTextWidth
= pFilterBox
->GetTextWidth( aTabName
);
986 if ( nTextWidth
> nMaxText
)
987 nMaxText
= nTextWidth
;
991 if (nEntryCount
> SC_FILTERLISTBOX_LINES
)
992 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
993 nMaxText
+= 4; // fuer Rand
994 if ( nMaxText
> 300 )
995 nMaxText
= 300; // auch nicht uebertreiben (Pixel)
997 if (nMaxText
> nSizeX
) // Groesse auf benoetigte Groesse anpassen
999 long nDiff
= nMaxText
- nSizeX
;
1000 aSize
= Size( nMaxText
, nHeight
);
1001 pFilterBox
->SetSizePixel( aSize
);
1002 pFilterFloat
->SetOutputSizePixel( aSize
);
1006 // also move popup position
1007 long nNewX
= aCellRect
.Left() - nDiff
;
1010 aCellRect
.Left() = nNewX
;
1014 pFilterFloat
->SetOutputSizePixel( aSize
);
1015 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1017 pFilterBox
->SetUpdateMode(sal_True
);
1018 pFilterBox
->GrabFocus();
1020 sal_uInt16 nPos
= LISTBOX_ENTRY_NOTFOUND
;
1021 if (!aCurrent
.isEmpty())
1023 nPos
= pFilterBox
->GetEntryPos(String(aCurrent
));
1025 if (LISTBOX_ENTRY_NOTFOUND
== nPos
&& pFilterBox
->GetEntryCount() > 0 )
1027 if (LISTBOX_ENTRY_NOTFOUND
!= nPos
)
1028 pFilterBox
->SelectEntryPos(nPos
);
1030 pFilterBox
->EndInit();
1032 // Szenario-Auswahl kommt aus MouseButtonDown:
1033 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1035 nMouseStatus
= SC_GM_FILTER
;
1039 void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol
, SCROW nRow
, bool bDataSelect
)
1042 delete pFilterFloat
;
1045 ScDocument
* pDoc
= pViewData
->GetDocument();
1046 SCTAB nTab
= pViewData
->GetTabNo();
1047 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1052 pViewData
->GetMergeSizePixel( nCol
, nRow
, nSizeX
, nSizeY
);
1053 Point aPos
= pViewData
->GetScrPos( nCol
, nRow
, eWhich
);
1057 Rectangle
aCellRect( OutputToScreenPixel(aPos
), Size(nSizeX
,nSizeY
) );
1060 aPos
.Y() += nSizeY
- 1;
1062 pFilterFloat
= new ScFilterFloatingWindow( this, WinBits(WB_BORDER
) ); // nicht resizable etc.
1063 pFilterFloat
->SetPopupModeEndHdl( LINK( this, ScGridWindow
, PopupModeEndHdl
) );
1064 pFilterBox
= new ScFilterListBox(
1065 pFilterFloat
, this, nCol
, nRow
, bDataSelect
? SC_FILTERBOX_DATASELECT
: SC_FILTERBOX_FILTER
);
1066 // Fix for bug fdo#44925
1067 if (Application::GetSettings().GetLayoutRTL() != bLayoutRTL
)
1068 pFilterBox
->EnableMirroring();
1073 Font aOldFont
= GetFont(); SetFont( pFilterBox
->GetFont() );
1074 MapMode aOldMode
= GetMapMode(); SetMapMode( MAP_PIXEL
);
1076 nHeight
= GetTextHeight();
1077 nHeight
*= SC_FILTERLISTBOX_LINES
;
1079 SetMapMode( aOldMode
);
1080 SetFont( aOldFont
);
1085 bool bEmpty
= false;
1086 std::vector
<ScTypedStrData
> aStrings
; // case sensitive
1087 if ( bDataSelect
) // Auswahl-Liste
1090 pDoc
->GetDataEntries(nCol
, nRow
, nTab
, true, aStrings
);
1091 if (aStrings
.empty())
1096 //! wird der Titel ueberhaupt ausgewertet ???
1098 pDoc
->GetString( nCol
, nRow
, nTab
, aString
);
1099 pFilterBox
->SetText( aString
);
1104 static const sal_uInt16 nDefIDs
[] = { SCSTR_TOP10FILTER
, SCSTR_STDFILTER
, SCSTR_FILTER_EMPTY
, SCSTR_FILTER_NOTEMPTY
};
1105 const size_t nDefCount
= SAL_N_ELEMENTS(nDefIDs
);
1106 for (i
=0; i
<nDefCount
; i
++)
1108 String
aEntry( (ScResId
) nDefIDs
[i
] );
1109 pFilterBox
->InsertEntry( aEntry
);
1110 long nTextWidth
= pFilterBox
->GetTextWidth( aEntry
);
1111 if ( nTextWidth
> nMaxText
)
1112 nMaxText
= nTextWidth
;
1114 pFilterBox
->SetSeparatorPos( nDefCount
- 1 );
1117 bool bHasDates
= false;
1118 pDoc
->GetFilterEntries( nCol
, nRow
, nTab
, true, aStrings
, bHasDates
);
1119 pFilterBox
->SetListHasDates(bHasDates
);
1121 // check widths of numerical entries (string entries are not included)
1122 // so all numbers are completely visible
1123 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1124 for (; it
!= itEnd
; ++it
)
1126 if (!it
->IsStrData()) // only numerical entries
1128 long nTextWidth
= pFilterBox
->GetTextWidth(it
->GetString());
1129 if ( nTextWidth
> nMaxText
)
1130 nMaxText
= nTextWidth
;
1134 // add scrollbar width if needed (string entries are counted here)
1135 // (scrollbar is shown if the box is exactly full?)
1136 if (aStrings
.size() + nDefCount
>= SC_FILTERLISTBOX_LINES
)
1137 nMaxText
+= GetSettings().GetStyleSettings().GetScrollBarSize();
1139 nMaxText
+= 4; // for borders
1141 if ( nMaxText
> nSizeX
)
1142 nSizeX
= nMaxText
; // just modify width - starting position is unchanged
1147 // Position und Groesse an Fenster anpassen
1148 //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
1150 Size aParentSize
= GetParent()->GetOutputSizePixel();
1151 Size
aSize( nSizeX
, nHeight
);
1153 if ( aSize
.Height() > aParentSize
.Height() )
1154 aSize
.Height() = aParentSize
.Height();
1155 if ( aPos
.Y() + aSize
.Height() > aParentSize
.Height() )
1156 aPos
.Y() = aParentSize
.Height() - aSize
.Height();
1158 pFilterBox
->SetSizePixel( aSize
);
1159 pFilterBox
->Show(); // Show muss vor SetUpdateMode kommen !!!
1160 pFilterBox
->SetUpdateMode(false);
1162 pFilterFloat
->SetOutputSizePixel( aSize
);
1163 pFilterFloat
->StartPopupMode( aCellRect
, FLOATWIN_POPUPMODE_DOWN
|FLOATWIN_POPUPMODE_GRABFOCUS
);
1166 bool bWait
= aStrings
.size() > 100;
1171 std::vector
<ScTypedStrData
>::const_iterator it
= aStrings
.begin(), itEnd
= aStrings
.end();
1172 for (; it
!= itEnd
; ++it
)
1173 pFilterBox
->InsertEntry(it
->GetString());
1178 pFilterBox
->SetUpdateMode(true);
1181 sal_uInt16 nSelPos
= LISTBOX_ENTRY_NOTFOUND
;
1183 if (!bDataSelect
) // AutoFilter: aktiven Eintrag selektieren
1185 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1188 ScQueryParam aParam
;
1189 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1191 sal_Bool bValid
= sal_True
;
1192 SCSIZE nCount
= aParam
.GetEntryCount();
1193 for (SCSIZE j
= 0; j
< nCount
&& bValid
; ++j
) // bisherige Filter-Einstellungen
1194 if (aParam
.GetEntry(j
).bDoQuery
)
1196 //! Abfrage mit DrawButtons zusammenfassen!
1198 ScQueryEntry
& rEntry
= aParam
.GetEntry(j
);
1200 if (rEntry
.eConnect
!= SC_AND
)
1202 if (rEntry
.nField
== nCol
)
1204 const rtl::OUString
& rQueryStr
= rEntry
.GetQueryItem().maString
;
1205 if (rEntry
.eOp
== SC_EQUAL
)
1207 if (!rQueryStr
.isEmpty())
1209 nSelPos
= pFilterBox
->GetEntryPos(rQueryStr
);
1212 else if ( rEntry
.eOp
== SC_TOPVAL
&& rQueryStr
== "10" )
1213 nSelPos
= SC_AUTOFILTER_TOP10
;
1215 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1220 nSelPos
= SC_AUTOFILTER_CUSTOM
;
1226 sal_uLong nIndex
= ((SfxUInt32Item
*)pDoc
->GetAttr(
1227 nCol
, nRow
, nTab
, ATTR_VALIDDATA
))->GetValue();
1230 const ScValidationData
* pData
= pDoc
->GetValidationEntry( nIndex
);
1233 ScTypedStrData
* pNew
= NULL
;
1234 rtl::OUString aDocStr
;
1235 pDoc
->GetString( nCol
, nRow
, nTab
, aDocStr
);
1236 if ( pDoc
->HasValueData( nCol
, nRow
, nTab
) )
1238 double fVal
= pDoc
->GetValue(ScAddress(nCol
, nRow
, nTab
));
1239 pNew
= new ScTypedStrData(aDocStr
, fVal
, ScTypedStrData::Value
);
1242 pNew
= new ScTypedStrData(aDocStr
, 0.0, ScTypedStrData::Standard
);
1244 bool bSortList
= ( pData
->GetListType() == ValidListType::SORTEDASCENDING
);
1247 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1248 std::vector
<ScTypedStrData
>::const_iterator it
=
1249 std::find_if(itBeg
, itEnd
, FindTypedStrData(*pNew
, true));
1252 nSelPos
= std::distance(itBeg
, it
);
1256 ScTypedStrData::EqualCaseSensitive aHdl
;
1257 std::vector
<ScTypedStrData
>::const_iterator itBeg
= aStrings
.begin(), itEnd
= aStrings
.end();
1258 std::vector
<ScTypedStrData
>::const_iterator it
= itBeg
;
1259 for (; it
!= itEnd
&& LISTBOX_ENTRY_NOTFOUND
== nSelPos
; ++it
)
1261 if (aHdl(*it
, *pNew
))
1262 nSelPos
= std::distance(itBeg
, it
);
1270 // neu (309): irgendwas muss immer selektiert sein:
1271 if ( LISTBOX_ENTRY_NOTFOUND
== nSelPos
&& pFilterBox
->GetEntryCount() > 0 && !bDataSelect
)
1274 // keine leere Auswahl-Liste anzeigen:
1278 DELETEZ(pFilterBox
); // war nix
1279 DELETEZ(pFilterFloat
);
1283 pFilterBox
->GrabFocus();
1285 // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1286 if ( LISTBOX_ENTRY_NOTFOUND
!= nSelPos
)
1287 pFilterBox
->SelectEntryPos( nSelPos
);
1291 pFilterBox
->SetNoSelection();
1294 pFilterBox
->EndInit();
1298 // AutoFilter (aus MouseButtonDown):
1299 // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1301 nMouseStatus
= SC_GM_FILTER
;
1307 void ScGridWindow::FilterSelect( sal_uLong nSel
)
1309 String aString
= pFilterBox
->GetEntry( static_cast< sal_uInt16
>( nSel
) );
1311 SCCOL nCol
= pFilterBox
->GetCol();
1312 SCROW nRow
= pFilterBox
->GetRow();
1313 switch ( pFilterBox
->GetMode() )
1315 case SC_FILTERBOX_DATASELECT
:
1316 ExecDataSelect( nCol
, nRow
, aString
);
1318 case SC_FILTERBOX_FILTER
:
1319 ExecFilter( nSel
, nCol
, nRow
, aString
, pFilterBox
->HasDates() );
1321 case SC_FILTERBOX_SCENARIO
:
1322 pViewData
->GetView()->UseScenario( aString
);
1324 case SC_FILTERBOX_PAGEFIELD
:
1325 // first entry is "all"
1326 ExecPageFieldSelect( nCol
, nRow
, (nSel
!= 0), aString
);
1331 pFilterFloat
->EndPopupMode();
1333 GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
1336 void ScGridWindow::ExecDataSelect( SCCOL nCol
, SCROW nRow
, const String
& rStr
)
1340 SCTAB nTab
= pViewData
->GetTabNo();
1341 ScViewFunc
* pView
= pViewData
->GetView();
1342 pView
->EnterData( nCol
, nRow
, nTab
, rStr
);
1344 // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1345 // if the cursor is moved afterwards.
1346 pView
->CellContentChanged();
1350 void ScGridWindow::ExecFilter( sal_uLong nSel
,
1351 SCCOL nCol
, SCROW nRow
,
1352 const String
& aValue
, bool bCheckForDates
)
1354 SCTAB nTab
= pViewData
->GetTabNo();
1355 ScDocument
* pDoc
= pViewData
->GetDocument();
1357 ScDBData
* pDBData
= pDoc
->GetDBAtCursor( nCol
, nRow
, nTab
);
1360 ScQueryParam aParam
;
1361 pDBData
->GetQueryParam( aParam
); // kann nur MAXQUERY Eintraege ergeben
1363 if (SC_AUTOFILTER_CUSTOM
== nSel
)
1370 pDBData
->GetArea( nAreaTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
);
1371 pViewData
->GetView()->MarkRange( ScRange( nStartCol
,nStartRow
,nAreaTab
,nEndCol
,nEndRow
,nAreaTab
));
1372 pViewData
->GetView()->SetCursor(nCol
,nRow
); //! auch ueber Slot ??
1373 pViewData
->GetDispatcher().Execute( SID_FILTER
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
1377 sal_Bool bDeleteOld
= false;
1378 SCSIZE nQueryPos
= 0;
1379 sal_Bool bFound
= false;
1380 if (!aParam
.bInplace
)
1381 bDeleteOld
= sal_True
;
1383 bDeleteOld
= sal_True
;
1384 SCSIZE nCount
= aParam
.GetEntryCount();
1385 for (SCSIZE i
= 0; i
< nCount
&& !bDeleteOld
; ++i
) // bisherige Filter-Einstellungen
1386 if (aParam
.GetEntry(i
).bDoQuery
)
1388 //! Abfrage mit DrawButtons zusammenfassen!
1390 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1392 if (rEntry
.eConnect
!= SC_AND
)
1393 bDeleteOld
= sal_True
;
1395 if (rEntry
.nField
== nCol
)
1397 if (bFound
) // diese Spalte zweimal?
1398 bDeleteOld
= sal_True
;
1408 SCSIZE nEC
= aParam
.GetEntryCount();
1409 for (SCSIZE i
=0; i
<nEC
; i
++)
1410 aParam
.GetEntry(i
).Clear();
1412 aParam
.bInplace
= sal_True
;
1413 aParam
.bRegExp
= false;
1416 if ( nQueryPos
< nCount
|| SC_AUTOFILTER_ALL
== nSel
) // loeschen geht immer
1420 ScQueryEntry
& rNewEntry
= aParam
.GetEntry(nQueryPos
);
1421 ScQueryEntry::Item
& rItem
= rNewEntry
.GetQueryItem();
1422 rNewEntry
.bDoQuery
= true;
1423 rNewEntry
.nField
= nCol
;
1424 rItem
.meType
= bCheckForDates
? ScQueryEntry::ByDate
: ScQueryEntry::ByString
;
1426 if ( nSel
== SC_AUTOFILTER_TOP10
)
1428 rNewEntry
.eOp
= SC_TOPVAL
;
1429 rItem
.maString
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("10"));
1431 else if (nSel
== SC_AUTOFILTER_EMPTY
)
1433 rNewEntry
.SetQueryByEmpty();
1435 else if (nSel
== SC_AUTOFILTER_NOTEMPTY
)
1437 rNewEntry
.SetQueryByNonEmpty();
1441 rNewEntry
.eOp
= SC_EQUAL
;
1442 rItem
.maString
= aValue
;
1445 rNewEntry
.eConnect
= SC_AND
;
1450 aParam
.RemoveEntryByField(nCol
);
1453 // end edit mode - like in ScCellShell::ExecuteDB
1454 if ( pViewData
->HasEditView( pViewData
->GetActivePart() ) )
1456 SC_MOD()->InputEnterHandler();
1457 pViewData
->GetViewShell()->UpdateInputHandler();
1460 pViewData
->GetView()->Query( aParam
, NULL
, true );
1461 pDBData
->SetQueryParam( aParam
); // speichern
1463 else // "Zuviele Bedingungen"
1464 pViewData
->GetView()->ErrorMessage( STR_FILTER_TOOMANY
);
1469 OSL_FAIL("Wo ist der Datenbankbereich?");
1473 void ScGridWindow::SetPointer( const Pointer
& rPointer
)
1475 nCurrentPointer
= 0;
1476 Window::SetPointer( rPointer
);
1479 void ScGridWindow::MoveMouseStatus( ScGridWindow
& rDestWin
)
1483 rDestWin
.nButtonDown
= nButtonDown
;
1484 rDestWin
.nMouseStatus
= nMouseStatus
;
1489 rDestWin
.bRFMouse
= bRFMouse
;
1490 rDestWin
.bRFSize
= bRFSize
;
1491 rDestWin
.nRFIndex
= nRFIndex
;
1492 rDestWin
.nRFAddX
= nRFAddX
;
1493 rDestWin
.nRFAddY
= nRFAddY
;
1497 if (nPagebreakMouse
)
1499 rDestWin
.nPagebreakMouse
= nPagebreakMouse
;
1500 rDestWin
.nPagebreakBreak
= nPagebreakBreak
;
1501 rDestWin
.nPagebreakPrev
= nPagebreakPrev
;
1502 rDestWin
.aPagebreakSource
= aPagebreakSource
;
1503 rDestWin
.aPagebreakDrag
= aPagebreakDrag
;
1504 nPagebreakMouse
= SC_PD_NONE
;
1508 bool ScGridWindow::TestMouse( const MouseEvent
& rMEvt
, bool bAction
)
1510 // MouseEvent buttons must only be checked if bAction==TRUE
1511 // to allow changing the mouse pointer in MouseMove,
1512 // but not start AutoFill with right button (#74229#).
1513 // with bAction==sal_True, SetFillMode / SetDragMode is called
1515 if ( bAction
&& !rMEvt
.IsLeft() )
1518 bool bNewPointer
= false;
1520 SfxInPlaceClient
* pClient
= pViewData
->GetViewShell()->GetIPClient();
1521 bool bOleActive
= ( pClient
&& pClient
->IsObjectInPlaceActive() );
1523 if ( pViewData
->IsActive() && !bOleActive
)
1525 ScDocument
* pDoc
= pViewData
->GetDocument();
1526 SCTAB nTab
= pViewData
->GetTabNo();
1527 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
1532 if (pViewData
->GetSimpleArea( aMarkRange
) == SC_MARK_SIMPLE
)
1534 if (aMarkRange
.aStart
.Tab() == pViewData
->GetTabNo() && mpAutoFillRect
)
1536 Point aMousePos
= rMEvt
.GetPosPixel();
1537 if (mpAutoFillRect
->IsInside(aMousePos
))
1539 SetPointer( Pointer( POINTER_CROSS
) ); //! dickeres Kreuz ?
1542 SCCOL nX
= aMarkRange
.aEnd
.Col();
1543 SCROW nY
= aMarkRange
.aEnd
.Row();
1545 if ( lcl_IsEditableMatrix( pViewData
->GetDocument(), aMarkRange
) )
1546 pViewData
->SetDragMode(
1547 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
, SC_FILL_MATRIX
);
1549 pViewData
->SetFillMode(
1550 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nX
, nY
);
1552 // The simple selection must also be recognized when dragging,
1553 // where the Marking flag is set and MarkToSimple won't work anymore.
1554 pViewData
->GetMarkData().MarkToSimple();
1561 // Embedded-Rechteck
1563 if (pDoc
->IsEmbedded())
1566 pDoc
->GetEmbedded( aRange
);
1567 if ( pViewData
->GetTabNo() == aRange
.aStart
.Tab() )
1569 Point aStartPos
= pViewData
->GetScrPos( aRange
.aStart
.Col(), aRange
.aStart
.Row(), eWhich
);
1570 Point aEndPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1, eWhich
);
1571 Point aMousePos
= rMEvt
.GetPosPixel();
1577 bool bTop
= ( aMousePos
.X() >= aStartPos
.X()-3 && aMousePos
.X() <= aStartPos
.X()+1 &&
1578 aMousePos
.Y() >= aStartPos
.Y()-3 && aMousePos
.Y() <= aStartPos
.Y()+1 );
1579 bool bBottom
= ( aMousePos
.X() >= aEndPos
.X()-3 && aMousePos
.X() <= aEndPos
.X()+1 &&
1580 aMousePos
.Y() >= aEndPos
.Y()-3 && aMousePos
.Y() <= aEndPos
.Y()+1 );
1581 if ( bTop
|| bBottom
)
1583 SetPointer( Pointer( POINTER_CROSS
) );
1586 sal_uInt8 nMode
= bTop
? SC_FILL_EMBED_LT
: SC_FILL_EMBED_RB
;
1587 pViewData
->SetDragMode(
1588 aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1589 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), nMode
);
1597 if (!bNewPointer
&& bAction
)
1599 pViewData
->ResetFillMode();
1605 void ScGridWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
1607 nNestedButtonState
= SC_NESTEDBUTTON_DOWN
;
1609 MouseEventState aState
;
1610 HandleMouseButtonDown(rMEvt
, aState
);
1611 if (aState
.mbActivatePart
)
1612 pViewData
->GetView()->ActivatePart(eWhich
);
1614 if ( nNestedButtonState
== SC_NESTEDBUTTON_UP
)
1616 // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1617 // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1618 // simulate another MouseButtonUp call, so the selection state is consistent.
1620 nButtonDown
= rMEvt
.GetButtons();
1624 EndTracking(); // normally done in VCL as part of MouseButtonUp handling
1626 nNestedButtonState
= SC_NESTEDBUTTON_NONE
;
1629 void ScGridWindow::HandleMouseButtonDown( const MouseEvent
& rMEvt
, MouseEventState
& rState
)
1631 // We have to check if a context menu is shown and we have an UI
1632 // active inplace client. In that case we have to ignore the event.
1633 // Otherwise we would crash (context menu has been
1634 // opened by inplace client and we would deactivate the inplace client,
1635 // the contex menu is closed by VCL asynchronously which in the end
1636 // would work on deleted objects or the context menu has no parent anymore)
1637 SfxViewShell
* pViewSh
= pViewData
->GetViewShell();
1638 SfxInPlaceClient
* pClient
= pViewSh
->GetIPClient();
1640 pClient
->IsObjectInPlaceActive() &&
1641 PopupMenu::IsInExecute() )
1644 aCurMousePos
= rMEvt
.GetPosPixel();
1646 // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1647 // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1648 ClickExtern(); // loescht FilterBox, wenn vorhanden
1650 HideNoteMarker(); // Notiz-Anzeige
1654 ScModule
* pScMod
= SC_MOD();
1655 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1658 pScActiveViewShell
= pViewData
->GetViewShell(); // falls auf Link geklickt wird
1659 nScClickMouseModifier
= rMEvt
.GetModifier(); // um Control-Klick immer zu erkennen
1661 sal_Bool bDetective
= pViewData
->GetViewShell()->IsAuditShell();
1662 sal_Bool bRefMode
= pViewData
->IsRefMode(); // Referenz angefangen
1663 sal_Bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
1664 sal_Bool bEditMode
= pViewData
->HasEditView(eWhich
); // auch bei Mode==SC_INPUT_TYPE
1665 sal_Bool bDouble
= (rMEvt
.GetClicks() == 2);
1667 // DeactivateIP passiert nur noch bei MarkListHasChanged
1669 // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1670 // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1672 if ( !nButtonDown
|| !bDouble
) // single (first) click is always valid
1673 nButtonDown
= rMEvt
.GetButtons(); // set nButtonDown first, so StopMarking works
1675 if ( ( bEditMode
&& pViewData
->GetActivePart() == eWhich
) || !bFormulaMode
)
1678 // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1679 // but a single (first) click is always valid
1680 if ( nMouseStatus
== SC_GM_IGNORE
&& bDouble
)
1683 nMouseStatus
= SC_GM_NONE
;
1687 if ( bDetective
) // Detektiv-Fuell-Modus
1689 if ( rMEvt
.IsLeft() && !rMEvt
.GetModifier() )
1691 Point aPos
= rMEvt
.GetPosPixel();
1694 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1696 SfxInt16Item
aPosXItem( SID_RANGE_COL
, nPosX
);
1697 SfxInt32Item
aPosYItem( SID_RANGE_ROW
, nPosY
);
1698 pViewData
->GetDispatcher().Execute( SID_FILL_SELECT
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
1699 &aPosXItem
, &aPosYItem
, (void*)0L );
1703 nMouseStatus
= SC_GM_NONE
;
1708 nMouseStatus
= SC_GM_NONE
;
1710 rState
.mbActivatePart
= !bFormulaMode
; // Don't activate when in formula mode.
1714 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1715 pSelEng
->SetWindow(this);
1716 pSelEng
->SetWhich(eWhich
);
1717 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1720 if (bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()))
1722 Point aPos
= rMEvt
.GetPosPixel();
1725 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1727 EditView
* pEditView
;
1730 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1731 SCCOL nEndCol
= pViewData
->GetEditEndCol();
1732 SCROW nEndRow
= pViewData
->GetEditEndRow();
1734 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
1735 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
1737 // beim Klick in die Tabellen-EditView immer den Focus umsetzen
1738 if (bFormulaMode
) // sonst ist es oben schon passiert
1741 pScMod
->SetInputMode( SC_INPUT_TABLE
);
1743 bEditMode
= pEditView
->MouseButtonDown( rMEvt
);
1748 if (pScMod
->GetIsWaterCan())
1750 //! was is mit'm Mac ???
1751 if ( rMEvt
.GetModifier() + rMEvt
.GetButtons() == MOUSE_RIGHT
)
1753 nMouseStatus
= SC_GM_WATERUNDO
;
1758 // Reihenfolge passend zum angezeigten Cursor:
1759 // RangeFinder, AutoFill, PageBreak, Drawing
1762 bool bFound
= HitRangeFinder(rMEvt
.GetPosPixel(), bCorner
, &nRFIndex
, &nRFAddX
, &nRFAddY
);
1766 bRFMouse
= true; // die anderen Variablen sind oben initialisiert
1768 rState
.mbActivatePart
= true; // always activate ?
1773 sal_Bool bCrossPointer
= TestMouse( rMEvt
, sal_True
);
1774 if ( bCrossPointer
)
1777 pViewData
->GetView()->FillCrossDblClick();
1779 pScMod
->InputEnterHandler(); // Autofill etc.
1782 if ( !bCrossPointer
)
1784 nPagebreakMouse
= HitPageBreak( rMEvt
.GetPosPixel(), &aPagebreakSource
,
1785 &nPagebreakBreak
, &nPagebreakPrev
);
1786 if (nPagebreakMouse
)
1788 bPagebreakDrawn
= false;
1790 PagebreakMove( rMEvt
, false );
1795 if (!bFormulaMode
&& !bEditMode
&& rMEvt
.IsLeft())
1797 if ( !bCrossPointer
&& DrawMouseButtonDown(rMEvt
) )
1802 pViewData
->GetViewShell()->SetDrawShell( false ); // kein Draw-Objekt selektiert
1804 // TestMouse schon oben passiert
1807 Point aPos
= rMEvt
.GetPosPixel();
1810 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
1811 SCTAB nTab
= pViewData
->GetTabNo();
1812 ScDocument
* pDoc
= pViewData
->GetDocument();
1814 // Auto filter / pivot table / data select popup. This shouldn't activate the part.
1816 if ( !bDouble
&& !bFormulaMode
&& rMEvt
.IsLeft() )
1820 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nRealPosX
, nRealPosY
, false );//the real row/col
1821 ScMergeFlagAttr
* pRealPosAttr
= (ScMergeFlagAttr
*)
1822 pDoc
->GetAttr( nRealPosX
, nRealPosY
, nTab
, ATTR_MERGE_FLAG
);
1823 ScMergeFlagAttr
* pAttr
= (ScMergeFlagAttr
*)
1824 pDoc
->GetAttr( nPosX
, nPosY
, nTab
, ATTR_MERGE_FLAG
);
1825 if( pRealPosAttr
->HasAutoFilter() )
1827 SC_MOD()->InputEnterHandler();
1828 if (DoAutoFilterButton( nRealPosX
, nRealPosY
, rMEvt
))
1831 if (pAttr
->HasAutoFilter())
1833 if (DoAutoFilterButton(nPosX
, nPosY
, rMEvt
))
1835 rState
.mbActivatePart
= false;
1840 if (pAttr
->HasPivotButton() || pAttr
->HasPivotPopupButton())
1842 DoPushPivotButton(nPosX
, nPosY
, rMEvt
, pAttr
->HasPivotButton(), pAttr
->HasPivotPopupButton());
1843 rState
.mbActivatePart
= false;
1847 // List Validity drop-down button
1849 if ( bListValButton
)
1851 Rectangle aButtonRect
= GetListValButtonRect( aListValPos
);
1852 if ( aButtonRect
.IsInside( aPos
) )
1854 LaunchDataSelectMenu( aListValPos
.Col(), aListValPos
.Row(), true );
1856 nMouseStatus
= SC_GM_FILTER
; // not set in DoAutoFilterMenue for bDataSelect
1858 rState
.mbActivatePart
= false;
1865 // scenario selection
1869 if ( rMEvt
.IsLeft() && HasScenarioButton( aPos
, aScenRange
) )
1871 DoScenarioMenue( aScenRange
);
1876 // Doppelklick angefangen ?
1879 // StopMarking kann aus DrawMouseButtonDown gerufen werden
1881 if ( nMouseStatus
!= SC_GM_IGNORE
&& !bRefMode
)
1883 if ( bDouble
&& !bCrossPointer
)
1885 if (nMouseStatus
== SC_GM_TABDOWN
)
1886 nMouseStatus
= SC_GM_DBLDOWN
;
1889 nMouseStatus
= SC_GM_TABDOWN
;
1893 // Links in Edit-Zellen
1896 sal_Bool bAlt
= rMEvt
.IsMod2();
1897 if ( !bAlt
&& rMEvt
.IsLeft() &&
1898 GetEditUrl(rMEvt
.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
1900 SetPointer( Pointer( POINTER_REFHAND
) );
1901 nMouseStatus
= SC_GM_URLDOWN
; // auch nur dann beim ButtonUp ausfuehren
1906 // Gridwin - SelectionEngine
1909 if ( rMEvt
.IsLeft() )
1911 ScViewSelectionEngine
* pSelEng
= pViewData
->GetView()->GetSelEngine();
1912 pSelEng
->SetWindow(this);
1913 pSelEng
->SetWhich(eWhich
);
1914 pSelEng
->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1916 // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1917 if ( pViewData
->GetView()->SelMouseButtonDown( rMEvt
) )
1919 if (IsMouseCaptured())
1921 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1922 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1926 pViewData
->GetMarkData().SetMarking(sal_True
);
1932 void ScGridWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
1934 aCurMousePos
= rMEvt
.GetPosPixel();
1935 ScDocument
* pDoc
= pViewData
->GetDocument();
1936 ScMarkData
& rMark
= pViewData
->GetMarkData();
1938 // #i41690# detect a MouseButtonUp call from within MouseButtonDown
1939 // (possible through Reschedule from storing an OLE object that is deselected)
1941 if ( nNestedButtonState
== SC_NESTEDBUTTON_DOWN
)
1942 nNestedButtonState
= SC_NESTEDBUTTON_UP
;
1944 if (nButtonDown
!= rMEvt
.GetButtons())
1945 nMouseStatus
= SC_GM_IGNORE
; // reset und return
1949 if (nMouseStatus
== SC_GM_IGNORE
)
1951 nMouseStatus
= SC_GM_NONE
;
1952 // Selection-Engine: Markieren abbrechen
1953 pViewData
->GetView()->GetSelEngine()->Reset();
1954 rMark
.SetMarking(false);
1955 if (pViewData
->IsAnyFillMode())
1957 pViewData
->GetView()->StopRefMode();
1958 pViewData
->ResetFillMode();
1961 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
1966 if (nMouseStatus
== SC_GM_FILTER
)
1968 nMouseStatus
= SC_GM_NONE
;
1970 return; // da muss nix mehr passieren
1973 ScModule
* pScMod
= SC_MOD();
1974 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
1977 SfxBindings
& rBindings
= pViewData
->GetBindings();
1978 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
1980 EditView
* pEditView
;
1983 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
1984 pEditView
->MouseButtonUp( rMEvt
);
1986 if ( rMEvt
.IsMiddle() &&
1987 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
)
1989 // EditView may have pasted from selection
1990 pScMod
->InputChanged( pEditView
);
1993 pScMod
->InputSelection( pEditView
); // parentheses etc.
1995 pViewData
->GetView()->InvalidateAttribs();
1996 rBindings
.Invalidate( SID_HYPERLINK_GETLINK
);
2003 DPMouseButtonUp( rMEvt
); // resets bDPMouse
2009 RFMouseMove( rMEvt
, sal_True
); // Range wieder richtigherum
2011 SetPointer( Pointer( POINTER_ARROW
) );
2016 if (nPagebreakMouse
)
2018 PagebreakMove( rMEvt
, sal_True
);
2019 nPagebreakMouse
= SC_PD_NONE
;
2020 SetPointer( Pointer( POINTER_ARROW
) );
2025 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus
2027 ::svl::IUndoManager
* pMgr
= pViewData
->GetDocShell()->GetUndoManager();
2028 if ( pMgr
->GetUndoActionCount() && pMgr
->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE
)
2033 if (DrawMouseButtonUp(rMEvt
)) // includes format paint brush handling for drawing objects
2036 rMark
.SetMarking(false);
2038 SetPointer( Pointer( POINTER_ARROW
) );
2040 if (pViewData
->IsFillMode() ||
2041 ( pViewData
->GetFillMode() == SC_FILL_MATRIX
&& rMEvt
.IsMod1() ))
2043 nScFillModeMouseModifier
= rMEvt
.GetModifier();
2048 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2050 sal_Bool bIsDel
= pViewData
->GetDelMark( aDelRange
);
2052 ScViewFunc
* pView
= pViewData
->GetView();
2053 pView
->StopRefMode();
2054 pViewData
->ResetFillMode();
2055 pView
->GetFunctionSet()->SetAnchorFlag( false ); // #i5819# don't use AutoFill anchor flag for selection
2059 pView
->MarkRange( aDelRange
, false );
2060 pView
->DeleteContents( IDF_CONTENTS
);
2061 SCTAB nTab
= pViewData
->GetTabNo();
2062 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2063 if ( aBlockRange
!= aDelRange
)
2065 if ( aDelRange
.aStart
.Row() == nStartRow
)
2066 aBlockRange
.aEnd
.SetCol( aDelRange
.aStart
.Col() - 1 );
2068 aBlockRange
.aEnd
.SetRow( aDelRange
.aStart
.Row() - 1 );
2069 pView
->MarkRange( aBlockRange
, false );
2073 pViewData
->GetDispatcher().Execute( FID_FILL_AUTO
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2075 else if (pViewData
->GetFillMode() == SC_FILL_MATRIX
)
2077 SCTAB nTab
= pViewData
->GetTabNo();
2082 pViewData
->GetFillData( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
2083 ScRange
aBlockRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
);
2084 SCCOL nFillCol
= pViewData
->GetRefEndX();
2085 SCROW nFillRow
= pViewData
->GetRefEndY();
2086 ScAddress
aEndPos( nFillCol
, nFillRow
, nTab
);
2088 ScTabView
* pView
= pViewData
->GetView();
2089 pView
->StopRefMode();
2090 pViewData
->ResetFillMode();
2091 pView
->GetFunctionSet()->SetAnchorFlag( false );
2093 if ( aEndPos
!= aBlockRange
.aEnd
)
2095 pViewData
->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange
, aEndPos
, false );
2096 pViewData
->GetView()->MarkRange( ScRange( aBlockRange
.aStart
, aEndPos
) );
2099 else if (pViewData
->IsAnyFillMode())
2101 // Embedded-Area has been changed
2102 ScTabView
* pView
= pViewData
->GetView();
2103 pView
->StopRefMode();
2104 pViewData
->ResetFillMode();
2105 pView
->GetFunctionSet()->SetAnchorFlag( false );
2106 pViewData
->GetDocShell()->UpdateOle(pViewData
);
2109 sal_Bool bRefMode
= pViewData
->IsRefMode();
2111 pScMod
->EndReference();
2114 // Giesskannen-Modus (Gestalter)
2117 if (pScMod
->GetIsWaterCan())
2119 // Abfrage auf Undo schon oben
2121 ScStyleSheetPool
* pStylePool
= (ScStyleSheetPool
*)
2122 (pViewData
->GetDocument()->
2123 GetStyleSheetPool());
2126 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)
2127 pStylePool
->GetActualStyleSheet();
2131 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
2135 case SFX_STYLE_FAMILY_PARA
:
2136 pViewData
->GetView()->SetStyleSheetToMarked( pStyleSheet
);
2137 pViewData
->GetView()->DoneBlockMode();
2140 case SFX_STYLE_FAMILY_PAGE
:
2141 pViewData
->GetDocument()->SetPageStyle( pViewData
->GetTabNo(),
2142 pStyleSheet
->GetName() );
2144 ScPrintFunc( pViewData
->GetDocShell(),
2145 pViewData
->GetViewShell()->GetPrinter(sal_True
),
2146 pViewData
->GetTabNo() ).UpdatePages();
2148 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
2158 ScDBFunc
* pView
= pViewData
->GetView();
2159 ScDocument
* pBrushDoc
= pView
->GetBrushDocument();
2162 pView
->PasteFromClip( IDF_ATTRIB
, pBrushDoc
);
2163 if ( !pView
->IsPaintBrushLocked() )
2164 pView
->ResetBrushDocument(); // invalidates pBrushDoc pointer
2168 // double click (only left button)
2171 sal_Bool bDouble
= ( rMEvt
.GetClicks() == 2 && rMEvt
.IsLeft() );
2172 if ( bDouble
&& !bRefMode
&& nMouseStatus
== SC_GM_DBLDOWN
&& !pScMod
->IsRefDialogOpen() )
2175 Point aPos
= rMEvt
.GetPosPixel();
2178 SCTAB nTab
= pViewData
->GetTabNo();
2179 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2180 ScDPObject
* pDPObj
= pDoc
->GetDPAtCursor( nPosX
, nPosY
, nTab
);
2181 if ( pDPObj
&& pDPObj
->GetSaveData()->GetDrillDown() )
2183 ScAddress
aCellPos( nPosX
, nPosY
, pViewData
->GetTabNo() );
2185 // Check for header drill-down first.
2186 sheet::DataPilotTableHeaderData aData
;
2187 pDPObj
->GetHeaderPositionData(aCellPos
, aData
);
2189 if ( ( aData
.Flags
& sheet::MemberResultFlags::HASMEMBER
) &&
2190 ! ( aData
.Flags
& sheet::MemberResultFlags::SUBTOTAL
) )
2193 if ( pView
->HasSelectionForDrillDown( nDummy
) )
2195 // execute slot to show dialog
2196 pViewData
->GetDispatcher().Execute( SID_OUTLINE_SHOW
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
2200 // toggle single entry
2201 ScDPObject
aNewObj( *pDPObj
);
2202 pDPObj
->ToggleDetails( aData
, &aNewObj
);
2203 ScDBDocFunc
aFunc( *pViewData
->GetDocShell() );
2204 aFunc
.DataPilotUpdate( pDPObj
, &aNewObj
, sal_True
, false );
2205 pViewData
->GetView()->CursorPosChanged(); // shells may be switched
2210 // Check if the data area is double-clicked.
2212 Sequence
<sheet::DataPilotFieldFilter
> aFilters
;
2213 if ( pDPObj
->GetDataFieldPositionData(aCellPos
, aFilters
) )
2214 pViewData
->GetView()->ShowDataPilotSourceData( *pDPObj
, aFilters
);
2220 // Check for cell protection attribute.
2221 ScTableProtection
* pProtect
= pDoc
->GetTabProtection( nTab
);
2222 bool bEditAllowed
= true;
2223 if ( pProtect
&& pProtect
->isProtected() )
2225 bool bCellProtected
= pDoc
->HasAttrib(nPosX
, nPosY
, nTab
, nPosX
, nPosY
, nTab
, HASATTR_PROTECTED
);
2226 bool bSkipProtected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2227 bool bSkipUnprotected
= !pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2229 if ( bSkipProtected
&& bSkipUnprotected
)
2230 bEditAllowed
= false;
2231 else if ( (bCellProtected
&& bSkipProtected
) || (!bCellProtected
&& bSkipUnprotected
) )
2232 bEditAllowed
= false;
2237 // edit cell contents
2238 pViewData
->GetViewShell()->UpdateInputHandler();
2239 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2240 if (pViewData
->HasEditView(eWhich
))
2242 // Text-Cursor gleich an die geklickte Stelle setzen
2243 EditView
* pEditView
= pViewData
->GetEditView( eWhich
);
2244 MouseEvent
aEditEvt( rMEvt
.GetPosPixel(), 1, MOUSE_SYNTHETIC
, MOUSE_LEFT
, 0 );
2245 pEditView
->MouseButtonDown( aEditEvt
);
2246 pEditView
->MouseButtonUp( aEditEvt
);
2253 // Links in edit cells
2256 sal_Bool bAlt
= rMEvt
.IsMod2();
2257 if ( !bAlt
&& !bRefMode
&& !bDouble
&& nMouseStatus
== SC_GM_URLDOWN
)
2259 // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2261 String aName
, aUrl
, aTarget
;
2262 if ( GetEditUrl( rMEvt
.GetPosPixel(), &aName
, &aUrl
, &aTarget
) )
2264 nMouseStatus
= SC_GM_NONE
; // keinen Doppelklick anfangen
2266 // ScGlobal::OpenURL() only understands Calc A1 style syntax.
2267 // Convert it to Calc A1 before calling OpenURL().
2269 if (pDoc
->GetAddressConvention() == formula::FormulaGrammar::CONV_OOO
)
2270 ScGlobal::OpenURL(aUrl
, aTarget
);
2273 ScAddress aTempAddr
;
2274 ScAddress::ExternalInfo aExtInfo
;
2275 sal_uInt16 nRes
= aTempAddr
.Parse(aUrl
, pDoc
, pDoc
->GetAddressConvention(), &aExtInfo
);
2276 if (!(nRes
& SCA_VALID
))
2278 // Not a reference string. Pass it through unmodified.
2279 ScGlobal::OpenURL(aUrl
, aTarget
);
2283 OUStringBuffer aBuf
;
2284 if (aExtInfo
.mbExternal
)
2286 // External reference.
2287 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
2288 const OUString
* pStr
= pRefMgr
->getExternalFileName(aExtInfo
.mnFileId
);
2293 aBuf
.append(aExtInfo
.maTabName
);
2295 OUString aRefCalcA1
;
2296 aTempAddr
.Format(aRefCalcA1
, SCA_ABS
, NULL
, formula::FormulaGrammar::CONV_OOO
);
2297 aBuf
.append(aRefCalcA1
);
2298 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2302 // Internal reference.
2304 OUString aUrlCalcA1
;
2305 aTempAddr
.Format(aUrlCalcA1
, SCA_ABS_3D
, pDoc
, formula::FormulaGrammar::CONV_OOO
);
2306 aBuf
.append(aUrlCalcA1
);
2307 ScGlobal::OpenURL(aBuf
.makeStringAndClear(), aTarget
);
2311 // fire worksheet_followhyperlink event
2312 uno::Reference
< script::vba::XVBAEventProcessor
> xVbaEvents
= pDoc
->GetVbaEventProcessor();
2313 if( xVbaEvents
.is() ) try
2315 Point aPos
= rMEvt
.GetPosPixel();
2318 SCTAB nTab
= pViewData
->GetTabNo();
2319 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2320 ScBaseCell
* pCell
= NULL
;
2321 if( lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
) )
2323 ScAddress
aCellPos( nPosX
, nPosY
, nTab
);
2324 uno::Reference
< table::XCell
> xCell( new ScCellObj( pViewData
->GetDocShell(), aCellPos
) );
2325 uno::Sequence
< uno::Any
> aArgs(1);
2327 xVbaEvents
->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK
, aArgs
);
2330 catch( uno::Exception
& )
2339 // Gridwin - SelectionEngine
2342 // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2343 // sal_True for any call, so IsLeft must be checked here, too.
2345 if ( rMEvt
.IsLeft() && pViewData
->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt
) )
2347 pViewData
->GetView()->SelectionChanged();
2349 SfxDispatcher
* pDisp
= pViewData
->GetViewShell()->GetDispatcher();
2350 sal_Bool bFormulaMode
= pScMod
->IsFormulaMode();
2351 OSL_ENSURE( pDisp
|| bFormulaMode
, "Cursor auf nicht aktiver View bewegen ?" );
2353 // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2354 // multiple selection, so the argument string completely describes the selection,
2355 // and executing the slot won't change the existing selection (executing the slot
2356 // here and from a recorded macro is treated equally)
2358 if ( pDisp
&& !bFormulaMode
&& !rMark
.IsMultiMarked() )
2360 String aAddr
; // CurrentCell
2361 if( rMark
.IsMarked() )
2364 rMark
.GetMarkArea( aScRange
);
2365 aScRange
.Format( aAddr
, SCR_ABS
);
2366 if ( aScRange
.aStart
== aScRange
.aEnd
)
2368 // make sure there is a range selection string even for a single cell
2369 String aSingle
= aAddr
;
2370 aAddr
.Append( (sal_Char
) ':' );
2371 aAddr
.Append( aSingle
);
2374 //! SID_MARKAREA gibts nicht mehr ???
2375 //! was passiert beim Markieren mit dem Cursor ???
2377 else // nur Cursor bewegen
2379 ScAddress
aScAddress( pViewData
->GetCurX(), pViewData
->GetCurY(), 0 );
2380 aScAddress
.Format( aAddr
, SCA_ABS
);
2383 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
2384 // We don't want to align to the cursor position because if the
2385 // cell cursor isn't visible after making selection, it would jump
2386 // back to the origin of the selection where the cell cursor is.
2387 SfxBoolItem
aAlignCursorItem( FN_PARAM_2
, false );
2388 pDisp
->Execute( SID_CURRENTCELL
, SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
2389 &aPosItem
, &aAlignCursorItem
, (void*)0L );
2391 pViewData
->GetView()->InvalidateAttribs();
2397 void ScGridWindow::FakeButtonUp()
2401 MouseEvent
aEvent( aCurMousePos
); // nButtons = 0 -> ignore
2402 MouseButtonUp( aEvent
);
2406 void ScGridWindow::MouseMove( const MouseEvent
& rMEvt
)
2408 aCurMousePos
= rMEvt
.GetPosPixel();
2410 if ( rMEvt
.IsLeaveWindow() && pNoteMarker
&& !pNoteMarker
->IsByKeyboard() )
2413 ScModule
* pScMod
= SC_MOD();
2414 if (pScMod
->IsModalMode(pViewData
->GetSfxDocShell()))
2417 // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2418 // nicht anders mit:
2420 if (bEEMouse
&& nButtonDown
&& !rMEvt
.GetButtons())
2424 nMouseStatus
= SC_GM_NONE
;
2428 if (nMouseStatus
== SC_GM_IGNORE
)
2431 if (nMouseStatus
== SC_GM_WATERUNDO
) // Undo im Giesskannenmodus -> nur auf Up warten
2434 if ( pViewData
->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
2436 SetPointer( Pointer( POINTER_FILL
) );
2440 if (nMouseStatus
== SC_GM_FILTER
&& pFilterBox
)
2442 Point aRelPos
= pFilterBox
->ScreenToOutputPixel( OutputToScreenPixel( rMEvt
.GetPosPixel() ) );
2443 if ( Rectangle(Point(),pFilterBox
->GetOutputSizePixel()).IsInside(aRelPos
) )
2446 nMouseStatus
= SC_GM_NONE
;
2448 pFilterBox
->MouseButtonDown( MouseEvent( aRelPos
, 1, MOUSE_SIMPLECLICK
, MOUSE_LEFT
) );
2453 sal_Bool bFormulaMode
= pScMod
->IsFormulaMode(); // naechster Klick -> Referenz
2455 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2457 EditView
* pEditView
;
2460 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2461 pEditView
->MouseMove( rMEvt
);
2467 DPMouseMove( rMEvt
);
2473 RFMouseMove( rMEvt
, false );
2477 if (nPagebreakMouse
)
2479 PagebreakMove( rMEvt
, false );
2483 // anderen Mauszeiger anzeigen?
2485 sal_Bool bEditMode
= pViewData
->HasEditView(eWhich
);
2487 //! Testen ob RefMode-Dragging !!!
2488 if ( bEditMode
&& (pViewData
->GetRefTabNo() == pViewData
->GetTabNo()) )
2490 Point aPos
= rMEvt
.GetPosPixel();
2493 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
2495 EditView
* pEditView
;
2498 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2499 SCCOL nEndCol
= pViewData
->GetEditEndCol();
2500 SCROW nEndRow
= pViewData
->GetEditEndRow();
2502 if ( nPosX
>= (SCsCOL
) nEditCol
&& nPosX
<= (SCsCOL
) nEndCol
&&
2503 nPosY
>= (SCsROW
) nEditRow
&& nPosY
<= (SCsROW
) nEndRow
)
2505 // Field can only be URL field
2506 sal_Bool bAlt
= rMEvt
.IsMod2();
2507 if ( !bAlt
&& !nButtonDown
&& pEditView
&& pEditView
->GetFieldUnderMousePointer() )
2508 SetPointer( Pointer( POINTER_REFHAND
) );
2509 else if ( pEditView
&& pEditView
->GetEditEngine()->IsVertical() )
2510 SetPointer( Pointer( POINTER_TEXT_VERTICAL
) );
2512 SetPointer( Pointer( POINTER_TEXT
) );
2517 sal_Bool bWater
= SC_MOD()->GetIsWaterCan() || pViewData
->GetView()->HasPaintBrush();
2519 SetPointer( Pointer(POINTER_FILL
) );
2523 sal_Bool bCross
= false;
2528 if ( HitRangeFinder( rMEvt
.GetPosPixel(), bCorner
) )
2531 SetPointer( Pointer( POINTER_CROSS
) );
2533 SetPointer( Pointer( POINTER_HAND
) );
2539 sal_uInt16 nBreakType
;
2540 if ( !nButtonDown
&& pViewData
->IsPagebreakMode() &&
2541 ( nBreakType
= HitPageBreak( rMEvt
.GetPosPixel() ) ) != 0 )
2543 PointerStyle eNew
= POINTER_ARROW
;
2544 switch ( nBreakType
)
2549 eNew
= POINTER_ESIZE
;
2554 eNew
= POINTER_SSIZE
;
2556 case SC_PD_RANGE_TL
:
2557 case SC_PD_RANGE_BR
:
2558 eNew
= POINTER_SESIZE
;
2560 case SC_PD_RANGE_TR
:
2561 case SC_PD_RANGE_BL
:
2562 eNew
= POINTER_NESIZE
;
2565 SetPointer( Pointer( eNew
) );
2569 // Fill-Cursor anzeigen ?
2571 if ( !bFormulaMode
&& !nButtonDown
)
2572 if (TestMouse( rMEvt
, false ))
2575 if ( nButtonDown
&& pViewData
->IsAnyFillMode() )
2577 SetPointer( Pointer( POINTER_CROSS
) );
2579 nScFillModeMouseModifier
= rMEvt
.GetModifier(); // ausgewertet bei AutoFill und Matrix
2584 sal_Bool bAlt
= rMEvt
.IsMod2();
2586 if (bEditMode
) // Edit-Mode muss zuerst kommen!
2587 SetPointer( Pointer( POINTER_ARROW
) );
2588 else if ( !bAlt
&& !nButtonDown
&&
2589 GetEditUrl(rMEvt
.GetPosPixel()) )
2590 SetPointer( Pointer( POINTER_REFHAND
) );
2591 else if ( DrawMouseMove(rMEvt
) ) // setzt Pointer um
2596 if ( pViewData
->GetView()->GetSelEngine()->SelMouseMove( rMEvt
) )
2600 static void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent
& rEvent
, const MouseEvent
& rEvt
)
2602 rEvent
.Modifiers
= 0;
2603 if ( rEvt
.IsShift() )
2604 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::SHIFT
;
2605 if ( rEvt
.IsMod1() )
2606 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD1
;
2607 if ( rEvt
.IsMod2() )
2608 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD2
;
2609 if ( rEvt
.IsMod3() )
2610 rEvent
.Modifiers
|= ::com::sun::star::awt::KeyModifier::MOD3
;
2613 if ( rEvt
.IsLeft() )
2614 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::LEFT
;
2615 if ( rEvt
.IsRight() )
2616 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::RIGHT
;
2617 if ( rEvt
.IsMiddle() )
2618 rEvent
.Buttons
|= ::com::sun::star::awt::MouseButton::MIDDLE
;
2620 rEvent
.X
= rEvt
.GetPosPixel().X();
2621 rEvent
.Y
= rEvt
.GetPosPixel().Y();
2622 rEvent
.ClickCount
= rEvt
.GetClicks();
2623 rEvent
.PopupTrigger
= false;
2626 long ScGridWindow::PreNotify( NotifyEvent
& rNEvt
)
2629 sal_uInt16 nType
= rNEvt
.GetType();
2630 if ( nType
== EVENT_MOUSEBUTTONUP
|| nType
== EVENT_MOUSEBUTTONDOWN
)
2632 Window
* pWindow
= rNEvt
.GetWindow();
2633 if (pWindow
== this && pViewData
)
2635 SfxViewFrame
* pViewFrame
= pViewData
->GetViewShell()->GetViewFrame();
2638 com::sun::star::uno::Reference
<com::sun::star::frame::XController
> xController
= pViewFrame
->GetFrame().GetController();
2639 if (xController
.is())
2641 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
2642 if (pImp
&& pImp
->IsMouseListening())
2644 ::com::sun::star::awt::MouseEvent aEvent
;
2645 lcl_InitMouseEvent( aEvent
, *rNEvt
.GetMouseEvent() );
2646 if ( rNEvt
.GetWindow() )
2647 aEvent
.Source
= rNEvt
.GetWindow()->GetComponentInterface();
2648 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2649 bDone
= pImp
->MousePressed( aEvent
);
2651 bDone
= pImp
->MouseReleased( aEvent
);
2657 if (bDone
) // event consumed by a listener
2659 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
2661 const MouseEvent
* pMouseEvent
= rNEvt
.GetMouseEvent();
2662 if ( pMouseEvent
->IsRight() && pMouseEvent
->GetClicks() == 1 )
2664 // If a listener returned true for a right-click call, also prevent opening the context menu
2665 // (this works only if the context menu is opened on mouse-down)
2666 nMouseStatus
= SC_GM_IGNORE
;
2673 return Window::PreNotify( rNEvt
);
2676 void ScGridWindow::Tracking( const TrackingEvent
& rTEvt
)
2678 // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2679 // die verschiedenen MouseHandler verteilen...
2681 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
2683 if ( rTEvt
.IsTrackingCanceled() ) // alles abbrechen...
2685 if (!pViewData
->GetView()->IsInActivatePart() && !SC_MOD()->IsRefDialogOpen())
2688 bDPMouse
= false; // gezeichnet wird per bDragRect
2691 // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2693 UpdateDragRectOverlay();
2697 RFMouseMove( rMEvt
, true ); // richtig abbrechen geht dabei nicht...
2700 if (nPagebreakMouse
)
2702 // if (bPagebreakDrawn)
2703 // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2704 // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
2705 bPagebreakDrawn
= false;
2706 UpdateDragRectOverlay();
2707 nPagebreakMouse
= SC_PD_NONE
;
2710 SetPointer( Pointer( POINTER_ARROW
) );
2712 MouseButtonUp( rMEvt
); // mit Status SC_GM_IGNORE aus StopMarking
2714 sal_Bool bRefMode
= pViewData
->IsRefMode();
2716 SC_MOD()->EndReference(); // Dialog nicht verkleinert lassen
2719 else if ( rTEvt
.IsTrackingEnded() )
2721 // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2722 // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2723 // abgebrochen wurde.
2725 MouseEvent
aUpEvt( rMEvt
.GetPosPixel(), rMEvt
.GetClicks(),
2726 rMEvt
.GetMode(), nButtonDown
, rMEvt
.GetModifier() );
2727 MouseButtonUp( aUpEvt
);
2733 void ScGridWindow::StartDrag( sal_Int8
/* nAction */, const Point
& rPosPixel
)
2735 if ( pFilterBox
|| nPagebreakMouse
)
2740 CommandEvent
aDragEvent( rPosPixel
, COMMAND_STARTDRAG
, sal_True
);
2742 if (bEEMouse
&& pViewData
->HasEditView( eWhich
))
2744 EditView
* pEditView
;
2747 pViewData
->GetEditView( eWhich
, pEditView
, nEditCol
, nEditRow
);
2749 // don't remove the edit view while switching views
2750 ScModule
* pScMod
= SC_MOD();
2751 pScMod
->SetInEditCommand( sal_True
);
2753 pEditView
->Command( aDragEvent
);
2755 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
2757 pHdl
->DataChanged();
2759 pScMod
->SetInEditCommand( false );
2760 if (!pViewData
->IsActive()) // dropped to different view?
2762 ScInputHandler
* pViewHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2763 if ( pViewHdl
&& pViewData
->HasEditView( eWhich
) )
2765 pViewHdl
->CancelHandler();
2766 ShowCursor(); // missing from KillEditView
2771 if ( !DrawCommand(aDragEvent
) )
2772 pViewData
->GetView()->GetSelEngine()->Command( aDragEvent
);
2775 static void lcl_SetTextCursorPos( ScViewData
* pViewData
, ScSplitPos eWhich
, Window
* pWin
)
2777 SCCOL nCol
= pViewData
->GetCurX();
2778 SCROW nRow
= pViewData
->GetCurY();
2779 Rectangle aEditArea
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, pWin
, NULL
, sal_True
);
2780 aEditArea
.Right() = aEditArea
.Left();
2781 aEditArea
= pWin
->PixelToLogic( aEditArea
);
2782 pWin
->SetCursorRect( &aEditArea
);
2785 void ScGridWindow::Command( const CommandEvent
& rCEvt
)
2787 // The command event is send to the window after a possible context
2788 // menu from an inplace client is closed. Now we have the chance to
2789 // deactivate the inplace client without any problem regarding parent
2790 // windows and code on the stack.
2791 sal_uInt16 nCmd
= rCEvt
.GetCommand();
2792 ScTabViewShell
* pTabViewSh
= pViewData
->GetViewShell();
2793 SfxInPlaceClient
* pClient
= pTabViewSh
->GetIPClient();
2795 pClient
->IsObjectInPlaceActive() &&
2796 nCmd
== COMMAND_CONTEXTMENU
)
2798 pTabViewSh
->DeactivateOle();
2802 ScModule
* pScMod
= SC_MOD();
2803 OSL_ENSURE( nCmd
!= COMMAND_STARTDRAG
, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2805 if ( nCmd
== COMMAND_STARTEXTTEXTINPUT
||
2806 nCmd
== COMMAND_ENDEXTTEXTINPUT
||
2807 nCmd
== COMMAND_EXTTEXTINPUT
||
2808 nCmd
== COMMAND_CURSORPOS
)
2810 sal_Bool bEditView
= pViewData
->HasEditView( eWhich
);
2813 // only if no cell editview is active, look at drawview
2814 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2817 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2818 if ( pOlView
&& pOlView
->GetWindow() == this )
2820 pOlView
->Command( rCEvt
);
2826 if ( nCmd
== COMMAND_CURSORPOS
&& !bEditView
)
2828 // CURSORPOS may be called without following text input,
2829 // to set the input method window position
2830 // -> input mode must not be started,
2831 // manually calculate text insert position if not in input mode
2833 lcl_SetTextCursorPos( pViewData
, eWhich
, this );
2837 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2840 pHdl
->InputCommand( rCEvt
, sal_True
);
2844 Window::Command( rCEvt
);
2848 if ( nCmd
== COMMAND_VOICE
)
2850 // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
2851 // also muss es eine EditView oder ein editiertes Zeichenobjekt geben
2853 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewData
->GetViewShell() );
2854 if ( pHdl
&& pViewData
->HasEditView( eWhich
) )
2856 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2857 pHdl
->DataChanging();
2858 pEditView
->Command( rCEvt
);
2859 pHdl
->DataChanged();
2862 SdrView
* pSdrView
= pViewData
->GetView()->GetSdrView();
2865 OutlinerView
* pOlView
= pSdrView
->GetTextEditOutlinerView();
2866 if ( pOlView
&& pOlView
->GetWindow() == this )
2868 pOlView
->Command( rCEvt
);
2872 Window::Command(rCEvt
); // sonst soll sich die Basisklasse drum kuemmern...
2876 if ( nCmd
== COMMAND_PASTESELECTION
)
2880 // EditEngine handles selection in MouseButtonUp - no action
2881 // needed in command handler
2885 PasteSelection( rCEvt
.GetMousePosPixel() );
2890 if ( nCmd
== COMMAND_INPUTLANGUAGECHANGE
)
2892 // #i55929# Font and font size state depends on input language if nothing is selected,
2893 // so the slots have to be invalidated when the input language is changed.
2895 SfxBindings
& rBindings
= pViewData
->GetBindings();
2896 rBindings
.Invalidate( SID_ATTR_CHAR_FONT
);
2897 rBindings
.Invalidate( SID_ATTR_CHAR_FONTHEIGHT
);
2901 if ( nCmd
== COMMAND_WHEEL
|| nCmd
== COMMAND_STARTAUTOSCROLL
|| nCmd
== COMMAND_AUTOSCROLL
)
2903 sal_Bool bDone
= pViewData
->GetView()->ScrollCommand( rCEvt
, eWhich
);
2905 Window::Command(rCEvt
);
2908 // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2909 sal_Bool bDisable
= pScMod
->IsFormulaMode() ||
2910 pScMod
->IsModalMode(pViewData
->GetSfxDocShell());
2914 if ( nCmd
== COMMAND_CONTEXTMENU
&& !SC_MOD()->GetIsWaterCan() )
2916 sal_Bool bMouse
= rCEvt
.IsMouseEvent();
2917 if ( bMouse
&& nMouseStatus
== SC_GM_IGNORE
)
2920 if (pViewData
->IsAnyFillMode())
2922 pViewData
->GetView()->StopRefMode();
2923 pViewData
->ResetFillMode();
2928 Point aPosPixel
= rCEvt
.GetMousePosPixel();
2929 Point aMenuPos
= aPosPixel
;
2935 pViewData
->GetPosFromPixel(aPosPixel
.X(), aPosPixel
.Y(), eWhich
, nCellX
, nCellY
);
2936 ScDocument
* pDoc
= pViewData
->GetDocument();
2937 SCTAB nTab
= pViewData
->GetTabNo();
2938 const ScTableProtection
* pProtect
= pDoc
->GetTabProtection(nTab
);
2939 bool bSelectAllowed
= true;
2940 if ( pProtect
&& pProtect
->isProtected() )
2942 // This sheet is protected. Check if a context menu is allowed on this cell.
2943 bool bCellProtected
= pDoc
->HasAttrib(nCellX
, nCellY
, nTab
, nCellX
, nCellY
, nTab
, HASATTR_PROTECTED
);
2944 bool bSelProtected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
);
2945 bool bSelUnprotected
= pProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
);
2948 bSelectAllowed
= bSelProtected
;
2950 bSelectAllowed
= bSelUnprotected
;
2952 if (!bSelectAllowed
)
2953 // Selecting this cell is not allowed, neither is context menu.
2956 // #i18735# First select the item under the mouse pointer.
2957 // This can change the selection, and the view state (edit mode, etc).
2958 SelectForContextMenu( aPosPixel
, nCellX
, nCellY
);
2961 sal_Bool bDone
= false;
2962 sal_Bool bEdit
= pViewData
->HasEditView(eWhich
);
2965 // Edit-Zelle mit Spelling-Errors ?
2966 if ( bMouse
&& GetEditUrlOrError( sal_True
, aPosPixel
) )
2968 // GetEditUrlOrError hat den Cursor schon bewegt
2970 pScMod
->SetInputMode( SC_INPUT_TABLE
);
2971 bEdit
= pViewData
->HasEditView(eWhich
); // hat's geklappt ?
2973 OSL_ENSURE( bEdit
, "kann nicht in Edit-Modus schalten" );
2978 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // ist dann nicht 0
2982 Cursor
* pCur
= pEditView
->GetCursor();
2985 Point aLogicPos
= pCur
->GetPos();
2986 // use the position right of the cursor (spell popup is opened if
2987 // the cursor is before the word, but not if behind it)
2988 aLogicPos
.X() += pCur
->GetWidth();
2989 aLogicPos
.Y() += pCur
->GetHeight() / 2; // center vertically
2990 aMenuPos
= LogicToPixel( aLogicPos
);
2994 // if edit mode was just started above, online spelling may be incomplete
2995 pEditView
->GetEditEngine()->CompleteOnlineSpelling();
2997 // IsCursorAtWrongSpelledWord could be used for !bMouse
2998 // if there was a corresponding ExecuteSpellPopup call
3000 if( pEditView
->IsWrongSpelledWordAtPos( aMenuPos
) )
3002 // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
3003 // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
3005 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
3007 pHdl
->SetModified();
3009 Link aLink
= LINK( this, ScGridWindow
, PopupSpellingHdl
);
3010 pEditView
->ExecuteSpellPopup( aMenuPos
, &aLink
);
3017 // non-edit menu by keyboard -> use lower right of cell cursor position
3019 SCCOL nCurX
= pViewData
->GetCurX();
3020 SCROW nCurY
= pViewData
->GetCurY();
3021 aMenuPos
= pViewData
->GetScrPos( nCurX
, nCurY
, eWhich
, sal_True
);
3024 pViewData
->GetMergeSizePixel( nCurX
, nCurY
, nSizeXPix
, nSizeYPix
);
3025 aMenuPos
.X() += nSizeXPix
;
3026 aMenuPos
.Y() += nSizeYPix
;
3030 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3033 // Is a draw object selected?
3035 SdrView
* pDrawView
= pViewSh
->GetSdrView();
3036 if (pDrawView
&& pDrawView
->AreObjectsMarked())
3038 // #100442#; the conext menu should open in the middle of the selected objects
3039 Rectangle
aSelectRect(LogicToPixel(pDrawView
->GetAllMarkedBoundRect()));
3040 aMenuPos
= aSelectRect
.Center();
3048 SfxDispatcher::ExecutePopup( 0, this, &aMenuPos
);
3053 void ScGridWindow::SelectForContextMenu( const Point
& rPosPixel
, SCsCOL nCellX
, SCsROW nCellY
)
3055 // #i18735# if the click was outside of the current selection,
3056 // the cursor is moved or an object at the click position selected.
3057 // (see SwEditWin::SelectMenuPosition in Writer)
3059 ScTabView
* pView
= pViewData
->GetView();
3060 ScDrawView
* pDrawView
= pView
->GetScDrawView();
3062 // check cell edit mode
3064 if ( pViewData
->HasEditView(eWhich
) )
3066 ScModule
* pScMod
= SC_MOD();
3067 SCCOL nEditStartCol
= pViewData
->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
3068 SCROW nEditStartRow
= pViewData
->GetEditViewRow();
3069 SCCOL nEditEndCol
= pViewData
->GetEditEndCol();
3070 SCROW nEditEndRow
= pViewData
->GetEditEndRow();
3072 if ( nCellX
>= (SCsCOL
) nEditStartCol
&& nCellX
<= (SCsCOL
) nEditEndCol
&&
3073 nCellY
>= (SCsROW
) nEditStartRow
&& nCellY
<= (SCsROW
) nEditEndRow
)
3075 // handle selection within the EditView
3077 EditView
* pEditView
= pViewData
->GetEditView( eWhich
); // not NULL (HasEditView)
3078 EditEngine
* pEditEngine
= pEditView
->GetEditEngine();
3079 Rectangle aOutputArea
= pEditView
->GetOutputArea();
3080 Rectangle aVisArea
= pEditView
->GetVisArea();
3082 Point aTextPos
= PixelToLogic( rPosPixel
);
3083 if ( pEditEngine
->IsVertical() ) // have to manually transform position
3085 aTextPos
-= aOutputArea
.TopRight();
3086 long nTemp
= -aTextPos
.X();
3087 aTextPos
.X() = aTextPos
.Y();
3088 aTextPos
.Y() = nTemp
;
3091 aTextPos
-= aOutputArea
.TopLeft();
3092 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3094 EPosition aDocPosition
= pEditEngine
->FindDocPosition(aTextPos
);
3095 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3096 ESelection aSelection
= pEditView
->GetSelection();
3097 aSelection
.Adjust(); // needed for IsLess/IsGreater
3098 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3100 // clicked outside the selected text - deselect and move text cursor
3101 MouseEvent
aEvent( rPosPixel
);
3102 pEditView
->MouseButtonDown( aEvent
);
3103 pEditView
->MouseButtonUp( aEvent
);
3104 pScMod
->InputSelection( pEditView
);
3107 return; // clicked within the edit view - keep edit mode
3111 // outside of the edit view - end edit mode, regardless of cell selection, then continue
3112 pScMod
->InputEnterHandler();
3116 // check draw text edit mode
3118 Point aLogicPos
= PixelToLogic( rPosPixel
); // after cell edit mode is ended
3119 if ( pDrawView
&& pDrawView
->GetTextEditObject() && pDrawView
->GetTextEditOutlinerView() )
3121 OutlinerView
* pOlView
= pDrawView
->GetTextEditOutlinerView();
3122 Rectangle aOutputArea
= pOlView
->GetOutputArea();
3123 if ( aOutputArea
.IsInside( aLogicPos
) )
3125 // handle selection within the OutlinerView
3127 Outliner
* pOutliner
= pOlView
->GetOutliner();
3128 const EditEngine
& rEditEngine
= pOutliner
->GetEditEngine();
3129 Rectangle aVisArea
= pOlView
->GetVisArea();
3131 Point aTextPos
= aLogicPos
;
3132 if ( pOutliner
->IsVertical() ) // have to manually transform position
3134 aTextPos
-= aOutputArea
.TopRight();
3135 long nTemp
= -aTextPos
.X();
3136 aTextPos
.X() = aTextPos
.Y();
3137 aTextPos
.Y() = nTemp
;
3140 aTextPos
-= aOutputArea
.TopLeft();
3141 aTextPos
+= aVisArea
.TopLeft(); // position in the edit document
3143 EPosition aDocPosition
= rEditEngine
.FindDocPosition(aTextPos
);
3144 ESelection
aCompare(aDocPosition
.nPara
, aDocPosition
.nIndex
);
3145 ESelection aSelection
= pOlView
->GetSelection();
3146 aSelection
.Adjust(); // needed for IsLess/IsGreater
3147 if ( aCompare
.IsLess(aSelection
) || aCompare
.IsGreater(aSelection
) )
3149 // clicked outside the selected text - deselect and move text cursor
3150 // use DrawView to allow extra handling there (none currently)
3151 MouseEvent
aEvent( rPosPixel
);
3152 pDrawView
->MouseButtonDown( aEvent
, this );
3153 pDrawView
->MouseButtonUp( aEvent
, this );
3156 return; // clicked within the edit area - keep edit mode
3160 // Outside of the edit area - end text edit mode, then continue.
3161 // DrawDeselectAll also ends text edit mode and updates the shells.
3162 // If the click was on the edited object, it will be selected again below.
3163 pView
->DrawDeselectAll();
3167 // look for existing selection
3169 sal_Bool bHitSelected
= false;
3170 if ( pDrawView
&& pDrawView
->IsMarkedObjHit( aLogicPos
) )
3172 // clicked on selected object -> don't change anything
3173 bHitSelected
= sal_True
;
3175 else if ( pViewData
->GetMarkData().IsCellMarked(nCellX
, nCellY
) )
3177 // clicked on selected cell -> don't change anything
3178 bHitSelected
= sal_True
;
3181 // select drawing object or move cell cursor
3183 if ( !bHitSelected
)
3185 sal_Bool bWasDraw
= ( pDrawView
&& pDrawView
->AreObjectsMarked() );
3186 sal_Bool bHitDraw
= false;
3189 pDrawView
->UnmarkAllObj();
3190 // Unlock the Internal Layer in order to activate the context menu.
3191 // re-lock in ScDrawView::MarkListHasChanged()
3192 lcl_UnLockComment( pDrawView
, pDrawView
->GetSdrPageView(), pDrawView
->GetModel(), aLogicPos
,pViewData
);
3193 bHitDraw
= pDrawView
->MarkObj( aLogicPos
);
3194 // draw shell is activated in MarkListHasChanged
3199 pView
->SetCursor(nCellX
, nCellY
);
3201 pViewData
->GetViewShell()->SetDrawShell( false ); // switch shells
3206 void ScGridWindow::KeyInput(const KeyEvent
& rKEvt
)
3208 // Cursor control for ref input dialog
3209 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
3210 if( SC_MOD()->IsRefDialogOpen() )
3212 if( !rKeyCode
.GetModifier() && (rKeyCode
.GetCode() == KEY_F2
) )
3214 SC_MOD()->EndReference();
3217 else if( pViewData
->GetViewShell()->MoveCursorKeyInput( rKEvt
) )
3220 pViewData
->GetRefStartX(), pViewData
->GetRefStartY(), pViewData
->GetRefStartZ(),
3221 pViewData
->GetRefEndX(), pViewData
->GetRefEndY(), pViewData
->GetRefEndZ() );
3222 SC_MOD()->SetReference( aRef
, pViewData
->GetDocument() );
3226 else if( rKeyCode
.GetCode() == KEY_RETURN
&& pViewData
->IsPasteMode() )
3228 ScTabViewShell
* pTabViewShell
= pViewData
->GetViewShell();
3229 ScClipUtil::PasteFromClipboard( pViewData
, pTabViewShell
, false );
3231 // Clear clipboard content.
3232 uno::Reference
<datatransfer::clipboard::XClipboard
> xSystemClipboard
=
3233 TransferableHelper::GetSystemClipboard();
3234 if (xSystemClipboard
.is())
3236 xSystemClipboard
->setContents(
3237 uno::Reference
<datatransfer::XTransferable
>(),
3238 uno::Reference
<datatransfer::clipboard::XClipboardOwner
>());
3241 // hide the border around the copy source
3242 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3243 UpdateCopySourceOverlay();
3246 // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3247 else if( !pViewData
->IsAnyFillMode() )
3249 if (rKeyCode
.GetCode() == KEY_ESCAPE
)
3251 pViewData
->SetPasteMode( SC_PASTE_NONE
);
3252 UpdateCopySourceOverlay();
3254 // query for existing note marker before calling ViewShell's keyboard handling
3255 // which may remove the marker
3256 sal_Bool bHadKeyMarker
= ( pNoteMarker
&& pNoteMarker
->IsByKeyboard() );
3257 ScTabViewShell
* pViewSh
= pViewData
->GetViewShell();
3259 if (pViewData
->GetDocShell()->GetProgress())
3262 if (DrawKeyInput(rKEvt
))
3265 if (!pViewData
->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
3266 { //! DrawShell abfragen !!!
3267 if (pViewSh
->TabKeyInput(rKEvt
))
3271 if (pViewSh
->SfxViewShell::KeyInput(rKEvt
)) // von SfxViewShell
3274 KeyCode aCode
= rKEvt
.GetKeyCode();
3275 if ( aCode
.GetCode() == KEY_ESCAPE
&& aCode
.GetModifier() == 0 )
3277 if ( bHadKeyMarker
)
3283 if ( aCode
.GetCode() == KEY_F1
&& aCode
.GetModifier() == KEY_MOD1
)
3285 // ctrl-F1 shows or hides the note or redlining info for the cursor position
3286 // (hard-coded because F1 can't be configured)
3288 if ( bHadKeyMarker
)
3289 HideNoteMarker(); // hide when previously visible
3291 ShowNoteMarker( pViewData
->GetCurX(), pViewData
->GetCurY(), sal_True
);
3294 if (aCode
.GetCode() == KEY_BRACKETLEFT
&& aCode
.GetModifier() == KEY_MOD1
)
3296 pViewSh
->DetectiveMarkPred();
3299 if (aCode
.GetCode() == KEY_BRACKETRIGHT
&& aCode
.GetModifier() == KEY_MOD1
)
3301 pViewSh
->DetectiveMarkSucc();
3307 Window::KeyInput(rKEvt
);
3310 void ScGridWindow::StopMarking()
3312 DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
3316 pViewData
->GetMarkData().SetMarking(false);
3317 nMouseStatus
= SC_GM_IGNORE
;
3321 void ScGridWindow::UpdateInputContext()
3323 sal_Bool bReadOnly
= pViewData
->GetDocShell()->IsReadOnly();
3324 sal_uLong nOptions
= bReadOnly
? 0 : ( INPUTCONTEXT_TEXT
| INPUTCONTEXT_EXTTEXTINPUT
);
3326 // when font from InputContext is used,
3327 // it must be taken from the cursor position's cell attributes
3329 InputContext aContext
;
3330 aContext
.SetOptions( nOptions
);
3331 SetInputContext( aContext
);
3334 //--------------------------------------------------------
3336 // sensitiver Bereich (Pixel)
3337 #define SCROLL_SENSITIVE 20
3339 bool ScGridWindow::DropScroll( const Point
& rMousePos
)
3343 Size aSize
= GetOutputSizePixel();
3345 if (aSize
.Width() > SCROLL_SENSITIVE
* 3)
3347 if ( rMousePos
.X() < SCROLL_SENSITIVE
&& pViewData
->GetPosX(WhichH(eWhich
)) > 0 )
3349 if ( rMousePos
.X() >= aSize
.Width() - SCROLL_SENSITIVE
3350 && pViewData
->GetPosX(WhichH(eWhich
)) < MAXCOL
)
3353 if (aSize
.Height() > SCROLL_SENSITIVE
* 3)
3355 if ( rMousePos
.Y() < SCROLL_SENSITIVE
&& pViewData
->GetPosY(WhichV(eWhich
)) > 0 )
3357 if ( rMousePos
.Y() >= aSize
.Height() - SCROLL_SENSITIVE
3358 && pViewData
->GetPosY(WhichV(eWhich
)) < MAXROW
)
3362 if ( nDx
!= 0 || nDy
!= 0 )
3365 pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
3367 pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
3373 static sal_Bool
lcl_TestScenarioRedliningDrop( ScDocument
* pDoc
, const ScRange
& aDragRange
)
3375 // Testet, ob bei eingeschalteten RedLining,
3376 // bei einem Drop ein Scenario betroffen ist.
3378 sal_Bool bReturn
= false;
3379 SCTAB nTab
= aDragRange
.aStart
.Tab();
3380 SCTAB nTabCount
= pDoc
->GetTableCount();
3382 if(pDoc
->GetChangeTrack()!=NULL
)
3384 if( pDoc
->IsScenario(nTab
) && pDoc
->HasScenarioRange(nTab
, aDragRange
))
3390 for(SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
3392 if(pDoc
->HasScenarioRange(i
, aDragRange
))
3403 static ScRange
lcl_MakeDropRange( SCCOL nPosX
, SCROW nPosY
, SCTAB nTab
, const ScRange
& rSource
)
3405 SCCOL nCol1
= nPosX
;
3406 SCCOL nCol2
= nCol1
+ ( rSource
.aEnd
.Col() - rSource
.aStart
.Col() );
3407 if ( nCol2
> MAXCOL
)
3409 nCol1
-= nCol2
- MAXCOL
;
3412 SCROW nRow1
= nPosY
;
3413 SCROW nRow2
= nRow1
+ ( rSource
.aEnd
.Row() - rSource
.aStart
.Row() );
3414 if ( nRow2
> MAXROW
)
3416 nRow1
-= nRow2
- MAXROW
;
3420 return ScRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
3423 //--------------------------------------------------------
3425 extern sal_Bool bPasteIsDrop
; // viewfun4 -> move to header
3426 extern sal_Bool bPasteIsMove
; // viewfun7 -> move to header
3428 //--------------------------------------------------------
3430 sal_Int8
ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent
& rEvt
)
3432 if ( rEvt
.mbLeaving
)
3435 UpdateDragRectOverlay();
3436 return rEvt
.mnAction
;
3439 const ScDragData
& rData
= SC_MOD()->GetDragData();
3440 if ( rData
.pCellTransfer
)
3442 // Don't move source that would include filtered rows.
3443 if ((rEvt
.mnAction
& DND_ACTION_MOVE
) && rData
.pCellTransfer
->HasFilteredRows())
3448 UpdateDragRectOverlay();
3450 return DND_ACTION_NONE
;
3453 Point aPos
= rEvt
.maPosPixel
;
3455 ScDocument
* pSourceDoc
= rData
.pCellTransfer
->GetSourceDocument();
3456 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3457 if (pSourceDoc
== pThisDoc
)
3459 rtl::OUString aName
;
3460 if ( pThisDoc
->HasChartAtPoint(pViewData
->GetTabNo(), PixelToLogic(aPos
), aName
))
3462 if (bDragRect
) // Rechteck loeschen
3465 UpdateDragRectOverlay();
3468 //! highlight chart? (selection border?)
3470 sal_Int8 nRet
= rEvt
.mnAction
;
3475 if ( rData
.pCellTransfer
->GetDragSourceFlags() & SC_DROP_TABLE
) // whole sheet?
3477 sal_Bool bOk
= pThisDoc
->IsDocEditable();
3478 return bOk
? rEvt
.mnAction
: 0; // don't draw selection frame
3483 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3485 ScRange aSourceRange
= rData
.pCellTransfer
->GetRange();
3486 SCCOL nSourceStartX
= aSourceRange
.aStart
.Col();
3487 SCROW nSourceStartY
= aSourceRange
.aStart
.Row();
3488 SCCOL nSourceEndX
= aSourceRange
.aEnd
.Col();
3489 SCROW nSourceEndY
= aSourceRange
.aEnd
.Row();
3490 SCCOL nSizeX
= nSourceEndX
- nSourceStartX
+ 1;
3491 SCROW nSizeY
= nSourceEndY
- nSourceStartY
+ 1;
3493 if ( rEvt
.mnAction
!= DND_ACTION_MOVE
)
3494 nSizeY
= rData
.pCellTransfer
->GetNonFilteredRows(); // copy/link: no filtered rows
3496 SCsCOL nNewDragX
= nPosX
- rData
.pCellTransfer
->GetDragHandleX();
3497 if (nNewDragX
<0) nNewDragX
=0;
3498 if (nNewDragX
+(nSizeX
-1) > MAXCOL
)
3499 nNewDragX
= MAXCOL
-(nSizeX
-1);
3500 SCsROW nNewDragY
= nPosY
- rData
.pCellTransfer
->GetDragHandleY();
3501 if (nNewDragY
<0) nNewDragY
=0;
3502 if (nNewDragY
+(nSizeY
-1) > MAXROW
)
3503 nNewDragY
= MAXROW
-(nSizeY
-1);
3505 // don't break scenario ranges, don't drop on filtered
3506 SCTAB nTab
= pViewData
->GetTabNo();
3507 ScRange aDropRange
= lcl_MakeDropRange( nNewDragX
, nNewDragY
, nTab
, aSourceRange
);
3508 if ( lcl_TestScenarioRedliningDrop( pThisDoc
, aDropRange
) ||
3509 lcl_TestScenarioRedliningDrop( pSourceDoc
, aSourceRange
) ||
3510 ScViewUtil::HasFiltered( aDropRange
, pThisDoc
) )
3515 UpdateDragRectOverlay();
3517 return DND_ACTION_NONE
;
3520 InsCellCmd eDragInsertMode
= INS_NONE
;
3521 Window::PointerState aState
= GetPointerState();
3523 // check for datapilot item sorting
3524 ScDPObject
* pDPObj
= NULL
;
3525 if ( pThisDoc
== pSourceDoc
&& ( pDPObj
= pThisDoc
->GetDPAtCursor( nNewDragX
, nNewDragY
, nTab
) ) != NULL
)
3527 // drop on DataPilot table: sort or nothing
3529 bool bDPSort
= false;
3530 if ( pThisDoc
->GetDPAtCursor( nSourceStartX
, nSourceStartY
, aSourceRange
.aStart
.Tab() ) == pDPObj
)
3532 sheet::DataPilotTableHeaderData aDestData
;
3533 pDPObj
->GetHeaderPositionData( ScAddress(nNewDragX
, nNewDragY
, nTab
), aDestData
);
3534 bool bValid
= ( aDestData
.Dimension
>= 0 ); // dropping onto a field
3536 // look through the source range
3537 for (SCROW nRow
= aSourceRange
.aStart
.Row(); bValid
&& nRow
<= aSourceRange
.aEnd
.Row(); ++nRow
)
3538 for (SCCOL nCol
= aSourceRange
.aStart
.Col(); bValid
&& nCol
<= aSourceRange
.aEnd
.Col(); ++nCol
)
3540 sheet::DataPilotTableHeaderData aSourceData
;
3541 pDPObj
->GetHeaderPositionData( ScAddress( nCol
, nRow
, aSourceRange
.aStart
.Tab() ), aSourceData
);
3542 if ( aSourceData
.Dimension
!= aDestData
.Dimension
|| aSourceData
.MemberName
.isEmpty() )
3543 bValid
= false; // empty (subtotal) or different field
3549 OUString aDimName
= pDPObj
->GetDimName( aDestData
.Dimension
, bIsDataLayout
);
3550 const ScDPSaveDimension
* pDim
= pDPObj
->GetSaveData()->GetExistingDimensionByName( aDimName
);
3553 ScRange aOutRange
= pDPObj
->GetOutRange();
3555 sal_uInt16 nOrient
= pDim
->GetOrientation();
3556 if ( nOrient
== sheet::DataPilotFieldOrientation_COLUMN
)
3558 eDragInsertMode
= INS_CELLSRIGHT
;
3559 nSizeY
= aOutRange
.aEnd
.Row() - nNewDragY
+ 1;
3562 else if ( nOrient
== sheet::DataPilotFieldOrientation_ROW
)
3564 eDragInsertMode
= INS_CELLSDOWN
;
3565 nSizeX
= aOutRange
.aEnd
.Col() - nNewDragX
+ 1;
3574 // no valid sorting in a DataPilot table -> disallow
3578 UpdateDragRectOverlay();
3580 return DND_ACTION_NONE
;
3583 else if ( aState
.mnState
& KEY_MOD2
)
3585 if ( pThisDoc
== pSourceDoc
&& nTab
== aSourceRange
.aStart
.Tab() )
3587 long nDeltaX
= labs( static_cast< long >( nNewDragX
- nSourceStartX
) );
3588 long nDeltaY
= labs( static_cast< long >( nNewDragY
- nSourceStartY
) );
3589 if ( nDeltaX
<= nDeltaY
)
3591 eDragInsertMode
= INS_CELLSDOWN
;
3595 eDragInsertMode
= INS_CELLSRIGHT
;
3598 if ( ( eDragInsertMode
== INS_CELLSDOWN
&& nNewDragY
<= nSourceEndY
&&
3599 ( nNewDragX
+ nSizeX
- 1 ) >= nSourceStartX
&& nNewDragX
<= nSourceEndX
&&
3600 ( nNewDragX
!= nSourceStartX
|| nNewDragY
>= nSourceStartY
) ) ||
3601 ( eDragInsertMode
== INS_CELLSRIGHT
&& nNewDragX
<= nSourceEndX
&&
3602 ( nNewDragY
+ nSizeY
- 1 ) >= nSourceStartY
&& nNewDragY
<= nSourceEndY
&&
3603 ( nNewDragY
!= nSourceStartY
|| nNewDragX
>= nSourceStartX
) ) )
3608 UpdateDragRectOverlay();
3610 return DND_ACTION_NONE
;
3615 if ( static_cast< long >( nSizeX
) >= static_cast< long >( nSizeY
) )
3617 eDragInsertMode
= INS_CELLSDOWN
;
3622 eDragInsertMode
= INS_CELLSRIGHT
;
3627 if ( nNewDragX
!= (SCsCOL
) nDragStartX
|| nNewDragY
!= (SCsROW
) nDragStartY
||
3628 nDragStartX
+nSizeX
-1 != nDragEndX
|| nDragStartY
+nSizeY
-1 != nDragEndY
||
3629 !bDragRect
|| eDragInsertMode
!= meDragInsertMode
)
3631 nDragStartX
= nNewDragX
;
3632 nDragStartY
= nNewDragY
;
3633 nDragEndX
= nDragStartX
+nSizeX
-1;
3634 nDragEndY
= nDragStartY
+nSizeY
-1;
3636 meDragInsertMode
= eDragInsertMode
;
3638 UpdateDragRectOverlay();
3642 return rEvt
.mnAction
;
3645 sal_Int8
ScGridWindow::AcceptDrop( const AcceptDropEvent
& rEvt
)
3647 const ScDragData
& rData
= SC_MOD()->GetDragData();
3648 if ( rEvt
.mbLeaving
)
3650 DrawMarkDropObj( NULL
);
3651 if ( rData
.pCellTransfer
)
3652 return AcceptPrivateDrop( rEvt
); // hide drop marker for internal D&D
3654 return rEvt
.mnAction
;
3657 if ( pViewData
->GetDocShell()->IsReadOnly() )
3658 return DND_ACTION_NONE
;
3661 sal_Int8 nRet
= DND_ACTION_NONE
;
3663 if (rData
.pCellTransfer
)
3665 ScRange aSource
= rData
.pCellTransfer
->GetRange();
3666 if ( aSource
.aStart
.Col() != 0 || aSource
.aEnd
.Col() != MAXCOL
||
3667 aSource
.aStart
.Row() != 0 || aSource
.aEnd
.Row() != MAXROW
)
3668 DropScroll( rEvt
.maPosPixel
);
3670 nRet
= AcceptPrivateDrop( rEvt
);
3674 if ( !rData
.aLinkDoc
.isEmpty() )
3676 rtl::OUString aThisName
;
3677 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3678 if (pDocSh
&& pDocSh
->HasName())
3679 aThisName
= pDocSh
->GetMedium()->GetName();
3681 if ( !rData
.aLinkDoc
.equals(aThisName
) )
3682 nRet
= rEvt
.mnAction
;
3684 else if (!rData
.aJumpTarget
.isEmpty())
3686 // internal bookmarks (from Navigator)
3687 // local jumps from an unnamed document are possible only within a document
3689 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
3690 nRet
= rEvt
.mnAction
;
3694 sal_Int8 nMyAction
= rEvt
.mnAction
;
3696 if ( !rData
.pDrawTransfer
||
3697 !IsMyModel(rData
.pDrawTransfer
->GetDragSourceView()) ) // drawing within the document
3698 if ( rEvt
.mbDefault
&& nMyAction
== DND_ACTION_MOVE
)
3699 nMyAction
= DND_ACTION_COPY
;
3701 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3702 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint(
3703 pViewData
->GetTabNo(), PixelToLogic(rEvt
.maPosPixel
) );
3704 if ( pHitObj
&& nMyAction
== DND_ACTION_LINK
&& !rData
.pDrawTransfer
)
3706 if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB
)
3707 || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE
)
3708 || IsDropFormatSupported(SOT_FORMAT_BITMAP
) )
3710 // graphic dragged onto drawing object
3711 DrawMarkDropObj( pHitObj
);
3716 DrawMarkDropObj( NULL
);
3720 switch ( nMyAction
)
3722 case DND_ACTION_COPY
:
3723 case DND_ACTION_MOVE
:
3724 case DND_ACTION_COPYMOVE
:
3726 sal_Bool bMove
= ( nMyAction
== DND_ACTION_MOVE
);
3727 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE
) ||
3728 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3729 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) ||
3730 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3731 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) ||
3732 IsDropFormatSupported( SOT_FORMAT_STRING
) ||
3733 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK
) ||
3734 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3735 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML
) ||
3736 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE
) ||
3737 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF
) ||
3738 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING
) ||
3739 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB
) ||
3740 IsDropFormatSupported( SOT_FORMAT_RTF
) ||
3741 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE
) ||
3742 IsDropFormatSupported( SOT_FORMAT_BITMAP
) ||
3743 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) ||
3744 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) ||
3746 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3747 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3748 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3749 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3750 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3751 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) ) ) )
3757 case DND_ACTION_LINK
:
3758 if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE
) ||
3759 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) ||
3760 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK
) ||
3761 IsDropFormatSupported( SOT_FORMAT_FILE_LIST
) ||
3762 IsDropFormatSupported( SOT_FORMAT_FILE
) ||
3763 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK
) ||
3764 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) ||
3765 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) ||
3766 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3775 // Simple check for protection: It's not known here if the drop will result
3776 // in cells or drawing objects (some formats can be both) and how many cells
3777 // the result will be. But if IsFormatEditable for the drop cell position
3778 // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
3779 // can already be rejected here.
3781 Point aPos
= rEvt
.maPosPixel
;
3784 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
3785 SCTAB nTab
= pViewData
->GetTabNo();
3786 ScDocument
* pDoc
= pViewData
->GetDocument();
3788 ScEditableTester
aTester( pDoc
, nTab
, nPosX
,nPosY
, nPosX
,nPosY
);
3789 if ( !aTester
.IsFormatEditable() )
3790 nRet
= DND_ACTION_NONE
; // forbidden
3795 // scroll only for accepted formats
3797 DropScroll( rEvt
.maPosPixel
);
3803 static sal_uLong
lcl_GetDropFormatId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
, bool bPreferText
= false )
3805 TransferableDataHelper
aDataHelper( xTransfer
);
3807 if ( !aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3809 // use bookmark formats if no sba is present
3811 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3812 return SOT_FORMATSTR_ID_SOLK
;
3813 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3814 return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3815 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3816 return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3817 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3818 return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3821 sal_uLong nFormatId
= 0;
3822 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_DRAWING
) )
3823 nFormatId
= SOT_FORMATSTR_ID_DRAWING
;
3824 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SVXB
) )
3825 nFormatId
= SOT_FORMATSTR_ID_SVXB
;
3826 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
) )
3828 // If it's a Writer object, insert RTF instead of OLE
3830 sal_Bool bDoRtf
= false;
3831 SotStorageStreamRef xStm
;
3832 TransferableObjectDescriptor aObjDesc
;
3833 if( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
) &&
3834 aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE
, xStm
) )
3836 SotStorageRef
xStore( new SotStorage( *xStm
) );
3837 bDoRtf
= ( ( aObjDesc
.maClassName
== SvGlobalName( SO3_SW_CLASSID
) ||
3838 aObjDesc
.maClassName
== SvGlobalName( SO3_SWWEB_CLASSID
) )
3839 && aDataHelper
.HasFormat( SOT_FORMAT_RTF
) );
3842 nFormatId
= FORMAT_RTF
;
3844 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE
;
3846 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3847 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3848 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
) )
3849 nFormatId
= SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
;
3850 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
) )
3851 nFormatId
= SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
;
3852 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_8
) )
3853 nFormatId
= SOT_FORMATSTR_ID_BIFF_8
;
3854 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_BIFF_5
) )
3855 nFormatId
= SOT_FORMATSTR_ID_BIFF_5
;
3856 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
) )
3857 nFormatId
= SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
;
3858 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
) )
3859 nFormatId
= SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
;
3860 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3861 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3862 else if ( aDataHelper
.HasFormat( SOT_FORMAT_RTF
) )
3863 nFormatId
= SOT_FORMAT_RTF
;
3864 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML
) )
3865 nFormatId
= SOT_FORMATSTR_ID_HTML
;
3866 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE
) )
3867 nFormatId
= SOT_FORMATSTR_ID_HTML_SIMPLE
;
3868 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SYLK
) )
3869 nFormatId
= SOT_FORMATSTR_ID_SYLK
;
3870 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3871 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3872 else if ( bPreferText
&& aDataHelper
.HasFormat( SOT_FORMAT_STRING
) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3873 nFormatId
= SOT_FORMAT_STRING
;
3874 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3875 nFormatId
= SOT_FORMAT_FILE_LIST
;
3876 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3877 nFormatId
= SOT_FORMAT_FILE
;
3878 else if ( aDataHelper
.HasFormat( SOT_FORMAT_STRING
) )
3879 nFormatId
= SOT_FORMAT_STRING
;
3880 else if ( aDataHelper
.HasFormat( SOT_FORMAT_GDIMETAFILE
) )
3881 nFormatId
= SOT_FORMAT_GDIMETAFILE
;
3882 else if ( aDataHelper
.HasFormat( SOT_FORMAT_BITMAP
) )
3883 nFormatId
= SOT_FORMAT_BITMAP
;
3888 static sal_uLong
lcl_GetDropLinkId( const uno::Reference
<datatransfer::XTransferable
>& xTransfer
)
3890 TransferableDataHelper
aDataHelper( xTransfer
);
3892 sal_uLong nFormatId
= 0;
3893 if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE
) )
3894 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE
;
3895 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE
) )
3896 nFormatId
= SOT_FORMATSTR_ID_LINK_SOURCE_OLE
;
3897 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_LINK
) )
3898 nFormatId
= SOT_FORMATSTR_ID_LINK
;
3899 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE_LIST
) )
3900 nFormatId
= SOT_FORMAT_FILE_LIST
;
3901 else if ( aDataHelper
.HasFormat( SOT_FORMAT_FILE
) )
3902 nFormatId
= SOT_FORMAT_FILE
;
3903 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_SOLK
) )
3904 nFormatId
= SOT_FORMATSTR_ID_SOLK
;
3905 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
) )
3906 nFormatId
= SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
;
3907 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
) )
3908 nFormatId
= SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
;
3909 else if ( aDataHelper
.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
) )
3910 nFormatId
= SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
;
3916 sal_Int8
ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent
& rEvt
)
3920 UpdateDragRectOverlay();
3922 ScModule
* pScMod
= SC_MOD();
3923 const ScDragData
& rData
= pScMod
->GetDragData();
3925 return DropTransferObj( rData
.pCellTransfer
, nDragStartX
, nDragStartY
,
3926 PixelToLogic(rEvt
.maPosPixel
), rEvt
.mnAction
);
3929 sal_Int8
ScGridWindow::DropTransferObj( ScTransferObj
* pTransObj
, SCCOL nDestPosX
, SCROW nDestPosY
,
3930 const Point
& rLogicPos
, sal_Int8 nDndAction
)
3935 ScDocument
* pSourceDoc
= pTransObj
->GetSourceDocument();
3936 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
3937 ScDocument
* pThisDoc
= pViewData
->GetDocument();
3938 ScViewFunc
* pView
= pViewData
->GetView();
3939 SCTAB nThisTab
= pViewData
->GetTabNo();
3940 sal_uInt16 nFlags
= pTransObj
->GetDragSourceFlags();
3942 sal_Bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
3943 sal_Bool bIsMove
= ( nDndAction
== DND_ACTION_MOVE
&& !bIsNavi
);
3945 // workaround for wrong nDndAction on Windows when pressing solely
3946 // the Alt key during drag and drop;
3947 // can be removed after #i79215# has been fixed
3948 if ( meDragInsertMode
!= INS_NONE
)
3950 bIsMove
= ( nDndAction
& DND_ACTION_MOVE
&& !bIsNavi
);
3953 sal_Bool bIsLink
= ( nDndAction
== DND_ACTION_LINK
);
3955 ScRange aSource
= pTransObj
->GetRange();
3957 // only use visible tab from source range - when dragging within one table,
3958 // all selected tables at the time of dropping are used (handled in MoveBlockTo)
3959 SCTAB nSourceTab
= pTransObj
->GetVisibleTab();
3960 aSource
.aStart
.SetTab( nSourceTab
);
3961 aSource
.aEnd
.SetTab( nSourceTab
);
3963 SCCOL nSizeX
= aSource
.aEnd
.Col() - aSource
.aStart
.Col() + 1;
3964 SCROW nSizeY
= (bIsMove
? (aSource
.aEnd
.Row() - aSource
.aStart
.Row() + 1) :
3965 pTransObj
->GetNonFilteredRows()); // copy/link: no filtered rows
3966 ScRange
aDest( nDestPosX
, nDestPosY
, nThisTab
,
3967 nDestPosX
+ nSizeX
- 1, nDestPosY
+ nSizeY
- 1, nThisTab
);
3970 /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3971 * dragging and adapted drawing of the selection frame. We check here
3972 * (again) because this may actually also be called from PasteSelection(),
3973 * we would have to duplicate determination of flags and destination range
3974 * and would lose the context of the "filtered destination is OK" cases
3975 * below, which is already awkward enough as is. */
3977 // Don't move filtered source.
3978 bool bFiltered
= (bIsMove
&& pTransObj
->HasFilteredRows());
3981 if (pSourceDoc
!= pThisDoc
&& ((nFlags
& SC_DROP_TABLE
) ||
3982 (!bIsLink
&& meDragInsertMode
== INS_NONE
)))
3984 // Nothing. Either entire sheet to be dropped, or the one case
3985 // where PasteFromClip() is to be called that handles a filtered
3986 // destination itself. Drag-copy from another document without
3990 // Don't copy or move to filtered destination.
3991 bFiltered
= ScViewUtil::HasFiltered( aDest
, pThisDoc
);
3994 sal_Bool bDone
= false;
3996 if (!bFiltered
&& pSourceDoc
== pThisDoc
)
3998 if ( nFlags
& SC_DROP_TABLE
) // whole sheet?
4000 if ( pThisDoc
->IsDocEditable() )
4002 SCTAB nSrcTab
= aSource
.aStart
.Tab();
4003 pViewData
->GetDocShell()->MoveTable( nSrcTab
, nThisTab
, !bIsMove
, sal_True
); // with Undo
4004 pView
->SetTabNo( nThisTab
, sal_True
);
4008 else // move/copy block
4010 rtl::OUString aChartName
;
4011 if (pThisDoc
->HasChartAtPoint( nThisTab
, rLogicPos
, aChartName
))
4014 aSource
.Format( aRangeName
, SCR_ABS_3D
, pThisDoc
);
4015 SfxStringItem
aNameItem( SID_CHART_NAME
, aChartName
);
4016 SfxStringItem
aRangeItem( SID_CHART_SOURCE
, aRangeName
);
4017 sal_uInt16 nId
= bIsMove
? SID_CHART_SOURCE
: SID_CHART_ADDSOURCE
;
4018 pViewData
->GetDispatcher().Execute( nId
, SFX_CALLMODE_ASYNCHRON
| SFX_CALLMODE_RECORD
,
4019 &aRangeItem
, &aNameItem
, (void*) NULL
);
4022 else if ( pThisDoc
->GetDPAtCursor( nDestPosX
, nDestPosY
, nThisTab
) )
4024 // drop on DataPilot table: try to sort, fail if that isn't possible
4026 ScAddress
aDestPos( nDestPosX
, nDestPosY
, nThisTab
);
4027 if ( aDestPos
!= aSource
.aStart
)
4028 bDone
= pViewData
->GetView()->DataPilotMove( aSource
, aDestPos
);
4030 bDone
= sal_True
; // same position: nothing
4032 else if ( nDestPosX
!= aSource
.aStart
.Col() || nDestPosY
!= aSource
.aStart
.Row() ||
4033 nSourceTab
!= nThisTab
)
4035 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4036 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4038 SCsCOL nCorrectCursorPosCol
= 0;
4039 SCsROW nCorrectCursorPosRow
= 0;
4042 if ( meDragInsertMode
!= INS_NONE
)
4044 // call with bApi = sal_True to avoid error messages in drop handler
4045 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, sal_True
/*bRecord*/, sal_True
/*bApi*/, sal_True
/*bPartOfPaste*/ );
4048 if ( nThisTab
== nSourceTab
)
4050 if ( meDragInsertMode
== INS_CELLSDOWN
&&
4051 nDestPosX
== aSource
.aStart
.Col() && nDestPosY
< aSource
.aStart
.Row() )
4053 bDone
= aSource
.Move( 0, nSizeY
, 0, pSourceDoc
);
4054 nCorrectCursorPosRow
= nSizeY
;
4056 else if ( meDragInsertMode
== INS_CELLSRIGHT
&&
4057 nDestPosY
== aSource
.aStart
.Row() && nDestPosX
< aSource
.aStart
.Col() )
4059 bDone
= aSource
.Move( nSizeX
, 0, 0, pSourceDoc
);
4060 nCorrectCursorPosCol
= nSizeX
;
4063 pDocSh
->UpdateOle( pViewData
);
4064 pView
->CellContentChanged();
4072 // call with bApi = sal_True to avoid error messages in drop handler
4073 bDone
= pView
->LinkBlock( aSource
, aDest
.aStart
, sal_True
/*bApi*/ );
4077 // call with bApi = sal_True to avoid error messages in drop handler
4078 bDone
= pView
->MoveBlockTo( aSource
, aDest
.aStart
, bIsMove
, sal_True
/*bRecord*/, sal_True
/*bPaint*/, sal_True
/*bApi*/ );
4082 if ( bDone
&& meDragInsertMode
!= INS_NONE
&& bIsMove
&& nThisTab
== nSourceTab
)
4084 DelCellCmd eCmd
= DEL_NONE
;
4085 if ( meDragInsertMode
== INS_CELLSDOWN
)
4089 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
4091 eCmd
= DEL_CELLSLEFT
;
4094 if ( ( eCmd
== DEL_CELLSUP
&& nDestPosX
== aSource
.aStart
.Col() ) ||
4095 ( eCmd
== DEL_CELLSLEFT
&& nDestPosY
== aSource
.aStart
.Row() ) )
4097 // call with bApi = sal_True to avoid error messages in drop handler
4098 bDone
= pDocSh
->GetDocFunc().DeleteCells( aSource
, NULL
, eCmd
, sal_True
/*bRecord*/, sal_True
/*bApi*/ );
4101 if ( eCmd
== DEL_CELLSUP
&& nDestPosY
> aSource
.aEnd
.Row() )
4103 bDone
= aDest
.Move( 0, -nSizeY
, 0, pThisDoc
);
4105 else if ( eCmd
== DEL_CELLSLEFT
&& nDestPosX
> aSource
.aEnd
.Col() )
4107 bDone
= aDest
.Move( -nSizeX
, 0, 0, pThisDoc
);
4109 pDocSh
->UpdateOle( pViewData
);
4110 pView
->CellContentChanged();
4117 pView
->MarkRange( aDest
, false, false );
4119 SCCOL nDCol
= pViewData
->GetCurX() - aSource
.aStart
.Col() + nCorrectCursorPosCol
;
4120 SCROW nDRow
= pViewData
->GetCurY() - aSource
.aStart
.Row() + nCorrectCursorPosRow
;
4121 pView
->SetCursor( aDest
.aStart
.Col() + nDCol
, aDest
.aStart
.Row() + nDRow
);
4124 pDocSh
->GetUndoManager()->LeaveListAction();
4128 bDone
= sal_True
; // nothing to do
4132 pTransObj
->SetDragWasInternal(); // don't delete source in DragFinished
4134 else if ( !bFiltered
&& pSourceDoc
) // between documents
4136 if ( nFlags
& SC_DROP_TABLE
) // copy/link sheets between documents
4138 if ( pThisDoc
->IsDocEditable() )
4140 ScDocShell
* pSrcShell
= pTransObj
->GetSourceDocShell();
4142 std::vector
<SCTAB
> nTabs
;
4144 ScMarkData aMark
= pTransObj
->GetSourceMarkData();
4145 SCTAB nTabCount
= pSourceDoc
->GetTableCount();
4147 for(SCTAB i
=0; i
<nTabCount
; i
++)
4149 if(aMark
.GetTableSelect(i
))
4152 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
4154 if((!pSourceDoc
->IsVisible(j
))&&(pSourceDoc
->IsScenario(j
)))
4156 nTabs
.push_back( j
);
4164 pView
->ImportTables( pSrcShell
,static_cast<SCTAB
>(nTabs
.size()), &nTabs
[0], bIsLink
, nThisTab
);
4171 // (external references might be used instead?)
4173 SfxObjectShell
* pSourceSh
= pSourceDoc
->GetDocumentShell();
4174 OSL_ENSURE(pSourceSh
, "drag document has no shell");
4177 String aUndo
= ScGlobal::GetRscString( STR_UNDO_COPY
);
4178 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4181 if ( meDragInsertMode
!= INS_NONE
)
4183 // call with bApi = sal_True to avoid error messages in drop handler
4184 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, sal_True
/*bRecord*/, sal_True
/*bApi*/, sal_True
/*bPartOfPaste*/ );
4187 pDocSh
->UpdateOle( pViewData
);
4188 pView
->CellContentChanged();
4194 String aApp
= Application::GetAppName();
4195 String aTopic
= pSourceSh
->GetTitle( SFX_TITLE_FULLNAME
);
4197 aSource
.Format( aItem
, SCA_VALID
| SCA_TAB_3D
, pSourceDoc
);
4199 // TODO: we could define ocQuote for "
4200 const rtl::OUString
aQuote('"');
4201 const String
& sSep
= ScCompiler::GetNativeSymbol( ocSep
);
4202 rtl::OUStringBuffer aFormula
;
4203 aFormula
.append('=');
4204 aFormula
.append(ScCompiler::GetNativeSymbol(ocDde
));
4205 aFormula
.append(ScCompiler::GetNativeSymbol(ocOpen
));
4206 aFormula
.append(aQuote
);
4207 aFormula
.append(aApp
);
4208 aFormula
.append(aQuote
);
4209 aFormula
.append(sSep
);
4210 aFormula
.append(aQuote
);
4211 aFormula
.append(aTopic
);
4212 aFormula
.append(aQuote
);
4213 aFormula
.append(sSep
);
4214 aFormula
.append(aQuote
);
4215 aFormula
.append(aItem
);
4216 aFormula
.append(aQuote
);
4217 aFormula
.append(ScCompiler::GetNativeSymbol(ocClose
));
4219 pView
->DoneBlockMode();
4220 pView
->InitBlockMode( nDestPosX
, nDestPosY
, nThisTab
);
4221 pView
->MarkCursor( nDestPosX
+ nSizeX
- 1,
4222 nDestPosY
+ nSizeY
- 1, nThisTab
);
4224 pView
->EnterMatrix( aFormula
.makeStringAndClear(), ::formula::FormulaGrammar::GRAM_NATIVE
);
4226 pView
->MarkRange( aDest
, false, false );
4227 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4230 pDocSh
->GetUndoManager()->LeaveListAction();
4235 //! HasSelectedBlockMatrixFragment without selected sheet?
4236 //! or don't start dragging on a part of a matrix
4238 String aUndo
= ScGlobal::GetRscString( bIsMove
? STR_UNDO_MOVE
: STR_UNDO_COPY
);
4239 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
);
4242 if ( meDragInsertMode
!= INS_NONE
)
4244 // call with bApi = sal_True to avoid error messages in drop handler
4245 bDone
= pDocSh
->GetDocFunc().InsertCells( aDest
, NULL
, meDragInsertMode
, sal_True
/*bRecord*/, sal_True
/*bApi*/, sal_True
/*bPartOfPaste*/ );
4248 pDocSh
->UpdateOle( pViewData
);
4249 pView
->CellContentChanged();
4255 pView
->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4256 pView
->SetCursor( nDestPosX
, nDestPosY
);
4257 bDone
= pView
->PasteFromClip( IDF_ALL
, pTransObj
->GetDocument() ); // clip-doc
4260 pView
->MarkRange( aDest
, false, false );
4261 pView
->SetCursor( aDest
.aStart
.Col(), aDest
.aStart
.Row() );
4265 pDocSh
->GetUndoManager()->LeaveListAction();
4267 // no longer call ResetMark here - the inserted block has been selected
4268 // and may have been copied to primary selection
4272 sal_Int8 nRet
= bDone
? nDndAction
: DND_ACTION_NONE
;
4276 sal_Int8
ScGridWindow::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
4278 DrawMarkDropObj( NULL
); // drawing layer
4280 ScModule
* pScMod
= SC_MOD();
4281 const ScDragData
& rData
= pScMod
->GetDragData();
4282 if (rData
.pCellTransfer
)
4283 return ExecutePrivateDrop( rEvt
);
4285 Point aPos
= rEvt
.maPosPixel
;
4287 if ( !rData
.aLinkDoc
.isEmpty() )
4289 // try to insert a link
4292 rtl::OUString aThisName
;
4293 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4294 if (pDocSh
&& pDocSh
->HasName())
4295 aThisName
= pDocSh
->GetMedium()->GetName();
4297 if ( rData
.aLinkDoc
.equals(aThisName
) ) // error - no link within a document
4301 ScViewFunc
* pView
= pViewData
->GetView();
4302 if ( !rData
.aLinkTable
.isEmpty() )
4303 pView
->InsertTableLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4305 else if ( !rData
.aLinkArea
.isEmpty() )
4309 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4310 pView
->MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, false, false );
4312 pView
->InsertAreaLink( rData
.aLinkDoc
, EMPTY_STRING
, EMPTY_STRING
,
4313 rData
.aLinkArea
, 0 );
4317 OSL_FAIL("drop with link: no sheet nor area");
4322 return bOk
? rEvt
.mnAction
: DND_ACTION_NONE
; // don't try anything else
4325 Point aLogicPos
= PixelToLogic(aPos
);
4327 if (rData
.pDrawTransfer
)
4329 sal_uInt16 nFlags
= rData
.pDrawTransfer
->GetDragSourceFlags();
4331 sal_Bool bIsNavi
= ( nFlags
& SC_DROP_NAVIGATOR
) != 0;
4332 sal_Bool bIsMove
= ( rEvt
.mnAction
== DND_ACTION_MOVE
&& !bIsNavi
);
4334 bPasteIsMove
= bIsMove
;
4336 pViewData
->GetView()->PasteDraw( aLogicPos
, rData
.pDrawTransfer
->GetModel() );
4339 rData
.pDrawTransfer
->SetDragWasInternal();
4340 bPasteIsMove
= false;
4342 return rEvt
.mnAction
;
4348 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4350 if (!rData
.aJumpTarget
.isEmpty())
4352 // internal bookmark (from Navigator)
4353 // bookmark clipboard formats are in PasteScDataObject
4355 if ( !rData
.pJumpLocalDoc
|| rData
.pJumpLocalDoc
== pViewData
->GetDocument() )
4357 pViewData
->GetViewShell()->InsertBookmark( rData
.aJumpText
, rData
.aJumpTarget
,
4359 return rEvt
.mnAction
;
4363 sal_Bool bIsLink
= ( rEvt
.mnAction
== DND_ACTION_LINK
);
4365 ScDocument
* pThisDoc
= pViewData
->GetDocument();
4366 SdrObject
* pHitObj
= pThisDoc
->GetObjectAtPoint( pViewData
->GetTabNo(), PixelToLogic(aPos
) );
4367 if ( pHitObj
&& bIsLink
)
4369 // dropped on drawing object
4370 // PasteOnDrawObject checks for valid formats
4371 if ( pViewData
->GetView()->PasteOnDrawObject( rEvt
.maDropEvent
.Transferable
, pHitObj
, sal_True
) )
4372 return rEvt
.mnAction
;
4375 sal_Bool bDone
= false;
4377 sal_uLong nFormatId
= bIsLink
?
4378 lcl_GetDropLinkId( rEvt
.maDropEvent
.Transferable
) :
4379 lcl_GetDropFormatId( rEvt
.maDropEvent
.Transferable
);
4382 pScMod
->SetInExecuteDrop( sal_True
); // #i28468# prevent error messages from PasteDataFormat
4383 bPasteIsDrop
= sal_True
;
4384 bDone
= pViewData
->GetView()->PasteDataFormat(
4385 nFormatId
, rEvt
.maDropEvent
.Transferable
, nPosX
, nPosY
, &aLogicPos
, bIsLink
);
4386 bPasteIsDrop
= false;
4387 pScMod
->SetInExecuteDrop( false );
4390 sal_Int8 nRet
= bDone
? rEvt
.mnAction
: DND_ACTION_NONE
;
4394 //--------------------------------------------------------
4396 void ScGridWindow::PasteSelection( const Point
& rPosPixel
)
4398 Point aLogicPos
= PixelToLogic( rPosPixel
);
4402 pViewData
->GetPosFromPixel( rPosPixel
.X(), rPosPixel
.Y(), eWhich
, nPosX
, nPosY
);
4404 // If the mouse down was inside a visible note window, ignore it and
4405 // leave it up to the ScPostIt to handle it
4406 SdrView
* pDrawView
= pViewData
->GetViewShell()->GetSdrView();
4409 sal_uLong nCount
= pDrawView
->GetMarkedObjectCount();
4410 for (sal_uLong i
= 0; i
< nCount
; ++i
)
4412 SdrObject
* pObj
= pDrawView
->GetMarkedObjectByIndex(i
);
4413 if (pObj
&& pObj
->GetLogicRect().IsInside(aLogicPos
))
4415 // Inside an active drawing object. Bail out.
4421 ScSelectionTransferObj
* pOwnSelection
= SC_MOD()->GetSelectionTransfer();
4422 if ( pOwnSelection
)
4426 ScTransferObj
* pCellTransfer
= pOwnSelection
->GetCellData();
4427 if ( pCellTransfer
)
4429 // keep a reference to the data in case the selection is changed during paste
4430 uno::Reference
<datatransfer::XTransferable
> xRef( pCellTransfer
);
4431 DropTransferObj( pCellTransfer
, nPosX
, nPosY
, aLogicPos
, DND_ACTION_COPY
);
4435 ScDrawTransferObj
* pDrawTransfer
= pOwnSelection
->GetDrawData();
4436 if ( pDrawTransfer
)
4438 // keep a reference to the data in case the selection is changed during paste
4439 uno::Reference
<datatransfer::XTransferable
> xRef( pDrawTransfer
);
4441 // bSameDocClipboard argument for PasteDraw is needed
4442 // because only DragData is checked directly inside PasteDraw
4443 pViewData
->GetView()->PasteDraw( aLogicPos
, pDrawTransfer
->GetModel(), false,
4444 pDrawTransfer
->GetSourceDocID() == pViewData
->GetDocument()->GetDocumentID() );
4450 // get selection from system
4452 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4453 uno::Reference
<datatransfer::XTransferable
> xTransferable
= aDataHelper
.GetTransferable();
4454 if ( xTransferable
.is() )
4456 sal_uLong nFormatId
= lcl_GetDropFormatId( xTransferable
, true );
4459 bPasteIsDrop
= sal_True
;
4460 pViewData
->GetView()->PasteDataFormat( nFormatId
, xTransferable
, nPosX
, nPosY
, &aLogicPos
);
4461 bPasteIsDrop
= false;
4467 //--------------------------------------------------------
4469 void ScGridWindow::UpdateEditViewPos()
4471 if (pViewData
->HasEditView(eWhich
))
4476 pViewData
->GetEditView( eWhich
, pView
, nCol
, nRow
);
4477 SCCOL nEndCol
= pViewData
->GetEditEndCol();
4478 SCROW nEndRow
= pViewData
->GetEditEndRow();
4482 sal_Bool bHide
= ( nEndCol
<pViewData
->GetPosX(eHWhich
) || nEndRow
<pViewData
->GetPosY(eVWhich
) );
4483 if ( SC_MOD()->IsFormulaMode() )
4484 if ( pViewData
->GetTabNo() != pViewData
->GetRefTabNo() )
4489 Rectangle aRect
= pView
->GetOutputArea();
4490 long nHeight
= aRect
.Bottom() - aRect
.Top();
4491 aRect
.Top() = PixelToLogic(GetOutputSizePixel(), pViewData
->GetLogicMode()).
4493 aRect
.Bottom() = aRect
.Top() + nHeight
;
4494 pView
->SetOutputArea( aRect
);
4495 pView
->HideCursor();
4499 // bForceToTop = sal_True for editing
4500 Rectangle aPixRect
= pViewData
->GetEditArea( eWhich
, nCol
, nRow
, this, NULL
, sal_True
);
4501 Point aScrPos
= PixelToLogic( aPixRect
.TopLeft(), pViewData
->GetLogicMode() );
4503 Rectangle aRect
= pView
->GetOutputArea();
4504 aRect
.SetPos( aScrPos
);
4505 pView
->SetOutputArea( aRect
);
4506 pView
->ShowCursor();
4511 void ScGridWindow::ScrollPixel( long nDifX
, long nDifY
)
4518 SetMapMode(MAP_PIXEL
);
4519 Scroll( nDifX
, nDifY
, SCROLL_CHILDREN
);
4520 SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
4522 UpdateEditViewPos();
4525 bIsInScroll
= false;
4528 // Formeln neu zeichnen -------------------------------------------------
4530 void ScGridWindow::UpdateFormulas()
4532 if (pViewData
->GetView()->IsMinimized())
4537 // nicht anfangen, verschachtelt zu painten
4538 // (dann wuerde zumindest der MapMode nicht mehr stimmen)
4540 bNeedsRepaint
= true; // -> am Ende vom Paint nochmal Invalidate auf alles
4541 aRepaintPixel
= Rectangle(); // alles
4545 SCCOL nX1
= pViewData
->GetPosX( eHWhich
);
4546 SCROW nY1
= pViewData
->GetPosY( eVWhich
);
4547 SCCOL nX2
= nX1
+ pViewData
->VisibleCellsX( eHWhich
);
4548 SCROW nY2
= nY1
+ pViewData
->VisibleCellsY( eVWhich
);
4550 if (nX2
> MAXCOL
) nX2
= MAXCOL
;
4551 if (nY2
> MAXROW
) nY2
= MAXROW
;
4553 // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4555 // don't draw directly - instead use OutputData to find changed area and invalidate
4559 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4560 ScDocument
* pDoc
= pDocSh
->GetDocument();
4561 SCTAB nTab
= pViewData
->GetTabNo();
4563 pDoc
->ExtendHidden( nX1
, nY1
, nX2
, nY2
, nTab
);
4565 Point aScrPos
= pViewData
->GetScrPos( nX1
, nY1
, eWhich
);
4566 long nMirrorWidth
= GetSizePixel().Width();
4567 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4570 long nEndPixel
= pViewData
->GetScrPos( nX2
+1, nPosY
, eWhich
).X();
4571 nMirrorWidth
= aScrPos
.X() - nEndPixel
;
4572 aScrPos
.X() = nEndPixel
+ 1;
4575 long nScrX
= aScrPos
.X();
4576 long nScrY
= aScrPos
.Y();
4578 double nPPTX
= pViewData
->GetPPTX();
4579 double nPPTY
= pViewData
->GetPPTY();
4581 ScTableInfo aTabInfo
;
4582 pDoc
->FillInfo( aTabInfo
, nX1
, nY1
, nX2
, nY2
, nTab
, nPPTX
, nPPTY
, false, false );
4584 Fraction aZoomX
= pViewData
->GetZoomX();
4585 Fraction aZoomY
= pViewData
->GetZoomY();
4586 ScOutputData
aOutputData( this, OUTTYPE_WINDOW
, aTabInfo
, pDoc
, nTab
,
4587 nScrX
, nScrY
, nX1
, nY1
, nX2
, nY2
, nPPTX
, nPPTY
,
4589 aOutputData
.SetMirrorWidth( nMirrorWidth
);
4591 aOutputData
.FindChanged();
4593 PolyPolygon
aChangedPoly( aOutputData
.GetChangedArea() ); // logic (PixelToLogic)
4594 if ( aChangedPoly
.Count() )
4596 Invalidate( aChangedPoly
);
4599 CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
4602 void ScGridWindow::UpdateAutoFillMark(bool bMarked
, const ScRange
& rMarkRange
)
4604 if ( bMarked
!= bAutoMarkVisible
|| ( bMarked
&& rMarkRange
.aEnd
!= aAutoMarkPos
) )
4606 bAutoMarkVisible
= bMarked
;
4608 aAutoMarkPos
= rMarkRange
.aEnd
;
4610 UpdateAutoFillOverlay();
4614 void ScGridWindow::UpdateListValPos( bool bVisible
, const ScAddress
& rPos
)
4616 bool bOldButton
= bListValButton
;
4617 ScAddress aOldPos
= aListValPos
;
4619 bListValButton
= bVisible
;
4622 if ( bListValButton
)
4624 if ( !bOldButton
|| aListValPos
!= aOldPos
)
4626 // paint area of new button
4627 Invalidate( PixelToLogic( GetListValButtonRect( aListValPos
) ) );
4632 if ( !bListValButton
|| aListValPos
!= aOldPos
)
4634 // paint area of old button
4635 Invalidate( PixelToLogic( GetListValButtonRect( aOldPos
) ) );
4640 void ScGridWindow::HideCursor()
4645 void ScGridWindow::ShowCursor()
4650 void ScGridWindow::GetFocus()
4652 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4653 pViewShell
->GotFocus();
4654 pViewShell
->SetFormShellAtTop( false ); // focus in GridWindow -> FormShell no longer on top
4656 if (pViewShell
->HasAccessibilityObjects())
4657 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich
, GetAccessible()));
4660 if ( !SC_MOD()->IsFormulaMode() )
4662 pViewShell
->UpdateInputHandler();
4663 // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
4664 // MO: nur wenn nicht im RefInput-Modus
4665 // -> GetFocus/MouseButtonDown-Reihenfolge
4669 pViewData
->GetDocShell()->CheckConfigOptions();
4673 void ScGridWindow::LoseFocus()
4675 ScTabViewShell
* pViewShell
= pViewData
->GetViewShell();
4676 pViewShell
->LostFocus();
4678 if (pViewShell
->HasAccessibilityObjects())
4679 pViewShell
->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich
, GetAccessible()));
4681 Window::LoseFocus();
4684 Point
ScGridWindow::GetMousePosPixel() const { return aCurMousePos
; }
4686 //------------------------------------------------------------------------
4688 bool ScGridWindow::HitRangeFinder( const Point
& rMouse
, bool& rCorner
,
4689 sal_uInt16
* pIndex
, SCsCOL
* pAddX
, SCsROW
* pAddY
)
4691 bool bFound
= false;
4692 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4695 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4696 if ( pRangeFinder
&& !pRangeFinder
->IsHidden() &&
4697 pRangeFinder
->GetDocName() == pViewData
->GetDocShell()->GetTitle() )
4699 ScDocument
* pDoc
= pViewData
->GetDocument();
4700 SCTAB nTab
= pViewData
->GetTabNo();
4701 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
4702 long nLayoutSign
= bLayoutRTL
? -1 : 1;
4706 pViewData
->GetPosFromPixel( rMouse
.X(), rMouse
.Y(), eWhich
, nPosX
, nPosY
);
4707 // zusammengefasste (einzeln/Bereich) ???
4708 ScAddress
aAddr( nPosX
, nPosY
, nTab
);
4710 Point aNext
= pViewData
->GetScrPos( nPosX
, nPosY
, eWhich
, true );
4713 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeXPix
, nSizeYPix
);
4714 aNext
.X() += nSizeXPix
* nLayoutSign
;
4715 aNext
.Y() += nSizeYPix
;
4719 bCornerHor
= ( rMouse
.X() >= aNext
.X() && rMouse
.X() <= aNext
.X() + 8 );
4721 bCornerHor
= ( rMouse
.X() >= aNext
.X() - 8 && rMouse
.X() <= aNext
.X() );
4723 bool bCellCorner
= ( bCornerHor
&&
4724 rMouse
.Y() >= aNext
.Y() - 8 && rMouse
.Y() <= aNext
.Y() );
4725 // corner is hit only if the mouse is within the cell
4727 sal_uInt16 nCount
= (sal_uInt16
)pRangeFinder
->Count();
4728 for (sal_uInt16 i
=nCount
; i
;)
4730 // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4732 ScRangeFindData
* pData
= pRangeFinder
->GetObject(i
);
4733 if ( pData
->aRef
.In(aAddr
) )
4735 if (pIndex
) *pIndex
= i
;
4736 if (pAddX
) *pAddX
= nPosX
- pData
->aRef
.aStart
.Col();
4737 if (pAddY
) *pAddY
= nPosY
- pData
->aRef
.aStart
.Row();
4739 rCorner
= ( bCellCorner
&& aAddr
== pData
->aRef
.aEnd
);
4749 #define SCE_BOTTOM 2
4754 static void lcl_PaintOneRange( ScDocShell
* pDocSh
, const ScRange
& rRange
, sal_uInt16 nEdges
)
4756 // der Range ist immer richtigherum
4758 SCCOL nCol1
= rRange
.aStart
.Col();
4759 SCROW nRow1
= rRange
.aStart
.Row();
4760 SCTAB nTab1
= rRange
.aStart
.Tab();
4761 SCCOL nCol2
= rRange
.aEnd
.Col();
4762 SCROW nRow2
= rRange
.aEnd
.Row();
4763 SCTAB nTab2
= rRange
.aEnd
.Tab();
4764 sal_Bool bHiddenEdge
= false;
4767 ScDocument
* pDoc
= pDocSh
->GetDocument();
4768 while ( nCol1
> 0 && pDoc
->ColHidden(nCol1
, nTab1
) )
4771 bHiddenEdge
= sal_True
;
4773 while ( nCol2
< MAXCOL
&& pDoc
->ColHidden(nCol2
, nTab1
) )
4776 bHiddenEdge
= sal_True
;
4778 nTmp
= pDoc
->FirstVisibleRow(0, nRow1
, nTab1
);
4779 if (!ValidRow(nTmp
))
4784 bHiddenEdge
= sal_True
;
4786 nTmp
= pDoc
->FirstVisibleRow(nRow2
, MAXROW
, nTab1
);
4787 if (!ValidRow(nTmp
))
4792 bHiddenEdge
= sal_True
;
4795 if ( nCol2
> nCol1
+ 1 && nRow2
> nRow1
+ 1 && !bHiddenEdge
)
4797 // nur an den Raendern entlang
4798 // (die Ecken werden evtl. zweimal getroffen)
4800 if ( nEdges
& SCE_TOP
)
4801 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow1
, nTab2
, PAINT_MARKS
);
4802 if ( nEdges
& SCE_LEFT
)
4803 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol1
, nRow2
, nTab2
, PAINT_MARKS
);
4804 if ( nEdges
& SCE_RIGHT
)
4805 pDocSh
->PostPaint( nCol2
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4806 if ( nEdges
& SCE_BOTTOM
)
4807 pDocSh
->PostPaint( nCol1
, nRow2
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4809 else // everything in one call
4810 pDocSh
->PostPaint( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, PAINT_MARKS
);
4813 static void lcl_PaintRefChanged( ScDocShell
* pDocSh
, const ScRange
& rOldUn
, const ScRange
& rNewUn
)
4815 // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4817 ScRange aOld
= rOldUn
;
4818 ScRange aNew
= rNewUn
;
4822 if ( aOld
.aStart
== aOld
.aEnd
) //! Tab ignorieren?
4823 pDocSh
->GetDocument()->ExtendMerge(aOld
);
4824 if ( aNew
.aStart
== aNew
.aEnd
) //! Tab ignorieren?
4825 pDocSh
->GetDocument()->ExtendMerge(aNew
);
4827 SCCOL nOldCol1
= aOld
.aStart
.Col();
4828 SCROW nOldRow1
= aOld
.aStart
.Row();
4829 SCCOL nOldCol2
= aOld
.aEnd
.Col();
4830 SCROW nOldRow2
= aOld
.aEnd
.Row();
4831 SCCOL nNewCol1
= aNew
.aStart
.Col();
4832 SCROW nNewRow1
= aNew
.aStart
.Row();
4833 SCCOL nNewCol2
= aNew
.aEnd
.Col();
4834 SCROW nNewRow2
= aNew
.aEnd
.Row();
4835 SCTAB nTab1
= aOld
.aStart
.Tab(); // Tab aendert sich nicht
4836 SCTAB nTab2
= aOld
.aEnd
.Tab();
4838 if ( nNewRow2
< nOldRow1
|| nNewRow1
> nOldRow2
||
4839 nNewCol2
< nOldCol1
|| nNewCol1
> nOldCol2
||
4840 ( nNewCol1
!= nOldCol1
&& nNewRow1
!= nOldRow1
&&
4841 nNewCol2
!= nOldCol2
&& nNewRow2
!= nOldRow2
) )
4843 // komplett weggeschoben oder alle Seiten veraendert
4844 // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4846 lcl_PaintOneRange( pDocSh
, aOld
, SCE_ALL
);
4848 else // alle vier Kanten einzeln testen
4851 if ( nNewRow1
< nOldRow1
) // nur obere Linie loeschen
4852 lcl_PaintOneRange( pDocSh
, ScRange(
4853 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nOldRow1
, nTab2
), SCE_ALL
);
4854 else if ( nNewRow1
> nOldRow1
) // den Teil, der oben wegkommt
4855 lcl_PaintOneRange( pDocSh
, ScRange(
4856 nOldCol1
, nOldRow1
, nTab1
, nOldCol2
, nNewRow1
-1, nTab2
),
4857 SCE_ALL
&~ SCE_BOTTOM
);
4860 if ( nNewRow2
> nOldRow2
) // nur untere Linie loeschen
4861 lcl_PaintOneRange( pDocSh
, ScRange(
4862 nOldCol1
, nOldRow2
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4863 else if ( nNewRow2
< nOldRow2
) // den Teil, der unten wegkommt
4864 lcl_PaintOneRange( pDocSh
, ScRange(
4865 nOldCol1
, nNewRow2
+1, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4866 SCE_ALL
&~ SCE_TOP
);
4869 if ( nNewCol1
< nOldCol1
) // nur linke Linie loeschen
4870 lcl_PaintOneRange( pDocSh
, ScRange(
4871 nOldCol1
, nOldRow1
, nTab1
, nOldCol1
, nOldRow2
, nTab2
), SCE_ALL
);
4872 else if ( nNewCol1
> nOldCol1
) // den Teil, der links wegkommt
4873 lcl_PaintOneRange( pDocSh
, ScRange(
4874 nOldCol1
, nOldRow1
, nTab1
, nNewCol1
-1, nOldRow2
, nTab2
),
4875 SCE_ALL
&~ SCE_RIGHT
);
4878 if ( nNewCol2
> nOldCol2
) // nur rechte Linie loeschen
4879 lcl_PaintOneRange( pDocSh
, ScRange(
4880 nOldCol2
, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
), SCE_ALL
);
4881 else if ( nNewCol2
< nOldCol2
) // den Teil, der rechts wegkommt
4882 lcl_PaintOneRange( pDocSh
, ScRange(
4883 nNewCol2
+1, nOldRow1
, nTab1
, nOldCol2
, nOldRow2
, nTab2
),
4884 SCE_ALL
&~ SCE_LEFT
);
4888 void ScGridWindow::RFMouseMove( const MouseEvent
& rMEvt
, sal_Bool bUp
)
4890 ScInputHandler
* pHdl
= SC_MOD()->GetInputHdl( pViewData
->GetViewShell() );
4893 ScRangeFindList
* pRangeFinder
= pHdl
->GetRangeFindList();
4894 if (!pRangeFinder
|| nRFIndex
>= pRangeFinder
->Count())
4896 ScRangeFindData
* pData
= pRangeFinder
->GetObject( nRFIndex
);
4901 SetPointer( Pointer( POINTER_CROSS
) );
4903 SetPointer( Pointer( POINTER_HAND
) );
4907 sal_Bool bTimer
= false;
4908 Point aPos
= rMEvt
.GetPosPixel();
4911 if ( aPos
.X() < 0 ) nDx
= -1;
4912 if ( aPos
.Y() < 0 ) nDy
= -1;
4913 Size aSize
= GetOutputSizePixel();
4914 if ( aPos
.X() >= aSize
.Width() )
4916 if ( aPos
.Y() >= aSize
.Height() )
4918 if ( nDx
!= 0 || nDy
!= 0 )
4920 if ( nDx
!= 0) pViewData
->GetView()->ScrollX( nDx
, WhichH(eWhich
) );
4921 if ( nDy
!= 0 ) pViewData
->GetView()->ScrollY( nDy
, WhichV(eWhich
) );
4925 // Umschalten bei Fixierung (damit Scrolling funktioniert)
4927 if ( eWhich
== pViewData
->GetActivePart() ) //??
4929 if ( pViewData
->GetHSplitMode() == SC_SPLIT_FIX
)
4932 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4933 pViewData
->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT
);
4934 else if ( eWhich
== SC_SPLIT_BOTTOMLEFT
)
4935 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4938 if ( pViewData
->GetVSplitMode() == SC_SPLIT_FIX
)
4941 if ( eWhich
== SC_SPLIT_TOPLEFT
)
4942 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT
);
4943 else if ( eWhich
== SC_SPLIT_TOPRIGHT
)
4944 pViewData
->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT
);
4952 pViewData
->GetPosFromPixel( aPos
.X(), aPos
.Y(), eWhich
, nPosX
, nPosY
);
4954 ScRange aOld
= pData
->aRef
;
4955 ScRange aNew
= aOld
;
4958 aNew
.aEnd
.SetCol((SCCOL
)nPosX
);
4959 aNew
.aEnd
.SetRow((SCROW
)nPosY
);
4963 long nStartX
= nPosX
- nRFAddX
;
4964 if ( nStartX
< 0 ) nStartX
= 0;
4965 long nStartY
= nPosY
- nRFAddY
;
4966 if ( nStartY
< 0 ) nStartY
= 0;
4967 long nEndX
= nStartX
+ aOld
.aEnd
.Col() - aOld
.aStart
.Col();
4968 if ( nEndX
> MAXCOL
)
4970 nStartX
-= ( nEndX
- MAXROW
);
4973 long nEndY
= nStartY
+ aOld
.aEnd
.Row() - aOld
.aStart
.Row();
4974 if ( nEndY
> MAXROW
)
4976 nStartY
-= ( nEndY
- MAXROW
);
4980 aNew
.aStart
.SetCol((SCCOL
)nStartX
);
4981 aNew
.aStart
.SetRow((SCROW
)nStartY
);
4982 aNew
.aEnd
.SetCol((SCCOL
)nEndX
);
4983 aNew
.aEnd
.SetRow((SCROW
)nEndY
);
4987 aNew
.Justify(); // beim ButtonUp wieder richtigherum
4991 pHdl
->UpdateRange( nRFIndex
, aNew
);
4993 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
4995 // nur das neuzeichnen, was sich veraendert hat...
4996 lcl_PaintRefChanged( pDocSh
, aOld
, aNew
);
4998 // neuen Rahmen nur drueberzeichnen (synchron)
4999 pDocSh
->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER
, nRFIndex
) );
5001 Update(); // was man bewegt, will man auch sofort sehen
5004 // Timer fuer Scrolling
5007 pViewData
->GetView()->SetTimer( this, rMEvt
); // Event wiederholen
5009 pViewData
->GetView()->ResetTimer();
5012 //------------------------------------------------------------------------
5014 bool ScGridWindow::GetEditUrl( const Point
& rPos
,
5015 String
* pName
, String
* pUrl
, String
* pTarget
)
5017 return GetEditUrlOrError( false, rPos
, pName
, pUrl
, pTarget
);
5020 bool ScGridWindow::GetEditUrlOrError( bool bSpellErr
, const Point
& rPos
,
5021 String
* pName
, String
* pUrl
, String
* pTarget
)
5023 //! nPosX/Y mit uebergeben?
5026 pViewData
->GetPosFromPixel( rPos
.X(), rPos
.Y(), eWhich
, nPosX
, nPosY
);
5028 SCTAB nTab
= pViewData
->GetTabNo();
5029 ScDocShell
* pDocSh
= pViewData
->GetDocShell();
5030 ScDocument
* pDoc
= pDocSh
->GetDocument();
5031 ScBaseCell
* pCell
= NULL
;
5033 sal_Bool bFound
= lcl_GetHyperlinkCell( pDoc
, nPosX
, nPosY
, nTab
, pCell
);
5037 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nPosX
, nPosY
, nTab
);
5038 // bForceToTop = sal_False, use the cell's real position
5039 Rectangle aEditRect
= pViewData
->GetEditArea( eWhich
, nPosX
, nPosY
, this, pPattern
, false );
5040 if (rPos
.Y() < aEditRect
.Top())
5043 // vertikal kann (noch) nicht angeklickt werden:
5045 if (pPattern
->GetCellOrientation() != SVX_ORIENTATION_STANDARD
)
5048 sal_Bool bBreak
= ((SfxBoolItem
&)pPattern
->GetItem(ATTR_LINEBREAK
)).GetValue() ||
5049 ((SvxCellHorJustify
)((const SvxHorJustifyItem
&)pPattern
->
5050 GetItem( ATTR_HOR_JUSTIFY
)).GetValue() == SVX_HOR_JUSTIFY_BLOCK
);
5051 SvxCellHorJustify eHorJust
= (SvxCellHorJustify
)((SvxHorJustifyItem
&)pPattern
->
5052 GetItem(ATTR_HOR_JUSTIFY
)).GetValue();
5056 ScFieldEditEngine
aEngine(pDoc
, pDoc
->GetEditPool());
5057 ScSizeDeviceProvider
aProv(pDocSh
);
5058 aEngine
.SetRefDevice( aProv
.GetDevice() );
5059 aEngine
.SetRefMapMode( MAP_100TH_MM
);
5060 SfxItemSet
aDefault( aEngine
.GetEmptyItemSet() );
5061 pPattern
->FillEditItemSet( &aDefault
);
5062 SvxAdjust eSvxAdjust
= SVX_ADJUST_LEFT
;
5065 case SVX_HOR_JUSTIFY_LEFT
:
5066 case SVX_HOR_JUSTIFY_REPEAT
: // nicht implementiert
5067 case SVX_HOR_JUSTIFY_STANDARD
: // always Text if an EditCell type
5068 eSvxAdjust
= SVX_ADJUST_LEFT
;
5070 case SVX_HOR_JUSTIFY_RIGHT
:
5071 eSvxAdjust
= SVX_ADJUST_RIGHT
;
5073 case SVX_HOR_JUSTIFY_CENTER
:
5074 eSvxAdjust
= SVX_ADJUST_CENTER
;
5076 case SVX_HOR_JUSTIFY_BLOCK
:
5077 eSvxAdjust
= SVX_ADJUST_BLOCK
;
5080 aDefault
.Put( SvxAdjustItem( eSvxAdjust
, EE_PARA_JUST
) );
5081 aEngine
.SetDefaults( aDefault
);
5083 aEngine
.SetControlWord( aEngine
.GetControlWord() | EE_CNTRL_ONLINESPELLING
);
5085 MapMode aEditMode
= pViewData
->GetLogicMode(eWhich
); // ohne Drawing-Skalierung
5086 Rectangle aLogicEdit
= PixelToLogic( aEditRect
, aEditMode
);
5087 long nThisColLogic
= aLogicEdit
.Right() - aLogicEdit
.Left() + 1;
5088 Size aPaperSize
= Size( 1000000, 1000000 );
5089 if(pCell
->GetCellType() == CELLTYPE_FORMULA
)
5093 pViewData
->GetMergeSizePixel( nPosX
, nPosY
, nSizeX
, nSizeY
);
5094 aPaperSize
= Size(nSizeX
, nSizeY
);
5095 aPaperSize
= PixelToLogic(aPaperSize
);
5099 aPaperSize
.Width() = nThisColLogic
;
5100 aEngine
.SetPaperSize( aPaperSize
);
5102 ::std::auto_ptr
< EditTextObject
> pTextObj
;
5103 const EditTextObject
* pData
;
5104 if(pCell
->GetCellType() == CELLTYPE_EDIT
)
5106 ((ScEditCell
*)pCell
)->GetData(pData
);
5108 aEngine
.SetText(*pData
);
5110 else // HyperLink Formula cell
5112 pTextObj
.reset((static_cast<ScFormulaCell
*>(pCell
))->CreateURLObject());
5114 aEngine
.SetText(*pTextObj
);
5117 long nStartX
= aLogicEdit
.Left();
5119 long nTextWidth
= aEngine
.CalcTextWidth();
5120 long nTextHeight
= aEngine
.GetTextHeight();
5121 if ( nTextWidth
< nThisColLogic
)
5123 if (eHorJust
== SVX_HOR_JUSTIFY_RIGHT
)
5124 nStartX
+= nThisColLogic
- nTextWidth
;
5125 else if (eHorJust
== SVX_HOR_JUSTIFY_CENTER
)
5126 nStartX
+= (nThisColLogic
- nTextWidth
) / 2;
5129 aLogicEdit
.Left() = nStartX
;
5131 aLogicEdit
.Right() = nStartX
+ nTextWidth
;
5133 // There is one glitch when dealing with a hyperlink cell and
5134 // the cell content is NUMERIC. This defaults to right aligned and
5135 // we need to adjust accordingly.
5136 if(pCell
->GetCellType() == CELLTYPE_FORMULA
&&
5137 static_cast<ScFormulaCell
*>(pCell
)->IsValue() &&
5138 eHorJust
== SVX_HOR_JUSTIFY_STANDARD
)
5140 aLogicEdit
.Right() = aLogicEdit
.Left() + nThisColLogic
- 1;
5141 aLogicEdit
.Left() = aLogicEdit
.Right() - nTextWidth
;
5143 aLogicEdit
.Bottom() = aLogicEdit
.Top() + nTextHeight
;
5146 Point aLogicClick
= PixelToLogic(rPos
,aEditMode
);
5147 if ( aLogicEdit
.IsInside(aLogicClick
) )
5149 EditView
aTempView( &aEngine
, this );
5150 aTempView
.SetOutputArea( aLogicEdit
);
5152 sal_Bool bRet
= false;
5153 MapMode aOld
= GetMapMode();
5154 SetMapMode(aEditMode
); // kein return mehr
5156 if (bSpellErr
) // Spelling-Fehler suchen
5158 bRet
= aTempView
.IsWrongSpelledWordAtPos( rPos
);
5160 pViewData
->GetView()->SetCursor( nPosX
, nPosY
); // Cursor setzen
5164 const SvxFieldItem
* pFieldItem
= aTempView
.GetFieldUnderMousePointer();
5168 const SvxFieldData
* pField
= pFieldItem
->GetField();
5169 if ( pField
&& pField
->ISA(SvxURLField
) )
5171 if ( pName
|| pUrl
|| pTarget
)
5173 const SvxURLField
* pURLField
= (const SvxURLField
*)pField
;
5175 *pName
= pURLField
->GetRepresentation();
5177 *pUrl
= pURLField
->GetURL();
5179 *pTarget
= pURLField
->GetTargetFrame();
5193 bool ScGridWindow::HasScenarioButton( const Point
& rPosPixel
, ScRange
& rScenRange
)
5195 ScDocument
* pDoc
= pViewData
->GetDocument();
5196 SCTAB nTab
= pViewData
->GetTabNo();
5197 SCTAB nTabCount
= pDoc
->GetTableCount();
5198 if ( nTab
+1<nTabCount
&& pDoc
->IsScenario(nTab
+1) && !pDoc
->IsScenario(nTab
) )
5200 bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5202 Size aButSize
= pViewData
->GetScenButSize();
5203 long nBWidth
= aButSize
.Width();
5205 return false; // noch kein Button gezeichnet -> da ist auch keiner
5206 long nBHeight
= aButSize
.Height();
5207 long nHSpace
= (long)( SC_SCENARIO_HSPACE
* pViewData
->GetPPTX() );
5209 //! Ranges an der Table cachen!!!!
5212 for (SCTAB i
=nTab
+1; i
<nTabCount
&& pDoc
->IsScenario(i
); i
++)
5213 pDoc
->MarkScenario( i
, nTab
, aMarks
, false, SC_SCENARIO_SHOWFRAME
);
5214 ScRangeList aRanges
;
5215 aMarks
.FillRangeListWithMarks( &aRanges
, false );
5218 size_t nRangeCount
= aRanges
.size();
5219 for (size_t j
=0; j
< nRangeCount
; ++j
)
5221 ScRange aRange
= *aRanges
[j
];
5222 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5223 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5224 pDoc
->ExtendTotalMerge( aRange
);
5226 bool bTextBelow
= ( aRange
.aStart
.Row() == 0 );
5231 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aEnd
.Row()+1,
5236 aButtonPos
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1, aRange
.aStart
.Row(),
5238 aButtonPos
.Y() -= nBHeight
;
5241 aButtonPos
.X() -= nHSpace
- 1;
5243 aButtonPos
.X() -= nBWidth
- nHSpace
; // same for top or bottom
5245 Rectangle
aButRect( aButtonPos
, Size(nBWidth
,nBHeight
) );
5246 if ( aButRect
.IsInside( rPosPixel
) )
5248 rScenRange
= aRange
;
5258 void ScGridWindow::DrawLayerCreated()
5260 SetMapMode( GetDrawMapMode() );
5262 // initially create overlay objects
5263 ImpCreateOverlayObjects();
5267 void ScGridWindow::CursorChanged()
5269 // here the created OverlayObjects may be transformed in later versions. For
5270 // now, just re-create them
5272 UpdateCursorOverlay();
5276 void ScGridWindow::ImpCreateOverlayObjects()
5278 UpdateCursorOverlay();
5279 UpdateCopySourceOverlay();
5280 UpdateSelectionOverlay();
5281 UpdateAutoFillOverlay();
5282 UpdateDragRectOverlay();
5283 UpdateHeaderOverlay();
5284 UpdateShrinkOverlay();
5288 void ScGridWindow::ImpDestroyOverlayObjects()
5290 DeleteCursorOverlay();
5291 DeleteCopySourceOverlay();
5292 DeleteSelectionOverlay();
5293 DeleteAutoFillOverlay();
5294 DeleteDragRectOverlay();
5295 DeleteHeaderOverlay();
5296 DeleteShrinkOverlay();
5299 void ScGridWindow::UpdateAllOverlays()
5301 // delete and re-allocate all overlay objects
5303 ImpDestroyOverlayObjects();
5304 ImpCreateOverlayObjects();
5307 void ScGridWindow::DeleteCursorOverlay()
5309 DELETEZ( mpOOCursors
);
5312 void ScGridWindow::DeleteCopySourceOverlay()
5314 DELETEZ( mpOOSelectionBorder
);
5317 void ScGridWindow::UpdateCopySourceOverlay()
5319 MapMode aDrawMode
= GetDrawMapMode();
5320 MapMode aOldMode
= GetMapMode();
5321 if ( aOldMode
!= aDrawMode
)
5322 SetMapMode( aDrawMode
);
5324 DeleteCopySourceOverlay();
5326 if (!pViewData
->ShowPasteSource())
5328 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5329 if (!xOverlayManager
.is())
5331 ScTransferObj
* pTransObj
= ScTransferObj::GetOwnClipboard( pViewData
->GetActiveWin() );
5334 ScDocument
* pClipDoc
= pTransObj
->GetDocument();
5338 SCTAB nCurTab
= pViewData
->GetCurPos().Tab();
5340 ScClipParam
& rClipParam
= pClipDoc
->GetClipParam();
5341 mpOOSelectionBorder
= new ::sdr::overlay::OverlayObjectList
;
5342 for ( size_t i
= 0; i
< rClipParam
.maRanges
.size(); ++i
)
5344 ScRange
* p
= rClipParam
.maRanges
[i
];
5345 if (p
->aStart
.Tab() != nCurTab
)
5348 SCCOL nClipStartX
= p
->aStart
.Col();
5349 SCROW nClipStartY
= p
->aStart
.Row();
5350 SCCOL nClipEndX
= p
->aEnd
.Col();
5351 SCROW nClipEndY
= p
->aEnd
.Row();
5353 Point aClipStartScrPos
= pViewData
->GetScrPos( nClipStartX
, nClipStartY
, eWhich
);
5354 Point aClipEndScrPos
= pViewData
->GetScrPos( nClipEndX
+ 1, nClipEndY
+ 1, eWhich
);
5355 aClipStartScrPos
-= Point(1, 1);
5356 long nSizeXPix
= aClipEndScrPos
.X() - aClipStartScrPos
.X();
5357 long nSizeYPix
= aClipEndScrPos
.Y() - aClipStartScrPos
.Y();
5359 Rectangle
aRect( aClipStartScrPos
, Size(nSizeXPix
, nSizeYPix
) );
5362 Color aHighlight
= GetSettings().GetStyleSettings().GetHighlightColor();
5364 Rectangle aLogic
= PixelToLogic(aRect
, aDrawMode
);
5365 ::basegfx::B2DRange
aRange(aLogic
.Left(), aLogic
.Top(), aLogic
.Right(), aLogic
.Bottom());
5366 ScOverlayDashedBorder
* pDashedBorder
= new ScOverlayDashedBorder(aRange
, aHighlight
);
5367 xOverlayManager
->add(*pDashedBorder
);
5368 mpOOSelectionBorder
->append(*pDashedBorder
);
5371 if ( aOldMode
!= aDrawMode
)
5372 SetMapMode( aOldMode
);
5375 void ScGridWindow::UpdateCursorOverlay()
5377 MapMode aDrawMode
= GetDrawMapMode();
5378 MapMode aOldMode
= GetMapMode();
5379 if ( aOldMode
!= aDrawMode
)
5380 SetMapMode( aDrawMode
);
5382 // Existing OverlayObjects may be transformed in later versions.
5383 // For now, just re-create them.
5385 DeleteCursorOverlay();
5387 std::vector
<Rectangle
> aPixelRects
;
5390 // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5393 SCTAB nTab
= pViewData
->GetTabNo();
5394 SCCOL nX
= pViewData
->GetCurX();
5395 SCROW nY
= pViewData
->GetCurY();
5397 if (!maVisibleRange
.isInside(nX
, nY
))
5400 // don't show the cursor in overlapped cells
5402 ScDocument
* pDoc
= pViewData
->GetDocument();
5403 const ScPatternAttr
* pPattern
= pDoc
->GetPattern(nX
,nY
,nTab
);
5404 const ScMergeFlagAttr
& rMergeFlag
= (const ScMergeFlagAttr
&) pPattern
->GetItem(ATTR_MERGE_FLAG
);
5405 sal_Bool bOverlapped
= rMergeFlag
.IsOverlapped();
5407 // left or above of the screen?
5409 sal_Bool bVis
= ( nX
>=pViewData
->GetPosX(eHWhich
) && nY
>=pViewData
->GetPosY(eVWhich
) );
5414 const ScMergeAttr
& rMerge
= (const ScMergeAttr
&) pPattern
->GetItem(ATTR_MERGE
);
5415 if (rMerge
.GetColMerge() > 1)
5416 nEndX
+= rMerge
.GetColMerge()-1;
5417 if (rMerge
.GetRowMerge() > 1)
5418 nEndY
+= rMerge
.GetRowMerge()-1;
5419 bVis
= ( nEndX
>=pViewData
->GetPosX(eHWhich
) && nEndY
>=pViewData
->GetPosY(eVWhich
) );
5422 if ( bVis
&& !bOverlapped
&& !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5424 Point aScrPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, sal_True
);
5425 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5427 // completely right of/below the screen?
5428 // (test with logical start position in aScrPos)
5429 sal_Bool bMaybeVisible
;
5431 bMaybeVisible
= ( aScrPos
.X() >= -2 && aScrPos
.Y() >= -2 );
5434 Size aOutSize
= GetOutputSizePixel();
5435 bMaybeVisible
= ( aScrPos
.X() <= aOutSize
.Width() + 2 && aScrPos
.Y() <= aOutSize
.Height() + 2 );
5437 if ( bMaybeVisible
)
5441 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5444 aScrPos
.X() -= nSizeXPix
- 2; // move instead of mirroring
5446 // Now, draw the cursor.
5450 Rectangle
aRect( aScrPos
, Size( nSizeXPix
+ 3, nSizeYPix
+ 3 ) );
5452 aPixelRects
.push_back(Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ));
5453 aPixelRects
.push_back(Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ));
5454 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ));
5455 aPixelRects
.push_back(Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ));
5459 if ( !aPixelRects
.empty() )
5461 // #i70788# get the OverlayManager safely
5462 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5464 if (xOverlayManager
.is())
5466 Color
aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5467 if (pViewData
->GetActivePart() != eWhich
)
5468 // non-active pane uses a different color.
5469 aCursorColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5470 std::vector
< basegfx::B2DRange
> aRanges
;
5471 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5473 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5475 const Rectangle
aRA(aPixelRects
[a
]);
5476 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5477 aRB
.transform(aTransform
);
5478 aRanges
.push_back(aRB
);
5481 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5482 sdr::overlay::OVERLAY_SOLID
,
5487 xOverlayManager
->add(*pOverlay
);
5488 mpOOCursors
= new ::sdr::overlay::OverlayObjectList
;
5489 mpOOCursors
->append(*pOverlay
);
5493 if ( aOldMode
!= aDrawMode
)
5494 SetMapMode( aOldMode
);
5497 void ScGridWindow::DeleteSelectionOverlay()
5499 DELETEZ( mpOOSelection
);
5502 void ScGridWindow::UpdateSelectionOverlay()
5504 MapMode aDrawMode
= GetDrawMapMode();
5505 MapMode aOldMode
= GetMapMode();
5506 if ( aOldMode
!= aDrawMode
)
5507 SetMapMode( aDrawMode
);
5509 DeleteSelectionOverlay();
5510 std::vector
<Rectangle
> aPixelRects
;
5511 GetSelectionRects( aPixelRects
);
5513 if ( aPixelRects
.size() && pViewData
->IsActive() )
5515 // #i70788# get the OverlayManager safely
5516 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5518 if (xOverlayManager
.is())
5520 std::vector
< basegfx::B2DRange
> aRanges
;
5521 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5523 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5525 const Rectangle
aRA(aPixelRects
[a
]);
5526 basegfx::B2DRange
aRB(aRA
.Left() - 1, aRA
.Top() - 1, aRA
.Right(), aRA
.Bottom());
5527 aRB
.transform(aTransform
);
5528 aRanges
.push_back(aRB
);
5531 // #i97672# get the system's hilight color and limit it to the maximum
5532 // allowed luminance. This is needed to react on too bright hilight colors
5533 // which would otherwise vive a bad visualisation
5534 Color
aHighlight(GetSettings().GetStyleSettings().GetHighlightColor());
5535 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer
;
5536 const basegfx::BColor
aSelection(aHighlight
.getBColor());
5537 const double fLuminance(aSelection
.luminance());
5538 const double fMaxLum(aSvtOptionsDrawinglayer
.GetSelectionMaximumLuminancePercent() / 100.0);
5540 if(fLuminance
> fMaxLum
)
5542 const double fFactor(fMaxLum
/ fLuminance
);
5543 const basegfx::BColor
aNewSelection(
5544 aSelection
.getRed() * fFactor
,
5545 aSelection
.getGreen() * fFactor
,
5546 aSelection
.getBlue() * fFactor
);
5548 aHighlight
= Color(aNewSelection
);
5551 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5552 sdr::overlay::OVERLAY_TRANSPARENT
,
5557 xOverlayManager
->add(*pOverlay
);
5558 mpOOSelection
= new ::sdr::overlay::OverlayObjectList
;
5559 mpOOSelection
->append(*pOverlay
);
5563 if ( aOldMode
!= aDrawMode
)
5564 SetMapMode( aOldMode
);
5567 void ScGridWindow::DeleteAutoFillOverlay()
5569 DELETEZ( mpOOAutoFill
);
5570 mpAutoFillRect
.reset();
5573 void ScGridWindow::UpdateAutoFillOverlay()
5575 MapMode aDrawMode
= GetDrawMapMode();
5576 MapMode aOldMode
= GetMapMode();
5577 if ( aOldMode
!= aDrawMode
)
5578 SetMapMode( aDrawMode
);
5580 DeleteAutoFillOverlay();
5583 // get the AutoFill handle rectangle in pixels
5586 if ( bAutoMarkVisible
&& aAutoMarkPos
.Tab() == pViewData
->GetTabNo() &&
5587 !pViewData
->HasEditView(eWhich
) && pViewData
->IsActive() )
5589 SCCOL nX
= aAutoMarkPos
.Col();
5590 SCROW nY
= aAutoMarkPos
.Row();
5592 if (!maVisibleRange
.isInside(nX
, nY
))
5593 // Autofill mark is not visible. Bail out.
5596 SCTAB nTab
= pViewData
->GetTabNo();
5597 ScDocument
* pDoc
= pViewData
->GetDocument();
5598 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5600 Point aFillPos
= pViewData
->GetScrPos( nX
, nY
, eWhich
, sal_True
);
5603 pViewData
->GetMergeSizePixel( nX
, nY
, nSizeXPix
, nSizeYPix
);
5605 aFillPos
.X() -= nSizeXPix
+ 3;
5607 aFillPos
.X() += nSizeXPix
- 2;
5609 aFillPos
.Y() += nSizeYPix
;
5611 mpAutoFillRect
.reset(new Rectangle(aFillPos
, Size(6, 6)));
5613 // #i70788# get the OverlayManager safely
5614 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5616 if (xOverlayManager
.is())
5618 Color
aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
5619 if (pViewData
->GetActivePart() != eWhich
)
5620 // non-active pane uses a different color.
5621 aHandleColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
;
5622 std::vector
< basegfx::B2DRange
> aRanges
;
5623 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5624 basegfx::B2DRange
aRB(mpAutoFillRect
->Left(), mpAutoFillRect
->Top(), mpAutoFillRect
->Right() + 1, mpAutoFillRect
->Bottom() + 1);
5626 aRB
.transform(aTransform
);
5627 aRanges
.push_back(aRB
);
5629 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5630 sdr::overlay::OVERLAY_SOLID
,
5635 xOverlayManager
->add(*pOverlay
);
5636 mpOOAutoFill
= new ::sdr::overlay::OverlayObjectList
;
5637 mpOOAutoFill
->append(*pOverlay
);
5640 if ( aOldMode
!= aDrawMode
)
5641 SetMapMode( aOldMode
);
5645 void ScGridWindow::DeleteDragRectOverlay()
5647 DELETEZ( mpOODragRect
);
5650 void ScGridWindow::UpdateDragRectOverlay()
5652 MapMode aDrawMode
= GetDrawMapMode();
5653 MapMode aOldMode
= GetMapMode();
5654 if ( aOldMode
!= aDrawMode
)
5655 SetMapMode( aDrawMode
);
5657 DeleteDragRectOverlay();
5660 // get the rectangles in pixels (moved from DrawDragRect)
5663 if ( bDragRect
|| bPagebreakDrawn
)
5665 std::vector
<Rectangle
> aPixelRects
;
5667 SCCOL nX1
= bDragRect
? nDragStartX
: aPagebreakDrag
.aStart
.Col();
5668 SCROW nY1
= bDragRect
? nDragStartY
: aPagebreakDrag
.aStart
.Row();
5669 SCCOL nX2
= bDragRect
? nDragEndX
: aPagebreakDrag
.aEnd
.Col();
5670 SCROW nY2
= bDragRect
? nDragEndY
: aPagebreakDrag
.aEnd
.Row();
5672 SCTAB nTab
= pViewData
->GetTabNo();
5674 SCCOL nPosX
= pViewData
->GetPosX(WhichH(eWhich
));
5675 SCROW nPosY
= pViewData
->GetPosY(WhichV(eWhich
));
5676 if (nX1
< nPosX
) nX1
= nPosX
;
5677 if (nX2
< nPosX
) nX2
= nPosX
;
5678 if (nY1
< nPosY
) nY1
= nPosY
;
5679 if (nY2
< nPosY
) nY2
= nPosY
;
5681 Point
aScrPos( pViewData
->GetScrPos( nX1
, nY1
, eWhich
) );
5685 ScDocument
* pDoc
= pViewData
->GetDocument();
5686 double nPPTX
= pViewData
->GetPPTX();
5687 double nPPTY
= pViewData
->GetPPTY();
5690 sal_Bool bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
5691 long nLayoutSign
= bLayoutRTL
? -1 : 1;
5693 if (ValidCol(nX2
) && nX2
>=nX1
)
5694 for (i
=nX1
; i
<=nX2
; i
++)
5695 nSizeXPix
+= ScViewData::ToPixel( pDoc
->GetColWidth( static_cast<SCCOL
>(i
), nTab
), nPPTX
);
5698 aScrPos
.X() -= nLayoutSign
;
5702 if (ValidRow(nY2
) && nY2
>=nY1
)
5703 for (i
=nY1
; i
<=nY2
; i
++)
5704 nSizeYPix
+= ScViewData::ToPixel( pDoc
->GetRowHeight( i
, nTab
), nPPTY
);
5711 aScrPos
.X() -= 2 * nLayoutSign
;
5713 Rectangle
aRect( aScrPos
.X(), aScrPos
.Y(),
5714 aScrPos
.X() + ( nSizeXPix
+ 2 ) * nLayoutSign
, aScrPos
.Y() + nSizeYPix
+ 2 );
5717 aRect
.Left() = aRect
.Right(); // end position is left
5718 aRect
.Right() = aScrPos
.X();
5721 if ( meDragInsertMode
== INS_CELLSDOWN
)
5723 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top()+3, aRect
.Left()+1, aRect
.Bottom()-2 ) );
5724 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+3, aRect
.Right()-1, aRect
.Bottom()-2 ) );
5725 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Top(), aRect
.Right()-1, aRect
.Top()+2 ) );
5726 aPixelRects
.push_back( Rectangle( aRect
.Left()+1, aRect
.Bottom()-1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5728 else if ( meDragInsertMode
== INS_CELLSRIGHT
)
5730 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top()+1, aRect
.Left()+2, aRect
.Bottom()-1 ) );
5731 aPixelRects
.push_back( Rectangle( aRect
.Right()-1, aRect
.Top()+1, aRect
.Right()-1, aRect
.Bottom()-1 ) );
5732 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top()+1, aRect
.Right()-2, aRect
.Top()+1 ) );
5733 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-1, aRect
.Right()-2, aRect
.Bottom()-1 ) );
5737 aPixelRects
.push_back( Rectangle( aRect
.Left(), aRect
.Top(), aRect
.Left()+2, aRect
.Bottom() ) );
5738 aPixelRects
.push_back( Rectangle( aRect
.Right()-2, aRect
.Top(), aRect
.Right(), aRect
.Bottom() ) );
5739 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Top(), aRect
.Right()-3, aRect
.Top()+2 ) );
5740 aPixelRects
.push_back( Rectangle( aRect
.Left()+3, aRect
.Bottom()-2, aRect
.Right()-3, aRect
.Bottom() ) );
5743 // #i70788# get the OverlayManager safely
5744 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5746 if (xOverlayManager
.is())
5748 std::vector
< basegfx::B2DRange
> aRanges
;
5749 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5751 for(sal_uInt32
a(0); a
< aPixelRects
.size(); a
++)
5753 const Rectangle
aRA(aPixelRects
[a
]);
5754 basegfx::B2DRange
aRB(aRA
.Left(), aRA
.Top(), aRA
.Right() + 1, aRA
.Bottom() + 1);
5755 aRB
.transform(aTransform
);
5756 aRanges
.push_back(aRB
);
5759 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5760 sdr::overlay::OVERLAY_INVERT
,
5765 xOverlayManager
->add(*pOverlay
);
5766 mpOODragRect
= new ::sdr::overlay::OverlayObjectList
;
5767 mpOODragRect
->append(*pOverlay
);
5771 if ( aOldMode
!= aDrawMode
)
5772 SetMapMode( aOldMode
);
5775 void ScGridWindow::DeleteHeaderOverlay()
5777 DELETEZ( mpOOHeader
);
5780 void ScGridWindow::UpdateHeaderOverlay()
5782 MapMode aDrawMode
= GetDrawMapMode();
5783 MapMode aOldMode
= GetMapMode();
5784 if ( aOldMode
!= aDrawMode
)
5785 SetMapMode( aDrawMode
);
5787 DeleteHeaderOverlay();
5789 // Pixel rectangle is in aInvertRect
5790 if ( !aInvertRect
.IsEmpty() )
5792 // #i70788# get the OverlayManager safely
5793 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5795 if (xOverlayManager
.is())
5797 // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5798 std::vector
< basegfx::B2DRange
> aRanges
;
5799 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5800 basegfx::B2DRange
aRB(aInvertRect
.Left(), aInvertRect
.Top(), aInvertRect
.Right() + 1, aInvertRect
.Bottom() + 1);
5802 aRB
.transform(aTransform
);
5803 aRanges
.push_back(aRB
);
5805 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5806 sdr::overlay::OVERLAY_INVERT
,
5811 xOverlayManager
->add(*pOverlay
);
5812 mpOOHeader
= new ::sdr::overlay::OverlayObjectList
;
5813 mpOOHeader
->append(*pOverlay
);
5817 if ( aOldMode
!= aDrawMode
)
5818 SetMapMode( aOldMode
);
5821 void ScGridWindow::DeleteShrinkOverlay()
5823 DELETEZ( mpOOShrink
);
5826 void ScGridWindow::UpdateShrinkOverlay()
5828 MapMode aDrawMode
= GetDrawMapMode();
5829 MapMode aOldMode
= GetMapMode();
5830 if ( aOldMode
!= aDrawMode
)
5831 SetMapMode( aDrawMode
);
5833 DeleteShrinkOverlay();
5836 // get the rectangle in pixels
5841 SCTAB nTab
= pViewData
->GetTabNo();
5842 if ( pViewData
->IsRefMode() && nTab
>= pViewData
->GetRefStartZ() && nTab
<= pViewData
->GetRefEndZ() &&
5843 pViewData
->GetDelMark( aRange
) )
5845 //! limit to visible area
5846 if ( aRange
.aStart
.Col() <= aRange
.aEnd
.Col() &&
5847 aRange
.aStart
.Row() <= aRange
.aEnd
.Row() )
5849 Point aStart
= pViewData
->GetScrPos( aRange
.aStart
.Col(),
5850 aRange
.aStart
.Row(), eWhich
);
5851 Point aEnd
= pViewData
->GetScrPos( aRange
.aEnd
.Col()+1,
5852 aRange
.aEnd
.Row()+1, eWhich
);
5856 aPixRect
= Rectangle( aStart
,aEnd
);
5860 if ( !aPixRect
.IsEmpty() )
5862 // #i70788# get the OverlayManager safely
5863 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5865 if (xOverlayManager
.is())
5867 std::vector
< basegfx::B2DRange
> aRanges
;
5868 const basegfx::B2DHomMatrix
aTransform(GetInverseViewTransformation());
5869 basegfx::B2DRange
aRB(aPixRect
.Left(), aPixRect
.Top(), aPixRect
.Right() + 1, aPixRect
.Bottom() + 1);
5871 aRB
.transform(aTransform
);
5872 aRanges
.push_back(aRB
);
5874 sdr::overlay::OverlayObject
* pOverlay
= new sdr::overlay::OverlaySelection(
5875 sdr::overlay::OVERLAY_INVERT
,
5880 xOverlayManager
->add(*pOverlay
);
5881 mpOOShrink
= new ::sdr::overlay::OverlayObjectList
;
5882 mpOOShrink
->append(*pOverlay
);
5886 if ( aOldMode
!= aDrawMode
)
5887 SetMapMode( aOldMode
);
5890 // #i70788# central method to get the OverlayManager safely
5891 rtl::Reference
<sdr::overlay::OverlayManager
> ScGridWindow::getOverlayManager()
5893 SdrPageView
* pPV
= pViewData
->GetView()->GetScDrawView()->GetSdrPageView();
5897 SdrPageWindow
* pPageWin
= pPV
->FindPageWindow( *this );
5901 return (pPageWin
->GetOverlayManager());
5905 return rtl::Reference
<sdr::overlay::OverlayManager
>();
5908 void ScGridWindow::flushOverlayManager()
5910 // #i70788# get the OverlayManager safely
5911 rtl::Reference
<sdr::overlay::OverlayManager
> xOverlayManager
= getOverlayManager();
5913 if (xOverlayManager
.is())
5914 xOverlayManager
->flush();
5917 void ScGridWindow::SetInRefMode( bool bInRefMode
)
5919 WinBits nBits
= GetStyle();
5921 nBits
|= WB_REFMODE
;
5923 nBits
&= ~WB_REFMODE
;
5928 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */