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 <osl/file.hxx>
24 #include <sfx2/event.hxx>
25 #include <sfx2/frame.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <sot/formats.hxx>
28 #include <sfx2/sfxsids.hrc>
29 #include <svl/macitem.hxx>
30 #include <ucbhelper/content.hxx>
31 #include <cuihyperdlg.hxx>
32 #include <hltpbase.hxx>
33 #include <macroass.hxx>
34 #include <svx/svxdlg.hxx>
35 #include <strings.hrc>
36 #include <dialmgr.hxx>
37 #include <bitmaps.hlst>
38 #include <vcl/builderfactory.hxx>
39 #include <comphelper/lok.hxx>
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 #
77 SvxHyperURLBox::SvxHyperURLBox( vcl::Window
* pParent
, INetProtocol eSmart
)
78 : SvtURLBox ( pParent
, eSmart
),
79 DropTargetHelper ( this )
83 VCL_BUILDER_FACTORY_ARGS(SvxHyperURLBox
, INetProtocol::Http
)
85 sal_Int8
SvxHyperURLBox::AcceptDrop( const AcceptDropEvent
& /* rEvt */ )
87 return IsDropFormatSupported( SotClipboardFormatId::STRING
) ? DND_ACTION_COPY
: DND_ACTION_NONE
;
90 sal_Int8
SvxHyperURLBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
92 TransferableDataHelper
aDataHelper( rEvt
.maDropEvent
.Transferable
);
94 sal_Int8 nRet
= DND_ACTION_NONE
;
96 if( aDataHelper
.GetString( SotClipboardFormatId::STRING
, aString
) )
99 nRet
= DND_ACTION_COPY
;
105 //# Hyperlink-Dialog: Tabpages-Baseclass #
107 SvxHyperlinkTabPageBase::SvxHyperlinkTabPageBase ( vcl::Window
*pParent
,
108 IconChoiceDialog
* pDlg
,
110 const OUString
& rUIXMLDescription
,
111 const SfxItemSet
* pItemSet
)
112 : IconChoicePage ( pParent
, rID
, rUIXMLDescription
, pItemSet
),
113 mpCbbFrame ( nullptr ),
114 mpLbForm ( nullptr ),
115 mpEdIndication ( nullptr ),
116 mpEdText ( nullptr ),
117 mpBtScript ( nullptr ),
118 mbIsCloseDisabled ( false ),
120 mbStdControlsInit ( false )
122 // create bookmark-window
123 mpMarkWnd
= VclPtr
<SvxHlinkDlgMarkWnd
>::Create( this );
126 SvxHyperlinkTabPageBase::~SvxHyperlinkTabPageBase()
131 void SvxHyperlinkTabPageBase::dispose()
135 mpMarkWnd
.disposeAndClear();
139 mpEdIndication
.clear();
144 IconChoicePage::dispose();
147 bool SvxHyperlinkTabPageBase::QueryClose()
149 return !mbIsCloseDisabled
;
152 void SvxHyperlinkTabPageBase::InitStdControls ()
154 if ( !mbStdControlsInit
)
156 get(mpCbbFrame
, "frame");
158 SfxDispatcher
* pDispatch
= GetDispatcher();
159 SfxViewFrame
* pViewFrame
= pDispatch
? pDispatch
->GetFrame() : nullptr;
160 SfxFrame
* pFrame
= pViewFrame
? &pViewFrame
->GetFrame() : nullptr;
163 std::unique_ptr
<TargetList
> pList(new TargetList
);
164 SfxFrame::GetDefaultTargetList(*pList
);
165 if( !pList
->empty() )
167 size_t nCount
= pList
->size();
169 for ( i
= 0; i
< nCount
; i
++ )
171 mpCbbFrame
->InsertEntry( pList
->at( i
) );
176 get(mpLbForm
, "form");
177 get(mpEdIndication
, "indication");
178 get(mpEdText
, "name");
179 get(mpBtScript
, "script");
180 mpBtScript
->SetModeImage(Image(StockImage::Yes
, RID_SVXBMP_SCRIPT
));
182 mpBtScript
->SetClickHdl ( LINK ( this, SvxHyperlinkTabPageBase
, ClickScriptHdl_Impl
) );
183 mpBtScript
->EnableTextDisplay (false);
186 mbStdControlsInit
= true;
190 bool SvxHyperlinkTabPageBase::MoveToExtraWnd( Point aNewPos
, bool bDisConnectDlg
)
192 bool bReturn
= mpMarkWnd
->MoveTo ( aNewPos
);
195 mpMarkWnd
->ConnectToDialog();
197 return ( !bReturn
&& IsMarkWndVisible() );
201 void SvxHyperlinkTabPageBase::ShowMarkWnd ()
203 static_cast<vcl::Window
*>(mpMarkWnd
)->Show();
205 // Size of dialog-window in screen pixels
206 ::tools::Rectangle
aDlgRect( mpDialog
->GetWindowExtentsRelative( nullptr ) );
207 Point
aDlgPos ( aDlgRect
.TopLeft() );
208 Size
aDlgSize ( mpDialog
->GetSizePixel () );
210 // Absolute size of the screen
211 ::tools::Rectangle
aScreen( mpDialog
->GetDesktopRectPixel() );
213 // Size of Extrawindow
214 Size
aExtraWndSize( mpMarkWnd
->GetSizePixel () );
216 // mpMarkWnd is a child of mpDialog, so coordinates for positioning must be relative to mpDialog
217 if( aDlgPos
.X()+(1.05*aDlgSize
.Width())+aExtraWndSize
.Width() > aScreen
.Right() )
219 if( aDlgPos
.X() - ( 0.05*aDlgSize
.Width() ) - aExtraWndSize
.Width() < 0 )
221 // Pos Extrawindow anywhere
222 MoveToExtraWnd( Point(10,10) ); // very unlikely
223 mpMarkWnd
->ConnectToDialog();
227 // Pos Extrawindow on the left side of Dialog
228 MoveToExtraWnd( Point(0,0) - Point( long(0.05*aDlgSize
.Width()), 0 ) - Point( aExtraWndSize
.Width(), 0 ) );
233 // Pos Extrawindow on the right side of Dialog
234 MoveToExtraWnd ( Point( long(1.05*aDlgSize
.getWidth()), 0 ) );
237 // Set size of Extra-Window
238 mpMarkWnd
->SetSizePixel( Size( aExtraWndSize
.Width(), aDlgSize
.Height() ) );
242 void SvxHyperlinkTabPageBase::FillStandardDlgFields ( const SvxHyperlinkItem
* pHyperlinkItem
)
244 if (!comphelper::LibreOfficeKit::isActive())
247 sal_Int32 nPos
= mpCbbFrame
->GetEntryPos ( pHyperlinkItem
->GetTargetFrame() );
248 if ( nPos
!= COMBOBOX_ENTRY_NOTFOUND
)
249 mpCbbFrame
->SetText ( pHyperlinkItem
->GetTargetFrame() );
252 OUString aStrFormText
= CuiResId( RID_SVXSTR_HYPERDLG_FROM_TEXT
);
254 OUString aStrFormButton
= CuiResId( RID_SVXSTR_HYPERDLG_FORM_BUTTON
);
256 if( pHyperlinkItem
->GetInsertMode() & HLINK_HTMLMODE
)
259 mpLbForm
->InsertEntry( aStrFormText
);
260 mpLbForm
->SelectEntryPos ( 0 );
265 mpLbForm
->InsertEntry( aStrFormText
);
266 mpLbForm
->InsertEntry( aStrFormButton
);
267 mpLbForm
->SelectEntryPos ( pHyperlinkItem
->GetInsertMode() == HLINK_BUTTON
? 1 : 0 );
275 VclPtr
<FixedText
> pLabel
;
276 get(pLabel
, "form_label");
278 get(pLabel
, "frame_label");
283 mpEdIndication
->SetText ( pHyperlinkItem
->GetName() );
286 mpEdText
->SetText ( pHyperlinkItem
->GetIntName() );
289 if ( pHyperlinkItem
->GetMacroEvents() == HyperDialogEvent::NONE
)
290 mpBtScript
->Disable();
292 mpBtScript
->Enable();
295 // Any action to do after apply-button is pressed
296 void SvxHyperlinkTabPageBase::DoApply ()
298 // default-implementation : do nothing
301 // Ask page whether an insert is possible
302 bool SvxHyperlinkTabPageBase::AskApply ()
304 // default-implementation
308 // This method would be called from bookmark-window to set new mark-string
309 void SvxHyperlinkTabPageBase::SetMarkStr ( const OUString
& /*aStrMark*/ )
311 // default-implementation : do nothing
315 void SvxHyperlinkTabPageBase::SetInitFocus()
320 // retrieve dispatcher
321 SfxDispatcher
* SvxHyperlinkTabPageBase::GetDispatcher() const
323 return static_cast<SvxHpLinkDlg
*>(mpDialog
.get())->GetDispatcher();
326 // Click on imagebutton : Script
327 IMPL_LINK_NOARG(SvxHyperlinkTabPageBase
, ClickScriptHdl_Impl
, Button
*, void)
329 SvxHyperlinkItem
*pHyperlinkItem
= const_cast<SvxHyperlinkItem
*>(static_cast<const SvxHyperlinkItem
*>(
330 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
)));
332 if ( pHyperlinkItem
->GetMacroEvents() != HyperDialogEvent::NONE
)
334 // get macros from itemset
335 const SvxMacroTableDtor
* pMacroTbl
= pHyperlinkItem
->GetMacroTable();
336 SvxMacroItem
aItem ( SID_ATTR_MACROITEM
);
338 aItem
.SetMacroTable( *pMacroTbl
);
340 // create empty itemset for macro-dlg
341 std::unique_ptr
<SfxItemSet
> pItemSet( new SfxItemSet(SfxGetpApp()->GetPool(),
342 svl::Items
<SID_ATTR_MACROITEM
,
343 SID_ATTR_MACROITEM
>{} ) );
344 pItemSet
->Put ( aItem
);
346 /* disable HyperLinkDlg for input while the MacroAssignDlg is working
347 because if no JAVA is installed an error box occurs and then it is possible
348 to close the HyperLinkDlg before its child (MacroAssignDlg) -> GPF
350 bool bIsInputEnabled
= GetParent()->IsInputEnabled();
351 if ( bIsInputEnabled
)
352 GetParent()->EnableInput( false );
353 SfxMacroAssignDlg
aDlg(GetFrameWeld(), mxDocumentFrame
, *pItemSet
);
356 SfxMacroTabPage
*pMacroPage
= aDlg
.GetTabPage();
358 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseOverObject
)
359 pMacroPage
->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT1
),
360 SvMacroItemId::OnMouseOver
);
361 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseClickObject
)
362 pMacroPage
->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT2
),
363 SvMacroItemId::OnClick
);
364 if ( pHyperlinkItem
->GetMacroEvents() & HyperDialogEvent::MouseOutObject
)
365 pMacroPage
->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT3
),
366 SvMacroItemId::OnMouseOut
);
368 if ( bIsInputEnabled
)
369 GetParent()->EnableInput();
371 DisableClose( true );
372 short nRet
= aDlg
.run();
373 DisableClose( false );
374 if ( RET_OK
== nRet
)
376 const SfxItemSet
* pOutSet
= aDlg
.GetOutputItemSet();
377 const SfxPoolItem
* pItem
;
378 if( SfxItemState::SET
== pOutSet
->GetItemState( SID_ATTR_MACROITEM
, false, &pItem
))
380 pHyperlinkItem
->SetMacroTable( static_cast<const SvxMacroItem
*>(pItem
)->GetMacroTable() );
387 HyperDialogEvent
SvxHyperlinkTabPageBase::GetMacroEvents()
389 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
390 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
));
392 return pHyperlinkItem
->GetMacroEvents();
395 SvxMacroTableDtor
* SvxHyperlinkTabPageBase::GetMacroTable()
397 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
398 GetItemSet().GetItem (SID_HYPERLINK_GETLINK
));
400 return const_cast<SvxMacroTableDtor
*>(pHyperlinkItem
->GetMacroTable());
403 // try to detect the current protocol that is used in rStrURL
404 OUString
SvxHyperlinkTabPageBase::GetSchemeFromURL( const OUString
& rStrURL
)
408 INetURLObject
aURL( rStrURL
);
409 INetProtocol aProtocol
= aURL
.GetProtocol();
411 // our new INetUrlObject now has the ability
412 // to detect if a Url is valid or not :-(
413 if ( aProtocol
== INetProtocol::NotValid
)
415 if ( rStrURL
.startsWithIgnoreAsciiCase( INET_HTTP_SCHEME
) )
417 aStrScheme
= INET_HTTP_SCHEME
;
419 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_HTTPS_SCHEME
) )
421 aStrScheme
= INET_HTTPS_SCHEME
;
423 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_FTP_SCHEME
) )
425 aStrScheme
= INET_FTP_SCHEME
;
427 else if ( rStrURL
.startsWithIgnoreAsciiCase( INET_MAILTO_SCHEME
) )
429 aStrScheme
= INET_MAILTO_SCHEME
;
433 aStrScheme
= INetURLObject::GetScheme( aProtocol
);
438 void SvxHyperlinkTabPageBase::GetDataFromCommonFields( OUString
& aStrName
,
439 OUString
& aStrIntName
, OUString
& aStrFrame
,
440 SvxLinkInsertMode
& eMode
)
442 aStrIntName
= mpEdText
->GetText();
443 aStrName
= mpEdIndication
->GetText();
444 aStrFrame
= mpCbbFrame
->GetText();
446 sal_Int32 nPos
= mpLbForm
->GetSelectedEntryPos();
447 if (nPos
== LISTBOX_ENTRY_NOTFOUND
)
448 // This happens when FillStandardDlgFields() hides mpLbForm.
450 eMode
= static_cast<SvxLinkInsertMode
>(nPos
+ 1);
452 // Ask dialog whether the current doc is a HTML-doc
453 if (static_cast<SvxHpLinkDlg
*>(mpDialog
.get())->IsHTMLDoc())
454 eMode
= static_cast<SvxLinkInsertMode
>( sal_uInt16(eMode
) | HLINK_HTMLMODE
);
457 // reset dialog-fields
458 void SvxHyperlinkTabPageBase::Reset( const SfxItemSet
& rItemSet
)
461 // Set dialog-fields from create-itemset
462 maStrInitURL
.clear();
464 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
465 rItemSet
.GetItem (SID_HYPERLINK_GETLINK
));
467 if ( pHyperlinkItem
)
470 FillStandardDlgFields (pHyperlinkItem
);
472 // set all other fields
473 FillDlgFields ( pHyperlinkItem
->GetURL() );
476 maStrInitURL
= pHyperlinkItem
->GetURL();
480 // Fill output-ItemSet
481 bool SvxHyperlinkTabPageBase::FillItemSet( SfxItemSet
* rOut
)
483 OUString aStrURL
, aStrName
, aStrIntName
, aStrFrame
;
484 SvxLinkInsertMode eMode
;
486 GetCurentItemData ( aStrURL
, aStrName
, aStrIntName
, aStrFrame
, eMode
);
487 if ( aStrName
.isEmpty() ) //automatically create a visible name if the link is created without name
488 aStrName
= CreateUiNameFromURL(aStrURL
);
490 HyperDialogEvent nEvents
= GetMacroEvents();
491 SvxMacroTableDtor
* pTable
= GetMacroTable();
493 SvxHyperlinkItem
aItem( SID_HYPERLINK_SETLINK
, aStrName
, aStrURL
, aStrFrame
,
494 aStrIntName
, eMode
, nEvents
, pTable
);
500 // Activate / Deactivate Tabpage
501 void SvxHyperlinkTabPageBase::ActivatePage( const SfxItemSet
& rItemSet
)
504 // Set dialog-fields from input-itemset
505 const SvxHyperlinkItem
*pHyperlinkItem
= static_cast<const SvxHyperlinkItem
*>(
506 rItemSet
.GetItem (SID_HYPERLINK_GETLINK
));
508 if ( pHyperlinkItem
)
511 FillStandardDlgFields (pHyperlinkItem
);
514 // show mark-window if it was open before
515 if ( ShouldOpenMarkWnd () )
519 DeactivateRC
SvxHyperlinkTabPageBase::DeactivatePage( SfxItemSet
* _pSet
)
522 SetMarkWndShouldOpen( IsMarkWndVisible () );
525 // retrieve data of dialog
526 OUString aStrURL
, aStrName
, aStrIntName
, aStrFrame
;
527 SvxLinkInsertMode eMode
;
529 GetCurentItemData ( aStrURL
, aStrName
, aStrIntName
, aStrFrame
, eMode
);
531 HyperDialogEvent nEvents
= GetMacroEvents();
532 SvxMacroTableDtor
* pTable
= GetMacroTable();
536 SvxHyperlinkItem
aItem( SID_HYPERLINK_GETLINK
, aStrName
, aStrURL
, aStrFrame
,
537 aStrIntName
, eMode
, nEvents
, pTable
);
541 return DeactivateRC::LeavePage
;
544 bool SvxHyperlinkTabPageBase::ShouldOpenMarkWnd()
549 void SvxHyperlinkTabPageBase::SetMarkWndShouldOpen(bool)
553 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */