| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| #include "scitems.hxx" |
| |
| #include <memory> //auto_ptr |
| #include <editeng/adjitem.hxx> |
| #include <svx/algitem.hxx> |
| #include <svx/dbexch.hrc> |
| #include <editeng/editview.hxx> |
| #include <editeng/editstat.hxx> |
| #include <editeng/flditem.hxx> |
| #include <svx/svdetc.hxx> |
| #include <editeng/editobj.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <sfx2/docfile.hxx> |
| #include <svl/stritem.hxx> |
| #include <svtools/svlbox.hxx> |
| #include <svtools/svtabbx.hxx> |
| #include <svl/urlbmk.hxx> |
| #include <tools/urlobj.hxx> |
| #include <vcl/cursor.hxx> |
| #include <vcl/sound.hxx> |
| #include <vcl/graph.hxx> |
| #include <vcl/hatch.hxx> |
| #include <sot/formats.hxx> |
| #include <sot/clsids.hxx> |
| |
| #include <svx/svdview.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT) |
| #include <editeng/outliner.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT) |
| #include <svx/svditer.hxx> |
| #include <svx/svdocapt.hxx> |
| #include <svx/svdpagv.hxx> |
| |
| #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> |
| #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> |
| #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp> |
| #include <com/sun/star/sheet/DataPilotTableResultData.hpp> |
| #include <com/sun/star/sheet/DataPilotTablePositionData.hpp> |
| #include <com/sun/star/sheet/DataPilotTablePositionType.hpp> |
| #include <com/sun/star/sheet/MemberResultFlags.hpp> |
| #include <com/sun/star/awt/KeyModifier.hpp> |
| #include <com/sun/star/awt/MouseButton.hpp> |
| #include <com/sun/star/script/vba/VBAEventId.hpp> |
| #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> |
| |
| #include "gridwin.hxx" |
| #include "tabvwsh.hxx" |
| #include "docsh.hxx" |
| #include "viewdata.hxx" |
| #include "tabview.hxx" |
| #include "select.hxx" |
| #include "scmod.hxx" |
| #include "document.hxx" |
| #include "attrib.hxx" |
| #include "dbcolect.hxx" |
| #include "stlpool.hxx" |
| #include "printfun.hxx" |
| #include "cbutton.hxx" |
| #include "sc.hrc" |
| #include "globstr.hrc" |
| #include "editutil.hxx" |
| #include "scresid.hxx" |
| #include "inputhdl.hxx" |
| #include "uiitems.hxx" // Filter-Dialog - auslagern !!! |
| #include "filtdlg.hxx" |
| #include "impex.hxx" // Sylk-ID fuer CB |
| #include "cell.hxx" // fuer Edit-Felder |
| #include "patattr.hxx" |
| #include "notemark.hxx" |
| #include "rfindlst.hxx" |
| #include "docpool.hxx" |
| #include "output.hxx" |
| #include "docfunc.hxx" |
| #include "dbdocfun.hxx" |
| #include "dpobject.hxx" |
| #include "dpoutput.hxx" |
| #include "transobj.hxx" |
| #include "drwtrans.hxx" |
| #include "seltrans.hxx" |
| #include "sizedev.hxx" |
| #include "AccessibilityHints.hxx" |
| #include "dpsave.hxx" |
| #include "viewuno.hxx" |
| #include "compiler.hxx" |
| #include "editable.hxx" |
| #include "fillinfo.hxx" |
| #include "scitems.hxx" |
| #include "userdat.hxx" |
| #include "drwlayer.hxx" |
| #include "attrib.hxx" |
| #include "validat.hxx" |
| #include "tabprotection.hxx" |
| #include "postit.hxx" |
| #include "dpcontrol.hxx" |
| #include "cellsuno.hxx" |
| |
| #include "drawview.hxx" |
| #include <svx/sdrpagewindow.hxx> |
| #include <svx/sdr/overlay/overlaymanager.hxx> |
| #include <vcl/svapp.hxx> |
| #include <svx/sdr/overlay/overlayselection.hxx> |
| |
| using namespace com::sun::star; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Any; |
| |
| const sal_uInt8 SC_NESTEDBUTTON_NONE = 0; |
| const sal_uInt8 SC_NESTEDBUTTON_DOWN = 1; |
| const sal_uInt8 SC_NESTEDBUTTON_UP = 2; |
| |
| #define SC_AUTOFILTER_ALL 0 |
| #define SC_AUTOFILTER_TOP10 1 |
| #define SC_AUTOFILTER_CUSTOM 2 |
| |
| // Modi fuer die FilterListBox |
| enum ScFilterBoxMode |
| { |
| SC_FILTERBOX_FILTER, |
| SC_FILTERBOX_DATASELECT, |
| SC_FILTERBOX_SCENARIO, |
| SC_FILTERBOX_PAGEFIELD |
| }; |
| |
| extern SfxViewShell* pScActiveViewShell; // global.cxx |
| extern sal_uInt16 nScClickMouseModifier; // global.cxx |
| extern sal_uInt16 nScFillModeMouseModifier; // global.cxx |
| |
| #define SC_FILTERLISTBOX_LINES 12 |
| |
| // ============================================================================ |
| |
| ScGridWindow::VisibleRange::VisibleRange() : |
| mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW) |
| { |
| } |
| |
| bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const |
| { |
| return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2; |
| } |
| |
| // ============================================================================ |
| |
| class ScFilterListBox : public ListBox |
| { |
| private: |
| ScGridWindow* pGridWin; |
| SCCOL nCol; |
| SCROW nRow; |
| sal_Bool bButtonDown; |
| sal_Bool bInit; |
| sal_Bool bCancelled; |
| sal_Bool bInSelect; |
| bool mbListHasDates; |
| sal_uLong nSel; |
| ScFilterBoxMode eMode; |
| |
| protected: |
| virtual void LoseFocus(); |
| void SelectHdl(); |
| |
| public: |
| ScFilterListBox( Window* pParent, ScGridWindow* pGrid, |
| SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ); |
| ~ScFilterListBox(); |
| |
| virtual long PreNotify( NotifyEvent& rNEvt ); |
| virtual void Select(); |
| |
| SCCOL GetCol() const { return nCol; } |
| SCROW GetRow() const { return nRow; } |
| ScFilterBoxMode GetMode() const { return eMode; } |
| sal_Bool IsDataSelect() const { return (eMode == SC_FILTERBOX_DATASELECT); } |
| void EndInit(); |
| sal_Bool IsInInit() const { return bInit; } |
| void SetCancelled() { bCancelled = sal_True; } |
| sal_Bool IsInSelect() const { return bInSelect; } |
| void SetListHasDates(bool b) { mbListHasDates = b; } |
| bool HasDates() const { return mbListHasDates; } |
| }; |
| |
| //------------------------------------------------------------------- |
| |
| // ListBox in einem FloatingWindow (pParent) |
| ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid, |
| SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) : |
| ListBox( pParent, WB_AUTOHSCROLL ), |
| pGridWin( pGrid ), |
| nCol( nNewCol ), |
| nRow( nNewRow ), |
| bButtonDown( sal_False ), |
| bInit( sal_True ), |
| bCancelled( sal_False ), |
| bInSelect( sal_False ), |
| mbListHasDates(false), |
| nSel( 0 ), |
| eMode( eNewMode ) |
| { |
| } |
| |
| __EXPORT ScFilterListBox::~ScFilterListBox() |
| { |
| if (IsMouseCaptured()) |
| ReleaseMouse(); |
| } |
| |
| void ScFilterListBox::EndInit() |
| { |
| sal_uInt16 nPos = GetSelectEntryPos(); |
| if ( LISTBOX_ENTRY_NOTFOUND == nPos ) |
| nSel = 0; |
| else |
| nSel = nPos; |
| |
| bInit = sal_False; |
| } |
| |
| void __EXPORT ScFilterListBox::LoseFocus() |
| { |
| #ifndef UNX |
| Hide(); |
| #endif |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long ScFilterListBox::PreNotify( NotifyEvent& rNEvt ) |
| { |
| long nDone = 0; |
| if ( rNEvt.GetType() == EVENT_KEYINPUT ) |
| { |
| KeyEvent aKeyEvt = *rNEvt.GetKeyEvent(); |
| KeyCode aCode = aKeyEvt.GetKeyCode(); |
| if ( !aCode.GetModifier() ) // ohne alle Modifiers |
| { |
| sal_uInt16 nKey = aCode.GetCode(); |
| if ( nKey == KEY_RETURN ) |
| { |
| SelectHdl(); // auswaehlen |
| nDone = 1; |
| } |
| else if ( nKey == KEY_ESCAPE ) |
| { |
| pGridWin->ClickExtern(); // loescht die List-Box !!! |
| nDone = 1; |
| } |
| } |
| } |
| |
| return nDone ? nDone : ListBox::PreNotify( rNEvt ); |
| } |
| |
| void __EXPORT ScFilterListBox::Select() |
| { |
| ListBox::Select(); |
| SelectHdl(); |
| } |
| |
| void __EXPORT ScFilterListBox::SelectHdl() |
| { |
| if ( !IsTravelSelect() && !bInit && !bCancelled ) |
| { |
| sal_uInt16 nPos = GetSelectEntryPos(); |
| if ( LISTBOX_ENTRY_NOTFOUND != nPos ) |
| { |
| nSel = nPos; |
| if (!bButtonDown) |
| { |
| // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect |
| bInSelect = sal_True; |
| pGridWin->FilterSelect( nSel ); |
| bInSelect = sal_False; |
| } |
| } |
| } |
| } |
| |
| // ============================================================================ |
| |
| // use a System floating window for the above filter listbox |
| class ScFilterFloatingWindow : public FloatingWindow |
| { |
| public: |
| ScFilterFloatingWindow( Window* pParent, WinBits nStyle = WB_STDFLOATWIN ); |
| virtual ~ScFilterFloatingWindow(); |
| // required for System FloatingWindows that will not process KeyInput by themselves |
| virtual Window* GetPreferredKeyInputWindow(); |
| }; |
| |
| ScFilterFloatingWindow::ScFilterFloatingWindow( Window* pParent, WinBits nStyle ) : |
| FloatingWindow( pParent, nStyle|WB_SYSTEMWINDOW ) // make it a system floater |
| {} |
| |
| ScFilterFloatingWindow::~ScFilterFloatingWindow() |
| { |
| EndPopupMode(); |
| } |
| |
| Window* ScFilterFloatingWindow::GetPreferredKeyInputWindow() |
| { |
| // redirect keyinput in the child window |
| return GetWindow(WINDOW_FIRSTCHILD) ? GetWindow(WINDOW_FIRSTCHILD)->GetPreferredKeyInputWindow() : NULL; // will be the FilterBox |
| } |
| |
| // ============================================================================ |
| |
| sal_Bool lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange ) |
| { |
| // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle |
| // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix. |
| //! Direkt die MatrixEdges Funktionen von der Column herausreichen ??? |
| |
| if ( !pDoc->IsBlockEditable( rRange.aStart.Tab(), rRange.aStart.Col(),rRange.aStart.Row(), |
| rRange.aEnd.Col(),rRange.aEnd.Row() ) ) |
| return sal_False; |
| |
| ScAddress aPos; |
| const ScBaseCell* pCell = pDoc->GetCell( rRange.aEnd ); |
| return ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && |
| ((ScFormulaCell*)pCell)->GetMatrixOrigin(aPos) && aPos == rRange.aStart ); |
| |
| } |
| |
| void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const Point& rPos, ScViewData* pViewData ) |
| { |
| if (!pView && !pPV && !pDrDoc && !pViewData) |
| return; |
| |
| ScDocument& rDoc = *pViewData->GetDocument(); |
| ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); |
| ScPostIt* pNote = rDoc.GetNote( aCellPos ); |
| SdrObject* pObj = pNote ? pNote->GetCaption() : 0; |
| if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) ) |
| { |
| const ScProtectionAttr* pProtAttr = static_cast< const ScProtectionAttr* > (rDoc.GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ) ); |
| bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell() ; |
| bool bProtectDoc = rDoc.IsTabProtected( aCellPos.Tab() ) || pViewData->GetSfxDocShell()->IsReadOnly() ; |
| // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged() |
| pView->LockInternalLayer( bProtectDoc && bProtectAttr ); |
| } |
| } |
| |
| sal_Bool lcl_GetHyperlinkCell(ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScBaseCell*& rpCell ) |
| { |
| sal_Bool bFound = sal_False; |
| do |
| { |
| pDoc->GetCell( rPosX, rPosY, nTab, rpCell ); |
| if ( !rpCell || rpCell->GetCellType() == CELLTYPE_NOTE ) |
| { |
| if ( rPosX <= 0 ) |
| return sal_False; // alles leer bis links |
| else |
| --rPosX; // weitersuchen |
| } |
| else if ( rpCell->GetCellType() == CELLTYPE_EDIT) |
| bFound = sal_True; |
| else if (rpCell->GetCellType() == CELLTYPE_FORMULA && |
| static_cast<ScFormulaCell*>(rpCell)->IsHyperLinkCell()) |
| bFound = sal_True; |
| else |
| return sal_False; // andere Zelle |
| } |
| while ( !bFound ); |
| |
| return bFound; |
| } |
| |
| // --------------------------------------------------------------------------- |
| // WB_DIALOGCONTROL noetig fuer UNO-Controls |
| ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos ) |
| : Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ), |
| DropTargetHelper( this ), |
| DragSourceHelper( this ), |
| mpOOCursors( NULL ), |
| mpOOSelection( NULL ), |
| mpOOAutoFill( NULL ), |
| mpOODragRect( NULL ), |
| mpOOHeader( NULL ), |
| mpOOShrink( NULL ), |
| mpAutoFillRect(static_cast<Rectangle*>(NULL)), |
| pViewData( pData ), |
| eWhich( eWhichPos ), |
| pNoteMarker( NULL ), |
| pFilterBox( NULL ), |
| pFilterFloat( NULL ), |
| mpDPFieldPopup(NULL), |
| mpFilterButton(NULL), |
| nCursorHideCount( 0 ), |
| bMarking( sal_False ), |
| nButtonDown( 0 ), |
| bEEMouse( sal_False ), |
| nMouseStatus( SC_GM_NONE ), |
| nNestedButtonState( SC_NESTEDBUTTON_NONE ), |
| bDPMouse( sal_False ), |
| bRFMouse( sal_False ), |
| nPagebreakMouse( SC_PD_NONE ), |
| bPagebreakDrawn( sal_False ), |
| nPageScript( 0 ), |
| bDragRect( sal_False ), |
| meDragInsertMode( INS_NONE ), |
| nCurrentPointer( 0 ), |
| bIsInScroll( sal_False ), |
| bIsInPaint( sal_False ), |
| aComboButton( this ), |
| aCurMousePos( 0,0 ), |
| nPaintCount( 0 ), |
| bNeedsRepaint( sal_False ), |
| bAutoMarkVisible( sal_False ), |
| bListValButton( sal_False ) |
| { |
| switch(eWhich) |
| { |
| case SC_SPLIT_TOPLEFT: |
| eHWhich = SC_SPLIT_LEFT; |
| eVWhich = SC_SPLIT_TOP; |
| break; |
| case SC_SPLIT_TOPRIGHT: |
| eHWhich = SC_SPLIT_RIGHT; |
| eVWhich = SC_SPLIT_TOP; |
| break; |
| case SC_SPLIT_BOTTOMLEFT: |
| eHWhich = SC_SPLIT_LEFT; |
| eVWhich = SC_SPLIT_BOTTOM; |
| break; |
| case SC_SPLIT_BOTTOMRIGHT: |
| eHWhich = SC_SPLIT_RIGHT; |
| eVWhich = SC_SPLIT_BOTTOM; |
| break; |
| default: |
| DBG_ERROR("GridWindow: falsche Position"); |
| } |
| |
| SetBackground(); |
| |
| SetMapMode(pViewData->GetLogicMode(eWhich)); |
| // EnableDrop(); |
| EnableChildTransparentMode(); |
| SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS ); |
| |
| SetHelpId( HID_SC_WIN_GRIDWIN ); |
| SetUniqueId( HID_SC_WIN_GRIDWIN ); |
| |
| SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() ); |
| EnableRTL( sal_False ); |
| } |
| |
| __EXPORT ScGridWindow::~ScGridWindow() |
| { |
| // #114409# |
| ImpDestroyOverlayObjects(); |
| |
| delete pFilterBox; |
| delete pFilterFloat; |
| delete pNoteMarker; |
| } |
| |
| void __EXPORT ScGridWindow::Resize( const Size& ) |
| { |
| // gar nix |
| } |
| |
| void ScGridWindow::ClickExtern() |
| { |
| do |
| { |
| // #i81298# don't delete the filter box when called from its select handler |
| // (possible through row header size update) |
| // #i84277# when initializing the filter box, a Basic error can deactivate the view |
| if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) ) |
| { |
| break; |
| } |
| |
| DELETEZ(pFilterBox); |
| DELETEZ(pFilterFloat); |
| } |
| while (false); |
| |
| if (mpDPFieldPopup.get()) |
| { |
| mpDPFieldPopup->close(false); |
| mpDPFieldPopup.reset(); |
| } |
| } |
| |
| IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG ) |
| { |
| if (pFilterBox) |
| pFilterBox->SetCancelled(); // nicht mehr auswaehlen |
| GrabFocus(); |
| return 0; |
| } |
| |
| IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo*, pInfo ) |
| { |
| if( pInfo->nCommand == SPELLCMD_STARTSPELLDLG ) |
| pViewData->GetDispatcher().Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON ); |
| return 0; |
| } |
| |
| void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, sal_Bool bHasSelection, const String& rStr ) |
| { |
| //! gridwin2 ? |
| |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab); |
| if ( pDPObj && nCol > 0 ) |
| { |
| // look for the dimension header left of the drop-down arrow |
| sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN; |
| long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient ); |
| if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE ) |
| { |
| ScDPSaveData aSaveData( *pDPObj->GetSaveData() ); |
| |
| sal_Bool bIsDataLayout; |
| String aDimName = pDPObj->GetDimName( nField, bIsDataLayout ); |
| if ( !bIsDataLayout ) |
| { |
| ScDPSaveDimension* pDim = aSaveData.GetDimensionByName(aDimName); |
| |
| if ( bHasSelection ) |
| pDim->SetCurrentPage( &rStr ); |
| else |
| pDim->SetCurrentPage( NULL ); |
| |
| ScDPObject aNewObj( *pDPObj ); |
| aNewObj.SetSaveData( aSaveData ); |
| ScDBDocFunc aFunc( *pViewData->GetDocShell() ); |
| aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False ); |
| pViewData->GetView()->CursorPosChanged(); // shells may be switched |
| } |
| } |
| } |
| } |
| |
| void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) |
| { |
| //! merge position/size handling with DoAutoFilterMenue |
| |
| delete pFilterBox; |
| delete pFilterFloat; |
| |
| sal_uInt16 i; |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| |
| long nSizeX = 0; |
| long nSizeY = 0; |
| long nHeight = 0; |
| pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); |
| Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich ); |
| if ( bLayoutRTL ) |
| aPos.X() -= nSizeX; |
| |
| Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); |
| |
| aPos.X() -= 1; |
| aPos.Y() += nSizeY - 1; |
| |
| pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // not resizable etc. |
| pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); |
| pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_PAGEFIELD ); |
| if ( bLayoutRTL ) |
| pFilterBox->EnableMirroring(); |
| |
| nSizeX += 1; |
| |
| { |
| Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() ); |
| MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL ); |
| |
| nHeight = GetTextHeight(); |
| nHeight *= SC_FILTERLISTBOX_LINES; |
| |
| SetMapMode( aOldMode ); |
| SetFont( aOldFont ); |
| } |
| |
| // SetSize comes later |
| |
| TypedScStrCollection aStrings( 128, 128 ); |
| |
| // get list box entries and selection |
| sal_Bool bHasCurrentPage = sal_False; |
| String aCurrentPage; |
| ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab); |
| if ( pDPObj && nCol > 0 ) |
| { |
| // look for the dimension header left of the drop-down arrow |
| sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN; |
| long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient ); |
| if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE ) |
| { |
| pDPObj->FillPageList( aStrings, nField ); |
| |
| // get current page from SaveData |
| |
| ScDPSaveData* pSaveData = pDPObj->GetSaveData(); |
| sal_Bool bIsDataLayout; |
| String aDimName = pDPObj->GetDimName( nField, bIsDataLayout ); |
| if ( pSaveData && !bIsDataLayout ) |
| { |
| ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName); |
| if ( pDim && pDim->HasCurrentPage() ) |
| { |
| aCurrentPage = pDim->GetCurrentPage(); |
| bHasCurrentPage = sal_True; |
| } |
| } |
| } |
| } |
| |
| // include all entry widths for the size of the drop-down |
| long nMaxText = 0; |
| sal_uInt16 nCount = aStrings.GetCount(); |
| for (i=0; i<nCount; i++) |
| { |
| TypedStrData* pData = aStrings[i]; |
| long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() ); |
| if ( nTextWidth > nMaxText ) |
| nMaxText = nTextWidth; |
| } |
| |
| // add scrollbar width if needed (string entries are counted here) |
| // (scrollbar is shown if the box is exactly full?) |
| if ( nCount >= SC_FILTERLISTBOX_LINES ) |
| nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); |
| |
| nMaxText += 4; // for borders |
| |
| if ( nMaxText > nSizeX ) |
| nSizeX = nMaxText; // just modify width - starting position is unchanged |
| |
| // adjust position and size to window |
| |
| Size aParentSize = GetParent()->GetOutputSizePixel(); |
| Size aSize( nSizeX, nHeight ); |
| |
| if ( aSize.Height() > aParentSize.Height() ) |
| aSize.Height() = aParentSize.Height(); |
| if ( aPos.Y() + aSize.Height() > aParentSize.Height() ) |
| aPos.Y() = aParentSize.Height() - aSize.Height(); |
| |
| pFilterBox->SetSizePixel( aSize ); |
| pFilterBox->Show(); // Show must be called before SetUpdateMode |
| pFilterBox->SetUpdateMode(sal_False); |
| |
| pFilterFloat->SetOutputSizePixel( aSize ); |
| pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS); |
| |
| // fill the list box |
| sal_Bool bWait = ( nCount > 100 ); |
| |
| if (bWait) |
| EnterWait(); |
| |
| for (i=0; i<nCount; i++) |
| pFilterBox->InsertEntry( aStrings[i]->GetString() ); |
| |
| pFilterBox->SetSeparatorPos( 0 ); |
| |
| if (bWait) |
| LeaveWait(); |
| |
| pFilterBox->SetUpdateMode(sal_True); |
| |
| sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND; |
| if (bHasCurrentPage) |
| nSelPos = pFilterBox->GetEntryPos( aCurrentPage ); |
| |
| if ( nSelPos == LISTBOX_ENTRY_NOTFOUND ) |
| nSelPos = 0; // first entry |
| |
| pFilterBox->GrabFocus(); |
| |
| // call Select after GrabFocus, so the focus rectangle ends up in the right position |
| if ( nSelPos != LISTBOX_ENTRY_NOTFOUND ) |
| pFilterBox->SelectEntryPos( nSelPos ); |
| |
| pFilterBox->EndInit(); |
| |
| nMouseStatus = SC_GM_FILTER; |
| CaptureMouse(); |
| } |
| |
| void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ) |
| { |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab); |
| if (!pDPObj) |
| return; |
| |
| // Get the geometry of the cell. |
| Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich); |
| long nSizeX, nSizeY; |
| pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY); |
| Size aScrSize(nSizeX-1, nSizeY-1); |
| |
| DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj); |
| } |
| |
| void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange ) |
| { |
| delete pFilterBox; |
| delete pFilterFloat; |
| |
| SCCOL nCol = rScenRange.aEnd.Col(); // Zelle unterhalb des Buttons |
| SCROW nRow = rScenRange.aStart.Row(); |
| if (nRow == 0) |
| { |
| nRow = rScenRange.aEnd.Row() + 1; // Bereich ganz oben -> Button unterhalb |
| if (nRow>MAXROW) nRow = MAXROW; |
| //! Texthoehe addieren (wenn sie an der View gespeichert ist...) |
| } |
| |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| |
| long nSizeX = 0; |
| long nSizeY = 0; |
| long nHeight = 0; |
| pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); |
| Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich ); |
| if ( bLayoutRTL ) |
| aPos.X() -= nSizeX; |
| Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); |
| aCellRect.Top() -= nSizeY; |
| aCellRect.Bottom() -= nSizeY - 1; |
| // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter |
| // (wenn die Linie verdeckt wird, sieht es komisch aus...) |
| |
| pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc. |
| pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); |
| pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_SCENARIO ); |
| if ( bLayoutRTL ) |
| pFilterBox->EnableMirroring(); |
| |
| nSizeX += 1; |
| |
| { |
| Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() ); |
| MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL ); |
| |
| nHeight = GetTextHeight(); |
| nHeight *= SC_FILTERLISTBOX_LINES; |
| |
| SetMapMode( aOldMode ); |
| SetFont( aOldFont ); |
| } |
| |
| // SetSize spaeter |
| /* |
| pFilterBox->SetSelectionMode( SINGLE_SELECTION ); |
| pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT )); |
| pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft ); |
| */ |
| |
| // ParentSize Abfrage fehlt |
| Size aSize( nSizeX, nHeight ); |
| pFilterBox->SetSizePixel( aSize ); |
| pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!! |
| pFilterBox->SetUpdateMode(sal_False); |
| |
| // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht |
| |
| // Listbox fuellen |
| |
| long nMaxText = 0; |
| String aCurrent; |
| String aTabName; |
| SCTAB nTabCount = pDoc->GetTableCount(); |
| SCTAB nEntryCount = 0; |
| for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) |
| { |
| if (pDoc->HasScenarioRange( i, rScenRange )) |
| if (pDoc->GetName( i, aTabName )) |
| { |
| pFilterBox->InsertEntry( aTabName ); |
| if (pDoc->IsActiveScenario(i)) |
| aCurrent = aTabName; |
| long nTextWidth = pFilterBox->GetTextWidth( aTabName ); |
| if ( nTextWidth > nMaxText ) |
| nMaxText = nTextWidth; |
| ++nEntryCount; |
| } |
| } |
| if (nEntryCount > SC_FILTERLISTBOX_LINES) |
| nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); |
| nMaxText += 4; // fuer Rand |
| if ( nMaxText > 300 ) |
| nMaxText = 300; // auch nicht uebertreiben (Pixel) |
| |
| if (nMaxText > nSizeX) // Groesse auf benoetigte Groesse anpassen |
| { |
| long nDiff = nMaxText - nSizeX; |
| aSize = Size( nMaxText, nHeight ); |
| pFilterBox->SetSizePixel( aSize ); |
| pFilterFloat->SetOutputSizePixel( aSize ); |
| |
| if ( !bLayoutRTL ) |
| { |
| // also move popup position |
| long nNewX = aCellRect.Left() - nDiff; |
| if ( nNewX < 0 ) |
| nNewX = 0; |
| aCellRect.Left() = nNewX; |
| } |
| } |
| |
| pFilterFloat->SetOutputSizePixel( aSize ); |
| pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS ); |
| |
| pFilterBox->SetUpdateMode(sal_True); |
| pFilterBox->GrabFocus(); |
| |
| // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet |
| //! SvLBoxEntry* pSelect = NULL; |
| sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND; |
| if (aCurrent.Len()) |
| { |
| nPos = pFilterBox->GetEntryPos( aCurrent ); |
| //! pSelect = pFilterBox->GetEntry( nPos ); |
| } |
| if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND == nPos && pFilterBox->GetEntryCount() > 0 ) |
| nPos = 0; |
| //! pSelect = pFilterBox->GetEntry(0); // einer sollte immer selektiert sein |
| if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND != nPos ) |
| pFilterBox->SelectEntryPos(nPos); |
| |
| pFilterBox->EndInit(); |
| |
| // Szenario-Auswahl kommt aus MouseButtonDown: |
| // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown |
| |
| nMouseStatus = SC_GM_FILTER; |
| CaptureMouse(); |
| } |
| |
| sal_Bool ScGridWindow::HasScenarioRange( sal_uInt16 nCol, sal_Int32 nRow, ScRange& rScenRange ) |
| { |
| ScDocument* pDoc = pViewData->GetDocument(); |
| sal_uInt16 nTab = pViewData->GetTabNo(); |
| sal_uInt16 nTabCount = pDoc->GetTableCount(); |
| if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) ) |
| { |
| sal_uInt16 i; |
| ScMarkData aMarks; |
| for (i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) |
| pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME ); |
| ScRangeList aRanges; |
| aMarks.FillRangeListWithMarks( &aRanges, sal_False ); |
| sal_uInt16 nRangeCount = (sal_uInt16)aRanges.Count(); |
| for (i=0; i<nRangeCount; i++) |
| { |
| ScRange aRange = *aRanges.GetObject(i); |
| pDoc->ExtendTotalMerge( aRange ); |
| sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 ); |
| sal_Bool bIsInScen = sal_False; |
| if ( bTextBelow ) |
| { |
| bIsInScen = (aRange.aStart.Col() == nCol && aRange.aEnd.Row() == nRow-1); |
| } |
| else |
| { |
| bIsInScen = (aRange.aStart.Col() == nCol && aRange.aStart.Row() == nRow+1); |
| } |
| if (bIsInScen) |
| { |
| rScenRange = aRange; |
| return sal_True; |
| } |
| } |
| } |
| return sal_False; |
| } |
| void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, sal_Bool bDataSelect ) |
| { |
| delete pFilterBox; |
| delete pFilterFloat; |
| |
| sal_uInt16 i; |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| |
| long nSizeX = 0; |
| long nSizeY = 0; |
| long nHeight = 0; |
| pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); |
| // The button height should not use the merged cell height, should still use single row height |
| nSizeY = pViewData->ToPixel(pDoc->GetRowHeight(nRow, nTab), pViewData->GetPPTY()); |
| Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich ); |
| if ( bLayoutRTL ) |
| aPos.X() -= nSizeX; |
| |
| Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); |
| |
| aPos.X() -= 1; |
| aPos.Y() += nSizeY - 1; |
| |
| pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc. |
| pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); |
| pFilterBox = new ScFilterListBox( |
| pFilterFloat, this, nCol, nRow, bDataSelect ? SC_FILTERBOX_DATASELECT : SC_FILTERBOX_FILTER ); |
| if ( bLayoutRTL ) |
| pFilterBox->EnableMirroring(); |
| |
| nSizeX += 1; |
| |
| { |
| Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() ); |
| MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL ); |
| |
| nHeight = GetTextHeight(); |
| nHeight *= SC_FILTERLISTBOX_LINES; |
| |
| SetMapMode( aOldMode ); |
| SetFont( aOldFont ); |
| } |
| |
| // SetSize spaeter |
| /* |
| pFilterBox->SetSelectionMode( SINGLE_SELECTION ); |
| pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT )); |
| pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft ); |
| */ |
| |
| sal_Bool bEmpty = sal_False; |
| TypedScStrCollection aStrings( 128, 128 ); |
| if ( bDataSelect ) // Auswahl-Liste |
| { |
| // Liste fuellen |
| aStrings.SetCaseSensitive( sal_True ); |
| pDoc->GetDataEntries( nCol, nRow, nTab, aStrings ); |
| if ( aStrings.GetCount() == 0 ) |
| bEmpty = sal_True; |
| } |
| else // AutoFilter |
| { |
| //! wird der Titel ueberhaupt ausgewertet ??? |
| String aString; |
| pDoc->GetString( nCol, nRow, nTab, aString ); |
| pFilterBox->SetText( aString ); |
| |
| long nMaxText = 0; |
| |
| // default entries |
| static const sal_uInt16 nDefIDs[] = { SCSTR_ALLFILTER, SCSTR_TOP10FILTER, SCSTR_STDFILTER }; |
| const sal_uInt16 nDefCount = sizeof(nDefIDs) / sizeof(sal_uInt16); |
| for (i=0; i<nDefCount; i++) |
| { |
| String aEntry( (ScResId) nDefIDs[i] ); |
| pFilterBox->InsertEntry( aEntry ); |
| long nTextWidth = pFilterBox->GetTextWidth( aEntry ); |
| if ( nTextWidth > nMaxText ) |
| nMaxText = nTextWidth; |
| } |
| pFilterBox->SetSeparatorPos( nDefCount - 1 ); |
| |
| // get list entries |
| bool bHasDates = false; |
| pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates); |
| pFilterBox->SetListHasDates(bHasDates); |
| |
| // check widths of numerical entries (string entries are not included) |
| // so all numbers are completely visible |
| sal_uInt16 nCount = aStrings.GetCount(); |
| for (i=0; i<nCount; i++) |
| { |
| TypedStrData* pData = aStrings[i]; |
| if ( !pData->IsStrData() ) // only numerical entries |
| { |
| long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() ); |
| if ( nTextWidth > nMaxText ) |
| nMaxText = nTextWidth; |
| } |
| } |
| |
| // add scrollbar width if needed (string entries are counted here) |
| // (scrollbar is shown if the box is exactly full?) |
| if ( nCount + nDefCount >= SC_FILTERLISTBOX_LINES ) |
| nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); |
| |
| nMaxText += 4; // for borders |
| |
| if ( nMaxText > nSizeX ) |
| nSizeX = nMaxText; // just modify width - starting position is unchanged |
| } |
| |
| if (!bEmpty) |
| { |
| // Position und Groesse an Fenster anpassen |
| //! vorher Abfrage, ob die Eintraege hineinpassen (Breite) |
| |
| Size aParentSize = GetParent()->GetOutputSizePixel(); |
| Size aSize( nSizeX, nHeight ); |
| |
| if ( aSize.Height() > aParentSize.Height() ) |
| aSize.Height() = aParentSize.Height(); |
| if ( aPos.Y() + aSize.Height() > aParentSize.Height() ) |
| aPos.Y() = aParentSize.Height() - aSize.Height(); |
| |
| pFilterBox->SetSizePixel( aSize ); |
| pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!! |
| pFilterBox->SetUpdateMode(sal_False); |
| |
| pFilterFloat->SetOutputSizePixel( aSize ); |
| pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS); |
| |
| // Listbox fuellen |
| sal_uInt16 nCount = aStrings.GetCount(); |
| sal_Bool bWait = ( nCount > 100 ); |
| |
| if (bWait) |
| EnterWait(); |
| |
| for (i=0; i<nCount; i++) |
| pFilterBox->InsertEntry( aStrings[i]->GetString() ); |
| |
| if (bWait) |
| LeaveWait(); |
| |
| pFilterBox->SetUpdateMode(sal_True); |
| } |
| |
| //! SvLBoxEntry* pSelect = NULL; |
| sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND; |
| |
| if (!bDataSelect) // AutoFilter: aktiven Eintrag selektieren |
| { |
| ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab ); |
| if (pDBData) |
| { |
| ScQueryParam aParam; |
| pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben |
| |
| sal_Bool bValid = sal_True; |
| for (SCSIZE j=0; j<MAXQUERY && bValid; j++) // bisherige Filter-Einstellungen |
| if (aParam.GetEntry(j).bDoQuery) |
| { |
| //! Abfrage mit DrawButtons zusammenfassen! |
| |
| ScQueryEntry& rEntry = aParam.GetEntry(j); |
| if (j>0) |
| if (rEntry.eConnect != SC_AND) |
| bValid = sal_False; |
| if (rEntry.nField == nCol) |
| { |
| if (rEntry.eOp == SC_EQUAL) |
| { |
| String* pStr = rEntry.pStr; |
| if (pStr) |
| { |
| nSelPos = pFilterBox->GetEntryPos( *pStr ); |
| //! pSelect = pFilterBox->GetEntry( nPos ); |
| } |
| } |
| else if (rEntry.eOp == SC_TOPVAL && rEntry.pStr && |
| rEntry.pStr->EqualsAscii("10")) |
| nSelPos = SC_AUTOFILTER_TOP10; |
| else |
| nSelPos = SC_AUTOFILTER_CUSTOM; |
| } |
| } |
| |
| if (!bValid) |
| nSelPos = SC_AUTOFILTER_CUSTOM; |
| } |
| } |
| else |
| { |
| |
| sal_uLong nIndex = ((SfxUInt32Item*)pDoc->GetAttr( |
| nCol, nRow, nTab, ATTR_VALIDDATA ))->GetValue(); |
| if ( nIndex ) |
| { |
| const ScValidationData* pData = pDoc->GetValidationEntry( nIndex ); |
| if (pData) |
| { |
| TypedStrData* pNew = NULL; |
| String aDocStr; |
| pDoc->GetString( nCol, nRow, nTab, aDocStr ); |
| if ( pDoc->HasValueData( nCol, nRow, nTab ) ) |
| { |
| double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nTab)); |
| pNew = new TypedStrData( aDocStr, fVal, SC_STRTYPE_VALUE ); |
| } |
| else |
| pNew = new TypedStrData( aDocStr, 0.0, SC_STRTYPE_STANDARD ); |
| |
| bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING); |
| if ( bSortList ) |
| { |
| sal_uInt16 nStrIndex; |
| if (aStrings.Search(pNew,nStrIndex)) |
| nSelPos = nStrIndex; |
| } |
| else |
| { |
| sal_uInt16 nCount = aStrings.GetCount(); |
| for (i = 0; ((i < nCount) && ( LISTBOX_ENTRY_NOTFOUND == nSelPos)); i++) |
| { |
| if ( aStrings.Compare(aStrings[i], pNew)==0 ) |
| nSelPos = i; |
| } |
| } |
| delete pNew; |
| } |
| } |
| } |
| |
| // neu (309): irgendwas muss immer selektiert sein: |
| if ( LISTBOX_ENTRY_NOTFOUND == nSelPos && pFilterBox->GetEntryCount() > 0 && !bDataSelect) |
| nSelPos = 0; |
| |
| // keine leere Auswahl-Liste anzeigen: |
| |
| if ( bEmpty ) |
| { |
| DELETEZ(pFilterBox); // war nix |
| DELETEZ(pFilterFloat); |
| Sound::Beep(); // bemerkbar machen |
| } |
| else |
| { |
| // pFilterBox->Show(); // schon vorne |
| pFilterBox->GrabFocus(); |
| |
| // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet |
| if ( LISTBOX_ENTRY_NOTFOUND != nSelPos ) |
| pFilterBox->SelectEntryPos( nSelPos ); |
| else |
| { |
| if (bDataSelect) |
| pFilterBox->SetNoSelection(); |
| } |
| |
| pFilterBox->EndInit(); |
| |
| if (!bDataSelect) |
| { |
| // AutoFilter (aus MouseButtonDown): |
| // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown |
| |
| nMouseStatus = SC_GM_FILTER; |
| CaptureMouse(); |
| } |
| } |
| } |
| |
| void ScGridWindow::FilterSelect( sal_uLong nSel ) |
| { |
| String aString; |
| /* |
| SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel ); |
| if (pEntry) |
| { |
| SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING ); |
| if ( pStringEntry ) |
| aString = pStringEntry->GetText(); |
| } |
| */ |
| aString = pFilterBox->GetEntry( static_cast< sal_uInt16 >( nSel ) ); |
| |
| SCCOL nCol = pFilterBox->GetCol(); |
| SCROW nRow = pFilterBox->GetRow(); |
| switch ( pFilterBox->GetMode() ) |
| { |
| case SC_FILTERBOX_DATASELECT: |
| ExecDataSelect( nCol, nRow, aString ); |
| break; |
| case SC_FILTERBOX_FILTER: |
| ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() ); |
| break; |
| case SC_FILTERBOX_SCENARIO: |
| pViewData->GetView()->UseScenario( aString ); |
| break; |
| case SC_FILTERBOX_PAGEFIELD: |
| // first entry is "all" |
| ExecPageFieldSelect( nCol, nRow, (nSel != 0), aString ); |
| break; |
| } |
| |
| if (pFilterFloat) |
| pFilterFloat->EndPopupMode(); |
| |
| GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht |
| } |
| |
| void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr ) |
| { |
| if ( rStr.Len() ) |
| { |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScViewFunc* pView = pViewData->GetView(); |
| pView->EnterData( nCol, nRow, nTab, rStr ); |
| |
| // #i52307# CellContentChanged is not in EnterData so it isn't called twice |
| // if the cursor is moved afterwards. |
| pView->CellContentChanged(); |
| } |
| } |
| |
| void ScGridWindow::ExecFilter( sal_uLong nSel, |
| SCCOL nCol, SCROW nRow, |
| const String& aValue, bool bCheckForDates ) |
| { |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScDocument* pDoc = pViewData->GetDocument(); |
| |
| ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab ); |
| if (pDBData) |
| { |
| ScQueryParam aParam; |
| pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben |
| |
| if (SC_AUTOFILTER_CUSTOM == nSel) |
| { |
| SCTAB nAreaTab; |
| SCCOL nStartCol; |
| SCROW nStartRow; |
| SCCOL nEndCol; |
| SCROW nEndRow; |
| pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow ); |
| pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab)); |
| pViewData->GetView()->SetCursor(nCol,nRow); //! auch ueber Slot ?? |
| pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD ); |
| } |
| else |
| { |
| sal_Bool bDeleteOld = sal_False; |
| SCSIZE nQueryPos = 0; |
| sal_Bool bFound = sal_False; |
| if (!aParam.bInplace) |
| bDeleteOld = sal_True; |
| if (aParam.bRegExp) |
| bDeleteOld = sal_True; |
| for (SCSIZE i=0; i<MAXQUERY && !bDeleteOld; i++) // bisherige Filter-Einstellungen |
| if (aParam.GetEntry(i).bDoQuery) |
| { |
| //! Abfrage mit DrawButtons zusammenfassen! |
| |
| ScQueryEntry& rEntry = aParam.GetEntry(i); |
| if (i>0) |
| if (rEntry.eConnect != SC_AND) |
| bDeleteOld = sal_True; |
| |
| if (rEntry.nField == nCol) |
| { |
| if (bFound) // diese Spalte zweimal? |
| bDeleteOld = sal_True; |
| nQueryPos = i; |
| bFound = sal_True; |
| } |
| if (!bFound) |
| nQueryPos = i + 1; |
| } |
| |
| if (bDeleteOld) |
| { |
| SCSIZE nEC = aParam.GetEntryCount(); |
| for (SCSIZE i=0; i<nEC; i++) |
| aParam.GetEntry(i).Clear(); |
| nQueryPos = 0; |
| aParam.bInplace = sal_True; |
| aParam.bRegExp = sal_False; |
| } |
| |
| if ( nQueryPos < MAXQUERY || SC_AUTOFILTER_ALL == nSel ) // loeschen geht immer |
| { |
| if (nSel) |
| { |
| ScQueryEntry& rNewEntry = aParam.GetEntry(nQueryPos); |
| |
| rNewEntry.bDoQuery = sal_True; |
| rNewEntry.bQueryByString = sal_True; |
| rNewEntry.nField = nCol; |
| rNewEntry.bQueryByDate = bCheckForDates; |
| if ( nSel == SC_AUTOFILTER_TOP10 ) |
| { |
| rNewEntry.eOp = SC_TOPVAL; |
| *rNewEntry.pStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10")); |
| } |
| else |
| { |
| rNewEntry.eOp = SC_EQUAL; |
| *rNewEntry.pStr = aValue; |
| } |
| if (nQueryPos > 0) |
| rNewEntry.eConnect = SC_AND; |
| } |
| else |
| { |
| if (bFound) |
| aParam.DeleteQuery(nQueryPos); |
| } |
| |
| // #100597# end edit mode - like in ScCellShell::ExecuteDB |
| if ( pViewData->HasEditView( pViewData->GetActivePart() ) ) |
| { |
| SC_MOD()->InputEnterHandler(); |
| pViewData->GetViewShell()->UpdateInputHandler(); |
| } |
| |
| pViewData->GetView()->Query( aParam, NULL, sal_True ); |
| pDBData->SetQueryParam( aParam ); // speichern |
| } |
| else // "Zuviele Bedingungen" |
| pViewData->GetView()->ErrorMessage( STR_FILTER_TOOMANY ); |
| } |
| } |
| else |
| { |
| DBG_ERROR("Wo ist der Datenbankbereich?"); |
| } |
| } |
| |
| void ScGridWindow::SetPointer( const Pointer& rPointer ) |
| { |
| nCurrentPointer = 0; |
| Window::SetPointer( rPointer ); |
| } |
| |
| void ScGridWindow::MoveMouseStatus( ScGridWindow& rDestWin ) |
| { |
| if (nButtonDown) |
| { |
| rDestWin.nButtonDown = nButtonDown; |
| rDestWin.nMouseStatus = nMouseStatus; |
| } |
| |
| if (bRFMouse) |
| { |
| rDestWin.bRFMouse = bRFMouse; |
| rDestWin.bRFSize = bRFSize; |
| rDestWin.nRFIndex = nRFIndex; |
| rDestWin.nRFAddX = nRFAddX; |
| rDestWin.nRFAddY = nRFAddY; |
| bRFMouse = sal_False; |
| } |
| |
| if (nPagebreakMouse) |
| { |
| rDestWin.nPagebreakMouse = nPagebreakMouse; |
| rDestWin.nPagebreakBreak = nPagebreakBreak; |
| rDestWin.nPagebreakPrev = nPagebreakPrev; |
| rDestWin.aPagebreakSource = aPagebreakSource; |
| rDestWin.aPagebreakDrag = aPagebreakDrag; |
| nPagebreakMouse = SC_PD_NONE; |
| } |
| } |
| |
| sal_Bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, sal_Bool bAction ) |
| { |
| // MouseEvent buttons must only be checked if bAction==TRUE |
| // to allow changing the mouse pointer in MouseMove, |
| // but not start AutoFill with right button (#74229#). |
| // with bAction==sal_True, SetFillMode / SetDragMode is called |
| |
| if ( bAction && !rMEvt.IsLeft() ) |
| return sal_False; |
| |
| sal_Bool bNewPointer = sal_False; |
| |
| SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient(); |
| sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() ); |
| |
| if ( pViewData->IsActive() && !bOleActive ) |
| { |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| |
| // Auto-Fill |
| |
| ScRange aMarkRange; |
| if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE) |
| { |
| if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect) |
| { |
| Point aMousePos = rMEvt.GetPosPixel(); |
| if (mpAutoFillRect->IsInside(aMousePos)) |
| { |
| SetPointer( Pointer( POINTER_CROSS ) ); //! dickeres Kreuz ? |
| if (bAction) |
| { |
| SCCOL nX = aMarkRange.aEnd.Col(); |
| SCROW nY = aMarkRange.aEnd.Row(); |
| |
| if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) ) |
| pViewData->SetDragMode( |
| aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX ); |
| else |
| pViewData->SetFillMode( |
| aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY ); |
| |
| // #108266# The simple selection must also be recognized when dragging, |
| // where the Marking flag is set and MarkToSimple won't work anymore. |
| pViewData->GetMarkData().MarkToSimple(); |
| } |
| bNewPointer = sal_True; |
| } |
| } |
| } |
| |
| // Embedded-Rechteck |
| |
| if (pDoc->IsEmbedded()) |
| { |
| ScRange aRange; |
| pDoc->GetEmbedded( aRange ); |
| if ( pViewData->GetTabNo() == aRange.aStart.Tab() ) |
| { |
| Point aStartPos = pViewData->GetScrPos( aRange.aStart.Col(), aRange.aStart.Row(), eWhich ); |
| Point aEndPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich ); |
| Point aMousePos = rMEvt.GetPosPixel(); |
| if ( bLayoutRTL ) |
| { |
| aStartPos.X() += 2; |
| aEndPos.X() += 2; |
| } |
| sal_Bool bTop = ( aMousePos.X() >= aStartPos.X()-3 && aMousePos.X() <= aStartPos.X()+1 && |
| aMousePos.Y() >= aStartPos.Y()-3 && aMousePos.Y() <= aStartPos.Y()+1 ); |
| sal_Bool bBottom = ( aMousePos.X() >= aEndPos.X()-3 && aMousePos.X() <= aEndPos.X()+1 && |
| aMousePos.Y() >= aEndPos.Y()-3 && aMousePos.Y() <= aEndPos.Y()+1 ); |
| if ( bTop || bBottom ) |
| { |
| SetPointer( Pointer( POINTER_CROSS ) ); |
| if (bAction) |
| { |
| sal_uInt8 nMode = bTop ? SC_FILL_EMBED_LT : SC_FILL_EMBED_RB; |
| pViewData->SetDragMode( |
| aRange.aStart.Col(), aRange.aStart.Row(), |
| aRange.aEnd.Col(), aRange.aEnd.Row(), nMode ); |
| } |
| bNewPointer = sal_True; |
| } |
| } |
| } |
| } |
| |
| if (!bNewPointer && bAction) |
| { |
| // SetPointer( POINTER_ARROW ); // in Fu... |
| pViewData->ResetFillMode(); |
| } |
| |
| return bNewPointer; |
| } |
| |
| void __EXPORT ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt ) |
| { |
| nNestedButtonState = SC_NESTEDBUTTON_DOWN; |
| |
| HandleMouseButtonDown( rMEvt ); |
| |
| if ( nNestedButtonState == SC_NESTEDBUTTON_UP ) |
| { |
| // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule, |
| // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case, |
| // simulate another MouseButtonUp call, so the selection state is consistent. |
| |
| nButtonDown = rMEvt.GetButtons(); |
| FakeButtonUp(); |
| |
| if ( IsTracking() ) |
| EndTracking(); // normally done in VCL as part of MouseButtonUp handling |
| } |
| nNestedButtonState = SC_NESTEDBUTTON_NONE; |
| } |
| |
| void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt ) |
| { |
| // We have to check if a context menu is shown and we have an UI |
| // active inplace client. In that case we have to ignore the event. |
| // Otherwise we would crash (context menu has been |
| // opened by inplace client and we would deactivate the inplace client, |
| // the contex menu is closed by VCL asynchronously which in the end |
| // would work on deleted objects or the context menu has no parent anymore) |
| // See #126086# and #128122# |
| SfxViewShell* pViewSh = pViewData->GetViewShell(); |
| SfxInPlaceClient* pClient = pViewSh->GetIPClient(); |
| if ( pClient && |
| pClient->IsObjectInPlaceActive() && |
| PopupMenu::IsInExecute() ) |
| return; |
| |
| aCurMousePos = rMEvt.GetPosPixel(); |
| |
| // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick |
| // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig: |
| #if 0 |
| // merken, dass FilterBox geloescht wird, damit sichergestellt |
| // ist, dass in diesem Handler nicht an gleicher Stelle wieder |
| // eine neue geoeffnet wird. |
| sal_Bool bWasFilterBox = ( pFilterBox != NULL && |
| ((Window*)pFilterBox)->IsVisible() && |
| !pFilterBox->IsDataSelect() ); |
| SCCOL nOldColFBox = bWasFilterBox ? pFilterBox->GetCol() : 0; |
| SCROW nOldRowFBox = bWasFilterBox ? pFilterBox->GetRow() : 0; |
| #endif |
| |
| ClickExtern(); // loescht FilterBox, wenn vorhanden |
| |
| HideNoteMarker(); // Notiz-Anzeige |
| |
| bEEMouse = sal_False; |
| |
| ScModule* pScMod = SC_MOD(); |
| if (pScMod->IsModalMode(pViewData->GetSfxDocShell())) |
| { |
| Sound::Beep(); |
| return; |
| } |
| |
| pScActiveViewShell = pViewData->GetViewShell(); // falls auf Link geklickt wird |
| nScClickMouseModifier = rMEvt.GetModifier(); // um Control-Klick immer zu erkennen |
| |
| sal_Bool bDetective = pViewData->GetViewShell()->IsAuditShell(); |
| sal_Bool bRefMode = pViewData->IsRefMode(); // Referenz angefangen |
| sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz |
| sal_Bool bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE |
| sal_Bool bDouble = (rMEvt.GetClicks() == 2); |
| |
| // DeactivateIP passiert nur noch bei MarkListHasChanged |
| |
| // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen |
| // (z.B. beim Umbenennen von Tabellen per Tab-Reiter) |
| |
| if ( !nButtonDown || !bDouble ) // single (first) click is always valid |
| nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works |
| |
| // pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus(); |
| if ( ( bEditMode && pViewData->GetActivePart() == eWhich ) || !bFormulaMode ) |
| GrabFocus(); |
| |
| // #i31846# need to cancel a double click if the first click has set the "ignore" state, |
| // but a single (first) click is always valid |
| if ( nMouseStatus == SC_GM_IGNORE && bDouble ) |
| { |
| nButtonDown = 0; |
| nMouseStatus = SC_GM_NONE; |
| return; |
| } |
| |
| if ( bDetective ) // Detektiv-Fuell-Modus |
| { |
| if ( rMEvt.IsLeft() && !rMEvt.GetModifier() ) |
| { |
| Point aPos = rMEvt.GetPosPixel(); |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| |
| SfxInt16Item aPosXItem( SID_RANGE_COL, nPosX ); |
| SfxInt32Item aPosYItem( SID_RANGE_ROW, nPosY ); |
| pViewData->GetDispatcher().Execute( SID_FILL_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, |
| &aPosXItem, &aPosYItem, (void*)0L ); |
| |
| } |
| nButtonDown = 0; |
| nMouseStatus = SC_GM_NONE; |
| return; |
| } |
| |
| if (!bDouble) |
| nMouseStatus = SC_GM_NONE; |
| |
| if (!bFormulaMode) |
| { |
| if ( pViewData->GetActivePart() != eWhich ) |
| pViewData->GetView()->ActivatePart( eWhich ); |
| } |
| else |
| { |
| ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine(); |
| pSelEng->SetWindow(this); |
| pSelEng->SetWhich(eWhich); |
| pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) ); |
| } |
| |
| if (bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo())) |
| { |
| Point aPos = rMEvt.GetPosPixel(); |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| |
| EditView* pEditView; |
| SCCOL nEditCol; |
| SCROW nEditRow; |
| pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); |
| SCCOL nEndCol = pViewData->GetEditEndCol(); |
| SCROW nEndRow = pViewData->GetEditEndRow(); |
| |
| if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol && |
| nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow ) |
| { |
| // #53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen |
| if (bFormulaMode) // sonst ist es oben schon passiert |
| GrabFocus(); |
| |
| pScMod->SetInputMode( SC_INPUT_TABLE ); |
| bEEMouse = sal_True; |
| bEditMode = pEditView->MouseButtonDown( rMEvt ); |
| return; |
| } |
| } |
| |
| if (pScMod->GetIsWaterCan()) |
| { |
| //! was is mit'm Mac ??? |
| if ( rMEvt.GetModifier() + rMEvt.GetButtons() == MOUSE_RIGHT ) |
| { |
| nMouseStatus = SC_GM_WATERUNDO; |
| return; |
| } |
| } |
| |
| // Reihenfolge passend zum angezeigten Cursor: |
| // RangeFinder, AutoFill, PageBreak, Drawing |
| |
| if ( HitRangeFinder( rMEvt.GetPosPixel(), bRFSize, &nRFIndex, &nRFAddX, &nRFAddY ) ) |
| { |
| bRFMouse = sal_True; // die anderen Variablen sind oben initialisiert |
| |
| if ( pViewData->GetActivePart() != eWhich ) |
| pViewData->GetView()->ActivatePart( eWhich ); //! schon oben immer ??? |
| |
| // CaptureMouse(); |
| StartTracking(); |
| return; |
| } |
| |
| sal_Bool bCrossPointer = TestMouse( rMEvt, sal_True ); |
| if ( bCrossPointer ) |
| { |
| if ( bDouble ) |
| pViewData->GetView()->FillCrossDblClick(); |
| else |
| pScMod->InputEnterHandler(); // Autofill etc. |
| } |
| |
| if ( !bCrossPointer ) |
| { |
| nPagebreakMouse = HitPageBreak( rMEvt.GetPosPixel(), &aPagebreakSource, |
| &nPagebreakBreak, &nPagebreakPrev ); |
| if (nPagebreakMouse) |
| { |
| bPagebreakDrawn = sal_False; |
| // CaptureMouse(); |
| StartTracking(); |
| PagebreakMove( rMEvt, sal_False ); |
| return; |
| } |
| } |
| |
| if (!bFormulaMode && !bEditMode && rMEvt.IsLeft()) |
| { |
| if ( !bCrossPointer && DrawMouseButtonDown(rMEvt) ) |
| { |
| //if (DrawHasMarkedObj()) |
| // pViewData->GetViewShell()->SetDrawShellOrSub(); // Draw-Objekt selektiert |
| return; |
| } |
| |
| pViewData->GetViewShell()->SetDrawShell( sal_False ); // kein Draw-Objekt selektiert |
| |
| // TestMouse schon oben passiert |
| } |
| |
| Point aPos = rMEvt.GetPosPixel(); |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScDocument* pDoc = pViewData->GetDocument(); |
| |
| |
| // |
| // AutoFilter buttons |
| // |
| |
| if ( !bDouble && !bFormulaMode && rMEvt.IsLeft() ) |
| { |
| SCsCOL nRealPosX; |
| SCsROW nRealPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nRealPosX, nRealPosY, false );//the real row/col |
| ScMergeFlagAttr* pRealPosAttr = (ScMergeFlagAttr*) |
| pDoc->GetAttr( nRealPosX, nRealPosY, nTab, ATTR_MERGE_FLAG ); |
| ScMergeFlagAttr* pAttr = (ScMergeFlagAttr*) |
| pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG ); |
| if( pRealPosAttr->HasAutoFilter() ) |
| { |
| SC_MOD()->InputEnterHandler(); |
| if (DoAutoFilterButton( nRealPosX, nRealPosY, rMEvt)) |
| return; |
| } |
| if( pAttr->HasAutoFilter() ) |
| { |
| SC_MOD()->InputEnterHandler(); //Add for i85305 |
| if (DoAutoFilterButton( nPosX, nPosY, rMEvt)) |
| return; |
| } |
| if (pAttr->HasButton()) |
| { |
| DoPushButton( nPosX, nPosY, rMEvt ); // setzt evtl. bPivotMouse / bDPMouse |
| return; |
| } |
| |
| // List Validity drop-down button |
| |
| if ( bListValButton ) |
| { |
| Rectangle aButtonRect = GetListValButtonRect( aListValPos ); |
| if ( aButtonRect.IsInside( aPos ) ) |
| { |
| DoAutoFilterMenue( aListValPos.Col(), aListValPos.Row(), sal_True ); |
| |
| nMouseStatus = SC_GM_FILTER; // not set in DoAutoFilterMenue for bDataSelect |
| CaptureMouse(); |
| return; |
| } |
| } |
| } |
| |
| // |
| // scenario selection |
| // |
| |
| ScRange aScenRange; |
| if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) ) |
| { |
| DoScenarioMenue( aScenRange ); |
| return; |
| } |
| |
| // |
| // Doppelklick angefangen ? |
| // |
| |
| // StopMarking kann aus DrawMouseButtonDown gerufen werden |
| |
| if ( nMouseStatus != SC_GM_IGNORE && !bRefMode ) |
| { |
| if ( bDouble && !bCrossPointer ) |
| { |
| if (nMouseStatus == SC_GM_TABDOWN) |
| nMouseStatus = SC_GM_DBLDOWN; |
| } |
| else |
| nMouseStatus = SC_GM_TABDOWN; |
| } |
| |
| // |
| // Links in Edit-Zellen |
| // |
| |
| sal_Bool bAlt = rMEvt.IsMod2(); |
| if ( !bAlt && rMEvt.IsLeft() && |
| GetEditUrl(rMEvt.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen |
| { |
| SetPointer( Pointer( POINTER_REFHAND ) ); |
| nMouseStatus = SC_GM_URLDOWN; // auch nur dann beim ButtonUp ausfuehren |
| return; |
| } |
| |
| // |
| // Gridwin - SelectionEngine |
| // |
| |
| if ( rMEvt.IsLeft() ) |
| { |
| ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine(); |
| pSelEng->SetWindow(this); |
| pSelEng->SetWhich(eWhich); |
| pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) ); |
| |
| // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag |
| if ( pViewData->GetView()->SelMouseButtonDown( rMEvt ) ) |
| { |
| if (IsMouseCaptured()) |
| { |
| // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann |
| //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?! |
| ReleaseMouse(); |
| StartTracking(); |
| } |
| pViewData->GetMarkData().SetMarking(sal_True); |
| return; |
| } |
| } |
| } |
| |
| void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt ) |
| { |
| aCurMousePos = rMEvt.GetPosPixel(); |
| ScDocument* pDoc = pViewData->GetDocument(); |
| ScMarkData& rMark = pViewData->GetMarkData(); |
| |
| // #i41690# detect a MouseButtonUp call from within MouseButtonDown |
| // (possible through Reschedule from storing an OLE object that is deselected) |
| |
| if ( nNestedButtonState == SC_NESTEDBUTTON_DOWN ) |
| nNestedButtonState = SC_NESTEDBUTTON_UP; |
| |
| if (nButtonDown != rMEvt.GetButtons()) |
| nMouseStatus = SC_GM_IGNORE; // reset und return |
| |
| nButtonDown = 0; |
| |
| if (nMouseStatus == SC_GM_IGNORE) |
| { |
| nMouseStatus = SC_GM_NONE; |
| // Selection-Engine: Markieren abbrechen |
| pViewData->GetView()->GetSelEngine()->Reset(); |
| rMark.SetMarking(sal_False); |
| if (pViewData->IsAnyFillMode()) |
| { |
| pViewData->GetView()->StopRefMode(); |
| pViewData->ResetFillMode(); |
| } |
| StopMarking(); |
| DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen |
| ReleaseMouse(); |
| return; |
| } |
| |
| if (nMouseStatus == SC_GM_FILTER) |
| { |
| if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER ) |
| { |
| if (mpFilterButton.get()) |
| { |
| bool bFilterActive = IsAutoFilterActive( |
| pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() ); |
| |
| mpFilterButton->setHasHiddenMember(bFilterActive); |
| mpFilterButton->setPopupPressed(false); |
| HideCursor(); |
| mpFilterButton->draw(); |
| ShowCursor(); |
| } |
| } |
| nMouseStatus = SC_GM_NONE; |
| ReleaseMouse(); |
| return; // da muss nix mehr passieren |
| } |
| |
| ScModule* pScMod = SC_MOD(); |
| if (pScMod->IsModalMode(pViewData->GetSfxDocShell())) |
| return; |
| |
| SfxBindings& rBindings = pViewData->GetBindings(); |
| if (bEEMouse && pViewData->HasEditView( eWhich )) |
| { |
| EditView* pEditView; |
| SCCOL nEditCol; |
| SCROW nEditRow; |
| pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); |
| pEditView->MouseButtonUp( rMEvt ); |
| |
| if ( rMEvt.IsMiddle() && |
| GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) |
| { |
| // EditView may have pasted from selection |
| pScMod->InputChanged( pEditView ); |
| } |
| else |
| pScMod->InputSelection( pEditView ); // parentheses etc. |
| |
| pViewData->GetView()->InvalidateAttribs(); |
| rBindings.Invalidate( SID_HYPERLINK_GETLINK ); |
| bEEMouse = sal_False; |
| return; |
| } |
| |
| if (bDPMouse) |
| { |
| DPMouseButtonUp( rMEvt ); // resets bDPMouse |
| return; |
| } |
| |
| if (bRFMouse) |
| { |
| RFMouseMove( rMEvt, sal_True ); // Range wieder richtigherum |
| bRFMouse = sal_False; |
| SetPointer( Pointer( POINTER_ARROW ) ); |
| ReleaseMouse(); |
| return; |
| } |
| |
| if (nPagebreakMouse) |
| { |
| PagebreakMove( rMEvt, sal_True ); |
| nPagebreakMouse = SC_PD_NONE; |
| SetPointer( Pointer( POINTER_ARROW ) ); |
| ReleaseMouse(); |
| return; |
| } |
| |
| if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus |
| { |
| ::svl::IUndoManager* pMgr = pViewData->GetDocShell()->GetUndoManager(); |
| if ( pMgr->GetUndoActionCount() && pMgr->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE ) |
| pMgr->Undo(); |
| else |
| Sound::Beep(); |
| return; |
| } |
| |
| if (DrawMouseButtonUp(rMEvt)) // includes format paint brush handling for drawing objects |
| { |
| ScTabViewShell* pViewShell = pViewData->GetViewShell(); |
| SfxBindings& rBindings=pViewShell->GetViewFrame()->GetBindings(); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_WIDTH); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_HEIGHT); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_X); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_Y); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_ANGLE); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_ROT_X); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_ROT_Y); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_AUTOWIDTH); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_AUTOHEIGHT); |
| return; |
| } |
| |
| rMark.SetMarking(sal_False); |
| |
| SetPointer( Pointer( POINTER_ARROW ) ); |
| |
| if (pViewData->IsFillMode() || |
| ( pViewData->GetFillMode() == SC_FILL_MATRIX && rMEvt.IsMod1() )) |
| { |
| nScFillModeMouseModifier = rMEvt.GetModifier(); |
| SCCOL nStartCol; |
| SCROW nStartRow; |
| SCCOL nEndCol; |
| SCROW nEndRow; |
| pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow ); |
| // DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(), |
| // "Block falsch fuer AutoFill" ); |
| ScRange aDelRange; |
| sal_Bool bIsDel = pViewData->GetDelMark( aDelRange ); |
| |
| ScViewFunc* pView = pViewData->GetView(); |
| pView->StopRefMode(); |
| pViewData->ResetFillMode(); |
| pView->GetFunctionSet()->SetAnchorFlag( sal_False ); // #i5819# don't use AutoFill anchor flag for selection |
| |
| if ( bIsDel ) |
| { |
| pView->MarkRange( aDelRange, sal_False ); |
| pView->DeleteContents( IDF_CONTENTS ); |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ); |
| if ( aBlockRange != aDelRange ) |
| { |
| if ( aDelRange.aStart.Row() == nStartRow ) |
| aBlockRange.aEnd.SetCol( aDelRange.aStart.Col() - 1 ); |
| else |
| aBlockRange.aEnd.SetRow( aDelRange.aStart.Row() - 1 ); |
| pView->MarkRange( aBlockRange, sal_False ); |
| } |
| } |
| else |
| pViewData->GetDispatcher().Execute( FID_FILL_AUTO, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD ); |
| } |
| else if (pViewData->GetFillMode() == SC_FILL_MATRIX) |
| { |
| SCTAB nTab = pViewData->GetTabNo(); |
| SCCOL nStartCol; |
| SCROW nStartRow; |
| SCCOL nEndCol; |
| SCROW nEndRow; |
| pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow ); |
| ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ); |
| SCCOL nFillCol = pViewData->GetRefEndX(); |
| SCROW nFillRow = pViewData->GetRefEndY(); |
| ScAddress aEndPos( nFillCol, nFillRow, nTab ); |
| |
| ScTabView* pView = pViewData->GetView(); |
| pView->StopRefMode(); |
| pViewData->ResetFillMode(); |
| pView->GetFunctionSet()->SetAnchorFlag( sal_False ); |
| |
| if ( aEndPos != aBlockRange.aEnd ) |
| { |
| pViewData->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange, aEndPos, sal_False ); |
| pViewData->GetView()->MarkRange( ScRange( aBlockRange.aStart, aEndPos ) ); |
| } |
| } |
| else if (pViewData->IsAnyFillMode()) |
| { |
| // Embedded-Area has been changed |
| ScTabView* pView = pViewData->GetView(); |
| pView->StopRefMode(); |
| pViewData->ResetFillMode(); |
| pView->GetFunctionSet()->SetAnchorFlag( sal_False ); |
| pViewData->GetDocShell()->UpdateOle(pViewData); |
| } |
| |
| sal_Bool bRefMode = pViewData->IsRefMode(); |
| if (bRefMode) |
| pScMod->EndReference(); |
| |
| // |
| // Giesskannen-Modus (Gestalter) |
| // |
| |
| if (pScMod->GetIsWaterCan()) |
| { |
| // Abfrage auf Undo schon oben |
| |
| ScStyleSheetPool* pStylePool = (ScStyleSheetPool*) |
| (pViewData->GetDocument()-> |
| GetStyleSheetPool()); |
| if ( pStylePool ) |
| { |
| SfxStyleSheet* pStyleSheet = (SfxStyleSheet*) |
| pStylePool->GetActualStyleSheet(); |
| |
| if ( pStyleSheet ) |
| { |
| SfxStyleFamily eFamily = pStyleSheet->GetFamily(); |
| |
| switch ( eFamily ) |
| { |
| case SFX_STYLE_FAMILY_PARA: |
| pViewData->GetView()->SetStyleSheetToMarked( pStyleSheet ); |
| pViewData->GetView()->DoneBlockMode(); |
| break; |
| |
| case SFX_STYLE_FAMILY_PAGE: |
| pViewData->GetDocument()->SetPageStyle( pViewData->GetTabNo(), |
| pStyleSheet->GetName() ); |
| |
| ScPrintFunc( pViewData->GetDocShell(), |
| pViewData->GetViewShell()->GetPrinter(sal_True), |
| pViewData->GetTabNo() ).UpdatePages(); |
| |
| rBindings.Invalidate( SID_STATUS_PAGESTYLE ); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| } |
| } |
| |
| ScDBFunc* pView = pViewData->GetView(); |
| ScDocument* pBrushDoc = pView->GetBrushDocument(); |
| if ( pBrushDoc ) |
| { |
| pView->PasteFromClip( IDF_ATTRIB, pBrushDoc ); |
| if ( !pView->IsPaintBrushLocked() ) |
| pView->ResetBrushDocument(); // invalidates pBrushDoc pointer |
| } |
| |
| // |
| // double click (only left button) |
| // |
| |
| sal_Bool bDouble = ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() ); |
| if ( bDouble && !bRefMode && nMouseStatus == SC_GM_DBLDOWN && !pScMod->IsRefDialogOpen() ) |
| { |
| // data pilot table |
| Point aPos = rMEvt.GetPosPixel(); |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| SCTAB nTab = pViewData->GetTabNo(); |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, nTab ); |
| if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() ) |
| { |
| ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() ); |
| |
| // Check for header drill-down first. |
| sheet::DataPilotTableHeaderData aData; |
| pDPObj->GetHeaderPositionData(aCellPos, aData); |
| |
| if ( ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) && |
| ! ( aData.Flags & sheet::MemberResultFlags::SUBTOTAL ) ) |
| { |
| sal_uInt16 nDummy; |
| if ( pView->HasSelectionForDrillDown( nDummy ) ) |
| { |
| // execute slot to show dialog |
| pViewData->GetDispatcher().Execute( SID_OUTLINE_SHOW, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD ); |
| } |
| else |
| { |
| // toggle single entry |
| ScDPObject aNewObj( *pDPObj ); |
| pDPObj->ToggleDetails( aData, &aNewObj ); |
| ScDBDocFunc aFunc( *pViewData->GetDocShell() ); |
| aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False ); |
| pViewData->GetView()->CursorPosChanged(); // shells may be switched |
| } |
| } |
| else |
| { |
| // Check if the data area is double-clicked. |
| |
| Sequence<sheet::DataPilotFieldFilter> aFilters; |
| if ( pDPObj->GetDataFieldPositionData(aCellPos, aFilters) ) |
| pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters ); |
| else |
| Sound::Beep(); // nothing to expand/collapse/show |
| } |
| |
| return; |
| } |
| |
| // Check for cell protection attribute. |
| ScTableProtection* pProtect = pDoc->GetTabProtection( nTab ); |
| bool bEditAllowed = true; |
| if ( pProtect && pProtect->isProtected() ) |
| { |
| bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED); |
| bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); |
| bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); |
| |
| if ( bSkipProtected && bSkipUnprotected ) |
| bEditAllowed = false; |
| else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) ) |
| bEditAllowed = false; |
| } |
| |
| if ( bEditAllowed ) |
| { |
| // edit cell contents |
| pViewData->GetViewShell()->UpdateInputHandler(); |
| pScMod->SetInputMode( SC_INPUT_TABLE ); |
| if (pViewData->HasEditView(eWhich)) |
| { |
| // Text-Cursor gleich an die geklickte Stelle setzen |
| EditView* pEditView = pViewData->GetEditView( eWhich ); |
| MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 ); |
| pEditView->MouseButtonDown( aEditEvt ); |
| pEditView->MouseButtonUp( aEditEvt ); |
| } |
| } |
| return; |
| } |
| |
| // |
| // Links in edit cells |
| // |
| |
| sal_Bool bAlt = rMEvt.IsMod2(); |
| if ( !bAlt && !bRefMode && !bDouble && nMouseStatus == SC_GM_URLDOWN ) |
| { |
| // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war |
| |
| String aName, aUrl, aTarget; |
| if ( GetEditUrl( rMEvt.GetPosPixel(), &aName, &aUrl, &aTarget ) ) |
| { |
| nMouseStatus = SC_GM_NONE; // keinen Doppelklick anfangen |
| ScGlobal::OpenURL( aUrl, aTarget ); |
| |
| // fire worksheet_followhyperlink event |
| uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor(); |
| if( xVbaEvents.is() ) try |
| { |
| Point aPos = rMEvt.GetPosPixel(); |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| SCTAB nTab = pViewData->GetTabNo(); |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| ScBaseCell* pCell = NULL; |
| if( lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ) ) |
| { |
| ScAddress aCellPos( nPosX, nPosY, nTab ); |
| uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) ); |
| uno::Sequence< uno::Any > aArgs(1); |
| aArgs[0] <<= xCell; |
| xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs ); |
| } |
| } |
| catch( uno::Exception& ) |
| { |
| } |
| |
| return; |
| } |
| } |
| |
| // |
| // Gridwin - SelectionEngine |
| // |
| |
| // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return |
| // sal_True for any call, so IsLeft must be checked here, too. |
| |
| if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) ) |
| { |
| // rMark.MarkToSimple(); |
| pViewData->GetView()->UpdateAutoFillMark(); |
| |
| SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher(); |
| sal_Bool bFormulaMode = pScMod->IsFormulaMode(); |
| DBG_ASSERT( pDisp || bFormulaMode, "Cursor auf nicht aktiver View bewegen ?" ); |
| |
| // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no |
| // multiple selection, so the argument string completely describes the selection, |
| // and executing the slot won't change the existing selection (executing the slot |
| // here and from a recorded macro is treated equally) |
| |
| if ( pDisp && !bFormulaMode && !rMark.IsMultiMarked() ) |
| { |
| String aAddr; // CurrentCell |
| if( rMark.IsMarked() ) |
| { |
| // sal_Bool bKeep = rMark.IsMultiMarked(); //! wohin damit ??? |
| |
| ScRange aScRange; |
| rMark.GetMarkArea( aScRange ); |
| aScRange.Format( aAddr, SCR_ABS ); |
| if ( aScRange.aStart == aScRange.aEnd ) |
| { |
| // make sure there is a range selection string even for a single cell |
| String aSingle = aAddr; |
| aAddr.Append( (sal_Char) ':' ); |
| aAddr.Append( aSingle ); |
| } |
| |
| //! SID_MARKAREA gibts nicht mehr ??? |
| //! was passiert beim Markieren mit dem Cursor ??? |
| } |
| else // nur Cursor bewegen |
| { |
| ScAddress aScAddress( pViewData->GetCurX(), pViewData->GetCurY(), 0 ); |
| aScAddress.Format( aAddr, SCA_ABS ); |
| } |
| |
| SfxStringItem aPosItem( SID_CURRENTCELL, aAddr ); |
| pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, |
| &aPosItem, (void*)0L ); |
| |
| pViewData->GetView()->InvalidateAttribs(); |
| } |
| pViewData->GetViewShell()->SelectionChanged(); |
| return; |
| } |
| } |
| |
| void ScGridWindow::FakeButtonUp() |
| { |
| if ( nButtonDown ) |
| { |
| MouseEvent aEvent( aCurMousePos ); // nButtons = 0 -> ignore |
| MouseButtonUp( aEvent ); |
| } |
| } |
| |
| void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt ) |
| { |
| aCurMousePos = rMEvt.GetPosPixel(); |
| |
| if ( rMEvt.IsLeaveWindow() && pNoteMarker && !pNoteMarker->IsByKeyboard() ) |
| HideNoteMarker(); |
| |
| ScModule* pScMod = SC_MOD(); |
| if (pScMod->IsModalMode(pViewData->GetSfxDocShell())) |
| return; |
| |
| // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider |
| // nicht anders mit: |
| |
| if (bEEMouse && nButtonDown && !rMEvt.GetButtons()) |
| { |
| bEEMouse = sal_False; |
| nButtonDown = 0; |
| nMouseStatus = SC_GM_NONE; |
| return; |
| } |
| |
| if (nMouseStatus == SC_GM_IGNORE) |
| return; |
| |
| if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus -> nur auf Up warten |
| return; |
| |
| if ( pViewData->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus |
| { |
| SetPointer( Pointer( POINTER_FILL ) ); |
| return; |
| } |
| |
| if (nMouseStatus == SC_GM_FILTER && pFilterBox) |
| { |
| Point aRelPos = pFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ); |
| if ( Rectangle(Point(),pFilterBox->GetOutputSizePixel()).IsInside(aRelPos) ) |
| { |
| nButtonDown = 0; |
| nMouseStatus = SC_GM_NONE; |
| if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER ) |
| { |
| if (mpFilterButton.get()) |
| { |
| mpFilterButton->setHasHiddenMember(false); |
| mpFilterButton->setPopupPressed(false); |
| HideCursor(); |
| mpFilterButton->draw(); |
| ShowCursor(); |
| } |
| } |
| ReleaseMouse(); |
| pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) ); |
| return; |
| } |
| } |
| |
| sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz |
| |
| if (bEEMouse && pViewData->HasEditView( eWhich )) |
| { |
| EditView* pEditView; |
| SCCOL nEditCol; |
| SCROW nEditRow; |
| pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); |
| pEditView->MouseMove( rMEvt ); |
| return; |
| } |
| |
| if (bDPMouse) |
| { |
| DPMouseMove( rMEvt ); |
| return; |
| } |
| |
| if (bRFMouse) |
| { |
| RFMouseMove( rMEvt, sal_False ); |
| return; |
| } |
| |
| if (nPagebreakMouse) |
| { |
| PagebreakMove( rMEvt, sal_False ); |
| return; |
| } |
| |
| // anderen Mauszeiger anzeigen? |
| |
| sal_Bool bEditMode = pViewData->HasEditView(eWhich); |
| |
| //! Testen ob RefMode-Dragging !!! |
| if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) ) |
| { |
| Point aPos = rMEvt.GetPosPixel(); |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| |
| EditView* pEditView; |
| SCCOL nEditCol; |
| SCROW nEditRow; |
| pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); |
| SCCOL nEndCol = pViewData->GetEditEndCol(); |
| SCROW nEndRow = pViewData->GetEditEndRow(); |
| |
| if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol && |
| nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow ) |
| { |
| // Field can only be URL field |
| sal_Bool bAlt = rMEvt.IsMod2(); |
| if ( !bAlt && !nButtonDown && pEditView && pEditView->GetFieldUnderMousePointer() ) |
| SetPointer( Pointer( POINTER_REFHAND ) ); |
| else if ( pEditView && pEditView->GetEditEngine()->IsVertical() ) |
| SetPointer( Pointer( POINTER_TEXT_VERTICAL ) ); |
| else |
| SetPointer( Pointer( POINTER_TEXT ) ); |
| return; |
| } |
| } |
| |
| sal_Bool bWater = SC_MOD()->GetIsWaterCan() || pViewData->GetView()->HasPaintBrush(); |
| if (bWater) |
| SetPointer( Pointer(POINTER_FILL) ); |
| |
| if (!bWater) |
| { |
| sal_Bool bCross = sal_False; |
| |
| // Range-Finder |
| |
| sal_Bool bCorner; |
| if ( HitRangeFinder( rMEvt.GetPosPixel(), bCorner ) ) |
| { |
| if (bCorner) |
| SetPointer( Pointer( POINTER_CROSS ) ); |
| else |
| SetPointer( Pointer( POINTER_HAND ) ); |
| bCross = sal_True; |
| } |
| |
| // Page-Break-Modus |
| |
| sal_uInt16 nBreakType; |
| if ( !nButtonDown && pViewData->IsPagebreakMode() && |
| ( nBreakType = HitPageBreak( rMEvt.GetPosPixel() ) ) != 0 ) |
| { |
| PointerStyle eNew = POINTER_ARROW; |
| switch ( nBreakType ) |
| { |
| case SC_PD_RANGE_L: |
| case SC_PD_RANGE_R: |
| case SC_PD_BREAK_H: |
| eNew = POINTER_ESIZE; |
| break; |
| case SC_PD_RANGE_T: |
| case SC_PD_RANGE_B: |
| case SC_PD_BREAK_V: |
| eNew = POINTER_SSIZE; |
| break; |
| case SC_PD_RANGE_TL: |
| case SC_PD_RANGE_BR: |
| eNew = POINTER_SESIZE; |
| break; |
| case SC_PD_RANGE_TR: |
| case SC_PD_RANGE_BL: |
| eNew = POINTER_NESIZE; |
| break; |
| } |
| SetPointer( Pointer( eNew ) ); |
| bCross = sal_True; |
| } |
| |
| // Fill-Cursor anzeigen ? |
| |
| if ( !bFormulaMode && !nButtonDown ) |
| if (TestMouse( rMEvt, sal_False )) |
| bCross = sal_True; |
| |
| if ( nButtonDown && pViewData->IsAnyFillMode() ) |
| { |
| SetPointer( Pointer( POINTER_CROSS ) ); |
| bCross = sal_True; |
| nScFillModeMouseModifier = rMEvt.GetModifier(); // ausgewertet bei AutoFill und Matrix |
| } |
| |
| if (!bCross) |
| { |
| sal_Bool bAlt = rMEvt.IsMod2(); |
| |
| if (bEditMode) // Edit-Mode muss zuerst kommen! |
| SetPointer( Pointer( POINTER_ARROW ) ); |
| else if ( !bAlt && !nButtonDown && |
| GetEditUrl(rMEvt.GetPosPixel()) ) |
| SetPointer( Pointer( POINTER_REFHAND ) ); |
| else if ( DrawMouseMove(rMEvt) ) // setzt Pointer um |
| return; |
| } |
| } |
| |
| if ( pViewData->GetView()->GetSelEngine()->SelMouseMove( rMEvt ) ) |
| return; |
| } |
| |
| void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseEvent& rEvt ) |
| { |
| rEvent.Modifiers = 0; |
| if ( rEvt.IsShift() ) |
| rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT; |
| if ( rEvt.IsMod1() ) |
| rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1; |
| if ( rEvt.IsMod2() ) |
| rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2; |
| if ( rEvt.IsMod3() ) |
| rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD3; |
| |
| rEvent.Buttons = 0; |
| if ( rEvt.IsLeft() ) |
| rEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT; |
| if ( rEvt.IsRight() ) |
| rEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT; |
| if ( rEvt.IsMiddle() ) |
| rEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE; |
| |
| rEvent.X = rEvt.GetPosPixel().X(); |
| rEvent.Y = rEvt.GetPosPixel().Y(); |
| rEvent.ClickCount = rEvt.GetClicks(); |
| rEvent.PopupTrigger = sal_False; |
| } |
| |
| long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) |
| { |
| bool bDone = false; |
| sal_uInt16 nType = rNEvt.GetType(); |
| if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN ) |
| { |
| Window* pWindow = rNEvt.GetWindow(); |
| if (pWindow == this && pViewData) |
| { |
| SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame(); |
| if (pViewFrame) |
| { |
| com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController(); |
| if (xController.is()) |
| { |
| ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); |
| if (pImp && pImp->IsMouseListening()) |
| { |
| ::com::sun::star::awt::MouseEvent aEvent; |
| lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() ); |
| if ( rNEvt.GetWindow() ) |
| aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); |
| if ( nType == EVENT_MOUSEBUTTONDOWN) |
| bDone = pImp->MousePressed( aEvent ); |
| else |
| bDone = pImp->MouseReleased( aEvent ); |
| } |
| } |
| } |
| } |
| } |
| if (bDone) // event consumed by a listener |
| { |
| if ( nType == EVENT_MOUSEBUTTONDOWN ) |
| { |
| const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent(); |
| if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 ) |
| { |
| // If a listener returned true for a right-click call, also prevent opening the context menu |
| // (this works only if the context menu is opened on mouse-down) |
| nMouseStatus = SC_GM_IGNORE; |
| } |
| } |
| |
| return 1; |
| } |
| else |
| return Window::PreNotify( rNEvt ); |
| } |
| |
| void ScGridWindow::Tracking( const TrackingEvent& rTEvt ) |
| { |
| // Weil die SelectionEngine kein Tracking kennt, die Events nur auf |
| // die verschiedenen MouseHandler verteilen... |
| |
| const MouseEvent& rMEvt = rTEvt.GetMouseEvent(); |
| |
| if ( rTEvt.IsTrackingCanceled() ) // alles abbrechen... |
| { |
| if (!pViewData->GetView()->IsInActivatePart()) |
| { |
| if (bDPMouse) |
| bDPMouse = sal_False; // gezeichnet wird per bDragRect |
| if (bDragRect) |
| { |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| } |
| if (bRFMouse) |
| { |
| RFMouseMove( rMEvt, sal_True ); // richtig abbrechen geht dabei nicht... |
| bRFMouse = sal_False; |
| } |
| if (nPagebreakMouse) |
| { |
| // if (bPagebreakDrawn) |
| // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(), |
| // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False ); |
| bPagebreakDrawn = sal_False; |
| UpdateDragRectOverlay(); |
| nPagebreakMouse = SC_PD_NONE; |
| } |
| |
| SetPointer( Pointer( POINTER_ARROW ) ); |
| StopMarking(); |
| MouseButtonUp( rMEvt ); // mit Status SC_GM_IGNORE aus StopMarking |
| |
| sal_Bool bRefMode = pViewData->IsRefMode(); |
| if (bRefMode) |
| SC_MOD()->EndReference(); // #63148# Dialog nicht verkleinert lassen |
| } |
| } |
| else if ( rTEvt.IsTrackingEnded() ) |
| { |
| // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#) |
| // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht |
| // abgebrochen wurde. |
| |
| MouseEvent aUpEvt( rMEvt.GetPosPixel(), rMEvt.GetClicks(), |
| rMEvt.GetMode(), nButtonDown, rMEvt.GetModifier() ); |
| MouseButtonUp( aUpEvt ); |
| } |
| else |
| MouseMove( rMEvt ); |
| } |
| |
| void ScGridWindow::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel ) |
| { |
| if ( pFilterBox || nPagebreakMouse ) |
| return; |
| |
| HideNoteMarker(); |
| |
| CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True ); |
| |
| if (bEEMouse && pViewData->HasEditView( eWhich )) |
| { |
| EditView* pEditView; |
| SCCOL nEditCol; |
| SCROW nEditRow; |
| pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); |
| |
| // #63263# don't remove the edit view while switching views |
| ScModule* pScMod = SC_MOD(); |
| pScMod->SetInEditCommand( sal_True ); |
| |
| pEditView->Command( aDragEvent ); |
| |
| ScInputHandler* pHdl = pScMod->GetInputHdl(); |
| if (pHdl) |
| pHdl->DataChanged(); |
| |
| pScMod->SetInEditCommand( sal_False ); |
| if (!pViewData->IsActive()) // dropped to different view? |
| { |
| ScInputHandler* pViewHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); |
| if ( pViewHdl && pViewData->HasEditView( eWhich ) ) |
| { |
| pViewHdl->CancelHandler(); |
| ShowCursor(); // missing from KillEditView |
| } |
| } |
| } |
| else |
| if ( !DrawCommand(aDragEvent) ) |
| pViewData->GetView()->GetSelEngine()->Command( aDragEvent ); |
| } |
| |
| void lcl_SetTextCursorPos( ScViewData* pViewData, ScSplitPos eWhich, Window* pWin ) |
| { |
| SCCOL nCol = pViewData->GetCurX(); |
| SCROW nRow = pViewData->GetCurY(); |
| Rectangle aEditArea = pViewData->GetEditArea( eWhich, nCol, nRow, pWin, NULL, sal_True ); |
| aEditArea.Right() = aEditArea.Left(); |
| aEditArea = pWin->PixelToLogic( aEditArea ); |
| pWin->SetCursorRect( &aEditArea ); |
| } |
| |
| void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) |
| { |
| // The command event is send to the window after a possible context |
| // menu from an inplace client is closed. Now we have the chance to |
| // deactivate the inplace client without any problem regarding parent |
| // windows and code on the stack. |
| // For more information, see #126086# and #128122# |
| sal_uInt16 nCmd = rCEvt.GetCommand(); |
| ScTabViewShell* pTabViewSh = pViewData->GetViewShell(); |
| SfxInPlaceClient* pClient = pTabViewSh->GetIPClient(); |
| if ( pClient && |
| pClient->IsObjectInPlaceActive() && |
| nCmd == COMMAND_CONTEXTMENU ) |
| { |
| pTabViewSh->DeactivateOle(); |
| return; |
| } |
| |
| ScModule* pScMod = SC_MOD(); |
| DBG_ASSERT( nCmd != COMMAND_STARTDRAG, "ScGridWindow::Command called with COMMAND_STARTDRAG" ); |
| |
| if ( nCmd == COMMAND_STARTEXTTEXTINPUT || |
| nCmd == COMMAND_ENDEXTTEXTINPUT || |
| nCmd == COMMAND_EXTTEXTINPUT || |
| nCmd == COMMAND_CURSORPOS ) |
| { |
| sal_Bool bEditView = pViewData->HasEditView( eWhich ); |
| if (!bEditView) |
| { |
| // only if no cell editview is active, look at drawview |
| SdrView* pSdrView = pViewData->GetView()->GetSdrView(); |
| if ( pSdrView ) |
| { |
| OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView(); |
| if ( pOlView && pOlView->GetWindow() == this ) |
| { |
| pOlView->Command( rCEvt ); |
| return; // done |
| } |
| } |
| } |
| |
| if ( nCmd == COMMAND_CURSORPOS && !bEditView ) |
| { |
| // #88458# CURSORPOS may be called without following text input, |
| // to set the input method window position |
| // -> input mode must not be started, |
| // manually calculate text insert position if not in input mode |
| |
| lcl_SetTextCursorPos( pViewData, eWhich, this ); |
| return; |
| } |
| |
| ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); |
| if ( pHdl ) |
| { |
| pHdl->InputCommand( rCEvt, sal_True ); |
| return; // done |
| } |
| |
| Window::Command( rCEvt ); |
| return; |
| } |
| |
| if ( nCmd == COMMAND_VOICE ) |
| { |
| // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist, |
| // also muss es eine EditView oder ein editiertes Zeichenobjekt geben |
| |
| ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); |
| if ( pHdl && pViewData->HasEditView( eWhich ) ) |
| { |
| EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0 |
| pHdl->DataChanging(); |
| pEditView->Command( rCEvt ); |
| pHdl->DataChanged(); |
| return; // erledigt |
| } |
| SdrView* pSdrView = pViewData->GetView()->GetSdrView(); |
| if ( pSdrView ) |
| { |
| OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView(); |
| if ( pOlView && pOlView->GetWindow() == this ) |
| { |
| pOlView->Command( rCEvt ); |
| return; // erledigt |
| } |
| } |
| Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern... |
| return; |
| } |
| |
| if ( nCmd == COMMAND_PASTESELECTION ) |
| { |
| if ( bEEMouse ) |
| { |
| // EditEngine handles selection in MouseButtonUp - no action |
| // needed in command handler |
| } |
| else |
| { |
| PasteSelection( rCEvt.GetMousePosPixel() ); |
| } |
| return; |
| } |
| |
| if ( nCmd == COMMAND_INPUTLANGUAGECHANGE ) |
| { |
| // #i55929# Font and font size state depends on input language if nothing is selected, |
| // so the slots have to be invalidated when the input language is changed. |
| |
| SfxBindings& rBindings = pViewData->GetBindings(); |
| rBindings.Invalidate( SID_ATTR_CHAR_FONT ); |
| rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); |
| return; |
| } |
| |
| if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL ) |
| { |
| sal_Bool bDone = pViewData->GetView()->ScrollCommand( rCEvt, eWhich ); |
| if (!bDone) |
| Window::Command(rCEvt); |
| return; |
| } |
| // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input |
| sal_Bool bDisable = pScMod->IsFormulaMode() || |
| pScMod->IsModalMode(pViewData->GetSfxDocShell()); |
| if (bDisable) |
| return; |
| |
| if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() ) |
| { |
| sal_Bool bMouse = rCEvt.IsMouseEvent(); |
| if ( bMouse && nMouseStatus == SC_GM_IGNORE ) |
| return; |
| |
| if (pViewData->IsAnyFillMode()) |
| { |
| pViewData->GetView()->StopRefMode(); |
| pViewData->ResetFillMode(); |
| } |
| ReleaseMouse(); |
| StopMarking(); |
| |
| Point aPosPixel = rCEvt.GetMousePosPixel(); |
| Point aMenuPos = aPosPixel; |
| |
| if ( bMouse ) |
| { |
| SCsCOL nCellX = -1; |
| SCsROW nCellY = -1; |
| pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY); |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); |
| bool bSelectAllowed = true; |
| if ( pProtect && pProtect->isProtected() ) |
| { |
| // This sheet is protected. Check if a context menu is allowed on this cell. |
| bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED); |
| bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); |
| bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); |
| |
| if (bCellProtected) |
| bSelectAllowed = bSelProtected; |
| else |
| bSelectAllowed = bSelUnprotected; |
| } |
| if (!bSelectAllowed) |
| // Selecting this cell is not allowed, neither is context menu. |
| return; |
| |
| // #i18735# First select the item under the mouse pointer. |
| // This can change the selection, and the view state (edit mode, etc). |
| SelectForContextMenu( aPosPixel, nCellX, nCellY ); |
| } |
| |
| sal_Bool bDone = sal_False; |
| sal_Bool bEdit = pViewData->HasEditView(eWhich); |
| if ( !bEdit ) |
| { |
| // Edit-Zelle mit Spelling-Errors ? |
| if ( bMouse && GetEditUrlOrError( sal_True, aPosPixel ) ) |
| { |
| // GetEditUrlOrError hat den Cursor schon bewegt |
| |
| pScMod->SetInputMode( SC_INPUT_TABLE ); |
| bEdit = pViewData->HasEditView(eWhich); // hat's geklappt ? |
| |
| DBG_ASSERT( bEdit, "kann nicht in Edit-Modus schalten" ); |
| } |
| } |
| if ( bEdit ) |
| { |
| EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0 |
| |
| if ( !bMouse ) |
| { |
| Cursor* pCur = pEditView->GetCursor(); |
| if ( pCur ) |
| { |
| Point aLogicPos = pCur->GetPos(); |
| // use the position right of the cursor (spell popup is opened if |
| // the cursor is before the word, but not if behind it) |
| aLogicPos.X() += pCur->GetWidth(); |
| aLogicPos.Y() += pCur->GetHeight() / 2; // center vertically |
| aMenuPos = LogicToPixel( aLogicPos ); |
| } |
| } |
| |
| // if edit mode was just started above, online spelling may be incomplete |
| pEditView->GetEditEngine()->CompleteOnlineSpelling(); |
| |
| // IsCursorAtWrongSpelledWord could be used for !bMouse |
| // if there was a corresponding ExecuteSpellPopup call |
| |
| if( pEditView->IsWrongSpelledWordAtPos( aMenuPos ) ) |
| { |
| // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown |
| // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen |
| // (Bug #40968#) |
| ScInputHandler* pHdl = pScMod->GetInputHdl(); |
| if (pHdl) |
| pHdl->SetModified(); |
| |
| Link aLink = LINK( this, ScGridWindow, PopupSpellingHdl ); |
| pEditView->ExecuteSpellPopup( aMenuPos, &aLink ); |
| |
| bDone = sal_True; |
| } |
| } |
| else if ( !bMouse ) |
| { |
| // non-edit menu by keyboard -> use lower right of cell cursor position |
| |
| SCCOL nCurX = pViewData->GetCurX(); |
| SCROW nCurY = pViewData->GetCurY(); |
| aMenuPos = pViewData->GetScrPos( nCurX, nCurY, eWhich, sal_True ); |
| long nSizeXPix; |
| long nSizeYPix; |
| pViewData->GetMergeSizePixel( nCurX, nCurY, nSizeXPix, nSizeYPix ); |
| aMenuPos.X() += nSizeXPix; |
| aMenuPos.Y() += nSizeYPix; |
| |
| if (pViewData) |
| { |
| ScTabViewShell* pViewSh = pViewData->GetViewShell(); |
| if (pViewSh) |
| { |
| // Is a draw object selected? |
| |
| SdrView* pDrawView = pViewSh->GetSdrView(); |
| if (pDrawView && pDrawView->AreObjectsMarked()) |
| { |
| // #100442#; the conext menu should open in the middle of the selected objects |
| Rectangle aSelectRect(LogicToPixel(pDrawView->GetAllMarkedBoundRect())); |
| aMenuPos = aSelectRect.Center(); |
| } |
| } |
| } |
| } |
| |
| if (!bDone) |
| { |
| SfxDispatcher::ExecutePopup( 0, this, &aMenuPos ); |
| } |
| } |
| } |
| |
| void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY ) |
| { |
| // #i18735# if the click was outside of the current selection, |
| // the cursor is moved or an object at the click position selected. |
| // (see SwEditWin::SelectMenuPosition in Writer) |
| |
| ScTabView* pView = pViewData->GetView(); |
| ScDrawView* pDrawView = pView->GetScDrawView(); |
| |
| // check cell edit mode |
| |
| if ( pViewData->HasEditView(eWhich) ) |
| { |
| ScModule* pScMod = SC_MOD(); |
| SCCOL nEditStartCol = pViewData->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated |
| SCROW nEditStartRow = pViewData->GetEditViewRow(); |
| SCCOL nEditEndCol = pViewData->GetEditEndCol(); |
| SCROW nEditEndRow = pViewData->GetEditEndRow(); |
| |
| if ( nCellX >= (SCsCOL) nEditStartCol && nCellX <= (SCsCOL) nEditEndCol && |
| nCellY >= (SCsROW) nEditStartRow && nCellY <= (SCsROW) nEditEndRow ) |
| { |
| // handle selection within the EditView |
| |
| EditView* pEditView = pViewData->GetEditView( eWhich ); // not NULL (HasEditView) |
| EditEngine* pEditEngine = pEditView->GetEditEngine(); |
| Rectangle aOutputArea = pEditView->GetOutputArea(); |
| Rectangle aVisArea = pEditView->GetVisArea(); |
| |
| Point aTextPos = PixelToLogic( rPosPixel ); |
| if ( pEditEngine->IsVertical() ) // have to manually transform position |
| { |
| aTextPos -= aOutputArea.TopRight(); |
| long nTemp = -aTextPos.X(); |
| aTextPos.X() = aTextPos.Y(); |
| aTextPos.Y() = nTemp; |
| } |
| else |
| aTextPos -= aOutputArea.TopLeft(); |
| aTextPos += aVisArea.TopLeft(); // position in the edit document |
| |
| EPosition aDocPosition = pEditEngine->FindDocPosition(aTextPos); |
| ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex); |
| ESelection aSelection = pEditView->GetSelection(); |
| aSelection.Adjust(); // needed for IsLess/IsGreater |
| if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) ) |
| { |
| // clicked outside the selected text - deselect and move text cursor |
| MouseEvent aEvent( rPosPixel ); |
| pEditView->MouseButtonDown( aEvent ); |
| pEditView->MouseButtonUp( aEvent ); |
| pScMod->InputSelection( pEditView ); |
| } |
| |
| return; // clicked within the edit view - keep edit mode |
| } |
| else |
| { |
| // outside of the edit view - end edit mode, regardless of cell selection, then continue |
| pScMod->InputEnterHandler(); |
| } |
| } |
| |
| // check draw text edit mode |
| |
| Point aLogicPos = PixelToLogic( rPosPixel ); // after cell edit mode is ended |
| if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() ) |
| { |
| OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView(); |
| Rectangle aOutputArea = pOlView->GetOutputArea(); |
| if ( aOutputArea.IsInside( aLogicPos ) ) |
| { |
| // handle selection within the OutlinerView |
| |
| Outliner* pOutliner = pOlView->GetOutliner(); |
| const EditEngine& rEditEngine = pOutliner->GetEditEngine(); |
| Rectangle aVisArea = pOlView->GetVisArea(); |
| |
| Point aTextPos = aLogicPos; |
| if ( pOutliner->IsVertical() ) // have to manually transform position |
| { |
| aTextPos -= aOutputArea.TopRight(); |
| long nTemp = -aTextPos.X(); |
| aTextPos.X() = aTextPos.Y(); |
| aTextPos.Y() = nTemp; |
| } |
| else |
| aTextPos -= aOutputArea.TopLeft(); |
| aTextPos += aVisArea.TopLeft(); // position in the edit document |
| |
| EPosition aDocPosition = rEditEngine.FindDocPosition(aTextPos); |
| ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex); |
| ESelection aSelection = pOlView->GetSelection(); |
| aSelection.Adjust(); // needed for IsLess/IsGreater |
| if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) ) |
| { |
| // clicked outside the selected text - deselect and move text cursor |
| // use DrawView to allow extra handling there (none currently) |
| MouseEvent aEvent( rPosPixel ); |
| pDrawView->MouseButtonDown( aEvent, this ); |
| pDrawView->MouseButtonUp( aEvent, this ); |
| } |
| |
| return; // clicked within the edit area - keep edit mode |
| } |
| else |
| { |
| // Outside of the edit area - end text edit mode, then continue. |
| // DrawDeselectAll also ends text edit mode and updates the shells. |
| // If the click was on the edited object, it will be selected again below. |
| pView->DrawDeselectAll(); |
| } |
| } |
| |
| // look for existing selection |
| |
| sal_Bool bHitSelected = sal_False; |
| if ( pDrawView && pDrawView->IsMarkedObjHit( aLogicPos ) ) |
| { |
| // clicked on selected object -> don't change anything |
| bHitSelected = sal_True; |
| } |
| else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) ) |
| { |
| // clicked on selected cell -> don't change anything |
| bHitSelected = sal_True; |
| } |
| |
| // select drawing object or move cell cursor |
| |
| if ( !bHitSelected ) |
| { |
| sal_Bool bWasDraw = ( pDrawView && pDrawView->AreObjectsMarked() ); |
| sal_Bool bHitDraw = sal_False; |
| if ( pDrawView ) |
| { |
| pDrawView->UnmarkAllObj(); |
| // Unlock the Internal Layer in order to activate the context menu. |
| // re-lock in ScDrawView::MarkListHasChanged() |
| lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), pDrawView->GetModel(), aLogicPos ,pViewData); |
| bHitDraw = pDrawView->MarkObj( aLogicPos ); |
| // draw shell is activated in MarkListHasChanged |
| } |
| if ( !bHitDraw ) |
| { |
| pView->Unmark(); |
| pView->SetCursor(nCellX, nCellY); |
| if ( bWasDraw ) |
| pViewData->GetViewShell()->SetDrawShell( sal_False ); // switch shells |
| } |
| } |
| } |
| |
| void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt) |
| { |
| // #96965# Cursor control for ref input dialog |
| if( SC_MOD()->IsRefDialogOpen() ) |
| { |
| const KeyCode& rKeyCode = rKEvt.GetKeyCode(); |
| if( !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) ) |
| { |
| SC_MOD()->EndReference(); |
| } |
| else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) ) |
| { |
| ScRange aRef( |
| pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(), |
| pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() ); |
| SC_MOD()->SetReference( aRef, pViewData->GetDocument() ); |
| } |
| pViewData->GetViewShell()->SelectionChanged(); |
| return ; |
| } |
| // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs: |
| else if( !pViewData->IsAnyFillMode() ) |
| { |
| // query for existing note marker before calling ViewShell's keyboard handling |
| // which may remove the marker |
| sal_Bool bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() ); |
| ScTabViewShell* pViewSh = pViewData->GetViewShell(); |
| |
| if (pViewData->GetDocShell()->GetProgress()) |
| return; |
| |
| if (DrawKeyInput(rKEvt)) |
| { |
| const KeyCode& rKeyCode = rKEvt.GetKeyCode(); |
| if (rKeyCode.GetCode() == KEY_DOWN |
| || rKeyCode.GetCode() == KEY_UP |
| || rKeyCode.GetCode() == KEY_LEFT |
| || rKeyCode.GetCode() == KEY_RIGHT) |
| { |
| ScTabViewShell* pViewShell = pViewData->GetViewShell(); |
| SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings(); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_X); |
| rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_Y); |
| } |
| return; |
| } |
| |
| if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus |
| { //! DrawShell abfragen !!! |
| if (pViewSh->TabKeyInput(rKEvt)) |
| return; |
| } |
| else |
| if (pViewSh->SfxViewShell::KeyInput(rKEvt)) // von SfxViewShell |
| return; |
| |
| KeyCode aCode = rKEvt.GetKeyCode(); |
| if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 ) |
| { |
| if ( bHadKeyMarker ) |
| HideNoteMarker(); |
| else |
| pViewSh->Escape(); |
| return; |
| } |
| if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 ) |
| { |
| // ctrl-F1 shows or hides the note or redlining info for the cursor position |
| // (hard-coded because F1 can't be configured) |
| |
| if ( bHadKeyMarker ) |
| HideNoteMarker(); // hide when previously visible |
| else |
| ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), sal_True ); |
| return; |
| } |
| } |
| |
| Window::KeyInput(rKEvt); |
| } |
| |
| void ScGridWindow::StopMarking() |
| { |
| DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen |
| |
| if (nButtonDown) |
| { |
| pViewData->GetMarkData().SetMarking(sal_False); |
| nMouseStatus = SC_GM_IGNORE; |
| } |
| } |
| |
| void ScGridWindow::UpdateInputContext() |
| { |
| sal_Bool bReadOnly = pViewData->GetDocShell()->IsReadOnly(); |
| sal_uLong nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT ); |
| |
| // when font from InputContext is used, |
| // it must be taken from the cursor position's cell attributes |
| |
| InputContext aContext; |
| aContext.SetOptions( nOptions ); |
| SetInputContext( aContext ); |
| } |
| |
| //-------------------------------------------------------- |
| |
| // sensitiver Bereich (Pixel) |
| #define SCROLL_SENSITIVE 20 |
| |
| sal_Bool ScGridWindow::DropScroll( const Point& rMousePos ) |
| { |
| /* doch auch auf nicht aktiven Views... |
| if ( !pViewData->IsActive() ) |
| return sal_False; |
| */ |
| SCsCOL nDx = 0; |
| SCsROW nDy = 0; |
| Size aSize = GetOutputSizePixel(); |
| |
| if (aSize.Width() > SCROLL_SENSITIVE * 3) |
| { |
| if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 ) |
| nDx = -1; |
| if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE |
| && pViewData->GetPosX(WhichH(eWhich)) < MAXCOL ) |
| nDx = 1; |
| } |
| if (aSize.Height() > SCROLL_SENSITIVE * 3) |
| { |
| if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 ) |
| nDy = -1; |
| if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE |
| && pViewData->GetPosY(WhichV(eWhich)) < MAXROW ) |
| nDy = 1; |
| } |
| |
| if ( nDx != 0 || nDy != 0 ) |
| { |
| // if (bDragRect) |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| |
| if ( nDx != 0 ) |
| pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) ); |
| if ( nDy != 0 ) |
| pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) ); |
| |
| // if (bDragRect) |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| } |
| |
| return sal_False; |
| } |
| |
| sal_Bool lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange) |
| { |
| // Testet, ob bei eingeschalteten RedLining, |
| // bei einem Drop ein Scenario betroffen ist. |
| |
| sal_Bool bReturn = sal_False; |
| SCTAB nTab = aDragRange.aStart.Tab(); |
| SCTAB nTabCount = pDoc->GetTableCount(); |
| |
| if(pDoc->GetChangeTrack()!=NULL) |
| { |
| if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange)) |
| { |
| bReturn = sal_True; |
| } |
| else |
| { |
| for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) |
| { |
| if(pDoc->HasScenarioRange(i, aDragRange)) |
| { |
| bReturn = sal_True; |
| break; |
| } |
| } |
| } |
| } |
| return bReturn; |
| } |
| |
| ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource ) |
| { |
| SCCOL nCol1 = nPosX; |
| SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() ); |
| if ( nCol2 > MAXCOL ) |
| { |
| nCol1 -= nCol2 - MAXCOL; |
| nCol2 = MAXCOL; |
| } |
| SCROW nRow1 = nPosY; |
| SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() ); |
| if ( nRow2 > MAXROW ) |
| { |
| nRow1 -= nRow2 - MAXROW; |
| nRow2 = MAXROW; |
| } |
| |
| return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab ); |
| } |
| |
| //-------------------------------------------------------- |
| |
| extern sal_Bool bPasteIsDrop; // viewfun4 -> move to header |
| extern sal_Bool bPasteIsMove; // viewfun7 -> move to header |
| |
| //-------------------------------------------------------- |
| |
| sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt ) |
| { |
| if ( rEvt.mbLeaving ) |
| { |
| // if (bDragRect) |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| return rEvt.mnAction; |
| } |
| |
| const ScDragData& rData = SC_MOD()->GetDragData(); |
| if ( rData.pCellTransfer ) |
| { |
| // Don't move source that would include filtered rows. |
| if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows()) |
| { |
| if (bDragRect) |
| { |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| } |
| return DND_ACTION_NONE; |
| } |
| |
| Point aPos = rEvt.maPosPixel; |
| |
| ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument(); |
| ScDocument* pThisDoc = pViewData->GetDocument(); |
| if (pSourceDoc == pThisDoc) |
| { |
| if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos)) ) |
| { |
| if (bDragRect) // Rechteck loeschen |
| { |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| } |
| |
| //! highlight chart? (selection border?) |
| |
| sal_Int8 nRet = rEvt.mnAction; |
| //! if ( rEvt.GetAction() == DROP_LINK ) |
| //! bOk = rEvt.SetAction( DROP_COPY ); // can't link onto chart |
| return nRet; |
| } |
| } |
| //! else |
| //! if ( rEvt.GetAction() == DROP_MOVE ) |
| //! rEvt.SetAction( DROP_COPY ); // different doc: default=COPY |
| |
| |
| if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) // whole sheet? |
| { |
| sal_Bool bOk = pThisDoc->IsDocEditable(); |
| return bOk ? rEvt.mnAction : 0; // don't draw selection frame |
| } |
| |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| |
| ScRange aSourceRange = rData.pCellTransfer->GetRange(); |
| SCCOL nSourceStartX = aSourceRange.aStart.Col(); |
| SCROW nSourceStartY = aSourceRange.aStart.Row(); |
| SCCOL nSourceEndX = aSourceRange.aEnd.Col(); |
| SCROW nSourceEndY = aSourceRange.aEnd.Row(); |
| SCCOL nSizeX = nSourceEndX - nSourceStartX + 1; |
| SCROW nSizeY = nSourceEndY - nSourceStartY + 1; |
| |
| if ( rEvt.mnAction != DND_ACTION_MOVE ) |
| nSizeY = rData.pCellTransfer->GetNonFilteredRows(); // copy/link: no filtered rows |
| |
| SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX(); |
| if (nNewDragX<0) nNewDragX=0; |
| if (nNewDragX+(nSizeX-1) > MAXCOL) |
| nNewDragX = MAXCOL-(nSizeX-1); |
| SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY(); |
| if (nNewDragY<0) nNewDragY=0; |
| if (nNewDragY+(nSizeY-1) > MAXROW) |
| nNewDragY = MAXROW-(nSizeY-1); |
| |
| // don't break scenario ranges, don't drop on filtered |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange ); |
| if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) || |
| lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) || |
| ScViewUtil::HasFiltered( aDropRange, pThisDoc) ) |
| { |
| if (bDragRect) |
| { |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| } |
| return DND_ACTION_NONE; |
| } |
| |
| InsCellCmd eDragInsertMode = INS_NONE; |
| Window::PointerState aState = GetPointerState(); |
| |
| // check for datapilot item sorting |
| ScDPObject* pDPObj = NULL; |
| if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL ) |
| { |
| // drop on DataPilot table: sort or nothing |
| |
| bool bDPSort = false; |
| if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj ) |
| { |
| sheet::DataPilotTableHeaderData aDestData; |
| pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData ); |
| bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field |
| |
| // look through the source range |
| for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow ) |
| for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol ) |
| { |
| sheet::DataPilotTableHeaderData aSourceData; |
| pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData ); |
| if ( aSourceData.Dimension != aDestData.Dimension || !aSourceData.MemberName.getLength() ) |
| bValid = false; // empty (subtotal) or different field |
| } |
| |
| if ( bValid ) |
| { |
| sal_Bool bIsDataLayout; |
| String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout ); |
| const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName ); |
| if ( pDim ) |
| { |
| ScRange aOutRange = pDPObj->GetOutRange(); |
| |
| sal_uInt16 nOrient = pDim->GetOrientation(); |
| if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN ) |
| { |
| eDragInsertMode = INS_CELLSRIGHT; |
| nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1; |
| bDPSort = true; |
| } |
| else if ( nOrient == sheet::DataPilotFieldOrientation_ROW ) |
| { |
| eDragInsertMode = INS_CELLSDOWN; |
| nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1; |
| bDPSort = true; |
| } |
| } |
| } |
| } |
| |
| if ( !bDPSort ) |
| { |
| // no valid sorting in a DataPilot table -> disallow |
| if ( bDragRect ) |
| { |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| } |
| return DND_ACTION_NONE; |
| } |
| } |
| else if ( aState.mnState & KEY_MOD2 ) |
| { |
| if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() ) |
| { |
| long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) ); |
| long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) ); |
| if ( nDeltaX <= nDeltaY ) |
| { |
| eDragInsertMode = INS_CELLSDOWN; |
| } |
| else |
| { |
| eDragInsertMode = INS_CELLSRIGHT; |
| } |
| |
| if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY && |
| ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX && |
| ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) || |
| ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX && |
| ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY && |
| ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) ) |
| { |
| if ( bDragRect ) |
| { |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| } |
| return DND_ACTION_NONE; |
| } |
| } |
| else |
| { |
| if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) ) |
| { |
| eDragInsertMode = INS_CELLSDOWN; |
| |
| } |
| else |
| { |
| eDragInsertMode = INS_CELLSRIGHT; |
| } |
| } |
| } |
| |
| if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY || |
| nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY || |
| !bDragRect || eDragInsertMode != meDragInsertMode ) |
| { |
| // if (bDragRect) |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| |
| nDragStartX = nNewDragX; |
| nDragStartY = nNewDragY; |
| nDragEndX = nDragStartX+nSizeX-1; |
| nDragEndY = nDragStartY+nSizeY-1; |
| bDragRect = sal_True; |
| meDragInsertMode = eDragInsertMode; |
| |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| |
| UpdateDragRectOverlay(); |
| |
| // show target position as tip help |
| #if 0 |
| if (Help::IsQuickHelpEnabled()) |
| { |
| ScRange aRange( nDragStartX, nDragStartY, nTab, nDragEndX, nDragEndY, nTab ); |
| String aHelpStr; |
| aRange.Format( aHelpStr, SCA_VALID ); // non-3D |
| |
| Point aPos = Pointer::GetPosPixel(); |
| sal_uInt16 nAlign = QUICKHELP_BOTTOM|QUICKHELP_RIGHT; |
| Rectangle aRect( aPos, aPos ); |
| Help::ShowQuickHelp(aRect, aHelpStr, nAlign); |
| } |
| #endif |
| } |
| } |
| |
| return rEvt.mnAction; |
| } |
| |
| sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt ) |
| { |
| const ScDragData& rData = SC_MOD()->GetDragData(); |
| if ( rEvt.mbLeaving ) |
| { |
| DrawMarkDropObj( NULL ); |
| if ( rData.pCellTransfer ) |
| return AcceptPrivateDrop( rEvt ); // hide drop marker for internal D&D |
| else |
| return rEvt.mnAction; |
| } |
| |
| if ( pViewData->GetDocShell()->IsReadOnly() ) |
| return DND_ACTION_NONE; |
| |
| |
| sal_Int8 nRet = DND_ACTION_NONE; |
| |
| if (rData.pCellTransfer) |
| { |
| ScRange aSource = rData.pCellTransfer->GetRange(); |
| if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL || |
| aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW ) |
| DropScroll( rEvt.maPosPixel ); |
| |
| nRet = AcceptPrivateDrop( rEvt ); |
| } |
| else |
| { |
| if ( rData.aLinkDoc.Len() ) |
| { |
| String aThisName; |
| ScDocShell* pDocSh = pViewData->GetDocShell(); |
| if (pDocSh && pDocSh->HasName()) |
| aThisName = pDocSh->GetMedium()->GetName(); |
| |
| if ( rData.aLinkDoc != aThisName ) |
| nRet = rEvt.mnAction; |
| } |
| else if (rData.aJumpTarget.Len()) |
| { |
| // internal bookmarks (from Navigator) |
| // local jumps from an unnamed document are possible only within a document |
| |
| if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() ) |
| nRet = rEvt.mnAction; |
| } |
| else |
| { |
| sal_Int8 nMyAction = rEvt.mnAction; |
| |
| // clear DND_ACTION_LINK when other actions are set. The usage below cannot handle |
| // multiple set values |
| if((nMyAction & DND_ACTION_LINK) && (nMyAction & (DND_ACTION_COPYMOVE))) |
| { |
| nMyAction &= ~DND_ACTION_LINK; |
| } |
| |
| if ( !rData.pDrawTransfer || |
| !IsMyModel(rData.pDrawTransfer->GetDragSourceView()) ) // drawing within the document |
| if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE ) |
| nMyAction = DND_ACTION_COPY; |
| |
| ScDocument* pThisDoc = pViewData->GetDocument(); |
| SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( |
| pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) ); |
| if ( pHitObj && nMyAction == DND_ACTION_LINK ) // && !rData.pDrawTransfer ) |
| { |
| if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB) |
| || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE) |
| || IsDropFormatSupported(SOT_FORMATSTR_ID_PNG) |
| || IsDropFormatSupported(SOT_FORMAT_BITMAP) ) |
| { |
| // graphic dragged onto drawing object |
| DrawMarkDropObj( pHitObj ); |
| nRet = nMyAction; |
| } |
| } |
| if (!nRet) |
| DrawMarkDropObj( NULL ); |
| |
| if (!nRet) |
| { |
| switch ( nMyAction ) |
| { |
| case DND_ACTION_COPY: |
| case DND_ACTION_MOVE: |
| case DND_ACTION_COPYMOVE: |
| { |
| sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE ); |
| if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) || |
| IsDropFormatSupported( SOT_FORMAT_STRING ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) || |
| IsDropFormatSupported( SOT_FORMAT_RTF ) || |
| IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_PNG ) || |
| IsDropFormatSupported( SOT_FORMAT_BITMAP ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) || |
| ( !bMove && ( |
| IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) || |
| IsDropFormatSupported( SOT_FORMAT_FILE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) ) |
| { |
| nRet = nMyAction; |
| } |
| } |
| break; |
| case DND_ACTION_LINK: |
| if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) || |
| IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) || |
| IsDropFormatSupported( SOT_FORMAT_FILE ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) || |
| IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) |
| { |
| nRet = nMyAction; |
| } |
| break; |
| } |
| |
| if ( nRet ) |
| { |
| // Simple check for protection: It's not known here if the drop will result |
| // in cells or drawing objects (some formats can be both) and how many cells |
| // the result will be. But if IsFormatEditable for the drop cell position |
| // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop |
| // can already be rejected here. |
| |
| Point aPos = rEvt.maPosPixel; |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScDocument* pDoc = pViewData->GetDocument(); |
| |
| ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY ); |
| if ( !aTester.IsFormatEditable() ) |
| nRet = DND_ACTION_NONE; // forbidden |
| } |
| } |
| } |
| |
| // scroll only for accepted formats |
| if (nRet) |
| DropScroll( rEvt.maPosPixel ); |
| } |
| |
| return nRet; |
| } |
| |
| sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false ) |
| { |
| TransferableDataHelper aDataHelper( xTransfer ); |
| |
| if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ) |
| { |
| // use bookmark formats if no sba is present |
| |
| if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) ) |
| return SOT_FORMATSTR_ID_SOLK; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ) |
| return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ) |
| return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) |
| return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR; |
| } |
| |
| sal_uLong nFormatId = 0; |
| if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) ) |
| nFormatId = SOT_FORMATSTR_ID_DRAWING; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) ) |
| nFormatId = SOT_FORMATSTR_ID_SVXB; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ) |
| { |
| // If it's a Writer object, insert RTF instead of OLE |
| |
| sal_Bool bDoRtf = sal_False; |
| SotStorageStreamRef xStm; |
| TransferableObjectDescriptor aObjDesc; |
| if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) && |
| aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) ) |
| { |
| SotStorageRef xStore( new SotStorage( *xStm ) ); |
| bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) || |
| aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) ) |
| && aDataHelper.HasFormat( SOT_FORMAT_RTF ) ); |
| } |
| if ( bDoRtf ) |
| nFormatId = FORMAT_RTF; |
| else |
| nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE; |
| } |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ) |
| nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ) |
| nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ) |
| nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) ) |
| nFormatId = SOT_FORMATSTR_ID_BIFF_8; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) ) |
| nFormatId = SOT_FORMATSTR_ID_BIFF_5; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ) |
| nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ) |
| nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ) |
| nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) ) |
| nFormatId = SOT_FORMAT_RTF; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) ) |
| nFormatId = SOT_FORMATSTR_ID_HTML; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ) |
| nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) ) |
| nFormatId = SOT_FORMATSTR_ID_SYLK; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) ) |
| nFormatId = SOT_FORMATSTR_ID_LINK; |
| else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting |
| nFormatId = SOT_FORMAT_STRING; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) ) |
| nFormatId = SOT_FORMAT_FILE_LIST; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers) |
| nFormatId = SOT_FORMAT_FILE; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) |
| nFormatId = SOT_FORMAT_STRING; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) ) |
| nFormatId = SOT_FORMAT_GDIMETAFILE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_PNG ) ) |
| nFormatId = SOT_FORMATSTR_ID_PNG; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) ) |
| nFormatId = SOT_FORMAT_BITMAP; |
| |
| return nFormatId; |
| } |
| |
| sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer ) |
| { |
| TransferableDataHelper aDataHelper( xTransfer ); |
| |
| sal_uLong nFormatId = 0; |
| if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ) |
| nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ) |
| nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) ) |
| nFormatId = SOT_FORMATSTR_ID_LINK; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) ) |
| nFormatId = SOT_FORMAT_FILE_LIST; |
| else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) |
| nFormatId = SOT_FORMAT_FILE; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) ) |
| nFormatId = SOT_FORMATSTR_ID_SOLK; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ) |
| nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ) |
| nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; |
| else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) |
| nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR; |
| |
| return nFormatId; |
| } |
| |
| |
| sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt ) |
| { |
| // hide drop marker |
| // if (bDragRect) |
| // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich ); |
| bDragRect = sal_False; |
| UpdateDragRectOverlay(); |
| |
| ScModule* pScMod = SC_MOD(); |
| const ScDragData& rData = pScMod->GetDragData(); |
| |
| return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY, |
| PixelToLogic(rEvt.maPosPixel), rEvt.mnAction ); |
| } |
| |
| sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY, |
| const Point& rLogicPos, sal_Int8 nDndAction ) |
| { |
| if ( !pTransObj ) |
| return 0; |
| |
| ScDocument* pSourceDoc = pTransObj->GetSourceDocument(); |
| ScDocShell* pDocSh = pViewData->GetDocShell(); |
| ScDocument* pThisDoc = pViewData->GetDocument(); |
| ScViewFunc* pView = pViewData->GetView(); |
| SCTAB nThisTab = pViewData->GetTabNo(); |
| sal_uInt16 nFlags = pTransObj->GetDragSourceFlags(); |
| |
| sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0; |
| sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi ); |
| |
| // workaround for wrong nDndAction on Windows when pressing solely |
| // the Alt key during drag and drop; |
| // can be removed after #i79215# has been fixed |
| if ( meDragInsertMode != INS_NONE ) |
| { |
| bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi ); |
| } |
| |
| sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK ); |
| |
| ScRange aSource = pTransObj->GetRange(); |
| |
| // only use visible tab from source range - when dragging within one table, |
| // all selected tables at the time of dropping are used (handled in MoveBlockTo) |
| SCTAB nSourceTab = pTransObj->GetVisibleTab(); |
| aSource.aStart.SetTab( nSourceTab ); |
| aSource.aEnd.SetTab( nSourceTab ); |
| |
| SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1; |
| SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) : |
| pTransObj->GetNonFilteredRows()); // copy/link: no filtered rows |
| ScRange aDest( nDestPosX, nDestPosY, nThisTab, |
| nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab ); |
| |
| |
| /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during |
| * dragging and adapted drawing of the selection frame. We check here |
| * (again) because this may actually also be called from PasteSelection(), |
| * we would have to duplicate determination of flags and destination range |
| * and would lose the context of the "filtered destination is OK" cases |
| * below, which is already awkward enough as is. */ |
| |
| // Don't move filtered source. |
| bool bFiltered = (bIsMove && pTransObj->HasFilteredRows()); |
| if (!bFiltered) |
| { |
| if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) || |
| (!bIsLink && meDragInsertMode == INS_NONE))) |
| { |
| // Nothing. Either entire sheet to be dropped, or the one case |
| // where PasteFromClip() is to be called that handles a filtered |
| // destination itself. Drag-copy from another document without |
| // inserting cells. |
| } |
| else |
| // Don't copy or move to filtered destination. |
| bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc); |
| } |
| |
| sal_Bool bDone = sal_False; |
| |
| if (!bFiltered && pSourceDoc == pThisDoc) |
| { |
| if ( nFlags & SC_DROP_TABLE ) // whole sheet? |
| { |
| if ( pThisDoc->IsDocEditable() ) |
| { |
| SCTAB nSrcTab = aSource.aStart.Tab(); |
| pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True ); // with Undo |
| pView->SetTabNo( nThisTab, sal_True ); |
| bDone = sal_True; |
| } |
| } |
| else // move/copy block |
| { |
| String aChartName; |
| if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName )) |
| { |
| String aRangeName; |
| aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc ); |
| SfxStringItem aNameItem( SID_CHART_NAME, aChartName ); |
| SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName ); |
| sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE; |
| pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, |
| &aRangeItem, &aNameItem, (void*) NULL ); |
| bDone = sal_True; |
| } |
| else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) ) |
| { |
| // drop on DataPilot table: try to sort, fail if that isn't possible |
| |
| ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab ); |
| if ( aDestPos != aSource.aStart ) |
| bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos ); |
| else |
| bDone = sal_True; // same position: nothing |
| } |
| else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() || |
| nSourceTab != nThisTab ) |
| { |
| String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY ); |
| pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); |
| |
| bDone = sal_True; |
| if ( meDragInsertMode != INS_NONE ) |
| { |
| // call with bApi = sal_True to avoid error messages in drop handler |
| bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); |
| if ( bDone ) |
| { |
| if ( nThisTab == nSourceTab ) |
| { |
| if ( meDragInsertMode == INS_CELLSDOWN && |
| nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() ) |
| { |
| bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc ); |
| } |
| else if ( meDragInsertMode == INS_CELLSRIGHT && |
| nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() ) |
| { |
| bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc ); |
| } |
| } |
| pDocSh->UpdateOle( pViewData ); |
| pView->CellContentChanged(); |
| } |
| } |
| |
| if ( bDone ) |
| { |
| if ( bIsLink ) |
| { |
| // call with bApi = sal_True to avoid error messages in drop handler |
| bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ ); |
| } |
| else |
| { |
| // call with bApi = sal_True to avoid error messages in drop handler |
| bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ ); |
| } |
| } |
| |
| if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab ) |
| { |
| DelCellCmd eCmd = DEL_NONE; |
| if ( meDragInsertMode == INS_CELLSDOWN ) |
| { |
| eCmd = DEL_CELLSUP; |
| } |
| else if ( meDragInsertMode == INS_CELLSRIGHT ) |
| { |
| eCmd = DEL_CELLSLEFT; |
| } |
| |
| if ( ( eCmd == DEL_CELLSUP && nDestPosX == aSource.aStart.Col() ) || |
| ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) ) |
| { |
| // call with bApi = sal_True to avoid error messages in drop handler |
| bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ ); |
| if ( bDone ) |
| { |
| if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() ) |
| { |
| bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc ); |
| } |
| else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() ) |
| { |
| bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc ); |
| } |
| pDocSh->UpdateOle( pViewData ); |
| pView->CellContentChanged(); |
| } |
| } |
| } |
| |
| if ( bDone ) |
| { |
| pView->MarkRange( aDest, sal_False, sal_False ); |
| pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); |
| } |
| |
| pDocSh->GetUndoManager()->LeaveListAction(); |
| |
| if (!bDone) |
| Sound::Beep(); // instead of error message in drop handler |
| } |
| else |
| bDone = sal_True; // nothing to do |
| } |
| |
| if (bDone) |
| pTransObj->SetDragWasInternal(); // don't delete source in DragFinished |
| } |
| else if ( !bFiltered && pSourceDoc ) // between documents |
| { |
| if ( nFlags & SC_DROP_TABLE ) // copy/link sheets between documents |
| { |
| if ( pThisDoc->IsDocEditable() ) |
| { |
| ScDocShell* pSrcShell = pTransObj->GetSourceDocShell(); |
| |
| SCTAB nTabs[MAXTABCOUNT]; |
| |
| ScMarkData aMark = pTransObj->GetSourceMarkData(); |
| SCTAB nTabCount = pSourceDoc->GetTableCount(); |
| SCTAB nTabSelCount = 0; |
| |
| for(SCTAB i=0; i<nTabCount; i++) |
| { |
| if(aMark.GetTableSelect(i)) |
| { |
| nTabs[nTabSelCount++]=i; |
| for(SCTAB j=i+1;j<nTabCount;j++) |
| { |
| if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j))) |
| { |
| nTabs[nTabSelCount++]=j; |
| i=j; |
| } |
| else break; |
| } |
| } |
| } |
| |
| pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab ); |
| bDone = sal_True; |
| } |
| } |
| else if ( bIsLink ) |
| { |
| // as in PasteDDE |
| // (external references might be used instead?) |
| |
| SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell(); |
| DBG_ASSERT(pSourceSh, "drag document has no shell"); |
| if (pSourceSh) |
| { |
| String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY ); |
| pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); |
| |
| bDone = sal_True; |
| if ( meDragInsertMode != INS_NONE ) |
| { |
| // call with bApi = sal_True to avoid error messages in drop handler |
| bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); |
| if ( bDone ) |
| { |
| pDocSh->UpdateOle( pViewData ); |
| pView->CellContentChanged(); |
| } |
| } |
| |
| if ( bDone ) |
| { |
| String aApp = Application::GetAppName(); |
| String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME ); |
| String aItem; |
| aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc ); |
| |
| // TODO: we could define ocQuote for " |
| const String aQuote( '"' ); |
| const String& sSep = ScCompiler::GetNativeSymbol( ocSep); |
| String aFormula( '=' ); |
| aFormula += ScCompiler::GetNativeSymbol( ocDde); |
| aFormula += ScCompiler::GetNativeSymbol( ocOpen); |
| aFormula += aQuote; |
| aFormula += aApp; |
| aFormula += aQuote; |
| aFormula += sSep; |
| aFormula += aQuote; |
| aFormula += aTopic; |
| aFormula += aQuote; |
| aFormula += sSep; |
| aFormula += aQuote; |
| aFormula += aItem; |
| aFormula += aQuote; |
| aFormula += ScCompiler::GetNativeSymbol( ocClose); |
| |
| pView->DoneBlockMode(); |
| pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab ); |
| pView->MarkCursor( nDestPosX + nSizeX - 1, |
| nDestPosY + nSizeY - 1, nThisTab ); |
| |
| pView->EnterMatrix( aFormula ); |
| |
| pView->MarkRange( aDest, sal_False, sal_False ); |
| pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); |
| } |
| |
| pDocSh->GetUndoManager()->LeaveListAction(); |
| } |
| } |
| else |
| { |
| //! HasSelectedBlockMatrixFragment without selected sheet? |
| //! or don't start dragging on a part of a matrix |
| |
| String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY ); |
| pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo ); |
| |
| bDone = sal_True; |
| if ( meDragInsertMode != INS_NONE ) |
| { |
| // call with bApi = sal_True to avoid error messages in drop handler |
| bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ ); |
| if ( bDone ) |
| { |
| pDocSh->UpdateOle( pViewData ); |
| pView->CellContentChanged(); |
| } |
| } |
| |
| if ( bDone ) |
| { |
| pView->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection |
| pView->SetCursor( nDestPosX, nDestPosY ); |
| bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() ); // clip-doc |
| if ( bDone ) |
| { |
| pView->MarkRange( aDest, sal_False, sal_False ); |
| pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() ); |
| } |
| } |
| |
| pDocSh->GetUndoManager()->LeaveListAction(); |
| |
| // no longer call ResetMark here - the inserted block has been selected |
| // and may have been copied to primary selection |
| } |
| } |
| |
| sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE; |
| return nRet; |
| } |
| |
| sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt ) |
| { |
| DrawMarkDropObj( NULL ); // drawing layer |
| |
| ScModule* pScMod = SC_MOD(); |
| const ScDragData& rData = pScMod->GetDragData(); |
| if (rData.pCellTransfer) |
| return ExecutePrivateDrop( rEvt ); |
| |
| Point aPos = rEvt.maPosPixel; |
| |
| if ( rData.aLinkDoc.Len() ) |
| { |
| // try to insert a link |
| |
| sal_Bool bOk = sal_True; |
| String aThisName; |
| ScDocShell* pDocSh = pViewData->GetDocShell(); |
| if (pDocSh && pDocSh->HasName()) |
| aThisName = pDocSh->GetMedium()->GetName(); |
| |
| if ( rData.aLinkDoc == aThisName ) // error - no link within a document |
| bOk = sal_False; |
| else |
| { |
| ScViewFunc* pView = pViewData->GetView(); |
| if ( rData.aLinkTable.Len() ) |
| pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING, |
| rData.aLinkTable ); |
| else if ( rData.aLinkArea.Len() ) |
| { |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False ); |
| |
| pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING, |
| rData.aLinkArea, 0 ); |
| } |
| else |
| { |
| DBG_ERROR("drop with link: no sheet nor area"); |
| bOk = sal_False; |
| } |
| } |
| |
| return bOk ? rEvt.mnAction : DND_ACTION_NONE; // don't try anything else |
| } |
| |
| Point aLogicPos = PixelToLogic(aPos); |
| sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK ); |
| |
| if (!bIsLink && rData.pDrawTransfer) |
| { |
| sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags(); |
| |
| sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0; |
| sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi ); |
| |
| bPasteIsMove = bIsMove; |
| |
| pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() ); |
| |
| if (bPasteIsMove) |
| rData.pDrawTransfer->SetDragWasInternal(); |
| bPasteIsMove = sal_False; |
| |
| return rEvt.mnAction; |
| } |
| |
| |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| |
| if (rData.aJumpTarget.Len()) |
| { |
| // internal bookmark (from Navigator) |
| // bookmark clipboard formats are in PasteScDataObject |
| |
| if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() ) |
| { |
| pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget, |
| nPosX, nPosY ); |
| return rEvt.mnAction; |
| } |
| } |
| |
| ScDocument* pThisDoc = pViewData->GetDocument(); |
| SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) ); |
| if ( pHitObj && bIsLink ) |
| { |
| // dropped on drawing object |
| // PasteOnDrawObjectLinked checks for valid formats |
| if ( pViewData->GetView()->PasteOnDrawObjectLinked( rEvt.maDropEvent.Transferable, *pHitObj ) ) |
| return rEvt.mnAction; |
| } |
| |
| sal_Bool bDone = sal_False; |
| |
| sal_uLong nFormatId = bIsLink ? |
| lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) : |
| lcl_GetDropFormatId( rEvt.maDropEvent.Transferable ); |
| if ( nFormatId ) |
| { |
| pScMod->SetInExecuteDrop( sal_True ); // #i28468# prevent error messages from PasteDataFormat |
| bPasteIsDrop = sal_True; |
| bDone = pViewData->GetView()->PasteDataFormat( |
| nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink ); |
| bPasteIsDrop = sal_False; |
| pScMod->SetInExecuteDrop( sal_False ); |
| } |
| |
| sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE; |
| return nRet; |
| } |
| |
| //-------------------------------------------------------- |
| |
| void ScGridWindow::PasteSelection( const Point& rPosPixel ) |
| { |
| Point aLogicPos = PixelToLogic( rPosPixel ); |
| |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY ); |
| |
| ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer(); |
| if ( pOwnSelection ) |
| { |
| // within Calc |
| |
| ScTransferObj* pCellTransfer = pOwnSelection->GetCellData(); |
| if ( pCellTransfer ) |
| { |
| // keep a reference to the data in case the selection is changed during paste |
| uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer ); |
| DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY ); |
| } |
| else |
| { |
| ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData(); |
| if ( pDrawTransfer ) |
| { |
| // keep a reference to the data in case the selection is changed during paste |
| uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer ); |
| |
| // #96821# bSameDocClipboard argument for PasteDraw is needed |
| // because only DragData is checked directly inside PasteDraw |
| pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), sal_False, |
| pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() ); |
| } |
| } |
| } |
| else |
| { |
| // get selection from system |
| |
| TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) ); |
| uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable(); |
| if ( xTransferable.is() ) |
| { |
| sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true ); |
| if ( nFormatId ) |
| { |
| bPasteIsDrop = sal_True; |
| pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos ); |
| bPasteIsDrop = sal_False; |
| } |
| } |
| } |
| } |
| |
| //-------------------------------------------------------- |
| |
| void ScGridWindow::UpdateEditViewPos() |
| { |
| if (pViewData->HasEditView(eWhich)) |
| { |
| EditView* pView; |
| SCCOL nCol; |
| SCROW nRow; |
| pViewData->GetEditView( eWhich, pView, nCol, nRow ); |
| SCCOL nEndCol = pViewData->GetEditEndCol(); |
| SCROW nEndRow = pViewData->GetEditEndRow(); |
| |
| // hide EditView? |
| |
| sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) ); |
| if ( SC_MOD()->IsFormulaMode() ) |
| if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() ) |
| bHide = sal_True; |
| |
| if (bHide) |
| { |
| Rectangle aRect = pView->GetOutputArea(); |
| long nHeight = aRect.Bottom() - aRect.Top(); |
| aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()). |
| Height() * 2; |
| aRect.Bottom() = aRect.Top() + nHeight; |
| pView->SetOutputArea( aRect ); |
| pView->HideCursor(); |
| } |
| else |
| { |
| // bForceToTop = sal_True for editing |
| Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True ); |
| Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() ); |
| |
| Rectangle aRect = pView->GetOutputArea(); |
| aRect.SetPos( aScrPos ); |
| pView->SetOutputArea( aRect ); |
| pView->ShowCursor(); |
| } |
| } |
| } |
| |
| void ScGridWindow::ScrollPixel( long nDifX, long nDifY ) |
| { |
| ClickExtern(); |
| HideNoteMarker(); |
| |
| bIsInScroll = sal_True; |
| //sal_Bool bXor=DrawBeforeScroll(); |
| |
| SetMapMode(MAP_PIXEL); |
| Scroll( nDifX, nDifY, SCROLL_CHILDREN ); |
| SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen |
| |
| UpdateEditViewPos(); |
| |
| DrawAfterScroll(); //bXor); |
| bIsInScroll = sal_False; |
| } |
| |
| // Formeln neu zeichnen ------------------------------------------------- |
| |
| void ScGridWindow::UpdateFormulas() |
| { |
| if (pViewData->GetView()->IsMinimized()) |
| return; |
| |
| if ( nPaintCount ) |
| { |
| // nicht anfangen, verschachtelt zu painten |
| // (dann wuerde zumindest der MapMode nicht mehr stimmen) |
| |
| bNeedsRepaint = sal_True; // -> am Ende vom Paint nochmal Invalidate auf alles |
| aRepaintPixel = Rectangle(); // alles |
| return; |
| } |
| |
| SCCOL nX1 = pViewData->GetPosX( eHWhich ); |
| SCROW nY1 = pViewData->GetPosY( eVWhich ); |
| SCCOL nX2 = nX1 + pViewData->VisibleCellsX( eHWhich ); |
| SCROW nY2 = nY1 + pViewData->VisibleCellsY( eVWhich ); |
| |
| if (nX2 > MAXCOL) nX2 = MAXCOL; |
| if (nY2 > MAXROW) nY2 = MAXROW; |
| |
| // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED ); |
| |
| // don't draw directly - instead use OutputData to find changed area and invalidate |
| |
| SCROW nPosY = nY1; |
| |
| ScDocShell* pDocSh = pViewData->GetDocShell(); |
| ScDocument* pDoc = pDocSh->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| |
| pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab ); |
| |
| Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich ); |
| long nMirrorWidth = GetSizePixel().Width(); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1; |
| if ( bLayoutRTL ) |
| { |
| long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X(); |
| nMirrorWidth = aScrPos.X() - nEndPixel; |
| aScrPos.X() = nEndPixel + 1; |
| } |
| |
| long nScrX = aScrPos.X(); |
| long nScrY = aScrPos.Y(); |
| |
| double nPPTX = pViewData->GetPPTX(); |
| double nPPTY = pViewData->GetPPTY(); |
| |
| ScTableInfo aTabInfo; |
| pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, sal_False, sal_False ); |
| |
| Fraction aZoomX = pViewData->GetZoomX(); |
| Fraction aZoomY = pViewData->GetZoomY(); |
| ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab, |
| nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY, |
| &aZoomX, &aZoomY ); |
| aOutputData.SetMirrorWidth( nMirrorWidth ); |
| |
| aOutputData.FindChanged(); |
| |
| // #122149# do not use old GetChangedArea() which used polygon-based Regions, but use |
| // the region-band based new version; anyways, only rectangles are added |
| Region aChangedRegion( aOutputData.GetChangedAreaRegion() ); // logic (PixelToLogic) |
| if(!aChangedRegion.IsEmpty()) |
| { |
| Invalidate(aChangedRegion); |
| } |
| |
| CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here |
| } |
| |
| void ScGridWindow::UpdateAutoFillMark(sal_Bool bMarked, const ScRange& rMarkRange) |
| { |
| if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) ) |
| { |
| HideCursor(); |
| bAutoMarkVisible = bMarked; |
| if ( bMarked ) |
| aAutoMarkPos = rMarkRange.aEnd; |
| ShowCursor(); |
| |
| UpdateAutoFillOverlay(); |
| } |
| } |
| |
| void ScGridWindow::UpdateListValPos( sal_Bool bVisible, const ScAddress& rPos ) |
| { |
| sal_Bool bOldButton = bListValButton; |
| ScAddress aOldPos = aListValPos; |
| |
| bListValButton = bVisible; |
| aListValPos = rPos; |
| |
| if ( bListValButton ) |
| { |
| if ( !bOldButton || aListValPos != aOldPos ) |
| { |
| // paint area of new button |
| Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) ); |
| } |
| } |
| if ( bOldButton ) |
| { |
| if ( !bListValButton || aListValPos != aOldPos ) |
| { |
| // paint area of old button |
| Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) ); |
| } |
| } |
| } |
| |
| void ScGridWindow::HideCursor() |
| { |
| ++nCursorHideCount; |
| if (nCursorHideCount==1) |
| { |
| DrawCursor(); |
| DrawAutoFillMark(); |
| } |
| } |
| |
| void ScGridWindow::ShowCursor() |
| { |
| if (nCursorHideCount==0) |
| { |
| DBG_ERROR("zuviel ShowCursor"); |
| return; |
| } |
| |
| if (nCursorHideCount==1) |
| { |
| // #i57745# Draw the cursor before setting the variable, in case the |
| // GetSizePixel call from drawing causes a repaint (resize handler is called) |
| DrawAutoFillMark(); |
| DrawCursor(); |
| } |
| |
| --nCursorHideCount; |
| } |
| |
| void __EXPORT ScGridWindow::GetFocus() |
| { |
| ScTabViewShell* pViewShell = pViewData->GetViewShell(); |
| pViewShell->GotFocus(); |
| pViewShell->SetFormShellAtTop( sal_False ); // focus in GridWindow -> FormShell no longer on top |
| |
| if (pViewShell->HasAccessibilityObjects()) |
| pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible())); |
| |
| |
| if ( !SC_MOD()->IsFormulaMode() ) |
| { |
| pViewShell->UpdateInputHandler(); |
| // StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp |
| // MO: nur wenn nicht im RefInput-Modus |
| // -> GetFocus/MouseButtonDown-Reihenfolge |
| // auf dem Mac |
| } |
| |
| Window::GetFocus(); |
| } |
| |
| void __EXPORT ScGridWindow::LoseFocus() |
| { |
| ScTabViewShell* pViewShell = pViewData->GetViewShell(); |
| pViewShell->LostFocus(); |
| |
| if (pViewShell->HasAccessibilityObjects()) |
| pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible())); |
| |
| Window::LoseFocus(); |
| } |
| |
| Point ScGridWindow::GetMousePosPixel() const { return aCurMousePos; } |
| |
| //------------------------------------------------------------------------ |
| |
| sal_Bool ScGridWindow::HitRangeFinder( const Point& rMouse, sal_Bool& rCorner, |
| sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY ) |
| { |
| sal_Bool bFound = sal_False; |
| ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() ); |
| if (pHdl) |
| { |
| ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList(); |
| if ( pRangeFinder && !pRangeFinder->IsHidden() && |
| pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() ) |
| { |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| long nLayoutSign = bLayoutRTL ? -1 : 1; |
| |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY ); |
| // zusammengefasste (einzeln/Bereich) ??? |
| ScAddress aAddr( nPosX, nPosY, nTab ); |
| |
| // Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich ); |
| |
| Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, sal_True ); |
| long nSizeXPix; |
| long nSizeYPix; |
| pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix ); |
| aNext.X() += nSizeXPix * nLayoutSign; |
| aNext.Y() += nSizeYPix; |
| |
| sal_Bool bCornerHor; |
| if ( bLayoutRTL ) |
| bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 ); |
| else |
| bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() ); |
| |
| sal_Bool bCellCorner = ( bCornerHor && |
| rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() ); |
| // corner is hit only if the mouse is within the cell |
| |
| sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count(); |
| for (sal_uInt16 i=nCount; i;) |
| { |
| // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird |
| --i; |
| ScRangeFindData* pData = pRangeFinder->GetObject(i); |
| if ( pData && pData->aRef.In(aAddr) ) |
| { |
| if (pIndex) *pIndex = i; |
| if (pAddX) *pAddX = nPosX - pData->aRef.aStart.Col(); |
| if (pAddY) *pAddY = nPosY - pData->aRef.aStart.Row(); |
| bFound = sal_True; |
| rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd ); |
| break; |
| } |
| } |
| } |
| } |
| return bFound; |
| } |
| |
| #define SCE_TOP 1 |
| #define SCE_BOTTOM 2 |
| #define SCE_LEFT 4 |
| #define SCE_RIGHT 8 |
| #define SCE_ALL 15 |
| |
| void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges ) |
| { |
| // der Range ist immer richtigherum |
| |
| SCCOL nCol1 = rRange.aStart.Col(); |
| SCROW nRow1 = rRange.aStart.Row(); |
| SCTAB nTab1 = rRange.aStart.Tab(); |
| SCCOL nCol2 = rRange.aEnd.Col(); |
| SCROW nRow2 = rRange.aEnd.Row(); |
| SCTAB nTab2 = rRange.aEnd.Tab(); |
| sal_Bool bHiddenEdge = sal_False; |
| SCROW nTmp; |
| |
| ScDocument* pDoc = pDocSh->GetDocument(); |
| while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) ) |
| { |
| --nCol1; |
| bHiddenEdge = sal_True; |
| } |
| while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) ) |
| { |
| ++nCol2; |
| bHiddenEdge = sal_True; |
| } |
| nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1); |
| if (!ValidRow(nTmp)) |
| nTmp = 0; |
| if (nTmp < nRow1) |
| { |
| nRow1 = nTmp; |
| bHiddenEdge = sal_True; |
| } |
| nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1); |
| if (!ValidRow(nTmp)) |
| nTmp = MAXROW; |
| if (nTmp > nRow2) |
| { |
| nRow2 = nTmp; |
| bHiddenEdge = sal_True; |
| } |
| |
| if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge ) |
| { |
| // nur an den Raendern entlang |
| // (die Ecken werden evtl. zweimal getroffen) |
| |
| if ( nEdges & SCE_TOP ) |
| pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS ); |
| if ( nEdges & SCE_LEFT ) |
| pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS ); |
| if ( nEdges & SCE_RIGHT ) |
| pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); |
| if ( nEdges & SCE_BOTTOM ) |
| pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); |
| } |
| else // everything in one call |
| pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS ); |
| } |
| |
| void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn ) |
| { |
| // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind |
| |
| ScRange aOld = rOldUn; |
| ScRange aNew = rNewUn; |
| aOld.Justify(); |
| aNew.Justify(); |
| |
| if ( aOld.aStart == aOld.aEnd ) //! Tab ignorieren? |
| pDocSh->GetDocument()->ExtendMerge(aOld); |
| if ( aNew.aStart == aNew.aEnd ) //! Tab ignorieren? |
| pDocSh->GetDocument()->ExtendMerge(aNew); |
| |
| SCCOL nOldCol1 = aOld.aStart.Col(); |
| SCROW nOldRow1 = aOld.aStart.Row(); |
| SCCOL nOldCol2 = aOld.aEnd.Col(); |
| SCROW nOldRow2 = aOld.aEnd.Row(); |
| SCCOL nNewCol1 = aNew.aStart.Col(); |
| SCROW nNewRow1 = aNew.aStart.Row(); |
| SCCOL nNewCol2 = aNew.aEnd.Col(); |
| SCROW nNewRow2 = aNew.aEnd.Row(); |
| SCTAB nTab1 = aOld.aStart.Tab(); // Tab aendert sich nicht |
| SCTAB nTab2 = aOld.aEnd.Tab(); |
| |
| if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 || |
| nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 || |
| ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 && |
| nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) ) |
| { |
| // komplett weggeschoben oder alle Seiten veraendert |
| // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten) |
| |
| lcl_PaintOneRange( pDocSh, aOld, SCE_ALL ); |
| } |
| else // alle vier Kanten einzeln testen |
| { |
| // oberer Teil |
| if ( nNewRow1 < nOldRow1 ) // nur obere Linie loeschen |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL ); |
| else if ( nNewRow1 > nOldRow1 ) // den Teil, der oben wegkommt |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ), |
| SCE_ALL &~ SCE_BOTTOM ); |
| |
| // unterer Teil |
| if ( nNewRow2 > nOldRow2 ) // nur untere Linie loeschen |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL ); |
| else if ( nNewRow2 < nOldRow2 ) // den Teil, der unten wegkommt |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ), |
| SCE_ALL &~ SCE_TOP ); |
| |
| // linker Teil |
| if ( nNewCol1 < nOldCol1 ) // nur linke Linie loeschen |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL ); |
| else if ( nNewCol1 > nOldCol1 ) // den Teil, der links wegkommt |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ), |
| SCE_ALL &~ SCE_RIGHT ); |
| |
| // rechter Teil |
| if ( nNewCol2 > nOldCol2 ) // nur rechte Linie loeschen |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL ); |
| else if ( nNewCol2 < nOldCol2 ) // den Teil, der rechts wegkommt |
| lcl_PaintOneRange( pDocSh, ScRange( |
| nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), |
| SCE_ALL &~ SCE_LEFT ); |
| } |
| } |
| |
| void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp ) |
| { |
| ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() ); |
| if (!pHdl) |
| return; |
| ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList(); |
| if (!pRangeFinder || nRFIndex >= pRangeFinder->Count()) |
| return; |
| ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex ); |
| if (!pData) |
| return; |
| |
| // Mauszeiger |
| |
| if (bRFSize) |
| SetPointer( Pointer( POINTER_CROSS ) ); |
| else |
| SetPointer( Pointer( POINTER_HAND ) ); |
| |
| // Scrolling |
| |
| sal_Bool bTimer = sal_False; |
| Point aPos = rMEvt.GetPosPixel(); |
| SCsCOL nDx = 0; |
| SCsROW nDy = 0; |
| if ( aPos.X() < 0 ) nDx = -1; |
| if ( aPos.Y() < 0 ) nDy = -1; |
| Size aSize = GetOutputSizePixel(); |
| if ( aPos.X() >= aSize.Width() ) |
| nDx = 1; |
| if ( aPos.Y() >= aSize.Height() ) |
| nDy = 1; |
| if ( nDx != 0 || nDy != 0 ) |
| { |
| if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) ); |
| if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) ); |
| bTimer = sal_True; |
| } |
| |
| // Umschalten bei Fixierung (damit Scrolling funktioniert) |
| |
| if ( eWhich == pViewData->GetActivePart() ) //?? |
| { |
| if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ) |
| if ( nDx > 0 ) |
| { |
| if ( eWhich == SC_SPLIT_TOPLEFT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ); |
| else if ( eWhich == SC_SPLIT_BOTTOMLEFT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ); |
| } |
| |
| if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX ) |
| if ( nDy > 0 ) |
| { |
| if ( eWhich == SC_SPLIT_TOPLEFT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ); |
| else if ( eWhich == SC_SPLIT_TOPRIGHT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ); |
| } |
| } |
| |
| // Verschieben |
| |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); |
| |
| ScRange aOld = pData->aRef; |
| ScRange aNew = aOld; |
| if ( bRFSize ) |
| { |
| aNew.aEnd.SetCol((SCCOL)nPosX); |
| aNew.aEnd.SetRow((SCROW)nPosY); |
| } |
| else |
| { |
| long nStartX = nPosX - nRFAddX; |
| if ( nStartX < 0 ) nStartX = 0; |
| long nStartY = nPosY - nRFAddY; |
| if ( nStartY < 0 ) nStartY = 0; |
| long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col(); |
| if ( nEndX > MAXCOL ) |
| { |
| nStartX -= ( nEndX - MAXROW ); |
| nEndX = MAXCOL; |
| } |
| long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row(); |
| if ( nEndY > MAXROW ) |
| { |
| nStartY -= ( nEndY - MAXROW ); |
| nEndY = MAXROW; |
| } |
| |
| aNew.aStart.SetCol((SCCOL)nStartX); |
| aNew.aStart.SetRow((SCROW)nStartY); |
| aNew.aEnd.SetCol((SCCOL)nEndX); |
| aNew.aEnd.SetRow((SCROW)nEndY); |
| } |
| |
| if ( bUp ) |
| aNew.Justify(); // beim ButtonUp wieder richtigherum |
| |
| if ( aNew != aOld ) |
| { |
| pHdl->UpdateRange( nRFIndex, aNew ); |
| |
| ScDocShell* pDocSh = pViewData->GetDocShell(); |
| |
| // nur das neuzeichnen, was sich veraendert hat... |
| lcl_PaintRefChanged( pDocSh, aOld, aNew ); |
| |
| // neuen Rahmen nur drueberzeichnen (synchron) |
| pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) ); |
| |
| Update(); // was man bewegt, will man auch sofort sehen |
| } |
| |
| // Timer fuer Scrolling |
| |
| if (bTimer) |
| pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen |
| else |
| pViewData->GetView()->ResetTimer(); |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| sal_Bool ScGridWindow::GetEditUrl( const Point& rPos, |
| String* pName, String* pUrl, String* pTarget ) |
| { |
| return GetEditUrlOrError( sal_False, rPos, pName, pUrl, pTarget ); |
| } |
| |
| sal_Bool ScGridWindow::GetEditUrlOrError( sal_Bool bSpellErr, const Point& rPos, |
| String* pName, String* pUrl, String* pTarget ) |
| { |
| //! nPosX/Y mit uebergeben? |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY ); |
| |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScDocShell* pDocSh = pViewData->GetDocShell(); |
| ScDocument* pDoc = pDocSh->GetDocument(); |
| ScBaseCell* pCell = NULL; |
| |
| sal_Bool bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ); |
| if( !bFound ) |
| return sal_False; |
| |
| ScHideTextCursor aHideCursor( pViewData, eWhich ); // before GetEditArea (MapMode is changed) |
| |
| const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab ); |
| // bForceToTop = sal_False, use the cell's real position |
| Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False ); |
| if (rPos.Y() < aEditRect.Top()) |
| return sal_False; |
| |
| // vertikal kann (noch) nicht angeklickt werden: |
| |
| if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD) |
| return sal_False; |
| |
| sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() || |
| ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern-> |
| GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK); |
| SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern-> |
| GetItem(ATTR_HOR_JUSTIFY)).GetValue(); |
| |
| // EditEngine |
| |
| ScFieldEditEngine aEngine( pDoc->GetEditPool() ); |
| ScSizeDeviceProvider aProv(pDocSh); |
| aEngine.SetRefDevice( aProv.GetDevice() ); |
| aEngine.SetRefMapMode( MAP_100TH_MM ); |
| SfxItemSet aDefault( aEngine.GetEmptyItemSet() ); |
| pPattern->FillEditItemSet( &aDefault ); |
| SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT; |
| switch (eHorJust) |
| { |
| case SVX_HOR_JUSTIFY_LEFT: |
| case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert |
| case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type |
| eSvxAdjust = SVX_ADJUST_LEFT; |
| break; |
| case SVX_HOR_JUSTIFY_RIGHT: |
| eSvxAdjust = SVX_ADJUST_RIGHT; |
| break; |
| case SVX_HOR_JUSTIFY_CENTER: |
| eSvxAdjust = SVX_ADJUST_CENTER; |
| break; |
| case SVX_HOR_JUSTIFY_BLOCK: |
| eSvxAdjust = SVX_ADJUST_BLOCK; |
| break; |
| } |
| aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) ); |
| aEngine.SetDefaults( aDefault ); |
| if (bSpellErr) |
| aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING ); |
| |
| MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung |
| Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode ); |
| long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1; |
| Size aPaperSize = Size( 1000000, 1000000 ); |
| if(pCell->GetCellType() == CELLTYPE_FORMULA) |
| { |
| long nSizeX = 0; |
| long nSizeY = 0; |
| pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY ); |
| aPaperSize = Size(nSizeX, nSizeY ); |
| aPaperSize = PixelToLogic(aPaperSize); |
| } |
| |
| if (bBreak) |
| aPaperSize.Width() = nThisColLogic; |
| aEngine.SetPaperSize( aPaperSize ); |
| |
| ::std::auto_ptr< EditTextObject > pTextObj; |
| const EditTextObject* pData; |
| if(pCell->GetCellType() == CELLTYPE_EDIT) |
| { |
| ((ScEditCell*)pCell)->GetData(pData); |
| if (pData) |
| aEngine.SetText(*pData); |
| } |
| else // HyperLink Formula cell |
| { |
| pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject()); |
| if (pTextObj.get()) |
| aEngine.SetText(*pTextObj); |
| } |
| |
| long nStartX = aLogicEdit.Left(); |
| |
| long nTextWidth = aEngine.CalcTextWidth(); |
| long nTextHeight = aEngine.GetTextHeight(); |
| if ( nTextWidth < nThisColLogic ) |
| { |
| if (eHorJust == SVX_HOR_JUSTIFY_RIGHT) |
| nStartX += nThisColLogic - nTextWidth; |
| else if (eHorJust == SVX_HOR_JUSTIFY_CENTER) |
| nStartX += (nThisColLogic - nTextWidth) / 2; |
| } |
| |
| aLogicEdit.Left() = nStartX; |
| if (!bBreak) |
| aLogicEdit.Right() = nStartX + nTextWidth; |
| |
| // There is one glitch when dealing with a hyperlink cell and |
| // the cell content is NUMERIC. This defaults to right aligned and |
| // we need to adjust accordingly. |
| if(pCell->GetCellType() == CELLTYPE_FORMULA && |
| static_cast<ScFormulaCell*>(pCell)->IsValue() && |
| eHorJust == SVX_HOR_JUSTIFY_STANDARD) |
| { |
| aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1; |
| aLogicEdit.Left() = aLogicEdit.Right() - nTextWidth; |
| } |
| aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight; |
| |
| |
| Point aLogicClick = PixelToLogic(rPos,aEditMode); |
| if ( aLogicEdit.IsInside(aLogicClick) ) |
| { |
| // aEngine.SetUpdateMode(sal_False); |
| EditView aTempView( &aEngine, this ); |
| aTempView.SetOutputArea( aLogicEdit ); |
| |
| sal_Bool bRet = sal_False; |
| MapMode aOld = GetMapMode(); |
| SetMapMode(aEditMode); // kein return mehr |
| |
| if (bSpellErr) // Spelling-Fehler suchen |
| { |
| bRet = aTempView.IsWrongSpelledWordAtPos( rPos ); |
| if ( bRet ) |
| pViewData->GetView()->SetCursor( nPosX, nPosY ); // Cursor setzen |
| } |
| else // URL suchen |
| { |
| const SvxFieldItem* pFieldItem = aTempView.GetFieldUnderMousePointer(); |
| |
| if (pFieldItem) |
| { |
| const SvxFieldData* pField = pFieldItem->GetField(); |
| if ( pField && pField->ISA(SvxURLField) ) |
| { |
| if ( pName || pUrl || pTarget ) |
| { |
| const SvxURLField* pURLField = (const SvxURLField*)pField; |
| if (pName) |
| *pName = pURLField->GetRepresentation(); |
| if (pUrl) |
| *pUrl = pURLField->GetURL(); |
| if (pTarget) |
| *pTarget = pURLField->GetTargetFrame(); |
| } |
| bRet = sal_True; |
| } |
| } |
| } |
| |
| SetMapMode(aOld); |
| |
| // text cursor is restored in ScHideTextCursor dtor |
| |
| return bRet; |
| } |
| return sal_False; |
| } |
| |
| sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange ) |
| { |
| ScDocument* pDoc = pViewData->GetDocument(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| SCTAB nTabCount = pDoc->GetTableCount(); |
| if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) ) |
| { |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| |
| Size aButSize = pViewData->GetScenButSize(); |
| long nBWidth = aButSize.Width(); |
| if (!nBWidth) |
| return sal_False; // noch kein Button gezeichnet -> da ist auch keiner |
| long nBHeight = aButSize.Height(); |
| long nHSpace = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() ); |
| |
| //! Ranges an der Table cachen!!!! |
| |
| ScMarkData aMarks; |
| for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) |
| pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME ); |
| ScRangeList aRanges; |
| aMarks.FillRangeListWithMarks( &aRanges, sal_False ); |
| |
| |
| sal_uLong nRangeCount = aRanges.Count(); |
| for (sal_uLong j=0; j<nRangeCount; j++) |
| { |
| ScRange aRange = *aRanges.GetObject(j); |
| // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn |
| // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden |
| pDoc->ExtendTotalMerge( aRange ); |
| |
| sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 ); |
| |
| Point aButtonPos; |
| if ( bTextBelow ) |
| { |
| aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, |
| eWhich, sal_True ); |
| } |
| else |
| { |
| aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(), |
| eWhich, sal_True ); |
| aButtonPos.Y() -= nBHeight; |
| } |
| if ( bLayoutRTL ) |
| aButtonPos.X() -= nHSpace - 1; |
| else |
| aButtonPos.X() -= nBWidth - nHSpace; // same for top or bottom |
| |
| Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) ); |
| if ( aButRect.IsInside( rPosPixel ) ) |
| { |
| rScenRange = aRange; |
| return sal_True; |
| } |
| } |
| } |
| |
| return sal_False; |
| } |
| |
| void ScGridWindow::UpdateVisibleRange() |
| { |
| // #163911# Update the visible range outside of paint (called when switching sheets). |
| // Use the same logic here as in ScGridWindow::Draw. |
| |
| SCCOL nPosX = pViewData->GetPosX( eHWhich ); |
| SCROW nPosY = pViewData->GetPosY( eVWhich ); |
| |
| SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich); |
| if (nXRight > MAXCOL) nXRight = MAXCOL; |
| SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); |
| if (nYBottom > MAXROW) nYBottom = MAXROW; |
| |
| // Store the current visible range. |
| maVisibleRange.mnCol1 = nPosX; |
| maVisibleRange.mnCol2 = nXRight; |
| maVisibleRange.mnRow1 = nPosY; |
| maVisibleRange.mnRow2 = nYBottom; |
| } |
| |
| // #114409# |
| void ScGridWindow::DrawLayerCreated() |
| { |
| SetMapMode( GetDrawMapMode() ); |
| |
| // initially create overlay objects |
| ImpCreateOverlayObjects(); |
| } |
| |
| // #114409# |
| void ScGridWindow::CursorChanged() |
| { |
| // here the created OverlayObjects may be transformed in later versions. For |
| // now, just re-create them |
| |
| UpdateCursorOverlay(); |
| } |
| |
| // #114409# |
| void ScGridWindow::ImpCreateOverlayObjects() |
| { |
| UpdateCursorOverlay(); |
| UpdateSelectionOverlay(); |
| UpdateAutoFillOverlay(); |
| UpdateDragRectOverlay(); |
| UpdateHeaderOverlay(); |
| UpdateShrinkOverlay(); |
| } |
| |
| // #114409# |
| void ScGridWindow::ImpDestroyOverlayObjects() |
| { |
| DeleteCursorOverlay(); |
| DeleteSelectionOverlay(); |
| DeleteAutoFillOverlay(); |
| DeleteDragRectOverlay(); |
| DeleteHeaderOverlay(); |
| DeleteShrinkOverlay(); |
| } |
| |
| void ScGridWindow::UpdateAllOverlays() |
| { |
| // delete and re-allocate all overlay objects |
| |
| ImpDestroyOverlayObjects(); |
| ImpCreateOverlayObjects(); |
| } |
| |
| void ScGridWindow::DeleteCursorOverlay() |
| { |
| DELETEZ( mpOOCursors ); |
| } |
| |
| void ScGridWindow::UpdateCursorOverlay() |
| { |
| MapMode aDrawMode = GetDrawMapMode(); |
| MapMode aOldMode = GetMapMode(); |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aDrawMode ); |
| |
| // Existing OverlayObjects may be transformed in later versions. |
| // For now, just re-create them. |
| |
| DeleteCursorOverlay(); |
| |
| std::vector<Rectangle> aPixelRects; |
| |
| // |
| // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor) |
| // |
| |
| SCTAB nTab = pViewData->GetTabNo(); |
| SCCOL nX = pViewData->GetCurX(); |
| SCROW nY = pViewData->GetCurY(); |
| |
| if (!maVisibleRange.isInside(nX, nY)) |
| return; |
| |
| // don't show the cursor in overlapped cells |
| |
| ScDocument* pDoc = pViewData->GetDocument(); |
| const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab); |
| const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG); |
| sal_Bool bOverlapped = rMergeFlag.IsOverlapped(); |
| |
| // left or above of the screen? |
| |
| sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) ); |
| if (!bVis) |
| { |
| SCCOL nEndX = nX; |
| SCROW nEndY = nY; |
| const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE); |
| if (rMerge.GetColMerge() > 1) |
| nEndX += rMerge.GetColMerge()-1; |
| if (rMerge.GetRowMerge() > 1) |
| nEndY += rMerge.GetRowMerge()-1; |
| bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) ); |
| } |
| |
| if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() ) |
| { |
| Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| |
| // completely right of/below the screen? |
| // (test with logical start position in aScrPos) |
| sal_Bool bMaybeVisible; |
| if ( bLayoutRTL ) |
| bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 ); |
| else |
| { |
| Size aOutSize = GetOutputSizePixel(); |
| bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 ); |
| } |
| if ( bMaybeVisible ) |
| { |
| long nSizeXPix; |
| long nSizeYPix; |
| pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); |
| |
| if ( bLayoutRTL ) |
| aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring |
| |
| sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX || |
| pViewData->GetVSplitMode() == SC_SPLIT_FIX ); |
| if ( pViewData->GetActivePart()==eWhich || bFix ) |
| { |
| aScrPos.X() -= 2; |
| aScrPos.Y() -= 2; |
| Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); |
| |
| aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() )); |
| aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() )); |
| aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 )); |
| aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() )); |
| } |
| else |
| { |
| Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) ); |
| aPixelRects.push_back( aRect ); |
| } |
| } |
| } |
| |
| if ( aPixelRects.size() ) |
| { |
| // #i70788# get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); |
| |
| if(pOverlayManager) |
| { |
| const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); |
| std::vector< basegfx::B2DRange > aRanges; |
| const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); |
| |
| for(sal_uInt32 a(0); a < aPixelRects.size(); a++) |
| { |
| const Rectangle aRA(aPixelRects[a]); |
| basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); |
| aRB.transform(aTransform); |
| aRanges.push_back(aRB); |
| } |
| |
| sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( |
| sdr::overlay::OVERLAY_SOLID, |
| aCursorColor, |
| aRanges, |
| false); |
| |
| pOverlayManager->add(*pOverlay); |
| mpOOCursors = new ::sdr::overlay::OverlayObjectList; |
| mpOOCursors->append(*pOverlay); |
| } |
| } |
| |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aOldMode ); |
| } |
| |
| void ScGridWindow::DeleteSelectionOverlay() |
| { |
| DELETEZ( mpOOSelection ); |
| } |
| |
| void ScGridWindow::UpdateSelectionOverlay() |
| { |
| MapMode aDrawMode = GetDrawMapMode(); |
| MapMode aOldMode = GetMapMode(); |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aDrawMode ); |
| |
| DeleteSelectionOverlay(); |
| std::vector<Rectangle> aPixelRects; |
| GetSelectionRects( aPixelRects ); |
| |
| if ( aPixelRects.size() && pViewData->IsActive() ) |
| { |
| // #i70788# get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); |
| |
| if(pOverlayManager) |
| { |
| std::vector< basegfx::B2DRange > aRanges; |
| const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); |
| |
| for(sal_uInt32 a(0); a < aPixelRects.size(); a++) |
| { |
| const Rectangle aRA(aPixelRects[a]); |
| basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom()); |
| aRB.transform(aTransform); |
| aRanges.push_back(aRB); |
| } |
| |
| // get the system's hilight color |
| const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; |
| const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor()); |
| |
| sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( |
| sdr::overlay::OVERLAY_TRANSPARENT, |
| aHighlight, |
| aRanges, |
| true); |
| |
| pOverlayManager->add(*pOverlay); |
| mpOOSelection = new ::sdr::overlay::OverlayObjectList; |
| mpOOSelection->append(*pOverlay); |
| } |
| } |
| |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aOldMode ); |
| } |
| |
| void ScGridWindow::DeleteAutoFillOverlay() |
| { |
| DELETEZ( mpOOAutoFill ); |
| mpAutoFillRect.reset(); |
| } |
| |
| void ScGridWindow::UpdateAutoFillOverlay() |
| { |
| MapMode aDrawMode = GetDrawMapMode(); |
| MapMode aOldMode = GetMapMode(); |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aDrawMode ); |
| |
| DeleteAutoFillOverlay(); |
| |
| // |
| // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark) |
| // |
| |
| if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() && |
| !pViewData->HasEditView(eWhich) && pViewData->IsActive() ) |
| { |
| SCCOL nX = aAutoMarkPos.Col(); |
| SCROW nY = aAutoMarkPos.Row(); |
| |
| if (!maVisibleRange.isInside(nX, nY)) |
| // Autofill mark is not visible. Bail out. |
| return; |
| |
| SCTAB nTab = pViewData->GetTabNo(); |
| ScDocument* pDoc = pViewData->GetDocument(); |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| |
| Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); |
| long nSizeXPix; |
| long nSizeYPix; |
| pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); |
| if ( bLayoutRTL ) |
| aFillPos.X() -= nSizeXPix + 3; |
| else |
| aFillPos.X() += nSizeXPix - 2; |
| |
| aFillPos.Y() += nSizeYPix; |
| aFillPos.Y() -= 2; |
| mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6))); |
| |
| // #i70788# get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); |
| |
| if(pOverlayManager) |
| { |
| const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); |
| std::vector< basegfx::B2DRange > aRanges; |
| const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); |
| basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1); |
| |
| aRB.transform(aTransform); |
| aRanges.push_back(aRB); |
| |
| sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( |
| sdr::overlay::OVERLAY_SOLID, |
| aHandleColor, |
| aRanges, |
| false); |
| |
| pOverlayManager->add(*pOverlay); |
| mpOOAutoFill = new ::sdr::overlay::OverlayObjectList; |
| mpOOAutoFill->append(*pOverlay); |
| } |
| |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aOldMode ); |
| } |
| } |
| |
| void ScGridWindow::DeleteDragRectOverlay() |
| { |
| DELETEZ( mpOODragRect ); |
| } |
| |
| void ScGridWindow::UpdateDragRectOverlay() |
| { |
| MapMode aDrawMode = GetDrawMapMode(); |
| MapMode aOldMode = GetMapMode(); |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aDrawMode ); |
| |
| DeleteDragRectOverlay(); |
| |
| // |
| // get the rectangles in pixels (moved from DrawDragRect) |
| // |
| |
| if ( bDragRect || bPagebreakDrawn ) |
| { |
| std::vector<Rectangle> aPixelRects; |
| |
| SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col(); |
| SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row(); |
| SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col(); |
| SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row(); |
| |
| SCTAB nTab = pViewData->GetTabNo(); |
| |
| SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich)); |
| SCROW nPosY = pViewData->GetPosY(WhichV(eWhich)); |
| if (nX1 < nPosX) nX1 = nPosX; |
| if (nX2 < nPosX) nX2 = nPosX; |
| if (nY1 < nPosY) nY1 = nPosY; |
| if (nY2 < nPosY) nY2 = nPosY; |
| |
| Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) ); |
| |
| long nSizeXPix=0; |
| long nSizeYPix=0; |
| ScDocument* pDoc = pViewData->GetDocument(); |
| double nPPTX = pViewData->GetPPTX(); |
| double nPPTY = pViewData->GetPPTY(); |
| SCCOLROW i; |
| |
| sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); |
| long nLayoutSign = bLayoutRTL ? -1 : 1; |
| |
| if (ValidCol(nX2) && nX2>=nX1) |
| for (i=nX1; i<=nX2; i++) |
| nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX ); |
| else |
| { |
| aScrPos.X() -= nLayoutSign; |
| nSizeXPix += 2; |
| } |
| |
| if (ValidRow(nY2) && nY2>=nY1) |
| for (i=nY1; i<=nY2; i++) |
| nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY ); |
| else |
| { |
| aScrPos.Y() -= 1; |
| nSizeYPix += 2; |
| } |
| |
| aScrPos.X() -= 2 * nLayoutSign; |
| aScrPos.Y() -= 2; |
| // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); |
| Rectangle aRect( aScrPos.X(), aScrPos.Y(), |
| aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 ); |
| if ( bLayoutRTL ) |
| { |
| aRect.Left() = aRect.Right(); // end position is left |
| aRect.Right() = aScrPos.X(); |
| } |
| |
| if ( meDragInsertMode == INS_CELLSDOWN ) |
| { |
| aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) ); |
| aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) ); |
| aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) ); |
| aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) ); |
| } |
| else if ( meDragInsertMode == INS_CELLSRIGHT ) |
| { |
| aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) ); |
| aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) ); |
| aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) ); |
| aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) ); |
| } |
| else |
| { |
| aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) ); |
| aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) ); |
| aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) ); |
| aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) ); |
| } |
| |
| // #i70788# get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); |
| |
| if(pOverlayManager) |
| { |
| // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); |
| std::vector< basegfx::B2DRange > aRanges; |
| const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); |
| |
| for(sal_uInt32 a(0); a < aPixelRects.size(); a++) |
| { |
| const Rectangle aRA(aPixelRects[a]); |
| basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); |
| aRB.transform(aTransform); |
| aRanges.push_back(aRB); |
| } |
| |
| sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( |
| sdr::overlay::OVERLAY_INVERT, |
| Color(COL_BLACK), |
| aRanges, |
| false); |
| |
| pOverlayManager->add(*pOverlay); |
| mpOODragRect = new ::sdr::overlay::OverlayObjectList; |
| mpOODragRect->append(*pOverlay); |
| } |
| } |
| |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aOldMode ); |
| } |
| |
| void ScGridWindow::DeleteHeaderOverlay() |
| { |
| DELETEZ( mpOOHeader ); |
| } |
| |
| void ScGridWindow::UpdateHeaderOverlay() |
| { |
| MapMode aDrawMode = GetDrawMapMode(); |
| MapMode aOldMode = GetMapMode(); |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aDrawMode ); |
| |
| DeleteHeaderOverlay(); |
| |
| // Pixel rectangle is in aInvertRect |
| if ( !aInvertRect.IsEmpty() ) |
| { |
| // #i70788# get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); |
| |
| if(pOverlayManager) |
| { |
| // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); |
| std::vector< basegfx::B2DRange > aRanges; |
| const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); |
| basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1); |
| |
| aRB.transform(aTransform); |
| aRanges.push_back(aRB); |
| |
| sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( |
| sdr::overlay::OVERLAY_INVERT, |
| Color(COL_BLACK), |
| aRanges, |
| false); |
| |
| pOverlayManager->add(*pOverlay); |
| mpOOHeader = new ::sdr::overlay::OverlayObjectList; |
| mpOOHeader->append(*pOverlay); |
| } |
| } |
| |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aOldMode ); |
| } |
| |
| void ScGridWindow::DeleteShrinkOverlay() |
| { |
| DELETEZ( mpOOShrink ); |
| } |
| |
| void ScGridWindow::UpdateShrinkOverlay() |
| { |
| MapMode aDrawMode = GetDrawMapMode(); |
| MapMode aOldMode = GetMapMode(); |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aDrawMode ); |
| |
| DeleteShrinkOverlay(); |
| |
| // |
| // get the rectangle in pixels |
| // |
| |
| Rectangle aPixRect; |
| ScRange aRange; |
| SCTAB nTab = pViewData->GetTabNo(); |
| if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() && |
| pViewData->GetDelMark( aRange ) ) |
| { |
| //! limit to visible area |
| if ( aRange.aStart.Col() <= aRange.aEnd.Col() && |
| aRange.aStart.Row() <= aRange.aEnd.Row() ) |
| { |
| Point aStart = pViewData->GetScrPos( aRange.aStart.Col(), |
| aRange.aStart.Row(), eWhich ); |
| Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1, |
| aRange.aEnd.Row()+1, eWhich ); |
| aEnd.X() -= 1; |
| aEnd.Y() -= 1; |
| |
| aPixRect = Rectangle( aStart,aEnd ); |
| } |
| } |
| |
| if ( !aPixRect.IsEmpty() ) |
| { |
| // #i70788# get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); |
| |
| if(pOverlayManager) |
| { |
| // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor(); |
| std::vector< basegfx::B2DRange > aRanges; |
| const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); |
| basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1); |
| |
| aRB.transform(aTransform); |
| aRanges.push_back(aRB); |
| |
| sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( |
| sdr::overlay::OVERLAY_INVERT, |
| Color(COL_BLACK), |
| aRanges, |
| false); |
| |
| pOverlayManager->add(*pOverlay); |
| mpOOShrink = new ::sdr::overlay::OverlayObjectList; |
| mpOOShrink->append(*pOverlay); |
| } |
| } |
| |
| if ( aOldMode != aDrawMode ) |
| SetMapMode( aOldMode ); |
| } |
| |
| // #i70788# central method to get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager() |
| { |
| SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView(); |
| |
| if(pPV) |
| { |
| SdrPageWindow* pPageWin = pPV->FindPageWindow( *this ); |
| |
| if ( pPageWin ) |
| { |
| return (pPageWin->GetOverlayManager()); |
| } |
| } |
| |
| return 0L; |
| } |
| |
| void ScGridWindow::flushOverlayManager() |
| { |
| // #i70788# get the OverlayManager safely |
| ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); |
| |
| if(pOverlayManager) |
| { |
| pOverlayManager->flush(); |
| } |
| } |
| |
| // --------------------------------------------------------------------------- |
| // eof |