Files
loongoffice/fpicker/source/office/RemoteFilesDialog.cxx
Jan-Marek Glogowski ea5a0918c8 VCL add vcl::WindowPosSize abstract class
... and use it to remove a duplicate and simplify code.

Should mostly be a refactoring, which was mainly done by some
larger sed calls, except for the new API calls, which helped
shrinking some LOC. All data is also now private.

Originally two of the "replaced" "classes" had unsigned width
and height and one had signed. Noel pointed out, that during
calculations, the value might get negative temporarly, so this
now settles with signed values. Still the set size should never
be negative and this is enforced this way. Not sure that is what
Noel had in mind.

This also includes:
- rename WindowState => WindowData
- rename WindowStateMask => WindowDataMask
- rename WindowStateState => WindowState
- move WindowState and WindowDataMask to vcl/windowstate.hxx
- move WindowData(Mask) and WindowState into vcl namespace
- readability: replace or'ed WindowState enums with "meta" enums
  + add "meta" WindowState enums PosSize and PosSizeState

Change-Id: Icd16cfb498531aa7238ddbde83fcb0ed6d9e4f77
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135426
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2022-06-08 18:17:17 +02:00

1202 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, "fps/ui/remotefilesdialog.ui", "RemoteFilesDialog" )
, m_xContext( comphelper::getProcessComponentContext() )
, m_xMasterPasswd( PasswordContainer::create( m_xContext ) )
, m_bIsInExecute( false )
, m_xOk_btn(m_xBuilder->weld_button("ok"))
, m_xCancel_btn(m_xBuilder->weld_button("cancel"))
, m_xManageServices(m_xBuilder->weld_menu_button("add_service_btn"))
, m_xServices_lb(m_xBuilder->weld_combo_box("services_lb"))
, m_xPathContainer(m_xBuilder->weld_container("breadcrumb_container"))
, m_xNewFolder(m_xBuilder->weld_button("new_folder"))
, m_xListView_btn(m_xBuilder->weld_toggle_button("list_view"))
, m_xIconView_btn(m_xBuilder->weld_toggle_button("icon_view"))
, m_xFilter_lb(m_xBuilder->weld_combo_box("filter_lb"))
, m_xName_ed(new AutocompleteEdit(m_xBuilder->weld_entry("filename")))
{
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("container");
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("fileview"),
m_xBuilder->weld_icon_view("iconview"),
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("foldertree"), 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(OStringToOUString(m_xDialog->get_window_state(vcl::WindowDataMask::All), RTL_TEXTENCODING_UTF8));
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( "UserData",
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("change_password", bEnable);
m_xManageServices->set_item_visible("edit_service", bEnable);
m_xManageServices->set_item_visible("delete_service", bEnable);
m_xManageServices->set_item_visible("change_password", 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::Ftp:
return "FTP";
case INetProtocol::Cmis:
{
OUString sHost = pService->GetUrlObject().GetHost( INetURLObject::DecodeMechanism::WithCharset );
if( sHost.startsWith( GDRIVE_BASE_URL ) )
return "Google Drive";
else if( sHost.startsWith( ALFRESCO_CLOUD_BASE_URL ) )
return "Alfresco Cloud";
else if( sHost.startsWith( ONEDRIVE_BASE_URL ) )
return "OneDrive";
return "CMIS";
}
case INetProtocol::Smb:
return "Windows Share";
case INetProtocol::File:
return "SSH";
case INetProtocol::Http:
return "WebDAV";
case INetProtocol::Https:
return "WebDAV";
case INetProtocol::Generic:
return "SSH";
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(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_UTF8));
Any aUserData = aDlgOpt.GetUserItem( "UserData" );
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 )
{
OUString sName = rFilter;
m_aFilters.emplace_back( rFilter, rType );
if (rType.isEmpty())
m_xFilter_lb->append_separator("");
else
m_xFilter_lb->append_text(sName);
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( "" );
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("change_password", 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("change_password", 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 OString&, rIdent, void )
{
OString 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() )
{
OUString aNewPass = pPasswordRequest->getPassword();
Sequence<OUString> aPasswd { aNewPass };
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( "" );
}
}
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 >& rFolders = m_xFileView->GetContent();
::std::vector< std::pair< OUString, OUString > > aFolders;
m_xName_ed->ClearEntries();
for(const auto & rFolder : rFolders)
{
//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: */