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/.
10 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
11 #include <com/sun/star/task/InteractionHandler.hpp>
12 #include <com/sun/star/ucb/XCommandEnvironment.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 <officecfg/Office/Common.hxx>
19 #include <rtl/uri.hxx>
20 #include <ucbhelper/content.hxx>
21 #include <ucbhelper/commandenvironment.hxx>
23 #include <svtools/PlaceEditDialog.hxx>
24 #include <svtools/ServerDetailsControls.hxx>
25 #include <config_oauth2.h>
28 using namespace com::sun::star::lang
;
29 using namespace com::sun::star::sdbc
;
30 using namespace com::sun::star::task
;
31 using namespace com::sun::star::ucb
;
32 using namespace com::sun::star::uno
;
34 DetailsContainer::DetailsContainer( VclBuilderContainer
* pBuilder
) :
37 pBuilder
->get( m_pDetailsGrid
, "Details" );
38 pBuilder
->get( m_pHostBox
, "HostDetails" );
39 pBuilder
->get( m_pEDHost
, "host" );
40 pBuilder
->get( m_pFTHost
, "hostLabel" );
41 pBuilder
->get( m_pEDPort
, "port-nospin" );
42 pBuilder
->get( m_pFTPort
, "portLabel" );
43 pBuilder
->get( m_pEDRoot
, "path" );
44 pBuilder
->get( m_pFTRoot
, "pathLabel" );
47 DetailsContainer::~DetailsContainer( )
51 void DetailsContainer::show( bool )
53 m_pDetailsGrid
->Enable( m_bIsActive
);
55 m_pEDHost
->SetModifyHdl( LINK( this, DetailsContainer
, ValueChangeHdl
) );
56 m_pEDPort
->SetModifyHdl( LINK( this, DetailsContainer
, ValueChangeHdl
) );
57 m_pEDRoot
->SetModifyHdl( 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.
73 void DetailsContainer::notifyChange( )
75 m_aChangeHdl
.Call( this );
78 void DetailsContainer::setActive( bool bActive
)
80 m_bIsActive
= bActive
;
83 IMPL_LINK_NOARG( DetailsContainer
, ValueChangeHdl
)
89 HostDetailsContainer::HostDetailsContainer( VclBuilderContainer
* pBuilder
, sal_uInt16 nPort
, const OUString
& sScheme
) :
90 DetailsContainer( pBuilder
),
91 m_nDefaultPort( nPort
),
97 void HostDetailsContainer::show( bool bShow
)
99 m_pFTHost
->Show( bShow
);
100 m_pHostBox
->Show( bShow
);
101 m_pEDRoot
->Show( bShow
);
102 m_pFTRoot
->Show( bShow
);
104 DetailsContainer::show( bShow
);
108 m_pEDPort
->SetValue( m_nDefaultPort
);
109 m_pEDHost
->SetText( m_sHost
);
113 INetURLObject
HostDetailsContainer::getUrl( )
115 OUString sHost
= m_pEDHost
->GetText().trim( );
116 sal_Int64 nPort
= m_pEDPort
->GetValue();
117 OUString sPath
= m_pEDRoot
->GetText().trim( );
120 if ( !sHost
.isEmpty( ) )
122 sUrl
= m_sScheme
+ "://" + sHost
;
123 if ( nPort
!= m_nDefaultPort
)
124 sUrl
+= ":" + OUString::number( nPort
);
125 if ( !sPath
.isEmpty( ) )
126 if ( sPath
.indexOf( '/' ) != 0 )
131 return INetURLObject( sUrl
);
134 bool HostDetailsContainer::setUrl( const INetURLObject
& rUrl
)
136 bool bSuccess
= verifyScheme( INetURLObject::GetScheme( rUrl
.GetProtocol( ) ) );
140 m_pEDHost
->SetText( rUrl
.GetHost( ) );
141 m_pEDPort
->SetValue( rUrl
.GetPort( ) );
142 m_pEDRoot
->SetText( rUrl
.GetURLPath() );
148 bool HostDetailsContainer::verifyScheme( const OUString
& sScheme
)
150 return sScheme
.equals( m_sScheme
+ "://" );
153 DavDetailsContainer::DavDetailsContainer( VclBuilderContainer
* pBuilder
) :
154 HostDetailsContainer( pBuilder
, 80, "http" )
156 pBuilder
->get( m_pCBDavs
, "webdavs" );
157 m_pCBDavs
->SetToggleHdl( LINK( this, DavDetailsContainer
, ToggledDavsHdl
) );
162 void DavDetailsContainer::show( bool bShow
)
164 HostDetailsContainer::show( bShow
);
166 m_pCBDavs
->Show( bShow
);
169 m_pCBDavs
->Check( false );
172 bool DavDetailsContainer::verifyScheme( const OUString
& rScheme
)
175 if ( rScheme
== "http://" )
178 m_pCBDavs
->Check( false );
180 else if ( rScheme
== "https://" )
183 m_pCBDavs
->Check( true );
188 IMPL_LINK( DavDetailsContainer
, ToggledDavsHdl
, CheckBox
*, pCheckBox
)
190 // Change default port if needed
191 bool bCheckedDavs
= pCheckBox
->IsChecked();
192 if ( m_pEDPort
->GetValue() == 80 && bCheckedDavs
)
193 m_pEDPort
->SetValue( 443 );
194 else if ( m_pEDPort
->GetValue() == 443 && !bCheckedDavs
)
195 m_pEDPort
->SetValue( 80 );
197 OUString
sScheme( "http" );
200 setScheme( sScheme
);
207 SmbDetailsContainer::SmbDetailsContainer( VclBuilderContainer
* pBuilder
) :
208 DetailsContainer( pBuilder
)
210 pBuilder
->get( m_pEDShare
, "share" );
211 pBuilder
->get( m_pFTShare
, "shareLabel" );
213 m_pEDShare
->SetModifyHdl( LINK( this, DetailsContainer
, ValueChangeHdl
) );
218 INetURLObject
SmbDetailsContainer::getUrl( )
220 OUString sHost
= m_pEDHost
->GetText().trim( );
221 OUString sShare
= m_pEDShare
->GetText().trim( );
222 OUString sPath
= m_pEDRoot
->GetText().trim( );
225 if ( !sHost
.isEmpty( ) )
227 sUrl
= "smb://" + sHost
+ "/";
228 if ( !sShare
.isEmpty( ) )
230 if ( !sPath
.isEmpty( ) )
231 if ( sPath
.indexOf( '/' ) != 0 )
236 return INetURLObject( sUrl
);
239 bool SmbDetailsContainer::setUrl( const INetURLObject
& rUrl
)
241 bool bSuccess
= rUrl
.GetProtocol() == INetProtocol::Smb
;
245 OUString sShare
= rUrl
.getName( 0 );
246 OUString sFullPath
= rUrl
.GetURLPath( );
248 if ( sFullPath
.getLength( ) > sShare
.getLength( ) )
250 sal_Int32 nPos
= sShare
.getLength( );
253 sPath
= sFullPath
.copy( nPos
);
256 m_pEDHost
->SetText( rUrl
.GetHost( ) );
257 m_pEDShare
->SetText( sShare
);
258 m_pEDRoot
->SetText( sPath
);
264 void SmbDetailsContainer::show( bool bShow
)
266 m_pEDShare
->Show( bShow
);
267 m_pFTShare
->Show( bShow
);
268 m_pEDRoot
->Show( bShow
);
269 m_pFTRoot
->Show( bShow
);
271 m_pFTHost
->Show( bShow
);
272 m_pHostBox
->Show( bShow
);
273 m_pEDPort
->Enable( !bShow
);
274 m_pFTPort
->Enable( !bShow
);
277 CmisDetailsContainer::CmisDetailsContainer( VclBuilderContainer
* pBuilder
, OUString
const & sBinding
) :
278 DetailsContainer( pBuilder
),
283 m_sBinding( sBinding
)
285 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
286 Reference
< XInteractionHandler
> xGlobalInteractionHandler(
287 InteractionHandler::createWithParent(xContext
, 0), UNO_QUERY
);
288 m_xCmdEnv
= new ucbhelper::CommandEnvironment( xGlobalInteractionHandler
, Reference
< XProgressHandler
>() );
290 pBuilder
->get( m_pFTRepository
, "repositoryLabel" );
291 pBuilder
->get( m_pLBRepository
, "repositories" );
292 pBuilder
->get( m_pBTRepoRefresh
, "repositoriesRefresh" );
293 pBuilder
->get( m_pRepositoryBox
, "RepositoryDetails" );
298 void CmisDetailsContainer::show( bool bShow
)
300 m_pLBRepository
->SetSelectHdl( LINK( this, CmisDetailsContainer
, SelectRepoHdl
) );
301 m_pBTRepoRefresh
->SetClickHdl( LINK( this, CmisDetailsContainer
, RefreshReposHdl
) );
303 m_pEDHost
->SetText( m_sBinding
);
305 if( ( m_sBinding
== GDRIVE_BASE_URL
)
306 || m_sBinding
.startsWith( ALFRESCO_CLOUD_BASE_URL
)
307 || ( m_sBinding
== ONEDRIVE_BASE_URL
) )
309 m_pFTHost
->Show( false );
310 m_pHostBox
->Show( false );
311 m_pFTRepository
->Show( false );
312 m_pRepositoryBox
->Show( false );
313 m_pEDRoot
->Show( false );
314 m_pFTRoot
->Show( false );
318 m_pFTHost
->Show( bShow
);
319 m_pHostBox
->Show( bShow
);
320 m_pFTRepository
->Show( bShow
);
321 m_pRepositoryBox
->Show( bShow
);
322 m_pEDRoot
->Show( bShow
);
323 m_pFTRoot
->Show( bShow
);
326 DetailsContainer::show( bShow
);
327 m_pEDPort
->Enable( !bShow
);
328 m_pFTPort
->Enable( !bShow
);
331 INetURLObject
CmisDetailsContainer::getUrl( )
333 OUString sBindingUrl
= m_pEDHost
->GetText().trim( );
334 OUString sPath
= m_pEDRoot
->GetText().trim( );
337 if( ( m_sBinding
== GDRIVE_BASE_URL
)
338 || m_sBinding
.startsWith( ALFRESCO_CLOUD_BASE_URL
)
339 || ( m_sBinding
== ONEDRIVE_BASE_URL
) )
341 bSkip
= m_sUsername
.isEmpty();
345 bSkip
= m_sRepoId
.isEmpty();
349 if ( !sBindingUrl
.isEmpty( ) && !bSkip
)
351 OUString sEncodedBinding
= rtl::Uri::encode(
352 sBindingUrl
+ "#" + m_sRepoId
,
353 rtl_UriCharClassRelSegment
,
354 rtl_UriEncodeKeepEscapes
,
355 RTL_TEXTENCODING_UTF8
);
356 sUrl
= "vnd.libreoffice.cmis://" + sEncodedBinding
;
360 return INetURLObject( sUrl
);
363 bool CmisDetailsContainer::setUrl( const INetURLObject
& rUrl
)
365 bool bSuccess
= rUrl
.GetProtocol() == INetProtocol::Cmis
;
369 OUString sDecodedHost
= rUrl
.GetHost( INetURLObject::DECODE_WITH_CHARSET
);
370 INetURLObject
aHostUrl( sDecodedHost
);
371 m_sBinding
= aHostUrl
.GetURLNoMark( );
372 m_sRepoId
= aHostUrl
.GetMark( );
374 m_pEDHost
->SetText( m_sBinding
);
375 m_pEDRoot
->SetText( rUrl
.GetURLPath() );
380 void CmisDetailsContainer::setUsername( const OUString
& rUsername
)
382 m_sUsername
= rUsername
;
385 void CmisDetailsContainer::setPassword( const OUString
& rPass
)
390 void CmisDetailsContainer::selectRepository( )
392 // Get the repo ID and call the Change listener
393 sal_uInt16 nPos
= m_pLBRepository
->GetSelectEntryPos( );
394 if( nPos
< m_aRepoIds
.size() )
396 m_sRepoId
= m_aRepoIds
[nPos
];
401 IMPL_LINK_NOARG( CmisDetailsContainer
, RefreshReposHdl
)
403 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
404 Reference
< XPasswordContainer2
> xMasterPasswd
= PasswordContainer::create( xContext
);
407 OUString sBindingUrl
= m_pEDHost
->GetText().trim( );
409 OUString sEncodedUsername
= "";
411 if ( !m_sUsername
.isEmpty( ) )
413 sEncodedUsername
= rtl::Uri::encode(m_sUsername
,
414 rtl_UriCharClassUserinfo
,
415 rtl_UriEncodeKeepEscapes
,
416 RTL_TEXTENCODING_UTF8
);
417 sEncodedUsername
+= "@";
421 m_pLBRepository
->Clear( );
426 if ( !sBindingUrl
.isEmpty( ) )
428 OUString sEncodedBinding
= rtl::Uri::encode(
430 rtl_UriCharClassRelSegment
,
431 rtl_UriEncodeKeepEscapes
,
432 RTL_TEXTENCODING_UTF8
);
433 sUrl
= "vnd.libreoffice.cmis://" + sEncodedUsername
+ sEncodedBinding
;
436 // temporary remember the password
439 if( !sUrl
.isEmpty() && !m_sUsername
.isEmpty() && !m_sPassword
.isEmpty() )
441 Reference
< XInteractionHandler
> xInteractionHandler(
442 InteractionHandler::createWithParent( xContext
, 0 ),
445 Sequence
< OUString
> aPasswd( 1 );
446 aPasswd
[0] = m_sPassword
;
449 sUrl
, m_sUsername
, aPasswd
, xInteractionHandler
);
452 catch( const Exception
& )
456 ::ucbhelper::Content
aCnt( sUrl
, m_xCmdEnv
, comphelper::getProcessComponentContext() );
457 Sequence
< OUString
> aProps( 1 );
462 Reference
< XResultSet
> xResultSet( aCnt
.createCursor( aProps
), UNO_QUERY_THROW
);
463 Reference
< XContentAccess
> xAccess( xResultSet
, UNO_QUERY_THROW
);
464 while ( xResultSet
->next() )
466 OUString sURL
= xAccess
->queryContentIdentifierString( );
467 INetURLObject
aURL( sURL
);
468 OUString sId
= aURL
.GetURLPath( INetURLObject::DECODE_WITH_CHARSET
);
470 m_aRepoIds
.push_back( sId
);
472 Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
473 OUString sName
= xRow
->getString( 1 );
474 m_pLBRepository
->InsertEntry( sName
);
477 catch ( const Exception
& )
481 // Auto-select the first one
482 if ( m_pLBRepository
->GetEntryCount( ) > 0 )
484 m_pLBRepository
->SelectEntryPos( 0 );
488 // remove temporary password
490 xMasterPasswd
->remove( sUrl
, m_sUsername
);
496 IMPL_LINK_NOARG( CmisDetailsContainer
, SelectRepoHdl
)
502 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */