1196 lines
35 KiB
C++
1196 lines
35 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include <config_oauth2.h>
|
|
|
|
#include "fpsmartcontent.hxx"
|
|
#include "QueryFolderName.hxx"
|
|
#include "RemoteFilesDialog.hxx"
|
|
#include <fpicker/fpsofficeResMgr.hxx>
|
|
#include <fpicker/strings.hrc>
|
|
#include <strings.hrc>
|
|
#include <comphelper/docpasswordrequest.hxx>
|
|
#include <com/sun/star/task/InteractionHandler.hpp>
|
|
#include <com/sun/star/task/PasswordContainer.hpp>
|
|
#include <svtools/PlaceEditDialog.hxx>
|
|
#include <tools/debug.hxx>
|
|
#include <unotools/ucbhelper.hxx>
|
|
#include <vcl/errinf.hxx>
|
|
#include <officecfg/Office/Common.hxx>
|
|
|
|
using namespace ::svt;
|
|
|
|
RemoteFilesDialog::RemoteFilesDialog( weld::Window* pParent, PickerFlags nBits )
|
|
: SvtFileDialog_Base( pParent, u"fps/ui/remotefilesdialog.ui"_ustr, u"RemoteFilesDialog"_ustr )
|
|
, m_xContext( comphelper::getProcessComponentContext() )
|
|
, m_xMasterPasswd( PasswordContainer::create( m_xContext ) )
|
|
, m_bIsInExecute( false )
|
|
, m_xOk_btn(m_xBuilder->weld_button(u"ok"_ustr))
|
|
, m_xCancel_btn(m_xBuilder->weld_button(u"cancel"_ustr))
|
|
, m_xManageServices(m_xBuilder->weld_menu_button(u"add_service_btn"_ustr))
|
|
, m_xServices_lb(m_xBuilder->weld_combo_box(u"services_lb"_ustr))
|
|
, m_xPathContainer(m_xBuilder->weld_container(u"breadcrumb_container"_ustr))
|
|
, m_xNewFolder(m_xBuilder->weld_button(u"new_folder"_ustr))
|
|
, m_xListView_btn(m_xBuilder->weld_toggle_button(u"list_view"_ustr))
|
|
, m_xIconView_btn(m_xBuilder->weld_toggle_button(u"icon_view"_ustr))
|
|
, m_xFilter_lb(m_xBuilder->weld_combo_box(u"filter_lb"_ustr))
|
|
, m_xName_ed(new AutocompleteEdit(m_xBuilder->weld_entry(u"filename"_ustr)))
|
|
{
|
|
m_eMode = ( nBits & PickerFlags::SaveAs ) ? REMOTEDLG_MODE_SAVE : REMOTEDLG_MODE_OPEN;
|
|
m_eType = ( nBits & PickerFlags::PathDialog ) ? REMOTEDLG_TYPE_PATHDLG : REMOTEDLG_TYPE_FILEDLG;
|
|
bool bMultiselection = bool( nBits & PickerFlags::MultiSelection );
|
|
m_bIsUpdated = false;
|
|
m_bIsConnected = false;
|
|
m_bServiceChanged = false;
|
|
m_nCurrentFilter = -1;
|
|
|
|
m_xName_ed->show();
|
|
|
|
// limit width due to super wide strings that may end up here
|
|
m_xFilter_lb->set_size_request(m_xFilter_lb->get_approximate_digit_width() * 60, -1);
|
|
|
|
m_xFilter_lb->set_sensitive(false);
|
|
m_xName_ed->set_sensitive(false);
|
|
m_xNewFolder->set_sensitive(false);
|
|
|
|
if( m_eMode == REMOTEDLG_MODE_OPEN )
|
|
{
|
|
m_xNewFolder->hide();
|
|
}
|
|
else
|
|
{
|
|
m_xOk_btn->set_label(FpsResId(STR_EXPLORERFILE_BUTTONSAVE));
|
|
m_xNewFolder->connect_clicked( LINK( this, RemoteFilesDialog, NewFolderHdl ) );
|
|
}
|
|
|
|
m_xListView_btn->set_active(true);
|
|
m_xIconView_btn->connect_clicked( LINK( this, RemoteFilesDialog, IconViewHdl ) );
|
|
m_xListView_btn->connect_clicked( LINK( this, RemoteFilesDialog, ListViewHdl ) );
|
|
|
|
m_xOk_btn->set_sensitive(false);
|
|
|
|
m_xOk_btn->connect_clicked( LINK( this, RemoteFilesDialog, OkHdl ) );
|
|
m_xCancel_btn->connect_clicked( LINK( this, RemoteFilesDialog, CancelHdl ) );
|
|
|
|
m_sRootLabel = FpsResId( STR_SVT_ROOTLABEL );
|
|
m_xPath.reset(new Breadcrumb(m_xPathContainer.get()));
|
|
m_xPath->connect_clicked( LINK( this, RemoteFilesDialog, SelectBreadcrumbHdl ) );
|
|
m_xPath->SetMode( SvtBreadcrumbMode::ALL_VISITED );
|
|
|
|
m_xContainer = m_xBuilder->weld_container(u"container"_ustr);
|
|
m_xContainer->set_size_request(m_xContainer->get_approximate_digit_width() * 82, -1);
|
|
|
|
m_xFileView.reset(new SvtFileView(m_xDialog.get(),
|
|
m_xBuilder->weld_tree_view(u"fileview"_ustr),
|
|
m_xBuilder->weld_icon_view(u"iconview"_ustr),
|
|
REMOTEDLG_TYPE_PATHDLG == m_eType,
|
|
bMultiselection, false));
|
|
|
|
m_xFileView->SetDoubleClickHdl( LINK( this, RemoteFilesDialog, DoubleClickHdl ) );
|
|
m_xFileView->SetSelectHdl( LINK( this, RemoteFilesDialog, SelectHdl ) );
|
|
m_xFileView->EnableDelete( true );
|
|
|
|
m_xTreeView.reset(new FolderTree(m_xBuilder->weld_tree_view(u"foldertree"_ustr), m_xDialog.get()));
|
|
m_xTreeView->connect_changed(LINK(this, RemoteFilesDialog, TreeSelectHdl));
|
|
|
|
m_xContainer->set_sensitive(false);
|
|
|
|
m_sIniKey = "RemoteFilesDialog";
|
|
InitSize();
|
|
|
|
m_xName_ed->connect_focus_in(LINK(this, RemoteFilesDialog, FileNameGetFocusHdl));
|
|
m_xName_ed->connect_changed(LINK(this, RemoteFilesDialog, FileNameModifyHdl));
|
|
|
|
m_xManageServices->connect_selected(LINK(this, RemoteFilesDialog, EditServiceMenuHdl));
|
|
|
|
FillServicesListbox();
|
|
|
|
m_xServices_lb->connect_changed( LINK( this, RemoteFilesDialog, SelectServiceHdl ) );
|
|
|
|
m_xFilter_lb->connect_changed( LINK( this, RemoteFilesDialog, SelectFilterHdl ) );
|
|
}
|
|
|
|
RemoteFilesDialog::~RemoteFilesDialog()
|
|
{
|
|
m_xFileView->SetSelectHdl(Link<SvtFileView*,void>());
|
|
|
|
// save window state
|
|
if( !m_sIniKey.isEmpty() )
|
|
{
|
|
SvtViewOptions aDlgOpt( EViewType::Dialog, m_sIniKey );
|
|
aDlgOpt.SetWindowState(m_xDialog->get_window_state(vcl::WindowDataMask::All));
|
|
|
|
Size aSize(m_xDialog->get_size());
|
|
|
|
OUString sSize = OUString::number( aSize.Width() ) + "|";
|
|
sSize = sSize + OUString::number( aSize.Height() ) + "|";
|
|
|
|
OUString sUserData = m_xFileView->GetConfigString();
|
|
aDlgOpt.SetUserItem( u"UserData"_ustr,
|
|
Any( sSize + sUserData ) );
|
|
}
|
|
|
|
// save services
|
|
std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
|
|
|
|
officecfg::Office::Common::Misc::FilePickerLastService::set( m_sLastServiceUrl, batch );
|
|
|
|
if( m_bIsUpdated )
|
|
{
|
|
Sequence< OUString > placesUrlsList( m_aServices.size() );
|
|
auto placesUrlsListRange = asNonConstRange(placesUrlsList);
|
|
Sequence< OUString > placesNamesList( m_aServices.size() );
|
|
auto placesNamesListRange = asNonConstRange(placesNamesList);
|
|
|
|
int i = 0;
|
|
for (auto const& service : m_aServices)
|
|
{
|
|
placesUrlsListRange[i] = service->GetUrl();
|
|
placesNamesListRange[i] = service->GetName();
|
|
++i;
|
|
}
|
|
|
|
officecfg::Office::Common::Misc::FilePickerPlacesUrls::set( placesUrlsList, batch );
|
|
officecfg::Office::Common::Misc::FilePickerPlacesNames::set( placesNamesList, batch );
|
|
}
|
|
|
|
batch->commit();
|
|
}
|
|
|
|
void RemoteFilesDialog::EnableExtraMenuItems(bool bEnable)
|
|
{
|
|
m_xManageServices->set_item_visible(u"change_password"_ustr, bEnable);
|
|
m_xManageServices->set_item_visible(u"edit_service"_ustr, bEnable);
|
|
m_xManageServices->set_item_visible(u"delete_service"_ustr, bEnable);
|
|
m_xManageServices->set_item_visible(u"change_password"_ustr, bEnable);
|
|
}
|
|
|
|
short RemoteFilesDialog::run()
|
|
{
|
|
if (m_xServices_lb->get_count() > 0)
|
|
{
|
|
m_xDialog->show();
|
|
SelectServiceHdl(*m_xServices_lb);
|
|
}
|
|
if (!m_bIsConnected)
|
|
{
|
|
m_xServices_lb->set_active(-1);
|
|
EnableExtraMenuItems(false);
|
|
}
|
|
|
|
m_bIsInExecute = true;
|
|
short nRet = SvtFileDialog_Base::run();
|
|
m_bIsInExecute = false;
|
|
return nRet;
|
|
}
|
|
|
|
static OUString lcl_GetServiceType( const ServicePtr& pService )
|
|
{
|
|
INetProtocol aProtocol = pService->GetUrlObject().GetProtocol();
|
|
switch( aProtocol )
|
|
{
|
|
case INetProtocol::Cmis:
|
|
{
|
|
OUString sHost = pService->GetUrlObject().GetHost( INetURLObject::DecodeMechanism::WithCharset );
|
|
|
|
if( sHost.startsWith( GDRIVE_BASE_URL ) )
|
|
return u"Google Drive"_ustr;
|
|
else if( sHost.startsWith( ALFRESCO_CLOUD_BASE_URL ) )
|
|
return u"Alfresco Cloud"_ustr;
|
|
else if( sHost.startsWith( ONEDRIVE_BASE_URL ) )
|
|
return u"OneDrive"_ustr;
|
|
|
|
return u"CMIS"_ustr;
|
|
}
|
|
case INetProtocol::Smb:
|
|
return u"Windows Share"_ustr;
|
|
case INetProtocol::File:
|
|
return u"SSH"_ustr;
|
|
case INetProtocol::Http:
|
|
return u"WebDAV"_ustr;
|
|
case INetProtocol::Https:
|
|
return u"WebDAV"_ustr;
|
|
case INetProtocol::Generic:
|
|
return u"SSH"_ustr;
|
|
default:
|
|
return OUString();
|
|
}
|
|
}
|
|
|
|
void RemoteFilesDialog::InitSize()
|
|
{
|
|
if( m_sIniKey.isEmpty() )
|
|
return;
|
|
|
|
// initialize from config
|
|
SvtViewOptions aDlgOpt( EViewType::Dialog, m_sIniKey );
|
|
|
|
if( !aDlgOpt.Exists() )
|
|
return;
|
|
|
|
m_xDialog->set_window_state(aDlgOpt.GetWindowState());
|
|
|
|
Any aUserData = aDlgOpt.GetUserItem( u"UserData"_ustr );
|
|
OUString sCfgStr;
|
|
if( aUserData >>= sCfgStr )
|
|
{
|
|
sal_Int32 nPos1{ sCfgStr.indexOf('|') };
|
|
if (nPos1<0)
|
|
return;
|
|
sal_Int32 nPos2{ sCfgStr.indexOf('|', nPos1+1 ) };
|
|
if (nPos2<0)
|
|
return;
|
|
m_xFileView->SetConfigString( sCfgStr.subView(nPos2+1) );
|
|
}
|
|
}
|
|
|
|
void RemoteFilesDialog::FillServicesListbox()
|
|
{
|
|
m_xServices_lb->clear();
|
|
m_aServices.clear();
|
|
|
|
// Load from user settings
|
|
Sequence< OUString > placesUrlsList( officecfg::Office::Common::Misc::FilePickerPlacesUrls::get() );
|
|
Sequence< OUString > placesNamesList( officecfg::Office::Common::Misc::FilePickerPlacesNames::get() );
|
|
|
|
unsigned int nPos = 0;
|
|
unsigned int i = 0;
|
|
|
|
m_sLastServiceUrl = officecfg::Office::Common::Misc::FilePickerLastService::get();
|
|
|
|
for( sal_Int32 nPlace = 0; nPlace < placesUrlsList.getLength() && nPlace < placesNamesList.getLength(); ++nPlace )
|
|
{
|
|
ServicePtr pService = std::make_shared<Place>( placesNamesList[nPlace], placesUrlsList[nPlace], true );
|
|
m_aServices.push_back( pService );
|
|
|
|
// Add to the listbox only remote services, not local bookmarks
|
|
if( !pService->IsLocal() )
|
|
{
|
|
OUString sPrefix = lcl_GetServiceType( pService );
|
|
|
|
if( !sPrefix.isEmpty() )
|
|
sPrefix += ": ";
|
|
|
|
if( placesUrlsList[nPlace] == m_sLastServiceUrl )
|
|
nPos = i;
|
|
|
|
m_xServices_lb->append_text(sPrefix + placesNamesList[nPlace]);
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
if (m_xServices_lb->get_count() > 0)
|
|
{
|
|
m_xServices_lb->set_active(nPos);
|
|
EnableExtraMenuItems(true);
|
|
}
|
|
else
|
|
EnableExtraMenuItems(false);
|
|
|
|
EnableControls();
|
|
}
|
|
|
|
int RemoteFilesDialog::GetSelectedServicePos()
|
|
{
|
|
if( m_aServices.empty() )
|
|
return -1;
|
|
|
|
int nPos = 0;
|
|
int i = -1;
|
|
|
|
int nSelected = m_xServices_lb->get_active();
|
|
|
|
int nServices = static_cast<int>(m_aServices.size());
|
|
while( nPos < nServices )
|
|
{
|
|
while( (nPos < nServices) && m_aServices[nPos]->IsLocal() )
|
|
nPos++;
|
|
i++;
|
|
if( i == nSelected )
|
|
break;
|
|
nPos++;
|
|
}
|
|
|
|
return nPos;
|
|
}
|
|
|
|
void RemoteFilesDialog::AddFilter( const OUString& rFilter, const OUString& rType )
|
|
{
|
|
m_aFilters.emplace_back( rFilter, rType );
|
|
if (rType.isEmpty())
|
|
m_xFilter_lb->append_separator(u""_ustr);
|
|
else
|
|
m_xFilter_lb->append_text(rFilter);
|
|
|
|
if (m_xFilter_lb->get_active() == -1)
|
|
m_xFilter_lb->set_active(0);
|
|
}
|
|
|
|
void RemoteFilesDialog::OpenURL( OUString const & sURL )
|
|
{
|
|
if( !m_xFileView )
|
|
return;
|
|
|
|
DisableControls();
|
|
|
|
auto xWait = std::make_unique<weld::WaitObject>(m_xDialog.get());
|
|
|
|
if( !sURL.isEmpty() )
|
|
{
|
|
OUString sFilter = FILEDIALOG_FILTER_ALL;
|
|
|
|
if( m_nCurrentFilter != -1)
|
|
{
|
|
sFilter = m_aFilters[m_nCurrentFilter].second;
|
|
}
|
|
|
|
m_xFileView->EndInplaceEditing();
|
|
|
|
DBG_ASSERT( !m_pCurrentAsyncAction.is(), "SvtFileDialog::executeAsync: previous async action not yet finished!" );
|
|
|
|
m_pCurrentAsyncAction = new AsyncPickerAction( this, m_xFileView.get(), AsyncPickerAction::Action::eOpenURL );
|
|
|
|
// -1 timeout - sync
|
|
m_pCurrentAsyncAction->execute( sURL, sFilter, -1, -1, GetDenyList() );
|
|
|
|
if( m_eMode != REMOTEDLG_MODE_SAVE )
|
|
m_xName_ed->set_text( u""_ustr );
|
|
|
|
m_xFileView->grab_focus();
|
|
}
|
|
else
|
|
{
|
|
xWait.reset();
|
|
|
|
// content doesn't exist
|
|
ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTS );
|
|
|
|
EnableControls();
|
|
}
|
|
}
|
|
|
|
OUString RemoteFilesDialog::AddFileExtension(const OUString& rFileName)
|
|
{
|
|
if (m_nCurrentFilter == -1)
|
|
return rFileName;
|
|
|
|
OUString sExt = m_aFilters[m_nCurrentFilter].second;
|
|
sal_Int32 nDotPos = rFileName.lastIndexOf( '.' );
|
|
|
|
if (nDotPos == -1)
|
|
return rFileName + sExt.subView( 1 ); // without '*'
|
|
|
|
return rFileName;
|
|
}
|
|
|
|
void RemoteFilesDialog::EnableControls()
|
|
{
|
|
if (m_xServices_lb->get_count() > 0)
|
|
{
|
|
m_xServices_lb->set_sensitive(true);
|
|
|
|
if (m_xServices_lb->get_active() != -1)
|
|
{
|
|
m_xManageServices->set_item_sensitive(u"change_password"_ustr, false);
|
|
|
|
try
|
|
{
|
|
if( m_xMasterPasswd->isPersistentStoringAllowed() )
|
|
{
|
|
int nPos = GetSelectedServicePos();
|
|
|
|
if( nPos >= 0 )
|
|
{
|
|
OUString sUrl( m_aServices[nPos]->GetUrl() );
|
|
|
|
UrlRecord aURLEntries = m_xMasterPasswd->find( sUrl, Reference< XInteractionHandler>() );
|
|
|
|
if( aURLEntries.UserList.hasElements() )
|
|
{
|
|
m_xManageServices->set_item_sensitive(u"change_password"_ustr, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{}
|
|
}
|
|
}
|
|
else
|
|
m_xServices_lb->set_sensitive(false);
|
|
|
|
if( m_bIsConnected )
|
|
{
|
|
m_xFilter_lb->set_sensitive(true);
|
|
m_xName_ed->set_sensitive(true);
|
|
m_xContainer->set_sensitive(true);
|
|
m_xNewFolder->set_sensitive(true);
|
|
|
|
if (!m_xName_ed->get_text().isEmpty())
|
|
m_xOk_btn->set_sensitive(true);
|
|
else
|
|
m_xOk_btn->set_sensitive(false);
|
|
}
|
|
else
|
|
{
|
|
m_xFilter_lb->set_sensitive(false);
|
|
m_xName_ed->set_sensitive(false);
|
|
m_xContainer->set_sensitive(false);
|
|
m_xNewFolder->set_sensitive(false);
|
|
m_xOk_btn->set_sensitive(false);
|
|
}
|
|
|
|
m_xPath->EnableFields( true );
|
|
m_xManageServices->set_sensitive(true);
|
|
}
|
|
|
|
void RemoteFilesDialog::DisableControls()
|
|
{
|
|
m_xServices_lb->set_sensitive(false);
|
|
m_xFilter_lb->set_sensitive(false);
|
|
m_xManageServices->set_sensitive(false);
|
|
m_xName_ed->set_sensitive(false);
|
|
m_xContainer->set_sensitive(false);
|
|
m_xOk_btn->set_sensitive(false);
|
|
m_xPath->EnableFields( false );
|
|
|
|
m_xCancel_btn->set_sensitive(true);
|
|
}
|
|
|
|
void RemoteFilesDialog::SavePassword(const OUString& rURL, const OUString& rUser,
|
|
const OUString& rPassword, bool bPersistent)
|
|
{
|
|
if( rURL.isEmpty() || rUser.isEmpty() || rPassword.isEmpty() )
|
|
return;
|
|
|
|
try
|
|
{
|
|
if( !bPersistent ||
|
|
( m_xMasterPasswd->isPersistentStoringAllowed()
|
|
&& m_xMasterPasswd->authorizateWithMasterPassword( Reference< XInteractionHandler>() ) )
|
|
)
|
|
{
|
|
Reference< XInteractionHandler > xInteractionHandler =
|
|
InteractionHandler::createWithParent( m_xContext, nullptr );
|
|
|
|
Sequence<OUString> aPasswd { rPassword };
|
|
|
|
if( bPersistent )
|
|
m_xMasterPasswd->addPersistent(
|
|
rURL, rUser, aPasswd, xInteractionHandler );
|
|
else
|
|
m_xMasterPasswd->add( rURL, rUser, aPasswd, xInteractionHandler );
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{}
|
|
}
|
|
|
|
IMPL_LINK_NOARG ( RemoteFilesDialog, IconViewHdl, weld::Button&, void )
|
|
{
|
|
m_xListView_btn->set_active(false);
|
|
m_xFileView->SetViewMode( eIcon );
|
|
}
|
|
|
|
IMPL_LINK_NOARG ( RemoteFilesDialog, ListViewHdl, weld::Button&, void )
|
|
{
|
|
m_xIconView_btn->set_active(false);
|
|
m_xFileView->SetViewMode( eDetailedList );
|
|
}
|
|
|
|
void RemoteFilesDialog::AddService()
|
|
{
|
|
PlaceEditDialog aDlg(m_xDialog.get());
|
|
aDlg.ShowPasswordControl();
|
|
short aRetCode = aDlg.run();
|
|
|
|
switch( aRetCode )
|
|
{
|
|
case RET_OK :
|
|
{
|
|
ServicePtr newService = aDlg.GetPlace();
|
|
m_aServices.push_back( newService );
|
|
|
|
OUString sPassword = aDlg.GetPassword();
|
|
OUString sUser = aDlg.GetUser();
|
|
if( !sUser.isEmpty() && !sPassword.isEmpty() )
|
|
{
|
|
bool bPersistent = aDlg.IsRememberChecked();
|
|
SavePassword( newService->GetUrl(), sUser, sPassword, bPersistent );
|
|
}
|
|
|
|
OUString sPrefix = lcl_GetServiceType( newService );
|
|
|
|
if(!sPrefix.isEmpty())
|
|
sPrefix += ": ";
|
|
|
|
m_xServices_lb->append_text( sPrefix + newService->GetName() );
|
|
m_xServices_lb->set_active( m_xServices_lb->get_count() - 1 );
|
|
EnableExtraMenuItems(true);
|
|
SelectServiceHdl( *m_xServices_lb );
|
|
|
|
m_bIsUpdated = true;
|
|
|
|
EnableControls();
|
|
break;
|
|
}
|
|
case RET_CANCEL :
|
|
default :
|
|
// Do Nothing
|
|
break;
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG( RemoteFilesDialog, SelectServiceHdl, weld::ComboBox&, void )
|
|
{
|
|
int nPos = GetSelectedServicePos();
|
|
|
|
if( nPos >= 0 )
|
|
{
|
|
OUString sURL = m_aServices[nPos]->GetUrl();
|
|
EnableExtraMenuItems(true);
|
|
|
|
m_bServiceChanged = true;
|
|
OpenURL( sURL );
|
|
}
|
|
}
|
|
|
|
IMPL_LINK ( RemoteFilesDialog, EditServiceMenuHdl, const OUString&, rIdent, void )
|
|
{
|
|
OUString sIdent(rIdent);
|
|
if( sIdent == "edit_service" && m_xServices_lb->get_count() > 0 )
|
|
{
|
|
int nSelected = m_xServices_lb->get_active();
|
|
int nPos = GetSelectedServicePos();
|
|
|
|
if( nPos >= 0 )
|
|
{
|
|
PlaceEditDialog aDlg(m_xDialog.get(), m_aServices[nPos]);
|
|
short aRetCode = aDlg.run();
|
|
|
|
switch( aRetCode )
|
|
{
|
|
case RET_OK :
|
|
{
|
|
ServicePtr pEditedService = aDlg.GetPlace();
|
|
|
|
m_aServices[nPos] = pEditedService;
|
|
m_xServices_lb->remove( nSelected );
|
|
|
|
OUString sPrefix = lcl_GetServiceType( pEditedService );
|
|
|
|
if(!sPrefix.isEmpty())
|
|
sPrefix += ": ";
|
|
|
|
m_xServices_lb->insert_text(nSelected, sPrefix + pEditedService->GetName());
|
|
m_xServices_lb->set_active( nSelected );
|
|
|
|
m_bIsUpdated = true;
|
|
break;
|
|
}
|
|
case RET_NO:
|
|
sIdent = "delete_service";
|
|
break;
|
|
case RET_CANCEL :
|
|
default :
|
|
// Do Nothing
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if( sIdent == "delete_service" && m_xServices_lb->get_count() > 0 )
|
|
{
|
|
int nSelected = m_xServices_lb->get_active();
|
|
int nPos = GetSelectedServicePos();
|
|
|
|
if( nPos >= 0 )
|
|
{
|
|
OUString sMsg = FpsResId( STR_SVT_DELETESERVICE );
|
|
sMsg = sMsg.replaceFirst( "$servicename$", m_xServices_lb->get_active_text() );
|
|
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
|
|
VclMessageType::Question, VclButtonsType::YesNo, sMsg));
|
|
if (xBox->run() == RET_YES)
|
|
{
|
|
// remove password
|
|
try
|
|
{
|
|
if( m_xMasterPasswd->isPersistentStoringAllowed() )
|
|
{
|
|
OUString sUrl( m_aServices[nPos]->GetUrl() );
|
|
|
|
Reference< XInteractionHandler > xInteractionHandler =
|
|
InteractionHandler::createWithParent( m_xContext, nullptr );
|
|
|
|
UrlRecord aURLEntries = m_xMasterPasswd->find( sUrl, xInteractionHandler );
|
|
|
|
if( aURLEntries.Url == sUrl && aURLEntries.UserList.hasElements() )
|
|
{
|
|
OUString sUserName = aURLEntries.UserList[0].UserName;
|
|
|
|
m_xMasterPasswd->removePersistent( sUrl, sUserName );
|
|
}
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{}
|
|
|
|
m_aServices.erase( m_aServices.begin() + nPos );
|
|
m_xServices_lb->remove( nSelected );
|
|
|
|
m_xServices_lb->set_active(-1);
|
|
EnableExtraMenuItems(false);
|
|
|
|
m_bIsUpdated = true;
|
|
|
|
m_bIsConnected = false;
|
|
EnableControls();
|
|
}
|
|
}
|
|
}
|
|
else if( sIdent == "change_password" )
|
|
{
|
|
try
|
|
{
|
|
if( m_xMasterPasswd->isPersistentStoringAllowed() && m_xMasterPasswd->authorizateWithMasterPassword( Reference< XInteractionHandler>() ) )
|
|
{
|
|
int nPos = GetSelectedServicePos();
|
|
|
|
if( nPos >= 0 )
|
|
{
|
|
OUString sUrl( m_aServices[nPos]->GetUrl() );
|
|
|
|
Reference< XInteractionHandler > xInteractionHandler =
|
|
InteractionHandler::createWithParent( m_xContext, nullptr );
|
|
|
|
UrlRecord aURLEntries = m_xMasterPasswd->find( sUrl, xInteractionHandler );
|
|
|
|
if( aURLEntries.Url == sUrl && aURLEntries.UserList.hasElements() )
|
|
{
|
|
OUString sUserName = aURLEntries.UserList[0].UserName;
|
|
|
|
rtl::Reference<::comphelper::SimplePasswordRequest> pPasswordRequest
|
|
= new ::comphelper::SimplePasswordRequest;
|
|
|
|
xInteractionHandler->handle( pPasswordRequest );
|
|
|
|
if ( pPasswordRequest->isPassword() )
|
|
{
|
|
Sequence<OUString> aPasswd { pPasswordRequest->getPassword() };
|
|
|
|
m_xMasterPasswd->addPersistent(
|
|
sUrl, sUserName, aPasswd, xInteractionHandler );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{}
|
|
}
|
|
else if( sIdent == "add_service" )
|
|
AddService();
|
|
|
|
EnableControls();
|
|
}
|
|
|
|
IMPL_LINK_NOARG( RemoteFilesDialog, DoubleClickHdl, SvtFileView*, bool )
|
|
{
|
|
SvtContentEntry* pData = m_xFileView->FirstSelected();
|
|
if (pData)
|
|
{
|
|
if (!pData->mbIsFolder)
|
|
OkHdl(*m_xOk_btn);
|
|
else
|
|
OpenURL(pData->maURL);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
IMPL_LINK_NOARG( RemoteFilesDialog, SelectHdl, SvtFileView*, void )
|
|
{
|
|
SvtContentEntry* pData = m_xFileView->FirstSelected();
|
|
if (!pData)
|
|
return;
|
|
|
|
if( ( pData->mbIsFolder && ( m_eType == REMOTEDLG_TYPE_PATHDLG ) )
|
|
|| ( !pData->mbIsFolder && ( m_eType == REMOTEDLG_TYPE_FILEDLG ) ) )
|
|
{
|
|
// url must contain user info, because we need this info in recent files entry
|
|
// (to fill user field in login box by default)
|
|
INetURLObject aURL( pData->maURL );
|
|
INetURLObject aCurrentURL( m_sLastServiceUrl );
|
|
aURL.SetUser( aCurrentURL.GetUser() );
|
|
|
|
m_sPath = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
|
|
|
|
m_xName_ed->set_text( aURL.GetLastName(INetURLObject::DecodeMechanism::WithCharset) );
|
|
}
|
|
else
|
|
{
|
|
if( m_eMode == REMOTEDLG_MODE_OPEN )
|
|
{
|
|
m_sPath.clear();
|
|
m_xName_ed->set_text( u""_ustr );
|
|
}
|
|
}
|
|
|
|
EnableControls();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(RemoteFilesDialog, FileNameGetFocusHdl, weld::Widget&, void)
|
|
{
|
|
m_xFileView->SetNoSelection();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(RemoteFilesDialog, FileNameModifyHdl, weld::Entry&, void)
|
|
{
|
|
m_xFileView->SetNoSelection();
|
|
if (!m_xOk_btn->get_sensitive())
|
|
EnableControls();
|
|
}
|
|
|
|
IMPL_LINK_NOARG( RemoteFilesDialog, SelectFilterHdl, weld::ComboBox&, void )
|
|
{
|
|
int nPos = m_xFilter_lb->get_active();
|
|
|
|
if( nPos != -1 && !m_aFilters[nPos].second.isEmpty() )
|
|
{
|
|
m_nCurrentFilter = nPos;
|
|
|
|
OUString sCurrentURL = m_xFileView->GetViewURL();
|
|
|
|
if( !sCurrentURL.isEmpty() && m_bIsConnected )
|
|
OpenURL( sCurrentURL );
|
|
}
|
|
}
|
|
|
|
IMPL_LINK(RemoteFilesDialog, TreeSelectHdl, weld::TreeView&, rBox, void)
|
|
{
|
|
OpenURL(rBox.get_selected_id());
|
|
m_xFileView->grab_focus();
|
|
}
|
|
|
|
IMPL_LINK(RemoteFilesDialog, SelectBreadcrumbHdl, Breadcrumb*, pPtr, bool)
|
|
{
|
|
OpenURL( pPtr->GetHdlURL() );
|
|
return true;
|
|
}
|
|
|
|
IMPL_LINK_NOARG ( RemoteFilesDialog, NewFolderHdl, weld::Button&, void )
|
|
{
|
|
m_xFileView->EndInplaceEditing();
|
|
|
|
// will be bound after InteractionHandler is enabled
|
|
SmartContent aContent;
|
|
aContent.enableDefaultInteractionHandler();
|
|
// now it can be bound
|
|
aContent.bindTo( m_xFileView->GetViewURL() );
|
|
if( !aContent.canCreateFolder() )
|
|
return;
|
|
|
|
OUString aTitle;
|
|
aContent.getTitle( aTitle );
|
|
QueryFolderNameDialog aDlg(m_xDialog.get(), aTitle, FpsResId(STR_SVT_NEW_FOLDER));
|
|
bool bHandled = false;
|
|
|
|
while( !bHandled )
|
|
{
|
|
if (aDlg.run() == RET_OK)
|
|
{
|
|
OUString aUrl = aContent.createFolder(aDlg.GetName());
|
|
if( !aUrl.isEmpty() )
|
|
{
|
|
m_xFileView->CreatedFolder(aUrl, aDlg.GetName());
|
|
bHandled = true;
|
|
}
|
|
}
|
|
else
|
|
bHandled = true;
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG ( RemoteFilesDialog, OkHdl, weld::Button&, void )
|
|
{
|
|
OUString sUserSelectedPath;
|
|
|
|
// check if file/path exists
|
|
OUString sCurrentPath = m_xFileView->GetViewURL();
|
|
OUString sSelectedItem = m_xFileView->GetCurrentURL();
|
|
OUString sUserTypedName = m_xName_ed->get_text();
|
|
OUString sFileName;
|
|
// auto extension
|
|
if( m_eMode == REMOTEDLG_MODE_SAVE )
|
|
sFileName = AddFileExtension(sUserTypedName);
|
|
else
|
|
sFileName = sUserTypedName;
|
|
|
|
bool bFileDlg = ( m_eType == REMOTEDLG_TYPE_FILEDLG );
|
|
bool bSelected = ( m_xFileView->GetSelectionCount() > 0 );
|
|
|
|
if( !sCurrentPath.endsWith("/") )
|
|
sCurrentPath += "/";
|
|
|
|
if( !bSelected )
|
|
{
|
|
m_sPath = sCurrentPath + INetURLObject::encode(sFileName, INetURLObject::PART_FPATH, INetURLObject::EncodeMechanism::All);
|
|
sUserSelectedPath = sCurrentPath + INetURLObject::encode(sUserTypedName, INetURLObject::PART_FPATH, INetURLObject::EncodeMechanism::All);
|
|
}
|
|
else
|
|
{
|
|
if( m_eType == REMOTEDLG_TYPE_PATHDLG )
|
|
m_sPath = sCurrentPath;
|
|
else
|
|
m_sPath = sSelectedItem;
|
|
|
|
// url must contain user info, because we need this info in recent files entry
|
|
// (to fill user field in login box by default)
|
|
INetURLObject aURL( m_sPath );
|
|
INetURLObject aCurrentURL( m_sLastServiceUrl );
|
|
aURL.SetUser( aCurrentURL.GetUser() );
|
|
|
|
m_sPath = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
|
|
sUserSelectedPath = m_sPath;
|
|
}
|
|
|
|
bool bExists = false;
|
|
|
|
if( bFileDlg )
|
|
bExists = ContentIsDocument( m_sPath );
|
|
else
|
|
bExists = ContentIsFolder( m_sPath );
|
|
|
|
if( bExists )
|
|
{
|
|
if( m_eMode == REMOTEDLG_MODE_SAVE )
|
|
{
|
|
OUString sMsg = FpsResId( STR_SVT_ALREADYEXISTOVERWRITE );
|
|
sMsg = sMsg.replaceFirst("$filename$", sFileName);
|
|
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
|
|
VclMessageType::Question, VclButtonsType::YesNo, sMsg));
|
|
if (xBox->run() != RET_YES)
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ContentIsFolder(sUserSelectedPath))
|
|
{
|
|
OpenURL(sUserSelectedPath);
|
|
|
|
if (!bSelected)
|
|
m_xName_ed->grab_focus();
|
|
|
|
return;
|
|
}
|
|
|
|
if( m_eMode == REMOTEDLG_MODE_OPEN )
|
|
return;
|
|
}
|
|
|
|
m_xDialog->response(RET_OK);
|
|
}
|
|
|
|
IMPL_LINK_NOARG ( RemoteFilesDialog, CancelHdl, weld::Button&, void )
|
|
{
|
|
if( m_pCurrentAsyncAction.is() )
|
|
{
|
|
m_pCurrentAsyncAction->cancel();
|
|
onAsyncOperationFinished();
|
|
}
|
|
else
|
|
{
|
|
m_xDialog->response(RET_CANCEL);
|
|
}
|
|
}
|
|
|
|
// SvtFileDialog_Base
|
|
SvtFileView* RemoteFilesDialog::GetView()
|
|
{
|
|
return m_xFileView.get();
|
|
}
|
|
|
|
void RemoteFilesDialog::SetHasFilename( bool )
|
|
{
|
|
}
|
|
|
|
void RemoteFilesDialog::SetDenyList( const css::uno::Sequence< OUString >& rDenyList )
|
|
{
|
|
m_aDenyList = rDenyList;
|
|
m_xTreeView->SetDenyList( rDenyList );
|
|
}
|
|
|
|
const css::uno::Sequence< OUString >& RemoteFilesDialog::GetDenyList() const
|
|
{
|
|
return m_aDenyList;
|
|
}
|
|
|
|
void RemoteFilesDialog::SetStandardDir( const OUString& rStdDir )
|
|
{
|
|
m_sStdDir = rStdDir;
|
|
}
|
|
|
|
const OUString& RemoteFilesDialog::GetStandardDir() const
|
|
{
|
|
return m_sStdDir;
|
|
}
|
|
|
|
void RemoteFilesDialog::SetPath( const OUString& rNewURL )
|
|
{
|
|
m_sPath = rNewURL;
|
|
|
|
if( m_eMode == REMOTEDLG_MODE_SAVE )
|
|
{
|
|
INetURLObject aUrl( m_sPath );
|
|
OUString sFileName = aUrl.GetLastName( INetURLObject::DecodeMechanism::WithCharset );
|
|
|
|
m_xName_ed->set_text( sFileName );
|
|
}
|
|
}
|
|
|
|
OUString RemoteFilesDialog::getCurrentFileText() const
|
|
{
|
|
OUString sReturn;
|
|
if( m_xName_ed )
|
|
sReturn = m_xName_ed->get_text();
|
|
return sReturn;
|
|
}
|
|
|
|
void RemoteFilesDialog::setCurrentFileText( const OUString& rText, bool bSelectAll )
|
|
{
|
|
if (m_xName_ed)
|
|
{
|
|
m_xName_ed->set_text(rText);
|
|
if( bSelectAll )
|
|
m_xName_ed->select_region(0, -1);
|
|
}
|
|
}
|
|
|
|
void RemoteFilesDialog::AddFilterGroup(
|
|
const OUString& rFilter,
|
|
const css::uno::Sequence< css::beans::StringPair >& rFilters )
|
|
{
|
|
AddFilter( rFilter, OUString() );
|
|
const StringPair* pSubFilters = rFilters.getConstArray();
|
|
const StringPair* pSubFiltersEnd = pSubFilters + rFilters.getLength();
|
|
for ( ; pSubFilters != pSubFiltersEnd; ++pSubFilters )
|
|
AddFilter( pSubFilters->First, pSubFilters->Second );
|
|
}
|
|
|
|
OUString RemoteFilesDialog::GetCurFilter() const
|
|
{
|
|
OUString sFilter;
|
|
|
|
if (m_nCurrentFilter != -1)
|
|
{
|
|
sFilter = m_aFilters[m_nCurrentFilter].first;
|
|
}
|
|
|
|
return sFilter;
|
|
}
|
|
|
|
OUString RemoteFilesDialog::getCurFilter( ) const
|
|
{
|
|
return GetCurFilter();
|
|
}
|
|
|
|
void RemoteFilesDialog::SetCurFilter( const OUString& rFilter )
|
|
{
|
|
DBG_ASSERT( !m_bIsInExecute, "SvtFileDialog::SetCurFilter: currently executing!" );
|
|
|
|
// look for corresponding filter
|
|
sal_uInt16 nPos = m_aFilters.size();
|
|
|
|
while ( nPos-- )
|
|
{
|
|
if ( m_aFilters[nPos].first == rFilter )
|
|
{
|
|
m_nCurrentFilter = nPos;
|
|
m_xFilter_lb->set_active( m_nCurrentFilter );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RemoteFilesDialog::FilterSelect()
|
|
{
|
|
}
|
|
|
|
void RemoteFilesDialog::SetFileCallback( ::svt::IFilePickerListener * )
|
|
{
|
|
}
|
|
|
|
void RemoteFilesDialog::onAsyncOperationStarted()
|
|
{
|
|
DisableControls();
|
|
}
|
|
|
|
void RemoteFilesDialog::onAsyncOperationFinished()
|
|
{
|
|
m_pCurrentAsyncAction = nullptr;
|
|
EnableControls();
|
|
}
|
|
|
|
void RemoteFilesDialog::UpdateControls( const OUString& rURL )
|
|
{
|
|
int nPos = GetSelectedServicePos();
|
|
|
|
if( nPos >= 0 && m_bServiceChanged && rURL == m_aServices[nPos]->GetUrl() )
|
|
{
|
|
OUString sURL = m_aServices[nPos]->GetUrl();
|
|
|
|
m_xPath->SetRootName( m_sRootLabel );
|
|
m_xTreeView->clear();
|
|
|
|
m_xTreeView->InsertRootEntry(rURL, m_sRootLabel);
|
|
|
|
m_xName_ed->grab_focus();
|
|
|
|
m_sLastServiceUrl = sURL;
|
|
|
|
m_bServiceChanged = false;
|
|
}
|
|
|
|
m_xPath->SetURL( rURL );
|
|
|
|
m_xTreeView->connect_changed(Link<weld::TreeView&,void>());
|
|
|
|
// read cached data for this url and fill the tree
|
|
const ::std::vector< SvtContentEntry > aContentFolders = m_xFileView->GetContent();
|
|
::std::vector< std::pair< OUString, OUString > > aFolders;
|
|
|
|
m_xName_ed->ClearEntries();
|
|
|
|
for(const auto & rFolder : aContentFolders)
|
|
{
|
|
//WebDAV folders path ends in '/', so strip it
|
|
OUString aFolderName = rFolder.maURL;
|
|
if( rFolder.mbIsFolder && ( ( aFolderName.lastIndexOf( '/' ) + 1 ) == aFolderName.getLength() ) )
|
|
aFolderName = aFolderName.copy( 0, aFolderName.getLength() - 1 );
|
|
|
|
int nTitleStart = aFolderName.lastIndexOf( '/' );
|
|
if( nTitleStart != -1 )
|
|
{
|
|
OUString sTitle( INetURLObject::decode(
|
|
aFolderName.subView( nTitleStart + 1 ),
|
|
INetURLObject::DecodeMechanism::WithCharset ) );
|
|
|
|
if( rFolder.mbIsFolder )
|
|
{
|
|
aFolders.emplace_back( sTitle, aFolderName );
|
|
}
|
|
|
|
// add entries to the autocompletion mechanism
|
|
m_xName_ed->AddEntry( sTitle );
|
|
}
|
|
}
|
|
|
|
m_xTreeView->FillTreeEntry( rURL, aFolders );
|
|
|
|
m_xTreeView->connect_changed( LINK( this, RemoteFilesDialog, TreeSelectHdl ) );
|
|
|
|
m_bIsConnected = true;
|
|
EnableControls();
|
|
}
|
|
|
|
void RemoteFilesDialog::EnableAutocompletion( bool )
|
|
{
|
|
// This dialog contains Breadcrumb, not Edit
|
|
}
|
|
|
|
const OUString& RemoteFilesDialog::GetPath()
|
|
{
|
|
return m_sPath;
|
|
}
|
|
|
|
std::vector<OUString> RemoteFilesDialog::GetPathList() const
|
|
{
|
|
std::vector<OUString> aList;
|
|
|
|
m_xFileView->selected_foreach([this, &aList](weld::TreeIter& rCurEntry){
|
|
// url must contain user info, because we need this info in recent files entry
|
|
// (to fill user field in login box by default)
|
|
INetURLObject aURL(m_xFileView->GetURL(rCurEntry));
|
|
INetURLObject aCurrentURL( m_sLastServiceUrl );
|
|
aURL.SetUser( aCurrentURL.GetUser() );
|
|
|
|
aList.push_back( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
|
|
|
|
return false;
|
|
});
|
|
|
|
if( aList.empty() && !m_sPath.isEmpty() )
|
|
aList.push_back( m_sPath );
|
|
|
|
return aList;
|
|
}
|
|
|
|
bool RemoteFilesDialog::ContentIsFolder( const OUString& rURL )
|
|
{
|
|
try
|
|
{
|
|
::ucbhelper::Content content(rURL,
|
|
::utl::UCBContentHelper::getDefaultCommandEnvironment(),
|
|
m_xContext);
|
|
return content.isFolder();
|
|
}
|
|
catch (css::uno::Exception const&)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool RemoteFilesDialog::ContentIsDocument( const OUString& rURL )
|
|
{
|
|
try
|
|
{
|
|
::ucbhelper::Content content(rURL,
|
|
::utl::UCBContentHelper::getDefaultCommandEnvironment(),
|
|
m_xContext);
|
|
return content.isDocument();
|
|
}
|
|
catch (css::uno::Exception const&)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
sal_Int32 RemoteFilesDialog::getAvailableWidth()
|
|
{
|
|
// This dialog doesn't contain preview
|
|
return 0;
|
|
}
|
|
|
|
sal_Int32 RemoteFilesDialog::getAvailableHeight()
|
|
{
|
|
// This dialog doesn't contain preview
|
|
return 0;
|
|
}
|
|
|
|
void RemoteFilesDialog::setImage( const css::uno::Any& )
|
|
{
|
|
// This dialog doesn't contain preview
|
|
}
|
|
|
|
bool RemoteFilesDialog::getShowState()
|
|
{
|
|
// This dialog doesn't contain preview
|
|
return false;
|
|
}
|
|
|
|
weld::Widget* RemoteFilesDialog::getControl( sal_Int16, bool) const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
void RemoteFilesDialog::enableControl( sal_Int16, bool )
|
|
{
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|