1
0
Fork 0
libreoffice/cui/source/dialogs/hltpbase.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

535 lines
16 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <memory>
#include <sal/config.h>
#include <comphelper/lok.hxx>
#include <osl/file.hxx>
#include <sfx2/app.hxx>
#include <sfx2/event.hxx>
#include <sfx2/frame.hxx>
#include <sfx2/viewfrm.hxx>
#include <sot/formats.hxx>
#include <sfx2/sfxsids.hrc>
#include <svl/macitem.hxx>
#include <ucbhelper/content.hxx>
#include <cuihyperdlg.hxx>
#include <hltpbase.hxx>
#include <macroass.hxx>
#include <svx/svxdlg.hxx>
#include <strings.hrc>
#include <dialmgr.hxx>
#include <bitmaps.hlst>
namespace {
OUString CreateUiNameFromURL( const OUString& aStrURL )
{
OUString aStrUiURL;
INetURLObject aURLObj( aStrURL );
switch(aURLObj.GetProtocol())
{
case INetProtocol::File:
osl::FileBase::getSystemPathFromFileURL(aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE), aStrUiURL);
break;
case INetProtocol::Ftp :
{
//remove password from name
INetURLObject aTmpURL(aURLObj);
aTmpURL.SetPass(u"");
aStrUiURL = aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
}
break;
default :
{
aStrUiURL = aURLObj.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous);
}
}
if(aStrUiURL.isEmpty())
return aStrURL;
return aStrUiURL;
}
}
// ComboBox-Control for URL's with History and Autocompletion
SvxHyperURLBox::SvxHyperURLBox(std::unique_ptr<weld::ComboBox> xControl)
: SvtURLBox(std::move(xControl))
, DropTargetHelper(getWidget()->get_drop_target())
{
SetSmartProtocol(INetProtocol::Http);
}
sal_Int8 SvxHyperURLBox::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
{
return IsDropFormatSupported( SotClipboardFormatId::STRING ) ? DND_ACTION_COPY : DND_ACTION_NONE;
}
sal_Int8 SvxHyperURLBox::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
TransferableDataHelper aDataHelper( rEvt.maDropEvent.Transferable );
OUString aString;
sal_Int8 nRet = DND_ACTION_NONE;
if( aDataHelper.GetString( SotClipboardFormatId::STRING, aString ) )
{
set_entry_text(aString);
nRet = DND_ACTION_COPY;
}
return nRet;
}
//# Hyperlink-Dialog: Tabpages-Baseclass #
SvxHyperlinkTabPageBase::SvxHyperlinkTabPageBase(weld::Container* pParent,
SvxHpLinkDlg* pDlg,
const OUString& rUIXMLDescription,
const OUString& rID,
const SfxItemSet* pItemSet)
: IconChoicePage(pParent, rUIXMLDescription, rID, pItemSet)
, mxCbbFrame(xBuilder->weld_combo_box(u"frame"_ustr))
, mxLbForm(xBuilder->weld_combo_box(u"form"_ustr))
, mxEdIndication(xBuilder->weld_entry(u"indication"_ustr))
, mxEdText(xBuilder->weld_entry(u"name"_ustr))
, mxBtScript(xBuilder->weld_button(u"script"_ustr))
, mxFormLabel(xBuilder->weld_label(u"form_label"_ustr))
, mxFrameLabel(xBuilder->weld_label(u"frame_label"_ustr))
, mbIsCloseDisabled( false )
, mpDialog( pDlg )
, mbStdControlsInit( false )
, maTimer("cui SvxHyperlinkTabPageBase maTimer")
{
// create bookmark-window
}
SvxHyperlinkTabPageBase::~SvxHyperlinkTabPageBase()
{
maTimer.Stop();
HideMarkWnd();
}
bool SvxHyperlinkTabPageBase::QueryClose()
{
return !mbIsCloseDisabled;
}
void SvxHyperlinkTabPageBase::InitStdControls ()
{
if ( !mbStdControlsInit )
{
SfxDispatcher* pDispatch = GetDispatcher();
SfxViewFrame* pViewFrame = pDispatch ? pDispatch->GetFrame() : nullptr;
SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
if ( pFrame )
{
TargetList aList;
SfxFrame::GetDefaultTargetList(aList);
if( !aList.empty() )
{
size_t nCount = aList.size();
size_t i;
for ( i = 0; i < nCount; i++ )
{
mxCbbFrame->append_text( aList.at( i ) );
}
}
}
mxBtScript->set_from_icon_name(RID_SVXBMP_SCRIPT);
mxBtScript->connect_clicked ( LINK ( this, SvxHyperlinkTabPageBase, ClickScriptHdl_Impl ) );
}
mbStdControlsInit = true;
}
// Move Extra-Window
void SvxHyperlinkTabPageBase::MoveToExtraWnd( Point aNewPos )
{
mxMarkWnd->MoveTo(aNewPos);
}
// Show Extra-Window
void SvxHyperlinkTabPageBase::ShowMarkWnd()
{
if (mxMarkWnd)
{
mxMarkWnd->getDialog()->present();
return;
}
weld::Dialog* pDialog = mpDialog->getDialog();
mxMarkWnd = std::make_shared<SvxHlinkDlgMarkWnd>(pDialog, this);
// Size of dialog-window in screen pixels
Point aDlgPos(pDialog->get_position());
Size aDlgSize(pDialog->get_size());
// Absolute size of the screen
::tools::Rectangle aScreen(pDialog->get_monitor_workarea());
// Size of Extrawindow
Size aExtraWndSize(mxMarkWnd->getDialog()->get_preferred_size());
// mxMarkWnd is a child of mpDialog, so coordinates for positioning must be relative to mpDialog
if( aDlgPos.X()+(1.05*aDlgSize.Width())+aExtraWndSize.Width() > aScreen.Right() )
{
if( aDlgPos.X() - ( 0.05*aDlgSize.Width() ) - aExtraWndSize.Width() < 0 )
{
// Pos Extrawindow anywhere
MoveToExtraWnd( Point(10,10) ); // very unlikely
}
else
{
// Pos Extrawindow on the left side of Dialog
MoveToExtraWnd( Point(0,0) - Point( tools::Long(0.05*aDlgSize.Width()), 0 ) - Point( aExtraWndSize.Width(), 0 ) );
}
}
else
{
// Pos Extrawindow on the right side of Dialog
MoveToExtraWnd ( Point( tools::Long(1.05*aDlgSize.getWidth()), 0 ) );
}
// Set size of Extra-Window
mxMarkWnd->getDialog()->set_size_request(aExtraWndSize.Width(), aDlgSize.Height());
weld::DialogController::runAsync(mxMarkWnd, [this](sal_Int32 /*nResult*/) { mxMarkWnd.reset(); } );
}
void SvxHyperlinkTabPageBase::HideMarkWnd()
{
if (mxMarkWnd)
{
mxMarkWnd->response(RET_CANCEL);
mxMarkWnd.reset();
}
}
// Fill Dialogfields
void SvxHyperlinkTabPageBase::FillStandardDlgFields ( const SvxHyperlinkItem* pHyperlinkItem )
{
if (!comphelper::LibreOfficeKit::isActive())
{
// Frame
sal_Int32 nPos = mxCbbFrame->find_text(pHyperlinkItem->GetTargetFrame());
if (nPos != -1)
mxCbbFrame->set_active(nPos);
// Form
OUString aStrFormText = CuiResId( RID_CUISTR_HYPERDLG_FROM_TEXT );
OUString aStrFormButton = CuiResId( RID_CUISTR_HYPERDLG_FORM_BUTTON );
if( pHyperlinkItem->GetInsertMode() & HLINK_HTMLMODE )
{
mxLbForm->clear();
mxLbForm->append_text( aStrFormText );
mxLbForm->set_active( 0 );
}
else
{
mxLbForm->clear();
mxLbForm->append_text( aStrFormText );
mxLbForm->append_text( aStrFormButton );
mxLbForm->set_active( pHyperlinkItem->GetInsertMode() == HLINK_BUTTON ? 1 : 0 );
}
}
else
{
mxCbbFrame->hide();
mxLbForm->hide();
mxFormLabel->hide();
mxFrameLabel->hide();
}
// URL
mxEdIndication->set_text( pHyperlinkItem->GetName() );
// Name
mxEdText->set_text( pHyperlinkItem->GetIntName() );
// Script-button
if (!comphelper::LibreOfficeKit::isActive())
{
if ( pHyperlinkItem->GetMacroEvents() == HyperDialogEvent::NONE )
mxBtScript->set_sensitive(false);
else
mxBtScript->set_sensitive(true);
}
else
{
mxBtScript->hide();
}
}
// Any action to do after apply-button is pressed
void SvxHyperlinkTabPageBase::DoApply ()
{
// default-implementation : do nothing
}
// This method would be called from bookmark-window to set new mark-string
void SvxHyperlinkTabPageBase::SetMarkStr ( const OUString& /*aStrMark*/ )
{
// default-implementation : do nothing
}
// Set initial focus
void SvxHyperlinkTabPageBase::SetInitFocus()
{
xContainer->grab_focus();
}
// retrieve dispatcher
SfxDispatcher* SvxHyperlinkTabPageBase::GetDispatcher() const
{
return mpDialog->GetDispatcher();
}
void SvxHyperlinkTabPageBase::DisableClose(bool _bDisable)
{
mbIsCloseDisabled = _bDisable;
if (mbIsCloseDisabled)
maBusy.incBusy(mpDialog->getDialog());
else
maBusy.decBusy();
}
// Click on imagebutton : Script
IMPL_LINK_NOARG(SvxHyperlinkTabPageBase, ClickScriptHdl_Impl, weld::Button&, void)
{
SvxHyperlinkItem *pHyperlinkItem = const_cast<SvxHyperlinkItem*>(
GetItemSet().GetItem (SID_HYPERLINK_GETLINK));
if (!pHyperlinkItem || pHyperlinkItem->GetMacroEvents() == HyperDialogEvent::NONE)
return;
// get macros from itemset
const SvxMacroTableDtor* pMacroTbl = pHyperlinkItem->GetMacroTable();
SvxMacroItem aItem ( SID_ATTR_MACROITEM );
if( pMacroTbl )
aItem.SetMacroTable( *pMacroTbl );
// create empty itemset for macro-dlg
auto xItemSet = std::make_unique<SfxItemSetFixed<SID_ATTR_MACROITEM, SID_ATTR_MACROITEM>>( SfxGetpApp()->GetPool() );
xItemSet->Put( aItem );
DisableClose( true );
SfxMacroAssignDlg aDlg(mpDialog->getDialog(), mxDocumentFrame, std::move(xItemSet));
// add events
SfxMacroTabPage *pMacroPage = aDlg.GetTabPage();
if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseOverObject )
pMacroPage->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT1),
SvMacroItemId::OnMouseOver );
if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseClickObject )
pMacroPage->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT2),
SvMacroItemId::OnClick);
if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseOutObject )
pMacroPage->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT3),
SvMacroItemId::OnMouseOut);
// execute dlg
short nRet = aDlg.run();
DisableClose( false );
if ( RET_OK == nRet )
{
const SfxItemSet* pOutSet = aDlg.GetOutputItemSet();
const SfxPoolItem* pItem;
if( SfxItemState::SET == pOutSet->GetItemState( SID_ATTR_MACROITEM, false, &pItem ))
{
pHyperlinkItem->SetMacroTable( static_cast<const SvxMacroItem*>(pItem)->GetMacroTable() );
}
}
}
// Get Macro-Infos
HyperDialogEvent SvxHyperlinkTabPageBase::GetMacroEvents() const
{
const SvxHyperlinkItem *pHyperlinkItem =
GetItemSet().GetItem (SID_HYPERLINK_GETLINK);
return pHyperlinkItem ? pHyperlinkItem->GetMacroEvents() : HyperDialogEvent();
}
SvxMacroTableDtor* SvxHyperlinkTabPageBase::GetMacroTable()
{
const SvxHyperlinkItem *pHyperlinkItem =
GetItemSet().GetItem (SID_HYPERLINK_GETLINK);
return const_cast<SvxMacroTableDtor*>(pHyperlinkItem->GetMacroTable());
}
// try to detect the current protocol that is used in rStrURL
OUString SvxHyperlinkTabPageBase::GetSchemeFromURL( const OUString& rStrURL )
{
OUString aStrScheme;
INetURLObject aURL( rStrURL );
INetProtocol aProtocol = aURL.GetProtocol();
// our new INetUrlObject now has the ability
// to detect if a Url is valid or not :-(
if ( aProtocol == INetProtocol::NotValid )
{
if ( rStrURL.startsWithIgnoreAsciiCase( INET_HTTP_SCHEME ) )
{
aStrScheme = INET_HTTP_SCHEME;
}
else if ( rStrURL.startsWithIgnoreAsciiCase( INET_HTTPS_SCHEME ) )
{
aStrScheme = INET_HTTPS_SCHEME;
}
else if ( rStrURL.startsWithIgnoreAsciiCase( INET_FTP_SCHEME ) )
{
aStrScheme = INET_FTP_SCHEME;
}
else if ( rStrURL.startsWithIgnoreAsciiCase( INET_MAILTO_SCHEME ) )
{
aStrScheme = INET_MAILTO_SCHEME;
}
}
else
aStrScheme = INetURLObject::GetScheme( aProtocol );
return aStrScheme;
}
void SvxHyperlinkTabPageBase::GetDataFromCommonFields( OUString& aStrName,
OUString& aStrIntName, OUString& aStrFrame,
SvxLinkInsertMode& eMode )
{
aStrIntName = mxEdText->get_text();
aStrName = mxEdIndication->get_text();
aStrFrame = mxCbbFrame->get_active_text();
sal_Int32 nPos = mxLbForm->get_active();
if (nPos == -1)
// This happens when FillStandardDlgFields() hides mpLbForm.
nPos = 0;
eMode = static_cast<SvxLinkInsertMode>(nPos + 1);
// Ask dialog whether the current doc is a HTML-doc
if (mpDialog->IsHTMLDoc())
eMode = static_cast<SvxLinkInsertMode>( sal_uInt16(eMode) | HLINK_HTMLMODE );
}
// reset dialog-fields
void SvxHyperlinkTabPageBase::Reset( const SfxItemSet& rItemSet )
{
// Set dialog-fields from create-itemset
maStrInitURL.clear();
const SvxHyperlinkItem *pHyperlinkItem =
rItemSet.GetItem (SID_HYPERLINK_GETLINK);
if ( pHyperlinkItem )
{
// set dialog-fields
FillStandardDlgFields (pHyperlinkItem);
// set all other fields
FillDlgFields(pHyperlinkItem->GetURL());
// Store initial URL
maStrInitURL = pHyperlinkItem->GetURL();
}
}
// Fill output-ItemSet
bool SvxHyperlinkTabPageBase::FillItemSet( SfxItemSet* rOut)
{
OUString aStrURL, aStrName, aStrIntName, aStrFrame;
SvxLinkInsertMode eMode;
GetCurrentItemData ( aStrURL, aStrName, aStrIntName, aStrFrame, eMode);
if ( aStrName.isEmpty() ) //automatically create a visible name if the link is created without name
aStrName = CreateUiNameFromURL(aStrURL);
HyperDialogEvent nEvents = GetMacroEvents();
SvxMacroTableDtor* pTable = GetMacroTable();
SvxHyperlinkItem aItem( SID_HYPERLINK_SETLINK, aStrName, aStrURL, aStrFrame,
aStrIntName, eMode, nEvents, pTable );
rOut->Put (aItem);
return true;
}
// Activate / Deactivate Tabpage
void SvxHyperlinkTabPageBase::ActivatePage( const SfxItemSet& rItemSet )
{
// Set dialog-fields from input-itemset
const SvxHyperlinkItem *pHyperlinkItem =
rItemSet.GetItem (SID_HYPERLINK_GETLINK);
if ( pHyperlinkItem )
{
// standard-fields
FillStandardDlgFields (pHyperlinkItem);
}
// show mark-window if it was open before
if ( ShouldOpenMarkWnd () )
ShowMarkWnd ();
}
DeactivateRC SvxHyperlinkTabPageBase::DeactivatePage( SfxItemSet* _pSet)
{
// hide mark-wnd
SetMarkWndShouldOpen( IsMarkWndVisible () );
HideMarkWnd ();
// retrieve data of dialog
OUString aStrURL, aStrName, aStrIntName, aStrFrame;
SvxLinkInsertMode eMode;
GetCurrentItemData ( aStrURL, aStrName, aStrIntName, aStrFrame, eMode);
HyperDialogEvent nEvents = GetMacroEvents();
SvxMacroTableDtor* pTable = GetMacroTable();
if( _pSet )
{
SvxHyperlinkItem aItem( SID_HYPERLINK_GETLINK, aStrName, aStrURL, aStrFrame,
aStrIntName, eMode, nEvents, pTable );
_pSet->Put( aItem );
}
return DeactivateRC::LeavePage;
}
bool SvxHyperlinkTabPageBase::ShouldOpenMarkWnd()
{
return false;
}
void SvxHyperlinkTabPageBase::SetMarkWndShouldOpen(bool)
{
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */