1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <sal/config.h>
23 #include <comphelper/lok.hxx>
24 #include <osl/file.hxx>
25 #include <sfx2/app.hxx>
26 #include <sfx2/event.hxx>
27 #include <sfx2/frame.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <sot/formats.hxx>
30 #include <sfx2/sfxsids.hrc>
31 #include <svl/macitem.hxx>
32 #include <ucbhelper/content.hxx>
33 #include <cuihyperdlg.hxx>
34 #include <hltpbase.hxx>
35 #include <macroass.hxx>
36 #include <svx/svxdlg.hxx>
37 #include <strings.hrc>
38 #include <dialmgr.hxx>
39 #include <bitmaps.hlst>
43 OUString
CreateUiNameFromURL( const OUString
& aStrURL
)
46 INetURLObject
aURLObj( aStrURL
);
48 switch(aURLObj
.GetProtocol())
50 case INetProtocol::File
:
51 osl::FileBase::getSystemPathFromFileURL(aURLObj
.GetMainURL(INetURLObject::DecodeMechanism::NONE
), aStrUiURL
);
53 case INetProtocol::Ftp
:
55 //remove password from name
56 INetURLObject
aTmpURL(aURLObj
);
58 aStrUiURL
= aTmpURL
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
);
63 aStrUiURL
= aURLObj
.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous
);
66 if(aStrUiURL
.isEmpty())
73 // ComboBox-Control for URL's with History and Autocompletion
74 SvxHyperURLBox::SvxHyperURLBox(std::unique_ptr
<weld::ComboBox
> xControl
)
75 : SvtURLBox(std::move(xControl
))
76 , DropTargetHelper(getWidget()->get_drop_target())
78 SetSmartProtocol(INetProtocol::Http
);
81 sal_Int8
SvxHyperURLBox::AcceptDrop( const AcceptDropEvent
& /* rEvt */ )
83 return IsDropFormatSupported( SotClipboardFormatId::STRING
) ? DND_ACTION_COPY
: DND_ACTION_NONE
;
86 sal_Int8
SvxHyperURLBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
88 TransferableDataHelper
aDataHelper( rEvt
.maDropEvent
.Transferable
);
90 sal_Int8 nRet
= DND_ACTION_NONE
;
92 if( aDataHelper
.GetString( SotClipboardFormatId::STRING
, aString
) )
94 set_entry_text(aString
);
95 nRet
= DND_ACTION_COPY
;
101 //# Hyperlink-Dialog: Tabpages-Baseclass #
103 SvxHyperlinkTabPageBase::SvxHyperlinkTabPageBase(weld::Container
* pParent
,
105 const OUString
& rUIXMLDescription
,
107 const SfxItemSet
* pItemSet
)
108 : IconChoicePage(pParent
, rUIXMLDescription
, rID
, pItemSet
)
109 , mxCbbFrame(xBuilder
->weld_combo_box(u
"frame"_ustr
))
110 , mxLbForm(xBuilder
->weld_combo_box(u
"form"_ustr
))
111 , mxEdIndication(xBuilder
->weld_entry(u
"indication"_ustr
))
112 , mxEdText(xBuilder
->weld_entry(u
"name"_ustr
))
113 , mxBtScript(xBuilder
->weld_button(u
"script"_ustr
))
114 , mxFormLabel(xBuilder
->weld_label(u
"form_label"_ustr
))
115 , mxFrameLabel(xBuilder
->weld_label(u
"frame_label"_ustr
))
116 , mbIsCloseDisabled( false )
118 , mbStdControlsInit( false )
119 , maTimer("cui SvxHyperlinkTabPageBase maTimer")
121 // create bookmark-window
124 SvxHyperlinkTabPageBase::~SvxHyperlinkTabPageBase()
131 bool SvxHyperlinkTabPageBase::QueryClose()
133 return !mbIsCloseDisabled
;
136 void SvxHyperlinkTabPageBase::InitStdControls ()
138 if ( !mbStdControlsInit
)
140 SfxDispatcher
* pDispatch
= GetDispatcher();
141 SfxViewFrame
* pViewFrame
= pDispatch
? pDispatch
->GetFrame() : nullptr;
142 SfxFrame
* pFrame
= pViewFrame
? &pViewFrame
->GetFrame() : nullptr;
146 SfxFrame::GetDefaultTargetList(aList
);
149 size_t nCount
= aList
.size();
151 for ( i
= 0; i
< nCount
; i
++ )
153 mxCbbFrame
->append_text( aList
.at( i
) );
158 mxBtScript
->set_from_icon_name(RID_SVXBMP_SCRIPT
);
160 mxBtScript
->connect_clicked ( LINK ( this, SvxHyperlinkTabPageBase
, ClickScriptHdl_Impl
) );
163 mbStdControlsInit
= true;
167 void SvxHyperlinkTabPageBase::MoveToExtraWnd( Point aNewPos
)
169 mxMarkWnd
->MoveTo(aNewPos
);
173 void SvxHyperlinkTabPageBase::ShowMarkWnd()
177 mxMarkWnd
->getDialog()->present();
181 weld::Dialog
* pDialog
= mpDialog
->getDialog();
183 mxMarkWnd
= std::make_shared
<SvxHlinkDlgMarkWnd
>(pDialog
, this);
185 // Size of dialog-window in screen pixels
186 Point
aDlgPos(pDialog
->get_position());
187 Size
aDlgSize(pDialog
->get_size());
189 // Absolute size of the screen
190 ::tools::Rectangle
aScreen(pDialog
->get_monitor_workarea());
192 // Size of Extrawindow
193 Size
aExtraWndSize(mxMarkWnd
->getDialog()->get_preferred_size());
195 // mxMarkWnd is a child of mpDialog, so coordinates for positioning must be relative to mpDialog
196 if( aDlgPos
.X()+(1.05*aDlgSize
.Width())+aExtraWndSize
.Width() > aScreen
.Right() )
198 if( aDlgPos
.X() - ( 0.05*aDlgSize
.Width() ) - aExtraWndSize
.Width() < 0 )
200 // Pos Extrawindow anywhere
201 MoveToExtraWnd( Point(10,10) ); // very unlikely
205 // Pos Extrawindow on the left side of Dialog
206 MoveToExtraWnd( Point(0,0) - Point( tools::Long(0.05*aDlgSize
.Width()), 0 ) - Point( aExtraWndSize
.Width(), 0 ) );
211 // Pos Extrawindow on the right side of Dialog
212 MoveToExtraWnd ( Point( tools::Long(1.05*aDlgSize
.getWidth()), 0 ) );
215 // Set size of Extra-Window
216 mxMarkWnd
->getDialog()->set_size_request(aExtraWndSize
.Width(), aDlgSize
.Height());
218 weld::DialogController::runAsync(mxMarkWnd
, [this](sal_Int32
/*nResult*/) { mxMarkWnd
.reset(); } );
221 void SvxHyperlinkTabPageBase::HideMarkWnd()
225 mxMarkWnd
->response(RET_CANCEL
);
231 void SvxHyperlinkTabPageBase::FillStandardDlgFields ( const SvxHyperlinkItem
* pHyperlinkItem
)
233 if (!comphelper::LibreOfficeKit::isActive())
236 sal_Int32 nPos
= mxCbbFrame
->find_text(pHyperlinkItem
->GetTargetFrame());
238 mxCbbFrame
->set_active(nPos
);
241 OUString aStrFormText
= CuiResId( RID_CUISTR_HYPERDLG_FROM_TEXT
);
243 OUString aStrFormButton
= CuiResId( RID_CUISTR_HYPERDLG_FORM_BUTTON
);
245 if( pHyperlinkItem
->GetInsertMode() & HLINK_HTMLMODE
)
248 mxLbForm
->append_text( aStrFormText
);
249 mxLbForm
->set_active( 0 );
254 mxLbForm
->append_text( aStrFormText
);
255 mxLbForm
->append_text( aStrFormButton
);
256 mxLbForm
->set_active( pHyperlinkItem
->GetInsertMode() == HLINK_BUTTON
? 1 : 0 );
264 mxFrameLabel
->hide();
268 mxEdIndication
->set_text( pHyperlinkItem
->GetName() );
271 mxEdText
->set_text( pHyperlinkItem
->GetIntName() );
274 if (!comphelper::LibreOfficeKit::isActive())
276 if ( pHyperlinkItem
->GetMacroEvents() == HyperDialogEvent::NONE
)
277 mxBtScript
->set_sensitive(false);
279 mxBtScript
->set_sensitive(true);
287 // Any action to do after apply-button is pressed
288 void SvxHyperlinkTabPageBase::DoApply ()
290 // default-implementation : do nothing
293 // This method would be called from bookmark-window to set new mark-string
294 void SvxHyperlinkTabPageBase::SetMarkStr ( const OUString
& /*aStrMark*/ )
296 // default-implementation : do nothing
300 void SvxHyperlinkTabPageBase::SetInitFocus()
302 xContainer
->grab_focus();
305 // retrieve dispatcher
306 SfxDispatcher
* SvxHyperlinkTabPageBase::GetDispatcher() const
308 return mpDialog
->GetDispatcher();
311 void SvxHyperlinkTabPageBase::DisableClose(bool _bDisable
)
313 mbIsCloseDisabled
= _bDisable
;
314 if (mbIsCloseDisabled
)
315 maBusy
.incBusy(mpDialog
->getDialog());
320 // Click on imagebutton : Script
321 IMPL_LINK_NOARG(SvxHyperlinkTabPageBase
, ClickScriptHdl_Impl
, weld::Button
&, void)
323 SvxHyperlinkItem
*pHyperlinkItem
= const_cast<SvxHyperlinkItem
*>(
324 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
));
326 if (!pHyperlinkItem
|| pHyperlinkItem
->GetMacroEvents() == HyperDialogEvent::NONE
)
329 // get macros from itemset
330 const SvxMacroTableDtor
* pMacroTbl
= pHyperlinkItem
->GetMacroTable();
331 SvxMacroItem
aItem ( SID_ATTR_MACROITEM
);
333 aItem
.SetMacroTable( *pMacroTbl
);
335 // create empty itemset for macro-dlg
336 auto xItemSet
= std::make_unique
<SfxItemSetFixed
<SID_ATTR_MACROITEM
, SID_ATTR_MACROITEM
>>( SfxGetpApp()->GetPool() );
337 xItemSet
->Put( aItem
);
339 DisableClose( true );
341 SfxMacroAssignDlg
aDlg(mpDialog
->getDialog(), mxDocumentFrame
, std::move(xItemSet
));
344 SfxMacroTabPage
*pMacroPage
= aDlg
.GetTabPage();
346 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseOverObject
)
347 pMacroPage
->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT1
),
348 SvMacroItemId::OnMouseOver
);
349 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseClickObject
)
350 pMacroPage
->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT2
),
351 SvMacroItemId::OnClick
);
352 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseOutObject
)
353 pMacroPage
->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT3
),
354 SvMacroItemId::OnMouseOut
);
356 short nRet
= aDlg
.run();
357 DisableClose( false );
358 if ( RET_OK
== nRet
)
360 const SfxItemSet
* pOutSet
= aDlg
.GetOutputItemSet();
361 const SfxPoolItem
* pItem
;
362 if( SfxItemState::SET
== pOutSet
->GetItemState( SID_ATTR_MACROITEM
, false, &pItem
))
364 pHyperlinkItem
->SetMacroTable( static_cast<const SvxMacroItem
*>(pItem
)->GetMacroTable() );
370 HyperDialogEvent
SvxHyperlinkTabPageBase::GetMacroEvents() const
372 const SvxHyperlinkItem
*pHyperlinkItem
=
373 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
);
375 return pHyperlinkItem
? pHyperlinkItem
->GetMacroEvents() : HyperDialogEvent();
378 SvxMacroTableDtor
* SvxHyperlinkTabPageBase::GetMacroTable()
380 const SvxHyperlinkItem
*pHyperlinkItem
=
381 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
);
383 return const_cast<SvxMacroTableDtor
*>(pHyperlinkItem
->GetMacroTable());
386 // try to detect the current protocol that is used in rStrURL
387 OUString
SvxHyperlinkTabPageBase::GetSchemeFromURL( const OUString
& rStrURL
)
391 INetURLObject
aURL( rStrURL
);
392 INetProtocol aProtocol
= aURL
.GetProtocol();
394 // our new INetUrlObject now has the ability
395 // to detect if a Url is valid or not :-(
396 if ( aProtocol
== INetProtocol::NotValid
)
398 if ( rStrURL
.startsWithIgnoreAsciiCase( INET_HTTP_SCHEME
) )
400 aStrScheme
= INET_HTTP_SCHEME
;
402 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_HTTPS_SCHEME
) )
404 aStrScheme
= INET_HTTPS_SCHEME
;
406 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_FTP_SCHEME
) )
408 aStrScheme
= INET_FTP_SCHEME
;
410 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_MAILTO_SCHEME
) )
412 aStrScheme
= INET_MAILTO_SCHEME
;
416 aStrScheme
= INetURLObject::GetScheme( aProtocol
);
420 void SvxHyperlinkTabPageBase::GetDataFromCommonFields( OUString
& aStrName
,
421 OUString
& aStrIntName
, OUString
& aStrFrame
,
422 SvxLinkInsertMode
& eMode
)
424 aStrIntName
= mxEdText
->get_text();
425 aStrName
= mxEdIndication
->get_text();
426 aStrFrame
= mxCbbFrame
->get_active_text();
428 sal_Int32 nPos
= mxLbForm
->get_active();
430 // This happens when FillStandardDlgFields() hides mpLbForm.
432 eMode
= static_cast<SvxLinkInsertMode
>(nPos
+ 1);
434 // Ask dialog whether the current doc is a HTML-doc
435 if (mpDialog
->IsHTMLDoc())
436 eMode
= static_cast<SvxLinkInsertMode
>( sal_uInt16(eMode
) | HLINK_HTMLMODE
);
439 // reset dialog-fields
440 void SvxHyperlinkTabPageBase::Reset( const SfxItemSet
& rItemSet
)
443 // Set dialog-fields from create-itemset
444 maStrInitURL
.clear();
446 const SvxHyperlinkItem
*pHyperlinkItem
=
447 rItemSet
.GetItem (SID_HYPERLINK_GETLINK
);
449 if ( pHyperlinkItem
)
452 FillStandardDlgFields (pHyperlinkItem
);
454 // set all other fields
455 FillDlgFields(pHyperlinkItem
->GetURL());
458 maStrInitURL
= pHyperlinkItem
->GetURL();
462 // Fill output-ItemSet
463 bool SvxHyperlinkTabPageBase::FillItemSet( SfxItemSet
* rOut
)
465 OUString aStrURL
, aStrName
, aStrIntName
, aStrFrame
;
466 SvxLinkInsertMode eMode
;
468 GetCurrentItemData ( aStrURL
, aStrName
, aStrIntName
, aStrFrame
, eMode
);
469 if ( aStrName
.isEmpty() ) //automatically create a visible name if the link is created without name
470 aStrName
= CreateUiNameFromURL(aStrURL
);
472 HyperDialogEvent nEvents
= GetMacroEvents();
473 SvxMacroTableDtor
* pTable
= GetMacroTable();
475 SvxHyperlinkItem
aItem( SID_HYPERLINK_SETLINK
, aStrName
, aStrURL
, aStrFrame
,
476 aStrIntName
, eMode
, nEvents
, pTable
);
482 // Activate / Deactivate Tabpage
483 void SvxHyperlinkTabPageBase::ActivatePage( const SfxItemSet
& rItemSet
)
486 // Set dialog-fields from input-itemset
487 const SvxHyperlinkItem
*pHyperlinkItem
=
488 rItemSet
.GetItem (SID_HYPERLINK_GETLINK
);
490 if ( pHyperlinkItem
)
493 FillStandardDlgFields (pHyperlinkItem
);
496 // show mark-window if it was open before
497 if ( ShouldOpenMarkWnd () )
501 DeactivateRC
SvxHyperlinkTabPageBase::DeactivatePage( SfxItemSet
* _pSet
)
504 SetMarkWndShouldOpen( IsMarkWndVisible () );
507 // retrieve data of dialog
508 OUString aStrURL
, aStrName
, aStrIntName
, aStrFrame
;
509 SvxLinkInsertMode eMode
;
511 GetCurrentItemData ( aStrURL
, aStrName
, aStrIntName
, aStrFrame
, eMode
);
513 HyperDialogEvent nEvents
= GetMacroEvents();
514 SvxMacroTableDtor
* pTable
= GetMacroTable();
518 SvxHyperlinkItem
aItem( SID_HYPERLINK_GETLINK
, aStrName
, aStrURL
, aStrFrame
,
519 aStrIntName
, eMode
, nEvents
, pTable
);
523 return DeactivateRC::LeavePage
;
526 bool SvxHyperlinkTabPageBase::ShouldOpenMarkWnd()
531 void SvxHyperlinkTabPageBase::SetMarkWndShouldOpen(bool)
535 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */