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 <fpicker/fpsofficeResMgr.hxx>
16 #include <fpicker/strings.hrc>
17 #include <strings.hrc>
18 #include <comphelper/docpasswordrequest.hxx>
19 #include <com/sun/star/task/InteractionHandler.hpp>
20 #include <com/sun/star/task/PasswordContainer.hpp>
21 #include <svtools/PlaceEditDialog.hxx>
22 #include <tools/debug.hxx>
23 #include <unotools/ucbhelper.hxx>
24 #include <vcl/errinf.hxx>
25 #include <officecfg/Office/Common.hxx>
27 using namespace ::svt
;
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_xOk_btn(m_xBuilder
->weld_button("ok"))
35 , m_xCancel_btn(m_xBuilder
->weld_button("cancel"))
36 , m_xManageServices(m_xBuilder
->weld_menu_button("add_service_btn"))
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_eMode
= ( nBits
& PickerFlags::SaveAs
) ? REMOTEDLG_MODE_SAVE
: REMOTEDLG_MODE_OPEN
;
46 m_eType
= ( nBits
& PickerFlags::PathDialog
) ? REMOTEDLG_TYPE_PATHDLG
: REMOTEDLG_TYPE_FILEDLG
;
47 bool bMultiselection
= bool( nBits
& PickerFlags::MultiSelection
);
49 m_bIsConnected
= false;
50 m_bServiceChanged
= false;
51 m_nCurrentFilter
= -1;
55 // limit width due to super wide strings that may end up here
56 m_xFilter_lb
->set_size_request(m_xFilter_lb
->get_approximate_digit_width() * 60, -1);
58 m_xFilter_lb
->set_sensitive(false);
59 m_xName_ed
->set_sensitive(false);
60 m_xNewFolder
->set_sensitive(false);
62 if( m_eMode
== REMOTEDLG_MODE_OPEN
)
68 m_xOk_btn
->set_label(FpsResId(STR_EXPLORERFILE_BUTTONSAVE
));
69 m_xNewFolder
->connect_clicked( LINK( this, RemoteFilesDialog
, NewFolderHdl
) );
72 m_xListView_btn
->set_active(true);
73 m_xIconView_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, IconViewHdl
) );
74 m_xListView_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, ListViewHdl
) );
76 m_xOk_btn
->set_sensitive(false);
78 m_xOk_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, OkHdl
) );
79 m_xCancel_btn
->connect_clicked( LINK( this, RemoteFilesDialog
, CancelHdl
) );
81 m_sRootLabel
= FpsResId( STR_SVT_ROOTLABEL
);
82 m_xPath
.reset(new Breadcrumb(m_xPathContainer
.get()));
83 m_xPath
->connect_clicked( LINK( this, RemoteFilesDialog
, SelectBreadcrumbHdl
) );
84 m_xPath
->SetMode( SvtBreadcrumbMode::ALL_VISITED
);
86 m_xContainer
= m_xBuilder
->weld_container("container");
87 m_xContainer
->set_size_request(m_xContainer
->get_approximate_digit_width() * 82, -1);
89 m_xFileView
.reset(new SvtFileView(m_xDialog
.get(),
90 m_xBuilder
->weld_tree_view("fileview"),
91 m_xBuilder
->weld_icon_view("iconview"),
92 REMOTEDLG_TYPE_PATHDLG
== m_eType
,
93 bMultiselection
, false));
95 m_xFileView
->SetDoubleClickHdl( LINK( this, RemoteFilesDialog
, DoubleClickHdl
) );
96 m_xFileView
->SetSelectHdl( LINK( this, RemoteFilesDialog
, SelectHdl
) );
97 m_xFileView
->EnableDelete( true );
99 m_xTreeView
.reset(new FolderTree(m_xBuilder
->weld_tree_view("foldertree"), m_xDialog
.get()));
100 m_xTreeView
->connect_changed(LINK(this, RemoteFilesDialog
, TreeSelectHdl
));
102 m_xContainer
->set_sensitive(false);
104 m_sIniKey
= "RemoteFilesDialog";
107 m_xName_ed
->connect_focus_in(LINK(this, RemoteFilesDialog
, FileNameGetFocusHdl
));
108 m_xName_ed
->connect_changed(LINK(this, RemoteFilesDialog
, FileNameModifyHdl
));
110 m_xManageServices
->connect_selected(LINK(this, RemoteFilesDialog
, EditServiceMenuHdl
));
112 FillServicesListbox();
114 m_xServices_lb
->connect_changed( LINK( this, RemoteFilesDialog
, SelectServiceHdl
) );
116 m_xFilter_lb
->connect_changed( LINK( this, RemoteFilesDialog
, SelectFilterHdl
) );
119 RemoteFilesDialog::~RemoteFilesDialog()
121 m_xFileView
->SetSelectHdl(Link
<SvtFileView
*,void>());
124 if( !m_sIniKey
.isEmpty() )
126 SvtViewOptions
aDlgOpt( EViewType::Dialog
, m_sIniKey
);
127 aDlgOpt
.SetWindowState(m_xDialog
->get_window_state(vcl::WindowDataMask::All
));
129 Size
aSize(m_xDialog
->get_size());
131 OUString sSize
= OUString::number( aSize
.Width() ) + "|";
132 sSize
= sSize
+ OUString::number( aSize
.Height() ) + "|";
134 OUString sUserData
= m_xFileView
->GetConfigString();
135 aDlgOpt
.SetUserItem( "UserData",
136 Any( sSize
+ sUserData
) );
140 std::shared_ptr
< comphelper::ConfigurationChanges
> batch( comphelper::ConfigurationChanges::create() );
142 officecfg::Office::Common::Misc::FilePickerLastService::set( m_sLastServiceUrl
, batch
);
146 Sequence
< OUString
> placesUrlsList( m_aServices
.size() );
147 auto placesUrlsListRange
= asNonConstRange(placesUrlsList
);
148 Sequence
< OUString
> placesNamesList( m_aServices
.size() );
149 auto placesNamesListRange
= asNonConstRange(placesNamesList
);
152 for (auto const& service
: m_aServices
)
154 placesUrlsListRange
[i
] = service
->GetUrl();
155 placesNamesListRange
[i
] = service
->GetName();
159 officecfg::Office::Common::Misc::FilePickerPlacesUrls::set( placesUrlsList
, batch
);
160 officecfg::Office::Common::Misc::FilePickerPlacesNames::set( placesNamesList
, batch
);
166 void RemoteFilesDialog::EnableExtraMenuItems(bool bEnable
)
168 m_xManageServices
->set_item_visible("change_password", bEnable
);
169 m_xManageServices
->set_item_visible("edit_service", bEnable
);
170 m_xManageServices
->set_item_visible("delete_service", bEnable
);
171 m_xManageServices
->set_item_visible("change_password", bEnable
);
174 short RemoteFilesDialog::run()
176 if (m_xServices_lb
->get_count() > 0)
179 SelectServiceHdl(*m_xServices_lb
);
183 m_xServices_lb
->set_active(-1);
184 EnableExtraMenuItems(false);
187 m_bIsInExecute
= true;
188 short nRet
= SvtFileDialog_Base::run();
189 m_bIsInExecute
= false;
193 static OUString
lcl_GetServiceType( const ServicePtr
& pService
)
195 INetProtocol aProtocol
= pService
->GetUrlObject().GetProtocol();
198 case INetProtocol::Cmis
:
200 OUString sHost
= pService
->GetUrlObject().GetHost( INetURLObject::DecodeMechanism::WithCharset
);
202 if( sHost
.startsWith( GDRIVE_BASE_URL
) )
203 return "Google Drive";
204 else if( sHost
.startsWith( ALFRESCO_CLOUD_BASE_URL
) )
205 return "Alfresco Cloud";
206 else if( sHost
.startsWith( ONEDRIVE_BASE_URL
) )
211 case INetProtocol::Smb
:
212 return "Windows Share";
213 case INetProtocol::File
:
215 case INetProtocol::Http
:
217 case INetProtocol::Https
:
219 case INetProtocol::Generic
:
226 void RemoteFilesDialog::InitSize()
228 if( m_sIniKey
.isEmpty() )
231 // initialize from config
232 SvtViewOptions
aDlgOpt( EViewType::Dialog
, m_sIniKey
);
234 if( !aDlgOpt
.Exists() )
237 m_xDialog
->set_window_state(aDlgOpt
.GetWindowState());
239 Any aUserData
= aDlgOpt
.GetUserItem( "UserData" );
241 if( aUserData
>>= sCfgStr
)
243 sal_Int32 nPos1
{ sCfgStr
.indexOf('|') };
246 sal_Int32 nPos2
{ sCfgStr
.indexOf('|', nPos1
+1 ) };
249 m_xFileView
->SetConfigString( sCfgStr
.subView(nPos2
+1) );
253 void RemoteFilesDialog::FillServicesListbox()
255 m_xServices_lb
->clear();
258 // Load from user settings
259 Sequence
< OUString
> placesUrlsList( officecfg::Office::Common::Misc::FilePickerPlacesUrls::get() );
260 Sequence
< OUString
> placesNamesList( officecfg::Office::Common::Misc::FilePickerPlacesNames::get() );
262 unsigned int nPos
= 0;
265 m_sLastServiceUrl
= officecfg::Office::Common::Misc::FilePickerLastService::get();
267 for( sal_Int32 nPlace
= 0; nPlace
< placesUrlsList
.getLength() && nPlace
< placesNamesList
.getLength(); ++nPlace
)
269 ServicePtr pService
= std::make_shared
<Place
>( placesNamesList
[nPlace
], placesUrlsList
[nPlace
], true );
270 m_aServices
.push_back( pService
);
272 // Add to the listbox only remote services, not local bookmarks
273 if( !pService
->IsLocal() )
275 OUString sPrefix
= lcl_GetServiceType( pService
);
277 if( !sPrefix
.isEmpty() )
280 if( placesUrlsList
[nPlace
] == m_sLastServiceUrl
)
283 m_xServices_lb
->append_text(sPrefix
+ placesNamesList
[nPlace
]);
289 if (m_xServices_lb
->get_count() > 0)
291 m_xServices_lb
->set_active(nPos
);
292 EnableExtraMenuItems(true);
295 EnableExtraMenuItems(false);
300 int RemoteFilesDialog::GetSelectedServicePos()
302 if( m_aServices
.empty() )
308 int nSelected
= m_xServices_lb
->get_active();
310 int nServices
= static_cast<int>(m_aServices
.size());
311 while( nPos
< nServices
)
313 while( (nPos
< nServices
) && m_aServices
[nPos
]->IsLocal() )
324 void RemoteFilesDialog::AddFilter( const OUString
& rFilter
, const OUString
& rType
)
326 OUString sName
= rFilter
;
328 m_aFilters
.emplace_back( rFilter
, rType
);
330 m_xFilter_lb
->append_separator("");
332 m_xFilter_lb
->append_text(sName
);
334 if (m_xFilter_lb
->get_active() == -1)
335 m_xFilter_lb
->set_active(0);
338 void RemoteFilesDialog::OpenURL( OUString
const & sURL
)
345 auto xWait
= std::make_unique
<weld::WaitObject
>(m_xDialog
.get());
347 if( !sURL
.isEmpty() )
349 OUString sFilter
= FILEDIALOG_FILTER_ALL
;
351 if( m_nCurrentFilter
!= -1)
353 sFilter
= m_aFilters
[m_nCurrentFilter
].second
;
356 m_xFileView
->EndInplaceEditing();
358 DBG_ASSERT( !m_pCurrentAsyncAction
.is(), "SvtFileDialog::executeAsync: previous async action not yet finished!" );
360 m_pCurrentAsyncAction
= new AsyncPickerAction( this, m_xFileView
.get(), AsyncPickerAction::Action::eOpenURL
);
363 m_pCurrentAsyncAction
->execute( sURL
, sFilter
, -1, -1, GetDenyList() );
365 if( m_eMode
!= REMOTEDLG_MODE_SAVE
)
366 m_xName_ed
->set_text( "" );
368 m_xFileView
->grab_focus();
374 // content doesn't exist
375 ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTS
);
381 OUString
RemoteFilesDialog::AddFileExtension(const OUString
& rFileName
)
383 if (m_nCurrentFilter
== -1)
386 OUString sExt
= m_aFilters
[m_nCurrentFilter
].second
;
387 sal_Int32 nDotPos
= rFileName
.lastIndexOf( '.' );
390 return rFileName
+ sExt
.subView( 1 ); // without '*'
395 void RemoteFilesDialog::EnableControls()
397 if (m_xServices_lb
->get_count() > 0)
399 m_xServices_lb
->set_sensitive(true);
401 if (m_xServices_lb
->get_active() != -1)
403 m_xManageServices
->set_item_sensitive("change_password", false);
407 if( m_xMasterPasswd
->isPersistentStoringAllowed() )
409 int nPos
= GetSelectedServicePos();
413 OUString
sUrl( m_aServices
[nPos
]->GetUrl() );
415 UrlRecord aURLEntries
= m_xMasterPasswd
->find( sUrl
, Reference
< XInteractionHandler
>() );
417 if( aURLEntries
.UserList
.hasElements() )
419 m_xManageServices
->set_item_sensitive("change_password", true);
424 catch( const Exception
& )
429 m_xServices_lb
->set_sensitive(false);
433 m_xFilter_lb
->set_sensitive(true);
434 m_xName_ed
->set_sensitive(true);
435 m_xContainer
->set_sensitive(true);
436 m_xNewFolder
->set_sensitive(true);
438 if (!m_xName_ed
->get_text().isEmpty())
439 m_xOk_btn
->set_sensitive(true);
441 m_xOk_btn
->set_sensitive(false);
445 m_xFilter_lb
->set_sensitive(false);
446 m_xName_ed
->set_sensitive(false);
447 m_xContainer
->set_sensitive(false);
448 m_xNewFolder
->set_sensitive(false);
449 m_xOk_btn
->set_sensitive(false);
452 m_xPath
->EnableFields( true );
453 m_xManageServices
->set_sensitive(true);
456 void RemoteFilesDialog::DisableControls()
458 m_xServices_lb
->set_sensitive(false);
459 m_xFilter_lb
->set_sensitive(false);
460 m_xManageServices
->set_sensitive(false);
461 m_xName_ed
->set_sensitive(false);
462 m_xContainer
->set_sensitive(false);
463 m_xOk_btn
->set_sensitive(false);
464 m_xPath
->EnableFields( false );
466 m_xCancel_btn
->set_sensitive(true);
469 void RemoteFilesDialog::SavePassword(const OUString
& rURL
, const OUString
& rUser
,
470 const OUString
& rPassword
, bool bPersistent
)
472 if( rURL
.isEmpty() || rUser
.isEmpty() || rPassword
.isEmpty() )
478 ( m_xMasterPasswd
->isPersistentStoringAllowed()
479 && m_xMasterPasswd
->authorizateWithMasterPassword( Reference
< XInteractionHandler
>() ) )
482 Reference
< XInteractionHandler
> xInteractionHandler
=
483 InteractionHandler::createWithParent( m_xContext
, nullptr );
485 Sequence
<OUString
> aPasswd
{ rPassword
};
488 m_xMasterPasswd
->addPersistent(
489 rURL
, rUser
, aPasswd
, xInteractionHandler
);
491 m_xMasterPasswd
->add( rURL
, rUser
, aPasswd
, xInteractionHandler
);
494 catch( const Exception
& )
498 IMPL_LINK_NOARG ( RemoteFilesDialog
, IconViewHdl
, weld::Button
&, void )
500 m_xListView_btn
->set_active(false);
501 m_xFileView
->SetViewMode( eIcon
);
504 IMPL_LINK_NOARG ( RemoteFilesDialog
, ListViewHdl
, weld::Button
&, void )
506 m_xIconView_btn
->set_active(false);
507 m_xFileView
->SetViewMode( eDetailedList
);
510 void RemoteFilesDialog::AddService()
512 PlaceEditDialog
aDlg(m_xDialog
.get());
513 aDlg
.ShowPasswordControl();
514 short aRetCode
= aDlg
.run();
520 ServicePtr newService
= aDlg
.GetPlace();
521 m_aServices
.push_back( newService
);
523 OUString sPassword
= aDlg
.GetPassword();
524 OUString sUser
= aDlg
.GetUser();
525 if( !sUser
.isEmpty() && !sPassword
.isEmpty() )
527 bool bPersistent
= aDlg
.IsRememberChecked();
528 SavePassword( newService
->GetUrl(), sUser
, sPassword
, bPersistent
);
531 OUString sPrefix
= lcl_GetServiceType( newService
);
533 if(!sPrefix
.isEmpty())
536 m_xServices_lb
->append_text( sPrefix
+ newService
->GetName() );
537 m_xServices_lb
->set_active( m_xServices_lb
->get_count() - 1 );
538 EnableExtraMenuItems(true);
539 SelectServiceHdl( *m_xServices_lb
);
553 IMPL_LINK_NOARG( RemoteFilesDialog
, SelectServiceHdl
, weld::ComboBox
&, void )
555 int nPos
= GetSelectedServicePos();
559 OUString sURL
= m_aServices
[nPos
]->GetUrl();
560 EnableExtraMenuItems(true);
562 m_bServiceChanged
= true;
567 IMPL_LINK ( RemoteFilesDialog
, EditServiceMenuHdl
, const OUString
&, rIdent
, void )
569 OUString
sIdent(rIdent
);
570 if( sIdent
== "edit_service" && m_xServices_lb
->get_count() > 0 )
572 int nSelected
= m_xServices_lb
->get_active();
573 int nPos
= GetSelectedServicePos();
577 PlaceEditDialog
aDlg(m_xDialog
.get(), m_aServices
[nPos
]);
578 short aRetCode
= aDlg
.run();
584 ServicePtr pEditedService
= aDlg
.GetPlace();
586 m_aServices
[nPos
] = pEditedService
;
587 m_xServices_lb
->remove( nSelected
);
589 OUString sPrefix
= lcl_GetServiceType( pEditedService
);
591 if(!sPrefix
.isEmpty())
594 m_xServices_lb
->insert_text(nSelected
, sPrefix
+ pEditedService
->GetName());
595 m_xServices_lb
->set_active( nSelected
);
601 sIdent
= "delete_service";
610 if( sIdent
== "delete_service" && m_xServices_lb
->get_count() > 0 )
612 int nSelected
= m_xServices_lb
->get_active();
613 int nPos
= GetSelectedServicePos();
617 OUString sMsg
= FpsResId( STR_SVT_DELETESERVICE
);
618 sMsg
= sMsg
.replaceFirst( "$servicename$", m_xServices_lb
->get_active_text() );
619 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
620 VclMessageType::Question
, VclButtonsType::YesNo
, sMsg
));
621 if (xBox
->run() == RET_YES
)
626 if( m_xMasterPasswd
->isPersistentStoringAllowed() )
628 OUString
sUrl( m_aServices
[nPos
]->GetUrl() );
630 Reference
< XInteractionHandler
> xInteractionHandler
=
631 InteractionHandler::createWithParent( m_xContext
, nullptr );
633 UrlRecord aURLEntries
= m_xMasterPasswd
->find( sUrl
, xInteractionHandler
);
635 if( aURLEntries
.Url
== sUrl
&& aURLEntries
.UserList
.hasElements() )
637 OUString sUserName
= aURLEntries
.UserList
[0].UserName
;
639 m_xMasterPasswd
->removePersistent( sUrl
, sUserName
);
643 catch( const Exception
& )
646 m_aServices
.erase( m_aServices
.begin() + nPos
);
647 m_xServices_lb
->remove( nSelected
);
649 m_xServices_lb
->set_active(-1);
650 EnableExtraMenuItems(false);
654 m_bIsConnected
= false;
659 else if( sIdent
== "change_password" )
663 if( m_xMasterPasswd
->isPersistentStoringAllowed() && m_xMasterPasswd
->authorizateWithMasterPassword( Reference
< XInteractionHandler
>() ) )
665 int nPos
= GetSelectedServicePos();
669 OUString
sUrl( m_aServices
[nPos
]->GetUrl() );
671 Reference
< XInteractionHandler
> xInteractionHandler
=
672 InteractionHandler::createWithParent( m_xContext
, nullptr );
674 UrlRecord aURLEntries
= m_xMasterPasswd
->find( sUrl
, xInteractionHandler
);
676 if( aURLEntries
.Url
== sUrl
&& aURLEntries
.UserList
.hasElements() )
678 OUString sUserName
= aURLEntries
.UserList
[0].UserName
;
680 rtl::Reference
<::comphelper::SimplePasswordRequest
> pPasswordRequest
681 = new ::comphelper::SimplePasswordRequest
;
683 xInteractionHandler
->handle( pPasswordRequest
);
685 if ( pPasswordRequest
->isPassword() )
687 OUString aNewPass
= pPasswordRequest
->getPassword();
688 Sequence
<OUString
> aPasswd
{ aNewPass
};
690 m_xMasterPasswd
->addPersistent(
691 sUrl
, sUserName
, aPasswd
, xInteractionHandler
);
697 catch( const Exception
& )
700 else if( sIdent
== "add_service" )
706 IMPL_LINK_NOARG( RemoteFilesDialog
, DoubleClickHdl
, SvtFileView
*, bool )
708 SvtContentEntry
* pData
= m_xFileView
->FirstSelected();
711 if (!pData
->mbIsFolder
)
714 OpenURL(pData
->maURL
);
719 IMPL_LINK_NOARG( RemoteFilesDialog
, SelectHdl
, SvtFileView
*, void )
721 SvtContentEntry
* pData
= m_xFileView
->FirstSelected();
725 if( ( pData
->mbIsFolder
&& ( m_eType
== REMOTEDLG_TYPE_PATHDLG
) )
726 || ( !pData
->mbIsFolder
&& ( m_eType
== REMOTEDLG_TYPE_FILEDLG
) ) )
728 // url must contain user info, because we need this info in recent files entry
729 // (to fill user field in login box by default)
730 INetURLObject
aURL( pData
->maURL
);
731 INetURLObject
aCurrentURL( m_sLastServiceUrl
);
732 aURL
.SetUser( aCurrentURL
.GetUser() );
734 m_sPath
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
736 m_xName_ed
->set_text( aURL
.GetLastName(INetURLObject::DecodeMechanism::WithCharset
) );
740 if( m_eMode
== REMOTEDLG_MODE_OPEN
)
743 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 sUserSelectedPath
;
826 // check if file/path exists
827 OUString sCurrentPath
= m_xFileView
->GetViewURL();
828 OUString sSelectedItem
= m_xFileView
->GetCurrentURL();
829 OUString sUserTypedName
= m_xName_ed
->get_text();
832 if( m_eMode
== REMOTEDLG_MODE_SAVE
)
833 sFileName
= AddFileExtension(sUserTypedName
);
835 sFileName
= sUserTypedName
;
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(sFileName
, INetURLObject::PART_FPATH
, INetURLObject::EncodeMechanism::All
);
846 sUserSelectedPath
= sCurrentPath
+ INetURLObject::encode(sUserTypedName
, 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
);
862 sUserSelectedPath
= m_sPath
;
865 bool bExists
= false;
868 bExists
= ContentIsDocument( m_sPath
);
870 bExists
= ContentIsFolder( m_sPath
);
874 if( m_eMode
== REMOTEDLG_MODE_SAVE
)
876 OUString sMsg
= FpsResId( STR_SVT_ALREADYEXISTOVERWRITE
);
877 sMsg
= sMsg
.replaceFirst("$filename$", sFileName
);
878 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
879 VclMessageType::Question
, VclButtonsType::YesNo
, sMsg
));
880 if (xBox
->run() != RET_YES
)
886 if (ContentIsFolder(sUserSelectedPath
))
888 OpenURL(sUserSelectedPath
);
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::SetDenyList( const css::uno::Sequence
< OUString
>& rDenyList
)
928 m_aDenyList
= rDenyList
;
929 m_xTreeView
->SetDenyList( rDenyList
);
932 const css::uno::Sequence
< OUString
>& RemoteFilesDialog::GetDenyList() 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
.subView( 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 ::ucbhelper::Content
content(rURL
,
1142 ::utl::UCBContentHelper::getDefaultCommandEnvironment(),
1144 return content
.isFolder();
1146 catch (css::uno::Exception
const&)
1152 bool RemoteFilesDialog::ContentIsDocument( const OUString
& rURL
)
1156 ::ucbhelper::Content
content(rURL
,
1157 ::utl::UCBContentHelper::getDefaultCommandEnvironment(),
1159 return content
.isDocument();
1161 catch (css::uno::Exception
const&)
1167 sal_Int32
RemoteFilesDialog::getAvailableWidth()
1169 // This dialog doesn't contain preview
1173 sal_Int32
RemoteFilesDialog::getAvailableHeight()
1175 // This dialog doesn't contain preview
1179 void RemoteFilesDialog::setImage( const css::uno::Any
& )
1181 // This dialog doesn't contain preview
1184 bool RemoteFilesDialog::getShowState()
1186 // This dialog doesn't contain preview
1190 weld::Widget
* RemoteFilesDialog::getControl( sal_Int16
, bool) const
1195 void RemoteFilesDialog::enableControl( sal_Int16
, bool )
1199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */