Skip to content

Commit c212fd9

Browse files
committed
vcl: extract scanning for resources to UserResourceScanner class
So the scanning for resources can be reused for other things. Change-Id: Ia1589eb6c2ce4f254be0a62e296b1e186d0ba323 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180371 Reviewed-by: Tomaž Vajngerl <[email protected]> Tested-by: Jenkins
1 parent 1ee3324 commit c212fd9

8 files changed

+230
-169
lines changed

include/vcl/UserResourceScanner.hxx

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2+
/*
3+
* This file is part of the LibreOffice project.
4+
*
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/.
8+
*/
9+
10+
#pragma once
11+
12+
#include <vcl/dllapi.h>
13+
#include <rtl/ustring.hxx>
14+
#include <memory>
15+
#include <vector>
16+
#include <osl/file.hxx>
17+
18+
namespace vcl
19+
{
20+
namespace file
21+
{
22+
VCL_DLLPUBLIC bool readFileStatus(osl::FileStatus& rStatus, const OUString& rFile);
23+
}
24+
25+
class VCL_DLLPUBLIC UserResourceScanner
26+
{
27+
protected:
28+
/** Scans the provided directory for the resoruce.
29+
*
30+
* The returned strings will contain the URLs to the resources.
31+
*/
32+
std::vector<OUString> readFilesFromPath(const OUString& dir);
33+
34+
/** Return true if the filename is a valid resource */
35+
virtual bool isValidResource(const OUString& rFilename) = 0;
36+
37+
/** Adds the provided resource by path. */
38+
virtual bool addResource(const OUString& /*path*/) = 0;
39+
40+
public:
41+
UserResourceScanner();
42+
virtual ~UserResourceScanner() {}
43+
44+
/** Provide a semicolon-separated list of paths to search for resource.
45+
*
46+
* There are several cases when scan will fail:
47+
* - The directory does not exist
48+
* - There are no files which have a valid resource
49+
*/
50+
51+
void addPaths(std::u16string_view paths);
52+
};
53+
54+
} // end namespace vcl
55+
56+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

vcl/CppunitTest_vcl_app_test.mk

+1-4
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ $(eval $(call gb_CppunitTest_use_sdk_api,vcl_app_test))
3434
$(eval $(call gb_CppunitTest_use_ure,vcl_app_test))
3535
$(eval $(call gb_CppunitTest_use_vcl,vcl_app_test))
3636

37-
$(eval $(call gb_CppunitTest_use_components,vcl_app_test,\
38-
configmgr/source/configmgr \
39-
i18npool/util/i18npool \
40-
))
37+
$(eval $(call gb_CppunitTest_use_rdb,vcl_app_test,services))
4138

4239
$(eval $(call gb_CppunitTest_use_configuration,vcl_app_test))
4340

vcl/Library_vcl.mk

+1
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
478478
vcl/source/app/timer \
479479
vcl/source/app/unohelp2 \
480480
vcl/source/app/htmltransferable \
481+
vcl/source/app/UserResourceScanner \
481482
vcl/source/app/unohelp \
482483
vcl/source/app/vclevent \
483484
vcl/source/app/watchdog \

vcl/inc/IconThemeScanner.hxx

+6-19
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <rtl/ustring.hxx>
1515
#include <vcl/IconThemeInfo.hxx>
16+
#include <vcl/UserResourceScanner.hxx>
1617

1718
#include <memory>
1819
#include <vector>
@@ -24,16 +25,10 @@ namespace vcl
2425
{
2526
/** This class scans a folder for icon themes and provides the results.
2627
*/
27-
class VCL_DLLPUBLIC IconThemeScanner
28+
class VCL_DLLPUBLIC IconThemeScanner : public UserResourceScanner
2829
{
2930
public:
30-
/** Provide a semicolon-separated list of paths to search for IconThemes.
31-
*
32-
* There are several cases when scan will fail:
33-
* - The directory does not exist
34-
* - There are no files which match the pattern images_xxx.zip
35-
*/
36-
explicit IconThemeScanner(std::u16string_view paths);
31+
IconThemeScanner();
3732

3833
/** This method will return the standard path where icon themes are located.
3934
*/
@@ -53,19 +48,11 @@ public:
5348
bool IconThemeIsInstalled(const OUString& themeId) const;
5449

5550
private:
56-
IconThemeScanner();
57-
58-
/** Adds the provided icon theme by path.
59-
*/
60-
bool AddIconThemeByPath(const OUString& path);
61-
62-
/** Scans the provided directory for icon themes.
63-
* The returned strings will contain the URLs to the icon themes.
64-
*/
65-
static std::vector<OUString> ReadIconThemesFromPath(const OUString& dir);
51+
/** Adds the provided icon theme by path. */
52+
bool addResource(const OUString& path) override;
6653

6754
/** Check whether a single file is valid */
68-
static bool FileIsValidIconTheme(const OUString&);
55+
bool isValidResource(const OUString& rFilename) override;
6956

7057
std::vector<IconThemeInfo> mFoundIconThemes;
7158

vcl/qa/cppunit/app/test_IconThemeScanner.cxx

+12-22
Original file line numberDiff line numberDiff line change
@@ -19,51 +19,41 @@
1919

2020
class IconThemeScannerTest : public CppUnit::TestFixture
2121
{
22-
void
23-
AddedThemeIsFoundById();
24-
25-
void
26-
AddedThemeInfoIsReturned();
27-
28-
void
29-
ExceptionIsThrownIfInvalidInfoIsRequested();
22+
void testAddedThemeIsFoundById();
23+
void testAddedThemeInfoIsReturned();
24+
void testExceptionIsThrownIfInvalidInfoIsRequested();
3025

3126
// Adds code needed to register the test suite
3227
CPPUNIT_TEST_SUITE(IconThemeScannerTest);
33-
CPPUNIT_TEST(AddedThemeIsFoundById);
34-
CPPUNIT_TEST(AddedThemeInfoIsReturned);
35-
CPPUNIT_TEST(ExceptionIsThrownIfInvalidInfoIsRequested);
36-
37-
// End of test suite definition
28+
CPPUNIT_TEST(testAddedThemeIsFoundById);
29+
CPPUNIT_TEST(testAddedThemeInfoIsReturned);
30+
CPPUNIT_TEST(testExceptionIsThrownIfInvalidInfoIsRequested);
3831
CPPUNIT_TEST_SUITE_END();
3932
};
4033

41-
void
42-
IconThemeScannerTest::AddedThemeIsFoundById()
34+
void IconThemeScannerTest::testAddedThemeIsFoundById()
4335
{
4436
vcl::IconThemeScanner scanner;
45-
scanner.AddIconThemeByPath(u"file:://images_katze.zip"_ustr);
37+
scanner.addResource(u"file:://images_katze.zip"_ustr);
4638
OUString id = vcl::IconThemeInfo::FileNameToThemeId(u"images_katze.zip");
4739
bool found = scanner.IconThemeIsInstalled(id);
4840
CPPUNIT_ASSERT_EQUAL_MESSAGE("icon theme could be added by url", true, found);
4941
}
5042

51-
void
52-
IconThemeScannerTest::AddedThemeInfoIsReturned()
43+
void IconThemeScannerTest::testAddedThemeInfoIsReturned()
5344
{
5445
vcl::IconThemeScanner scanner;
5546
OUString theme(u"file:://images_katze.zip"_ustr);
56-
scanner.AddIconThemeByPath(theme);
47+
scanner.addResource(theme);
5748
OUString id = vcl::IconThemeInfo::FileNameToThemeId(u"images_katze.zip");
5849
const vcl::IconThemeInfo& info = scanner.GetIconThemeInfo(id);
5950
CPPUNIT_ASSERT_EQUAL_MESSAGE("'katze' icon theme is found from id", theme, info.GetUrlToFile());
6051
}
6152

62-
void
63-
IconThemeScannerTest::ExceptionIsThrownIfInvalidInfoIsRequested()
53+
void IconThemeScannerTest::testExceptionIsThrownIfInvalidInfoIsRequested()
6454
{
6555
vcl::IconThemeScanner scanner;
66-
scanner.AddIconThemeByPath(u"file:://images_katze.zip"_ustr);
56+
scanner.addResource(u"file:://images_katze.zip"_ustr);
6757
bool thrown = false;
6858
try
6959
{

vcl/source/app/IconThemeScanner.cxx

+11-119
Original file line numberDiff line numberDiff line change
@@ -9,155 +9,47 @@
99

1010
#include <sal/config.h>
1111
#include <sal/log.hxx>
12-
13-
#include <deque>
14-
1512
#include <IconThemeScanner.hxx>
1613

17-
#include <osl/file.hxx>
1814
#include <salhelper/linkhelper.hxx>
1915
#include <unotools/pathoptions.hxx>
2016
#include <vcl/IconThemeInfo.hxx>
2117
#include <o3tl/string_view.hxx>
2218

23-
namespace vcl {
24-
25-
namespace {
26-
27-
// set the status of a file. Returns false if the status could not be determined.
28-
bool set_file_status(osl::FileStatus& status, const OUString& file)
19+
namespace vcl
2920
{
30-
osl::DirectoryItem dirItem;
31-
osl::FileBase::RC retvalGet = osl::DirectoryItem::get(file, dirItem);
32-
if (retvalGet != osl::FileBase::E_None) {
33-
SAL_WARN("vcl.app", "Could not determine status for file '" << file << "'.");
34-
return false;
35-
}
36-
osl::FileBase::RC retvalStatus = dirItem.getFileStatus(status);
37-
if (retvalStatus != osl::FileBase::E_None) {
38-
SAL_WARN("vcl.app", "Could not determine status for file '" << file << "'.");
39-
return false;
40-
}
41-
return true;
42-
}
43-
44-
OUString convert_to_absolute_path(const OUString& path)
45-
{
46-
salhelper::LinkResolver resolver(0);
47-
osl::FileBase::RC rc = resolver.fetchFileStatus(path);
48-
if (rc != osl::FileBase::E_None) {
49-
SAL_WARN("vcl.app", "Could not resolve path '" << path << "' to search for icon themes.");
50-
if (rc == osl::FileBase::E_MULTIHOP)
51-
{
52-
throw std::runtime_error("Provided a recursive symlink to an icon theme directory that could not be resolved.");
53-
}
54-
}
55-
return resolver.m_aStatus.getFileURL();
56-
}
57-
58-
}
5921

6022
IconThemeScanner::IconThemeScanner() = default;
6123

62-
IconThemeScanner::IconThemeScanner(std::u16string_view paths)
63-
{
64-
mFoundIconThemes.clear();
65-
66-
std::deque<OUString> aPaths;
67-
68-
sal_Int32 nIndex = 0;
69-
do
70-
{
71-
aPaths.push_front(OUString(o3tl::getToken(paths, 0, ';', nIndex)));
72-
}
73-
while (nIndex >= 0);
74-
75-
for (const auto& path : aPaths)
76-
{
77-
osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
78-
bool couldSetFileStatus = set_file_status(fileStatus, path);
79-
if (!couldSetFileStatus) {
80-
continue;
81-
}
82-
83-
if (!fileStatus.isDirectory()) {
84-
SAL_INFO("vcl.app", "Cannot search for icon themes in '"<< path << "'. It is not a directory.");
85-
continue;
86-
}
87-
88-
std::vector<OUString> iconThemePaths = ReadIconThemesFromPath(path);
89-
if (iconThemePaths.empty()) {
90-
SAL_WARN("vcl.app", "Could not find any icon themes in the provided directory ('" <<path<<"'.");
91-
continue;
92-
}
93-
for (auto const& iconThemePath : iconThemePaths)
94-
{
95-
AddIconThemeByPath(iconThemePath);
96-
}
97-
}
98-
}
99-
100-
bool
101-
IconThemeScanner::AddIconThemeByPath(const OUString &url)
24+
bool IconThemeScanner::addResource(const OUString& rURL)
10225
{
103-
if (!IconThemeInfo::UrlCanBeParsed(url)) {
26+
if (!IconThemeInfo::UrlCanBeParsed(rURL)) {
10427
return false;
10528
}
106-
SAL_INFO("vcl.app", "Found a file that seems to be an icon theme: '" << url << "'" );
107-
IconThemeInfo newTheme(url);
29+
SAL_INFO("vcl.app", "Found a file that seems to be an icon theme: '" << rURL << "'" );
30+
IconThemeInfo newTheme(rURL);
10831
mFoundIconThemes.push_back(newTheme);
10932
SAL_INFO("vcl.app", "Adding the file as '" << newTheme.GetDisplayName() <<
11033
"' with id '" << newTheme.GetThemeId() << "'.");
11134
return true;
11235
}
11336

114-
/*static*/ std::vector<OUString>
115-
IconThemeScanner::ReadIconThemesFromPath(const OUString& dir)
116-
{
117-
std::vector<OUString> found;
118-
SAL_INFO("vcl.app", "Scanning directory '" << dir << " for icon themes.");
119-
120-
osl::Directory dirToScan(dir);
121-
osl::FileBase::RC retvalOpen = dirToScan.open();
122-
if (retvalOpen != osl::FileBase::E_None) {
123-
return found;
124-
}
125-
126-
osl::DirectoryItem directoryItem;
127-
while (dirToScan.getNextItem(directoryItem) == osl::FileBase::E_None) {
128-
osl::FileStatus status(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName);
129-
osl::FileBase::RC retvalStatus = directoryItem.getFileStatus(status);
130-
if (retvalStatus != osl::FileBase::E_None) {
131-
continue;
132-
}
133-
134-
OUString filename = convert_to_absolute_path(status.getFileURL());
135-
if (!FileIsValidIconTheme(filename)) {
136-
continue;
137-
}
138-
found.push_back(filename);
139-
}
140-
return found;
141-
}
142-
143-
/*static*/ bool
144-
IconThemeScanner::FileIsValidIconTheme(const OUString& filename)
37+
bool IconThemeScanner::isValidResource(const OUString& filename)
14538
{
14639
// check whether we can construct an IconThemeInfo from it
147-
if (!IconThemeInfo::UrlCanBeParsed(filename)) {
40+
if (!IconThemeInfo::UrlCanBeParsed(filename))
41+
{
14842
SAL_INFO("vcl.app", "File '" << filename << "' does not seem to be an icon theme.");
14943
return false;
15044
}
15145

15246
osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
153-
bool couldSetFileStatus = set_file_status(fileStatus, filename);
154-
if (!couldSetFileStatus) {
47+
if (!vcl::file::readFileStatus(fileStatus, filename))
15548
return false;
156-
}
15749

158-
if (!fileStatus.isRegular()) {
50+
if (!fileStatus.isRegular())
15951
return false;
160-
}
52+
16153
return true;
16254
}
16355

0 commit comments

Comments
 (0)