summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTobias Lippert <drtl@fastmail.fm>2014-02-09 00:53:28 +0100
committerCaolán McNamara <caolanm@redhat.com>2014-02-21 17:23:50 +0000
commit076a7eacca48f203f0a8b9aa537e88fea9a88409 (patch)
treecd95446ac0b80b29658fa2a44030dacb5304a63d /vcl
parent1ec263e25d8606c70ac2089d5ceea22750d25daf (diff)
Bug #63962 Dynamically scan the config directory for icon themes
The hard-coded icon themes have been replaced by a dynamic list which is filled by scanning the config directory Conflicts: include/vcl/settings.hxx vcl/source/app/settings.cxx vcl/source/window/window.cxx Change-Id: Ie3680ffe27d06e375acf22753e036cb6ddabc4ed Reviewed-on: https://gerrit.libreoffice.org/7935 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/CppunitTest_vcl_app_test.mk30
-rw-r--r--vcl/Library_vcl.mk3
-rw-r--r--vcl/Module_vcl.mk1
-rw-r--r--vcl/inc/toolbox.h7
-rw-r--r--vcl/qa/cppunit/app/test_IconThemeInfo.cxx143
-rw-r--r--vcl/qa/cppunit/app/test_IconThemeScanner.cxx86
-rw-r--r--vcl/qa/cppunit/app/test_IconThemeSelector.cxx198
-rw-r--r--vcl/source/app/IconThemeInfo.cxx180
-rw-r--r--vcl/source/app/IconThemeScanner.cxx185
-rw-r--r--vcl/source/app/IconThemeSelector.cxx156
-rw-r--r--vcl/source/app/settings.cxx265
-rw-r--r--vcl/source/control/fixed.cxx8
-rw-r--r--vcl/source/gdi/bitmapex.cxx4
-rw-r--r--vcl/source/gdi/image.cxx4
-rw-r--r--vcl/source/gdi/imagerepository.cxx8
-rw-r--r--vcl/source/window/toolbox2.cxx40
-rw-r--r--vcl/source/window/window.cxx1
-rw-r--r--vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx2
-rw-r--r--vcl/unx/kde/salnativewidgets-kde.cxx2
19 files changed, 1089 insertions, 234 deletions
diff --git a/vcl/CppunitTest_vcl_app_test.mk b/vcl/CppunitTest_vcl_app_test.mk
new file mode 100644
index 000000000000..0aa3202abe32
--- /dev/null
+++ b/vcl/CppunitTest_vcl_app_test.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,vcl_app_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,vcl_app_test, \
+ vcl/qa/cppunit/app/test_IconThemeInfo \
+ vcl/qa/cppunit/app/test_IconThemeScanner \
+ vcl/qa/cppunit/app/test_IconThemeSelector \
+))
+
+# add a list of all needed libraries here
+$(eval $(call gb_CppunitTest_use_libraries,vcl_app_test, \
+sal \
+vcl \
+$(gb_STDLIBS) \
+))
+
+$(eval $(call gb_CppunitTest_set_include,vcl_app_test, \
+$$(INCLUDE) \
+-I$(OUTDIR)/inc \
+ ))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 17258235a8e1..ff915330308f 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -112,6 +112,9 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/app/salvtables \
vcl/source/app/session \
vcl/source/app/settings \
+ vcl/source/app/IconThemeInfo \
+ vcl/source/app/IconThemeScanner \
+ vcl/source/app/IconThemeSelector \
vcl/source/app/solarmutex \
vcl/source/app/sound \
vcl/source/app/stdtext \
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 4dc64347ae63..1f3c8e2bde59 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -88,6 +88,7 @@ endif
$(eval $(call gb_Module_add_check_targets,vcl,\
CppunitTest_vcl_complextext \
CppunitTest_vcl_filters_test \
+ CppunitTest_vcl_app_test \
))
# vim: set noet sw=4 ts=4:
diff --git a/vcl/inc/toolbox.h b/vcl/inc/toolbox.h
index bfffe7bcffd6..cf89d02d9759 100644
--- a/vcl/inc/toolbox.h
+++ b/vcl/inc/toolbox.h
@@ -34,13 +34,6 @@
#define TB_MENUBUTTON_SIZE 12
#define TB_MENUBUTTON_OFFSET 2
-#define TB_SMALLIMAGESIZE 16
-
-#define TB_LARGEIMAGESIZE 26
-#define TB_LARGEIMAGESIZE_INDUSTRIAL 24
-#define TB_LARGEIMAGESIZE_CRYSTAL 22
-#define TB_LARGEIMAGESIZE_OXYGEN 22
-
class Window;
struct ImplToolItem
diff --git a/vcl/qa/cppunit/app/test_IconThemeInfo.cxx b/vcl/qa/cppunit/app/test_IconThemeInfo.cxx
new file mode 100644
index 000000000000..e401046757ba
--- /dev/null
+++ b/vcl/qa/cppunit/app/test_IconThemeInfo.cxx
@@ -0,0 +1,143 @@
+/* -*- 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 <sal/types.h>
+
+#include <rtl/ustring.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+using namespace vcl;
+
+class IconThemeInfoTest : public CppUnit::TestFixture
+{
+ void
+ UpperCaseDisplayNameIsReturnedForNonDefaultId();
+
+ void
+ ImagesZipIsNotValid();
+
+ void
+ ImagesOxygenZipIsValid();
+
+ void
+ DefaultZipIsValid();
+
+ void
+ ThemeIdIsDetectedFromFileNameWithUnderscore();
+
+ void
+ ExceptionIsThrownWhenIdCannotBeDetermined1();
+
+ void
+ ExceptionIsThrownWhenIdCannotBeDetermined2();
+
+ void
+ GalaxyIsReturnedAsDisplayNameForDefaultZip();
+
+ // Adds code needed to register the test suite
+ CPPUNIT_TEST_SUITE(IconThemeInfoTest);
+ CPPUNIT_TEST(UpperCaseDisplayNameIsReturnedForNonDefaultId);
+ CPPUNIT_TEST(ThemeIdIsDetectedFromFileNameWithUnderscore);
+ CPPUNIT_TEST(ImagesZipIsNotValid);
+ CPPUNIT_TEST(ImagesOxygenZipIsValid);
+ CPPUNIT_TEST(DefaultZipIsValid);
+ CPPUNIT_TEST(GalaxyIsReturnedAsDisplayNameForDefaultZip);
+ CPPUNIT_TEST(ExceptionIsThrownWhenIdCannotBeDetermined1);
+ CPPUNIT_TEST(ExceptionIsThrownWhenIdCannotBeDetermined2);
+
+ // End of test suite definition
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void
+IconThemeInfoTest::UpperCaseDisplayNameIsReturnedForNonDefaultId()
+{
+ OUString id("katze");
+ OUString displayName = vcl::IconThemeInfo::ThemeIdToDisplayName(id);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("theme id is properly uppercased", OUString("Katze"), displayName);
+}
+
+void
+IconThemeInfoTest::ImagesZipIsNotValid()
+{
+ OUString id("file://images.zip");
+ bool valid = vcl::IconThemeInfo::UrlCanBeParsed(id);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("images.zip is not a valid theme name", false, valid);
+}
+
+void
+IconThemeInfoTest::ImagesOxygenZipIsValid()
+{
+ OUString id("file://images_oxygen.zip");
+ bool valid = vcl::IconThemeInfo::UrlCanBeParsed(id);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("images_oxygen.zip is a valid theme name", true, valid);
+}
+
+void
+IconThemeInfoTest::DefaultZipIsValid()
+{
+ OUString id("file://default.zip");
+ bool valid = vcl::IconThemeInfo::UrlCanBeParsed(id);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("default.zip is a valid theme name", true, valid);
+}
+
+
+void
+IconThemeInfoTest::ThemeIdIsDetectedFromFileNameWithUnderscore()
+{
+ OUString fname("images_oxygen.zip");
+ OUString sname = vcl::IconThemeInfo::FileNameToThemeId(fname);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme id is returned for 'images_oxygen.zip'", OUString("oxygen"), sname);
+}
+
+void
+IconThemeInfoTest::ExceptionIsThrownWhenIdCannotBeDetermined1()
+{
+ bool thrown = false;
+ OUString fname("images_oxygen");
+ try {
+ OUString sname = vcl::IconThemeInfo::FileNameToThemeId(fname);
+ }
+ catch (std::runtime_error&) {
+ thrown = true;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Exception was thrown",true, thrown);
+}
+
+void
+IconThemeInfoTest::ExceptionIsThrownWhenIdCannotBeDetermined2()
+{
+ bool thrown = false;
+ OUString fname("image_oxygen.zip");
+ try {
+ OUString sname = vcl::IconThemeInfo::FileNameToThemeId(fname);
+ }
+ catch (std::runtime_error&) {
+ thrown = true;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Exception was thrown", true, thrown);
+}
+
+void
+IconThemeInfoTest::GalaxyIsReturnedAsDisplayNameForDefaultZip()
+{
+ OUString id("file://default.zip");
+ IconThemeInfo i(id);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("default.zip is displayed as Galaxy", OUString("Galaxy"), i.GetDisplayName());
+}
+
+// Put the test suite in the registry
+CPPUNIT_TEST_SUITE_REGISTRATION(IconThemeInfoTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qa/cppunit/app/test_IconThemeScanner.cxx b/vcl/qa/cppunit/app/test_IconThemeScanner.cxx
new file mode 100644
index 000000000000..af2e95703953
--- /dev/null
+++ b/vcl/qa/cppunit/app/test_IconThemeScanner.cxx
@@ -0,0 +1,86 @@
+/* -*- 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 <sal/types.h>
+
+#include <rtl/ustring.hxx>
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+class IconThemeScannerTest : public CppUnit::TestFixture
+{
+ void
+ AddedThemeIsFoundById();
+
+ void
+ AddedThemeInfoIsReturned();
+
+ void
+ ExceptionIsThrownIfInvalidInfoIsRequested();
+
+ // Adds code needed to register the test suite
+ CPPUNIT_TEST_SUITE(IconThemeScannerTest);
+ CPPUNIT_TEST(AddedThemeIsFoundById);
+ CPPUNIT_TEST(AddedThemeInfoIsReturned);
+ CPPUNIT_TEST(ExceptionIsThrownIfInvalidInfoIsRequested);
+
+ // End of test suite definition
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void
+IconThemeScannerTest::AddedThemeIsFoundById()
+{
+ vcl::IconThemeScanner scanner;
+ OUString theme("file:://images_katze.zip");
+ scanner.AddIconThemeByPath(theme);
+ OUString id = vcl::IconThemeInfo::FileNameToThemeId("images_katze.zip");
+ bool found = false;
+ found = scanner.IconThemeIsInstalled(id);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("icon theme could be added by url", true, found);
+}
+
+void
+IconThemeScannerTest::AddedThemeInfoIsReturned()
+{
+ vcl::IconThemeScanner scanner;
+ OUString theme("file:://images_katze.zip");
+ scanner.AddIconThemeByPath(theme);
+ OUString id = vcl::IconThemeInfo::FileNameToThemeId("images_katze.zip");
+ const vcl::IconThemeInfo& info = scanner.GetIconThemeInfo(id);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'katze' icon theme is found from id", theme, info.GetUrlToFile());
+}
+
+void
+IconThemeScannerTest::ExceptionIsThrownIfInvalidInfoIsRequested()
+{
+ vcl::IconThemeScanner scanner;
+ OUString theme("file:://images_katze.zip");
+ scanner.AddIconThemeByPath(theme);
+ bool thrown = false;
+ try
+ {
+ scanner.GetIconThemeInfo("hund");
+ }
+ catch (const std::runtime_error&)
+ {
+ thrown = true;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Exception is thrown if invalid theme info is requested", true, thrown);
+}
+
+// Put the test suite in the registry
+CPPUNIT_TEST_SUITE_REGISTRATION(IconThemeScannerTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qa/cppunit/app/test_IconThemeSelector.cxx b/vcl/qa/cppunit/app/test_IconThemeSelector.cxx
new file mode 100644
index 000000000000..34961e761dcc
--- /dev/null
+++ b/vcl/qa/cppunit/app/test_IconThemeSelector.cxx
@@ -0,0 +1,198 @@
+/* -*- 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 <vcl/IconThemeSelector.hxx>
+
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+class IconThemeSelectorTest : public CppUnit::TestFixture
+{
+ void
+ OxygenThemeIsReturnedForKde4Desktop();
+
+ void
+ TangoThemeIsReturnedForGtkDesktop();
+
+ void
+ ThemeIsOverriddenByPreferredTheme();
+
+ void
+ ThemeIsOverriddenByHighContrastMode();
+
+ void
+ NotInstalledThemeDoesNotOverride();
+
+ void
+ InstalledThemeIsFound();
+
+ void
+ FirstThemeIsReturnedIfRequestedThemeIsNotFound();
+
+ void
+ FallbackThemeIsReturnedForEmptyInput();
+
+ void
+ DifferentPreferredThemesAreInequal();
+
+ void
+ DifferentHighContrastModesAreInequal();
+
+ static std::vector<vcl::IconThemeInfo>
+ GetFakeInstalledThemes();
+
+ // Adds code needed to register the test suite
+ CPPUNIT_TEST_SUITE(IconThemeSelectorTest);
+
+ CPPUNIT_TEST(OxygenThemeIsReturnedForKde4Desktop);
+ CPPUNIT_TEST(TangoThemeIsReturnedForGtkDesktop);
+ CPPUNIT_TEST(ThemeIsOverriddenByPreferredTheme);
+ CPPUNIT_TEST(ThemeIsOverriddenByHighContrastMode);
+ CPPUNIT_TEST(NotInstalledThemeDoesNotOverride);
+ CPPUNIT_TEST(InstalledThemeIsFound);
+ CPPUNIT_TEST(FirstThemeIsReturnedIfRequestedThemeIsNotFound);
+ CPPUNIT_TEST(FallbackThemeIsReturnedForEmptyInput);
+ CPPUNIT_TEST(DifferentPreferredThemesAreInequal);
+ CPPUNIT_TEST(DifferentHighContrastModesAreInequal);
+
+ // End of test suite definition
+
+
+ CPPUNIT_TEST_SUITE_END();
+};
+
+/*static*/ std::vector<vcl::IconThemeInfo>
+IconThemeSelectorTest::GetFakeInstalledThemes()
+{
+ std::vector<vcl::IconThemeInfo> r;
+ vcl::IconThemeInfo a{};
+ a.mThemeId = "tango";
+ r.push_back(a);
+ a.mThemeId = "oxygen";
+ r.push_back(a);
+ a.mThemeId = vcl::IconThemeSelector::HIGH_CONTRAST_ICON_THEME_ID;
+ r.push_back(a);
+ return r;
+}
+
+void
+IconThemeSelectorTest::OxygenThemeIsReturnedForKde4Desktop()
+{
+ std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+ vcl::IconThemeSelector s;
+ OUString r = s.SelectIconThemeForDesktopEnvironment(themes, "kde4");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is returned for kde4 desktop", OUString("oxygen"), r);
+}
+
+void
+IconThemeSelectorTest::TangoThemeIsReturnedForGtkDesktop()
+{
+ std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+ vcl::IconThemeSelector s;
+ OUString r = s.SelectIconThemeForDesktopEnvironment(themes, "gtk");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is returned for kde4 desktop", OUString("tango"), r);
+}
+
+void
+IconThemeSelectorTest::ThemeIsOverriddenByPreferredTheme()
+{
+ vcl::IconThemeSelector s;
+ OUString preferred("oxygen");
+ s.SetPreferredIconTheme(preferred);
+ std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+ OUString selected = s.SelectIconThemeForDesktopEnvironment(themes, "gtk");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is overridden by oxygen", preferred, selected);
+}
+
+void
+IconThemeSelectorTest::ThemeIsOverriddenByHighContrastMode()
+{
+ vcl::IconThemeSelector s;
+ s.SetUseHighContrastTheme(true);
+ std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+ OUString selected = s.SelectIconTheme(themes, "tango");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is overridden by high contrast mode",
+ vcl::IconThemeSelector::HIGH_CONTRAST_ICON_THEME_ID, selected);
+ s.SetUseHighContrastTheme(false);
+ selected = s.SelectIconTheme(themes, "tango");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is no longer overridden by high contrast mode",
+ OUString("tango"), selected);
+}
+
+void
+IconThemeSelectorTest::NotInstalledThemeDoesNotOverride()
+{
+ vcl::IconThemeSelector s;
+ s.SetPreferredIconTheme("oxygen_katze");
+ std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+ OUString selected = s.SelectIconTheme(themes, "oxygen");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is not overridden by 'oxygen_katze'", OUString("oxygen"), selected);
+}
+
+void
+IconThemeSelectorTest::InstalledThemeIsFound()
+{
+ vcl::IconThemeSelector s;
+ std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+ OUString selected = s.SelectIconTheme(themes, "oxygen");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is found", OUString("oxygen"), selected);
+}
+
+void
+IconThemeSelectorTest::FirstThemeIsReturnedIfRequestedThemeIsNotFound()
+{
+ vcl::IconThemeSelector s;
+ std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+ OUString selected = s.SelectIconTheme(themes, "oxygen_katze");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is found", themes.front().GetThemeId(), selected);
+}
+
+void
+IconThemeSelectorTest::FallbackThemeIsReturnedForEmptyInput()
+{
+ vcl::IconThemeSelector s;
+ OUString selected = s.SelectIconTheme(std::vector<vcl::IconThemeInfo>{}, "oxygen");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("fallback is returned for empty input",
+ vcl::IconThemeSelector::FALLBACK_ICON_THEME_ID, selected);
+}
+
+void
+IconThemeSelectorTest::DifferentHighContrastModesAreInequal()
+{
+ vcl::IconThemeSelector s1;
+ vcl::IconThemeSelector s2;
+ s1.SetUseHighContrastTheme(true);
+ s2.SetUseHighContrastTheme(false);
+ bool equal = (s1 == s2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Different high contrast modes are detected as inequal", false, equal);
+}
+
+void
+IconThemeSelectorTest::DifferentPreferredThemesAreInequal()
+{
+ vcl::IconThemeSelector s1;
+ vcl::IconThemeSelector s2;
+ s1.SetPreferredIconTheme("oxygen");
+ s2.SetUseHighContrastTheme("katze");
+ bool equal = (s1 == s2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Different preferred themes are detected as inequal", false, equal);
+}
+
+
+// Put the test suite in the registry
+CPPUNIT_TEST_SUITE_REGISTRATION(IconThemeSelectorTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/IconThemeInfo.cxx b/vcl/source/app/IconThemeInfo.cxx
new file mode 100644
index 000000000000..69f0302b6909
--- /dev/null
+++ b/vcl/source/app/IconThemeInfo.cxx
@@ -0,0 +1,180 @@
+/*
+ * 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 <vcl/IconThemeInfo.hxx>
+#include <rtl/character.hxx>
+
+#include <stdexcept>
+#include <algorithm>
+
+namespace {
+
+OUString
+filename_from_url(const OUString& url)
+{
+ sal_Int32 slashPosition = url.lastIndexOf( '/' );
+ if (slashPosition < 0) {
+ return OUString("");
+ }
+ OUString filename = url.copy( slashPosition+1 );
+ return filename;
+}
+
+}
+
+namespace vcl {
+
+static const char ICON_THEME_PACKAGE_PREFIX[] = "images_";
+
+static const char EXTENSION_FOR_ICON_PACKAGES[] = ".zip";
+
+IconThemeInfo::IconThemeInfo()
+{
+}
+
+IconThemeInfo::IconThemeInfo(const OUString& urlToFile)
+: mUrlToFile(urlToFile)
+{
+ OUString filename = filename_from_url(urlToFile);
+ if (filename.isEmpty()) {
+ throw std::runtime_error("invalid URL passed to IconThemeInfo()");
+ }
+
+ mThemeId = FileNameToThemeId(filename);
+ mDisplayName = ThemeIdToDisplayName(mThemeId);
+
+}
+
+/*static*/ Size
+IconThemeInfo::SizeByThemeName(const OUString& themeName)
+{
+ if (themeName == "tango") {
+ return Size( 24, 24 );
+ }
+ else if (themeName == "crystal") {
+ return Size( 22, 22 );
+ }
+ else if (themeName == "default") {
+ return Size( 22, 22 );
+ }
+ else {
+ return Size( 26, 26 );
+ }
+}
+
+/*static*/ bool
+IconThemeInfo::UrlCanBeParsed(const OUString& url)
+{
+ OUString fname = filename_from_url(url);
+ if (fname.isEmpty()) {
+ return false;
+ }
+
+ if (fname == "default.zip") {
+ return true;
+ }
+
+ if (!fname.startsWithIgnoreAsciiCase(ICON_THEME_PACKAGE_PREFIX)) {
+ return false;
+ }
+
+ if (!fname.endsWithIgnoreAsciiCase(EXTENSION_FOR_ICON_PACKAGES, nullptr)) {
+ return false;
+ }
+
+ return true;
+}
+
+/*static*/ OUString
+IconThemeInfo::FileNameToThemeId(const OUString& filename)
+{
+ if (filename == "default.zip") {
+ return OUString("default");
+ }
+ OUString r;
+ sal_Int32 positionOfLastDot = filename.lastIndexOf(EXTENSION_FOR_ICON_PACKAGES);
+ if (positionOfLastDot < 0) { // -1 means index not found
+ throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
+ }
+ sal_Int32 positionOfFirstUnderscore = filename.indexOf(ICON_THEME_PACKAGE_PREFIX);
+ if (positionOfFirstUnderscore < 0) { // -1 means index not found. Use the whole name instead
+ throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
+ }
+ positionOfFirstUnderscore += RTL_CONSTASCII_LENGTH(ICON_THEME_PACKAGE_PREFIX);
+ r = filename.copy(positionOfFirstUnderscore, positionOfLastDot - positionOfFirstUnderscore);
+ return r;
+}
+
+/*static*/ OUString
+IconThemeInfo::ThemeIdToDisplayName(const OUString& themeId)
+{
+ if (themeId.isEmpty()) {
+ throw std::runtime_error("IconThemeInfo::ThemeIdToDisplayName() called with invalid id.");
+ }
+
+ if (themeId == "default") {
+ return OUString("Galaxy");
+ }
+
+ // make the first letter uppercase
+ OUString r;
+ sal_Unicode firstLetter = themeId[0];
+ if (rtl::isAsciiLowerCase(firstLetter)) {
+ r = OUString(rtl::toAsciiUpperCase(firstLetter));
+ r += themeId.copy(1);
+ }
+ else {
+ r = themeId;
+ }
+ return r;
+}
+
+namespace
+{
+ class SameTheme :
+ public std::unary_function<const vcl::IconThemeInfo &, bool>
+ {
+ private:
+ const OUString& m_rThemeId;
+ public:
+ SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
+ bool operator()(const vcl::IconThemeInfo &rInfo)
+ {
+ return m_rThemeId == rInfo.GetThemeId();
+ }
+ };
+}
+
+/*static*/ const vcl::IconThemeInfo&
+IconThemeInfo::FindIconThemeById(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId)
+{
+ std::vector<vcl::IconThemeInfo>::const_iterator it = std::find_if(themes.begin(), themes.end(),
+ SameTheme(themeId));
+ if (it == themes.end())
+ {
+ throw std::runtime_error("Could not find theme id in theme vector.");
+ }
+ return *it;
+}
+
+/*static*/ bool
+IconThemeInfo::IconThemeIsInVector(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId)
+{
+ std::vector<vcl::IconThemeInfo>::const_iterator it = std::find_if(themes.begin(), themes.end(),
+ SameTheme(themeId));
+ if (it != themes.end()) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+} // end namespace vcl
+
+
diff --git a/vcl/source/app/IconThemeScanner.cxx b/vcl/source/app/IconThemeScanner.cxx
new file mode 100644
index 000000000000..e6a6a130b92f
--- /dev/null
+++ b/vcl/source/app/IconThemeScanner.cxx
@@ -0,0 +1,185 @@
+/*
+ * 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 <vcl/IconThemeScanner.hxx>
+
+#include <config_folders.h>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+namespace vcl {
+
+namespace {
+
+bool
+search_path_is_valid(const OUString& dir)
+{
+ osl::DirectoryItem dirItem;
+ osl::FileBase::RC retvalGet = osl::DirectoryItem::get(dir, dirItem);
+ if (retvalGet != osl::FileBase::RC::E_None) {
+ return false;
+ }
+ osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
+ osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus);
+ if (retvalStatus != osl::FileBase::RC::E_None) {
+ return false;
+ }
+
+ if (!fileStatus.isDirectory()) {
+ return false;
+ }
+ return true;
+}
+
+}
+
+IconThemeScanner::IconThemeScanner()
+{;}
+
+bool
+IconThemeScanner::ScanDirectoryForIconThemes(const OUString& path)
+{
+ bool pathIsValid = search_path_is_valid(path);
+ if (!pathIsValid) {
+ return false;
+ }
+ std::vector<OUString> iconThemePaths = ReadIconThemesFromPath(path);
+ if (iconThemePaths.empty()) {
+ return false;
+ }
+ mFoundIconThemes.clear();
+ for (const OUString& pathToTheme : iconThemePaths) {
+ AddIconThemeByPath(pathToTheme);
+ }
+ return true;
+}
+
+bool
+IconThemeScanner::AddIconThemeByPath(const OUString &url)
+{
+ if (!IconThemeInfo::UrlCanBeParsed(url)) {
+ return false;
+ }
+ IconThemeInfo newTheme{url};
+ mFoundIconThemes.push_back(newTheme);
+ return true;
+}
+
+/*static*/ std::vector<OUString>
+IconThemeScanner::ReadIconThemesFromPath(const OUString& dir)
+{
+ std::vector<OUString> found;
+
+ osl::Directory dirToScan(dir);
+ osl::FileBase::RC retvalOpen = dirToScan.open();
+ if (retvalOpen != osl::FileBase::RC::E_None) {
+ return found;
+ }
+
+ osl::DirectoryItem directoryItem;
+ while (dirToScan.getNextItem(directoryItem) == osl::FileBase::RC::E_None) {
+ osl::FileStatus status(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName);
+ osl::FileBase::RC retvalStatus = directoryItem.getFileStatus(status);
+ if (retvalStatus != osl::FileBase::RC::E_None) {
+ continue;
+ }
+ if (!status.isRegular()) {
+ continue;
+ }
+ if (!FileIsValidIconTheme(status.getFileURL())) {
+ continue;
+ }
+ OUString entry;
+ entry = status.getFileURL();
+ found.push_back(entry);
+ }
+ return found;
+}
+
+/*static*/ bool
+IconThemeScanner::FileIsValidIconTheme(const OUString& filename)
+{
+ // check whether we can construct a IconThemeInfo from it
+ if (!IconThemeInfo::UrlCanBeParsed(filename)) {
+ return false;
+ }
+
+ // check whether the file is a regular file
+ osl::DirectoryItem dirItem;
+ osl::FileBase::RC retvalGet = osl::DirectoryItem::get(filename, dirItem);
+ if (retvalGet != osl::FileBase::RC::E_None) {
+ return false;
+ }
+ osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
+ osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus);
+ if (retvalStatus != osl::FileBase::RC::E_None) {
+ return false;
+ }
+ if (!fileStatus.isRegular()) {
+ return false;
+ }
+ return true;
+}
+
+bool
+IconThemeScanner::IconThemeIsInstalled(const OUString& themeId) const
+{
+ return IconThemeInfo::IconThemeIsInVector(mFoundIconThemes, themeId);
+}
+
+/*static*/ boost::shared_ptr<IconThemeScanner>
+IconThemeScanner::Create(const OUString &path)
+{
+ boost::shared_ptr<IconThemeScanner> retval(new IconThemeScanner{});
+ retval->ScanDirectoryForIconThemes(path);
+ return retval;
+}
+
+/*static*/ OUString
+IconThemeScanner::GetStandardIconThemePath()
+{
+ OUString url( "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/config/" );
+ rtl::Bootstrap::expandMacros(url);
+ return url;
+}
+
+IconThemeScanner::~IconThemeScanner()
+{;}
+
+namespace
+{
+ class SameTheme :
+ public std::unary_function<const vcl::IconThemeInfo &, bool>
+ {
+ private:
+ const OUString& m_rThemeId;
+ public:
+ SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
+ bool operator()(const vcl::IconThemeInfo &rInfo)
+ {
+ return m_rThemeId == rInfo.GetThemeId();
+ }
+ };
+}
+
+const vcl::IconThemeInfo&
+IconThemeScanner::GetIconThemeInfo(const OUString& themeId)
+{
+ std::vector<IconThemeInfo>::iterator info = std::find_if(mFoundIconThemes.begin(), mFoundIconThemes.end(),
+ SameTheme(themeId));
+ if (info == mFoundIconThemes.end()) {
+ throw std::runtime_error("Requested information on not-installed icon theme");
+ }
+ return *info;
+}
+
+
+} // end namespace vcl
diff --git a/vcl/source/app/IconThemeSelector.cxx b/vcl/source/app/IconThemeSelector.cxx
new file mode 100644
index 000000000000..023745bf9bcd
--- /dev/null
+++ b/vcl/source/app/IconThemeSelector.cxx
@@ -0,0 +1,156 @@
+/* -*- 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 <vcl/IconThemeSelector.hxx>
+
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <algorithm>
+
+namespace vcl {
+
+/*static*/ const OUString
+IconThemeSelector::HIGH_CONTRAST_ICON_THEME_ID("hicontrast");
+
+/*static*/ const OUString
+IconThemeSelector::FALLBACK_ICON_THEME_ID("tango");
+
+
+namespace {
+
+ class SameTheme :
+ public std::unary_function<const vcl::IconThemeInfo &, bool>
+ {
+ private:
+ const OUString& m_rThemeId;
+ public:
+ SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
+ bool operator()(const vcl::IconThemeInfo &rInfo)
+ {
+ return m_rThemeId == rInfo.GetThemeId();
+ }
+ };
+
+bool icon_theme_is_in_installed_themes(const OUString& theme,
+ const std::vector<IconThemeInfo>& installedThemes)
+{
+ return std::find_if(installedThemes.begin(), installedThemes.end(),
+ SameTheme(theme)
+ ) != installedThemes.end();
+}
+
+} // end anonymous namespace
+
+IconThemeSelector::IconThemeSelector()
+: mUseHighContrastTheme(false)
+{
+}
+
+/*static*/ OUString
+IconThemeSelector::GetIconThemeForDesktopEnvironment(const OUString& desktopEnvironment)
+{
+ OUString r;
+ if ( desktopEnvironment.equalsIgnoreAsciiCase("tde") ||
+ desktopEnvironment.equalsIgnoreAsciiCase("kde") ) {
+ r = "crystal";
+ }
+ else if ( desktopEnvironment.equalsIgnoreAsciiCase("kde4") ) {
+ r = "oxygen";
+ }
+ else {
+ r = FALLBACK_ICON_THEME_ID;
+ }
+ return r;
+}
+
+OUString
+IconThemeSelector::SelectIconThemeForDesktopEnvironment(
+ const std::vector<IconThemeInfo>& installedThemes,
+ const OUString& desktopEnvironment) const
+{
+ if (!mPreferredIconTheme.isEmpty()) {
+ if (icon_theme_is_in_installed_themes(mPreferredIconTheme, installedThemes)) {
+ return mPreferredIconTheme;
+ }
+ }
+
+ OUString themeForDesktop = GetIconThemeForDesktopEnvironment(desktopEnvironment);
+ if (icon_theme_is_in_installed_themes(themeForDesktop, installedThemes)) {
+ return themeForDesktop;
+ }
+
+ return ReturnFallback(installedThemes);
+}
+
+OUString
+IconThemeSelector::SelectIconTheme(
+ const std::vector<IconThemeInfo>& installedThemes,
+ const OUString& theme) const
+{
+ if (mUseHighContrastTheme) {
+ if (icon_theme_is_in_installed_themes(HIGH_CONTRAST_ICON_THEME_ID, installedThemes)) {
+ return HIGH_CONTRAST_ICON_THEME_ID;
+ }
+ }
+
+ if (icon_theme_is_in_installed_themes(theme, installedThemes)) {
+ return theme;
+ }
+
+ return ReturnFallback(installedThemes);
+}
+
+void
+IconThemeSelector::SetUseHighContrastTheme(bool v)
+{
+ mUseHighContrastTheme = v;
+}
+
+void
+IconThemeSelector::SetPreferredIconTheme(const OUString& theme)
+{
+ mPreferredIconTheme = theme;
+}
+
+bool
+IconThemeSelector::operator==(const vcl::IconThemeSelector& other) const
+{
+ if (this == &other) {
+ return true;
+ }
+ if (mPreferredIconTheme != other.mPreferredIconTheme) {
+ return false;
+ }
+ if (mUseHighContrastTheme != other.mUseHighContrastTheme) {
+ return false;
+ }
+ return true;
+}
+
+bool
+IconThemeSelector::operator!=(const vcl::IconThemeSelector& other) const
+{
+ return !((*this) == other);
+}
+
+/*static*/ OUString
+IconThemeSelector::ReturnFallback(const std::vector<IconThemeInfo>& installedThemes)
+{
+ if (!installedThemes.empty()) {
+ return installedThemes.front().GetThemeId();
+ }
+ else {
+ return FALLBACK_ICON_THEME_ID;
+ }
+}
+
+} /* namespace vcl */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
index 97147478d3b0..c6c93dda5579 100644
--- a/vcl/source/app/settings.cxx
+++ b/vcl/source/app/settings.cxx
@@ -25,11 +25,14 @@
#include "comphelper/processfactory.hxx"
#include <rtl/bootstrap.hxx>
#include "tools/debug.hxx"
-#include <vcl/graphicfilter.hxx>
#include "i18nlangtag/mslangid.hxx"
#include "i18nlangtag/languagetag.hxx"
+#include <vcl/graphicfilter.hxx>
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeSelector.hxx>
+#include <vcl/IconThemeInfo.hxx>
#include "vcl/svapp.hxx"
#include "vcl/event.hxx"
#include "vcl/settings.hxx"
@@ -53,9 +56,6 @@ using namespace ::com::sun::star;
// =======================================================================
-
-// =======================================================================
-
ImplMouseData::ImplMouseData()
{
mnOptions = 0;
@@ -182,6 +182,8 @@ bool MouseSettings::operator ==( const MouseSettings& rSet ) const
// =======================================================================
ImplStyleData::ImplStyleData() :
+ mIconThemeScanner(vcl::IconThemeScanner::Create(vcl::IconThemeScanner::GetStandardIconThemePath())),
+ mIconThemeSelector(new vcl::IconThemeSelector()),
maPersonaHeaderFooter(),
maPersonaHeaderBitmap(),
maPersonaFooterBitmap()
@@ -205,9 +207,7 @@ ImplStyleData::ImplStyleData() :
mnOptions = 0;
mnAutoMnemonic = 1;
mnToolbarIconSize = STYLE_TOOLBAR_ICONSIZE_UNKNOWN;
- mnSymbolsStyle = STYLE_SYMBOLS_AUTO;
mnUseImagesInMenus = AUTO_STATE_AUTO;
- mnPreferredSymbolsStyle = STYLE_SYMBOLS_AUTO;
mpFontOptions = NULL;
mnEdgeBlending = 35;
maEdgeBlendingTopLeftColor = RGB_COLORDATA(0xC0, 0xC0, 0xC0);
@@ -288,6 +288,7 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) :
maFieldFont( rData.maFieldFont ),
maIconFont( rData.maIconFont ),
maGroupFont( rData.maGroupFont ),
+ mIconTheme(rData.mIconTheme),
maWorkspaceGradient( rData.maWorkspaceGradient ),
maDialogStyle( rData.maDialogStyle ),
maFrameStyle( rData.maFrameStyle ),
@@ -317,20 +318,20 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) :
mnSelectionOptions = rData.mnSelectionOptions;
mnDisplayOptions = rData.mnDisplayOptions;
mnOptions = rData.mnOptions;
- mnHighContrast = rData.mnHighContrast;
- mnUseSystemUIFonts = rData.mnUseSystemUIFonts;
+ mbHighContrast = rData.mbHighContrast;
+ mbUseSystemUIFonts = rData.mbUseSystemUIFonts;
mnUseFlatBorders = rData.mnUseFlatBorders;
mnUseFlatMenus = rData.mnUseFlatMenus;
mnAutoMnemonic = rData.mnAutoMnemonic;
mnUseImagesInMenus = rData.mnUseImagesInMenus;
mbPreferredUseImagesInMenus = rData.mbPreferredUseImagesInMenus;
- mnSkipDisabledInMenus = rData.mnSkipDisabledInMenus;
+ mbSkipDisabledInMenus = rData.mbSkipDisabledInMenus;
mbHideDisabledMenuItems = rData.mbHideDisabledMenuItems;
mbAcceleratorsInContextMenus = rData.mbAcceleratorsInContextMenus;
mbPrimaryButtonWarpsSlider = rData.mbPrimaryButtonWarpsSlider;
mnToolbarIconSize = rData.mnToolbarIconSize;
- mnSymbolsStyle = rData.mnSymbolsStyle;
- mnPreferredSymbolsStyle = rData.mnPreferredSymbolsStyle;
+ mIconThemeScanner.reset(new vcl::IconThemeScanner(*rData.mIconThemeScanner));
+ mIconThemeSelector.reset(new vcl::IconThemeSelector(*rData.mIconThemeSelector));
mpFontOptions = rData.mpFontOptions;
mnEdgeBlending = rData.mnEdgeBlending;
maEdgeBlendingTopLeftColor = rData.maEdgeBlendingTopLeftColor;
@@ -422,12 +423,12 @@ void ImplStyleData::SetStandardStyles()
mnFloatTitleHeight = 13;
mnTearOffTitleHeight = 8;
mnMenuBarHeight = 14;
- mnHighContrast = false;
- mnUseSystemUIFonts = true;
+ mbHighContrast = false;
+ mbUseSystemUIFonts = true;
mnUseFlatBorders = false;
mnUseFlatMenus = false;
mbPreferredUseImagesInMenus = true;
- mnSkipDisabledInMenus = false;
+ mbSkipDisabledInMenus = false;
mbHideDisabledMenuItems = false;
mbAcceleratorsInContextMenus = true;
mbPrimaryButtonWarpsSlider = false;
@@ -500,75 +501,6 @@ void StyleSettings::Set3DColors( const Color& rColor )
}
}
-// -----------------------------------------------------------------------
-
-OUString StyleSettings::ImplSymbolsStyleToName( sal_uLong nStyle ) const
-{
- switch ( nStyle )
- {
- case STYLE_SYMBOLS_DEFAULT: return OUString("default");
- case STYLE_SYMBOLS_HICONTRAST: return OUString("hicontrast");
- case STYLE_SYMBOLS_INDUSTRIAL: return OUString("tango"); // industrial is dead
- case STYLE_SYMBOLS_CRYSTAL: return OUString("crystal");
- case STYLE_SYMBOLS_TANGO: return OUString("tango");
- case STYLE_SYMBOLS_OXYGEN: return OUString("oxygen");
- case STYLE_SYMBOLS_CLASSIC: return OUString("classic");
- case STYLE_SYMBOLS_HUMAN: return OUString("human");
- case STYLE_SYMBOLS_SIFR: return OUString("sifr");
- case STYLE_SYMBOLS_TANGO_TESTING: return OUString("tango_testing");
- }
-
- return OUString("auto");
-}
-
-// -----------------------------------------------------------------------
-
-sal_uLong StyleSettings::ImplNameToSymbolsStyle( const OUString &rName ) const
-{
- if ( rName == "default" )
- return STYLE_SYMBOLS_DEFAULT;
- else if ( rName == "hicontrast" )
- return STYLE_SYMBOLS_HICONTRAST;
- else if ( rName == "industrial" )
- return STYLE_SYMBOLS_TANGO; // industrial is dead
- else if ( rName == "crystal" )
- return STYLE_SYMBOLS_CRYSTAL;
- else if ( rName == "tango" )
- return STYLE_SYMBOLS_TANGO;
- else if ( rName == "oxygen" )
- return STYLE_SYMBOLS_OXYGEN;
- else if ( rName == "classic" )
- return STYLE_SYMBOLS_CLASSIC;
- else if ( rName == "human" )
- return STYLE_SYMBOLS_HUMAN;
- else if ( rName == "sifr" )
- return STYLE_SYMBOLS_SIFR;
- else if ( rName == "tango_testing" )
- return STYLE_SYMBOLS_TANGO_TESTING;
-
- return STYLE_SYMBOLS_AUTO;
-}
-
-// -----------------------------------------------------------------------
-
-/**
- The preferred style name can be read from the desktop setting. We
- need to find the closest theme name registered in OOo. Therefore
- we check if any registered style name is a case-insensitive
- substring of the preferred style name.
-*/
-void StyleSettings::SetPreferredSymbolsStyleName( const OUString &rName )
-{
- if ( !rName.isEmpty() )
- {
- OUString rNameLowCase( rName.toAsciiLowerCase() );
-
- for( sal_uInt32 n = 0; n <= STYLE_SYMBOLS_THEMES_MAX; n++ )
- if ( rNameLowCase.indexOf( ImplSymbolsStyleToName( n ) ) != -1 )
- SetPreferredSymbolsStyle( n );
- }
-}
-
void StyleSettings::SetCheckedColorSpecialCase( )
{
CopyData();
@@ -584,99 +516,6 @@ void StyleSettings::SetCheckedColorSpecialCase( )
}
}
-// -----------------------------------------------------------------------
-
-sal_uLong StyleSettings::GetCurrentSymbolsStyle() const
-{
- // style selected in Tools -> Options... -> LibreOffice -> View
- sal_uLong nStyle = GetSymbolsStyle();
-
- if ( nStyle == STYLE_SYMBOLS_AUTO || ( !CheckSymbolStyle (nStyle) ) )
- {
- // the preferred style can be read from the desktop setting by the desktop native widgets modules
- sal_uLong nPreferredStyle = GetPreferredSymbolsStyle();
-
- if ( nPreferredStyle == STYLE_SYMBOLS_AUTO || ( !CheckSymbolStyle (nPreferredStyle) ) )
- {
-
- // use a hardcoded desktop-specific fallback if no preferred style has been detected
- static bool sbFallbackDesktopChecked = false;
- static sal_uLong snFallbackDesktopStyle = STYLE_SYMBOLS_DEFAULT;
-
- if ( !sbFallbackDesktopChecked )
- {
- snFallbackDesktopStyle = GetAutoSymbolsStyle();
- sbFallbackDesktopChecked = true;
- }
-
- nPreferredStyle = snFallbackDesktopStyle;
- }
-
- if (GetHighContrastMode() && CheckSymbolStyle (STYLE_SYMBOLS_HICONTRAST) )
- nStyle = STYLE_SYMBOLS_HICONTRAST;
- else
- nStyle = nPreferredStyle;
- }
-
- return nStyle;
-}
-
-// -----------------------------------------------------------------------
-
-sal_uLong StyleSettings::GetAutoSymbolsStyle() const
-{
- OUString const & env = Application::GetDesktopEnvironment();
-
- sal_uLong nRet;
- if ( env.equalsIgnoreAsciiCase("tde") ||
- env.equalsIgnoreAsciiCase("kde") )
- nRet = STYLE_SYMBOLS_CRYSTAL;
- else if ( env.equalsIgnoreAsciiCase("kde4") )
- nRet = STYLE_SYMBOLS_OXYGEN;
- else
- nRet = STYLE_SYMBOLS_TANGO;
-
- // fallback to any existing style
- if ( ! CheckSymbolStyle (nRet) )
- {
- for ( sal_uLong n = 0 ; n <= STYLE_SYMBOLS_THEMES_MAX ; n++ )
- {
- sal_uLong nStyleToCheck = n;
-
- // auto is not a real theme => can't be fallback
- if ( nStyleToCheck == STYLE_SYMBOLS_AUTO )
- continue;
-
- // will check hicontrast in the end
- if ( nStyleToCheck == STYLE_SYMBOLS_HICONTRAST )
- continue;
- if ( nStyleToCheck == STYLE_SYMBOLS_THEMES_MAX )
- nStyleToCheck = STYLE_SYMBOLS_HICONTRAST;
-
- if ( CheckSymbolStyle ( nStyleToCheck ) )
- {
- nRet = nStyleToCheck;
- n = STYLE_SYMBOLS_THEMES_MAX;
- }
- }
- }
-
- return nRet;
-}
-
-// -----------------------------------------------------------------------
-
-bool StyleSettings::CheckSymbolStyle( sal_uLong nStyle ) const
-{
- if ( nStyle == STYLE_SYMBOLS_INDUSTRIAL )
- return false; // industrial is dead
-
- static ImplImageTreeSingletonRef aImageTree;
- return aImageTree->checkStyle( ImplSymbolsStyleToName( nStyle ) );
-}
-
-// -----------------------------------------------------------------------
-
bool StyleSettings::GetUseImagesInMenus() const
{
// icon mode selected in Tools -> Options... -> OpenOffice.org -> View
@@ -841,6 +680,14 @@ bool StyleSettings::operator ==( const StyleSettings& rSet ) const
if ( mpData == rSet.mpData )
return true;
+ if (mpData->mIconTheme != rSet.mpData->mIconTheme) {
+ return sal_False;
+ }
+
+ if (*mpData->mIconThemeSelector != *rSet.mpData->mIconThemeSelector) {
+ return sal_False;
+ }
+
if ( (mpData->mnOptions == rSet.mpData->mnOptions) &&
(mpData->mnAutoMnemonic == rSet.mpData->mnAutoMnemonic) &&
(mpData->mnLogoDisplayTime == rSet.mpData->mnLogoDisplayTime) &&
@@ -864,12 +711,10 @@ bool StyleSettings::operator ==( const StyleSettings& rSet ) const
(mpData->mnAntialiasedMin == rSet.mpData->mnAntialiasedMin) &&
(mpData->mnScreenZoom == rSet.mpData->mnScreenZoom) &&
(mpData->mnScreenFontZoom == rSet.mpData->mnScreenFontZoom) &&
- (mpData->mnHighContrast == rSet.mpData->mnHighContrast) &&
- (mpData->mnUseSystemUIFonts == rSet.mpData->mnUseSystemUIFonts) &&
+ (mpData->mbHighContrast == rSet.mpData->mbHighContrast) &&
+ (mpData->mbUseSystemUIFonts == rSet.mpData->mbUseSystemUIFonts) &&
(mpData->mnUseFlatBorders == rSet.mpData->mnUseFlatBorders) &&
(mpData->mnUseFlatMenus == rSet.mpData->mnUseFlatMenus) &&
- (mpData->mnSymbolsStyle == rSet.mpData->mnSymbolsStyle) &&
- (mpData->mnPreferredSymbolsStyle == rSet.mpData->mnPreferredSymbolsStyle) &&
(mpData->maFaceColor == rSet.mpData->maFaceColor) &&
(mpData->maCheckedColor == rSet.mpData->maCheckedColor) &&
(mpData->maLightColor == rSet.mpData->maLightColor) &&
@@ -931,7 +776,7 @@ bool StyleSettings::operator ==( const StyleSettings& rSet ) const
(mpData->maIconFont == rSet.mpData->maIconFont) &&
(mpData->mnUseImagesInMenus == rSet.mpData->mnUseImagesInMenus) &&
(mpData->mbPreferredUseImagesInMenus == rSet.mpData->mbPreferredUseImagesInMenus) &&
- (mpData->mnSkipDisabledInMenus == rSet.mpData->mnSkipDisabledInMenus) &&
+ (mpData->mbSkipDisabledInMenus == rSet.mpData->mbSkipDisabledInMenus) &&
(mpData->mbHideDisabledMenuItems == rSet.mpData->mbHideDisabledMenuItems) &&
(mpData->mbAcceleratorsInContextMenus == rSet.mpData->mbAcceleratorsInContextMenus)&&
(mpData->mbPrimaryButtonWarpsSlider == rSet.mpData->mbPrimaryButtonWarpsSlider) &&
@@ -1635,4 +1480,62 @@ StyleSettings::GetOptions() const
return mpData->mnOptions;
}
+std::vector<vcl::IconThemeInfo>
+StyleSettings::GetInstalledIconThemes() const
+{
+ return mpData->mIconThemeScanner->GetFoundIconThemes();
+}
+
+/*static*/ OUString
+StyleSettings::GetAutomaticallyChosenIconTheme() const
+{
+ OUString desktopEnvironment = Application::GetDesktopEnvironment();
+ OUString themeName = mpData->mIconThemeSelector->SelectIconThemeForDesktopEnvironment(
+ mpData->mIconThemeScanner->GetFoundIconThemes(),
+ desktopEnvironment
+ );
+ return themeName;
+}
+
+void
+StyleSettings::SetIconTheme(const OUString& theme)
+{
+ CopyData();
+ mpData->mIconTheme = theme;
+}
+
+OUString
+StyleSettings::DetermineIconTheme() const
+{
+ OUString r = mpData->mIconThemeSelector->SelectIconTheme(
+ mpData->mIconThemeScanner->GetFoundIconThemes(),
+ mpData->mIconTheme
+ );
+ return r;
+}
+
+void
+StyleSettings::SetHighContrastMode(bool bHighContrast )
+{
+ if (mpData->mbHighContrast == bHighContrast) {
+ return;
+ }
+
+ CopyData();
+ mpData->mbHighContrast = bHighContrast;
+ mpData->mIconThemeSelector->SetUseHighContrastTheme(bHighContrast);
+}
+
+bool
+StyleSettings::GetHighContrastMode() const
+{
+ return mpData->mbHighContrast;
+}
+
+void
+StyleSettings::SetPreferredIconTheme(const OUString& theme)
+{
+ mpData->mIconThemeSelector->SetPreferredIconTheme(theme);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
index fe988dd0637c..695d3ae6b8e7 100644
--- a/vcl/source/control/fixed.cxx
+++ b/vcl/source/control/fixed.cxx
@@ -1210,13 +1210,13 @@ const Image& FixedImage::GetModeImage( ) const
Image FixedImage::loadThemeImage(const OString &rFileName)
{
static ImplImageTreeSingletonRef aImageTree;
- OUString sCurrentSymbolsStyle =
- Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+ OUString sIconTheme =
+ Application::GetSettings().GetStyleSettings().DetermineIconTheme();
const OUString sFileName(OStringToOUString(rFileName, RTL_TEXTENCODING_UTF8));
BitmapEx aBitmap;
- bool bSuccess = aImageTree->loadImage(sFileName, sCurrentSymbolsStyle, aBitmap, true);
+ bool bSuccess = aImageTree->loadImage(sFileName, sIconTheme, aBitmap, true);
SAL_WARN_IF(!bSuccess, "vcl.layout", "Unable to load " << sFileName
- << " from theme " << sCurrentSymbolsStyle);
+ << " from theme " << sIconTheme);
return Image(aBitmap);
}
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index a8b287724478..0e9cd05d7abc 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -96,9 +96,9 @@ BitmapEx::BitmapEx( const ResId& rResId ) :
pResMgr->ReadLong();
const OUString aFileName( pResMgr->ReadString() );
- OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+ OUString aIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
- if( !aImageTree->loadImage( aFileName, aCurrentSymbolsStyle, *this, true ) )
+ if( !aImageTree->loadImage( aFileName, aIconTheme, *this, true ) )
{
#ifdef DBG_UTIL
OStringBuffer aErrorStr(
diff --git a/vcl/source/gdi/image.cxx b/vcl/source/gdi/image.cxx
index 8400942651a5..77dd01ee1fdb 100644
--- a/vcl/source/gdi/image.cxx
+++ b/vcl/source/gdi/image.cxx
@@ -379,7 +379,7 @@ void ImageAryData::Load(const OUString &rPrefix)
{
static ImplImageTreeSingletonRef aImageTree;
- OUString aSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+ OUString aIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
BitmapEx aBmpEx;
@@ -388,7 +388,7 @@ void ImageAryData::Load(const OUString &rPrefix)
#if OSL_DEBUG_LEVEL > 0
bool bSuccess =
#endif
- aImageTree->loadImage( aFileName, aSymbolsStyle, maBitmapEx, true );
+ aImageTree->loadImage( aFileName, aIconTheme, maBitmapEx, true );
#if OSL_DEBUG_LEVEL > 0
if ( !bSuccess )
{
diff --git a/vcl/source/gdi/imagerepository.cxx b/vcl/source/gdi/imagerepository.cxx
index 43ee86e58764..f83981ecd22e 100644
--- a/vcl/source/gdi/imagerepository.cxx
+++ b/vcl/source/gdi/imagerepository.cxx
@@ -28,17 +28,17 @@ namespace vcl
{
bool ImageRepository::loadImage( const OUString& _rName, BitmapEx& _out_rImage, bool _bSearchLanguageDependent, bool loadMissing )
{
- OUString sCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+ OUString sIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
ImplImageTreeSingletonRef aImplImageTree;
- return aImplImageTree->loadImage( _rName, sCurrentSymbolsStyle, _out_rImage, _bSearchLanguageDependent, loadMissing );
+ return aImplImageTree->loadImage( _rName, sIconTheme, _out_rImage, _bSearchLanguageDependent, loadMissing );
}
bool ImageRepository::loadDefaultImage( BitmapEx& _out_rImage)
{
- OUString sCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+ OUString sIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
ImplImageTreeSingletonRef aImplImageTree;
- return aImplImageTree->loadDefaultImage( sCurrentSymbolsStyle,_out_rImage);
+ return aImplImageTree->loadDefaultImage( sIconTheme,_out_rImage);
}
} // namespace vcl
diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx
index 9c5667a96209..72039beca9bc 100644
--- a/vcl/source/window/toolbox2.cxx
+++ b/vcl/source/window/toolbox2.cxx
@@ -32,6 +32,7 @@
#include <vcl/menu.hxx>
#include <vcl/ImageListProvider.hxx>
#include <vcl/settings.hxx>
+#include <vcl/IconThemeInfo.hxx>
#include <svdata.hxx>
#include <brdwin.hxx>
@@ -995,42 +996,19 @@ ToolBoxButtonSize ToolBox::GetToolboxButtonSize() const
// -----------------------------------------------------------------------
-const Size& ToolBox::GetDefaultImageSize(bool bLarge)
+/*static*/ Size
+ToolBox::GetDefaultImageSize(bool bLarge)
{
- static Size aSmallButtonSize( TB_SMALLIMAGESIZE, TB_SMALLIMAGESIZE );
-
- static sal_uLong s_nSymbolsStyle = STYLE_SYMBOLS_DEFAULT;
- static Size aLargeButtonSize( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE );
-
- sal_uLong nSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyle();
- if ( s_nSymbolsStyle != nSymbolsStyle )
- {
- s_nSymbolsStyle = nSymbolsStyle;
- switch ( nSymbolsStyle )
- {
- case STYLE_SYMBOLS_TANGO:
- case STYLE_SYMBOLS_TANGO_TESTING:
- case STYLE_SYMBOLS_HUMAN:
- case STYLE_SYMBOLS_INDUSTRIAL:
- aLargeButtonSize = Size( TB_LARGEIMAGESIZE_INDUSTRIAL, TB_LARGEIMAGESIZE_INDUSTRIAL );
- break;
- case STYLE_SYMBOLS_CRYSTAL:
- aLargeButtonSize = Size( TB_LARGEIMAGESIZE_CRYSTAL, TB_LARGEIMAGESIZE_CRYSTAL );
- break;
- case STYLE_SYMBOLS_OXYGEN:
- aLargeButtonSize = Size( TB_LARGEIMAGESIZE_OXYGEN, TB_LARGEIMAGESIZE_OXYGEN );
- break;
- case STYLE_SYMBOLS_DEFAULT: // galaxy
- case STYLE_SYMBOLS_HICONTRAST:
- default:
- aLargeButtonSize = Size( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE );
- }
+ const long TB_SMALLIMAGESIZE = 16;
+ if (!bLarge) {
+ return Size(TB_SMALLIMAGESIZE, TB_SMALLIMAGESIZE);
}
- return bLarge ? aLargeButtonSize : aSmallButtonSize;
+ OUString iconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
+ return vcl::IconThemeInfo::SizeByThemeName(iconTheme);
}
-const Size& ToolBox::GetDefaultImageSize() const
+Size ToolBox::GetDefaultImageSize() const
{
return GetDefaultImageSize( GetToolboxButtonSize() == TOOLBOX_BUTTONSIZE_LARGE );
}
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index ed057f78fcd5..8a3f00645e13 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -661,7 +661,6 @@ void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, bool bCallHdl )
{
aStyleSettings = rSettings.GetStyleSettings();
aStyleSettings.SetHighContrastMode( true );
- aStyleSettings.SetSymbolsStyle( STYLE_SYMBOLS_HICONTRAST );
rSettings.SetStyleSettings( aStyleSettings );
}
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index 6056a84e0f7a..4ae67fef72a2 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -4082,7 +4082,7 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
// preferred icon style
gchar* pIconThemeName = NULL;
g_object_get( pSettings, "gtk-icon-theme-name", &pIconThemeName, (char *)NULL );
- aStyleSet.SetPreferredSymbolsStyleName( OUString::createFromAscii( pIconThemeName ) );
+ aStyleSet.SetPreferredIconTheme( OUString::createFromAscii( pIconThemeName ) );
g_free( pIconThemeName );
aStyleSet.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_LARGE );
diff --git a/vcl/unx/kde/salnativewidgets-kde.cxx b/vcl/unx/kde/salnativewidgets-kde.cxx
index 86096366d563..378930a3202b 100644
--- a/vcl/unx/kde/salnativewidgets-kde.cxx
+++ b/vcl/unx/kde/salnativewidgets-kde.cxx
@@ -1884,7 +1884,7 @@ void KDESalFrame::UpdateSettings( AllSettings& rSettings )
pKey = "Theme";
if ( pConfig->hasKey( pKey ) )
- aStyleSettings.SetPreferredSymbolsStyleName( readEntryUntranslated( pConfig, pKey ) );
+ aStyleSettings.SetPreferredIconTheme( readEntryUntranslated( pConfig, pKey ) );
}
// General settings