[Xfce4-commits] [apps/xfdashboard] 02/02: Split creation and handling of tab 'Themes' into seperate files at xfdashboard settings application

noreply at xfce.org noreply at xfce.org
Mon Feb 15 19:46:14 CET 2016


This is an automated email from the git hooks/post-receive script.

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit 57b4bc4642436108218ccff65a0f69004d22fef4
Author: Stephan Haller <nomad at froevel.de>
Date:   Mon Feb 15 15:07:53 2016 +0100

    Split creation and handling of tab 'Themes' into seperate files at xfdashboard settings application
---
 settings/Makefile.am |   6 +-
 settings/settings.c  | 780 ++---------------------------------------
 settings/themes.c    | 963 +++++++++++++++++++++++++++++++++++++++++++++++++++
 settings/themes.h    |  68 ++++
 4 files changed, 1062 insertions(+), 755 deletions(-)

diff --git a/settings/Makefile.am b/settings/Makefile.am
index 608f27e..df1d728 100644
--- a/settings/Makefile.am
+++ b/settings/Makefile.am
@@ -9,12 +9,14 @@ bin_PROGRAMS = \
 	xfdashboard-settings
 
 xfdashboard_settings_headers = \
-	settings.h
+	settings.h \
+	themes.h
 
 xfdashboard_settings_SOURCES = \
 	$(xfdashboard_settings_headers) \
 	main.c \
-	settings.c
+	settings.c \
+	themes.c
 
 xfdashboard_settings_CFLAGS = \
 	$(GTK_CFLAGS) \
diff --git a/settings/settings.c b/settings/settings.c
index 1762979..334b712 100644
--- a/settings/settings.c
+++ b/settings/settings.c
@@ -31,6 +31,9 @@
 #include <xfconf/xfconf.h>
 #include <math.h>
 
+#include "themes.h"
+
+
 /* Define this class in GObject system */
 G_DEFINE_TYPE(XfdashboardSettings,
 				xfdashboard_settings,
@@ -43,31 +46,25 @@ G_DEFINE_TYPE(XfdashboardSettings,
 struct _XfdashboardSettingsPrivate
 {
 	/* Instance related */
-	XfconfChannel	*xfconfChannel;
-
-	GtkBuilder		*builder;
-	GtkWidget		*widgetCloseButton;
-	GtkWidget		*widgetResetSearchOnResume;
-	GtkWidget		*widgetSwitchViewOnResume;
-	GtkWidget		*widgetNotificationTimeout;
-	GtkWidget		*widgetEnableUnmappedWindowWorkaround;
-	GtkWidget		*widgetWindowCreationPriority;
-	GtkWidget		*widgetAlwaysLaunchNewInstance;
-	GtkWidget		*widgetShowAllApps;
-	GtkWidget		*widgetScrollEventChangedWorkspace;
-	GtkWidget		*widgetDelaySearchTimeout;
-	GtkWidget		*widgetThemes;
-	GtkWidget		*widgetThemeScreenshot;
-	GtkWidget		*widgetThemeNameLabel;
-	GtkWidget		*widgetThemeName;
-	GtkWidget		*widgetThemeAuthorLabel;
-	GtkWidget		*widgetThemeAuthor;
-	GtkWidget		*widgetThemeVersionLabel;
-	GtkWidget		*widgetThemeVersion;
-	GtkWidget		*widgetThemeDescriptionLabel;
-	GtkWidget		*widgetThemeDescription;
+	XfconfChannel				*xfconfChannel;
+
+	GtkBuilder					*builder;
+
+	GtkWidget					*widgetCloseButton;
+	GtkWidget					*widgetResetSearchOnResume;
+	GtkWidget					*widgetSwitchViewOnResume;
+	GtkWidget					*widgetNotificationTimeout;
+	GtkWidget					*widgetEnableUnmappedWindowWorkaround;
+	GtkWidget					*widgetWindowCreationPriority;
+	GtkWidget					*widgetAlwaysLaunchNewInstance;
+	GtkWidget					*widgetShowAllApps;
+	GtkWidget					*widgetScrollEventChangedWorkspace;
+	GtkWidget					*widgetDelaySearchTimeout;
+
+	XfdashboardSettingsThemes	*themes;
 };
 
+
 /* IMPLEMENTATION: Private variables and methods */
 #define XFDASHBOARD_XFCONF_CHANNEL					"xfdashboard"
 #define PREFERENCES_UI_FILE							"preferences.ui"
@@ -115,19 +112,6 @@ static XfdashboardSettingsWindowContentPriority	windowCreationPriorities[]=
 	{ NULL, NULL },
 };
 
-enum
-{
-	COLUMN_THEME_NAME,
-	COLUMN_THEME_FILE,
-
-	COLUMN_THEME_DISPLAY_NAME,
-	COLUMN_THEME_AUTHORS,
-	COLUMN_THEME_VERSION,
-	COLUMN_THEME_DESCRIPTION,
-	COLUMN_THEME_SCREENSHOTS,
-
-	COLUMN_THEME_LAST
-};
 
 /* Setting '/switch-to-view-on-resume' changed either at widget or at xfconf property */
 static void _xfdashboard_settings_widget_changed_switch_view_on_resume(XfdashboardSettings *self, GtkComboBox *inComboBox)
@@ -371,640 +355,6 @@ static gchar* _xfdashboard_settings_on_format_delay_search_timeout_value(GtkScal
 }
 
 
-/* Setting '/theme' changed either at widget or at xfconf property */
-static void _xfdashboard_settings_widget_changed_theme(XfdashboardSettings *self, GtkTreeSelection *inSelection)
-{
-	XfdashboardSettingsPrivate		*priv;
-	GtkTreeModel					*model;
-	GtkTreeIter						iter;
-	gchar							*themeDisplayName;
-	gchar							*themeComment;
-	gchar							*themeAuthor;
-	gchar							*themeVersion;
-	gchar							*themeScreenshot;
-	gchar							*themeFilename;
-	gchar							*themeName;
-
-	g_return_if_fail(XFDASHBOARD_IS_SETTINGS(self));
-	g_return_if_fail(GTK_IS_TREE_SELECTION(inSelection));
-
-	priv=self->priv;
-	themeDisplayName=NULL;
-	themeComment=NULL;
-	themeAuthor=NULL;
-	themeVersion=NULL;
-	themeScreenshot=NULL;
-	themeFilename=NULL;
-	themeName=NULL;
-
-	/* Get selected entry from widget */
-	if(gtk_tree_selection_get_selected(inSelection, &model, &iter))
-	{
-		/* Get data from model */
-		gtk_tree_model_get(model,
-							&iter,
-							COLUMN_THEME_NAME, &themeName,
-							COLUMN_THEME_FILE, &themeFilename,
-							COLUMN_THEME_DISPLAY_NAME, &themeDisplayName,
-							COLUMN_THEME_DESCRIPTION, &themeComment,
-							COLUMN_THEME_AUTHORS, &themeAuthor,
-							COLUMN_THEME_VERSION, &themeVersion,
-							COLUMN_THEME_SCREENSHOTS, &themeScreenshot,
-							-1);
-	}
-
-	/* Set text in labels */
-	if(themeDisplayName)
-	{
-		gtk_label_set_text(GTK_LABEL(priv->widgetThemeName), themeDisplayName);
-		gtk_widget_show(priv->widgetThemeName);
-		gtk_widget_show(priv->widgetThemeNameLabel);
-	}
-		else
-		{
-			gtk_widget_hide(priv->widgetThemeName);
-			gtk_widget_hide(priv->widgetThemeNameLabel);
-		}
-
-	if(themeComment)
-	{
-		gtk_label_set_text(GTK_LABEL(priv->widgetThemeDescription), themeComment);
-		gtk_widget_show(priv->widgetThemeDescription);
-		gtk_widget_show(priv->widgetThemeDescriptionLabel);
-	}
-		else
-		{
-			gtk_widget_hide(priv->widgetThemeDescription);
-			gtk_widget_hide(priv->widgetThemeDescriptionLabel);
-		}
-
-	if(themeAuthor)
-	{
-		gtk_label_set_text(GTK_LABEL(priv->widgetThemeAuthor), themeAuthor);
-		gtk_widget_show(priv->widgetThemeAuthor);
-		gtk_widget_show(priv->widgetThemeAuthorLabel);
-	}
-		else
-		{
-			gtk_widget_hide(priv->widgetThemeAuthor);
-			gtk_widget_hide(priv->widgetThemeAuthorLabel);
-		}
-
-	if(themeVersion)
-	{
-		gtk_label_set_text(GTK_LABEL(priv->widgetThemeVersion), themeVersion);
-		gtk_widget_show(priv->widgetThemeVersion);
-		gtk_widget_show(priv->widgetThemeVersionLabel);
-	}
-		else
-		{
-			gtk_widget_hide(priv->widgetThemeVersion);
-			gtk_widget_hide(priv->widgetThemeVersionLabel);
-		}
-
-	/* Set screenshot */
-	if(themeScreenshot)
-	{
-		gchar						*screenshotFile;
-		GdkPixbuf					*screenshotImage;
-
-		screenshotFile=NULL;
-		screenshotImage=NULL;
-
-		/* Get screenshot file but resolve relative path if needed */
-		if(!g_path_is_absolute(themeScreenshot))
-		{
-			GFile					*file;
-			GFile					*parentPath;
-			gchar					*themePath;
-
-			file=NULL;
-			parentPath=NULL;
-			themePath=NULL;
-
-			/* Resolve relative path relative to theme path */
-			file=g_file_new_for_path(themeFilename);
-			if(file) parentPath=g_file_get_parent(file);
-			if(parentPath) themePath=g_file_get_path(parentPath);
-			if(themePath) screenshotFile=g_build_filename(themePath, themeScreenshot, NULL);
-
-			/* Release allocated resources */
-			if(themePath) g_free(themePath);
-			if(parentPath) g_object_unref(parentPath);
-			if(file) g_object_unref(file);
-		}
-			else
-			{
-				/* Path is absolute so just create a copy */
-				screenshotFile=g_strdup(themeScreenshot);
-			}
-
-		/* If screenshot file exists set up and show image
-		 * otherwise hide image.
-		 */
-		if(screenshotFile &&
-			g_file_test(screenshotFile, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
-		{
-			GError					*error;
-			gint					width;
-			gint					height;
-
-			error=NULL;
-
-			/* Check if screenshot fits into widget without scaling or
-			 * scale it to maximum size but preserve aspect ratio.
-			 */
-			if(gdk_pixbuf_get_file_info(screenshotFile, &width, &height))
-			{
-				if(width<MAX_SCREENSHOT_WIDTH)
-				{
-					screenshotImage=gdk_pixbuf_new_from_file(screenshotFile,
-																&error);
-				}
-					else
-					{
-						screenshotImage=gdk_pixbuf_new_from_file_at_scale(screenshotFile,
-																			MAX_SCREENSHOT_WIDTH,
-																			-1,
-																			TRUE,
-																			&error);
-					}
-
-				if(error)
-				{
-					g_warning("Could not load screenshot: %s",
-								error ? error->message : _("Unknown error"));
-
-					/* Release allocated resources */
-					if(error) g_error_free(error);
-					if(screenshotImage)
-					{
-						g_object_unref(screenshotImage);
-						screenshotImage=NULL;
-					}
-				}
-			}
-		}
-
-		if(screenshotImage)
-		{
-			gtk_image_set_from_pixbuf(GTK_IMAGE(priv->widgetThemeScreenshot), screenshotImage);
-			gtk_widget_show(priv->widgetThemeScreenshot);
-		}
-			else
-			{
-				gtk_widget_hide(priv->widgetThemeScreenshot);
-			}
-
-		/* Release allocated resources */
-		if(screenshotImage) g_object_unref(screenshotImage);
-		if(screenshotFile) g_free(screenshotFile);
-	}
-		else
-		{
-			gtk_widget_hide(priv->widgetThemeScreenshot);
-		}
-
-	/* Set value at xfconf property if it must be changed */
-	if(themeName)
-	{
-		gchar						*currentTheme;
-
-		currentTheme=xfconf_channel_get_string(priv->xfconfChannel, "/theme", DEFAULT_THEME);
-		if(g_strcmp0(currentTheme, themeName))
-		{
-			xfconf_channel_set_string(priv->xfconfChannel, "/theme", themeName);
-		}
-		g_free(currentTheme);
-	}
-
-	/* Release allocated resources */
-	if(themeDisplayName) g_free(themeDisplayName);
-	if(themeComment) g_free(themeComment);
-	if(themeAuthor) g_free(themeAuthor);
-	if(themeVersion) g_free(themeVersion);
-	if(themeScreenshot) g_free(themeScreenshot);
-	if(themeFilename) g_free(themeFilename);
-	if(themeName) g_free(themeName);
-}
-
-static void _xfdashboard_settings_xfconf_changed_theme(XfdashboardSettings *self,
-														const gchar *inProperty,
-														const GValue *inValue,
-														XfconfChannel *inChannel)
-{
-	XfdashboardSettingsPrivate		*priv;
-	const gchar						*newValue;
-	GtkTreeModel					*model;
-	GtkTreeIter						iter;
-	gboolean						selectionFound;
-
-	g_return_if_fail(XFDASHBOARD_IS_SETTINGS(self));
-	g_return_if_fail(inValue);
-	g_return_if_fail(XFCONF_IS_CHANNEL(inChannel));
-
-	priv=self->priv;
-	newValue=DEFAULT_THEME;
-
-	/* Get new value to set at widget */
-	if(G_LIKELY(G_VALUE_TYPE(inValue)==G_TYPE_STRING)) newValue=g_value_get_string(inValue);
-
-	/* Iterate through themes' model and lookup matching item
-	 * against new theme name and select it
-	 */
-	selectionFound=FALSE;
-	model=gtk_tree_view_get_model(GTK_TREE_VIEW(priv->widgetThemes));
-	if(newValue && gtk_tree_model_get_iter_first(model, &iter))
-	{
-		do
-		{
-			gchar					*value;
-
-			gtk_tree_model_get(model,
-								&iter,
-								COLUMN_THEME_NAME, &value,
-								-1);
-			if(G_UNLIKELY(g_str_equal(value, newValue)))
-			{
-				GtkTreePath			*selectionPath;
-
-				selectionPath=gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
-				gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->widgetThemes)), &iter);
-				gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(priv->widgetThemes), selectionPath, NULL, TRUE, 0.5, 0.5);
-				gtk_tree_path_free(selectionPath);
-
-				selectionFound=TRUE;
-			}
-			g_free(value);
-		}
-		while(!selectionFound && gtk_tree_model_iter_next(model, &iter));
-	}
-
-	/* If no selection was found, deselect any selected entry at widget */
-	if(!selectionFound)
-	{
-		GtkTreeSelection			*selection;
-
-		selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->widgetThemes));
-		gtk_tree_selection_unselect_all(selection);
-	}
-}
-
-/* Sorting function for theme list's model */
-static gint _xfdashboard_settings_sort_themes_list_model(GtkTreeModel *inModel,
-															GtkTreeIter *inLeft,
-															GtkTreeIter *inRight)
-{
-	gchar	*leftName;
-	gchar	*rightName;
-	gint	result;
-
-	/* Get theme names from model */
-	leftName=NULL;
-	gtk_tree_model_get(inModel, inLeft, 0, &leftName, -1);
-	if(!leftName) leftName=g_strdup("");
-
-	rightName=NULL;
-	gtk_tree_model_get(inModel, inRight, 0, &rightName, -1);
-	if(!rightName) rightName=g_strdup("");
-
-	result=g_utf8_collate(leftName, rightName);
-
-	/* Release allocated resources */
-	if(leftName) g_free(leftName);
-	if(rightName) g_free(rightName);
-
-	/* Return sorting result */
-	return(result);
-}
-
-/* Populate list of available themes */
-static void _xfdashboard_settings_populate_themes_list(XfdashboardSettings *self,
-														GtkWidget *inWidget)
-{
-	GHashTable						*themes;
-	GArray							*themesPaths;
-	GDir							*directory;
-	GtkListStore					*model;
-	GtkTreeIter						iter;
-	guint							i;
-
-	g_return_if_fail(XFDASHBOARD_IS_SETTINGS(self));
-	g_return_if_fail(GTK_IS_TREE_VIEW(inWidget));
-
-	/* Create hash-table to keep track of duplicates (e.g. user overrides standard themes) */
-	themes=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-
-	/* Get model of widget to fill */
-	model=gtk_list_store_new(COLUMN_THEME_LAST,
-								G_TYPE_STRING, /* COLUMN_THEME_NAME */
-								G_TYPE_STRING, /* COLUMN_THEME_FILE */
-								G_TYPE_STRING, /* COLUMN_THEME_DISPLAY_NAME */
-								G_TYPE_STRING, /* COLUMN_THEME_AUTHORS */
-								G_TYPE_STRING, /* COLUMN_THEME_VERSION */
-								G_TYPE_STRING, /* COLUMN_THEME_DESCRIPTION */
-								G_TYPE_STRING  /* COLUMN_THEME_SCREENSHOTS */
-							);
-	gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model),
-									COLUMN_THEME_DISPLAY_NAME,
-									(GtkTreeIterCompareFunc)_xfdashboard_settings_sort_themes_list_model,
-									NULL,
-									NULL);
-	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
-											COLUMN_THEME_DISPLAY_NAME,
-											GTK_SORT_ASCENDING);
-
-	/* Get paths to iterate through to find themes */
-	themesPaths=g_array_new(TRUE, TRUE, sizeof(gchar*));
-	if(themesPaths)
-	{
-		gchar						*themePath;
-		const gchar					*homeDirectory;
-
-		/* First add user's data dir */
-		themePath=g_build_filename(g_get_user_data_dir(), "themes", NULL);
-		g_array_append_val(themesPaths, themePath);
-		g_debug("Adding to theme search path: %s", themePath);
-
-		/* Then add user's home directory */
-		homeDirectory=g_get_home_dir();
-		if(homeDirectory)
-		{
-			themePath=g_build_filename(homeDirectory, ".themes", NULL);
-			g_array_append_val(themesPaths, themePath);
-			g_debug("Adding to theme search path: %s", themePath);
-		}
-
-		/* At last add system-wide path */
-		themePath=g_build_filename(PACKAGE_DATADIR, "themes", NULL);
-		g_array_append_val(themesPaths, themePath);
-		g_debug("Adding to theme search path: %s", themePath);
-	}
-
-	/* Iterate through all themes at all theme paths */
-	for(i=0; i<themesPaths->len; ++i)
-	{
-		const gchar					*themePath;
-		const gchar					*themeName;
-
-		/* Get theme path to iterate through */
-		themePath=g_array_index(themesPaths, const gchar*, i);
-
-		/* Open handle to directory to iterate through
-		 * but skip NULL paths or directory objects
-		 */
-		directory=g_dir_open(themePath, 0, NULL);
-		if(G_UNLIKELY(directory==NULL)) continue;
-
-		/* Iterate through directory and find available themes */
-		while((themeName=g_dir_read_name(directory)))
-		{
-			gchar					*themeIndexFile;
-			GKeyFile				*themeKeyFile;
-			GError					*error;
-			gchar					*themeDisplayName;
-			gchar					*themeComment;
-			gchar					**themeAuthors;
-			gchar					*realThemeAuthor;
-			gchar					*themeVersion;
-			gchar					**themeScreenshots;
-			gchar					*realThemeScreenshot;
-
-			error=NULL;
-			themeDisplayName=NULL;
-			themeComment=NULL;
-			themeAuthors=NULL;
-			themeVersion=NULL;
-			themeScreenshots=NULL;
-			realThemeAuthor=NULL;
-			realThemeScreenshot=NULL;
-
-			/* Check if theme description file exists and add it if there is no theme
-			 * with same name.
-			 */
-			themeIndexFile=g_build_filename(themePath, themeName, XFDASHBOARD_THEME_SUBPATH, XFDASHBOARD_THEME_FILE, NULL);
-			if(!g_file_test(themeIndexFile, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
-			{
-				g_debug("Invalid theme '%s': Missing theme index file at %s",
-							themeName,
-							themeIndexFile);
-
-				/* Release allocated resources */
-				if(themeIndexFile) g_free(themeIndexFile);
-
-				/* Continue with next entry */
-				continue;
-			}
-
-			if(g_hash_table_lookup(themes, themeName))
-			{
-				g_debug("Invalid theme '%s': Duplicate theme at %s",
-							themeName,
-							themeIndexFile);
-
-				/* Release allocated resources */
-				if(themeIndexFile) g_free(themeIndexFile);
-
-				/* Continue with next entry */
-				continue;
-			}
-
-			/* Get theme file to retrieve data of it */
-			themeKeyFile=g_key_file_new();
-			if(!g_key_file_load_from_file(themeKeyFile,
-											themeIndexFile,
-											G_KEY_FILE_NONE,
-											&error))
-			{
-				g_warning("Invalid theme '%s' at %s: %s",
-							themeName,
-							themeIndexFile,
-							error ? error->message : _("Unknown error"));
-
-				/* Release allocated resources */
-				if(error) g_error_free(error);
-				if(themeKeyFile) g_key_file_free(themeKeyFile);
-				if(themeIndexFile) g_free(themeIndexFile);
-
-				/* Continue with next entry */
-				continue;
-			}
-
-			/* Check if theme is valid by checking if all essential
-			 * keys are defined: Name, Comment, Style and Layout
-			 */
-			if(!g_key_file_has_key(themeKeyFile,
-									XFDASHBOARD_THEME_GROUP,
-									"Name",
-									&error))
-			{
-				g_warning("Invalid theme '%s' at %s: %s",
-							themeName,
-							themeIndexFile,
-							error ? error->message : _("Unknown error"));
-
-				/* Release allocated resources */
-				if(error) g_error_free(error);
-				if(themeKeyFile) g_key_file_free(themeKeyFile);
-				if(themeIndexFile) g_free(themeIndexFile);
-
-				/* Continue with next entry */
-				continue;
-			}
-
-			if(!g_key_file_has_key(themeKeyFile,
-									XFDASHBOARD_THEME_GROUP,
-									"Comment",
-									&error))
-			{
-				g_warning("Invalid theme '%s' at %s: %s",
-							themeName,
-							themeIndexFile,
-							error ? error->message : _("Unknown error"));
-
-				/* Release allocated resources */
-				if(error) g_error_free(error);
-				if(themeKeyFile) g_key_file_free(themeKeyFile);
-				if(themeIndexFile) g_free(themeIndexFile);
-
-				/* Continue with next entry */
-				continue;
-			}
-
-			if(!g_key_file_has_key(themeKeyFile,
-									XFDASHBOARD_THEME_GROUP,
-									"Style",
-									&error))
-			{
-				g_warning("Invalid theme '%s' at %s: %s",
-							themeName,
-							themeIndexFile,
-							error ? error->message : _("Unknown error"));
-
-				/* Release allocated resources */
-				if(error) g_error_free(error);
-				if(themeKeyFile) g_key_file_free(themeKeyFile);
-				if(themeIndexFile) g_free(themeIndexFile);
-
-				/* Continue with next entry */
-				continue;
-			}
-
-			if(!g_key_file_has_key(themeKeyFile,
-									XFDASHBOARD_THEME_GROUP,
-									"Layout",
-									&error))
-			{
-				g_warning("Invalid theme '%s' at %s: %s",
-							themeName,
-							themeIndexFile,
-							error ? error->message : _("Unknown error"));
-
-				/* Release allocated resources */
-				if(error) g_error_free(error);
-				if(themeKeyFile) g_key_file_free(themeKeyFile);
-				if(themeIndexFile) g_free(themeIndexFile);
-
-				/* Continue with next entry */
-				continue;
-			}
-
-			/* Theme is valid so get theme data which includes
-			 * optional field: Author, Version and Screenshot
-			 */
-			themeDisplayName=g_key_file_get_locale_string(themeKeyFile,
-															XFDASHBOARD_THEME_GROUP,
-															"Name",
-															NULL,
-															NULL);
-
-			themeComment=g_key_file_get_locale_string(themeKeyFile,
-															XFDASHBOARD_THEME_GROUP,
-															"Comment",
-															NULL,
-															NULL);
-
-			themeAuthors=g_key_file_get_string_list(themeKeyFile,
-													XFDASHBOARD_THEME_GROUP,
-													"Author",
-													NULL,
-													NULL);
-			if(themeAuthors)
-			{
-				/* Replace list of string with authors with one string
-				 * containing all authors seperated by new-line.
-				 */
-				realThemeAuthor=g_strjoinv("\n", themeAuthors);
-			}
-
-			themeVersion=g_key_file_get_string(themeKeyFile,
-												XFDASHBOARD_THEME_GROUP,
-												"Version",
-												NULL);
-
-			themeScreenshots=g_key_file_get_string_list(themeKeyFile,
-														XFDASHBOARD_THEME_GROUP,
-														"Screenshot",
-														NULL,
-														NULL);
-			if(themeScreenshots)
-			{
-				/* Replace list of string with filenames to screenshots
-				 * with one string containing the first screenshot's filename.
-				 */
-				realThemeScreenshot=g_strdup(themeScreenshots[0]);
-			}
-
-			/* Add to widget's list */
-			gtk_list_store_append(GTK_LIST_STORE(model), &iter);
-			gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-								COLUMN_THEME_NAME, themeName,
-								COLUMN_THEME_FILE, themeIndexFile,
-								COLUMN_THEME_DISPLAY_NAME, themeDisplayName,
-								COLUMN_THEME_AUTHORS, realThemeAuthor,
-								COLUMN_THEME_VERSION, themeVersion,
-								COLUMN_THEME_DESCRIPTION, themeComment,
-								COLUMN_THEME_SCREENSHOTS, realThemeScreenshot,
-								-1);
-
-			/* Remember theme to avoid duplicates (and allow overrides by user */
-			g_hash_table_insert(themes, g_strdup(themeName), GINT_TO_POINTER(1));
-			g_debug("Added theme '%s' from %s", themeName, themeIndexFile);
-
-			/* Release allocated resources */
-			if(realThemeAuthor) g_free(realThemeAuthor);
-			if(realThemeScreenshot) g_free(realThemeScreenshot);
-			if(themeDisplayName) g_free(themeDisplayName);
-			if(themeComment) g_free(themeComment);
-			if(themeAuthors) g_strfreev(themeAuthors);
-			if(themeVersion) g_free(themeVersion);
-			if(themeScreenshots) g_strfreev(themeScreenshots);
-			if(themeKeyFile) g_key_file_free(themeKeyFile);
-			if(themeIndexFile) g_free(themeIndexFile);
-		}
-
-		/* Close handle to directory */
-		g_dir_close(directory);
-	}
-
-	/* Set new list store at widget */
-	gtk_tree_view_set_model(GTK_TREE_VIEW(inWidget), GTK_TREE_MODEL(model));
-	g_object_unref(model);
-
-	/* Release allocated resources */
-	if(themesPaths)
-	{
-		for(i=0; i<themesPaths->len; ++i)
-		{
-			gchar						*themePath;
-
-			themePath=g_array_index(themesPaths, gchar*, i);
-			g_free(themePath);
-		}
-		g_array_free(themesPaths, TRUE);
-	}
-	if(themes) g_hash_table_destroy(themes);
-}
 
 /* Close button was clicked */
 static void _xfdashboard_settings_on_close_clicked(XfdashboardSettings *self,
@@ -1326,69 +676,7 @@ static gboolean _xfdashboard_settings_create_builder(XfdashboardSettings *self)
 	}
 
 	/* Tab: Themes */
-	priv->widgetThemeScreenshot=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-screenshot"));
-	priv->widgetThemeNameLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-name-label"));
-	priv->widgetThemeName=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-name"));
-	priv->widgetThemeAuthorLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-author-label"));
-	priv->widgetThemeAuthor=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-author"));
-	priv->widgetThemeVersionLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-version-label"));
-	priv->widgetThemeVersion=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-version"));
-	priv->widgetThemeDescriptionLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-description-label"));
-	priv->widgetThemeDescription=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-description"));
-
-	priv->widgetThemes=GTK_WIDGET(gtk_builder_get_object(priv->builder, "themes"));
-	if(priv->widgetThemes)
-	{
-		gchar								*currentTheme;
-		GValue								defaultValue=G_VALUE_INIT;
-		GtkTreeSelection					*selection;
-		GtkCellRenderer						*renderer;
-
-		/* Get default value */
-		currentTheme=xfconf_channel_get_string(priv->xfconfChannel, "/theme", DEFAULT_THEME);
-		g_value_init(&defaultValue, G_TYPE_STRING);
-		g_value_set_string(&defaultValue, currentTheme);
-		g_free(currentTheme);
-
-		/* Themes widget has only one column displaying theme's name.
-		 * Set up column and renderer.
-		 */
-		renderer=gtk_cell_renderer_text_new();
-		gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(priv->widgetThemes),
-													0,
-													_("Theme"),
-													renderer,
-													"text",
-													COLUMN_THEME_NAME,
-													NULL);
-
-		/* Ensure only one selection at time is possible */
-		selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->widgetThemes));
-		gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
-
-		/* Populate list of available themes */
-		_xfdashboard_settings_populate_themes_list(self, priv->widgetThemes);
-
-		/* Select default value */
-		_xfdashboard_settings_xfconf_changed_theme(self,
-													"/theme",
-													&defaultValue,
-													priv->xfconfChannel);
-		_xfdashboard_settings_widget_changed_theme(self, selection);
-
-		/* Connect signals */
-		g_signal_connect_swapped(selection,
-									"changed",
-									G_CALLBACK(_xfdashboard_settings_widget_changed_theme),
-									self);
-		g_signal_connect_swapped(priv->xfconfChannel,
-									"property-changed::/theme",
-									G_CALLBACK(_xfdashboard_settings_xfconf_changed_theme),
-									self);
-
-		/* Release allocated resources */
-		g_value_unset(&defaultValue);
-	}
+	priv->themes=xfdashboard_settings_themes_new(builder);
 
 	/* Release allocated resources */
 	g_free(builderFile);
@@ -1416,16 +704,12 @@ static void _xfdashboard_settings_dispose(GObject *inObject)
 	priv->widgetAlwaysLaunchNewInstance=NULL;
 	priv->widgetScrollEventChangedWorkspace=NULL;
 	priv->widgetDelaySearchTimeout=NULL;
-	priv->widgetThemes=NULL;
-	priv->widgetThemeScreenshot=NULL;
-	priv->widgetThemeNameLabel=NULL;
-	priv->widgetThemeName=NULL;
-	priv->widgetThemeAuthorLabel=NULL;
-	priv->widgetThemeAuthor=NULL;
-	priv->widgetThemeVersionLabel=NULL;
-	priv->widgetThemeVersion=NULL;
-	priv->widgetThemeDescriptionLabel=NULL;
-	priv->widgetThemeDescription=NULL;
+
+	if(priv->themes)
+	{
+		g_object_unref(priv->themes);
+		priv->themes=NULL;
+	}
 
 	if(priv->xfconfChannel)
 	{
@@ -1479,16 +763,6 @@ static void xfdashboard_settings_init(XfdashboardSettings *self)
 	priv->widgetAlwaysLaunchNewInstance=NULL;
 	priv->widgetScrollEventChangedWorkspace=NULL;
 	priv->widgetDelaySearchTimeout=NULL;
-	priv->widgetThemes=NULL;
-	priv->widgetThemeScreenshot=NULL;
-	priv->widgetThemeNameLabel=NULL;
-	priv->widgetThemeName=NULL;
-	priv->widgetThemeAuthorLabel=NULL;
-	priv->widgetThemeAuthor=NULL;
-	priv->widgetThemeVersionLabel=NULL;
-	priv->widgetThemeVersion=NULL;
-	priv->widgetThemeDescriptionLabel=NULL;
-	priv->widgetThemeDescription=NULL;
 }
 
 /* IMPLEMENTATION: Public API */
diff --git a/settings/themes.c b/settings/themes.c
new file mode 100644
index 0000000..d00e63c
--- /dev/null
+++ b/settings/themes.c
@@ -0,0 +1,963 @@
+/*
+ * themes: Theme settings of application
+ * 
+ * Copyright 2012-2016 Stephan Haller <nomad at froevel.de>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "themes.h"
+
+#include <glib/gi18n-lib.h>
+#include <xfconf/xfconf.h>
+
+/* Define this class in GObject system */
+G_DEFINE_TYPE(XfdashboardSettingsThemes,
+				xfdashboard_settings_themes,
+				G_TYPE_OBJECT)
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_SETTINGS_THEMES_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_SETTINGS_THEMES, XfdashboardSettingsThemesPrivate))
+
+struct _XfdashboardSettingsThemesPrivate
+{
+	/* Properties related */
+	GtkBuilder		*builder;
+
+	/* Instance related */
+	XfconfChannel	*xfconfChannel;
+
+	GtkWidget		*widgetThemes;
+	GtkWidget		*widgetThemeScreenshot;
+	GtkWidget		*widgetThemeNameLabel;
+	GtkWidget		*widgetThemeName;
+	GtkWidget		*widgetThemeAuthorLabel;
+	GtkWidget		*widgetThemeAuthor;
+	GtkWidget		*widgetThemeVersionLabel;
+	GtkWidget		*widgetThemeVersion;
+	GtkWidget		*widgetThemeDescriptionLabel;
+	GtkWidget		*widgetThemeDescription;
+};
+
+/* Properties */
+enum
+{
+	PROP_0,
+
+	PROP_BUILDER,
+
+	PROP_LAST
+};
+
+static GParamSpec* XfdashboardSettingsThemesProperties[PROP_LAST]={ 0, };
+
+
+/* IMPLEMENTATION: Private variables and methods */
+#define XFDASHBOARD_XFCONF_CHANNEL					"xfdashboard"
+#define THEME_XFCONF_PROP							"/theme"
+#define DEFAULT_THEME								"xfdashboard"
+
+#define XFDASHBOARD_THEME_SUBPATH					"xfdashboard-1.0"
+#define XFDASHBOARD_THEME_FILE						"xfdashboard.theme"
+#define XFDASHBOARD_THEME_GROUP						"Xfdashboard Theme"
+#define DEFAULT_ENABLE_HOTKEY						FALSE
+#define MAX_SCREENSHOT_WIDTH						400
+
+enum
+{
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_NAME,
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_FILE,
+
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_DISPLAY_NAME,
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_AUTHORS,
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_VERSION,
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_DESCRIPTION,
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_SCREENSHOTS,
+
+	XFDASHBOARD_SETTINGS_THEMES_COLUMN_LAST
+};
+
+/* Setting '/theme' changed either at widget or at xfconf property */
+static void _xfdashboard_settings_themes_theme_changed_by_widget(XfdashboardSettingsThemes *self,
+																GtkTreeSelection *inSelection)
+{
+	XfdashboardSettingsThemesPrivate		*priv;
+	GtkTreeModel							*model;
+	GtkTreeIter								iter;
+	gchar									*themeDisplayName;
+	gchar									*themeComment;
+	gchar									*themeAuthor;
+	gchar									*themeVersion;
+	gchar									*themeScreenshot;
+	gchar									*themeFilename;
+	gchar									*themeName;
+
+	g_return_if_fail(XFDASHBOARD_IS_SETTINGS_THEMES(self));
+	g_return_if_fail(GTK_IS_TREE_SELECTION(inSelection));
+
+	priv=self->priv;
+	themeDisplayName=NULL;
+	themeComment=NULL;
+	themeAuthor=NULL;
+	themeVersion=NULL;
+	themeScreenshot=NULL;
+	themeFilename=NULL;
+	themeName=NULL;
+
+	/* Get selected entry from widget */
+	if(gtk_tree_selection_get_selected(inSelection, &model, &iter))
+	{
+		/* Get data from model */
+		gtk_tree_model_get(model,
+							&iter,
+							XFDASHBOARD_SETTINGS_THEMES_COLUMN_NAME, &themeName,
+							XFDASHBOARD_SETTINGS_THEMES_COLUMN_FILE, &themeFilename,
+							XFDASHBOARD_SETTINGS_THEMES_COLUMN_DISPLAY_NAME, &themeDisplayName,
+							XFDASHBOARD_SETTINGS_THEMES_COLUMN_DESCRIPTION, &themeComment,
+							XFDASHBOARD_SETTINGS_THEMES_COLUMN_AUTHORS, &themeAuthor,
+							XFDASHBOARD_SETTINGS_THEMES_COLUMN_VERSION, &themeVersion,
+							XFDASHBOARD_SETTINGS_THEMES_COLUMN_SCREENSHOTS, &themeScreenshot,
+							-1);
+	}
+
+	/* Set text in labels */
+	if(themeDisplayName)
+	{
+		gtk_label_set_text(GTK_LABEL(priv->widgetThemeName), themeDisplayName);
+		gtk_widget_show(priv->widgetThemeName);
+		gtk_widget_show(priv->widgetThemeNameLabel);
+	}
+		else
+		{
+			gtk_widget_hide(priv->widgetThemeName);
+			gtk_widget_hide(priv->widgetThemeNameLabel);
+		}
+
+	if(themeComment)
+	{
+		gtk_label_set_text(GTK_LABEL(priv->widgetThemeDescription), themeComment);
+		gtk_widget_show(priv->widgetThemeDescription);
+		gtk_widget_show(priv->widgetThemeDescriptionLabel);
+	}
+		else
+		{
+			gtk_widget_hide(priv->widgetThemeDescription);
+			gtk_widget_hide(priv->widgetThemeDescriptionLabel);
+		}
+
+	if(themeAuthor)
+	{
+		gtk_label_set_text(GTK_LABEL(priv->widgetThemeAuthor), themeAuthor);
+		gtk_widget_show(priv->widgetThemeAuthor);
+		gtk_widget_show(priv->widgetThemeAuthorLabel);
+	}
+		else
+		{
+			gtk_widget_hide(priv->widgetThemeAuthor);
+			gtk_widget_hide(priv->widgetThemeAuthorLabel);
+		}
+
+	if(themeVersion)
+	{
+		gtk_label_set_text(GTK_LABEL(priv->widgetThemeVersion), themeVersion);
+		gtk_widget_show(priv->widgetThemeVersion);
+		gtk_widget_show(priv->widgetThemeVersionLabel);
+	}
+		else
+		{
+			gtk_widget_hide(priv->widgetThemeVersion);
+			gtk_widget_hide(priv->widgetThemeVersionLabel);
+		}
+
+	/* Set screenshot */
+	if(themeScreenshot)
+	{
+		gchar						*screenshotFile;
+		GdkPixbuf					*screenshotImage;
+
+		screenshotFile=NULL;
+		screenshotImage=NULL;
+
+		/* Get screenshot file but resolve relative path if needed */
+		if(!g_path_is_absolute(themeScreenshot))
+		{
+			GFile					*file;
+			GFile					*parentPath;
+			gchar					*themePath;
+
+			file=NULL;
+			parentPath=NULL;
+			themePath=NULL;
+
+			/* Resolve relative path relative to theme path */
+			file=g_file_new_for_path(themeFilename);
+			if(file) parentPath=g_file_get_parent(file);
+			if(parentPath) themePath=g_file_get_path(parentPath);
+			if(themePath) screenshotFile=g_build_filename(themePath, themeScreenshot, NULL);
+
+			/* Release allocated resources */
+			if(themePath) g_free(themePath);
+			if(parentPath) g_object_unref(parentPath);
+			if(file) g_object_unref(file);
+		}
+			else
+			{
+				/* Path is absolute so just create a copy */
+				screenshotFile=g_strdup(themeScreenshot);
+			}
+
+		/* If screenshot file exists set up and show image
+		 * otherwise hide image.
+		 */
+		if(screenshotFile &&
+			g_file_test(screenshotFile, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+		{
+			GError					*error;
+			gint					width;
+			gint					height;
+
+			error=NULL;
+
+			/* Check if screenshot fits into widget without scaling or
+			 * scale it to maximum size but preserve aspect ratio.
+			 */
+			if(gdk_pixbuf_get_file_info(screenshotFile, &width, &height))
+			{
+				if(width<MAX_SCREENSHOT_WIDTH)
+				{
+					screenshotImage=gdk_pixbuf_new_from_file(screenshotFile,
+																&error);
+				}
+					else
+					{
+						screenshotImage=gdk_pixbuf_new_from_file_at_scale(screenshotFile,
+																			MAX_SCREENSHOT_WIDTH,
+																			-1,
+																			TRUE,
+																			&error);
+					}
+
+				if(error)
+				{
+					g_warning("Could not load screenshot: %s",
+								error ? error->message : _("Unknown error"));
+
+					/* Release allocated resources */
+					if(error) g_error_free(error);
+					if(screenshotImage)
+					{
+						g_object_unref(screenshotImage);
+						screenshotImage=NULL;
+					}
+				}
+			}
+		}
+
+		if(screenshotImage)
+		{
+			gtk_image_set_from_pixbuf(GTK_IMAGE(priv->widgetThemeScreenshot), screenshotImage);
+			gtk_widget_show(priv->widgetThemeScreenshot);
+		}
+			else
+			{
+				gtk_widget_hide(priv->widgetThemeScreenshot);
+			}
+
+		/* Release allocated resources */
+		if(screenshotImage) g_object_unref(screenshotImage);
+		if(screenshotFile) g_free(screenshotFile);
+	}
+		else
+		{
+			gtk_widget_hide(priv->widgetThemeScreenshot);
+		}
+
+	/* Set value at xfconf property if it must be changed */
+	if(themeName)
+	{
+		gchar						*currentTheme;
+
+		currentTheme=xfconf_channel_get_string(priv->xfconfChannel, THEME_XFCONF_PROP, DEFAULT_THEME);
+		if(g_strcmp0(currentTheme, themeName))
+		{
+			xfconf_channel_set_string(priv->xfconfChannel, THEME_XFCONF_PROP, themeName);
+		}
+		g_free(currentTheme);
+	}
+
+	/* Release allocated resources */
+	if(themeDisplayName) g_free(themeDisplayName);
+	if(themeComment) g_free(themeComment);
+	if(themeAuthor) g_free(themeAuthor);
+	if(themeVersion) g_free(themeVersion);
+	if(themeScreenshot) g_free(themeScreenshot);
+	if(themeFilename) g_free(themeFilename);
+	if(themeName) g_free(themeName);
+}
+
+static void _xfdashboard_settings_themes_theme_changed_by_xfconf(XfdashboardSettingsThemes *self,
+																const gchar *inProperty,
+																const GValue *inValue,
+																XfconfChannel *inChannel)
+{
+	XfdashboardSettingsThemesPrivate		*priv;
+	const gchar						*newValue;
+	GtkTreeModel					*model;
+	GtkTreeIter						iter;
+	gboolean						selectionFound;
+
+	g_return_if_fail(XFDASHBOARD_IS_SETTINGS_THEMES(self));
+	g_return_if_fail(inValue);
+	g_return_if_fail(XFCONF_IS_CHANNEL(inChannel));
+
+	priv=self->priv;
+	newValue=DEFAULT_THEME;
+
+	/* Get new value to set at widget */
+	if(G_LIKELY(G_VALUE_TYPE(inValue)==G_TYPE_STRING)) newValue=g_value_get_string(inValue);
+
+	/* Iterate through themes' model and lookup matching item
+	 * against new theme name and select it
+	 */
+	selectionFound=FALSE;
+	model=gtk_tree_view_get_model(GTK_TREE_VIEW(priv->widgetThemes));
+	if(newValue && gtk_tree_model_get_iter_first(model, &iter))
+	{
+		do
+		{
+			gchar					*value;
+
+			gtk_tree_model_get(model,
+								&iter,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_NAME, &value,
+								-1);
+			if(G_UNLIKELY(g_str_equal(value, newValue)))
+			{
+				GtkTreePath			*selectionPath;
+
+				selectionPath=gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter);
+				gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->widgetThemes)), &iter);
+				gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(priv->widgetThemes), selectionPath, NULL, TRUE, 0.5, 0.5);
+				gtk_tree_path_free(selectionPath);
+
+				selectionFound=TRUE;
+			}
+			g_free(value);
+		}
+		while(!selectionFound && gtk_tree_model_iter_next(model, &iter));
+	}
+
+	/* If no selection was found, deselect any selected entry at widget */
+	if(!selectionFound)
+	{
+		GtkTreeSelection			*selection;
+
+		selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->widgetThemes));
+		gtk_tree_selection_unselect_all(selection);
+	}
+}
+
+/* Sorting function for theme list's model */
+static gint _xfdashboard_settings_themes_sort_themes_list_model(GtkTreeModel *inModel,
+																GtkTreeIter *inLeft,
+																GtkTreeIter *inRight)
+{
+	gchar	*leftName;
+	gchar	*rightName;
+	gint	result;
+
+	/* Get theme names from model */
+	leftName=NULL;
+	gtk_tree_model_get(inModel, inLeft, 0, &leftName, -1);
+	if(!leftName) leftName=g_strdup("");
+
+	rightName=NULL;
+	gtk_tree_model_get(inModel, inRight, 0, &rightName, -1);
+	if(!rightName) rightName=g_strdup("");
+
+	result=g_utf8_collate(leftName, rightName);
+
+	/* Release allocated resources */
+	if(leftName) g_free(leftName);
+	if(rightName) g_free(rightName);
+
+	/* Return sorting result */
+	return(result);
+}
+
+/* Populate list of available themes */
+static void _xfdashboard_settings_themes_populate_themes_list(XfdashboardSettingsThemes *self,
+														GtkWidget *inWidget)
+{
+	GHashTable						*themes;
+	GArray							*themesPaths;
+	GDir							*directory;
+	GtkListStore					*model;
+	GtkTreeIter						iter;
+	guint							i;
+
+	g_return_if_fail(XFDASHBOARD_IS_SETTINGS_THEMES(self));
+	g_return_if_fail(GTK_IS_TREE_VIEW(inWidget));
+
+	/* Create hash-table to keep track of duplicates (e.g. user overrides standard themes) */
+	themes=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
+	/* Get model of widget to fill */
+	model=gtk_list_store_new(XFDASHBOARD_SETTINGS_THEMES_COLUMN_LAST,
+								G_TYPE_STRING, /* XFDASHBOARD_SETTINGS_THEMES_COLUMN_NAME */
+								G_TYPE_STRING, /* XFDASHBOARD_SETTINGS_THEMES_COLUMN_FILE */
+								G_TYPE_STRING, /* XFDASHBOARD_SETTINGS_THEMES_COLUMN_DISPLAY_NAME */
+								G_TYPE_STRING, /* XFDASHBOARD_SETTINGS_THEMES_COLUMN_AUTHORS */
+								G_TYPE_STRING, /* XFDASHBOARD_SETTINGS_THEMES_COLUMN_VERSION */
+								G_TYPE_STRING, /* XFDASHBOARD_SETTINGS_THEMES_COLUMN_DESCRIPTION */
+								G_TYPE_STRING  /* XFDASHBOARD_SETTINGS_THEMES_COLUMN_SCREENSHOTS */
+							);
+	gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model),
+									XFDASHBOARD_SETTINGS_THEMES_COLUMN_DISPLAY_NAME,
+									(GtkTreeIterCompareFunc)_xfdashboard_settings_themes_sort_themes_list_model,
+									NULL,
+									NULL);
+	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
+											XFDASHBOARD_SETTINGS_THEMES_COLUMN_DISPLAY_NAME,
+											GTK_SORT_ASCENDING);
+
+	/* Get paths to iterate through to find themes */
+	themesPaths=g_array_new(TRUE, TRUE, sizeof(gchar*));
+	if(themesPaths)
+	{
+		gchar						*themePath;
+		const gchar					*homeDirectory;
+
+		/* First add user's data dir */
+		themePath=g_build_filename(g_get_user_data_dir(), "themes", NULL);
+		g_array_append_val(themesPaths, themePath);
+		g_debug("Adding to theme search path: %s", themePath);
+
+		/* Then add user's home directory */
+		homeDirectory=g_get_home_dir();
+		if(homeDirectory)
+		{
+			themePath=g_build_filename(homeDirectory, ".themes", NULL);
+			g_array_append_val(themesPaths, themePath);
+			g_debug("Adding to theme search path: %s", themePath);
+		}
+
+		/* At last add system-wide path */
+		themePath=g_build_filename(PACKAGE_DATADIR, "themes", NULL);
+		g_array_append_val(themesPaths, themePath);
+		g_debug("Adding to theme search path: %s", themePath);
+	}
+
+	/* Iterate through all themes at all theme paths */
+	for(i=0; i<themesPaths->len; ++i)
+	{
+		const gchar					*themePath;
+		const gchar					*themeName;
+
+		/* Get theme path to iterate through */
+		themePath=g_array_index(themesPaths, const gchar*, i);
+
+		/* Open handle to directory to iterate through
+		 * but skip NULL paths or directory objects
+		 */
+		directory=g_dir_open(themePath, 0, NULL);
+		if(G_UNLIKELY(directory==NULL)) continue;
+
+		/* Iterate through directory and find available themes */
+		while((themeName=g_dir_read_name(directory)))
+		{
+			gchar					*themeIndexFile;
+			GKeyFile				*themeKeyFile;
+			GError					*error;
+			gchar					*themeDisplayName;
+			gchar					*themeComment;
+			gchar					**themeAuthors;
+			gchar					*realThemeAuthor;
+			gchar					*themeVersion;
+			gchar					**themeScreenshots;
+			gchar					*realThemeScreenshot;
+
+			error=NULL;
+			themeDisplayName=NULL;
+			themeComment=NULL;
+			themeAuthors=NULL;
+			themeVersion=NULL;
+			themeScreenshots=NULL;
+			realThemeAuthor=NULL;
+			realThemeScreenshot=NULL;
+
+			/* Check if theme description file exists and add it if there is no theme
+			 * with same name.
+			 */
+			themeIndexFile=g_build_filename(themePath, themeName, XFDASHBOARD_THEME_SUBPATH, XFDASHBOARD_THEME_FILE, NULL);
+			if(!g_file_test(themeIndexFile, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+			{
+				g_debug("Invalid theme '%s': Missing theme index file at %s",
+							themeName,
+							themeIndexFile);
+
+				/* Release allocated resources */
+				if(themeIndexFile) g_free(themeIndexFile);
+
+				/* Continue with next entry */
+				continue;
+			}
+
+			if(g_hash_table_lookup(themes, themeName))
+			{
+				g_debug("Invalid theme '%s': Duplicate theme at %s",
+							themeName,
+							themeIndexFile);
+
+				/* Release allocated resources */
+				if(themeIndexFile) g_free(themeIndexFile);
+
+				/* Continue with next entry */
+				continue;
+			}
+
+			/* Get theme file to retrieve data of it */
+			themeKeyFile=g_key_file_new();
+			if(!g_key_file_load_from_file(themeKeyFile,
+											themeIndexFile,
+											G_KEY_FILE_NONE,
+											&error))
+			{
+				g_warning("Invalid theme '%s' at %s: %s",
+							themeName,
+							themeIndexFile,
+							error ? error->message : _("Unknown error"));
+
+				/* Release allocated resources */
+				if(error) g_error_free(error);
+				if(themeKeyFile) g_key_file_free(themeKeyFile);
+				if(themeIndexFile) g_free(themeIndexFile);
+
+				/* Continue with next entry */
+				continue;
+			}
+
+			/* Check if theme is valid by checking if all essential
+			 * keys are defined: Name, Comment, Style and Layout
+			 */
+			if(!g_key_file_has_key(themeKeyFile,
+									XFDASHBOARD_THEME_GROUP,
+									"Name",
+									&error))
+			{
+				g_warning("Invalid theme '%s' at %s: %s",
+							themeName,
+							themeIndexFile,
+							error ? error->message : _("Unknown error"));
+
+				/* Release allocated resources */
+				if(error) g_error_free(error);
+				if(themeKeyFile) g_key_file_free(themeKeyFile);
+				if(themeIndexFile) g_free(themeIndexFile);
+
+				/* Continue with next entry */
+				continue;
+			}
+
+			if(!g_key_file_has_key(themeKeyFile,
+									XFDASHBOARD_THEME_GROUP,
+									"Comment",
+									&error))
+			{
+				g_warning("Invalid theme '%s' at %s: %s",
+							themeName,
+							themeIndexFile,
+							error ? error->message : _("Unknown error"));
+
+				/* Release allocated resources */
+				if(error) g_error_free(error);
+				if(themeKeyFile) g_key_file_free(themeKeyFile);
+				if(themeIndexFile) g_free(themeIndexFile);
+
+				/* Continue with next entry */
+				continue;
+			}
+
+			if(!g_key_file_has_key(themeKeyFile,
+									XFDASHBOARD_THEME_GROUP,
+									"Style",
+									&error))
+			{
+				g_warning("Invalid theme '%s' at %s: %s",
+							themeName,
+							themeIndexFile,
+							error ? error->message : _("Unknown error"));
+
+				/* Release allocated resources */
+				if(error) g_error_free(error);
+				if(themeKeyFile) g_key_file_free(themeKeyFile);
+				if(themeIndexFile) g_free(themeIndexFile);
+
+				/* Continue with next entry */
+				continue;
+			}
+
+			if(!g_key_file_has_key(themeKeyFile,
+									XFDASHBOARD_THEME_GROUP,
+									"Layout",
+									&error))
+			{
+				g_warning("Invalid theme '%s' at %s: %s",
+							themeName,
+							themeIndexFile,
+							error ? error->message : _("Unknown error"));
+
+				/* Release allocated resources */
+				if(error) g_error_free(error);
+				if(themeKeyFile) g_key_file_free(themeKeyFile);
+				if(themeIndexFile) g_free(themeIndexFile);
+
+				/* Continue with next entry */
+				continue;
+			}
+
+			/* Theme is valid so get theme data which includes
+			 * optional field: Author, Version and Screenshot
+			 */
+			themeDisplayName=g_key_file_get_locale_string(themeKeyFile,
+															XFDASHBOARD_THEME_GROUP,
+															"Name",
+															NULL,
+															NULL);
+
+			themeComment=g_key_file_get_locale_string(themeKeyFile,
+															XFDASHBOARD_THEME_GROUP,
+															"Comment",
+															NULL,
+															NULL);
+
+			themeAuthors=g_key_file_get_string_list(themeKeyFile,
+													XFDASHBOARD_THEME_GROUP,
+													"Author",
+													NULL,
+													NULL);
+			if(themeAuthors)
+			{
+				/* Replace list of string with authors with one string
+				 * containing all authors seperated by new-line.
+				 */
+				realThemeAuthor=g_strjoinv("\n", themeAuthors);
+			}
+
+			themeVersion=g_key_file_get_string(themeKeyFile,
+												XFDASHBOARD_THEME_GROUP,
+												"Version",
+												NULL);
+
+			themeScreenshots=g_key_file_get_string_list(themeKeyFile,
+														XFDASHBOARD_THEME_GROUP,
+														"Screenshot",
+														NULL,
+														NULL);
+			if(themeScreenshots)
+			{
+				/* Replace list of string with filenames to screenshots
+				 * with one string containing the first screenshot's filename.
+				 */
+				realThemeScreenshot=g_strdup(themeScreenshots[0]);
+			}
+
+			/* Add to widget's list */
+			gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+			gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_NAME, themeName,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_FILE, themeIndexFile,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_DISPLAY_NAME, themeDisplayName,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_AUTHORS, realThemeAuthor,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_VERSION, themeVersion,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_DESCRIPTION, themeComment,
+								XFDASHBOARD_SETTINGS_THEMES_COLUMN_SCREENSHOTS, realThemeScreenshot,
+								-1);
+
+			/* Remember theme to avoid duplicates (and allow overrides by user */
+			g_hash_table_insert(themes, g_strdup(themeName), GINT_TO_POINTER(1));
+			g_debug("Added theme '%s' from %s", themeName, themeIndexFile);
+
+			/* Release allocated resources */
+			if(realThemeAuthor) g_free(realThemeAuthor);
+			if(realThemeScreenshot) g_free(realThemeScreenshot);
+			if(themeDisplayName) g_free(themeDisplayName);
+			if(themeComment) g_free(themeComment);
+			if(themeAuthors) g_strfreev(themeAuthors);
+			if(themeVersion) g_free(themeVersion);
+			if(themeScreenshots) g_strfreev(themeScreenshots);
+			if(themeKeyFile) g_key_file_free(themeKeyFile);
+			if(themeIndexFile) g_free(themeIndexFile);
+		}
+
+		/* Close handle to directory */
+		g_dir_close(directory);
+	}
+
+	/* Set new list store at widget */
+	gtk_tree_view_set_model(GTK_TREE_VIEW(inWidget), GTK_TREE_MODEL(model));
+	g_object_unref(model);
+
+	/* Release allocated resources */
+	if(themesPaths)
+	{
+		for(i=0; i<themesPaths->len; ++i)
+		{
+			gchar						*themePath;
+
+			themePath=g_array_index(themesPaths, gchar*, i);
+			g_free(themePath);
+		}
+		g_array_free(themesPaths, TRUE);
+	}
+	if(themes) g_hash_table_destroy(themes);
+}
+
+/* Create and set up GtkBuilder */
+static void _xfdashboard_settings_themes_set_builder(XfdashboardSettingsThemes *self,
+															GtkBuilder *inBuilder)
+{
+	XfdashboardSettingsThemesPrivate	*priv;
+
+	g_return_if_fail(XFDASHBOARD_IS_SETTINGS_THEMES(self));
+	g_return_if_fail(GTK_IS_BUILDER(inBuilder));
+
+	priv=self->priv;
+
+	/* Set builder object which must not be set yet */
+	g_assert(!priv->builder);
+
+	priv->builder=g_object_ref(inBuilder);
+
+	/* Get widgets from builder */
+	priv->widgetThemes=GTK_WIDGET(gtk_builder_get_object(priv->builder, "themes"));
+	priv->widgetThemeScreenshot=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-screenshot"));
+	priv->widgetThemeNameLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-name-label"));
+	priv->widgetThemeName=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-name"));
+	priv->widgetThemeAuthorLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-author-label"));
+	priv->widgetThemeAuthor=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-author"));
+	priv->widgetThemeVersionLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-version-label"));
+	priv->widgetThemeVersion=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-version"));
+	priv->widgetThemeDescriptionLabel=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-description-label"));
+	priv->widgetThemeDescription=GTK_WIDGET(gtk_builder_get_object(priv->builder, "theme-description"));
+
+	/* Set up theme list */
+	if(priv->widgetThemes)
+	{
+		gchar							*currentTheme;
+		GValue							defaultValue=G_VALUE_INIT;
+		GtkTreeSelection				*selection;
+		GtkCellRenderer					*renderer;
+
+		/* Get default value */
+		currentTheme=xfconf_channel_get_string(priv->xfconfChannel, THEME_XFCONF_PROP, DEFAULT_THEME);
+		g_value_init(&defaultValue, G_TYPE_STRING);
+		g_value_set_string(&defaultValue, currentTheme);
+		g_free(currentTheme);
+
+		/* Themes widget has only one column displaying theme's name.
+		 * Set up column and renderer.
+		 */
+		renderer=gtk_cell_renderer_text_new();
+		gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(priv->widgetThemes),
+													0,
+													_("Theme"),
+													renderer,
+													"text",
+													XFDASHBOARD_SETTINGS_THEMES_COLUMN_NAME,
+													NULL);
+
+		/* Ensure only one selection at time is possible */
+		selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->widgetThemes));
+		gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+		/* Populate list of available themes */
+		_xfdashboard_settings_themes_populate_themes_list(self, priv->widgetThemes);
+
+		/* Select default value */
+		_xfdashboard_settings_themes_theme_changed_by_xfconf(self,
+																THEME_XFCONF_PROP,
+																&defaultValue,
+																priv->xfconfChannel);
+		_xfdashboard_settings_themes_theme_changed_by_widget(self, selection);
+
+		/* Connect signals */
+		g_signal_connect_swapped(selection,
+									"changed",
+									G_CALLBACK(_xfdashboard_settings_themes_theme_changed_by_widget),
+									self);
+		g_signal_connect_swapped(priv->xfconfChannel,
+									"property-changed::/theme",
+									G_CALLBACK(_xfdashboard_settings_themes_theme_changed_by_xfconf),
+									self);
+
+		/* Release allocated resources */
+		g_value_unset(&defaultValue);
+	}
+}
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_settings_themes_dispose(GObject *inObject)
+{
+	XfdashboardSettingsThemes			*self=XFDASHBOARD_SETTINGS_THEMES(inObject);
+	XfdashboardSettingsThemesPrivate	*priv=self->priv;
+
+	/* Release allocated resouces */
+	priv->widgetThemes=NULL;
+	priv->widgetThemeScreenshot=NULL;
+	priv->widgetThemeNameLabel=NULL;
+	priv->widgetThemeName=NULL;
+	priv->widgetThemeAuthorLabel=NULL;
+	priv->widgetThemeAuthor=NULL;
+	priv->widgetThemeVersionLabel=NULL;
+	priv->widgetThemeVersion=NULL;
+	priv->widgetThemeDescriptionLabel=NULL;
+	priv->widgetThemeDescription=NULL;
+
+	if(priv->builder)
+	{
+		g_object_unref(priv->builder);
+		priv->builder=NULL;
+	}
+
+	if(priv->xfconfChannel)
+	{
+		priv->xfconfChannel=NULL;
+	}
+
+	/* Call parent's class dispose method */
+	G_OBJECT_CLASS(xfdashboard_settings_themes_parent_class)->dispose(inObject);
+}
+
+/* Set/get properties */
+static void _xfdashboard_settings_themes_set_property(GObject *inObject,
+														guint inPropID,
+														const GValue *inValue,
+														GParamSpec *inSpec)
+{
+	XfdashboardSettingsThemes				*self=XFDASHBOARD_SETTINGS_THEMES(inObject);
+
+	switch(inPropID)
+	{
+		case PROP_BUILDER:
+			_xfdashboard_settings_themes_set_builder(self, GTK_BUILDER(g_value_get_object(inValue)));
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+static void _xfdashboard_settings_themes_get_property(GObject *inObject,
+														guint inPropID,
+														GValue *outValue,
+														GParamSpec *inSpec)
+{
+	XfdashboardSettingsThemes				*self=XFDASHBOARD_SETTINGS_THEMES(inObject);
+	XfdashboardSettingsThemesPrivate		*priv=self->priv;
+
+	switch(inPropID)
+	{
+		case PROP_BUILDER:
+			g_value_set_object(outValue, priv->builder);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
+			break;
+	}
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+static void xfdashboard_settings_themes_class_init(XfdashboardSettingsThemesClass *klass)
+{
+	GObjectClass		*gobjectClass=G_OBJECT_CLASS(klass);
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_settings_themes_dispose;
+	gobjectClass->set_property=_xfdashboard_settings_themes_set_property;
+	gobjectClass->get_property=_xfdashboard_settings_themes_get_property;
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardSettingsThemesPrivate));
+
+	/* Define properties */
+	XfdashboardSettingsThemesProperties[PROP_BUILDER]=
+		g_param_spec_object("builder",
+								_("Builder"),
+								_("The initialized GtkBuilder object where to set up themes tab from"),
+								GTK_TYPE_BUILDER,
+								G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
+
+	g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardSettingsThemesProperties);
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+static void xfdashboard_settings_themes_init(XfdashboardSettingsThemes *self)
+{
+	XfdashboardSettingsThemesPrivate	*priv;
+
+	priv=self->priv=XFDASHBOARD_SETTINGS_THEMES_GET_PRIVATE(self);
+
+	/* Set default values */
+	priv->builder=NULL;
+
+	priv->xfconfChannel=xfconf_channel_get(XFDASHBOARD_XFCONF_CHANNEL);
+
+	priv->widgetThemes=NULL;
+	priv->widgetThemeScreenshot=NULL;
+	priv->widgetThemeNameLabel=NULL;
+	priv->widgetThemeName=NULL;
+	priv->widgetThemeAuthorLabel=NULL;
+	priv->widgetThemeAuthor=NULL;
+	priv->widgetThemeVersionLabel=NULL;
+	priv->widgetThemeVersion=NULL;
+	priv->widgetThemeDescriptionLabel=NULL;
+	priv->widgetThemeDescription=NULL;
+}
+
+/* IMPLEMENTATION: Public API */
+
+/* Create instance of this class */
+XfdashboardSettingsThemes* xfdashboard_settings_themes_new(GtkBuilder *inBuilder)
+{
+	GObject		*instance;
+
+	g_return_val_if_fail(GTK_IS_BUILDER(inBuilder), NULL);
+
+	/* Create instance */
+	instance=g_object_new(XFDASHBOARD_TYPE_SETTINGS_THEMES,
+							"builder", inBuilder,
+							NULL);
+
+	/* Return newly created instance */
+	return(XFDASHBOARD_SETTINGS_THEMES(instance));
+}
diff --git a/settings/themes.h b/settings/themes.h
new file mode 100644
index 0000000..1f6fce5
--- /dev/null
+++ b/settings/themes.h
@@ -0,0 +1,68 @@
+/*
+ * themes: Theme settings of application
+ * 
+ * Copyright 2012-2016 Stephan Haller <nomad at froevel.de>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifndef __XFDASHBOARD_SETTINGS_THEMES__
+#define __XFDASHBOARD_SETTINGS_THEMES__
+
+#include <gtk/gtkx.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_SETTINGS_THEMES				(xfdashboard_settings_themes_get_type())
+#define XFDASHBOARD_SETTINGS_THEMES(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_SETTINGS_THEMES, XfdashboardSettingsThemes))
+#define XFDASHBOARD_IS_SETTINGS_THEMES(obj)				(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_SETTINGS_THEMES))
+#define XFDASHBOARD_SETTINGS_THEMES_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_SETTINGS_THEMES, XfdashboardSettingsThemesClass))
+#define XFDASHBOARD_IS_SETTINGS_THEMES_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_SETTINGS_THEMES))
+#define XFDASHBOARD_SETTINGS_THEMES_GET_CLASS(obj)		(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_SETTINGS_THEMES, XfdashboardSettingsThemesClass))
+
+typedef struct _XfdashboardSettingsThemes				XfdashboardSettingsThemes;
+typedef struct _XfdashboardSettingsThemesClass			XfdashboardSettingsThemesClass;
+typedef struct _XfdashboardSettingsThemesPrivate		XfdashboardSettingsThemesPrivate;
+
+struct _XfdashboardSettingsThemes
+{
+	/* Parent instance */
+	GObject							parent_instance;
+
+	/* Private structure */
+	XfdashboardSettingsThemesPrivate	*priv;
+};
+
+struct _XfdashboardSettingsThemesClass
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass					parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_settings_themes_get_type(void) G_GNUC_CONST;
+
+XfdashboardSettingsThemes* xfdashboard_settings_themes_new(GtkBuilder *inBuilder);
+
+G_END_DECLS
+
+#endif	/* __XFDASHBOARD_SETTINGS_THEMES__ */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list