sw: improve error reporting of networked AutoText

Every error about an AutoText path is reported as "Inadmissible path",
which might imply that the path doesn't exist.

In the situation where the AutoText is on a WebDAV share that is mounted
by Windows Explorer, the path will be a file:// URL, and it is possible
that the user needs to authenticate before being able to access the
files, but it's not known how an authentication dialog could be shown in
LO (the Windows File Picker dialog is able to do this btw), so detect
this situation and show a more specific error message. (As far as
possible; we cannot tell if the problem is that the user is not
authenticated or if it is that the user is not authorised to access).

Use `PathIsNetworkPathW` to check if it is a mounted network location.

In case the network location is not reachable, the error code will be
different and the generic error dialog will be shown.

sw: fix -Werror=undef
(cherry picked from commit cee293d3ee4fef108790eed63c69eee40d37c0bf)

Change-Id: I633ea331f957edb4a943426464524a5decf0fe15
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200856
Tested-by: allotropia jenkins <jenkins@allotropia.de>
Reviewed-by: Thorsten Behrens <thorsten.behrens@collabora.com>
(cherry picked from commit 7a2efe02293382374cd80f9d23215740e731c755)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201398
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Stephan Bergmann <stephan.bergmann@collabora.com>
(cherry picked from commit 19e9e767145a5147bfee59f0b476c6a7dbf3ba12)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201468
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@collabora.com>
This commit is contained in:
Michael Stahl
2026-03-12 08:38:00 +01:00
parent 4e0c800134
commit fdd69f4dc8
5 changed files with 84 additions and 12 deletions
+4
View File
@@ -81,6 +81,10 @@ $(eval $(call gb_CppunitTest_use_externals,sw_uwriter,\
md4c \
))
$(eval $(call gb_CppunitTest_use_system_win32_libs,sw_uwriter,\
shlwapi \
))
$(eval $(call gb_CppunitTest_set_include,sw_uwriter,\
-I$(SRCDIR)/sw/source/core/inc \
-I$(SRCDIR)/sw/inc \
+4
View File
@@ -50,6 +50,10 @@ $(eval $(call gb_Library_add_defs,sw,\
-DSWUI_DLL_NAME=\"$(call gb_Library_get_runtime_filename,$(call gb_Library__get_name,swui))\" \
))
$(eval $(call gb_Library_use_system_win32_libs,sw,\
shlwapi \
))
$(eval $(call gb_Library_use_libraries,sw,\
avmedia \
basegfx \
+1
View File
@@ -889,6 +889,7 @@
#define STR_NO_TABLE NC_("STR_NO_TABLE", "A table with no rows or no cells cannot be inserted")
#define STR_TABLE_TOO_LARGE NC_("STR_TABLE_TOO_LARGE", "The table cannot be inserted because it is too large")
#define STR_ERR_INSERT_GLOS NC_("STR_ERR_INSERT_GLOS", "AutoText could not be created.")
#define STR_ERR_GLOS_NET_PATH_ACCESS NC_("STR_ERR_GLOS_NET_PATH_ACCESS", "Access to network paths denied. Please check with Windows Explorer if authentication is required to access.")
#define STR_CLPBRD_FORMAT_ERROR NC_("STR_CLPBRD_FORMAT_ERROR", "Requested clipboard format is not available.")
#define STR_PRIVATETEXT NC_("STR_PRIVATETEXT", "%PRODUCTNAME %PRODUCTVERSION Text Document")
#define STR_PRIVATEGRAPHIC NC_("STR_PRIVATEGRAPHIC", "Image (%PRODUCTNAME %PRODUCTVERSION Text Document)")
+4 -1
View File
@@ -33,6 +33,9 @@ typedef rtl::Reference<SwDocShell> SwDocShellRef;
#endif
#include <cppuhelper/weakref.hxx>
#include <com/sun/star/ucb/IOErrorCode.hpp>
#include <optional>
#include <vector>
#include <swdllapi.h>
@@ -50,7 +53,7 @@ class SW_DLLPUBLIC SwGlossaries
UnoAutoTextEntries m_aGlossaryEntries;
OUString m_aPath;
std::vector<OUString> m_aInvalidPaths;
std::vector<std::pair<OUString, std::optional<css::ucb::IOErrorCode>>> m_aInvalidPaths;
std::vector<OUString> m_PathArr;
std::vector<OUString> m_GlosArr;
bool m_bError;
+71 -11
View File
@@ -21,15 +21,22 @@
#include <string_view>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#include <comphelper/diagnose_ex.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/servicehelper.hxx>
#include <unotools/transliterationwrapper.hxx>
#include <vcl/errinf.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld/MessageDialog.hxx>
#include <osl/diagnose.h>
#include <rtl/character.hxx>
#include <svl/urihelper.hxx>
#include <svl/fstathelper.hxx>
#include <ucbhelper/content.hxx>
#include <unotools/pathoptions.hxx>
#include <unotools/tempfile.hxx>
#include <o3tl/string_view.hxx>
@@ -40,9 +47,15 @@
#include <unoatxt.hxx>
#include <swerror.h>
#include <strings.hrc>
#include <memory>
#ifdef _WIN32
#include <o3tl/char16_t2wchar_t.hxx>
#include <shlwapi.h>
#endif
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
@@ -358,7 +371,7 @@ void SwGlossaries::UpdateGlosPath(bool bFull)
m_PathArr.clear();
std::vector<OUString> aDirArr;
std::vector<OUString> aInvalidPaths;
decltype(m_aInvalidPaths) aInvalidPaths;
if (!m_aPath.isEmpty())
{
sal_Int32 nIndex = 0;
@@ -374,10 +387,30 @@ void SwGlossaries::UpdateGlosPath(bool bFull)
continue;
}
aDirArr.push_back(sPth);
if( !FStatHelper::IsFolder( sPth ) )
aInvalidPaths.push_back(sPth);
else
m_PathArr.push_back(sPth);
try
{
::ucbhelper::Content content{sPth,
uno::Reference<ucb::XCommandEnvironment>{},
::comphelper::getProcessComponentContext()};
if (content.isFolder())
{
m_PathArr.push_back(sPth);
}
else
{
aInvalidPaths.push_back({sPth, {}});
}
}
catch (ucb::InteractiveIOException const& e)
{
TOOLS_INFO_EXCEPTION("sw.ui", "AutoText path IO Exception: ");
aInvalidPaths.emplace_back(sPth, e.Code);
}
catch (...)
{
TOOLS_INFO_EXCEPTION("sw.ui", "AutoText path Exception: ");
aInvalidPaths.push_back({sPth, {}});
}
}
while (nIndex>=0);
}
@@ -389,11 +422,9 @@ void SwGlossaries::UpdateGlosPath(bool bFull)
if (bPathChanged || (m_aInvalidPaths != aInvalidPaths))
{
m_aInvalidPaths = std::move(aInvalidPaths);
// wrong path, that means AutoText directory doesn't exist
// AutoText directory not accessible or doesn't exist
ShowError();
ErrorHandler::HandleError( ErrCodeMsg(
ERR_AUTOPATH_ERROR, lcl_makePath(m_aInvalidPaths),
DialogMask::ButtonsOk | DialogMask::MessageError ) );
m_bError = true;
}
else
@@ -411,8 +442,37 @@ void SwGlossaries::UpdateGlosPath(bool bFull)
void SwGlossaries::ShowError()
{
ErrCodeMsg nPathError(ERR_AUTOPATH_ERROR, lcl_makePath(m_aInvalidPaths), DialogMask::ButtonsOk );
ErrorHandler::HandleError( nPathError );
std::vector<OUString> netaccess;
std::vector<OUString> others;
for (auto const& it : m_aInvalidPaths)
{
#ifdef _WIN32
OUString path;
if (it.second && *it.second == ucb::IOErrorCode_ACCESS_DENIED
&& osl::FileBase::getSystemPathFromFileURL(it.first, path) == osl::FileBase::E_None
&& PathIsNetworkPathW(o3tl::toW(path.getStr())) == TRUE)
{
netaccess.emplace_back(it.first);
}
else
#endif
{
others.emplace_back(it.first);
}
}
if (!netaccess.empty())
{
std::unique_ptr<weld::MessageDialog> const xDialog{
Application::CreateMessageDialog(nullptr,
VclMessageType::Error, VclButtonsType::Close,
SwResId(STR_ERR_GLOS_NET_PATH_ACCESS) + u"\n\n" + lcl_makePath(netaccess))};
xDialog->run();
}
if (!others.empty())
{
ErrCodeMsg nPathError(ERR_AUTOPATH_ERROR, lcl_makePath(others), DialogMask::ButtonsOk);
ErrorHandler::HandleError( nPathError );
}
}
OUString SwGlossaries::GetExtension()