LibreOffice Module svtools (master) 1
ServerDetailsControls.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 */
9
10#include <com/sun/star/task/InteractionHandler.hpp>
11#include <com/sun/star/task/PasswordContainer.hpp>
12#include <com/sun/star/task/XPasswordContainer2.hpp>
13#include <com/sun/star/ucb/XContentAccess.hpp>
14#include <com/sun/star/sdbc/XResultSet.hpp>
15#include <com/sun/star/sdbc/XRow.hpp>
16
18#include <o3tl/safeint.hxx>
19#include <rtl/uri.hxx>
20#include <ucbhelper/content.hxx>
23
25#include <utility>
26#include <config_oauth2.h>
27
29
30using namespace com::sun::star::sdbc;
31using namespace com::sun::star::task;
32using namespace com::sun::star::ucb;
33using namespace com::sun::star::uno;
34
35DetailsContainer::DetailsContainer(PlaceEditDialog* pDialog)
36 : m_pDialog(pDialog)
37{
38 m_pDialog->m_xEDPort->connect_output(LINK(this, DetailsContainer, FormatPortHdl));
39}
40
41//format without thousand separator
42IMPL_STATIC_LINK(DetailsContainer, FormatPortHdl, weld::SpinButton&, rSpinButton, void)
43{
44 rSpinButton.set_text(OUString::number(rSpinButton.get_value()));
45}
46
48{
49}
50
52{
53 m_pDialog->m_xDetailsGrid->set_sensitive(true);
54
55 m_pDialog->m_xEDHost->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
56 m_pDialog->m_xEDPort->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
57 m_pDialog->m_xEDRoot->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
58}
59
61{
62 // Don't use that class directly: make it smarter by subclassing it.
63 return INetURLObject( );
64}
65
67{
68 // That class doesn't contain any logic... it defers the dirty work
69 // to the sub classes.
70 return false;
71}
72
74{
75 m_aChangeHdl.Call( this );
76}
77
79{
80 notifyChange( );
81}
82
83HostDetailsContainer::HostDetailsContainer(PlaceEditDialog* pDialog, sal_uInt16 nPort, OUString sScheme) :
84 DetailsContainer( pDialog ),
85 m_nDefaultPort( nPort ),
86 m_sScheme(std::move( sScheme ))
87{
88 set_visible( false );
89}
90
92{
93 m_pDialog->m_xFTHost->set_visible( bShow );
94 m_pDialog->m_xHostBox->set_visible( bShow );
95 m_pDialog->m_xEDRoot->set_visible( bShow );
96 m_pDialog->m_xFTRoot->set_visible( bShow );
97
99
100 if ( bShow )
101 {
102 if (m_pDialog->m_xEDPort->get_value() == 0)
103 m_pDialog->m_xEDPort->set_value( m_nDefaultPort );
104 m_pDialog->m_xEDHost->set_text( m_sHost );
105 }
106 else
107 m_pDialog->m_xEDPort->set_value( 0 );
108}
109
111{
112 OUString sHost = m_pDialog->m_xEDHost->get_text().trim();
113 sal_Int64 nPort = m_pDialog->m_xEDPort->get_value();
114 OUString sPath = m_pDialog->m_xEDRoot->get_text().trim();
115
116 OUString sUrl;
117 if ( !sHost.isEmpty( ) )
118 {
119 sUrl = m_sScheme + "://" + sHost;
120 if ( nPort != m_nDefaultPort )
121 sUrl += ":" + OUString::number( nPort );
122 if ( !sPath.isEmpty( ) )
123 if ( sPath.indexOf( '/' ) != 0 )
124 sUrl += "/";
125 sUrl += sPath;
126 }
127
128 return INetURLObject( sUrl );
129}
130
132{
133 bool bSuccess = verifyScheme( INetURLObject::GetScheme( rUrl.GetProtocol( ) ) );
134
135 if ( bSuccess )
136 {
137 m_sHost = rUrl.GetHost( );
138 m_pDialog->m_xEDHost->set_text( rUrl.GetHost( ) );
139 m_pDialog->m_xEDPort->set_value( rUrl.GetPort( ) );
140 m_pDialog->m_xEDRoot->set_text( rUrl.GetURLPath() );
141 }
142
143 return bSuccess;
144}
145
146bool HostDetailsContainer::verifyScheme( const OUString& sScheme )
147{
148 return sScheme == Concat2View( m_sScheme + "://" );
149}
150
152 : HostDetailsContainer(pBuilder, 80, "http")
153{
154 m_pDialog->m_xCBDavs->connect_toggled(LINK(this, DavDetailsContainer, ToggledDavsHdl));
155
156 set_visible( false );
157}
158
160{
162
163 if ( !bShow )
164 m_pDialog->m_xCBDavs->set_active(false);
165
166 m_pDialog->m_xCBDavs->set_visible(bShow);
167}
168
169bool DavDetailsContainer::verifyScheme( const OUString& rScheme )
170{
171 bool bValid = false;
172 if ( rScheme == "http://" )
173 {
174 bValid = true;
175 m_pDialog->m_xCBDavs->set_active(false);
176 ToggledDavsHdl(*m_pDialog->m_xCBDavs);
177 }
178 else if ( rScheme == "https://" )
179 {
180 bValid = true;
181 m_pDialog->m_xCBDavs->set_active(true);
182 ToggledDavsHdl(*m_pDialog->m_xCBDavs);
183 }
184 return bValid;
185}
186
187IMPL_LINK( DavDetailsContainer, ToggledDavsHdl, weld::Toggleable&, rCheckBox, void )
188{
189 // Change default port if needed
190 bool bCheckedDavs = rCheckBox.get_active();
191 if ( m_pDialog->m_xEDPort->get_value() == 80 && bCheckedDavs )
192 m_pDialog->m_xEDPort->set_value( 443 );
193 else if ( m_pDialog->m_xEDPort->get_value() == 443 && !bCheckedDavs )
194 m_pDialog->m_xEDPort->set_value( 80 );
195
196 OUString sScheme( "http" );
197 if ( bCheckedDavs )
198 sScheme = "https";
199 setScheme( sScheme );
200
201 notifyChange( );
202}
203
205 : DetailsContainer(pDialog)
206{
207 m_pDialog->m_xEDShare->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
208
209 set_visible( false );
210}
211
213{
214 OUString sHost = m_pDialog->m_xEDHost->get_text().trim( );
215 OUString sShare = m_pDialog->m_xEDShare->get_text().trim( );
216 OUString sPath = m_pDialog->m_xEDRoot->get_text().trim( );
217
218 OUString sUrl;
219 if ( !sHost.isEmpty( ) )
220 {
221 sUrl = "smb://" + sHost + "/";
222 if ( !sShare.isEmpty( ) )
223 sUrl += sShare;
224 if ( !sPath.isEmpty( ) )
225 if ( sPath.indexOf( '/' ) != 0 )
226 sUrl += "/";
227 sUrl += sPath;
228 }
229
230 return INetURLObject( sUrl );
231}
232
234{
235 bool bSuccess = rUrl.GetProtocol() == INetProtocol::Smb;
236
237 if ( bSuccess )
238 {
239 OUString sShare = rUrl.getName( 0 );
240 OUString sFullPath = rUrl.GetURLPath( );
241 OUString sPath;
242 if ( sFullPath.getLength( ) > sShare.getLength( ) )
243 {
244 sal_Int32 nPos = sShare.getLength( );
245 if ( nPos != 0 )
246 ++nPos;
247 sPath = sFullPath.copy( nPos );
248 }
249
250 m_sHost = rUrl.GetHost( );
251 m_pDialog->m_xEDHost->set_text( m_sHost );
252 m_pDialog->m_xEDShare->set_text( sShare );
253 m_pDialog->m_xEDRoot->set_text( sPath );
254 }
255
256 return bSuccess;
257}
258
260{
261 m_pDialog->m_xEDShare->set_visible( bShow );
262 m_pDialog->m_xFTShare->set_visible( bShow );
263 m_pDialog->m_xEDRoot->set_visible( bShow );
264 m_pDialog->m_xFTRoot->set_visible( bShow );
265
266 m_pDialog->m_xFTHost->set_visible( bShow );
267 m_pDialog->m_xHostBox->set_visible( bShow );
268 m_pDialog->m_xEDPort->set_sensitive( !bShow );
269 m_pDialog->m_xFTPort->set_sensitive( !bShow );
270
271 if ( bShow )
272 m_pDialog->m_xEDHost->set_text( m_sHost );
273}
274
275CmisDetailsContainer::CmisDetailsContainer(PlaceEditDialog* pParentDialog, OUString sBinding) :
276 DetailsContainer( pParentDialog ),
277 m_sUsername( ),
278 m_xCmdEnv( ),
279 m_aRepoIds( ),
280 m_sRepoId( ),
281 m_sBinding(std::move( sBinding )),
282 m_xParentDialog(pParentDialog->getDialog()->GetXWindow())
283{
284 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
285 Reference< XInteractionHandler > xGlobalInteractionHandler =
286 InteractionHandler::createWithParent(xContext, m_xParentDialog);
287 m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
288
289 set_visible( false );
290}
291
293{
294 m_pDialog->m_xLBRepository->connect_changed( LINK( this, CmisDetailsContainer, SelectRepoHdl ) );
295 m_pDialog->m_xBTRepoRefresh->connect_clicked( LINK( this, CmisDetailsContainer, RefreshReposHdl ) );
296
297 m_pDialog->m_xEDHost->set_text( m_sBinding );
298
299 if( ( m_sBinding == GDRIVE_BASE_URL )
300 || m_sBinding.startsWith( ALFRESCO_CLOUD_BASE_URL )
301 || ( m_sBinding == ONEDRIVE_BASE_URL ) )
302 {
303 m_pDialog->m_xFTHost->hide();
304 m_pDialog->m_xHostBox->hide();
305 m_pDialog->m_xFTRepository->hide();
306 m_pDialog->m_xRepositoryBox->hide();
307 m_pDialog->m_xEDRoot->hide();
308 m_pDialog->m_xFTRoot->hide();
309 }
310 else
311 {
312 m_pDialog->m_xFTHost->set_visible( bShow );
313 m_pDialog->m_xHostBox->set_visible( bShow );
314 m_pDialog->m_xFTRepository->set_visible( bShow );
315 m_pDialog->m_xRepositoryBox->set_visible( bShow );
316 m_pDialog->m_xEDRoot->set_visible( bShow );
317 m_pDialog->m_xFTRoot->set_visible( bShow );
318 }
319
321 m_pDialog->m_xEDPort->set_sensitive( !bShow );
322 m_pDialog->m_xFTPort->set_sensitive( !bShow );
323}
324
326{
327 OUString sBindingUrl = m_pDialog->m_xEDHost->get_text().trim();
328 OUString sPath = m_pDialog->m_xEDRoot->get_text().trim();
329
330 bool bSkip = true;
331 if( ( m_sBinding == GDRIVE_BASE_URL )
332 || m_sBinding.startsWith( ALFRESCO_CLOUD_BASE_URL )
333 || ( m_sBinding == ONEDRIVE_BASE_URL ) )
334 {
335 bSkip = m_sUsername.isEmpty();
336 }
337 else
338 {
339 bSkip = m_sRepoId.isEmpty();
340 }
341
342 OUString sUrl;
343 if ( !sBindingUrl.isEmpty( ) && !bSkip )
344 {
345 OUString sEncodedBinding = rtl::Uri::encode(
346 sBindingUrl + "#" + m_sRepoId,
347 rtl_UriCharClassRelSegment,
348 rtl_UriEncodeKeepEscapes,
349 RTL_TEXTENCODING_UTF8 );
350 sUrl = "vnd.libreoffice.cmis://" + sEncodedBinding;
351 }
352 sUrl += sPath;
353
354 return INetURLObject( sUrl );
355}
356
358{
359 bool bSuccess = rUrl.GetProtocol() == INetProtocol::Cmis;
360
361 if ( bSuccess )
362 {
363 OUString sDecodedHost = rUrl.GetHost( INetURLObject::DecodeMechanism::WithCharset );
364 INetURLObject aHostUrl( sDecodedHost );
365 m_sBinding = aHostUrl.GetURLNoMark( );
366 m_sRepoId = aHostUrl.GetMark( );
367
368 m_pDialog->m_xEDHost->set_text( m_sBinding );
369 m_pDialog->m_xEDRoot->set_text( rUrl.GetURLPath() );
370 }
371 return bSuccess;
372}
373
374void CmisDetailsContainer::setUsername( const OUString& rUsername )
375{
376 m_sUsername = rUsername;
377}
378
379void CmisDetailsContainer::setPassword( const OUString& rPass )
380{
381 m_sPassword = rPass;
382}
383
385{
386 // Get the repo ID and call the Change listener
387 const int nPos = m_pDialog->m_xLBRepository->get_active();
388 if( o3tl::make_unsigned(nPos) < m_aRepoIds.size() )
389 {
391 notifyChange( );
392 }
393}
394
396{
397 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
398 Reference< XPasswordContainer2 > xMasterPasswd = PasswordContainer::create( xContext );
399
400
401 OUString sBindingUrl = m_pDialog->m_xEDHost->get_text().trim( );
402
403 OUString sEncodedUsername = "";
404
405 if ( !m_sUsername.isEmpty( ) )
406 {
407 sEncodedUsername = rtl::Uri::encode(m_sUsername,
408 rtl_UriCharClassUserinfo,
409 rtl_UriEncodeKeepEscapes,
410 RTL_TEXTENCODING_UTF8 )
411 + "@";
412 }
413
414 // Clean the listbox
415 m_pDialog->m_xLBRepository->clear();
416 m_aRepoIds.clear();
417
418 // Compute the URL
419 OUString sUrl;
420 if ( !sBindingUrl.isEmpty( ) )
421 {
422 OUString sEncodedBinding = rtl::Uri::encode(
423 sBindingUrl,
424 rtl_UriCharClassRelSegment,
425 rtl_UriEncodeKeepEscapes,
426 RTL_TEXTENCODING_UTF8 );
427 sUrl = "vnd.libreoffice.cmis://" + sEncodedUsername + sEncodedBinding;
428 }
429
430 // temporary remember the password
431 try
432 {
433 if( !sUrl.isEmpty() && !m_sUsername.isEmpty() && !m_sPassword.isEmpty() )
434 {
435 Reference< XInteractionHandler > xInteractionHandler =
436 InteractionHandler::createWithParent(xContext, m_xParentDialog);
437
438 Sequence<OUString> aPasswd { m_sPassword };
439
440 xMasterPasswd->add(
441 sUrl, m_sUsername, aPasswd, xInteractionHandler );
442 }
443 }
444 catch( const Exception& )
445 {}
446
447 try
448 {
449 // Get the Content
451 Sequence<OUString> aProps { "Title" };
452 Reference< XResultSet > xResultSet( aCnt.createCursor( aProps ), UNO_SET_THROW );
453 Reference< XContentAccess > xAccess( xResultSet, UNO_QUERY_THROW );
454 while ( xResultSet->next() )
455 {
456 OUString sURL = xAccess->queryContentIdentifierString( );
457 INetURLObject aURL( sURL );
459 sId = sId.copy( 1 );
460 m_aRepoIds.push_back( sId );
461
462 Reference< XRow > xRow( xResultSet, UNO_QUERY );
463 OUString sName = xRow->getString( 1 );
464 m_pDialog->m_xLBRepository->append_text(sName);
465 }
466 }
467 catch ( const Exception&)
468 {
469 TOOLS_WARN_EXCEPTION( "svtools.dialogs", "RefreshReposHdl" );
470 }
471
472 // Auto-select the first one
473 if (m_pDialog->m_xLBRepository->get_count() > 0)
474 {
475 m_pDialog->m_xLBRepository->set_active(0);
476 selectRepository( );
477 }
478
479 // remove temporary password
480 try
481 {
482 xMasterPasswd->remove( sUrl, m_sUsername );
483 }
484 catch( const Exception& )
485 {}
486}
487
489{
490 selectRepository( );
491}
492
493/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_STATIC_LINK(DetailsContainer, FormatPortHdl, weld::SpinButton &, rSpinButton, void)
IMPL_LINK(DavDetailsContainer, ToggledDavsHdl, weld::Toggleable &, rCheckBox, void)
IMPL_LINK_NOARG(DetailsContainer, ValueChangeHdl, weld::Entry &, void)
virtual bool setUrl(const INetURLObject &rUrl) override
Try to split the URL in the controls of that container.
virtual void setUsername(const OUString &rUsername) override
CmisDetailsContainer(PlaceEditDialog *pDialog, OUString sBinding)
std::vector< OUString > m_aRepoIds
css::uno::Reference< css::ucb::XCommandEnvironment > m_xCmdEnv
virtual INetURLObject getUrl() override
virtual void setPassword(const OUString &rPass) override
css::uno::Reference< css::awt::XWindow > m_xParentDialog
virtual void set_visible(bool bShow) override
DavDetailsContainer(PlaceEditDialog *pDialog)
virtual bool verifyScheme(const OUString &rScheme) override
Verifies that the scheme split from the URL can be handled by the container and set the proper contro...
virtual void set_visible(bool bShow) override
DetailsContainer(PlaceEditDialog *pDialog)
Link< DetailsContainer *, void > m_aChangeHdl
PlaceEditDialog * m_pDialog
virtual INetURLObject getUrl()
virtual bool setUrl(const INetURLObject &rUrl)
Try to split the URL in the controls of that container.
virtual void set_visible(bool bShow)
virtual INetURLObject getUrl() override
HostDetailsContainer(PlaceEditDialog *pDialog, sal_uInt16 nPort, OUString sScheme)
virtual bool setUrl(const INetURLObject &rUrl) override
Try to split the URL in the controls of that container.
virtual bool verifyScheme(const OUString &rScheme)
Verifies that the scheme split from the URL can be handled by the container and set the proper contro...
virtual void set_visible(bool bShow) override
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
sal_uInt32 GetPort() const
static OUString GetScheme(INetProtocol eTheScheme)
OUString GetMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString GetURLNoMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString GetURLPath(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString GetHost(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
INetProtocol GetProtocol() const
virtual INetURLObject getUrl() override
virtual void set_visible(bool bShow) override
virtual bool setUrl(const INetURLObject &rUrl) override
Try to split the URL in the controls of that container.
SmbDetailsContainer(PlaceEditDialog *pDialog)
css::uno::Reference< css::sdbc::XResultSet > createCursor(const css::uno::Sequence< OUString > &rPropertyNames, ResultSetInclude eMode=INCLUDE_FOLDERS_AND_DOCUMENTS)
#define TOOLS_WARN_EXCEPTION(area, stream)
URL aURL
OUString sName
sal_uInt16 nPos
@ Exception
Reference< XComponentContext > getProcessComponentContext()
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
OUString sId