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