Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/source/uibase/docvw/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 16 kB image not shown  

Quellcode-Bibliothek edtdd.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */


#include <svx/svdview.hxx>
#include <editeng/outliner.hxx>
#include <svx/svdobj.hxx>
#include <sot/exchange.hxx>
#include <sot/formats.hxx>
#include <sfx2/bindings.hxx>
#include <vcl/commandevent.hxx>
#include <osl/diagnose.h>

#include <sfx2/viewfrm.hxx>
#include <fmturl.hxx>
#include <frmfmt.hxx>
#include <wrtsh.hxx>
#include <edtdd.hxx>
#include <edtwin.hxx>
#include <view.hxx>
#include <viewopt.hxx>
#include <swdtflvr.hxx>
#include <swmodule.hxx>
#include <docsh.hxx>
#include <wdocsh.hxx>

using namespace ::com::sun::star;

// no include "dbgoutsw.hxx" here!!!!!!

bool g_bExecuteDrag = false;

void SwEditWin::StartDDTimer()
{
    m_aTimer.SetInvokeHandler(LINK(this, SwEditWin, DDHandler));
    m_aTimer.SetTimeout(480);
    m_aTimer.Start();
    g_bDDTimerStarted = true;
}

void SwEditWin::StopDDTimer(SwWrtShell *pSh, const Point &rPt)
{
    m_aTimer.Stop();
    g_bDDTimerStarted = false;
    if(!pSh->IsSelFrameMode())
        pSh->CallSetCursor(&rPt, false);
    m_aTimer.SetInvokeHandler(LINK(this,SwEditWin, TimerHandler));
}

void SwEditWin::StartDrag( sal_Int8 /*nAction*/, const Point& rPosPixel )
{
    if (m_rView.GetObjectShell()->isContentExtractionLocked())
        return;

    SwWrtShell &rSh = m_rView.GetWrtShell();
    if( rSh.GetDrawView() )
    {
        CommandEvent aDragEvent( rPosPixel, CommandEventId::StartDrag, true );
        if( rSh.GetDrawView()->Command( aDragEvent, this ) )
        {
            m_rView.GetViewFrame().GetBindings().InvalidateAll(false);
            return// Event evaluated by SdrView
        }
    }

    if ( m_pApplyTempl || rSh.IsDrawCreate() || IsDrawAction())
        return;

    bool bStart = false, bDelSelect = false;
    SdrObject *pObj = nullptr;
    Point aDocPos( PixelToLogic( rPosPixel ) );
    const bool bInSelect = rSh.IsInSelect();
    if (!bInSelect && rSh.TestCurrPam(aDocPos, true))
        //We are not selecting and aren't at a selection
        bStart = true;
    else if ( !g_bFrameDrag && rSh.IsSelFrameMode() &&
                rSh.IsInsideSelectedObj( aDocPos ) &&
                nullptr == m_pAnchorMarker)
    {
        //We are not dragging internally and are not at an
        //object (frame, draw object)

        // #i106131# *and* AnchorDrag is *not* active: When active,
        // entering global drag mode will destroy the AnchorHdl but
        // keep the now invalid ptr in place, next access will crash.
        // It is indeed wrong to enter drag mode when AnchorDrag is
        // already active
        bStart = true;
    }
    else if( !g_bFrameDrag && m_rView.GetDocShell()->IsReadOnly() &&
            OBJCNT_NONE != rSh.GetObjCntType( aDocPos, pObj ))
    {
        rSh.LockPaint(LockPaintReason::StartDrag);
        if( rSh.SelectObj( aDocPos, 0, pObj ))
            bStart = bDelSelect = true;
        else
            rSh.UnlockPaint();
    }
    else if (!bInSelect)// tdf#116384 only drag hyperlink if user's not currently setting the selection
    {
        SwContentAtPos aSwContentAtPos( IsAttrAtPos::InetAttr );
        bStart = rSh.GetContentAtPos( aDocPos,
                    aSwContentAtPos );
    }

    if ( !bStart || m_bIsInDrag )
        return;

    // If the add selection mode has been pushed in the MouseButtonDown handler it needs to be
    // popped or it will remain active and noticeable in the statusbar selection control until the
    // next MouseButtonUp event after the DnD, since a MouseButtonUp event is not received by the
    // edit window when DnD is done.
    if (g_bModePushed)
    {
        rSh.PopMode();
        g_bModePushed = false;
    }

    m_bMBPressed = false;
    ReleaseMouse();
    g_bFrameDrag = false;
    g_bExecuteDrag = true;
    SwEditWin::s_nDDStartPosY = aDocPos.Y();
    SwEditWin::s_nDDStartPosX = aDocPos.X();
    m_aMovePos = aDocPos;
    StartExecuteDrag();
    if( bDelSelect )
    {
        rSh.UnSelectFrame();
        rSh.UnlockPaint();
    }
}

void SwEditWin::StartExecuteDrag()
{
    if( !g_bExecuteDrag || m_bIsInDrag )
        return;

    m_bIsInDrag = true;

    rtl::Reference<SwTransferable> pTransfer = new SwTransferable( m_rView.GetWrtShell() );

    pTransfer->StartDrag( this, m_aMovePos );
}

void SwEditWin::DragFinished()
{
    DropCleanup();
    m_aTimer.SetInvokeHandler( LINK(this,SwEditWin, TimerHandler) );
    m_bIsInDrag = false;
}

void SwEditWin::DropCleanup()
{
    SwWrtShell &rSh =  m_rView.GetWrtShell();

    // reset statuses
    g_bNoInterrupt = false;
    if ( m_bOldIdleSet )
    {
        rSh.GetViewOptions()->SetIdle( m_bOldIdle );
        m_bOldIdleSet = false;
    }
    if ( m_pUserMarker )
        CleanupDropUserMarker();
    else
        rSh.UnSetVisibleCursor();

}

void SwEditWin::CleanupDropUserMarker()
{
    if ( m_pUserMarker )
    {
        m_pUserMarker.reset();
        m_pUserMarkerObj = nullptr;
    }
}

//exhibition hack (MA,MBA)
void SwView::SelectShellForDrop()
{
    if ( !GetCurShell() )
        SelectShell();
}

sal_Int8 SwEditWin::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
    GetView().SelectShellForDrop();
    DropCleanup();
    sal_Int8 nRet = DND_ACTION_NONE;

    //A Drop to an open OutlinerView doesn't concern us (also see QueryDrop)
    SwWrtShell &rSh = m_rView.GetWrtShell();
    const Point aDocPt( PixelToLogic( rEvt.maPosPixel ));
    SdrObject *pObj = nullptr;
    OutlinerView* pOLV;
    rSh.GetObjCntType( aDocPt, pObj );

    if( pObj && nullptr != ( pOLV = rSh.GetDrawView()->GetTextEditOutlinerView() ))
    {
        tools::Rectangle aRect( pOLV->GetOutputArea() );
        aRect.Union( pObj->GetLogicRect() );
        const Point aPos = pOLV->GetWindow()->PixelToLogic(rEvt.maPosPixel);
        if ( aRect.Contains(aPos) )
        {
            rSh.StartAllAction();
            rSh.EndAllAction();
            return nRet;
        }
    }

    // There's a special treatment for file lists with a single
    // element, that depends on the actual content of the
    // Transferable to be accessible. Since the transferable
    // may only be accessed after the drop has been accepted
    // (according to KA due to Java D&D), we'll have to
    // reevaluate the drop action once more _with_ the
    // Transferable.
    sal_uInt8 nEventAction;
    sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT
                                       : rEvt.mnAction;
    SotExchangeActionFlags nActionFlags;
    m_nDropAction = SotExchange::GetExchangeAction(
                                GetDataFlavorExVector(),
                                m_nDropDestination,
                                rEvt.mnAction,
                                nUserOpt, m_nDropFormat, nEventAction, SotClipboardFormatId::NONE,
                                &rEvt.maDropEvent.Transferable,
                                &nActionFlags );

    TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
    nRet = rEvt.mnAction;
    if( !SwTransferable::PasteData( aData, rSh, m_nDropAction, nActionFlags, m_nDropFormat,
                                m_nDropDestination, false, rEvt.mbDefault, &aDocPt, nRet))
        nRet = DND_ACTION_NONE;
    else if (SwModule* mod = SwModule::get(); mod->m_pDragDrop)
        //Don't clean up anymore at internal D&D!
        mod->m_pDragDrop->SetCleanUp(false);

    return nRet;
}

SotExchangeDest SwEditWin::GetDropDestination( const Point& rPixPnt, SdrObject ** ppObj )
{
    SwWrtShell &rSh = m_rView.GetWrtShell();
    const Point aDocPt( PixelToLogic( rPixPnt ) );
    if (rSh.IsOverReadOnlyPos(aDocPt) || rSh.DocPtInsideInputField(aDocPt))
        return SotExchangeDest::NONE;

    SdrObject *pObj = nullptr;
    const ObjCntType eType = rSh.GetObjCntType( aDocPt, pObj );

    //Drop to OutlinerView (TextEdit in Drawing) should decide it on its own!
    if( pObj )
    {
        OutlinerView* pOLV = rSh.GetDrawView()->GetTextEditOutlinerView();
        if ( pOLV )
        {
            tools::Rectangle aRect( pOLV->GetOutputArea() );
            aRect.Union( pObj->GetLogicRect() );
            const Point aPos = pOLV->GetWindow()->PixelToLogic( rPixPnt );
            if( aRect.Contains( aPos ) )
                return SotExchangeDest::NONE;
        }
    }

    //What do we want to drop on now?
    SotExchangeDest nDropDestination = SotExchangeDest::NONE;

    //Did anything else arrive from the DrawingEngine?
    if( OBJCNT_NONE != eType )
    {
        switch ( eType )
        {
        case OBJCNT_GRF:
            {
                bool bLink,
                    bIMap = nullptr != rSh.GetFormatFromObj( aDocPt )->GetURL().GetMap();
                OUString aDummy;
                rSh.GetGrfAtPos( aDocPt, aDummy, bLink );
                if ( bLink && bIMap )
                    nDropDestination = SotExchangeDest::DOC_LNKD_GRAPH_W_IMAP;
                else if ( bLink )
                    nDropDestination = SotExchangeDest::DOC_LNKD_GRAPHOBJ;
                else if ( bIMap )
                    nDropDestination = SotExchangeDest::DOC_GRAPH_W_IMAP;
                else
                    nDropDestination = SotExchangeDest::DOC_GRAPHOBJ;
            }
            break;
        case OBJCNT_FLY:
            ifdynamic_castconst SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr  )
                nDropDestination = SotExchangeDest::DOC_TEXTFRAME_WEB;
            else
                nDropDestination = SotExchangeDest::DOC_TEXTFRAME;
            break;
        case OBJCNT_OLE:        nDropDestination = SotExchangeDest::DOC_OLEOBJ; break;
        case OBJCNT_CONTROL:    /* no Action avail */
        case OBJCNT_SIMPLE:     nDropDestination = SotExchangeDest::DOC_DRAWOBJ; break;
        case OBJCNT_URLBUTTON:  nDropDestination = SotExchangeDest::DOC_URLBUTTON; break;
        case OBJCNT_GROUPOBJ:   nDropDestination = SotExchangeDest::DOC_GROUPOBJ;     break;

        default: OSL_ENSURE( false"new ObjectType?" );
        }
    }
    if ( nDropDestination == SotExchangeDest::NONE )
    {
        ifdynamic_castconst SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr  )
            nDropDestination = SotExchangeDest::SWDOC_FREE_AREA_WEB;
        else
            nDropDestination = SotExchangeDest::SWDOC_FREE_AREA;
    }
    if( ppObj )
        *ppObj = pObj;
    return nDropDestination;
}

sal_Int8 SwEditWin::AcceptDrop( const AcceptDropEvent& rEvt )
{
    if( rEvt.mbLeaving )
    {
        DropCleanup();
        return rEvt.mnAction;
    }

    if( m_rView.GetDocShell()->IsReadOnly() )
        return DND_ACTION_NONE;

    SwWrtShell &rSh = m_rView.GetWrtShell();

    Point aPixPt( rEvt.maPosPixel );

    // If the cursor is near the inner boundary
    // we attempt to scroll towards the desired direction.
    tools::Rectangle aWin(Point(), GetOutputSizePixel());
    const int nMargin = 10;
    aWin.AdjustLeft(nMargin );
    aWin.AdjustTop(nMargin );
    aWin.AdjustRight( -nMargin );
    aWin.AdjustBottom( -nMargin );
    if(!aWin.Contains(aPixPt)) {
        static sal_uInt64 last_tick = 0;
        sal_uInt64 current_tick = tools::Time::GetSystemTicks();
        if((current_tick-last_tick) > 500) {
            last_tick = current_tick;
            if(!m_bOldIdleSet) {
                m_bOldIdle = rSh.GetViewOptions()->IsIdle();
                rSh.GetViewOptions()->SetIdle(false);
                m_bOldIdleSet = true;
            }
            CleanupDropUserMarker();
            if(aPixPt.X() > aWin.Right()) aPixPt.AdjustX(nMargin );
            if(aPixPt.X() < aWin.Left()) aPixPt.AdjustX( -nMargin );
            if(aPixPt.Y() > aWin.Bottom()) aPixPt.AdjustY(nMargin );
            if(aPixPt.Y() < aWin.Top()) aPixPt.AdjustY( -nMargin );
            Point aDocPt(PixelToLogic(aPixPt));
            SwRect rect(aDocPt,Size(1,1));
            rSh.MakeVisible(rect, ScrollSizeMode::ScrollSizeTimer2);
        }
    }

    if(m_bOldIdleSet) {
        rSh.GetViewOptions()->SetIdle( m_bOldIdle );
        m_bOldIdleSet = false;
    }

    SdrObject *pObj = nullptr;
    m_nDropDestination = GetDropDestination( aPixPt, &pObj );
    if( m_nDropDestination == SotExchangeDest::NONE )
        return DND_ACTION_NONE;

    sal_uInt8 nEventAction;
    sal_Int8 nUserOpt = rEvt.mbDefault ? EXCHG_IN_ACTION_DEFAULT
                                       : rEvt.mnAction;

    m_nDropAction = SotExchange::GetExchangeAction(
                                GetDataFlavorExVector(),
                                m_nDropDestination,
                                rEvt.mnAction,
                                nUserOpt, m_nDropFormat, nEventAction );

    if( EXCHG_INOUT_ACTION_NONE != m_nDropAction )
    {
        const Point aDocPt( PixelToLogic( aPixPt ) );

        //With the default action we still want to have a say.
        SwModule* pMod = SwModule::get();
        if( pMod->m_pDragDrop )
        {
            bool bCleanup = false;
            //Drawing objects in Headers/Footers are not allowed

            SwWrtShell *pSrcSh = pMod->m_pDragDrop->GetShell();
            if( (pSrcSh->GetSelFrameType() == FrameTypeFlags::DRAWOBJ) &&
                pSrcSh->IsSelContainsControl() &&
                 (rSh.GetFrameType( &aDocPt, false ) & (FrameTypeFlags::HEADER|FrameTypeFlags::FOOTER)) )
            {
                bCleanup = true;
            }
            // don't more position protected objects!
            else if( DND_ACTION_MOVE == rEvt.mnAction &&
                     pSrcSh->IsSelObjProtected( FlyProtectFlags::Pos ) != FlyProtectFlags::NONE )
            {
                bCleanup = true;
            }
            else if( rEvt.mbDefault )
            {
                // internal Drag&Drop: within same Doc a Move
                // otherwise a Copy - Task 54974
                nEventAction = pSrcSh->GetDoc() == rSh.GetDoc()
                                    ? DND_ACTION_MOVE
                                    : DND_ACTION_COPY;
            }
            if ( bCleanup )
            {
                CleanupDropUserMarker();
                rSh.UnSetVisibleCursor();
                return DND_ACTION_NONE;
            }
        }
        else
        {
            //D&D from outside of SW should be a Copy per default.
            if( EXCHG_IN_ACTION_DEFAULT == nEventAction &&
                DND_ACTION_MOVE == rEvt.mnAction )
                nEventAction = DND_ACTION_COPY;

            if( (SotClipboardFormatId::SBA_FIELDDATAEXCHANGE == m_nDropFormat &&
                 EXCHG_IN_ACTION_LINK == m_nDropAction) ||
                 SotClipboardFormatId::SBA_CTRLDATAEXCHANGE == m_nDropFormat  )
            {
                SdrMarkView* pMView = rSh.GetDrawView();
                if( pMView && !pMView->IsDesignMode() )
                    return DND_ACTION_NONE;
            }
        }

        if ( EXCHG_IN_ACTION_DEFAULT != nEventAction )
            nUserOpt = static_cast<sal_Int8>(nEventAction);

        // show DropCursor or UserMarker ?
        if( SotExchangeDest::SWDOC_FREE_AREA_WEB == m_nDropDestination ||
            SotExchangeDest::SWDOC_FREE_AREA == m_nDropDestination )
        {
            CleanupDropUserMarker();
            SwContentAtPos aCont( IsAttrAtPos::ContentCheck );
            if(rSh.GetContentAtPos(aDocPt, aCont))
                rSh.SwCursorShell::SetVisibleCursor( aDocPt, ScrollSizeMode::ScrollSizeMouseSelection );
        }
        else
        {
            rSh.UnSetVisibleCursor();

            if ( m_pUserMarkerObj != pObj )
            {
                CleanupDropUserMarker();
                m_pUserMarkerObj = pObj;

                if(m_pUserMarkerObj)
                {
                    m_pUserMarker.reset(new SdrDropMarkerOverlay( *rSh.GetDrawView(), *m_pUserMarkerObj ));
                }
            }
        }
        return nUserOpt;
    }

    CleanupDropUserMarker();
    rSh.UnSetVisibleCursor();
    return DND_ACTION_NONE;
}

IMPL_LINK_NOARG(SwEditWin, DDHandler, Timer *, void)
{
    g_bDDTimerStarted = false;
    m_aTimer.Stop();
    m_aTimer.SetTimeout(240);
    m_bMBPressed = false;
    ReleaseMouse();
    g_bFrameDrag = false;
    g_bExecuteDrag = true;
    StartExecuteDrag();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=93 H=98 G=95

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.5Bemerkung:  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.