Files
libreoffice/cui/source/dialogs/cuihyperdlg.cxx

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

298 lines
9.3 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes: clarify Option->Language UI option Patch contributed by Herbert Duerr http://svn.apache.org/viewvc?view=revision&revision=1173991 cws mba34issues01: #i117712#: fix several resource errors introduced by IAccessible2 implementation Patch contributed by Mathias Bauer http://svn.apache.org/viewvc?view=revision&revision=1173991 cws mba34issues01: #i117709#: add missing string resource Patch contributed by Mathias Bauer http://svn.apache.org/viewvc?view=revision&revision=1172348 cws mba34issues01: #i117716#: fix missing resources my removing unused code Patch contributed by Mathias Bauer http://svn.apache.org/viewvc?view=revision&revision=1172345 re-add Crystal, Tango, Oxygen icon theme listings. correct method signature Patch contributed by Jean-Louis 'Hans' Fuchs http://svn.apache.org/viewvc?view=revision&revision=1306725 i#119063 - correct serf integration Patch contributed by Oliver-Rainer Wittmann http://svn.apache.org/viewvc?view=revision&revision=1300521 i#119036 - adapt serf integration -- use transfer-encoding 'chunked' on HTTPS -- switch transfer-encoding between 'chunked' and none on 413 HTTP status code -- refactoring -- improve user experience of certification dialog - only shown once Patch contributed by Oliver-Rainer Wittmann http://svn.apache.org/viewvc?view=revision&revision=1299727 118569: Use whole certification chain for verification. Patch contributed by Andre Fischer http://svn.apache.org/viewvc?view=revision&revision=1295493 serf integration: improve credential input handling Patch contributed by Oliver-Rainer Wittmann http://svn.apache.org/viewvc?view=revision&revision=1294557 warning-free ucb/source/ucp/webdav Patch contributed by Pavel Janik http://svn.apache.org/viewvc?view=revision&revision=1294086 some refactoring to PROPPATCH and PROPFIND requests Patch contributed by Oliver-Rainer Wittmann http://svn.apache.org/viewvc?view=revision&revision=1293281 i#118569: Replace neon with serf Patch contributed by Oliver-Rainer Wittmann http://svn.apache.org/viewvc?view=revision&revision=1292832 http://svn.apache.org/viewvc?view=revision&revision=1292794 remove OS/2 conditionals for now. re-enable webdav unit tests.
2012-10-04 11:25:41 +01:00
/*
* 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 .
*/
2009-10-31 00:36:06 +01:00
#include <sal/config.h>
#include <osl/diagnose.h>
#include <comphelper/lok.hxx>
2009-10-31 00:36:06 +01:00
#include <unotools/viewoptions.hxx>
#include <cuihyperdlg.hxx>
#include <hlinettp.hxx>
#include <hlmailtp.hxx>
#include <hldoctp.hxx>
#include <hldocntp.hxx>
#include <sfx2/app.hxx>
#include <sfx2/viewfrm.hxx>
#include <svl/eitem.hxx>
#include <svx/svxids.hrc>
#include <dialmgr.hxx>
#include <strings.hrc>
#include <vector>
2009-10-31 00:36:06 +01:00
using ::com::sun::star::uno::Reference;
using ::com::sun::star::frame::XFrame;
2009-10-31 00:36:06 +01:00
//# #
//# Childwindow-Wrapper-Class #
//# #
2009-10-31 00:36:06 +01:00
SvxHlinkCtrl::SvxHlinkCtrl( sal_uInt16 _nId, SfxBindings & rBindings, SvxHpLinkDlg* pDlg )
: SfxControllerItem ( _nId, rBindings )
, aRdOnlyForwarder ( SID_READONLY_MODE, *this )
2009-10-31 00:36:06 +01:00
{
pParent = pDlg;
}
void SvxHlinkCtrl::dispose()
{
pParent = nullptr;
aRdOnlyForwarder.dispose();
::SfxControllerItem::dispose();
}
void SvxHlinkCtrl::StateChangedAtToolBoxControl( sal_uInt16 nSID, SfxItemState eState,
2009-10-31 00:36:06 +01:00
const SfxPoolItem* pState )
{
if (!(eState == SfxItemState::DEFAULT && pParent))
return;
switch ( nSID )
2009-10-31 00:36:06 +01:00
{
case SID_HYPERLINK_GETLINK :
{
pParent->SetPage( static_cast<const SvxHyperlinkItem*>(pState) );
}
break;
case SID_READONLY_MODE :
2009-10-31 00:36:06 +01:00
{
pParent->SetReadOnlyMode( static_cast<const SfxBoolItem*>(pState)->GetValue() );
2009-10-31 00:36:06 +01:00
}
break;
2009-10-31 00:36:06 +01:00
}
}
// tdf#90496 - remember last used view in hyperlink dialog
OUString SvxHpLinkDlg::msRememberedPageId("internet");
2009-10-31 00:36:06 +01:00
//# #
//# Hyperlink - Dialog #
//# #
SvxHpLinkDlg::SvxHpLinkDlg(SfxBindings* pBindings, SfxChildWindow* pChild, weld::Window* pParent)
: SfxModelessDialogController(pBindings, pChild, pParent, "cui/ui/hyperlinkdialog.ui", "HyperlinkDialog")
, pSet ( nullptr )
, maCtrl ( SID_HYPERLINK_GETLINK, *pBindings, this )
, mbIsHTMLDoc ( false )
, m_xIconCtrl(m_xBuilder->weld_notebook("tabcontrol"))
, m_xOKBtn(m_xBuilder->weld_button("ok"))
, m_xApplyBtn(m_xBuilder->weld_button("apply"))
, m_xCancelBtn(m_xBuilder->weld_button("cancel"))
, m_xHelpBtn(m_xBuilder->weld_button("help"))
, m_xResetBtn(m_xBuilder->weld_button("reset"))
2009-10-31 00:36:06 +01:00
{
m_xIconCtrl->connect_enter_page( LINK ( this, SvxHpLinkDlg, ChosePageHdl_Impl ) );
m_xIconCtrl->show();
// ItemSet
if ( pSet )
{
pExampleSet.reset(new SfxItemSet( *pSet ));
pOutSet.reset(new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ));
}
// Buttons
m_xOKBtn->show();
m_xApplyBtn->show();
m_xCancelBtn->show();
m_xHelpBtn->show();
m_xResetBtn->show();
mbGrabFocus = true;
// set OK/Cancel - button
m_xCancelBtn->set_label(CuiResId(RID_CUISTR_HYPDLG_CLOSEBUT));
2009-10-31 00:36:06 +01:00
// create itemset for tabpages
mpItemSet = std::make_unique<SfxItemSetFixed<SID_HYPERLINK_GETLINK,
SID_HYPERLINK_SETLINK>>( SfxGetpApp()->GetPool());
2009-10-31 00:36:06 +01:00
SvxHyperlinkItem aItem(SID_HYPERLINK_GETLINK);
mpItemSet->Put(aItem);
2009-10-31 00:36:06 +01:00
SetInputSet (mpItemSet.get());
2009-10-31 00:36:06 +01:00
// insert pages
AddTabPage("internet", SvxHyperlinkInternetTp::Create);
AddTabPage("mail", SvxHyperlinkMailTp::Create);
if (!comphelper::LibreOfficeKit::isActive())
{
AddTabPage("document", SvxHyperlinkDocTp::Create);
AddTabPage("newdocument", SvxHyperlinkNewDocTp::Create);
}
// tdf#90496 - remember last used view in hyperlink dialog
SetCurPageId(msRememberedPageId);
2009-10-31 00:36:06 +01:00
// Init Dialog
Start();
2009-10-31 00:36:06 +01:00
Reliably set up controls of hyperlink dialog in constructor The recently added test_insert_hyperlink in sw/qa/uitest/writer_tests3/hyperlinkdialog.py (UITest_writer_tests3) has often failed on slow builds like <https://ci.libreoffice.org/job/lo_ubsan/>, by hitting the assert in rtl_uString_newFromSubString as described at <https://lists.freedesktop.org/archives/libreoffice/2020-July/085594.html> "Race with SwEditWinUIObject::get_state during UITest_writer_tests3?" However, it turns out that the actual race is rather different from what was assumed there: The initial content of the dialog's controls like "target" and "indication" were only set during the first SvxHlinkCtrl::StateChanged(SID_HYERLINK_GETLINK), which is called from the SfxBindings machinery based on a timer. When that happens, any text that has already been typed into those controls by the user would be overwritten again. But in normal GUI operations, the timer fires so quickly that the user has not yet typed anything into those controls. On the other hand, for a typical (fast) execution of test_insert_hyperlink, the whole test has already been executed when the timer fires, so the overwriting is not noticed. But for a slow execution of the test, the timer may e.g. fire after the "indication" control's content ("link") has been typed in (which SvxHlinkCtrl::StateChanged will reset to the empty string) and before the dialog is closed (so instead of "link", the empty string will be added to the Writer document, and obtaining the text selection of length 4 will crash as described in the email). (Also, the two calls to wait_until_property_is_updated added with 27798238ecb200e0753b013c79df0e6c014c7a7a "uitest : Avoid any timing issue in test_insert_hyperlink" and 1cdda798def040fe778348061c0e18b28aa0e6bd "Further timing issues with test_insert_hyperlink" probably just address other symptoms caused by the same underlying issue, and should no longer be necessary with this fix. But cleaning that up is left for a follow-up commit.) The solution is to set up the controls' initial content already in the constructor, so when the SfxBindings timer fires for the first time, it no longer calls StateChanged because that state has already been recorded. However, that caused the focus no longer to be set to the "target" control when the dialog is opened, at least for the gen and svp VCL backends (which caused the .uno:HyperlinkDialog-related tests in desktop/qa/desktop_lib/test_desktop_lib.cxx, CppunitTest_desktop_lib, to fail because GetFocusControl returned null): The first call to SvxHlinkCtrl::StateChanged -> SvxHplinkDlg::SetPage now happens during the constructor, before the dialog is shown, so the request to grab the focus in SetInitFocus was ignored. The solution to that problem is to shift setting the initial focus to the first call of SvxHpLInkDlg::Activate, which is called whenever the dialog gains focus. Change-Id: Ib4d5e06dfc21014ccec546565426fa2d27e63ce1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99903 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2020-07-31 22:38:09 +02:00
GetBindings().Update(SID_HYPERLINK_GETLINK);
GetBindings().Update(SID_READONLY_MODE);
2009-10-31 00:36:06 +01:00
m_xResetBtn->connect_clicked( LINK( this, SvxHpLinkDlg, ResetHdl ) );
m_xOKBtn->connect_clicked( LINK ( this, SvxHpLinkDlg, ClickOkHdl_Impl ) );
m_xApplyBtn->connect_clicked ( LINK ( this, SvxHpLinkDlg, ClickApplyHdl_Impl ) );
2009-10-31 00:36:06 +01:00
}
SvxHpLinkDlg::~SvxHpLinkDlg()
{
mbGrabFocus = false; // don't do any grab if tear-down moves focus around during destruction
// delete config item, so the base class (SfxModelessDialogController) can not load it on the next start
SvtViewOptions aViewOpt( EViewType::TabDialog, OUString::number(SID_HYPERLINK_DIALOG) );
2009-10-31 00:36:06 +01:00
aViewOpt.Delete();
mpItemSet.reset();
maCtrl.dispose();
maPageList.clear();
pRanges.reset();
pOutSet.reset();
2009-10-31 00:36:06 +01:00
}
Reliably set up controls of hyperlink dialog in constructor The recently added test_insert_hyperlink in sw/qa/uitest/writer_tests3/hyperlinkdialog.py (UITest_writer_tests3) has often failed on slow builds like <https://ci.libreoffice.org/job/lo_ubsan/>, by hitting the assert in rtl_uString_newFromSubString as described at <https://lists.freedesktop.org/archives/libreoffice/2020-July/085594.html> "Race with SwEditWinUIObject::get_state during UITest_writer_tests3?" However, it turns out that the actual race is rather different from what was assumed there: The initial content of the dialog's controls like "target" and "indication" were only set during the first SvxHlinkCtrl::StateChanged(SID_HYERLINK_GETLINK), which is called from the SfxBindings machinery based on a timer. When that happens, any text that has already been typed into those controls by the user would be overwritten again. But in normal GUI operations, the timer fires so quickly that the user has not yet typed anything into those controls. On the other hand, for a typical (fast) execution of test_insert_hyperlink, the whole test has already been executed when the timer fires, so the overwriting is not noticed. But for a slow execution of the test, the timer may e.g. fire after the "indication" control's content ("link") has been typed in (which SvxHlinkCtrl::StateChanged will reset to the empty string) and before the dialog is closed (so instead of "link", the empty string will be added to the Writer document, and obtaining the text selection of length 4 will crash as described in the email). (Also, the two calls to wait_until_property_is_updated added with 27798238ecb200e0753b013c79df0e6c014c7a7a "uitest : Avoid any timing issue in test_insert_hyperlink" and 1cdda798def040fe778348061c0e18b28aa0e6bd "Further timing issues with test_insert_hyperlink" probably just address other symptoms caused by the same underlying issue, and should no longer be necessary with this fix. But cleaning that up is left for a follow-up commit.) The solution is to set up the controls' initial content already in the constructor, so when the SfxBindings timer fires for the first time, it no longer calls StateChanged because that state has already been recorded. However, that caused the focus no longer to be set to the "target" control when the dialog is opened, at least for the gen and svp VCL backends (which caused the .uno:HyperlinkDialog-related tests in desktop/qa/desktop_lib/test_desktop_lib.cxx, CppunitTest_desktop_lib, to fail because GetFocusControl returned null): The first call to SvxHlinkCtrl::StateChanged -> SvxHplinkDlg::SetPage now happens during the constructor, before the dialog is shown, so the request to grab the focus in SetInitFocus was ignored. The solution to that problem is to shift setting the initial focus to the first call of SvxHpLInkDlg::Activate, which is called whenever the dialog gains focus. Change-Id: Ib4d5e06dfc21014ccec546565426fa2d27e63ce1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99903 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2020-07-31 22:38:09 +02:00
void SvxHpLinkDlg::Activate() {
if (mbGrabFocus) {
static_cast<SvxHyperlinkTabPageBase *>(GetTabPage(GetCurPageId()))->SetInitFocus();
mbGrabFocus = false;
}
SfxModelessDialogController::Activate();
}
void SvxHpLinkDlg::Close()
2009-10-31 00:36:06 +01:00
{
if (IsClosing())
return;
if (SfxViewFrame* pViewFrame = SfxViewFrame::Current())
pViewFrame->ToggleChildWindow(SID_HYPERLINK_DIALOG);
2009-10-31 00:36:06 +01:00
}
void SvxHpLinkDlg::Apply()
{
SfxItemSetFixed<SID_HYPERLINK_GETLINK, SID_HYPERLINK_SETLINK> aItemSet( SfxGetpApp()->GetPool() );
SvxHyperlinkTabPageBase* pCurrentPage = static_cast<SvxHyperlinkTabPageBase*>(
GetTabPage( GetCurPageId() ) );
pCurrentPage->FillItemSet( &aItemSet );
const SvxHyperlinkItem *aItem = aItemSet.GetItem(SID_HYPERLINK_SETLINK);
if ( !aItem->GetURL().isEmpty() )
GetDispatcher()->ExecuteList(SID_HYPERLINK_SETLINK,
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { aItem });
static_cast<SvxHyperlinkTabPageBase*>( GetTabPage( GetCurPageId() ) )->DoApply();
}
/// Click on OK button
IMPL_LINK_NOARG(SvxHpLinkDlg, ClickOkHdl_Impl, weld::Button&, void)
{
Apply();
m_xDialog->response(RET_OK);
}
2009-10-31 00:36:06 +01:00
/*************************************************************************
|*
|* Click on Apply-button
2009-10-31 00:36:06 +01:00
|*
|************************************************************************/
IMPL_LINK_NOARG(SvxHpLinkDlg, ClickApplyHdl_Impl, weld::Button&, void)
2009-10-31 00:36:06 +01:00
{
Apply();
2009-10-31 00:36:06 +01:00
}
/*************************************************************************
|*
|* Set Page
|*
|************************************************************************/
void SvxHpLinkDlg::SetPage ( SvxHyperlinkItem const * pItem )
2009-10-31 00:36:06 +01:00
{
OUString sPageId("internet");
2009-10-31 00:36:06 +01:00
OUString aStrURL(pItem->GetURL());
INetURLObject aURL(aStrURL);
2009-10-31 00:36:06 +01:00
INetProtocol eProtocolTyp = aURL.GetProtocol();
switch ( eProtocolTyp )
{
case INetProtocol::Http :
case INetProtocol::Ftp :
sPageId = "internet";
2009-10-31 00:36:06 +01:00
break;
case INetProtocol::File :
sPageId = "document";
2009-10-31 00:36:06 +01:00
break;
case INetProtocol::Mailto :
sPageId = "mail";
2009-10-31 00:36:06 +01:00
break;
default :
if (aStrURL.startsWith("#"))
sPageId = "document";
2009-10-31 00:36:06 +01:00
else
{
// not valid
sPageId = GetCurPageId();
2009-10-31 00:36:06 +01:00
}
break;
}
ShowPage (sPageId);
2009-10-31 00:36:06 +01:00
SvxHyperlinkTabPageBase* pCurrentPage = static_cast<SvxHyperlinkTabPageBase*>(GetTabPage( sPageId ));
2009-10-31 00:36:06 +01:00
mbIsHTMLDoc = (pItem->GetInsertMode() & HLINK_HTMLMODE) != 0;
2009-10-31 00:36:06 +01:00
IconChoicePage* pPage = GetTabPage (sPageId);
if(pPage)
2009-10-31 00:36:06 +01:00
{
SfxItemSet& aPageSet = const_cast<SfxItemSet&>(pPage->GetItemSet ());
aPageSet.Put ( *pItem );
pCurrentPage->Reset( aPageSet );
2009-10-31 00:36:06 +01:00
}
}
/*************************************************************************
|*
|* Enable/Disable ReadOnly mode
|*
|************************************************************************/
void SvxHpLinkDlg::SetReadOnlyMode( bool bRdOnly )
2009-10-31 00:36:06 +01:00
{
m_xOKBtn->set_sensitive(!bRdOnly);
2009-10-31 00:36:06 +01:00
}
/*************************************************************************
|*
|* late-initialization of newly created pages
|*
|************************************************************************/
void SvxHpLinkDlg::PageCreated(IconChoicePage& rPage)
2009-10-31 00:36:06 +01:00
{
SvxHyperlinkTabPageBase& rHyperlinkPage = dynamic_cast< SvxHyperlinkTabPageBase& >( rPage );
Reference< XFrame > xDocumentFrame = GetBindings().GetActiveFrame();
2009-10-31 00:36:06 +01:00
OSL_ENSURE( xDocumentFrame.is(), "SvxHpLinkDlg::PageCreated: macro assignment functionality won't work with a proper frame!" );
rHyperlinkPage.SetDocumentFrame( xDocumentFrame );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */