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 <vcl/errinf.hxx>
21 #include <tools/urlobj.hxx>
22 #include <unotools/ucbstreamhelper.hxx>
23 #include <svl/eitem.hxx>
24 #include <unotools/pathoptions.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/module.hxx>
27 #include <sfx2/filedlghelper.hxx>
28 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
29 #include <svl/urihelper.hxx>
30 #include <svtools/ehdl.hxx>
31 #include <svtools/inettbc.hxx>
32 #include <svtools/sfxecode.hxx>
33 #include <sfx2/viewfrm.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <unotools/localedatawrapper.hxx>
37 #include <vcl/weld.hxx>
38 #include <svx/imapdlg.hxx>
39 #include <svx/dialmgr.hxx>
40 #include <svx/strings.hrc>
41 #include <svx/svxids.hrc>
42 #include "imapwnd.hxx"
43 #include "imapimp.hxx"
44 #include <svx/svdopath.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/settings.hxx>
47 #include <osl/diagnose.h>
48 #include "dlgunit.hxx"
49 #include <memory>
50 
51 #define SELF_TARGET         "_self"
52 #define IMAP_CERN_FILTER    "MAP - CERN"
53 #define IMAP_NCSA_FILTER    "MAP - NCSA"
54 #define IMAP_BINARY_FILTER  "SIP - StarView ImageMap"
55 #define IMAP_ALL_TYPE       "*.*"
56 #define IMAP_BINARY_TYPE    "*.sip"
57 #define IMAP_CERN_TYPE      "*.map"
58 #define IMAP_NCSA_TYPE      "*.map"
59 
60 SFX_IMPL_MODELESSDIALOGCONTOLLER_WITHID( SvxIMapDlgChildWindow, SID_IMAP );
61 
62 // ControllerItem
63 
SvxIMapDlgItem(SvxIMapDlg & rIMapDlg,SfxBindings & rBindings)64 SvxIMapDlgItem::SvxIMapDlgItem( SvxIMapDlg& rIMapDlg, SfxBindings& rBindings ) :
65             SfxControllerItem   ( SID_IMAP_EXEC, rBindings ),
66             rIMap               ( rIMapDlg )
67 {
68 }
69 
StateChanged(sal_uInt16 nSID,SfxItemState,const SfxPoolItem * pItem)70 void SvxIMapDlgItem::StateChanged( sal_uInt16 nSID, SfxItemState /*eState*/,
71                                    const SfxPoolItem* pItem )
72 {
73     if ( ( nSID == SID_IMAP_EXEC ) && pItem )
74     {
75         const SfxBoolItem* pStateItem = dynamic_cast<const SfxBoolItem*>( pItem  );
76         assert(pStateItem); //SfxBoolItem expected
77         if (pStateItem)
78         {
79             // Disable Float if possible
80             rIMap.SetExecState( !pStateItem->GetValue() );
81         }
82     }
83 }
84 
SvxIMapDlgChildWindow(vcl::Window * _pParent,sal_uInt16 nId,SfxBindings * pBindings,SfxChildWinInfo const * pInfo)85 SvxIMapDlgChildWindow::SvxIMapDlgChildWindow(vcl::Window* _pParent, sal_uInt16 nId,
86                                              SfxBindings* pBindings,
87                                              SfxChildWinInfo const * pInfo)
88     : SfxChildWindow( _pParent, nId )
89 {
90     SetController(std::make_shared<SvxIMapDlg>(pBindings, this, _pParent->GetFrameWeld()));
91     SvxIMapDlg* pDlg = static_cast<SvxIMapDlg*>(GetController().get());
92     pDlg->Initialize( pInfo );
93 }
94 
UpdateIMapDlg(const Graphic & rGraphic,const ImageMap * pImageMap,const TargetList * pTargetList,void * pEditingObj)95 void SvxIMapDlgChildWindow::UpdateIMapDlg( const Graphic& rGraphic, const ImageMap* pImageMap,
96                                            const TargetList* pTargetList, void* pEditingObj )
97 {
98     SvxIMapDlg* pDlg = GetIMapDlg();
99     if (pDlg)
100         pDlg->UpdateLink(rGraphic, pImageMap, pTargetList, pEditingObj);
101 }
102 
SvxIMapDlg(SfxBindings * _pBindings,SfxChildWindow * pCW,weld::Window * _pParent)103 SvxIMapDlg::SvxIMapDlg(SfxBindings *_pBindings, SfxChildWindow *pCW, weld::Window* _pParent)
104     : SfxModelessDialogController(_pBindings, pCW, _pParent, "svx/ui/imapdialog.ui", "ImapDialog")
105     , pCheckObj(nullptr)
106     , aIMapItem(*this, *_pBindings)
107     , m_xIMapWnd(new IMapWindow(_pBindings->GetActiveFrame(), m_xDialog.get()))
108     , m_xTbxIMapDlg1(m_xBuilder->weld_toolbar("toolbar"))
109     , m_xFtURL(m_xBuilder->weld_label("urlft"))
110     , m_xURLBox(new SvtURLBox(m_xBuilder->weld_combo_box("url")))
111     , m_xFtText(m_xBuilder->weld_label("textft"))
112     , m_xEdtText(m_xBuilder->weld_entry("text"))
113     , m_xFtTarget(m_xBuilder->weld_label("targetft"))
114     , m_xCbbTarget(m_xBuilder->weld_combo_box("target"))
115     , m_xCancelBtn(m_xBuilder->weld_button("cancel"))
116     , m_xStbStatus1(m_xBuilder->weld_label("statusurl"))
117     , m_xStbStatus2(m_xBuilder->weld_label("statuspos"))
118     , m_xStbStatus3(m_xBuilder->weld_label("statussize"))
119     , m_xIMapWndWeld(new weld::CustomWeld(*m_xBuilder, "container", *m_xIMapWnd))
120 
121 {
122     m_xTbxIMapDlg1->insert_separator(4, "sep1");
123     m_xTbxIMapDlg1->insert_separator(10, "sep2");
124     m_xTbxIMapDlg1->insert_separator(15, "sep3");
125     m_xTbxIMapDlg1->insert_separator(18, "sel4");
126 
127     //lock this down so it doesn't jump around in size
128     //as entries are added later on
129     TargetList aTmpList;
130     SfxFrame::GetDefaultTargetList(aTmpList);
131     for (const OUString & s : aTmpList)
132         m_xCbbTarget->append_text(s);
133     Size aPrefSize(m_xCbbTarget->get_preferred_size());
134     m_xCbbTarget->set_size_request(aPrefSize.Width(), -1);
135     m_xCbbTarget->clear();
136 
137     m_xIMapWnd->Show();
138 
139     pOwnData.reset(new IMapOwnData);
140 
141     m_xIMapWnd->SetInfoLink( LINK( this, SvxIMapDlg, InfoHdl ) );
142     m_xIMapWnd->SetMousePosLink( LINK( this, SvxIMapDlg, MousePosHdl ) );
143     m_xIMapWnd->SetGraphSizeLink( LINK( this, SvxIMapDlg, GraphSizeHdl ) );
144     m_xIMapWnd->SetUpdateLink( LINK( this, SvxIMapDlg, StateHdl ) );
145 
146     m_xURLBox->connect_changed( LINK( this, SvxIMapDlg, URLModifyHdl ) );
147     m_xURLBox->connect_focus_out( LINK( this, SvxIMapDlg, URLLoseFocusHdl ) );
148     m_xEdtText->connect_changed( LINK( this, SvxIMapDlg, EntryModifyHdl ) );
149     m_xCbbTarget->connect_focus_out( LINK( this, SvxIMapDlg, URLLoseFocusHdl ) );
150 
151     m_xTbxIMapDlg1->connect_clicked( LINK( this, SvxIMapDlg, TbxClickHdl ) );
152     OString sSelect("TBI_SELECT");
153     m_xTbxIMapDlg1->set_item_active(sSelect, true);
154     TbxClickHdl(sSelect);
155 
156     m_xStbStatus1->set_size_request(120, -1);
157     const int nWidth = m_xStbStatus1->get_pixel_size(" 9999,99 cm / 9999,99 cm ").Width();
158     m_xStbStatus2->set_size_request(nWidth, -1);
159     m_xStbStatus3->set_size_request(nWidth, -1);
160 
161     m_xFtURL->set_sensitive(false);
162     m_xURLBox->set_sensitive(false);
163     m_xFtText->set_sensitive(false);
164     m_xEdtText->set_sensitive(false);
165     m_xFtTarget->set_sensitive(false);
166     m_xCbbTarget->set_sensitive(false);
167     pOwnData->bExecState = false;
168 
169     pOwnData->aIdle.SetInvokeHandler( LINK( this, SvxIMapDlg, UpdateHdl ) );
170 
171     m_xTbxIMapDlg1->set_item_sensitive("TBI_ACTIVE", false);
172     m_xTbxIMapDlg1->set_item_sensitive("TBI_MACRO", false );
173     m_xTbxIMapDlg1->set_item_sensitive("TBI_PROPERTY", false );
174 
175     m_xCancelBtn->connect_clicked(LINK(this, SvxIMapDlg, CancelHdl));
176 }
177 
~SvxIMapDlg()178 SvxIMapDlg::~SvxIMapDlg()
179 {
180     m_xIMapWnd->SetUpdateLink( Link<GraphCtrl*,void>() );
181     m_xIMapWnd.reset();
182 }
183 
IMPL_LINK_NOARG(SvxIMapDlg,CancelHdl,weld::Button &,void)184 IMPL_LINK_NOARG(SvxIMapDlg, CancelHdl, weld::Button&, void)
185 {
186     bool bRet = true;
187 
188     if ( m_xTbxIMapDlg1->get_item_sensitive("TBI_APPLY") )
189     {
190         std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "svx/ui/querymodifyimagemapchangesdialog.ui"));
191         std::unique_ptr<weld::MessageDialog> xQBox(xBuilder->weld_message_dialog("QueryModifyImageMapChangesDialog"));
192         const tools::Long nRet = xQBox->run();
193 
194         if( nRet == RET_YES )
195         {
196             SfxBoolItem aBoolItem( SID_IMAP_EXEC, true );
197             GetBindings().GetDispatcher()->ExecuteList(SID_IMAP_EXEC,
198                 SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
199                 { &aBoolItem });
200         }
201         else if( nRet == RET_CANCEL )
202             bRet = false;
203     }
204     else if( m_xIMapWnd->IsChanged() )
205     {
206         std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "svx/ui/querysaveimagemapchangesdialog.ui"));
207         std::unique_ptr<weld::MessageDialog> xQBox(xBuilder->weld_message_dialog("QuerySaveImageMapChangesDialog"));
208         const tools::Long nRet = xQBox->run();
209 
210         if( nRet == RET_YES )
211             bRet = DoSave();
212         else if( nRet == RET_CANCEL )
213             bRet = false;
214     }
215 
216     if (bRet)
217         m_xDialog->response(RET_CANCEL);
218 }
219 
220 // Enabled or disable all Controls
221 
SetExecState(bool bEnable)222 void SvxIMapDlg::SetExecState( bool bEnable )
223 {
224     pOwnData->bExecState = bEnable;
225 }
226 
GetImageMap() const227 const ImageMap& SvxIMapDlg::GetImageMap() const
228 {
229     return m_xIMapWnd->GetImageMap();
230 }
231 
SetTargetList(const TargetList & rTargetList)232 void SvxIMapDlg::SetTargetList( const TargetList& rTargetList )
233 {
234     TargetList aNewList( rTargetList );
235 
236     m_xIMapWnd->SetTargetList( aNewList );
237 
238     m_xCbbTarget->clear();
239 
240     for (const OUString & s : aNewList)
241         m_xCbbTarget->append_text(s);
242 }
243 
UpdateLink(const Graphic & rGraphic,const ImageMap * pImageMap,const TargetList * pTargetList,void * pEditingObj)244 void SvxIMapDlg::UpdateLink( const Graphic& rGraphic, const ImageMap* pImageMap,
245                          const TargetList* pTargetList, void* pEditingObj )
246 {
247     pOwnData->aUpdateGraphic = rGraphic;
248 
249     if ( pImageMap )
250         pOwnData->aUpdateImageMap = *pImageMap;
251     else
252         pOwnData->aUpdateImageMap.ClearImageMap();
253 
254     pOwnData->pUpdateEditingObject = pEditingObj;
255 
256     // Delete UpdateTargetList, because this method can still be called several
257     // times before the update timer is turned on
258     pOwnData->aUpdateTargetList.clear();
259 
260     // TargetList must be copied, since it is owned by the caller and can be
261     // deleted immediately after this call the copied list will be deleted
262     // again in the handler
263     if( pTargetList )
264     {
265         TargetList aTargetList( *pTargetList );
266 
267         for (const OUString & s : aTargetList)
268             pOwnData->aUpdateTargetList.push_back( s );
269     }
270 
271     pOwnData->aIdle.Start();
272 }
273 
274 
275 // Click-handler for ToolBox
276 
IMPL_LINK(SvxIMapDlg,TbxClickHdl,const OString &,rNewItemId,void)277 IMPL_LINK(SvxIMapDlg, TbxClickHdl, const OString&, rNewItemId, void)
278 {
279     if (rNewItemId == "TBI_APPLY")
280     {
281         URLLoseFocusHdl(*m_xCbbTarget);
282         SfxBoolItem aBoolItem( SID_IMAP_EXEC, true );
283         GetBindings().GetDispatcher()->ExecuteList(SID_IMAP_EXEC,
284             SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
285             { &aBoolItem });
286     }
287     else if (rNewItemId == "TBI_OPEN")
288         DoOpen();
289     else if (rNewItemId == "TBI_SAVEAS")
290         DoSave();
291     else if (rNewItemId == "TBI_CLOSE")
292         CancelHdl(*m_xCancelBtn);
293     else if (rNewItemId == "TBI_SELECT")
294     {
295         SetActiveTool( rNewItemId );
296         m_xIMapWnd->SetEditMode( true );
297     }
298     else if (rNewItemId == "TBI_RECT")
299     {
300         SetActiveTool( rNewItemId );
301         m_xIMapWnd->SetObjKind( OBJ_RECT );
302     }
303     else if (rNewItemId == "TBI_CIRCLE")
304     {
305         SetActiveTool( rNewItemId );
306         m_xIMapWnd->SetObjKind( OBJ_CIRC );
307     }
308     else if (rNewItemId == "TBI_POLY")
309     {
310         SetActiveTool( rNewItemId );
311         m_xIMapWnd->SetObjKind( OBJ_POLY );
312     }
313     else if (rNewItemId == "TBI_FREEPOLY")
314     {
315         SetActiveTool( rNewItemId );
316         m_xIMapWnd->SetObjKind( OBJ_FREEFILL );
317     }
318     else if (rNewItemId == "TBI_ACTIVE")
319     {
320         URLLoseFocusHdl(*m_xCbbTarget);
321         bool bNewState = !m_xTbxIMapDlg1->get_item_active(rNewItemId);
322         m_xTbxIMapDlg1->set_item_active(rNewItemId, bNewState);
323         m_xIMapWnd->SetCurrentObjState( !bNewState );
324     }
325     else if (rNewItemId == "TBI_MACRO")
326         m_xIMapWnd->DoMacroAssign();
327     else if (rNewItemId == "TBI_PROPERTY")
328         m_xIMapWnd->DoPropertyDialog();
329     else if (rNewItemId == "TBI_POLYEDIT")
330     {
331         SetActiveTool( rNewItemId );
332         m_xIMapWnd->SetPolyEditMode( m_xTbxIMapDlg1->get_item_active(rNewItemId) ? SID_BEZIER_MOVE : 0 );
333     }
334     else if (rNewItemId == "TBI_POLYMOVE")
335     {
336         SetActiveTool( rNewItemId );
337         m_xIMapWnd->SetPolyEditMode( SID_BEZIER_MOVE );
338     }
339     else if (rNewItemId == "TBI_POLYINSERT")
340     {
341         SetActiveTool( rNewItemId );
342         m_xIMapWnd->SetPolyEditMode( SID_BEZIER_INSERT );
343     }
344     else if (rNewItemId == "TBI_POLYDELETE")
345     {
346         SetActiveTool( rNewItemId );
347         m_xIMapWnd->GetSdrView()->DeleteMarkedPoints();
348     }
349     else if (rNewItemId == "TBI_UNDO")
350     {
351         URLLoseFocusHdl(*m_xCbbTarget);
352         m_xIMapWnd->GetSdrModel()->Undo();
353     }
354     else if (rNewItemId == "TBI_REDO")
355     {
356         URLLoseFocusHdl(*m_xCbbTarget);
357         m_xIMapWnd->GetSdrModel()->Redo();
358     }
359 }
360 
DoOpen()361 void SvxIMapDlg::DoOpen()
362 {
363     ::sfx2::FileDialogHelper aDlg(
364         css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
365         FileDialogFlags::NONE, m_xDialog.get());
366 
367     ImageMap        aLoadIMap;
368     const OUString  aFilter(SvxResId(RID_SVXSTR_IMAP_ALL_FILTER));
369 
370     aDlg.AddFilter( aFilter, IMAP_ALL_TYPE );
371     aDlg.AddFilter( IMAP_CERN_FILTER, IMAP_CERN_TYPE );
372     aDlg.AddFilter( IMAP_NCSA_FILTER, IMAP_NCSA_TYPE );
373     aDlg.AddFilter( IMAP_BINARY_FILTER, IMAP_BINARY_TYPE );
374 
375     aDlg.SetCurrentFilter( aFilter );
376     aDlg.SetDisplayDirectory( SvtPathOptions().GetWorkPath() );
377 
378     if( aDlg.Execute() != ERRCODE_NONE )
379         return;
380 
381     INetURLObject aURL( aDlg.GetPath() );
382     DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
383     std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
384 
385     if( pIStm )
386     {
387         aLoadIMap.Read( *pIStm, IMapFormat::Detect );
388 
389         if( pIStm->GetError() )
390         {
391             SfxErrorContext eEC(ERRCTX_ERROR, m_xDialog.get());
392             ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
393         }
394         else
395             m_xIMapWnd->SetImageMap( aLoadIMap );
396     }
397 
398     m_xIMapWnd->Invalidate();
399 }
400 
DoSave()401 bool SvxIMapDlg::DoSave()
402 {
403     ::sfx2::FileDialogHelper aDlg(
404         css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE,
405         FileDialogFlags::NONE, m_xDialog.get());
406 
407     const OUString    aBinFilter( IMAP_BINARY_FILTER );
408     const OUString    aCERNFilter( IMAP_CERN_FILTER );
409     const OUString    aNCSAFilter( IMAP_NCSA_FILTER );
410     SdrModel*       pModel = m_xIMapWnd->GetSdrModel();
411     const bool bChanged = pModel->IsChanged();
412     bool            bRet = false;
413 
414     aDlg.AddFilter( aCERNFilter, IMAP_CERN_TYPE );
415     aDlg.AddFilter( aNCSAFilter, IMAP_NCSA_TYPE );
416     aDlg.AddFilter( aBinFilter, IMAP_BINARY_TYPE );
417 
418     aDlg.SetCurrentFilter( aCERNFilter );
419     aDlg.SetDisplayDirectory( SvtPathOptions().GetWorkPath() );
420 
421     if( aDlg.Execute() == ERRCODE_NONE )
422     {
423         const OUString    aFilter( aDlg.GetCurrentFilter() );
424         OUString          aExt;
425         IMapFormat        nFormat;
426 
427         if ( aFilter == aBinFilter )
428         {
429             nFormat = IMapFormat::Binary;
430             aExt = "sip";
431         }
432         else if ( aFilter == aCERNFilter )
433         {
434             nFormat = IMapFormat::CERN;
435             aExt = "map";
436         }
437         else if ( aFilter == aNCSAFilter )
438         {
439             nFormat = IMapFormat::NCSA;
440             aExt = "map";
441         }
442         else
443         {
444             return false;
445         }
446 
447         INetURLObject aURL( aDlg.GetPath() );
448 
449         if( aURL.GetProtocol() == INetProtocol::NotValid )
450         {
451             OSL_FAIL( "invalid URL" );
452         }
453         else
454         {
455             if( aURL.getExtension().isEmpty() )
456                 aURL.setExtension( aExt );
457 
458             std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ));
459             if( pOStm )
460             {
461                 m_xIMapWnd->GetImageMap().Write( *pOStm, nFormat );
462 
463                 if( pOStm->GetError() )
464                     ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
465 
466                 pOStm.reset();
467                 pModel->SetChanged( bChanged );
468                 bRet = true;
469             }
470         }
471     }
472 
473     return bRet;
474 }
475 
SetActiveTool(std::string_view rId)476 void SvxIMapDlg::SetActiveTool(std::string_view rId)
477 {
478     m_xTbxIMapDlg1->set_item_active("TBI_SELECT", rId == "TBI_SELECT");
479     m_xTbxIMapDlg1->set_item_active("TBI_RECT", rId == "TBI_RECT");
480     m_xTbxIMapDlg1->set_item_active("TBI_CIRCLE", rId == "TBI_CIRCLE");
481     m_xTbxIMapDlg1->set_item_active("TBI_POLY", rId == "TBI_POLY");
482     m_xTbxIMapDlg1->set_item_active("TBI_FREEPOLY", rId == "TBI_FREEPOLY");
483 
484     m_xTbxIMapDlg1->set_item_active("TBI_POLYINSERT", rId == "TBI_POLYINSERT");
485     m_xTbxIMapDlg1->set_item_active("TBI_POLYDELETE", false);
486 
487     bool bMove = rId == "TBI_POLYMOVE"
488                 || ( rId == "TBI_POLYEDIT"
489                 && !m_xTbxIMapDlg1->get_item_active("TBI_POLYINSERT")
490                 && !m_xTbxIMapDlg1->get_item_active("TBI_POLYDELETE") );
491 
492     m_xTbxIMapDlg1->set_item_active("TBI_POLYMOVE", bMove );
493 
494     bool bEditMode = ( rId == "TBI_POLYEDIT" )
495                     || ( rId == "TBI_POLYMOVE")
496                     || ( rId == "TBI_POLYINSERT")
497                     || ( rId == "TBI_POLYDELETE" );
498 
499     m_xTbxIMapDlg1->set_item_active("TBI_POLYEDIT", bEditMode);
500 }
501 
IMPL_LINK(SvxIMapDlg,InfoHdl,IMapWindow &,rWnd,void)502 IMPL_LINK( SvxIMapDlg, InfoHdl, IMapWindow&, rWnd, void )
503 {
504     const NotifyInfo&   rInfo = rWnd.GetInfo();
505 
506     if ( rInfo.bNewObj )
507     {
508         if (!rInfo.aMarkURL.isEmpty() && ( m_xURLBox->find_text(rInfo.aMarkURL) == -1))
509             m_xURLBox->append_text(rInfo.aMarkURL);
510 
511         m_xURLBox->set_entry_text(rInfo.aMarkURL);
512         m_xEdtText->set_text(rInfo.aMarkAltText);
513 
514         if ( rInfo.aMarkTarget.isEmpty() )
515             m_xCbbTarget->set_entry_text( SELF_TARGET );
516         else
517             m_xCbbTarget->set_entry_text( rInfo.aMarkTarget );
518     }
519 
520     if ( !rInfo.bOneMarked )
521     {
522         m_xTbxIMapDlg1->set_item_active("TBI_ACTIVE", false);
523         m_xTbxIMapDlg1->set_item_sensitive("TBI_ACTIVE", false);
524         m_xTbxIMapDlg1->set_item_sensitive("TBI_MACRO", false);
525         m_xTbxIMapDlg1->set_item_sensitive("TBI_PROPERTY", false);
526         m_xStbStatus1->set_label(OUString());
527 
528         m_xFtURL->set_sensitive(false);
529         m_xURLBox->set_sensitive(false);
530         m_xFtText->set_sensitive(false);
531         m_xEdtText->set_sensitive(false);
532         m_xFtTarget->set_sensitive(false);
533         m_xCbbTarget->set_sensitive(false);
534 
535         m_xURLBox->set_entry_text( "" );
536         m_xEdtText->set_text( "" );
537     }
538     else
539     {
540         m_xTbxIMapDlg1->set_item_sensitive("TBI_ACTIVE", true);
541         m_xTbxIMapDlg1->set_item_active("TBI_ACTIVE", !rInfo.bActivated );
542         m_xTbxIMapDlg1->set_item_sensitive("TBI_MACRO", true);
543         m_xTbxIMapDlg1->set_item_sensitive("TBI_PROPERTY", true);
544 
545         m_xFtURL->set_sensitive(true);
546         m_xURLBox->set_sensitive(true);
547         m_xFtText->set_sensitive(true);
548         m_xEdtText->set_sensitive(true);
549         m_xFtTarget->set_sensitive(true);
550         m_xCbbTarget->set_sensitive(true);
551 
552         m_xStbStatus1->set_label(rInfo.aMarkURL);
553 
554         if ( m_xURLBox->get_active_text() != rInfo.aMarkURL )
555             m_xURLBox->set_entry_text( rInfo.aMarkURL );
556 
557         if ( m_xEdtText->get_text() != rInfo.aMarkAltText )
558             m_xEdtText->set_text( rInfo.aMarkAltText );
559 
560         if ( rInfo.aMarkTarget.isEmpty() )
561             m_xCbbTarget->set_entry_text( SELF_TARGET );
562         else
563             m_xCbbTarget->set_entry_text(  rInfo.aMarkTarget );
564     }
565 }
566 
IMPL_LINK(SvxIMapDlg,MousePosHdl,GraphCtrl *,pWnd,void)567 IMPL_LINK( SvxIMapDlg, MousePosHdl, GraphCtrl*, pWnd, void )
568 {
569     const FieldUnit eFieldUnit = GetBindings().GetDispatcher()->GetModule()->GetFieldUnit();
570     const Point& rMousePos = pWnd->GetMousePos();
571     const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
572     const sal_Unicode cSep = rLocaleWrapper.getNumDecimalSep()[0];
573 
574     OUString aStr = GetUnitString( rMousePos.X(), eFieldUnit, cSep ) +
575                     " / " + GetUnitString( rMousePos.Y(), eFieldUnit, cSep );
576 
577     m_xStbStatus2->set_label(aStr);
578 }
579 
IMPL_LINK(SvxIMapDlg,GraphSizeHdl,GraphCtrl *,pWnd,void)580 IMPL_LINK( SvxIMapDlg, GraphSizeHdl, GraphCtrl*, pWnd, void )
581 {
582     const FieldUnit eFieldUnit = GetBindings().GetDispatcher()->GetModule()->GetFieldUnit();
583     const Size& rSize = pWnd->GetGraphicSize();
584     const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
585     const sal_Unicode cSep = rLocaleWrapper.getNumDecimalSep()[0];
586 
587     OUString aStr = GetUnitString( rSize.Width(), eFieldUnit, cSep ) +
588                     " x " + GetUnitString( rSize.Height(), eFieldUnit, cSep );
589 
590     m_xStbStatus3->set_label(aStr);
591 }
592 
URLModify()593 void SvxIMapDlg::URLModify()
594 {
595     NotifyInfo  aNewInfo;
596 
597     aNewInfo.aMarkURL = m_xURLBox->get_active_text();
598     aNewInfo.aMarkAltText = m_xEdtText->get_text();
599     aNewInfo.aMarkTarget = m_xCbbTarget->get_active_text();
600 
601     m_xIMapWnd->ReplaceActualIMapInfo( aNewInfo );
602 }
603 
IMPL_LINK_NOARG(SvxIMapDlg,URLModifyHdl,weld::ComboBox &,void)604 IMPL_LINK_NOARG(SvxIMapDlg, URLModifyHdl, weld::ComboBox&, void)
605 {
606     URLModify();
607 }
608 
IMPL_LINK_NOARG(SvxIMapDlg,EntryModifyHdl,weld::Entry &,void)609 IMPL_LINK_NOARG(SvxIMapDlg, EntryModifyHdl, weld::Entry&, void)
610 {
611     URLModify();
612 }
613 
IMPL_LINK_NOARG(SvxIMapDlg,URLLoseFocusHdl,weld::Widget &,void)614 IMPL_LINK_NOARG(SvxIMapDlg, URLLoseFocusHdl, weld::Widget&, void)
615 {
616     NotifyInfo        aNewInfo;
617     const OUString    aURLText( m_xURLBox->get_active_text() );
618     const OUString    aTargetText( m_xCbbTarget->get_active_text() );
619 
620     if ( !aURLText.isEmpty() )
621     {
622         OUString aBase = GetBindings().GetDispatcher()->GetFrame()->GetObjectShell()->GetMedium()->GetBaseURL();
623         aNewInfo.aMarkURL = ::URIHelper::SmartRel2Abs( INetURLObject(aBase), aURLText, URIHelper::GetMaybeFileHdl(), true, false,
624                                                         INetURLObject::EncodeMechanism::WasEncoded,
625                                                         INetURLObject::DecodeMechanism::Unambiguous );
626     }
627     else
628         aNewInfo.aMarkURL = aURLText;
629 
630     aNewInfo.aMarkAltText = m_xEdtText->get_text();
631 
632     if ( aTargetText.isEmpty() )
633         aNewInfo.aMarkTarget = SELF_TARGET;
634     else
635         aNewInfo.aMarkTarget = aTargetText;
636 
637     m_xIMapWnd->ReplaceActualIMapInfo( aNewInfo );
638 }
639 
IMPL_LINK_NOARG(SvxIMapDlg,UpdateHdl,Timer *,void)640 IMPL_LINK_NOARG(SvxIMapDlg, UpdateHdl, Timer *, void)
641 {
642     pOwnData->aIdle.Stop();
643 
644     if ( pOwnData->pUpdateEditingObject != pCheckObj )
645     {
646         if (m_xIMapWnd->IsChanged())
647         {
648             std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "svx/ui/querysaveimagemapchangesdialog.ui"));
649             std::unique_ptr<weld::MessageDialog> xQBox(xBuilder->weld_message_dialog("QuerySaveImageMapChangesDialog"));
650             if (xQBox->run() == RET_YES)
651             {
652                 DoSave();
653             }
654         }
655 
656         m_xIMapWnd->SetGraphic( pOwnData->aUpdateGraphic );
657         m_xIMapWnd->SetImageMap( pOwnData->aUpdateImageMap );
658         SetTargetList( pOwnData->aUpdateTargetList );
659         pCheckObj = pOwnData->pUpdateEditingObject;
660 
661         // After changes => default selection
662         m_xTbxIMapDlg1->set_item_active("TBI_SELECT", true);
663         m_xIMapWnd->SetEditMode( true );
664     }
665 
666     // Delete the copied list again in the Update method
667     pOwnData->aUpdateTargetList.clear();
668 
669     GetBindings().Invalidate( SID_IMAP_EXEC );
670     m_xIMapWnd->QueueIdleUpdate();
671 }
672 
IMPL_LINK(SvxIMapDlg,StateHdl,GraphCtrl *,pWnd,void)673 IMPL_LINK( SvxIMapDlg, StateHdl, GraphCtrl*, pWnd, void )
674 {
675     const SdrObject*    pObj = pWnd->GetSelectedSdrObject();
676     const SdrModel*     pModel = pWnd->GetSdrModel();
677     const SdrView*      pView = pWnd->GetSdrView();
678     const bool          bPolyEdit = ( pObj != nullptr ) && dynamic_cast<const SdrPathObj*>( pObj) !=  nullptr;
679     const bool          bDrawEnabled = !( bPolyEdit && m_xTbxIMapDlg1->get_item_active("TBI_POLYEDIT") );
680 
681     m_xTbxIMapDlg1->set_item_sensitive("TBI_APPLY", pOwnData->bExecState && pWnd->IsChanged() );
682 
683     m_xTbxIMapDlg1->set_item_sensitive("TBI_SELECT", bDrawEnabled);
684     m_xTbxIMapDlg1->set_item_sensitive("TBI_RECT", bDrawEnabled);
685     m_xTbxIMapDlg1->set_item_sensitive("TBI_CIRCLE", bDrawEnabled);
686     m_xTbxIMapDlg1->set_item_sensitive("TBI_POLY", bDrawEnabled);
687     m_xTbxIMapDlg1->set_item_sensitive("TBI_FREEPOLY", bDrawEnabled);
688 
689     // BezierEditor State
690     m_xTbxIMapDlg1->set_item_sensitive( "TBI_POLYEDIT", bPolyEdit );
691     m_xTbxIMapDlg1->set_item_sensitive( "TBI_POLYMOVE", !bDrawEnabled );
692     m_xTbxIMapDlg1->set_item_sensitive( "TBI_POLYINSERT", !bDrawEnabled );
693     m_xTbxIMapDlg1->set_item_sensitive( "TBI_POLYDELETE", !bDrawEnabled && pView->IsDeleteMarkedPointsPossible() );
694 
695     // Undo/Redo
696     m_xTbxIMapDlg1->set_item_sensitive( "TBI_UNDO", pModel->HasUndoActions() );
697     m_xTbxIMapDlg1->set_item_sensitive( "TBI_REDO", pModel->HasRedoActions() );
698 
699     if ( bPolyEdit )
700     {
701         switch( pWnd->GetPolyEditMode() )
702         {
703             case SID_BEZIER_MOVE:
704                 m_xTbxIMapDlg1->set_item_active("TBI_POLYMOVE", true);
705                 m_xTbxIMapDlg1->set_item_active("TBI_POLYINSERT", false);
706                 break;
707             case SID_BEZIER_INSERT:
708                 m_xTbxIMapDlg1->set_item_active("TBI_POLYINSERT", true);
709                 m_xTbxIMapDlg1->set_item_active("TBI_POLYMOVE", false);
710                 break;
711             default:
712                 break;
713         }
714     }
715     else
716     {
717         m_xTbxIMapDlg1->set_item_active( "TBI_POLYEDIT", false );
718         m_xTbxIMapDlg1->set_item_active( "TBI_POLYMOVE", true);
719         m_xTbxIMapDlg1->set_item_active( "TBI_POLYINSERT", false );
720         pWnd->SetPolyEditMode( 0 );
721     }
722 
723     m_xIMapWnd->QueueIdleUpdate();
724 }
725 
GetIMapDlg()726 SvxIMapDlg* GetIMapDlg()
727 {
728     SfxChildWindow* pWnd = nullptr;
729     if (SfxViewFrame::Current() && SfxViewFrame::Current()->HasChildWindow(SvxIMapDlgChildWindow::GetChildWindowId()))
730         pWnd = SfxViewFrame::Current()->GetChildWindow(SvxIMapDlgChildWindow::GetChildWindowId());
731     return pWnd ? static_cast<SvxIMapDlg*>(pWnd->GetController().get()) : nullptr;
732 }
733 
734 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
735