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 <config_oauth2.h>
12 #include "fpsmartcontent.hxx"
13 #include "QueryFolderName.hxx"
14 #include "RemoteFilesDialog.hxx"
15 #include <fpsofficeResMgr.hxx>
16 #include <fpicker/strings.hrc>
17 #include <strings.hrc>
18 #include <comphelper/docpasswordrequest.hxx>
19 #include <comphelper/stillreadwriteinteraction.hxx>
20 #include <com/sun/star/task/InteractionHandler.hpp>
21 #include <com/sun/star/task/PasswordContainer.hpp>
22 #include <svtools/PlaceEditDialog.hxx>
23 #include <tools/debug.hxx>
24 #include <ucbhelper/commandenvironment.hxx>
25 #include <vcl/errinf.hxx>
26 #include <bitmaps.hlst>
27 #include <officecfg/Office/Common.hxx>
29 RemoteFilesDialog::RemoteFilesDialog( weld::Window
* pParent
, PickerFlags nBits
)
30 : SvtFileDialog_Base( pParent
, "fps/ui/remotefilesdialog.ui", "RemoteFilesDialog" )
31 , m_xContext( comphelper::getProcessComponentContext() )
32 , m_xMasterPasswd( PasswordContainer::create( m_xContext
) )
33 , m_bIsInExecute( false )
34 , m_xCancel_btn(m_xBuilder
->weld_button("cancel"))
35 , m_xAddService_bar(m_xBuilder
->weld_toolbar("add_service_bar"))
36 , m_xAddService_menu(m_xBuilder
->weld_menu("service_edit_menu"))
37 , m_xServices_lb(m_xBuilder
->weld_combo_box("services_lb"))
38 , m_xPathContainer(m_xBuilder
->weld_container("breadcrumb_container"))
39 , m_xNewFolder(m_xBuilder
->weld_button("new_folder"))
40 , m_xListView_btn(m_xBuilder
->weld_toggle_button("list_view"))
41 , m_xIconView_btn(m_xBuilder
->weld_toggle_button("icon_view"))
42 , m_xFilter_lb(m_xBuilder
->weld_combo_box("filter_lb"))
43 , m_xName_ed(new AutocompleteEdit(m_xBuilder
->weld_entry("filename")))
45 m_xAddService_bar
->set_item_menu("add_service_btn", m_xAddService_menu
.get());
47 m_eMode
= ( nBits
& PickerFlags::SaveAs
) ? REMOTEDLG_MODE_SAVE
: REMOTEDLG_MODE_OPEN
;
48 m_eType
= ( nBits
& PickerFlags::PathDialog
) ? REMOTEDLG_TYPE_PATHDLG
: REMOTEDLG_TYPE_FILEDLG
;
49 bool bMultiselection
= bool( nBits
& PickerFlags::MultiSelection
);
51 m_bIsConnected
= false;
52 m_bServiceChanged
= false;
53 m_nCurrentFilter
= -1;
57 // limit width due to super wide strings that may end up here
58 m_xFilter_lb
->set_size_request(m_xFilter_lb
->get_approximate_digit_width() * 60, -1);
60 m_xFilter_lb
->set_sensitive(false);
61 m_xName_ed
->set_sensitive(false);
62 m_xNewFolder
->set_sensitive(false);
64 if( m_eMode
== REMOTEDLG_MODE_OPEN
)
66 m_xOk_btn
= m_xBuilder
->weld_button("open");
72 m_xOk_btn
= m_xBuilder
->weld_button("save");
73 m_xNewFolder
->connect_clicked( LINK( this, RemoteFilesDialog
, NewFolderHdl
) );
76 m_xListView_btn
->set_active(true);
77 m_xIconView_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, IconViewHdl
) );
78 m_xListView_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, ListViewHdl
) );
81 m_xOk_btn
->set_sensitive(false);
83 m_xOk_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, OkHdl
) );
84 m_xCancel_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, CancelHdl
) );
86 m_sRootLabel
= FpsResId( STR_SVT_ROOTLABEL
);
87 m_xPath
.reset(new Breadcrumb(m_xPathContainer
.get()));
88 m_xPath
->connect_clicked( LINK( this, RemoteFilesDialog
, SelectBreadcrumbHdl
) );
89 m_xPath
->SetMode( SvtBreadcrumbMode::ALL_VISITED
);
91 m_xContainer
= m_xBuilder
->weld_container("container");
92 m_xContainer
->set_size_request(m_xContainer
->get_approximate_digit_width() * 82, -1);
94 m_xFileView
.reset(new SvtFileView(m_xDialog
.get(),
95 m_xBuilder
->weld_tree_view("fileview"),
96 m_xBuilder
->weld_icon_view("iconview"),
97 REMOTEDLG_TYPE_PATHDLG
== m_eType
,
98 bMultiselection
, false));
100 m_xFileView
->SetDoubleClickHdl( LINK( this, RemoteFilesDialog
, DoubleClickHdl
) );
101 m_xFileView
->SetSelectHdl( LINK( this, RemoteFilesDialog
, SelectHdl
) );
102 m_xFileView
->EnableDelete( true );
104 m_xTreeView
.reset(new FolderTree(m_xBuilder
->weld_tree_view("foldertree"), m_xDialog
.get()));
105 m_xTreeView
->connect_changed(LINK(this, RemoteFilesDialog
, TreeSelectHdl
));
107 m_xContainer
->set_sensitive(false);
109 m_sIniKey
= "RemoteFilesDialog";
112 m_xName_ed
->connect_focus_in(LINK(this, RemoteFilesDialog
, FileNameGetFocusHdl
));
113 m_xName_ed
->connect_changed(LINK(this, RemoteFilesDialog
, FileNameModifyHdl
));
115 m_xAddService_bar
->connect_clicked(LINK( this, RemoteFilesDialog
, AddServiceHdl
));
116 m_xAddService_menu
->connect_activate(LINK(this, RemoteFilesDialog
, EditServiceMenuHdl
));
118 FillServicesListbox();
120 m_xServices_lb
->connect_changed( LINK( this, RemoteFilesDialog
, SelectServiceHdl
) );
122 m_xFilter_lb
->connect_changed( LINK( this, RemoteFilesDialog
, SelectFilterHdl
) );
125 RemoteFilesDialog::~RemoteFilesDialog()
127 m_xFileView
->SetSelectHdl(Link
<SvtFileView
*,void>());
130 if( !m_sIniKey
.isEmpty() )
132 SvtViewOptions
aDlgOpt( EViewType::Dialog
, m_sIniKey
);
133 aDlgOpt
.SetWindowState(OStringToOUString(m_xDialog
->get_window_state(WindowStateMask::All
), RTL_TEXTENCODING_UTF8
));
135 Size
aSize(m_xDialog
->get_size());
137 OUString sSize
= OUString::number( aSize
.Width() ) + "|";
138 sSize
= sSize
+ OUString::number( aSize
.Height() ) + "|";
140 OUString sUserData
= m_xFileView
->GetConfigString();
141 aDlgOpt
.SetUserItem( "UserData",
142 makeAny( sSize
+ sUserData
) );
146 std::shared_ptr
< comphelper::ConfigurationChanges
> batch( comphelper::ConfigurationChanges::create( m_xContext
) );
148 officecfg::Office::Common::Misc::FilePickerLastService::set( m_sLastServiceUrl
, batch
);
152 Sequence
< OUString
> placesUrlsList( m_aServices
.size() );
153 Sequence
< OUString
> placesNamesList( m_aServices
.size() );
156 for (auto const& service
: m_aServices
)
158 placesUrlsList
[i
] = service
->GetUrl();
159 placesNamesList
[i
] = service
->GetName();
163 officecfg::Office::Common::Misc::FilePickerPlacesUrls::set( placesUrlsList
, batch
);
164 officecfg::Office::Common::Misc::FilePickerPlacesNames::set( placesNamesList
, batch
);
170 short RemoteFilesDialog::run()
172 if (m_xServices_lb
->get_count() > 0)
175 SelectServiceHdl(*m_xServices_lb
);
179 m_xServices_lb
->set_active(-1);
180 m_xAddService_bar
->set_item_menu("add_service_btn", nullptr);
183 m_bIsInExecute
= true;
184 short nRet
= SvtFileDialog_Base::run();
185 m_bIsInExecute
= false;
189 static OUString
lcl_GetServiceType( const ServicePtr
& pService
)
191 INetProtocol aProtocol
= pService
->GetUrlObject().GetProtocol();
194 case INetProtocol::Ftp
:
196 case INetProtocol::Cmis
:
198 OUString sHost
= pService
->GetUrlObject().GetHost( INetURLObject::DecodeMechanism::WithCharset
);
200 if( sHost
.startsWith( GDRIVE_BASE_URL
) )
201 return "Google Drive";
202 else if( sHost
.startsWith( ALFRESCO_CLOUD_BASE_URL
) )
203 return "Alfresco Cloud";
204 else if( sHost
.startsWith( ONEDRIVE_BASE_URL
) )
209 case INetProtocol::Smb
:
210 return "Windows Share";
211 case INetProtocol::File
:
213 case INetProtocol::Http
:
215 case INetProtocol::Https
:
217 case INetProtocol::Generic
:
224 void RemoteFilesDialog::InitSize()
226 if( m_sIniKey
.isEmpty() )
229 // initialize from config
230 SvtViewOptions
aDlgOpt( EViewType::Dialog
, m_sIniKey
);
232 if( aDlgOpt
.Exists() )
234 m_xDialog
->set_window_state(OUStringToOString(aDlgOpt
.GetWindowState(), RTL_TEXTENCODING_UTF8
));
236 Any aUserData
= aDlgOpt
.GetUserItem( "UserData" );
238 if( aUserData
>>= sCfgStr
)
240 sal_Int32 nPos1
{ sCfgStr
.indexOf('|') };
243 sal_Int32 nPos2
{ sCfgStr
.indexOf('|', nPos1
+1 ) };
246 m_xFileView
->SetConfigString( sCfgStr
.copy(nPos2
+1) );
251 void RemoteFilesDialog::FillServicesListbox()
253 m_xServices_lb
->clear();
256 // Load from user settings
257 Sequence
< OUString
> placesUrlsList( officecfg::Office::Common::Misc::FilePickerPlacesUrls::get( m_xContext
) );
258 Sequence
< OUString
> placesNamesList( officecfg::Office::Common::Misc::FilePickerPlacesNames::get( m_xContext
) );
260 unsigned int nPos
= 0;
263 m_sLastServiceUrl
= officecfg::Office::Common::Misc::FilePickerLastService::get( m_xContext
);
265 for( sal_Int32 nPlace
= 0; nPlace
< placesUrlsList
.getLength() && nPlace
< placesNamesList
.getLength(); ++nPlace
)
267 ServicePtr
pService( new Place( placesNamesList
[nPlace
], placesUrlsList
[nPlace
], true ) );
268 m_aServices
.push_back( pService
);
270 // Add to the listbox only remote services, not local bookmarks
271 if( !pService
->IsLocal() )
273 OUString sPrefix
= lcl_GetServiceType( pService
);
275 if( !sPrefix
.isEmpty() )
278 if( placesUrlsList
[nPlace
] == m_sLastServiceUrl
)
281 m_xServices_lb
->append_text(sPrefix
+ placesNamesList
[nPlace
]);
287 if (m_xServices_lb
->get_count() > 0)
289 m_xServices_lb
->set_active(nPos
);
290 m_xAddService_bar
->set_item_menu("add_service_btn", m_xAddService_menu
.get());
293 m_xAddService_bar
->set_item_menu("add_service_btn", nullptr);
298 int RemoteFilesDialog::GetSelectedServicePos()
300 if( m_aServices
.empty() )
306 int nSelected
= m_xServices_lb
->get_active();
308 int nServices
= static_cast<int>(m_aServices
.size());
309 while( nPos
< nServices
)
311 while( (nPos
< nServices
) && m_aServices
[nPos
]->IsLocal() )
322 void RemoteFilesDialog::AddFilter( const OUString
& rFilter
, const OUString
& rType
)
324 OUString sName
= rFilter
;
326 m_aFilters
.emplace_back( rFilter
, rType
);
328 m_xFilter_lb
->append_separator("");
330 m_xFilter_lb
->append_text(sName
);
332 if (m_xFilter_lb
->get_active() == -1)
333 m_xFilter_lb
->set_active(0);
336 void RemoteFilesDialog::OpenURL( OUString
const & sURL
)
342 auto xWait
= std::make_unique
<weld::WaitObject
>(m_xDialog
.get());
344 if( !sURL
.isEmpty() )
346 OUString sFilter
= FILEDIALOG_FILTER_ALL
;
348 if( m_nCurrentFilter
!= -1)
350 sFilter
= m_aFilters
[m_nCurrentFilter
].second
;
353 m_xFileView
->EndInplaceEditing();
355 DBG_ASSERT( !m_pCurrentAsyncAction
.is(), "SvtFileDialog::executeAsync: previous async action not yet finished!" );
357 m_pCurrentAsyncAction
= new AsyncPickerAction( this, m_xFileView
.get(), AsyncPickerAction::Action::eOpenURL
);
360 m_pCurrentAsyncAction
->execute( sURL
, sFilter
, -1, -1, GetBlackList() );
362 if( m_eMode
!= REMOTEDLG_MODE_SAVE
)
363 m_xName_ed
->set_text( "" );
365 m_xFileView
->grab_focus();
371 // content doesn't exist
372 ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTS
);
379 void RemoteFilesDialog::AddFileExtension()
381 if (m_nCurrentFilter
!= -1)
383 OUString sExt
= m_aFilters
[m_nCurrentFilter
].second
;
384 OUString sFileName
= m_xName_ed
->get_text();
386 sal_Int32 nDotPos
= sFileName
.lastIndexOf( '.' );
390 sFileName
+= sExt
.copy( 1 ); // without '*'
391 m_xName_ed
->set_text( sFileName
);
396 void RemoteFilesDialog::EnableControls()
398 if (m_xServices_lb
->get_count() > 0)
400 m_xServices_lb
->set_sensitive(true);
402 if (m_xServices_lb
->get_active() != -1)
404 m_xAddService_menu
->set_sensitive("change_password", false);
408 if( m_xMasterPasswd
->isPersistentStoringAllowed() )
410 int nPos
= GetSelectedServicePos();
414 OUString
sUrl( m_aServices
[nPos
]->GetUrl() );
416 UrlRecord aURLEntries
= m_xMasterPasswd
->find( sUrl
, Reference
< XInteractionHandler
>() );
418 if( aURLEntries
.UserList
.hasElements() )
420 m_xAddService_menu
->set_sensitive("change_password", true);
425 catch( const Exception
& )
430 m_xServices_lb
->set_sensitive(false);
434 m_xFilter_lb
->set_sensitive(true);
435 m_xName_ed
->set_sensitive(true);
436 m_xContainer
->set_sensitive(true);
437 m_xNewFolder
->set_sensitive(true);
439 if (!m_xName_ed
->get_text().isEmpty())
440 m_xOk_btn
->set_sensitive(true);
442 m_xOk_btn
->set_sensitive(false);
446 m_xFilter_lb
->set_sensitive(false);
447 m_xName_ed
->set_sensitive(false);
448 m_xContainer
->set_sensitive(false);
449 m_xNewFolder
->set_sensitive(false);
450 m_xOk_btn
->set_sensitive(false);
453 m_xPath
->EnableFields( true );
454 m_xAddService_bar
->set_sensitive(true);
457 void RemoteFilesDialog::DisableControls()
459 m_xServices_lb
->set_sensitive(false);
460 m_xFilter_lb
->set_sensitive(false);
461 m_xAddService_bar
->set_sensitive(false);
462 m_xName_ed
->set_sensitive(false);
463 m_xContainer
->set_sensitive(false);
464 m_xOk_btn
->set_sensitive(false);
465 m_xPath
->EnableFields( false );
467 m_xCancel_btn
->set_sensitive(true);
470 void RemoteFilesDialog::SavePassword(const OUString
& rURL
, const OUString
& rUser
,
471 const OUString
& rPassword
, bool bPersistent
)
473 if( rURL
.isEmpty() || rUser
.isEmpty() || rPassword
.isEmpty() )
479 ( m_xMasterPasswd
->isPersistentStoringAllowed()
480 && m_xMasterPasswd
->authorizateWithMasterPassword( Reference
< XInteractionHandler
>() ) )
483 Reference
< XInteractionHandler
> xInteractionHandler
=
484 InteractionHandler::createWithParent( m_xContext
, nullptr );
486 Sequence
<OUString
> aPasswd
{ rPassword
};
489 m_xMasterPasswd
->addPersistent(
490 rURL
, rUser
, aPasswd
, xInteractionHandler
);
492 m_xMasterPasswd
->add( rURL
, rUser
, aPasswd
, xInteractionHandler
);
495 catch( const Exception
& )
499 IMPL_LINK_NOARG ( RemoteFilesDialog
, IconViewHdl
, weld::Button
&, void )
501 m_xListView_btn
->set_active(false);
502 m_xFileView
->SetViewMode( eIcon
);
505 IMPL_LINK_NOARG ( RemoteFilesDialog
, ListViewHdl
, weld::Button
&, void )
507 m_xIconView_btn
->set_active(false);
508 m_xFileView
->SetViewMode( eDetailedList
);
511 IMPL_LINK_NOARG ( RemoteFilesDialog
, AddServiceHdl
, const OString
&, void )
513 PlaceEditDialog
aDlg(m_xDialog
.get());
514 aDlg
.ShowPasswordControl();
515 short aRetCode
= aDlg
.run();
521 ServicePtr newService
= aDlg
.GetPlace();
522 m_aServices
.push_back( newService
);
524 OUString sPassword
= aDlg
.GetPassword();
525 OUString sUser
= aDlg
.GetUser();
526 if( !sUser
.isEmpty() && !sPassword
.isEmpty() )
528 bool bPersistent
= aDlg
.IsRememberChecked();
529 SavePassword( newService
->GetUrl(), sUser
, sPassword
, bPersistent
);
532 OUString sPrefix
= lcl_GetServiceType( newService
);
534 if(!sPrefix
.isEmpty())
537 m_xServices_lb
->append_text( sPrefix
+ newService
->GetName() );
538 m_xServices_lb
->set_active( m_xServices_lb
->get_count() - 1 );
539 m_xAddService_bar
->set_item_menu("add_service_btn", m_xAddService_menu
.get());
540 SelectServiceHdl( *m_xServices_lb
);
554 IMPL_LINK_NOARG( RemoteFilesDialog
, SelectServiceHdl
, weld::ComboBox
&, void )
556 int nPos
= GetSelectedServicePos();
560 OUString sURL
= m_aServices
[nPos
]->GetUrl();
561 m_xAddService_bar
->set_item_menu("add_service_btn", m_xAddService_menu
.get());
563 m_bServiceChanged
= true;
568 IMPL_LINK ( RemoteFilesDialog
, EditServiceMenuHdl
, const OString
&, rIdent
, void )
570 OString
sIdent(rIdent
);
571 if( sIdent
== "edit_service" && m_xServices_lb
->get_count() > 0 )
573 int nSelected
= m_xServices_lb
->get_active();
574 int nPos
= GetSelectedServicePos();
578 PlaceEditDialog
aDlg(m_xDialog
.get(), m_aServices
[nPos
]);
579 short aRetCode
= aDlg
.run();
585 ServicePtr pEditedService
= aDlg
.GetPlace();
587 m_aServices
[nPos
] = pEditedService
;
588 m_xServices_lb
->remove( nSelected
);
590 OUString sPrefix
= lcl_GetServiceType( pEditedService
);
592 if(!sPrefix
.isEmpty())
595 m_xServices_lb
->insert_text(nSelected
, sPrefix
+ pEditedService
->GetName());
596 m_xServices_lb
->set_active( nSelected
);
602 sIdent
= "delete_service";
611 if( sIdent
== "delete_service" && m_xServices_lb
->get_count() > 0 )
613 int nSelected
= m_xServices_lb
->get_active();
614 int nPos
= GetSelectedServicePos();
618 OUString sMsg
= FpsResId( STR_SVT_DELETESERVICE
);
619 sMsg
= sMsg
.replaceFirst( "$servicename$", m_xServices_lb
->get_active_text() );
620 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
621 VclMessageType::Question
, VclButtonsType::YesNo
, sMsg
));
622 if (xBox
->run() == RET_YES
)
627 if( m_xMasterPasswd
->isPersistentStoringAllowed() )
629 OUString
sUrl( m_aServices
[nPos
]->GetUrl() );
631 Reference
< XInteractionHandler
> xInteractionHandler
=
632 InteractionHandler::createWithParent( m_xContext
, nullptr );
634 UrlRecord aURLEntries
= m_xMasterPasswd
->find( sUrl
, xInteractionHandler
);
636 if( aURLEntries
.Url
== sUrl
&& aURLEntries
.UserList
.hasElements() )
638 OUString sUserName
= aURLEntries
.UserList
[0].UserName
;
640 m_xMasterPasswd
->removePersistent( sUrl
, sUserName
);
644 catch( const Exception
& )
647 m_aServices
.erase( m_aServices
.begin() + nPos
);
648 m_xServices_lb
->remove( nSelected
);
650 m_xServices_lb
->set_active(-1);
651 m_xAddService_bar
->set_item_menu("add_service_btn", nullptr);
655 m_bIsConnected
= false;
660 else if( sIdent
== "change_password" )
664 if( m_xMasterPasswd
->isPersistentStoringAllowed() && m_xMasterPasswd
->authorizateWithMasterPassword( Reference
< XInteractionHandler
>() ) )
666 int nPos
= GetSelectedServicePos();
670 OUString
sUrl( m_aServices
[nPos
]->GetUrl() );
672 Reference
< XInteractionHandler
> xInteractionHandler
=
673 InteractionHandler::createWithParent( m_xContext
, nullptr );
675 UrlRecord aURLEntries
= m_xMasterPasswd
->find( sUrl
, xInteractionHandler
);
677 if( aURLEntries
.Url
== sUrl
&& aURLEntries
.UserList
.hasElements() )
679 OUString sUserName
= aURLEntries
.UserList
[0].UserName
;
681 ::comphelper::SimplePasswordRequest
* pPasswordRequest
682 = new ::comphelper::SimplePasswordRequest
;
683 Reference
< XInteractionRequest
> rRequest( pPasswordRequest
);
685 xInteractionHandler
->handle( rRequest
);
687 if ( pPasswordRequest
->isPassword() )
689 OUString aNewPass
= pPasswordRequest
->getPassword();
690 Sequence
<OUString
> aPasswd
{ aNewPass
};
692 m_xMasterPasswd
->addPersistent(
693 sUrl
, sUserName
, aPasswd
, xInteractionHandler
);
699 catch( const Exception
& )
706 IMPL_LINK_NOARG( RemoteFilesDialog
, DoubleClickHdl
, SvtFileView
*, bool )
708 SvtContentEntry
* pData
= m_xFileView
->FirstSelected();
711 if (!pData
->mbIsFolder
)
712 m_xDialog
->response(RET_OK
);
714 OpenURL(pData
->maURL
);
719 IMPL_LINK_NOARG( RemoteFilesDialog
, SelectHdl
, SvtFileView
*, void )
721 SvtContentEntry
* pData
= m_xFileView
->FirstSelected();
724 if( ( pData
->mbIsFolder
&& ( m_eType
== REMOTEDLG_TYPE_PATHDLG
) )
725 || ( !pData
->mbIsFolder
&& ( m_eType
== REMOTEDLG_TYPE_FILEDLG
) ) )
727 // url must contain user info, because we need this info in recent files entry
728 // (to fill user field in login box by default)
729 INetURLObject
aURL( pData
->maURL
);
730 INetURLObject
aCurrentURL( m_sLastServiceUrl
);
731 aURL
.SetUser( aCurrentURL
.GetUser() );
733 m_sPath
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
735 m_xName_ed
->set_text( aURL
.GetLastName(INetURLObject::DecodeMechanism::WithCharset
) );
739 if( m_eMode
== REMOTEDLG_MODE_OPEN
)
742 m_xName_ed
->set_text( "" );
750 IMPL_LINK_NOARG(RemoteFilesDialog
, FileNameGetFocusHdl
, weld::Widget
&, void)
752 m_xFileView
->SetNoSelection();
755 IMPL_LINK_NOARG(RemoteFilesDialog
, FileNameModifyHdl
, weld::Entry
&, void)
757 m_xFileView
->SetNoSelection();
758 if (!m_xOk_btn
->get_sensitive())
762 IMPL_LINK_NOARG( RemoteFilesDialog
, SelectFilterHdl
, weld::ComboBox
&, void )
764 int nPos
= m_xFilter_lb
->get_active();
766 if( nPos
!= -1 && !m_aFilters
[nPos
].second
.isEmpty() )
768 m_nCurrentFilter
= nPos
;
770 OUString sCurrentURL
= m_xFileView
->GetViewURL();
772 if( !sCurrentURL
.isEmpty() && m_bIsConnected
)
773 OpenURL( sCurrentURL
);
777 IMPL_LINK(RemoteFilesDialog
, TreeSelectHdl
, weld::TreeView
&, rBox
, void)
779 OpenURL(rBox
.get_selected_id());
780 m_xFileView
->grab_focus();
783 IMPL_LINK(RemoteFilesDialog
, SelectBreadcrumbHdl
, Breadcrumb
*, pPtr
, bool)
785 OpenURL( pPtr
->GetHdlURL() );
789 IMPL_LINK_NOARG ( RemoteFilesDialog
, NewFolderHdl
, weld::Button
&, void )
791 m_xFileView
->EndInplaceEditing();
793 // will be bound after InteractionHandler is enabled
794 SmartContent aContent
;
795 aContent
.enableDefaultInteractionHandler();
796 // now it can be bound
797 aContent
.bindTo( m_xFileView
->GetViewURL() );
798 if( !aContent
.canCreateFolder() )
802 aContent
.getTitle( aTitle
);
803 QueryFolderNameDialog
aDlg(m_xDialog
.get(), aTitle
, FpsResId(STR_SVT_NEW_FOLDER
));
804 bool bHandled
= false;
808 if (aDlg
.run() == RET_OK
)
810 OUString aUrl
= aContent
.createFolder(aDlg
.GetName());
811 if( !aUrl
.isEmpty() )
813 m_xFileView
->CreatedFolder(aUrl
, aDlg
.GetName());
822 IMPL_LINK_NOARG ( RemoteFilesDialog
, OkHdl
, weld::Button
&, void )
824 OUString sNameNoExt
= m_xName_ed
->get_text();
828 if( m_eMode
== REMOTEDLG_MODE_SAVE
)
831 // check if file/path exists
833 OUString sCurrentPath
= m_xFileView
->GetViewURL();
834 OUString sSelectedItem
= m_xFileView
->GetCurrentURL();
835 OUString sName
= m_xName_ed
->get_text();
837 bool bFileDlg
= ( m_eType
== REMOTEDLG_TYPE_FILEDLG
);
838 bool bSelected
= ( m_xFileView
->GetSelectionCount() > 0 );
840 if( !sCurrentPath
.endsWith("/") )
845 m_sPath
= sCurrentPath
+ INetURLObject::encode( sName
, INetURLObject::PART_FPATH
, INetURLObject::EncodeMechanism::All
);
846 sPathNoExt
= sCurrentPath
+ INetURLObject::encode( sNameNoExt
, INetURLObject::PART_FPATH
, INetURLObject::EncodeMechanism::All
);
850 if( m_eType
== REMOTEDLG_TYPE_PATHDLG
)
851 m_sPath
= sCurrentPath
;
853 m_sPath
= sSelectedItem
;
855 // url must contain user info, because we need this info in recent files entry
856 // (to fill user field in login box by default)
857 INetURLObject
aURL( m_sPath
);
858 INetURLObject
aCurrentURL( m_sLastServiceUrl
);
859 aURL
.SetUser( aCurrentURL
.GetUser() );
861 m_sPath
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
864 bool bExists
= false;
867 bExists
= ContentIsDocument( m_sPath
);
869 bExists
= ContentIsFolder( m_sPath
);
873 if( m_eMode
== REMOTEDLG_MODE_SAVE
)
875 OUString sMsg
= FpsResId( STR_SVT_ALREADYEXISTOVERWRITE
);
876 sMsg
= sMsg
.replaceFirst( "$filename$", sName
);
877 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
878 VclMessageType::Question
, VclButtonsType::YesNo
, sMsg
));
879 if (xBox
->run() != RET_YES
)
885 if( ContentIsFolder( sPathNoExt
) )
887 OpenURL( sPathNoExt
);
888 m_xName_ed
->set_text( "" );
891 m_xName_ed
->grab_focus();
896 if( m_eMode
== REMOTEDLG_MODE_OPEN
)
900 m_xDialog
->response(RET_OK
);
903 IMPL_LINK_NOARG ( RemoteFilesDialog
, CancelHdl
, weld::Button
&, void )
905 if( m_pCurrentAsyncAction
.is() )
907 m_pCurrentAsyncAction
->cancel();
908 onAsyncOperationFinished();
912 m_xDialog
->response(RET_CANCEL
);
916 // SvtFileDialog_Base
917 SvtFileView
* RemoteFilesDialog::GetView()
919 return m_xFileView
.get();
922 void RemoteFilesDialog::SetHasFilename( bool )
926 void RemoteFilesDialog::SetBlackList( const css::uno::Sequence
< OUString
>& rBlackList
)
928 m_aBlackList
= rBlackList
;
929 m_xTreeView
->SetBlackList( rBlackList
);
932 const css::uno::Sequence
< OUString
>& RemoteFilesDialog::GetBlackList() const
937 void RemoteFilesDialog::SetStandardDir( const OUString
& rStdDir
)
942 const OUString
& RemoteFilesDialog::GetStandardDir() const
947 void RemoteFilesDialog::SetPath( const OUString
& rNewURL
)
951 if( m_eMode
== REMOTEDLG_MODE_SAVE
)
953 INetURLObject
aUrl( m_sPath
);
954 OUString sFileName
= aUrl
.GetLastName( INetURLObject::DecodeMechanism::WithCharset
);
956 m_xName_ed
->set_text( sFileName
);
960 OUString
RemoteFilesDialog::getCurrentFileText() const
964 sReturn
= m_xName_ed
->get_text();
968 void RemoteFilesDialog::setCurrentFileText( const OUString
& rText
, bool bSelectAll
)
972 m_xName_ed
->set_text(rText
);
974 m_xName_ed
->select_region(0, -1);
978 void RemoteFilesDialog::AddFilterGroup(
979 const OUString
& rFilter
,
980 const css::uno::Sequence
< css::beans::StringPair
>& rFilters
)
982 AddFilter( rFilter
, OUString() );
983 const StringPair
* pSubFilters
= rFilters
.getConstArray();
984 const StringPair
* pSubFiltersEnd
= pSubFilters
+ rFilters
.getLength();
985 for ( ; pSubFilters
!= pSubFiltersEnd
; ++pSubFilters
)
986 AddFilter( pSubFilters
->First
, pSubFilters
->Second
);
989 OUString
RemoteFilesDialog::GetCurFilter() const
993 if (m_nCurrentFilter
!= -1)
995 sFilter
= m_aFilters
[m_nCurrentFilter
].first
;
1001 OUString
RemoteFilesDialog::getCurFilter( ) const
1003 return GetCurFilter();
1006 void RemoteFilesDialog::SetCurFilter( const OUString
& rFilter
)
1008 DBG_ASSERT( !m_bIsInExecute
, "SvtFileDialog::SetCurFilter: currently executing!" );
1010 // look for corresponding filter
1011 sal_uInt16 nPos
= m_aFilters
.size();
1015 if ( m_aFilters
[nPos
].first
== rFilter
)
1017 m_nCurrentFilter
= nPos
;
1018 m_xFilter_lb
->set_active( m_nCurrentFilter
);
1024 void RemoteFilesDialog::FilterSelect()
1028 void RemoteFilesDialog::SetFileCallback( ::svt::IFilePickerListener
* )
1032 void RemoteFilesDialog::onAsyncOperationStarted()
1037 void RemoteFilesDialog::onAsyncOperationFinished()
1039 m_pCurrentAsyncAction
= nullptr;
1043 void RemoteFilesDialog::UpdateControls( const OUString
& rURL
)
1045 int nPos
= GetSelectedServicePos();
1047 if( nPos
>= 0 && m_bServiceChanged
&& rURL
== m_aServices
[nPos
]->GetUrl() )
1049 OUString sURL
= m_aServices
[nPos
]->GetUrl();
1051 m_xPath
->SetRootName( m_sRootLabel
);
1052 m_xTreeView
->clear();
1054 m_xTreeView
->InsertRootEntry(rURL
, m_sRootLabel
);
1056 m_xName_ed
->grab_focus();
1058 m_sLastServiceUrl
= sURL
;
1060 m_bServiceChanged
= false;
1063 m_xPath
->SetURL( rURL
);
1065 m_xTreeView
->connect_changed(Link
<weld::TreeView
&,void>());
1067 // read cached data for this url and fill the tree
1068 const ::std::vector
< SvtContentEntry
>& rFolders
= m_xFileView
->GetContent();
1069 ::std::vector
< std::pair
< OUString
, OUString
> > aFolders
;
1071 m_xName_ed
->ClearEntries();
1073 for(const auto & rFolder
: rFolders
)
1075 //WebDAV folders path ends in '/', so strip it
1076 OUString aFolderName
= rFolder
.maURL
;
1077 if( rFolder
.mbIsFolder
&& ( ( aFolderName
.lastIndexOf( '/' ) + 1 ) == aFolderName
.getLength() ) )
1078 aFolderName
= aFolderName
.copy( 0, aFolderName
.getLength() - 1 );
1080 int nTitleStart
= aFolderName
.lastIndexOf( '/' );
1081 if( nTitleStart
!= -1 )
1083 OUString
sTitle( INetURLObject::decode(
1084 aFolderName
.copy( nTitleStart
+ 1 ),
1085 INetURLObject::DecodeMechanism::WithCharset
) );
1087 if( rFolder
.mbIsFolder
)
1089 aFolders
.emplace_back( sTitle
, aFolderName
);
1092 // add entries to the autocompletion mechanism
1093 m_xName_ed
->AddEntry( sTitle
);
1097 m_xTreeView
->FillTreeEntry( rURL
, aFolders
);
1099 m_xTreeView
->connect_changed( LINK( this, RemoteFilesDialog
, TreeSelectHdl
) );
1101 m_bIsConnected
= true;
1105 void RemoteFilesDialog::EnableAutocompletion( bool )
1107 // This dialog contains Breadcrumb, not Edit
1110 const OUString
& RemoteFilesDialog::GetPath()
1115 std::vector
<OUString
> RemoteFilesDialog::GetPathList() const
1117 std::vector
<OUString
> aList
;
1119 m_xFileView
->selected_foreach([this, &aList
](weld::TreeIter
& rCurEntry
){
1120 // url must contain user info, because we need this info in recent files entry
1121 // (to fill user field in login box by default)
1122 INetURLObject
aURL(m_xFileView
->GetURL(rCurEntry
));
1123 INetURLObject
aCurrentURL( m_sLastServiceUrl
);
1124 aURL
.SetUser( aCurrentURL
.GetUser() );
1126 aList
.push_back( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
1131 if( aList
.empty() && !m_sPath
.isEmpty() )
1132 aList
.push_back( m_sPath
);
1137 bool RemoteFilesDialog::ContentIsFolder( const OUString
& rURL
)
1141 Reference
< XInteractionHandler
> xInteractionHandler(
1142 InteractionHandler::createWithParent( m_xContext
, nullptr ), UNO_QUERY_THROW
);
1143 Reference
< XCommandEnvironment
> xEnv
= new ::ucbhelper::CommandEnvironment( xInteractionHandler
, Reference
< XProgressHandler
>() );
1144 ::ucbhelper::Content
aContent( rURL
, xEnv
, m_xContext
);
1146 return aContent
.isFolder();
1148 catch( const Exception
& )
1150 // a content doesn't exist
1156 bool RemoteFilesDialog::ContentIsDocument( const OUString
& rURL
)
1160 Reference
< XInteractionHandler
> xInteractionHandler(
1161 InteractionHandler::createWithParent( m_xContext
, nullptr ), UNO_QUERY_THROW
);
1162 //check if WebDAV or not
1163 if ( !INetURLObject( rURL
).isAnyKnownWebDAVScheme() )
1165 // no webdav, use the interaction handler as is
1166 Reference
< XCommandEnvironment
> xEnv
= new ::ucbhelper::CommandEnvironment( xInteractionHandler
, Reference
< XProgressHandler
>() );
1167 ::ucbhelper::Content
aContent( rURL
, xEnv
, m_xContext
);
1169 return aContent
.isDocument();
1173 // It's a webdav URL, so use the same open sequence as in normal open process.
1174 // Let's use a comphelper::StillReadWriteInteraction to trap errors here without showing the user.
1175 // This sequence will result in an exception if the target URL resource is not present
1176 comphelper::StillReadWriteInteraction
* pInteraction
= new comphelper::StillReadWriteInteraction(xInteractionHandler
,xInteractionHandler
);
1177 css::uno::Reference
< css::task::XInteractionHandler
> xInteraction(static_cast< css::task::XInteractionHandler
* >(pInteraction
), css::uno::UNO_QUERY
);
1179 Reference
< XCommandEnvironment
> xEnv
= new ::ucbhelper::CommandEnvironment( xInteraction
, Reference
< XProgressHandler
>() );
1180 ::ucbhelper::Content
aContent( rURL
, xEnv
, m_xContext
);
1182 aContent
.openStream();
1183 return aContent
.isDocument();
1186 catch( const Exception
& )
1188 // a content doesn't exist
1194 sal_Int32
RemoteFilesDialog::getAvailableWidth()
1196 // This dialog doesn't contain preview
1200 sal_Int32
RemoteFilesDialog::getAvailableHeight()
1202 // This dialog doesn't contain preview
1206 void RemoteFilesDialog::setImage( const css::uno::Any
& )
1208 // This dialog doesn't contain preview
1211 bool RemoteFilesDialog::getShowState()
1213 // This dialog doesn't contain preview
1217 weld::Widget
* RemoteFilesDialog::getControl( sal_Int16
, bool) const
1222 void RemoteFilesDialog::enableControl( sal_Int16
, bool )
1226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */