Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/svx/source/dialog/imapwnd.cxx
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <tools/urlobj.hxx>
21
#include <vcl/commandevent.hxx>
22
#include <vcl/imaprect.hxx>
23
#include <vcl/imapcirc.hxx>
24
#include <vcl/imappoly.hxx>
25
#include <vcl/svapp.hxx>
26
#include <svl/urlbmk.hxx>
27
28
#include <svx/svxids.hrc>
29
#include "imapwnd.hxx"
30
#include <svx/svdpage.hxx>
31
#include <svx/svdorect.hxx>
32
#include <svx/svdocirc.hxx>
33
#include <svx/svdopath.hxx>
34
#include <svx/xfltrit.hxx>
35
#include <svx/svdpagv.hxx>
36
#include <svx/xfillit0.hxx>
37
#include <svx/xflclit.hxx>
38
#include <svx/xlnclit.hxx>
39
40
#include <sfx2/evntconf.hxx>
41
42
#include <sot/formats.hxx>
43
44
#include <svx/svxdlg.hxx>
45
#include <basegfx/polygon/b2dpolygon.hxx>
46
#include <memory>
47
48
using namespace com::sun::star;
49
using ::com::sun::star::frame::XFrame;
50
using ::com::sun::star::uno::Reference;
51
52
0
#define TRANSCOL COL_WHITE
53
54
static ItemInfoPackage& getItemInfoPackageIMapWindow()
55
0
{
56
0
    class ItemInfoPackageIMapWindow : public ItemInfoPackage
57
0
    {
58
0
        typedef std::array<ItemInfoStatic, 1> ItemInfoArrayIMapWindow;
59
0
        ItemInfoArrayIMapWindow maItemInfos {{
60
            // m_nWhich, m_pItem, m_nSlotID, m_nItemInfoFlags
61
0
            { SID_ATTR_MACROITEM, new SvxMacroItem(SID_ATTR_MACROITEM), 0, SFX_ITEMINFOFLAG_NONE }
62
0
        }};
63
64
0
        virtual const ItemInfoStatic& getItemInfoStatic(size_t nIndex) const override { return maItemInfos[nIndex]; }
65
66
0
    public:
67
0
        virtual size_t size() const override { return maItemInfos.size(); }
68
0
        virtual const ItemInfo& getItemInfo(size_t nIndex, SfxItemPool& /*rPool*/) override { return maItemInfos[nIndex]; }
69
0
    };
70
71
0
    static std::unique_ptr<ItemInfoPackageIMapWindow> g_aItemInfoPackageIMapWindow;
72
0
    if (!g_aItemInfoPackageIMapWindow)
73
0
        g_aItemInfoPackageIMapWindow.reset(new ItemInfoPackageIMapWindow);
74
0
    return *g_aItemInfoPackageIMapWindow;
75
0
}
76
77
IMapWindow::IMapWindow(const Reference< XFrame >& rxDocumentFrame, weld::Dialog* pDialog)
78
0
    : GraphCtrl(pDialog)
79
0
    , mxDocumentFrame(rxDocumentFrame)
80
0
{
81
0
    pIMapPool = new SfxItemPool(u"IMapItemPool"_ustr);
82
0
    pIMapPool->registerItemInfoPackage(getItemInfoPackageIMapWindow());
83
0
}
84
85
IMapWindow::~IMapWindow()
86
0
{
87
0
}
88
89
void IMapWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
90
0
{
91
0
    weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
92
0
    Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(270, 170), MapMode(MapUnit::MapAppFont)));
93
0
    pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
94
0
    SetOutputSizePixel(aSize);
95
96
0
    SetSdrMode(true);
97
98
0
    mxDropTargetHelper.reset(new IMapDropTargetHelper(*this));
99
0
}
100
101
void IMapWindow::SetImageMap( const ImageMap& rImageMap )
102
0
{
103
0
    ReplaceImageMap( rImageMap );
104
0
}
105
106
void IMapWindow::ReplaceImageMap( const ImageMap& rImageMap )
107
0
{
108
0
    SdrPage* pPage = nullptr;
109
0
    aIMap = rImageMap;
110
111
0
    if(GetSdrModel())
112
0
    {
113
        // try to access page
114
0
        pPage = GetSdrModel()->GetPage(0);
115
0
    }
116
117
0
    if(pPage)
118
0
    {
119
        // clear SdrObjects with broadcasting
120
0
        pPage->ClearSdrObjList();
121
0
    }
122
123
0
    if(GetSdrView())
124
0
    {
125
        // #i63762# reset selection at view
126
0
        GetSdrView()->UnmarkAllObj();
127
0
    }
128
129
    // create new drawing objects
130
0
    const sal_uInt16 nCount(rImageMap.GetIMapObjectCount());
131
132
0
    for ( sal_uInt16 i(nCount); i > 0; i-- )
133
0
    {
134
0
        rtl::Reference<SdrObject> pNewObj = CreateObj( rImageMap.GetIMapObject( i - 1 ) );
135
136
0
        if (pNewObj && pPage)
137
0
        {
138
0
            pPage->InsertObject( pNewObj.get() );
139
0
        }
140
0
    }
141
0
}
142
143
void IMapWindow::ReplaceActualIMapInfo( const NotifyInfo& rNewInfo )
144
0
{
145
0
    const SdrObject*    pSdrObj = GetSelectedSdrObject();
146
147
0
    if ( pSdrObj )
148
0
    {
149
0
        IMapObject* pIMapObj = GetIMapObj( pSdrObj );
150
0
        if (pIMapObj)
151
0
        {
152
0
            pIMapObj->SetURL( rNewInfo.aMarkURL );
153
0
            pIMapObj->SetAltText( rNewInfo.aMarkAltText );
154
0
            pIMapObj->SetTarget( rNewInfo.aMarkTarget );
155
0
            pModel->SetChanged();
156
0
            UpdateInfo( false );
157
0
        }
158
0
    }
159
0
}
160
161
const ImageMap& IMapWindow::GetImageMap()
162
0
{
163
0
    if ( pModel->IsChanged() )
164
0
    {
165
0
        SdrPage* pPage = pModel->GetPage( 0 );
166
167
0
        if ( pPage )
168
0
        {
169
0
            const size_t nCount = pPage->GetObjCount();
170
171
0
            aIMap.ClearImageMap();
172
173
0
            for ( size_t i = nCount; i; )
174
0
            {
175
0
                --i;
176
0
                aIMap.InsertIMapObject( *( static_cast<IMapUserData*>( pPage->GetObj( i )->GetUserData( 0 ) )->GetObject() ) );
177
0
            }
178
0
        }
179
180
0
        pModel->SetChanged( false );
181
0
    }
182
183
0
    return aIMap;
184
0
}
185
186
void IMapWindow::SetTargetList( const TargetList& rTargetList )
187
0
{
188
    // Delete old List
189
    // Fill with the provided list
190
0
    aTargetList = rTargetList;
191
192
0
    pModel->SetChanged( false );
193
0
}
194
195
rtl::Reference<SdrObject> IMapWindow::CreateObj( const IMapObject* pIMapObj )
196
0
{
197
0
    tools::Rectangle   aClipRect( Point(), GetGraphicSize() );
198
0
    rtl::Reference<SdrObject> pSdrObj;
199
0
    IMapObjectPtr pCloneIMapObj;
200
201
0
    switch( pIMapObj->GetType() )
202
0
    {
203
0
        case IMapObjectType::Rectangle:
204
0
        {
205
0
            const IMapRectangleObject* pIMapRectObj = static_cast<const IMapRectangleObject*>(pIMapObj);
206
0
            tools::Rectangle               aDrawRect( pIMapRectObj->GetRectangle( false ) );
207
208
            // clipped on CanvasPane
209
0
            aDrawRect.Intersection( aClipRect );
210
211
0
            pSdrObj = new SdrRectObj(*pModel, aDrawRect);
212
0
            pCloneIMapObj.reset(static_cast<IMapObject*>(new IMapRectangleObject( *pIMapRectObj )));
213
0
        }
214
0
        break;
215
216
0
        case IMapObjectType::Circle:
217
0
        {
218
0
            const IMapCircleObject*   pIMapCircleObj = static_cast<const IMapCircleObject*>(pIMapObj);
219
0
            const Point         aCenter( pIMapCircleObj->GetCenter( false ) );
220
0
            const tools::Long          nRadius = pIMapCircleObj->GetRadius( false );
221
0
            const Point         aOffset( nRadius, nRadius );
222
0
            tools::Rectangle           aCircle( aCenter - aOffset, aCenter + aOffset );
223
224
            // limited to CanvasPane
225
0
            aCircle.Intersection( aClipRect );
226
227
0
            pSdrObj = new SdrCircObj(
228
0
                    *pModel,
229
0
                    SdrCircKind::Full,
230
0
                    aCircle,
231
0
                    0_deg100,
232
0
                    36000_deg100);
233
0
            pCloneIMapObj.reset(static_cast<IMapObject*>(new IMapCircleObject( *pIMapCircleObj )));
234
0
        }
235
0
        break;
236
237
0
        case IMapObjectType::Polygon:
238
0
        {
239
0
            const IMapPolygonObject*  pIMapPolyObj = static_cast<const IMapPolygonObject*>(pIMapObj);
240
241
            // If it actually is an ellipse, then another ellipse is created again
242
0
            if ( pIMapPolyObj->HasExtraEllipse() )
243
0
            {
244
0
                tools::Rectangle aDrawRect( pIMapPolyObj->GetExtraEllipse() );
245
246
                // clipped on CanvasPane
247
0
                aDrawRect.Intersection( aClipRect );
248
249
0
                pSdrObj = new SdrCircObj(
250
0
                        *pModel,
251
0
                        SdrCircKind::Full,
252
0
                        aDrawRect,
253
0
                        0_deg100,
254
0
                        36000_deg100);
255
0
            }
256
0
            else
257
0
            {
258
0
                const tools::Polygon aPoly = pIMapPolyObj->GetPolygon( false );
259
0
                tools::Polygon aDrawPoly( aPoly );
260
261
                // clipped on CanvasPane
262
0
                aDrawPoly.Clip( aClipRect );
263
264
0
                basegfx::B2DPolygon aPolygon;
265
0
                aPolygon.append(aDrawPoly.getB2DPolygon());
266
0
                pSdrObj = new SdrPathObj(
267
0
                        *pModel,
268
0
                        SdrObjKind::Polygon,
269
0
                        basegfx::B2DPolyPolygon(aPolygon));
270
0
            }
271
272
0
            pCloneIMapObj.reset(static_cast<IMapObject*>(new IMapPolygonObject( *pIMapPolyObj )));
273
0
        }
274
0
        break;
275
276
0
        default:
277
0
        break;
278
0
    }
279
280
0
    if ( pSdrObj )
281
0
    {
282
0
        SfxItemSet aSet( pModel->GetItemPool() );
283
284
0
        aSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
285
0
        aSet.Put( XFillColorItem( u""_ustr, TRANSCOL ) );
286
287
0
        if ( !pIMapObj->IsActive() )
288
0
        {
289
0
            aSet.Put( XFillTransparenceItem( 100 ) );
290
0
            aSet.Put( XLineColorItem( u""_ustr, COL_RED ) );
291
0
        }
292
0
        else
293
0
        {
294
0
            aSet.Put( XFillTransparenceItem( 50 ) );
295
0
            aSet.Put( XLineColorItem( u""_ustr, COL_BLACK ) );
296
0
        }
297
298
0
        pSdrObj->SetMergedItemSetAndBroadcast(aSet);
299
300
0
        pSdrObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new IMapUserData( std::move(pCloneIMapObj) )) );
301
0
        pSdrObj->SetUserCall( GetSdrUserCall() );
302
0
    }
303
304
0
    return pSdrObj;
305
0
}
306
307
void IMapWindow::InitSdrModel()
308
0
{
309
0
    GraphCtrl::InitSdrModel();
310
311
0
    SfxItemSet aSet( pModel->GetItemPool() );
312
313
0
    aSet.Put( XFillColorItem( u""_ustr, TRANSCOL ) );
314
0
    aSet.Put( XFillTransparenceItem( 50 ) );
315
0
    pView->SetAttributes( aSet );
316
0
    pView->SetFrameDragSingles();
317
0
}
318
319
void IMapWindow::SdrObjCreated( const SdrObject& rObj )
320
0
{
321
0
    switch( rObj.GetObjIdentifier() )
322
0
    {
323
0
        case SdrObjKind::Rectangle:
324
0
        {
325
0
            SdrRectObj*    pRectObj = const_cast<SdrRectObj*>(static_cast<const SdrRectObj*>(&rObj));
326
0
            auto pObj = std::make_shared<IMapRectangleObject>( pRectObj->GetLogicRect(), "", "", "", "", "", true, false );
327
328
0
            pRectObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new IMapUserData( pObj )) );
329
0
        }
330
0
        break;
331
332
0
        case SdrObjKind::CircleOrEllipse:
333
0
        {
334
0
            SdrCircObj* pCircObj = const_cast<SdrCircObj*>( static_cast<const SdrCircObj*>(&rObj) );
335
0
            rtl::Reference<SdrPathObj> pPathObj = static_cast<SdrPathObj*>( pCircObj->ConvertToPolyObj( false, false ).get() );
336
0
            tools::Polygon aPoly(pPathObj->GetPathPoly().getB2DPolygon(0));
337
338
0
            pPathObj.clear();
339
340
0
            auto pObj = std::make_shared<IMapPolygonObject>( aPoly, "", "", "", "", "", true, false );
341
0
            pObj->SetExtraEllipse( aPoly.GetBoundRect() );
342
0
            pCircObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new IMapUserData( pObj )) );
343
0
        }
344
0
        break;
345
346
0
        case SdrObjKind::Polygon:
347
0
        case SdrObjKind::FreehandFill:
348
0
        case SdrObjKind::PathPoly:
349
0
        case SdrObjKind::PathFill:
350
0
        {
351
0
            SdrPathObj* pPathObj = const_cast<SdrPathObj*>( static_cast<const SdrPathObj*>(&rObj) );
352
0
            const basegfx::B2DPolyPolygon& rXPolyPoly = pPathObj->GetPathPoly();
353
354
0
            if ( rXPolyPoly.count() )
355
0
            {
356
0
                tools::Polygon aPoly(rXPolyPoly.getB2DPolygon(0));
357
0
                auto pObj = std::make_shared<IMapPolygonObject>( aPoly, "", "", "", "", "", true, false );
358
0
                pPathObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new IMapUserData( pObj )) );
359
0
            }
360
0
        }
361
0
        break;
362
363
0
        default:
364
0
        break;
365
0
    }
366
0
}
367
368
void IMapWindow::SdrObjChanged( const SdrObject& rObj )
369
0
{
370
0
    IMapUserData* pUserData = static_cast<IMapUserData*>( rObj.GetUserData( 0 ) );
371
372
0
    if ( !pUserData )
373
0
        return;
374
375
0
    OUString        aURL;
376
0
    OUString        aAltText;
377
0
    OUString        aDesc;
378
0
    OUString        aTarget;
379
0
    IMapObjectPtr   pIMapObj = pUserData->GetObject();
380
0
    bool        bActive = true;
381
382
0
    if ( pIMapObj )
383
0
    {
384
0
        aURL = pIMapObj->GetURL();
385
0
        aAltText = pIMapObj->GetAltText();
386
0
        aDesc = pIMapObj->GetDesc();
387
0
        aTarget = pIMapObj->GetTarget();
388
0
        bActive = pIMapObj->IsActive();
389
0
    }
390
391
0
    switch( rObj.GetObjIdentifier() )
392
0
    {
393
0
        case SdrObjKind::Rectangle:
394
0
        {
395
0
            pUserData->ReplaceObject( std::make_shared<IMapRectangleObject>( static_cast<const SdrRectObj&>(rObj).GetLogicRect(),
396
0
                      aURL, aAltText, aDesc, aTarget, "", bActive, false ) );
397
0
        }
398
0
        break;
399
400
0
        case SdrObjKind::CircleOrEllipse:
401
0
        {
402
0
            const SdrCircObj& rCircObj = static_cast<const SdrCircObj&>(rObj);
403
0
            rtl::Reference<SdrPathObj> pPathObj = static_cast<SdrPathObj*>( rCircObj.ConvertToPolyObj( false, false ).get() );
404
0
            tools::Polygon aPoly(pPathObj->GetPathPoly().getB2DPolygon(0));
405
406
0
            auto pObj = std::make_shared<IMapPolygonObject>( aPoly, aURL, aAltText, aDesc, aTarget, "", bActive, false );
407
0
            pObj->SetExtraEllipse( aPoly.GetBoundRect() );
408
409
0
            pPathObj.clear();
410
411
0
            pUserData->ReplaceObject( pObj );
412
0
        }
413
0
        break;
414
415
0
        case SdrObjKind::Polygon:
416
0
        case SdrObjKind::FreehandFill:
417
0
        case SdrObjKind::PathPoly:
418
0
        case SdrObjKind::PathFill:
419
0
        {
420
0
            const SdrPathObj& rPathObj = static_cast<const SdrPathObj&>(rObj);
421
0
            const basegfx::B2DPolyPolygon& rXPolyPoly = rPathObj.GetPathPoly();
422
423
0
            if ( rXPolyPoly.count() )
424
0
            {
425
0
                tools::Polygon aPoly(rPathObj.GetPathPoly().getB2DPolygon(0));
426
0
                auto pObj = std::make_shared<IMapPolygonObject>( aPoly, aURL, aAltText, aDesc, aTarget, "", bActive, false );
427
0
                pUserData->ReplaceObject( pObj );
428
0
            }
429
0
        }
430
0
        break;
431
432
0
        default:
433
0
        break;
434
0
    }
435
0
}
436
437
bool IMapWindow::MouseButtonUp(const MouseEvent& rMEvt)
438
0
{
439
0
    bool bRet = GraphCtrl::MouseButtonUp( rMEvt );
440
0
    UpdateInfo( true );
441
0
    return bRet;
442
0
}
443
444
void IMapWindow::MarkListHasChanged()
445
0
{
446
0
    GraphCtrl::MarkListHasChanged();
447
0
    UpdateInfo( false );
448
0
}
449
450
SdrObject* IMapWindow::GetHitSdrObj( const Point& rPosPixel ) const
451
0
{
452
0
    OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
453
454
0
    SdrObject*  pObj = nullptr;
455
0
    Point       aPt = rDevice.PixelToLogic( rPosPixel );
456
457
0
    if ( tools::Rectangle( Point(), GetGraphicSize() ).Contains( aPt ) )
458
0
    {
459
0
        SdrPage* pPage = pModel->GetPage( 0 );
460
0
        if ( pPage )
461
0
        {
462
0
            for ( size_t i = pPage->GetObjCount(); i > 0; )
463
0
            {
464
0
                --i;
465
0
                SdrObject*  pTestObj = pPage->GetObj( i );
466
0
                IMapObject* pIMapObj = GetIMapObj( pTestObj );
467
468
0
                if ( pIMapObj && pIMapObj->IsHit( aPt ) )
469
0
                {
470
0
                    pObj = pTestObj;
471
0
                    break;
472
0
                }
473
0
            }
474
0
        }
475
0
    }
476
477
0
    return pObj;
478
0
}
479
480
IMapObject* IMapWindow::GetIMapObj( const SdrObject* pSdrObj )
481
0
{
482
0
    IMapObject* pIMapObj = nullptr;
483
484
0
    if ( pSdrObj )
485
0
    {
486
0
        IMapUserData* pUserData = static_cast<IMapUserData*>( pSdrObj->GetUserData( 0 ) );
487
488
0
        if ( pUserData )
489
0
            pIMapObj = pUserData->GetObject().get();
490
0
    }
491
492
0
    return pIMapObj;
493
0
}
494
495
bool IMapWindow::Command(const CommandEvent& rCEvt)
496
0
{
497
0
    if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
498
0
    {
499
0
        std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetDrawingArea(), u"svx/ui/imapmenu.ui"_ustr));
500
0
        mxPopupMenu = xBuilder->weld_menu(u"menu"_ustr);
501
0
        const SdrMarkList&  rMarkList = pView->GetMarkedObjectList();
502
0
        const size_t nMarked = rMarkList.GetMarkCount();
503
504
0
        mxPopupMenu->set_sensitive(u"url"_ustr, false);
505
0
        mxPopupMenu->set_sensitive(u"active"_ustr, false);
506
0
        mxPopupMenu->set_sensitive(u"macro"_ustr, false);
507
0
        mxPopupMenu->set_sensitive(u"selectall"_ustr, pModel->GetPage(0)->GetObjCount() != rMarkList.GetMarkCount());
508
509
0
        if ( !nMarked )
510
0
        {
511
0
            mxPopupMenu->set_sensitive(u"arrange"_ustr, false);
512
0
            mxPopupMenu->set_sensitive(u"delete"_ustr, false);
513
0
        }
514
0
        else
515
0
        {
516
0
            if ( nMarked == 1 )
517
0
            {
518
0
                SdrObject*  pSdrObj = GetSelectedSdrObject();
519
520
0
                mxPopupMenu->set_sensitive(u"url"_ustr, true);
521
0
                mxPopupMenu->set_sensitive(u"active"_ustr, true);
522
0
                mxPopupMenu->set_sensitive(u"macro"_ustr, true);
523
0
                mxPopupMenu->set_active(u"active"_ustr, GetIMapObj(pSdrObj)->IsActive());
524
0
            }
525
526
0
            mxPopupMenu->set_sensitive(u"arrange"_ustr, true);
527
0
            mxPopupMenu->set_sensitive(u"delete"_ustr, true);
528
0
        }
529
530
0
        MenuSelectHdl(mxPopupMenu->popup_at_rect(GetDrawingArea(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
531
532
0
        mxPopupMenu.reset();
533
534
0
        return true;
535
0
    }
536
0
    return CustomWidgetController::Command(rCEvt);
537
0
}
538
539
IMapDropTargetHelper::IMapDropTargetHelper(IMapWindow& rImapWindow)
540
0
    : DropTargetHelper(rImapWindow.GetDrawingArea()->get_drop_target())
541
0
    , m_rImapWindow(rImapWindow)
542
0
{
543
0
}
544
545
sal_Int8 IMapDropTargetHelper::AcceptDrop( const AcceptDropEvent& rEvt )
546
0
{
547
0
    return m_rImapWindow.AcceptDrop(rEvt);
548
0
}
549
550
sal_Int8 IMapDropTargetHelper::ExecuteDrop( const ExecuteDropEvent& rEvt )
551
0
{
552
0
    return m_rImapWindow.ExecuteDrop(rEvt);
553
0
}
554
555
sal_Int8 IMapWindow::AcceptDrop( const AcceptDropEvent& rEvt )
556
0
{
557
0
    return( ( GetHitSdrObj( rEvt.maPosPixel ) != nullptr ) ? rEvt.mnAction : DND_ACTION_NONE );
558
0
}
559
560
sal_Int8 IMapWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
561
0
{
562
0
    sal_Int8 nRet = DND_ACTION_NONE;
563
564
0
    if (mxDropTargetHelper->IsDropFormatSupported(SotClipboardFormatId::NETSCAPE_BOOKMARK))
565
0
    {
566
0
        INetBookmark    aBookMark( u""_ustr, u""_ustr );
567
0
        SdrObject*      pSdrObj = GetHitSdrObj( rEvt.maPosPixel );
568
569
0
        if( pSdrObj && TransferableDataHelper( rEvt.maDropEvent.Transferable ).GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aBookMark ) )
570
0
        {
571
0
            IMapObject* pIMapObj = GetIMapObj( pSdrObj );
572
573
0
            pIMapObj->SetURL( aBookMark.GetURL() );
574
0
            pIMapObj->SetAltText( aBookMark.GetDescription() );
575
0
            pModel->SetChanged();
576
0
            pView->UnmarkAll();
577
0
            pView->MarkObj( pSdrObj, pView->GetSdrPageView() );
578
0
            UpdateInfo( true );
579
0
            nRet =  rEvt.mnAction;
580
0
        }
581
0
    }
582
583
0
    return nRet;
584
0
}
585
586
OUString IMapWindow::RequestHelp(tools::Rectangle& rHelpArea)
587
0
{
588
0
    OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
589
590
0
    Point aPos = rDevice.PixelToLogic(rHelpArea.TopLeft());
591
592
0
    SdrPageView* pPageView = nullptr;
593
0
    SdrObject* pSdrObj = pView->PickObj(aPos, pView->getHitTolLog(), pPageView);
594
0
    if (pSdrObj)
595
0
    {
596
0
        const IMapObject*   pIMapObj = GetIMapObj( pSdrObj );
597
0
        if ( pIMapObj )
598
0
        {
599
0
            OUString aStr = pIMapObj->GetURL();
600
0
            if ( !aStr.isEmpty() )
601
0
            {
602
0
                rHelpArea = rDevice.LogicToPixel(tools::Rectangle( Point(), GetGraphicSize()));
603
0
                return aStr;
604
0
            }
605
0
        }
606
0
    }
607
608
0
    return OUString();
609
0
}
610
611
void IMapWindow::SetCurrentObjState( bool bActive )
612
0
{
613
0
    SdrObject* pObj = GetSelectedSdrObject();
614
615
0
    if ( !pObj )
616
0
        return;
617
618
0
    SfxItemSet aSet( pModel->GetItemPool() );
619
620
0
    GetIMapObj( pObj )->SetActive( bActive );
621
622
0
    aSet.Put( XFillColorItem( u""_ustr, TRANSCOL ) );
623
624
0
    if ( !bActive )
625
0
    {
626
0
        aSet.Put( XFillTransparenceItem( 100 ) );
627
0
        aSet.Put( XLineColorItem( u""_ustr, COL_RED ) );
628
0
    }
629
0
    else
630
0
    {
631
0
        aSet.Put( XFillTransparenceItem( 50 ) );
632
0
        aSet.Put( XLineColorItem( u""_ustr, COL_BLACK ) );
633
0
    }
634
635
0
    pView->SetAttributes( aSet );
636
0
}
637
638
void IMapWindow::UpdateInfo( bool bNewObj )
639
0
{
640
0
    if ( !aInfoLink.IsSet() )
641
0
        return;
642
643
0
    const SdrObject*    pSdrObj = GetSelectedSdrObject();
644
0
    const IMapObject*   pIMapObj = pSdrObj ? GetIMapObj( pSdrObj ) : nullptr;
645
646
0
    aInfo.bNewObj = bNewObj;
647
648
0
    if ( pIMapObj )
649
0
    {
650
0
        aInfo.bOneMarked = true;
651
0
        aInfo.aMarkURL = pIMapObj->GetURL();
652
0
        aInfo.aMarkAltText = pIMapObj->GetAltText();
653
0
        aInfo.aMarkTarget = pIMapObj->GetTarget();
654
0
        aInfo.bActivated = pIMapObj->IsActive();
655
0
        aInfoLink.Call( *this );
656
0
    }
657
0
    else
658
0
    {
659
0
        aInfo.aMarkURL.clear();
660
0
        aInfo.aMarkAltText.clear();
661
0
        aInfo.aMarkTarget.clear();
662
0
        aInfo.bOneMarked = false;
663
0
        aInfo.bActivated = false;
664
0
    }
665
666
0
    aInfoLink.Call( *this );
667
0
}
668
669
void IMapWindow::DoMacroAssign()
670
0
{
671
0
    SdrObject*  pSdrObj = GetSelectedSdrObject();
672
673
0
    if ( !pSdrObj )
674
0
        return;
675
676
0
    auto xSet = std::make_unique<SfxItemSetFixed<SID_ATTR_MACROITEM, SID_ATTR_MACROITEM, SID_EVENTCONFIG, SID_EVENTCONFIG>>
677
0
        (*pIMapPool);
678
679
0
    SfxEventNamesItem aNamesItem(SID_EVENTCONFIG);
680
0
    aNamesItem.AddEvent( u"MouseOver"_ustr, u""_ustr, SvMacroItemId::OnMouseOver );
681
0
    aNamesItem.AddEvent( u"MouseOut"_ustr, u""_ustr, SvMacroItemId::OnMouseOut );
682
0
    xSet->Put( aNamesItem );
683
684
0
    SvxMacroItem    aMacroItem(SID_ATTR_MACROITEM);
685
0
    IMapObject*     pIMapObj = GetIMapObj( pSdrObj );
686
0
    aMacroItem.SetMacroTable( pIMapObj->GetMacroTable() );
687
0
    xSet->Put( aMacroItem );
688
689
0
    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
690
0
    VclPtr<SfxAbstractDialog> pMacroDlg(pFact->CreateEventConfigDialog(GetDrawingArea(), std::move(xSet), mxDocumentFrame));
691
692
0
    pMacroDlg->StartExecuteAsync(
693
0
        [this, pMacroDlg, pIMapObj] (sal_Int32 nResult)->void
694
0
        {
695
0
            if (nResult == RET_OK)
696
0
            {
697
0
                const SfxItemSet* pOutSet = pMacroDlg->GetOutputItemSet();
698
0
                pIMapObj->SetMacroTable( pOutSet->Get( SID_ATTR_MACROITEM ).GetMacroTable() );
699
0
                pModel->SetChanged();
700
0
                UpdateInfo( false );
701
0
            }
702
0
            pMacroDlg->disposeOnce();
703
0
        }
704
0
    );
705
0
}
706
707
void IMapWindow::DoPropertyDialog()
708
0
{
709
0
    SdrObject*  pSdrObj = GetSelectedSdrObject();
710
711
0
    if ( !pSdrObj )
712
0
        return;
713
714
0
    IMapObject* pIMapObj = GetIMapObj( pSdrObj );
715
0
    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
716
0
    ScopedVclPtr<AbstractURLDlg> aDlg(pFact->CreateURLDialog(GetDrawingArea(), pIMapObj->GetURL(), pIMapObj->GetAltText(), pIMapObj->GetDesc(),
717
0
                                    pIMapObj->GetTarget(), pIMapObj->GetName(), aTargetList));
718
0
    if ( aDlg->Execute() != RET_OK )
719
0
        return;
720
721
0
    const OUString aURLText( aDlg->GetURL() );
722
723
0
    if ( !aURLText.isEmpty() )
724
0
    {
725
0
        INetURLObject aObj( aURLText, INetProtocol::File );
726
0
        DBG_ASSERT( aObj.GetProtocol() != INetProtocol::NotValid, "Invalid URL" );
727
0
        pIMapObj->SetURL( aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
728
0
    }
729
0
    else
730
0
        pIMapObj->SetURL( aURLText );
731
732
0
    pIMapObj->SetAltText( aDlg->GetAltText() );
733
0
    pIMapObj->SetDesc( aDlg->GetDesc() );
734
0
    pIMapObj->SetTarget( aDlg->GetTarget() );
735
0
    pIMapObj->SetName( aDlg->GetName() );
736
0
    pModel->SetChanged();
737
0
    UpdateInfo( true );
738
0
}
739
740
void IMapWindow::MenuSelectHdl(const OUString& rId)
741
0
{
742
0
    if (rId == "url")
743
0
        DoPropertyDialog();
744
0
    else if (rId == "macro")
745
0
        DoMacroAssign();
746
0
    else if (rId == "active")
747
0
    {
748
0
        const bool bNewState = !mxPopupMenu->get_active(rId);
749
0
        SetCurrentObjState(bNewState);
750
0
        UpdateInfo( false );
751
0
    }
752
0
    else if (rId == "front")
753
0
        pView->PutMarkedToTop();
754
0
    else if (rId == "forward")
755
0
        pView->MovMarkedToTop();
756
0
    else if (rId == "backward")
757
0
        pView->MovMarkedToBtm();
758
0
    else if (rId == "back")
759
0
        pView->PutMarkedToBtm();
760
0
    else if (rId == "selectall")
761
0
        pView->MarkAll();
762
0
    else if (rId == "delete")
763
0
        pView->DeleteMarked();
764
0
}
765
766
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */