use insert function instead of for loop
[LibreOffice.git] / svtools / source / dialogs / ServerDetailsControls.cxx
blobd4651945cbb0c9b34a8226379d721afa46df2ee9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
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>
17 #include <comphelper/processfactory.hxx>
18 #include <o3tl/safeint.hxx>
19 #include <rtl/uri.hxx>
20 #include <ucbhelper/content.hxx>
21 #include <ucbhelper/commandenvironment.hxx>
22 #include <comphelper/diagnose_ex.hxx>
24 #include <svtools/PlaceEditDialog.hxx>
25 #include <utility>
26 #include <config_oauth2.h>
28 #include "ServerDetailsControls.hxx"
30 using namespace com::sun::star::sdbc;
31 using namespace com::sun::star::task;
32 using namespace com::sun::star::ucb;
33 using namespace com::sun::star::uno;
35 DetailsContainer::DetailsContainer(PlaceEditDialog* pDialog)
36 : m_pDialog(pDialog)
38 m_pDialog->m_xEDPort->connect_output(LINK(this, DetailsContainer, FormatPortHdl));
41 //format without thousand separator
42 IMPL_STATIC_LINK(DetailsContainer, FormatPortHdl, weld::SpinButton&, rSpinButton, void)
44 rSpinButton.set_text(OUString::number(rSpinButton.get_value()));
47 DetailsContainer::~DetailsContainer( )
51 void DetailsContainer::set_visible( bool )
53 m_pDialog->m_xDetailsGrid->set_sensitive(true);
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 ) );
60 INetURLObject DetailsContainer::getUrl( )
62 // Don't use that class directly: make it smarter by subclassing it.
63 return INetURLObject( );
66 bool DetailsContainer::setUrl( const INetURLObject& )
68 // That class doesn't contain any logic... it defers the dirty work
69 // to the sub classes.
70 return false;
73 void DetailsContainer::notifyChange( )
75 m_aChangeHdl.Call( this );
78 IMPL_LINK_NOARG( DetailsContainer, ValueChangeHdl, weld::Entry&, void )
80 notifyChange( );
83 HostDetailsContainer::HostDetailsContainer(PlaceEditDialog* pDialog, sal_uInt16 nPort, OUString sScheme) :
84 DetailsContainer( pDialog ),
85 m_nDefaultPort( nPort ),
86 m_sScheme(std::move( sScheme ))
88 set_visible( false );
91 void HostDetailsContainer::set_visible( bool bShow )
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 );
98 DetailsContainer::set_visible( bShow );
100 if ( bShow )
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 );
106 else
107 m_pDialog->m_xEDPort->set_value( 0 );
110 INetURLObject HostDetailsContainer::getUrl( )
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();
116 OUString sUrl;
117 if ( !sHost.isEmpty( ) )
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;
128 return INetURLObject( sUrl );
131 bool HostDetailsContainer::setUrl( const INetURLObject& rUrl )
133 bool bSuccess = verifyScheme( INetURLObject::GetScheme( rUrl.GetProtocol( ) ) );
135 if ( bSuccess )
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() );
143 return bSuccess;
146 bool HostDetailsContainer::verifyScheme( const OUString& sScheme )
148 return sScheme == Concat2View( m_sScheme + "://" );
151 DavDetailsContainer::DavDetailsContainer(PlaceEditDialog* pBuilder)
152 : HostDetailsContainer(pBuilder, 80, u"http"_ustr)
154 m_pDialog->m_xCBDavs->connect_toggled(LINK(this, DavDetailsContainer, ToggledDavsHdl));
156 set_visible( false );
159 void DavDetailsContainer::set_visible( bool bShow )
161 HostDetailsContainer::set_visible( bShow );
163 if ( !bShow )
164 m_pDialog->m_xCBDavs->set_active(false);
166 m_pDialog->m_xCBDavs->set_visible(bShow);
169 bool DavDetailsContainer::verifyScheme( const OUString& rScheme )
171 bool bValid = false;
172 if ( rScheme == "http://" )
174 bValid = true;
175 m_pDialog->m_xCBDavs->set_active(false);
176 ToggledDavsHdl(*m_pDialog->m_xCBDavs);
178 else if ( rScheme == "https://" )
180 bValid = true;
181 m_pDialog->m_xCBDavs->set_active(true);
182 ToggledDavsHdl(*m_pDialog->m_xCBDavs);
184 return bValid;
187 IMPL_LINK( DavDetailsContainer, ToggledDavsHdl, weld::Toggleable&, rCheckBox, void )
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 );
196 OUString sScheme( u"http"_ustr );
197 if ( bCheckedDavs )
198 sScheme = "https";
199 setScheme( sScheme );
201 notifyChange( );
204 SmbDetailsContainer::SmbDetailsContainer(PlaceEditDialog* pDialog)
205 : DetailsContainer(pDialog)
207 m_pDialog->m_xEDShare->connect_changed( LINK( this, DetailsContainer, ValueChangeHdl ) );
209 set_visible( false );
212 INetURLObject SmbDetailsContainer::getUrl( )
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( );
218 OUString sUrl;
219 if ( !sHost.isEmpty( ) )
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;
230 return INetURLObject( sUrl );
233 bool SmbDetailsContainer::setUrl( const INetURLObject& rUrl )
235 bool bSuccess = rUrl.GetProtocol() == INetProtocol::Smb;
237 if ( bSuccess )
239 OUString sShare = rUrl.getName( 0 );
240 OUString sFullPath = rUrl.GetURLPath( );
241 OUString sPath;
242 if ( sFullPath.getLength( ) > sShare.getLength( ) )
244 sal_Int32 nPos = sShare.getLength( );
245 if ( nPos != 0 )
246 ++nPos;
247 sPath = sFullPath.copy( nPos );
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 );
256 return bSuccess;
259 void SmbDetailsContainer::set_visible( bool bShow )
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 );
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 );
271 if ( bShow )
272 m_pDialog->m_xEDHost->set_text( m_sHost );
275 CmisDetailsContainer::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())
284 const Reference< XComponentContext >& xContext = ::comphelper::getProcessComponentContext();
285 Reference< XInteractionHandler > xGlobalInteractionHandler =
286 InteractionHandler::createWithParent(xContext, m_xParentDialog);
287 m_xCmdEnv = new ucbhelper::CommandEnvironment( xGlobalInteractionHandler, Reference< XProgressHandler >() );
289 set_visible( false );
292 void CmisDetailsContainer::set_visible( bool bShow )
294 m_pDialog->m_xLBRepository->connect_changed( LINK( this, CmisDetailsContainer, SelectRepoHdl ) );
295 m_pDialog->m_xBTRepoRefresh->connect_clicked( LINK( this, CmisDetailsContainer, RefreshReposHdl ) );
297 m_pDialog->m_xEDHost->set_text( m_sBinding );
299 if( ( m_sBinding == GDRIVE_BASE_URL )
300 || m_sBinding.startsWith( ALFRESCO_CLOUD_BASE_URL )
301 || ( m_sBinding == ONEDRIVE_BASE_URL ) )
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();
310 else
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 );
320 DetailsContainer::set_visible( bShow );
321 m_pDialog->m_xEDPort->set_sensitive( !bShow );
322 m_pDialog->m_xFTPort->set_sensitive( !bShow );
325 INetURLObject CmisDetailsContainer::getUrl( )
327 OUString sBindingUrl = m_pDialog->m_xEDHost->get_text().trim();
328 OUString sPath = m_pDialog->m_xEDRoot->get_text().trim();
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 ) )
335 bSkip = m_sUsername.isEmpty();
337 else
339 bSkip = m_sRepoId.isEmpty();
342 OUString sUrl;
343 if ( !sBindingUrl.isEmpty( ) && !bSkip )
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;
352 sUrl += sPath;
354 return INetURLObject( sUrl );
357 bool CmisDetailsContainer::setUrl( const INetURLObject& rUrl )
359 bool bSuccess = rUrl.GetProtocol() == INetProtocol::Cmis;
361 if ( bSuccess )
363 OUString sDecodedHost = rUrl.GetHost( INetURLObject::DecodeMechanism::WithCharset );
364 INetURLObject aHostUrl( sDecodedHost );
365 m_sBinding = aHostUrl.GetURLNoMark( );
366 m_sRepoId = aHostUrl.GetMark( );
368 m_pDialog->m_xEDHost->set_text( m_sBinding );
369 m_pDialog->m_xEDRoot->set_text( rUrl.GetURLPath() );
371 return bSuccess;
374 void CmisDetailsContainer::setUsername( const OUString& rUsername )
376 m_sUsername = rUsername;
379 void CmisDetailsContainer::setPassword( const OUString& rPass )
381 m_sPassword = rPass;
384 void CmisDetailsContainer::selectRepository( )
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() )
390 m_sRepoId = m_aRepoIds[nPos];
391 notifyChange( );
395 IMPL_LINK_NOARG( CmisDetailsContainer, RefreshReposHdl, weld::Button&, void )
397 const Reference< XComponentContext >& xContext = ::comphelper::getProcessComponentContext();
398 Reference< XPasswordContainer2 > xMasterPasswd = PasswordContainer::create( xContext );
401 OUString sBindingUrl = m_pDialog->m_xEDHost->get_text().trim( );
403 OUString sEncodedUsername = u""_ustr;
405 if ( !m_sUsername.isEmpty( ) )
407 sEncodedUsername = rtl::Uri::encode(m_sUsername,
408 rtl_UriCharClassUserinfo,
409 rtl_UriEncodeKeepEscapes,
410 RTL_TEXTENCODING_UTF8 )
411 + "@";
414 // Clean the listbox
415 m_pDialog->m_xLBRepository->clear();
416 m_aRepoIds.clear();
418 // Compute the URL
419 OUString sUrl;
420 if ( !sBindingUrl.isEmpty( ) )
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;
430 // temporary remember the password
433 if( !sUrl.isEmpty() && !m_sUsername.isEmpty() && !m_sPassword.isEmpty() )
435 Reference< XInteractionHandler > xInteractionHandler =
436 InteractionHandler::createWithParent(xContext, m_xParentDialog);
438 Sequence<OUString> aPasswd { m_sPassword };
440 xMasterPasswd->add(
441 sUrl, m_sUsername, aPasswd, xInteractionHandler );
444 catch( const Exception& )
449 // Get the Content
450 ::ucbhelper::Content aCnt( sUrl, m_xCmdEnv, comphelper::getProcessComponentContext() );
451 Sequence<OUString> aProps { u"Title"_ustr };
452 Reference< XResultSet > xResultSet( aCnt.createCursor( aProps ), UNO_SET_THROW );
453 Reference< XContentAccess > xAccess( xResultSet, UNO_QUERY_THROW );
454 while ( xResultSet->next() )
456 OUString sURL = xAccess->queryContentIdentifierString( );
457 INetURLObject aURL( sURL );
458 OUString sId = aURL.GetURLPath( INetURLObject::DecodeMechanism::WithCharset );
459 sId = sId.copy( 1 );
460 m_aRepoIds.push_back( sId );
462 Reference< XRow > xRow( xResultSet, UNO_QUERY );
463 OUString sName = xRow->getString( 1 );
464 m_pDialog->m_xLBRepository->append_text(sName);
467 catch ( const Exception&)
469 TOOLS_WARN_EXCEPTION( "svtools.dialogs", "RefreshReposHdl" );
472 // Auto-select the first one
473 if (m_pDialog->m_xLBRepository->get_count() > 0)
475 m_pDialog->m_xLBRepository->set_active(0);
476 selectRepository( );
479 // remove temporary password
482 xMasterPasswd->remove( sUrl, m_sUsername );
484 catch( const Exception& )
488 IMPL_LINK_NOARG( CmisDetailsContainer, SelectRepoHdl, weld::ComboBox&, void )
490 selectRepository( );
493 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */