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 .
20 #include <vcl/svapp.hxx>
21 #include <vcl/settings.hxx>
22 #include <svl/numformat.hxx>
23 #include <svl/zforlist.hxx>
24 #include "optupdt.hxx"
25 #include <comphelper/processfactory.hxx>
26 #include <com/sun/star/configuration/theDefaultProvider.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
29 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
30 #include <com/sun/star/deployment/UpdateInformationProvider.hpp>
31 #include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
32 #include <com/sun/star/frame/Desktop.hpp>
33 #include <com/sun/star/frame/XDispatchProvider.hpp>
34 #include <com/sun/star/util/XChangesBatch.hpp>
35 #include <com/sun/star/util/URLTransformer.hpp>
36 #include <com/sun/star/util/XURLTransformer.hpp>
37 #include <com/sun/star/setup/UpdateCheckConfig.hpp>
38 #include <com/sun/star/configuration/ReadWriteAccess.hpp>
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <com/sun/star/beans/NamedValue.hpp>
41 #include <sfx2/filedlghelper.hxx>
42 #include <officecfg/Office/Common.hxx>
43 #include <osl/file.hxx>
44 #include <osl/security.hxx>
45 #include <comphelper/diagnose_ex.hxx>
46 #include <unotools/configmgr.hxx>
48 using namespace ::css
;
50 SvxOnlineUpdateTabPage::SvxOnlineUpdateTabPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rSet
)
51 : SfxTabPage(pPage
, pController
, "cui/ui/optonlineupdatepage.ui", "OptOnlineUpdatePage", &rSet
)
52 , m_xNeverChecked(m_xBuilder
->weld_label("neverchecked"))
53 , m_xAutoCheckCheckBox(m_xBuilder
->weld_check_button("autocheck"))
54 , m_xEveryDayButton(m_xBuilder
->weld_radio_button("everyday"))
55 , m_xEveryWeekButton(m_xBuilder
->weld_radio_button("everyweek"))
56 , m_xEveryMonthButton(m_xBuilder
->weld_radio_button("everymonth"))
57 , m_xCheckNowButton(m_xBuilder
->weld_button("checknow"))
58 , m_xAutoDownloadCheckBox(m_xBuilder
->weld_check_button("autodownload"))
59 , m_xDestPathLabel(m_xBuilder
->weld_label("destpathlabel"))
60 , m_xDestPath(m_xBuilder
->weld_label("destpath"))
61 , m_xChangePathButton(m_xBuilder
->weld_button("changepath"))
62 , m_xLastChecked(m_xBuilder
->weld_label("lastchecked"))
63 , m_xExtrasCheckBox(m_xBuilder
->weld_check_button("extrabits"))
64 , m_xUserAgentLabel(m_xBuilder
->weld_label("useragent"))
65 , m_xPrivacyPolicyButton(m_xBuilder
->weld_link_button("btnPrivacyPolicy"))
67 m_aNeverChecked
= m_xNeverChecked
->get_label();
69 m_xAutoCheckCheckBox
->connect_toggled( LINK( this, SvxOnlineUpdateTabPage
, AutoCheckHdl_Impl
) );
70 m_xExtrasCheckBox
->connect_toggled( LINK( this, SvxOnlineUpdateTabPage
, ExtrasCheckHdl_Impl
) );
71 m_xCheckNowButton
->connect_clicked( LINK( this, SvxOnlineUpdateTabPage
, CheckNowHdl_Impl
) );
72 m_xChangePathButton
->connect_clicked( LINK( this, SvxOnlineUpdateTabPage
, FileDialogHdl_Impl
) );
73 m_xPrivacyPolicyButton
->set_uri(
74 officecfg::Office::Common::Menus::PrivacyPolicyURL::get()
75 + "?type=updatecheck&LOvers=" + utl::ConfigManager::getProductVersion()
76 + "&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getBcp47());
79 uno::Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
81 m_xUpdateAccess
= setup::UpdateCheckConfig::create( xContext
);
82 m_xReadWriteAccess
= css::configuration::ReadWriteAccess::create(xContext
, "*");
84 bool bDownloadSupported
= false;
85 m_xUpdateAccess
->getByName( "DownloadSupported" ) >>= bDownloadSupported
;
87 m_xAutoDownloadCheckBox
->set_visible(bDownloadSupported
);
88 m_xDestPathLabel
->set_visible(bDownloadSupported
);
89 m_xDestPath
->set_visible(bDownloadSupported
);
90 m_xChangePathButton
->set_visible(bDownloadSupported
);
92 m_aLastCheckedTemplate
= m_xLastChecked
->get_label();
94 UpdateLastCheckedText();
98 SvxOnlineUpdateTabPage::~SvxOnlineUpdateTabPage()
102 void SvxOnlineUpdateTabPage::UpdateLastCheckedText()
105 sal_Int64 lastChecked
= 0;
107 m_xUpdateAccess
->getByName("LastCheck") >>= lastChecked
;
109 if( lastChecked
== 0 ) // never checked
111 aText
= m_aNeverChecked
;
115 TimeValue lastCheckedTV
;
116 oslDateTime lastCheckedDT
;
118 Date
aDate( Date::EMPTY
);
119 tools::Time
aTime( tools::Time::EMPTY
);
121 lastCheckedTV
.Seconds
= static_cast<sal_uInt32
>(lastChecked
);
122 osl_getLocalTimeFromSystemTime( &lastCheckedTV
, &lastCheckedTV
);
124 if ( osl_getDateTimeFromTimeValue( &lastCheckedTV
, &lastCheckedDT
) )
126 aDate
= Date( lastCheckedDT
.Day
, lastCheckedDT
.Month
, lastCheckedDT
.Year
);
127 aTime
= ::tools::Time( lastCheckedDT
.Hours
, lastCheckedDT
.Minutes
);
130 LanguageType eUILang
= Application::GetSettings().GetUILanguageTag().getLanguageType();
131 std::optional
<SvNumberFormatter
> pNumberFormatter( std::in_place
, ::comphelper::getProcessComponentContext(), eUILang
);
132 const Color
* pColor
= nullptr;
133 const Date
& rNullDate
= pNumberFormatter
->GetNullDate();
134 sal_uInt32 nFormat
= pNumberFormatter
->GetStandardFormat( SvNumFormatType::DATE
, eUILang
);
137 pNumberFormatter
->GetOutputString( aDate
- rNullDate
, nFormat
, aDateStr
, &pColor
);
139 nFormat
= pNumberFormatter
->GetStandardFormat( SvNumFormatType::TIME
, eUILang
);
141 pNumberFormatter
->GetOutputString( aTime
.GetTimeInDays(), nFormat
, aTimeStr
, &pColor
);
143 pNumberFormatter
.reset();
145 aText
= m_aLastCheckedTemplate
;
146 sal_Int32 nIndex
= aText
.indexOf( "%DATE%" );
148 aText
= aText
.replaceAt( nIndex
, 6, aDateStr
);
150 nIndex
= aText
.indexOf( "%TIME%" );
152 aText
= aText
.replaceAt( nIndex
, 6, aTimeStr
);
155 m_xLastChecked
->set_label(aText
);
158 void SvxOnlineUpdateTabPage::UpdateUserAgent()
161 uno::Reference
< ucb::XWebDAVCommandEnvironment
> xDav(
162 css::deployment::UpdateInformationProvider::create(
163 ::comphelper::getProcessComponentContext() ),
164 css::uno::UNO_QUERY_THROW
);
166 OUString aPseudoURL
= "useragent:normal";
167 if( m_xExtrasCheckBox
->get_active() )
168 aPseudoURL
= "useragent:extended";
169 const uno::Sequence
< beans::StringPair
> aHeaders
170 = xDav
->getUserRequestHeaders( aPseudoURL
, ucb::WebDAVHTTPMethod(0) );
172 for (const css::beans::StringPair
& aHeader
: aHeaders
)
174 if ( aHeader
.First
== "User-Agent" )
176 OUString aText
= aHeader
.Second
;
177 aText
= aText
.replaceAll(";", ";\n");
178 aText
= aText
.replaceAll("(", "\n(");
179 m_xUserAgentLabel
->set_label(aText
);
183 } catch (const uno::Exception
&) {
184 TOOLS_WARN_EXCEPTION( "cui.options", "Unexpected exception fetching User Agent" );
188 std::unique_ptr
<SfxTabPage
> SvxOnlineUpdateTabPage::Create( weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rAttrSet
)
190 return std::make_unique
<SvxOnlineUpdateTabPage
>( pPage
, pController
, *rAttrSet
);
193 bool SvxOnlineUpdateTabPage::FillItemSet( SfxItemSet
* )
195 bool bModified
= false;
200 if( m_xAutoCheckCheckBox
->get_state_changed_from_saved() )
202 bValue
= m_xAutoCheckCheckBox
->get_active();
203 m_xUpdateAccess
->replaceByName( "AutoCheckEnabled", uno::Any( bValue
) );
208 if( m_xEveryDayButton
->get_active() )
210 if( !m_xEveryDayButton
->get_saved_state() )
213 else if( m_xEveryWeekButton
->get_active() )
215 if( !m_xEveryWeekButton
->get_saved_state() )
218 else if( m_xEveryMonthButton
->get_active() )
220 if( !m_xEveryMonthButton
->get_saved_state() )
226 m_xUpdateAccess
->replaceByName( "CheckInterval", uno::Any( nValue
) );
230 if( m_xAutoDownloadCheckBox
->get_state_changed_from_saved() )
232 bValue
= m_xAutoDownloadCheckBox
->get_active();
233 m_xUpdateAccess
->replaceByName( "AutoDownloadEnabled", uno::Any( bValue
) );
237 OUString sValue
, aURL
;
238 m_xUpdateAccess
->getByName( "DownloadDestination" ) >>= sValue
;
240 if( ( osl::FileBase::E_None
== osl::FileBase::getFileURLFromSystemPath(m_xDestPath
->get_label(), aURL
) ) &&
243 m_xUpdateAccess
->replaceByName( "DownloadDestination", uno::Any( aURL
) );
247 if( m_xExtrasCheckBox
->get_state_changed_from_saved() )
249 bValue
= m_xExtrasCheckBox
->get_active();
250 m_xUpdateAccess
->replaceByName( "ExtendedUserAgent", uno::Any( bValue
) );
254 uno::Reference
< util::XChangesBatch
> xChangesBatch(m_xUpdateAccess
, uno::UNO_QUERY
);
255 if( xChangesBatch
.is() && xChangesBatch
->hasPendingChanges() )
256 xChangesBatch
->commitChanges();
261 void SvxOnlineUpdateTabPage::Reset( const SfxItemSet
* )
264 m_xUpdateAccess
->getByName( "AutoCheckEnabled" ) >>= bValue
;
265 beans::Property aProperty
= m_xReadWriteAccess
->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoCheckEnabled");
266 bool bReadOnly
= (aProperty
.Attributes
& beans::PropertyAttribute::READONLY
) != 0;
268 m_xAutoCheckCheckBox
->set_active(bValue
);
269 m_xAutoCheckCheckBox
->set_sensitive(!bReadOnly
);
271 sal_Int64 nValue
= 0;
272 m_xUpdateAccess
->getByName( "CheckInterval" ) >>= nValue
;
273 aProperty
= m_xReadWriteAccess
->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
274 bool bReadOnly2
= (aProperty
.Attributes
& beans::PropertyAttribute::READONLY
) != 0;
275 m_xEveryDayButton
->set_sensitive(bValue
&& !(bReadOnly
|| bReadOnly2
));
276 m_xEveryWeekButton
->set_sensitive(bValue
&& !(bReadOnly
|| bReadOnly2
));
277 m_xEveryMonthButton
->set_sensitive(bValue
&& !(bReadOnly
|| bReadOnly2
));
279 if( nValue
== 86400 )
280 m_xEveryDayButton
->set_active(true);
281 else if( nValue
== 604800 )
282 m_xEveryWeekButton
->set_active(true);
284 m_xEveryMonthButton
->set_active(true);
286 m_xAutoCheckCheckBox
->save_state();
287 m_xEveryDayButton
->save_state();
288 m_xEveryWeekButton
->save_state();
289 m_xEveryMonthButton
->save_state();
291 m_xUpdateAccess
->getByName( "AutoDownloadEnabled" ) >>= bValue
;
292 aProperty
= m_xReadWriteAccess
->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoDownloadEnabled");
293 bReadOnly
= (aProperty
.Attributes
& beans::PropertyAttribute::READONLY
) != 0;
294 m_xAutoDownloadCheckBox
->set_active(bValue
);
295 m_xAutoDownloadCheckBox
->set_sensitive(!bReadOnly
);
296 m_xDestPathLabel
->set_sensitive(true);
297 m_xDestPath
->set_sensitive(true);
299 OUString sValue
, aPath
;
300 m_xUpdateAccess
->getByName( "DownloadDestination" ) >>= sValue
;
301 aProperty
= m_xReadWriteAccess
->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/DownloadDestination");
302 bReadOnly
= (aProperty
.Attributes
& beans::PropertyAttribute::READONLY
) != 0;
303 m_xChangePathButton
->set_sensitive(!bReadOnly
);
305 if( osl::FileBase::E_None
== osl::FileBase::getSystemPathFromFileURL(sValue
, aPath
) )
306 m_xDestPath
->set_label(aPath
);
308 m_xUpdateAccess
->getByName( "ExtendedUserAgent" ) >>= bValue
;
309 aProperty
= m_xReadWriteAccess
->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/ExtendedUserAgent");
310 bReadOnly
= (aProperty
.Attributes
& beans::PropertyAttribute::READONLY
) != 0;
311 m_xExtrasCheckBox
->set_active(bValue
);
312 m_xExtrasCheckBox
->set_sensitive(!bReadOnly
);
313 m_xExtrasCheckBox
->save_state();
316 m_xAutoDownloadCheckBox
->save_state();
319 void SvxOnlineUpdateTabPage::FillUserData()
323 IMPL_LINK(SvxOnlineUpdateTabPage
, AutoCheckHdl_Impl
, weld::Toggleable
&, rBox
, void)
325 bool bEnabled
= rBox
.get_active();
326 beans::Property aProperty
= m_xReadWriteAccess
->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
327 bool bReadOnly
= (aProperty
.Attributes
& beans::PropertyAttribute::READONLY
) != 0;
328 m_xEveryDayButton
->set_sensitive(bEnabled
&& !bReadOnly
);
329 m_xEveryWeekButton
->set_sensitive(bEnabled
&& !bReadOnly
);
330 m_xEveryMonthButton
->set_sensitive(bEnabled
&& !bReadOnly
);
333 IMPL_LINK_NOARG(SvxOnlineUpdateTabPage
, ExtrasCheckHdl_Impl
, weld::Toggleable
&, void)
338 IMPL_LINK_NOARG(SvxOnlineUpdateTabPage
, FileDialogHdl_Impl
, weld::Button
&, void)
340 uno::Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
341 uno::Reference
< ui::dialogs::XFolderPicker2
> xFolderPicker
= sfx2::createFolderPicker(xContext
, GetFrameWeld());
344 if( osl::FileBase::E_None
!= osl::FileBase::getFileURLFromSystemPath(m_xDestPath
->get_label(), aURL
) )
345 osl::Security().getHomeDir(aURL
);
347 xFolderPicker
->setDisplayDirectory( aURL
);
348 sal_Int16 nRet
= xFolderPicker
->execute();
350 if ( ui::dialogs::ExecutableDialogResults::OK
== nRet
)
353 if( osl::FileBase::E_None
== osl::FileBase::getSystemPathFromFileURL(xFolderPicker
->getDirectory(), aFolder
))
354 m_xDestPath
->set_label(aFolder
);
358 IMPL_LINK_NOARG(SvxOnlineUpdateTabPage
, CheckNowHdl_Impl
, weld::Button
&, void)
360 uno::Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
364 uno::Reference
< lang::XMultiServiceFactory
> xConfigProvider(
365 css::configuration::theDefaultProvider::get( xContext
) );
367 beans::NamedValue aProperty
;
368 aProperty
.Name
= "nodepath";
369 aProperty
.Value
<<= OUString("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob");
371 uno::Sequence
< uno::Any
> aArgumentList
{ uno::Any(aProperty
) };
373 uno::Reference
< container::XNameAccess
> xNameAccess(
374 xConfigProvider
->createInstanceWithArguments(
375 "com.sun.star.configuration.ConfigurationAccess", aArgumentList
),
376 uno::UNO_QUERY_THROW
);
379 xNameAccess
->getByName("URL") >>= aURL
.Complete
;
381 uno::Reference
< util::XURLTransformer
> xTransformer( util::URLTransformer::create( xContext
) );
383 xTransformer
->parseStrict(aURL
);
385 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create( xContext
);
387 uno::Reference
< frame::XDispatchProvider
> xDispatchProvider(
388 xDesktop
->getCurrentFrame(), uno::UNO_QUERY
);
390 uno::Reference
< frame::XDispatch
> xDispatch
;
391 if( xDispatchProvider
.is() )
392 xDispatch
= xDispatchProvider
->queryDispatch(aURL
, OUString(), 0);
395 xDispatch
->dispatch(aURL
, uno::Sequence
< beans::PropertyValue
> ());
397 UpdateLastCheckedText();
399 catch( const uno::Exception
& )
401 TOOLS_WARN_EXCEPTION("cui.options", "Caught exception, thread terminated");
405 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */