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>
41 using namespace ::ucbhelper
;
45 OUString
CreateUiNameFromURL( const OUString
& aStrURL
)
48 INetURLObject
aURLObj( aStrURL
);
50 switch(aURLObj
.GetProtocol())
52 case INetProtocol::File
:
53 osl::FileBase::getSystemPathFromFileURL(aURLObj
.GetMainURL(INetURLObject::DecodeMechanism::NONE
), aStrUiURL
);
55 case INetProtocol::Ftp
:
57 //remove password from name
58 INetURLObject
aTmpURL(aURLObj
);
60 aStrUiURL
= aTmpURL
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
);
65 aStrUiURL
= aURLObj
.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous
);
68 if(aStrUiURL
.isEmpty())
75 // ComboBox-Control for URL's with History and Autocompletion
76 SvxHyperURLBox::SvxHyperURLBox(std::unique_ptr
<weld::ComboBox
> xControl
)
77 : URLBox(std::move(xControl
))
78 , DropTargetHelper(getWidget()->get_drop_target())
80 SetSmartProtocol(INetProtocol::Http
);
83 sal_Int8
SvxHyperURLBox::AcceptDrop( const AcceptDropEvent
& /* rEvt */ )
85 return IsDropFormatSupported( SotClipboardFormatId::STRING
) ? DND_ACTION_COPY
: DND_ACTION_NONE
;
88 sal_Int8
SvxHyperURLBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
90 TransferableDataHelper
aDataHelper( rEvt
.maDropEvent
.Transferable
);
92 sal_Int8 nRet
= DND_ACTION_NONE
;
94 if( aDataHelper
.GetString( SotClipboardFormatId::STRING
, aString
) )
96 set_entry_text(aString
);
97 nRet
= DND_ACTION_COPY
;
103 //# Hyperlink-Dialog: Tabpages-Baseclass #
105 SvxHyperlinkTabPageBase::SvxHyperlinkTabPageBase(weld::Container
* pParent
,
107 const OUString
& rUIXMLDescription
,
109 const SfxItemSet
* pItemSet
)
110 : IconChoicePage(pParent
, rUIXMLDescription
, rID
, pItemSet
)
111 , mxCbbFrame(xBuilder
->weld_combo_box("frame"))
112 , mxLbForm(xBuilder
->weld_combo_box("form"))
113 , mxEdIndication(xBuilder
->weld_entry("indication"))
114 , mxEdText(xBuilder
->weld_entry("name"))
115 , mxBtScript(xBuilder
->weld_button("script"))
116 , mxFormLabel(xBuilder
->weld_label("form_label"))
117 , mxFrameLabel(xBuilder
->weld_label("frame_label"))
118 , mbIsCloseDisabled( false )
120 , mbStdControlsInit( false )
122 // create bookmark-window
125 SvxHyperlinkTabPageBase::~SvxHyperlinkTabPageBase()
132 bool SvxHyperlinkTabPageBase::QueryClose()
134 return !mbIsCloseDisabled
;
137 void SvxHyperlinkTabPageBase::InitStdControls ()
139 if ( !mbStdControlsInit
)
141 SfxDispatcher
* pDispatch
= GetDispatcher();
142 SfxViewFrame
* pViewFrame
= pDispatch
? pDispatch
->GetFrame() : nullptr;
143 SfxFrame
* pFrame
= pViewFrame
? &pViewFrame
->GetFrame() : nullptr;
146 std::unique_ptr
<TargetList
> pList(new TargetList
);
147 SfxFrame::GetDefaultTargetList(*pList
);
148 if( !pList
->empty() )
150 size_t nCount
= pList
->size();
152 for ( i
= 0; i
< nCount
; i
++ )
154 mxCbbFrame
->append_text( pList
->at( i
) );
159 mxBtScript
->set_from_icon_name(RID_SVXBMP_SCRIPT
);
161 mxBtScript
->connect_clicked ( LINK ( this, SvxHyperlinkTabPageBase
, ClickScriptHdl_Impl
) );
164 mbStdControlsInit
= true;
168 void SvxHyperlinkTabPageBase::MoveToExtraWnd( Point aNewPos
)
170 mxMarkWnd
->MoveTo(aNewPos
);
174 void SvxHyperlinkTabPageBase::ShowMarkWnd()
178 mxMarkWnd
->getDialog()->present();
182 weld::Dialog
* pDialog
= mpDialog
->getDialog();
184 mxMarkWnd
= std::make_unique
<SvxHlinkDlgMarkWnd
>(pDialog
, this);
186 // Size of dialog-window in screen pixels
187 Point
aDlgPos(pDialog
->get_position());
188 Size
aDlgSize(pDialog
->get_size());
190 // Absolute size of the screen
191 ::tools::Rectangle
aScreen(pDialog
->get_monitor_workarea());
193 // Size of Extrawindow
194 Size
aExtraWndSize(mxMarkWnd
->getDialog()->get_preferred_size());
196 // mxMarkWnd is a child of mpDialog, so coordinates for positioning must be relative to mpDialog
197 if( aDlgPos
.X()+(1.05*aDlgSize
.Width())+aExtraWndSize
.Width() > aScreen
.Right() )
199 if( aDlgPos
.X() - ( 0.05*aDlgSize
.Width() ) - aExtraWndSize
.Width() < 0 )
201 // Pos Extrawindow anywhere
202 MoveToExtraWnd( Point(10,10) ); // very unlikely
206 // Pos Extrawindow on the left side of Dialog
207 MoveToExtraWnd( Point(0,0) - Point( long(0.05*aDlgSize
.Width()), 0 ) - Point( aExtraWndSize
.Width(), 0 ) );
212 // Pos Extrawindow on the right side of Dialog
213 MoveToExtraWnd ( Point( long(1.05*aDlgSize
.getWidth()), 0 ) );
216 // Set size of Extra-Window
217 mxMarkWnd
->getDialog()->set_size_request(aExtraWndSize
.Width(), aDlgSize
.Height());
219 weld::DialogController::runAsync(mxMarkWnd
, [this](sal_Int32
/*nResult*/) { mxMarkWnd
.reset(); } );
222 void SvxHyperlinkTabPageBase::HideMarkWnd()
226 mxMarkWnd
->response(RET_CANCEL
);
232 void SvxHyperlinkTabPageBase::FillStandardDlgFields ( const SvxHyperlinkItem
* pHyperlinkItem
)
234 if (!comphelper::LibreOfficeKit::isActive())
237 sal_Int32 nPos
= mxCbbFrame
->find_text(pHyperlinkItem
->GetTargetFrame());
239 mxCbbFrame
->set_active(nPos
);
242 OUString aStrFormText
= CuiResId( RID_SVXSTR_HYPERDLG_FROM_TEXT
);
244 OUString aStrFormButton
= CuiResId( RID_SVXSTR_HYPERDLG_FORM_BUTTON
);
246 if( pHyperlinkItem
->GetInsertMode() & HLINK_HTMLMODE
)
249 mxLbForm
->append_text( aStrFormText
);
250 mxLbForm
->set_active( 0 );
255 mxLbForm
->append_text( aStrFormText
);
256 mxLbForm
->append_text( aStrFormButton
);
257 mxLbForm
->set_active( pHyperlinkItem
->GetInsertMode() == HLINK_BUTTON
? 1 : 0 );
265 mxFrameLabel
->hide();
269 mxEdIndication
->set_text( pHyperlinkItem
->GetName() );
272 mxEdText
->set_text( pHyperlinkItem
->GetIntName() );
275 if (!comphelper::LibreOfficeKit::isActive())
277 if ( pHyperlinkItem
->GetMacroEvents() == HyperDialogEvent::NONE
)
278 mxBtScript
->set_sensitive(false);
280 mxBtScript
->set_sensitive(true);
288 // Any action to do after apply-button is pressed
289 void SvxHyperlinkTabPageBase::DoApply ()
291 // default-implementation : do nothing
294 // Ask page whether an insert is possible
295 bool SvxHyperlinkTabPageBase::AskApply ()
297 // default-implementation
301 // This method would be called from bookmark-window to set new mark-string
302 void SvxHyperlinkTabPageBase::SetMarkStr ( const OUString
& /*aStrMark*/ )
304 // default-implementation : do nothing
308 void SvxHyperlinkTabPageBase::SetInitFocus()
310 xContainer
->grab_focus();
313 // retrieve dispatcher
314 SfxDispatcher
* SvxHyperlinkTabPageBase::GetDispatcher() const
316 return mpDialog
->GetDispatcher();
319 void SvxHyperlinkTabPageBase::DisableClose(bool _bDisable
)
321 mbIsCloseDisabled
= _bDisable
;
322 if (mbIsCloseDisabled
)
323 maBusy
.incBusy(mpDialog
->getDialog());
328 // Click on imagebutton : Script
329 IMPL_LINK_NOARG(SvxHyperlinkTabPageBase
, ClickScriptHdl_Impl
, weld::Button
&, void)
331 SvxHyperlinkItem
*pHyperlinkItem
= const_cast<SvxHyperlinkItem
*>(static_cast<const SvxHyperlinkItem
*>(
332 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
)));
334 if ( pHyperlinkItem
->GetMacroEvents() != HyperDialogEvent::NONE
)
336 // get macros from itemset
337 const SvxMacroTableDtor
* pMacroTbl
= pHyperlinkItem
->GetMacroTable();
338 SvxMacroItem
aItem ( SID_ATTR_MACROITEM
);
340 aItem
.SetMacroTable( *pMacroTbl
);
342 // create empty itemset for macro-dlg
343 std::unique_ptr
<SfxItemSet
> pItemSet( new SfxItemSet(SfxGetpApp()->GetPool(),
344 svl::Items
<SID_ATTR_MACROITEM
,
345 SID_ATTR_MACROITEM
>{} ) );
346 pItemSet
->Put ( aItem
);
348 DisableClose( true );
350 SfxMacroAssignDlg
aDlg(mpDialog
->getDialog(), mxDocumentFrame
, *pItemSet
);
353 SfxMacroTabPage
*pMacroPage
= aDlg
.GetTabPage();
355 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseOverObject
)
356 pMacroPage
->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT1
),
357 SvMacroItemId::OnMouseOver
);
358 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseClickObject
)
359 pMacroPage
->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT2
),
360 SvMacroItemId::OnClick
);
361 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseOutObject
)
362 pMacroPage
->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT3
),
363 SvMacroItemId::OnMouseOut
);
365 short nRet
= aDlg
.run();
366 DisableClose( false );
367 if ( RET_OK
== nRet
)
369 const SfxItemSet
* pOutSet
= aDlg
.GetOutputItemSet();
370 const SfxPoolItem
* pItem
;
371 if( SfxItemState::SET
== pOutSet
->GetItemState( SID_ATTR_MACROITEM
, false, &pItem
))
373 pHyperlinkItem
->SetMacroTable( static_cast<const SvxMacroItem
*>(pItem
)->GetMacroTable() );
380 HyperDialogEvent
SvxHyperlinkTabPageBase::GetMacroEvents() const
382 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
383 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
));
385 return pHyperlinkItem
->GetMacroEvents();
388 SvxMacroTableDtor
* SvxHyperlinkTabPageBase::GetMacroTable()
390 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
391 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
));
393 return const_cast<SvxMacroTableDtor
*>(pHyperlinkItem
->GetMacroTable());
396 // try to detect the current protocol that is used in rStrURL
397 OUString
SvxHyperlinkTabPageBase::GetSchemeFromURL( const OUString
& rStrURL
)
401 INetURLObject
aURL( rStrURL
);
402 INetProtocol aProtocol
= aURL
.GetProtocol();
404 // our new INetUrlObject now has the ability
405 // to detect if a Url is valid or not :-(
406 if ( aProtocol
== INetProtocol::NotValid
)
408 if ( rStrURL
.startsWithIgnoreAsciiCase( INET_HTTP_SCHEME
) )
410 aStrScheme
= INET_HTTP_SCHEME
;
412 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_HTTPS_SCHEME
) )
414 aStrScheme
= INET_HTTPS_SCHEME
;
416 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_FTP_SCHEME
) )
418 aStrScheme
= INET_FTP_SCHEME
;
420 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_MAILTO_SCHEME
) )
422 aStrScheme
= INET_MAILTO_SCHEME
;
426 aStrScheme
= INetURLObject::GetScheme( aProtocol
);
430 void SvxHyperlinkTabPageBase::GetDataFromCommonFields( OUString
& aStrName
,
431 OUString
& aStrIntName
, OUString
& aStrFrame
,
432 SvxLinkInsertMode
& eMode
)
434 aStrIntName
= mxEdText
->get_text();
435 aStrName
= mxEdIndication
->get_text();
436 aStrFrame
= mxCbbFrame
->get_active_text();
438 sal_Int32 nPos
= mxLbForm
->get_active();
440 // This happens when FillStandardDlgFields() hides mpLbForm.
442 eMode
= static_cast<SvxLinkInsertMode
>(nPos
+ 1);
444 // Ask dialog whether the current doc is a HTML-doc
445 if (mpDialog
->IsHTMLDoc())
446 eMode
= static_cast<SvxLinkInsertMode
>( sal_uInt16(eMode
) | HLINK_HTMLMODE
);
449 // reset dialog-fields
450 void SvxHyperlinkTabPageBase::Reset( const SfxItemSet
& rItemSet
)
453 // Set dialog-fields from create-itemset
454 maStrInitURL
.clear();
456 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
457 rItemSet
.GetItem (SID_HYPERLINK_GETLINK
));
459 if ( pHyperlinkItem
)
462 FillStandardDlgFields (pHyperlinkItem
);
464 // set all other fields
465 FillDlgFields ( pHyperlinkItem
->GetURL() );
468 maStrInitURL
= pHyperlinkItem
->GetURL();
472 // Fill output-ItemSet
473 bool SvxHyperlinkTabPageBase::FillItemSet( SfxItemSet
* rOut
)
475 OUString aStrURL
, aStrName
, aStrIntName
, aStrFrame
;
476 SvxLinkInsertMode eMode
;
478 GetCurentItemData ( aStrURL
, aStrName
, aStrIntName
, aStrFrame
, eMode
);
479 if ( aStrName
.isEmpty() ) //automatically create a visible name if the link is created without name
480 aStrName
= CreateUiNameFromURL(aStrURL
);
482 HyperDialogEvent nEvents
= GetMacroEvents();
483 SvxMacroTableDtor
* pTable
= GetMacroTable();
485 SvxHyperlinkItem
aItem( SID_HYPERLINK_SETLINK
, aStrName
, aStrURL
, aStrFrame
,
486 aStrIntName
, eMode
, nEvents
, pTable
);
492 // Activate / Deactivate Tabpage
493 void SvxHyperlinkTabPageBase::ActivatePage( const SfxItemSet
& rItemSet
)
496 // Set dialog-fields from input-itemset
497 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
498 rItemSet
.GetItem (SID_HYPERLINK_GETLINK
));
500 if ( pHyperlinkItem
)
503 FillStandardDlgFields (pHyperlinkItem
);
506 // show mark-window if it was open before
507 if ( ShouldOpenMarkWnd () )
511 DeactivateRC
SvxHyperlinkTabPageBase::DeactivatePage( SfxItemSet
* _pSet
)
514 SetMarkWndShouldOpen( IsMarkWndVisible () );
517 // retrieve data of dialog
518 OUString aStrURL
, aStrName
, aStrIntName
, aStrFrame
;
519 SvxLinkInsertMode eMode
;
521 GetCurentItemData ( aStrURL
, aStrName
, aStrIntName
, aStrFrame
, eMode
);
523 HyperDialogEvent nEvents
= GetMacroEvents();
524 SvxMacroTableDtor
* pTable
= GetMacroTable();
528 SvxHyperlinkItem
aItem( SID_HYPERLINK_GETLINK
, aStrName
, aStrURL
, aStrFrame
,
529 aStrIntName
, eMode
, nEvents
, pTable
);
533 return DeactivateRC::LeavePage
;
536 bool SvxHyperlinkTabPageBase::ShouldOpenMarkWnd()
541 void SvxHyperlinkTabPageBase::SetMarkWndShouldOpen(bool)
545 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */