Coverage Report

Created: 2026-05-16 09:25

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