2009-07-15 22:16:39 +00:00
/**************************************************************************
*
* Tint2conf
*
2010-11-02 11:40:50 +00:00
* Copyright ( C ) 2009 Thierry lorthiois ( lorthiois @ bbsoft . fr ) from Omega distribution
2009-07-15 22:16:39 +00:00
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation .
*
* 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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-01-28 15:31:20 +00:00
# include <time.h>
2015-07-12 15:01:44 +00:00
# include <unistd.h>
2015-04-25 13:45:15 +00:00
2010-06-12 21:21:06 +00:00
# ifdef HAVE_VERSION_H
2015-01-20 02:23:28 +00:00
# include "version.h"
2010-06-09 15:31:18 +00:00
# endif
2015-01-28 15:31:20 +00:00
2010-06-14 15:08:51 +00:00
# include "main.h"
2009-10-25 16:36:40 +00:00
# include "common.h"
2009-11-16 09:27:44 +00:00
# include "theme_view.h"
2010-06-12 22:17:45 +00:00
# include "properties.h"
2011-06-06 09:16:51 +00:00
# include "properties_rw.h"
2009-07-15 22:16:39 +00:00
2016-03-20 12:08:40 +00:00
void refresh_theme ( const char * given_path ) ;
void remove_theme ( const char * given_path ) ;
static void theme_selection_changed ( GtkWidget * treeview , gpointer userdata ) ;
static gchar * find_theme_in_system_dirs ( const gchar * given_name ) ;
2017-03-04 15:14:01 +00:00
static void load_specific_themes ( char * * paths , int count ) ;
2009-10-24 23:23:01 +00:00
2015-04-25 13:45:15 +00:00
// ====== Utilities ======
2009-10-24 23:23:01 +00:00
2016-03-20 12:08:40 +00:00
// Returns ~/.config/tint2/tint2rc (or equivalent).
// Needs gfree.
gchar * get_home_config_path ( )
{
return g_build_filename ( g_get_user_config_dir ( ) , " tint2 " , " tint2rc " , NULL ) ;
}
// Returns /etc/xdg/tint2/tint2rc (or equivalent).
// Needs gfree.
gchar * get_etc_config_path ( )
2015-04-25 13:45:15 +00:00
{
gchar * path = NULL ;
2016-03-20 12:08:40 +00:00
const gchar * const * system_dirs = g_get_system_config_dirs ( ) ;
for ( int i = 0 ; system_dirs [ i ] ; i + + ) {
2015-04-25 13:45:15 +00:00
path = g_build_filename ( system_dirs [ i ] , " tint2 " , " tint2rc " , NULL ) ;
if ( g_file_test ( path , G_FILE_TEST_EXISTS ) )
return path ;
g_free ( path ) ;
path = NULL ;
}
return g_strdup ( " /dev/null " ) ;
}
2009-07-15 22:16:39 +00:00
2016-03-20 12:08:40 +00:00
gboolean startswith ( const char * str , const char * prefix )
{
return strstr ( str , prefix ) = = str ;
}
gboolean endswith ( const char * str , const char * suffix )
{
return strlen ( str ) > = strlen ( suffix ) & & g_str_equal ( str + strlen ( str ) - strlen ( suffix ) , suffix ) ;
}
// Returns TRUE if the theme file is in ~/.config.
gboolean theme_is_editable ( const char * filepath )
{
return startswith ( filepath , g_get_user_config_dir ( ) ) ;
}
// Returns TRUE if the theme file is ~/.config/tint2/tint2rc.
gboolean theme_is_default ( const char * filepath )
{
gchar * default_path = get_home_config_path ( ) ;
gboolean result = g_str_equal ( default_path , filepath ) ;
g_free ( default_path ) ;
return result ;
}
// Extracts the file name from the path. Do not free!
char * file_name_from_path ( const char * filepath )
{
char * name = strrchr ( filepath , ' / ' ) ;
if ( ! name )
return NULL ;
name + + ;
if ( ! * name )
return NULL ;
return name ;
}
void make_backup ( const char * filepath )
{
gchar * backup_path = g_strdup_printf ( " %s.backup.%ld " , filepath , time ( NULL ) ) ;
copy_file ( filepath , backup_path ) ;
g_free ( backup_path ) ;
}
// Imports a file to ~/.config/tint2/.
// If a file with the same name exists, it does not overwrite it.
// Takes care of updating the theme list in the GUI.
// Returns the new location. Needs gfree.
gchar * import_no_overwrite ( const char * filepath )
{
gchar * filename = file_name_from_path ( filepath ) ;
if ( ! filename )
return NULL ;
gchar * newpath = g_build_filename ( g_get_user_config_dir ( ) , " tint2 " , filename , NULL ) ;
if ( ! g_file_test ( newpath , G_FILE_TEST_EXISTS ) ) {
copy_file ( filepath , newpath ) ;
2016-03-24 22:20:00 +00:00
theme_list_append ( newpath ) ;
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , update_snapshot , NULL ) ;
2016-03-20 12:08:40 +00:00
}
return newpath ;
}
// Copies a theme file from filepath to newpath.
// Takes care of updating the theme list in the GUI.
void import_with_overwrite ( const char * filepath , const char * newpath )
2015-04-25 13:45:15 +00:00
{
2016-03-20 12:08:40 +00:00
gboolean theme_existed = g_file_test ( newpath , G_FILE_TEST_EXISTS ) ;
if ( theme_existed )
make_backup ( newpath ) ;
copy_file ( filepath , newpath ) ;
if ( theme_is_editable ( newpath ) ) {
if ( ! theme_existed ) {
2016-03-24 22:20:00 +00:00
theme_list_append ( newpath ) ;
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , update_snapshot , NULL ) ;
2016-03-20 12:08:40 +00:00
} else {
int unused = system ( " killall -SIGUSR1 tint2 || pkill -SIGUSR1 -x tint2 " ) ;
( void ) unused ;
refresh_theme ( newpath ) ;
}
}
2015-04-25 13:45:15 +00:00
}
static void menuAddWidget ( GtkUIManager * ui_manager , GtkWidget * p_widget , GtkContainer * p_box )
{
gtk_box_pack_start ( GTK_BOX ( p_box ) , p_widget , FALSE , FALSE , 0 ) ;
gtk_widget_show ( p_widget ) ;
}
2009-07-28 18:29:36 +00:00
2015-04-25 13:45:15 +00:00
static void menuAddWidget ( GtkUIManager * , GtkWidget * , GtkContainer * ) ;
2016-03-20 12:08:40 +00:00
static void menuImportFile ( ) ;
2010-04-02 20:02:41 +00:00
static void menuSaveAs ( ) ;
static void menuDelete ( ) ;
2016-03-20 12:08:40 +00:00
static void menuReset ( ) ;
2017-03-26 13:46:10 +00:00
static gboolean edit_theme ( gpointer ignored ) ;
2016-03-20 12:08:40 +00:00
static void make_selected_theme_default ( ) ;
2010-04-02 20:02:41 +00:00
static void menuAbout ( ) ;
2015-04-18 12:46:39 +00:00
static gboolean view_onPopupMenu ( GtkWidget * treeview , gpointer userdata ) ;
static gboolean view_onButtonPressed ( GtkWidget * treeview , GdkEventButton * event , gpointer userdata ) ;
2015-04-26 12:42:20 +00:00
static void viewRowActivated ( GtkTreeView * tree_view , GtkTreePath * path , GtkTreeViewColumn * column , gpointer user_data ) ;
2015-04-25 13:45:15 +00:00
static void select_first_theme ( ) ;
static void load_all_themes ( ) ;
2017-03-04 21:36:51 +00:00
static void reload_all_themes ( ) ;
2009-07-28 18:29:36 +00:00
2015-04-25 13:45:15 +00:00
// ====== Globals ======
2009-07-28 18:29:36 +00:00
2015-04-25 13:45:15 +00:00
GtkWidget * g_window ;
static GtkUIManager * globalUIManager = NULL ;
GtkWidget * tint_cmd ;
2009-07-28 18:29:36 +00:00
2016-03-08 22:42:35 +00:00
GtkActionGroup * actionGroup = NULL ;
2016-03-20 12:08:40 +00:00
static const char * global_ui = " <ui> "
" <menubar name='MenuBar'> "
" <menu action='ThemeMenu'> "
" <menuitem action='ThemeImportFile'/> "
" <separator/> "
" <menuitem action='ThemeEdit'/> "
" <menuitem action='ThemeSaveAs'/> "
2016-03-20 12:22:14 +00:00
" <menuitem action='ThemeMakeDefault'/> "
2016-03-20 12:08:40 +00:00
" <menuitem action='ThemeReset'/> "
" <menuitem action='ThemeDelete'/> "
" <separator/> "
" <menuitem action='ThemeRefresh'/> "
" <menuitem action='RefreshAll'/> "
" <separator/> "
" <menuitem action='Quit'/> "
" </menu> "
" <menu action='HelpMenu'> "
" <menuitem action='HelpAbout'/> "
" </menu> "
" </menubar> "
" <toolbar name='ToolBar'> "
" <toolitem action='ThemeEdit'/> "
" <toolitem action='ThemeMakeDefault'/> "
" </toolbar> "
" <popup name='ThemePopup'> "
" <menuitem action='ThemeEdit'/> "
" <menuitem action='ThemeRefresh'/> "
" <separator/> "
" <menuitem action='ThemeReset'/> "
" <menuitem action='ThemeDelete'/> "
" </popup> "
" </ui> " ;
2009-07-15 22:16:39 +00:00
2015-04-18 12:46:39 +00:00
int main ( int argc , char * * argv )
2009-07-15 22:16:39 +00:00
{
2015-11-01 11:53:48 +00:00
setlocale ( LC_ALL , " " ) ;
2015-05-21 10:34:52 +00:00
bindtextdomain ( GETTEXT_PACKAGE , LOCALEDIR ) ;
bind_textdomain_codeset ( GETTEXT_PACKAGE , " UTF-8 " ) ;
textdomain ( GETTEXT_PACKAGE ) ;
2009-11-10 17:07:51 +00:00
GtkWidget * vBox = NULL , * scrollbar = NULL ;
2015-04-18 12:46:39 +00:00
gtk_init ( & argc , & argv ) ;
2015-07-12 15:54:40 +00:00
# if !GLIB_CHECK_VERSION(2, 31, 0)
g_thread_init ( NULL ) ;
# endif
2015-04-18 12:46:39 +00:00
2015-04-25 13:45:15 +00:00
{
gchar * tint2_config_dir = g_build_filename ( g_get_user_config_dir ( ) , " tint2 " , NULL ) ;
if ( ! g_file_test ( tint2_config_dir , G_FILE_TEST_IS_DIR ) )
2017-03-04 14:10:44 +00:00
g_mkdir ( tint2_config_dir , 0700 ) ;
2015-04-25 13:45:15 +00:00
g_free ( tint2_config_dir ) ;
}
2015-04-18 12:46:39 +00:00
g_set_application_name ( _ ( " tint2conf " ) ) ;
2017-01-14 15:43:34 +00:00
gtk_window_set_default_icon_name ( " tint2conf " ) ;
2016-03-20 12:08:40 +00:00
2015-04-25 13:45:15 +00:00
// config file uses '.' as decimal separator
2011-06-06 09:16:51 +00:00
setlocale ( LC_NUMERIC , " POSIX " ) ;
2009-07-28 18:29:36 +00:00
2009-10-24 23:23:01 +00:00
// define main layout : container, menubar, toolbar
2015-04-18 12:46:39 +00:00
g_window = gtk_window_new ( GTK_WINDOW_TOPLEVEL ) ;
2016-05-14 06:16:10 +00:00
gtk_window_set_title ( GTK_WINDOW ( g_window ) , _ ( " Tint2 panel themes " ) ) ;
2016-03-08 22:42:35 +00:00
gtk_window_resize ( GTK_WINDOW ( g_window ) , 920 , 600 ) ;
2015-04-25 13:45:15 +00:00
g_signal_connect ( G_OBJECT ( g_window ) , " destroy " , G_CALLBACK ( gtk_main_quit ) , NULL ) ;
2015-04-18 12:46:39 +00:00
vBox = gtk_vbox_new ( FALSE , 0 ) ;
gtk_container_add ( GTK_CONTAINER ( g_window ) , vBox ) ;
2009-07-28 18:29:36 +00:00
2015-04-18 12:46:39 +00:00
actionGroup = gtk_action_group_new ( " menuActionGroup " ) ;
2015-05-21 10:34:52 +00:00
// Menubar and toolbar entries
2016-03-20 12:08:40 +00:00
GtkActionEntry entries [ ] =
2016-07-10 17:04:40 +00:00
{ { " ThemeMenu " , NULL , _ ( " _Theme " ) , NULL , NULL , NULL } ,
2016-03-20 12:45:06 +00:00
{ " ThemeImportFile " , GTK_STOCK_ADD , _ ( " _Import theme... " ) , " <Control>N " , _ ( " Import theme(s) from file system " ) , G_CALLBACK ( menuImportFile ) } ,
{ " ThemeSaveAs " , GTK_STOCK_SAVE_AS , _ ( " _Save as... " ) , NULL , _ ( " Save the theme with a new name " ) , G_CALLBACK ( menuSaveAs ) } ,
{ " ThemeDelete " , GTK_STOCK_DELETE , _ ( " _Delete " ) , NULL , _ ( " Delete the selected theme " ) , G_CALLBACK ( menuDelete ) } ,
{ " ThemeReset " , GTK_STOCK_REVERT_TO_SAVED , _ ( " _Reset " ) , NULL , _ ( " Reset the selected theme to default " ) , G_CALLBACK ( menuReset ) } ,
{ " ThemeEdit " , GTK_STOCK_PROPERTIES , _ ( " _Edit theme... " ) , NULL , _ ( " Edit the selected theme " ) , G_CALLBACK ( edit_theme ) } ,
2016-03-20 12:08:40 +00:00
{ " ThemeMakeDefault " , GTK_STOCK_APPLY , _ ( " _Make default " ) , NULL , _ ( " Replace the default theme with the selected one " ) , G_CALLBACK ( make_selected_theme_default ) } ,
2016-03-20 12:45:06 +00:00
{ " ThemeRefresh " , GTK_STOCK_REFRESH , _ ( " Refresh " ) , NULL , _ ( " Redraw the selected theme " ) , G_CALLBACK ( refresh_current_theme ) } ,
2017-03-04 21:36:51 +00:00
{ " RefreshAll " , GTK_STOCK_REFRESH , _ ( " Refresh all " ) , NULL , _ ( " Redraw all themes " ) , G_CALLBACK ( reload_all_themes ) } ,
2016-03-20 12:08:40 +00:00
{ " Quit " , GTK_STOCK_QUIT , _ ( " _Quit " ) , " <control>Q " , _ ( " Quit " ) , G_CALLBACK ( gtk_main_quit ) } ,
2016-07-10 17:04:40 +00:00
{ " HelpMenu " , NULL , _ ( " _Help " ) , NULL , NULL , NULL } ,
2016-03-20 12:08:40 +00:00
{ " HelpAbout " , GTK_STOCK_ABOUT , _ ( " _About " ) , " <Control>A " , _ ( " About " ) , G_CALLBACK ( menuAbout ) } } ;
2015-05-21 10:34:52 +00:00
2015-04-18 12:46:39 +00:00
gtk_action_group_add_actions ( actionGroup , entries , G_N_ELEMENTS ( entries ) , NULL ) ;
2009-10-26 20:17:05 +00:00
globalUIManager = gtk_ui_manager_new ( ) ;
2015-04-18 12:46:39 +00:00
gtk_ui_manager_insert_action_group ( globalUIManager , actionGroup , 0 ) ;
2016-07-06 12:00:00 +00:00
gtk_window_add_accel_group ( GTK_WINDOW ( g_window ) , gtk_ui_manager_get_accel_group ( globalUIManager ) ) ;
2015-04-18 12:46:39 +00:00
gtk_ui_manager_add_ui_from_string ( globalUIManager , global_ui , - 1 , ( NULL ) ) ;
g_signal_connect ( globalUIManager , " add_widget " , G_CALLBACK ( menuAddWidget ) , vBox ) ;
2009-10-26 20:17:05 +00:00
gtk_ui_manager_ensure_update ( globalUIManager ) ;
2015-04-25 13:45:15 +00:00
GtkWidget * table , * label ;
int row , col ;
row = col = 0 ;
table = gtk_table_new ( 1 , 2 , FALSE ) ;
gtk_widget_show ( table ) ;
gtk_box_pack_start ( GTK_BOX ( vBox ) , table , FALSE , TRUE , 0 ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( table ) , 8 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table ) , 8 ) ;
label = gtk_label_new ( _ ( " Command to run tint2: " ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0 , 0 ) ;
gtk_widget_show ( label ) ;
2016-03-20 12:08:40 +00:00
gtk_table_attach ( GTK_TABLE ( table ) , label , col , col + 1 , row , row + 1 , GTK_FILL , 0 , 0 , 0 ) ;
2015-04-25 13:45:15 +00:00
col + + ;
tint_cmd = gtk_entry_new ( ) ;
gtk_widget_show ( tint_cmd ) ;
gtk_entry_set_text ( GTK_ENTRY ( tint_cmd ) , " " ) ;
2016-03-20 12:08:40 +00:00
gtk_table_attach ( GTK_TABLE ( table ) , tint_cmd , col , col + 1 , row , row + 1 , GTK_FILL | GTK_EXPAND , 0 , 0 , 0 ) ;
2015-04-25 13:45:15 +00:00
2009-11-10 17:07:51 +00:00
scrollbar = gtk_scrolled_window_new ( NULL , NULL ) ;
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrollbar ) , GTK_POLICY_AUTOMATIC , GTK_POLICY_AUTOMATIC ) ;
gtk_box_pack_start ( GTK_BOX ( vBox ) , scrollbar , TRUE , TRUE , 0 ) ;
2009-07-28 18:29:36 +00:00
2009-11-16 09:27:44 +00:00
// define theme view
2010-03-26 23:16:25 +00:00
g_theme_view = create_view ( ) ;
2009-11-10 17:07:51 +00:00
gtk_container_add ( GTK_CONTAINER ( scrollbar ) , g_theme_view ) ;
2010-06-14 15:08:51 +00:00
gtk_widget_show ( g_theme_view ) ;
2009-10-26 20:17:05 +00:00
g_signal_connect ( g_theme_view , " button-press-event " , ( GCallback ) view_onButtonPressed , NULL ) ;
g_signal_connect ( g_theme_view , " popup-menu " , ( GCallback ) view_onPopupMenu , NULL ) ;
2015-04-26 12:42:20 +00:00
g_signal_connect ( g_theme_view , " row-activated " , G_CALLBACK ( viewRowActivated ) , NULL ) ;
2016-03-20 12:08:40 +00:00
g_signal_connect ( g_theme_view , " cursor-changed " , G_CALLBACK ( theme_selection_changed ) , NULL ) ;
2009-07-28 18:29:36 +00:00
2010-06-14 15:08:51 +00:00
// load themes
2015-04-25 13:45:15 +00:00
load_all_themes ( ) ;
2017-03-04 15:14:01 +00:00
argc - - , argv + + ;
if ( argc > 0 ) {
load_specific_themes ( argv , argc ) ;
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , edit_theme , NULL ) ;
2017-03-04 15:14:01 +00:00
}
2009-07-28 18:29:36 +00:00
2009-11-03 15:32:55 +00:00
gtk_widget_show_all ( g_window ) ;
2015-04-18 12:46:39 +00:00
gtk_main ( ) ;
2017-03-04 15:14:01 +00:00
2009-07-28 18:29:36 +00:00
return 0 ;
}
2010-04-02 20:02:41 +00:00
static void menuAbout ( )
2009-07-28 18:29:36 +00:00
{
2016-03-20 12:08:40 +00:00
const char * authors [ ] = { " Thierry Lorthiois <lorthiois@bbsoft.fr> " ,
" Andreas Fink <andreas.fink85@googlemail.com> " ,
" Christian Ruppert <Spooky85@gmail.com> (Build system) " ,
" Euan Freeman <euan04@gmail.com> (tintwizard http://code.google.com/p/tintwizard) " ,
( NULL ) } ;
2015-04-25 13:45:15 +00:00
gtk_show_about_dialog ( GTK_WINDOW ( g_window ) ,
2016-03-20 12:08:40 +00:00
" name " ,
g_get_application_name ( ) ,
" comments " ,
_ ( " Theming tool for tint2 panel " ) ,
" version " ,
VERSION_STRING ,
" copyright " ,
2017-01-14 15:43:34 +00:00
_ ( " Copyright 2009-2017 tint2 team \n Tint2 License GNU GPL version 2 \n Tintwizard License GNU "
2016-03-20 12:08:40 +00:00
" GPL version 3 " ) ,
" logo-icon-name " ,
2017-01-14 15:43:34 +00:00
" tint2conf " ,
2016-03-20 12:08:40 +00:00
" authors " ,
authors ,
/* Translators: translate "translator-credits" as your name to have it appear in the credits
in the " About " dialog */
" translator-credits " ,
_ ( " translator-credits " ) ,
2015-04-25 13:45:15 +00:00
NULL ) ;
2009-07-15 22:16:39 +00:00
}
2015-04-25 13:45:15 +00:00
// ====== Theme import/copy/delete ======
2009-07-28 18:29:36 +00:00
2016-03-20 12:08:40 +00:00
// Shows open dialog and copies the selected files to ~ without overwrite.
static void menuImportFile ( )
2015-04-25 13:45:15 +00:00
{
2016-03-20 12:08:40 +00:00
GtkWidget * dialog = gtk_file_chooser_dialog_new ( _ ( " Import theme(s) " ) ,
GTK_WINDOW ( g_window ) ,
GTK_FILE_CHOOSER_ACTION_OPEN ,
GTK_STOCK_CANCEL ,
GTK_RESPONSE_CANCEL ,
GTK_STOCK_ADD ,
GTK_RESPONSE_ACCEPT ,
NULL ) ;
2015-04-25 13:45:15 +00:00
GtkFileChooser * chooser = GTK_FILE_CHOOSER ( dialog ) ;
2015-04-26 12:42:20 +00:00
gtk_file_chooser_set_select_multiple ( chooser , TRUE ) ;
2009-07-28 18:29:36 +00:00
2015-04-18 12:46:39 +00:00
if ( gtk_dialog_run ( GTK_DIALOG ( dialog ) ) ! = GTK_RESPONSE_ACCEPT ) {
2010-04-03 15:56:34 +00:00
gtk_widget_destroy ( dialog ) ;
return ;
}
2015-04-25 13:45:15 +00:00
GSList * list = gtk_file_chooser_get_filenames ( chooser ) ;
2016-03-20 12:08:40 +00:00
for ( GSList * l = list ; l ; l = l - > next ) {
gchar * newpath = import_no_overwrite ( l - > data ) ;
g_free ( newpath ) ;
2009-07-28 18:29:36 +00:00
}
2010-04-03 15:56:34 +00:00
g_slist_foreach ( list , ( GFunc ) g_free , NULL ) ;
g_slist_free ( list ) ;
gtk_widget_destroy ( dialog ) ;
2009-07-15 22:16:39 +00:00
}
2016-03-20 12:08:40 +00:00
// Returns the path to the currently selected theme, or NULL if no theme is selected. Needs gfree.
gchar * get_current_theme_path ( )
2016-03-08 22:42:35 +00:00
{
GtkTreeSelection * sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( g_theme_view ) ) ;
GtkTreeIter iter ;
2016-03-20 12:08:40 +00:00
GtkTreeModel * model ;
2016-03-08 22:42:35 +00:00
if ( gtk_tree_selection_get_selected ( GTK_TREE_SELECTION ( sel ) , & model , & iter ) ) {
2016-03-20 12:08:40 +00:00
gchar * filepath ;
gtk_tree_model_get ( model , & iter , COL_THEME_FILE , & filepath , - 1 ) ;
return filepath ;
2016-03-08 22:42:35 +00:00
}
2016-03-20 12:08:40 +00:00
return NULL ;
}
2016-03-08 22:42:35 +00:00
2016-03-20 12:08:40 +00:00
// Returns the path to the currently selected theme, or NULL if no theme is selected. Needs gfree.
// Shows an error box if not theme is selected.
gchar * get_selected_theme_or_warn ( )
{
gchar * filepath = get_current_theme_path ( ) ;
if ( ! filepath ) {
GtkWidget * w = gtk_message_dialog_new ( GTK_WINDOW ( g_window ) ,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
GTK_MESSAGE_ERROR ,
GTK_BUTTONS_CLOSE ,
2016-03-20 12:45:06 +00:00
_ ( " Please select a theme. " ) ) ;
2016-03-20 12:08:40 +00:00
g_signal_connect_swapped ( w , " response " , G_CALLBACK ( gtk_widget_destroy ) , w ) ;
gtk_widget_show ( w ) ;
}
return filepath ;
2016-03-08 22:42:35 +00:00
}
2016-03-20 12:08:40 +00:00
// For the selected theme, shows save dialog (with overwrite confirmation) and copies to the selected file with overwrite.
// Shows error box if no theme is selected.
static void menuSaveAs ( )
2015-04-25 13:45:15 +00:00
{
2016-03-20 12:08:40 +00:00
gchar * filepath = get_selected_theme_or_warn ( ) ;
if ( ! filepath )
return ;
2015-04-25 13:45:15 +00:00
2016-03-20 12:08:40 +00:00
gchar * filename = file_name_from_path ( filepath ) ;
GtkWidget * dialog = gtk_file_chooser_dialog_new ( _ ( " Save theme as " ) ,
GTK_WINDOW ( g_window ) ,
GTK_FILE_CHOOSER_ACTION_SAVE ,
GTK_STOCK_CANCEL ,
GTK_RESPONSE_CANCEL ,
GTK_STOCK_SAVE ,
GTK_RESPONSE_ACCEPT ,
NULL ) ;
GtkFileChooser * chooser = GTK_FILE_CHOOSER ( dialog ) ;
2016-05-09 10:16:56 +00:00
gtk_file_chooser_set_do_overwrite_confirmation ( chooser , FALSE ) ;
2016-03-20 12:08:40 +00:00
gchar * config_dir = g_build_filename ( g_get_home_dir ( ) , " .config " , " tint2 " , NULL ) ;
2015-04-25 13:45:15 +00:00
gtk_file_chooser_set_current_folder ( chooser , config_dir ) ;
g_free ( config_dir ) ;
2016-05-09 10:16:56 +00:00
GtkFileFilter * filter = gtk_file_filter_new ( ) ;
gtk_file_filter_add_pattern ( filter , " *.tint2rc " ) ;
gtk_file_filter_add_pattern ( filter , " tint2rc " ) ;
gtk_file_chooser_set_filter ( GTK_FILE_CHOOSER ( dialog ) , filter ) ;
2016-03-20 12:08:40 +00:00
gtk_file_chooser_set_current_name ( chooser , filename ) ;
2015-04-25 13:45:15 +00:00
if ( gtk_dialog_run ( GTK_DIALOG ( dialog ) ) = = GTK_RESPONSE_ACCEPT ) {
2016-03-20 12:08:40 +00:00
gchar * newpath = gtk_file_chooser_get_filename ( chooser ) ;
2016-05-09 10:16:56 +00:00
if ( ! endswith ( newpath , " .tint2rc " ) & & ! endswith ( newpath , " /tint2rc " ) ) {
gchar * proper_path = g_strdup_printf ( " %s.tint2rc " , newpath ) ;
g_free ( newpath ) ;
newpath = proper_path ;
}
if ( g_file_test ( newpath , G_FILE_TEST_EXISTS ) ) {
GtkWidget * w = gtk_message_dialog_new ( GTK_WINDOW ( g_window ) ,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
GTK_MESSAGE_QUESTION ,
GTK_BUTTONS_YES_NO ,
_ ( " A file named \" %s \" already exists. Do you want to replace it? " ) ,
newpath ) ;
gint response = gtk_dialog_run ( GTK_DIALOG ( w ) ) ;
gtk_widget_destroy ( w ) ;
if ( response ! = GTK_RESPONSE_YES ) {
g_free ( newpath ) ;
gtk_widget_destroy ( dialog ) ;
g_free ( filepath ) ;
return ;
}
}
2016-03-20 12:08:40 +00:00
import_with_overwrite ( filepath , newpath ) ;
g_free ( newpath ) ;
2015-04-25 13:45:15 +00:00
}
gtk_widget_destroy ( dialog ) ;
2016-03-20 12:08:40 +00:00
g_free ( filepath ) ;
2015-04-25 13:45:15 +00:00
}
2010-03-26 23:16:25 +00:00
2016-03-20 12:08:40 +00:00
// Deletes the selected theme with confirmation.
static void menuDelete ( )
2009-07-15 22:16:39 +00:00
{
2016-03-20 12:08:40 +00:00
gchar * filepath = get_selected_theme_or_warn ( ) ;
if ( ! filepath )
return ;
2009-07-15 22:16:39 +00:00
2016-03-20 12:08:40 +00:00
GtkWidget * w = gtk_message_dialog_new ( GTK_WINDOW ( g_window ) ,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
GTK_MESSAGE_QUESTION ,
GTK_BUTTONS_YES_NO ,
2016-03-20 12:45:06 +00:00
_ ( " Do you really want to delete the selected theme? " ) ) ;
2016-03-20 12:08:40 +00:00
gint response = gtk_dialog_run ( GTK_DIALOG ( w ) ) ;
gtk_widget_destroy ( w ) ;
if ( response ! = GTK_RESPONSE_YES ) {
g_free ( filepath ) ;
2010-04-02 20:02:41 +00:00
return ;
}
2016-03-20 12:08:40 +00:00
GFile * file = g_file_new_for_path ( filepath ) ;
if ( g_file_trash ( file , NULL , NULL ) ) {
remove_theme ( filepath ) ;
2009-07-28 18:29:36 +00:00
}
2016-03-20 12:08:40 +00:00
g_object_unref ( G_OBJECT ( file ) ) ;
g_free ( filepath ) ;
2015-04-25 13:45:15 +00:00
}
2009-10-24 23:23:01 +00:00
2016-03-20 12:08:40 +00:00
static void menuReset ( )
2009-10-24 23:23:01 +00:00
{
2016-03-20 12:08:40 +00:00
gchar * filepath = get_selected_theme_or_warn ( ) ;
if ( ! filepath )
return ;
gchar * filename = file_name_from_path ( filepath ) ;
if ( ! filename ) {
g_free ( filepath ) ;
return ;
}
2009-10-25 18:59:59 +00:00
2016-03-20 12:08:40 +00:00
gchar * syspath = find_theme_in_system_dirs ( filename ) ;
if ( ! syspath )
syspath = find_theme_in_system_dirs ( " tint2rc " ) ;
if ( ! syspath ) {
g_free ( filepath ) ;
return ;
}
GtkWidget * w = gtk_message_dialog_new ( GTK_WINDOW ( g_window ) ,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
GTK_MESSAGE_QUESTION ,
GTK_BUTTONS_YES_NO ,
2016-03-20 12:45:06 +00:00
_ ( " Do you really want to reset the selected theme to default? " ) ) ;
2016-03-20 12:08:40 +00:00
gint response = gtk_dialog_run ( GTK_DIALOG ( w ) ) ;
gtk_widget_destroy ( w ) ;
if ( response ! = GTK_RESPONSE_YES ) {
g_free ( filepath ) ;
g_free ( syspath ) ;
return ;
2009-10-25 18:59:59 +00:00
}
2009-07-15 22:16:39 +00:00
2016-03-20 12:08:40 +00:00
import_with_overwrite ( syspath , filepath ) ;
g_free ( filepath ) ;
g_free ( syspath ) ;
}
2009-07-28 18:29:36 +00:00
2015-04-25 13:45:15 +00:00
// ====== Theme popup menu ======
2010-03-26 23:16:25 +00:00
2016-03-20 12:08:40 +00:00
static void show_popup_menu ( GtkWidget * treeview , GdkEventButton * event , gpointer userdata )
2009-10-26 20:17:05 +00:00
{
2016-03-20 12:08:40 +00:00
gtk_menu_popup ( GTK_MENU ( gtk_ui_manager_get_widget ( globalUIManager , " /ThemePopup " ) ) ,
NULL ,
NULL ,
NULL ,
NULL ,
( event ! = NULL ) ? event - > button : 0 ,
gdk_event_get_time ( ( GdkEvent * ) event ) ) ;
2009-10-26 20:17:05 +00:00
}
2015-04-18 12:46:39 +00:00
static gboolean view_onButtonPressed ( GtkWidget * treeview , GdkEventButton * event , gpointer userdata )
2009-07-28 18:29:36 +00:00
{
2009-10-26 21:21:54 +00:00
// single click with the right mouse button?
2016-03-20 12:08:40 +00:00
if ( event - > type = = GDK_BUTTON_PRESS & & event - > button = = 3 ) {
GtkTreeSelection * selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( treeview ) ) ;
if ( gtk_tree_selection_count_selected_rows ( selection ) < = 1 ) {
2009-10-26 21:21:54 +00:00
// Get tree path for row that was clicked
2016-03-20 12:08:40 +00:00
GtkTreePath * path ;
if ( gtk_tree_view_get_path_at_pos ( GTK_TREE_VIEW ( treeview ) ,
( gint ) event - > x ,
( gint ) event - > y ,
& path ,
NULL ,
NULL ,
NULL ) ) {
2009-10-26 20:17:05 +00:00
gtk_tree_selection_unselect_all ( selection ) ;
gtk_tree_selection_select_path ( selection , path ) ;
gtk_tree_path_free ( path ) ;
}
}
2016-03-20 12:08:40 +00:00
show_popup_menu ( treeview , event , userdata ) ;
2009-10-26 20:17:05 +00:00
return TRUE ;
}
return FALSE ;
}
2015-04-18 12:46:39 +00:00
static gboolean view_onPopupMenu ( GtkWidget * treeview , gpointer userdata )
2009-10-26 20:17:05 +00:00
{
2016-03-20 12:08:40 +00:00
show_popup_menu ( treeview , NULL , userdata ) ;
2009-10-26 20:17:05 +00:00
return TRUE ;
2009-07-28 18:29:36 +00:00
}
2016-03-20 12:08:40 +00:00
static void theme_selection_changed ( GtkWidget * treeview , gpointer userdata )
2010-04-02 20:02:41 +00:00
{
2016-03-20 12:08:40 +00:00
GtkTreeSelection * sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( g_theme_view ) ) ;
2015-04-25 13:45:15 +00:00
GtkTreeIter iter ;
2016-03-20 12:08:40 +00:00
GtkTreeModel * model ;
if ( gtk_tree_selection_get_selected ( GTK_TREE_SELECTION ( sel ) , & model , & iter ) ) {
gchar * filepath ;
gtk_tree_model_get ( model , & iter , COL_THEME_FILE , & filepath , - 1 ) ;
gboolean isdefault = theme_is_default ( filepath ) ;
gchar * text = isdefault ? g_strdup_printf ( " tint2 " ) : g_strdup_printf ( " tint2 -c %s " , filepath ) ;
gtk_entry_set_text ( GTK_ENTRY ( tint_cmd ) , text ) ;
g_free ( text ) ;
gboolean editable = theme_is_editable ( filepath ) ;
g_free ( filepath ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeSaveAs " ) , TRUE ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeDelete " ) , editable ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeReset " ) , editable ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeMakeDefault " ) , ! isdefault ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeEdit " ) , TRUE ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeRefresh " ) , TRUE ) ;
} else {
gtk_entry_set_text ( GTK_ENTRY ( tint_cmd ) , " " ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeSaveAs " ) , FALSE ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeDelete " ) , FALSE ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeReset " ) , FALSE ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeMakeDefault " ) , FALSE ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeEdit " ) , FALSE ) ;
gtk_action_set_sensitive ( gtk_action_group_get_action ( actionGroup , " ThemeRefresh " ) , FALSE ) ;
2015-04-25 13:45:15 +00:00
}
}
void select_first_theme ( )
{
2016-03-20 12:08:40 +00:00
GtkTreeModel * model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( g_theme_view ) ) ;
2015-04-25 13:45:15 +00:00
GtkTreeIter iter ;
2016-03-20 12:08:40 +00:00
if ( gtk_tree_model_get_iter_first ( model , & iter ) ) {
2015-04-25 13:45:15 +00:00
GtkTreePath * path = gtk_tree_model_get_path ( model , & iter ) ;
gtk_tree_selection_select_iter ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( g_theme_view ) ) , & iter ) ;
gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW ( g_theme_view ) , path , NULL , FALSE , 0 , 0 ) ;
gtk_tree_path_free ( path ) ;
}
2016-03-20 12:08:40 +00:00
theme_selection_changed ( NULL , NULL ) ;
2010-04-02 20:02:41 +00:00
}
2016-03-20 12:08:40 +00:00
void select_theme ( const char * given_path )
2015-04-18 12:46:39 +00:00
{
2016-03-20 12:08:40 +00:00
GtkTreeModel * model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( g_theme_view ) ) ;
2015-04-25 13:45:15 +00:00
GtkTreeIter iter ;
2016-03-20 12:08:40 +00:00
gboolean have_iter = gtk_tree_model_get_iter_first ( model , & iter ) ;
while ( have_iter ) {
gchar * filepath ;
gtk_tree_model_get ( model , & iter , COL_THEME_FILE , & filepath , - 1 ) ;
if ( g_str_equal ( filepath , given_path ) ) {
GtkTreePath * path = gtk_tree_model_get_path ( model , & iter ) ;
gtk_tree_selection_select_iter ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( g_theme_view ) ) , & iter ) ;
gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW ( g_theme_view ) , path , NULL , FALSE , 0 , 0 ) ;
gtk_tree_path_free ( path ) ;
g_free ( filepath ) ;
break ;
}
g_free ( filepath ) ;
have_iter = gtk_tree_model_iter_next ( model , & iter ) ;
2015-04-25 13:45:15 +00:00
}
2016-03-20 12:08:40 +00:00
theme_selection_changed ( NULL , NULL ) ;
2015-04-18 12:46:39 +00:00
}
2016-03-20 12:08:40 +00:00
// Edits the selected theme. If it is read-only, it copies first to ~.
2017-03-26 13:46:10 +00:00
static gboolean edit_theme ( gpointer ignored )
2009-07-28 18:29:36 +00:00
{
2016-03-20 12:08:40 +00:00
gchar * filepath = get_selected_theme_or_warn ( ) ;
if ( ! filepath )
2017-03-26 13:46:10 +00:00
return FALSE ;
2016-03-02 21:44:16 +00:00
2016-03-20 12:08:40 +00:00
gboolean editable = theme_is_editable ( filepath ) ;
if ( ! editable ) {
gchar * newpath = import_no_overwrite ( filepath ) ;
g_free ( filepath ) ;
filepath = newpath ;
select_theme ( filepath ) ;
2015-04-25 13:45:15 +00:00
}
2016-03-20 12:08:40 +00:00
create_please_wait ( GTK_WINDOW ( g_window ) ) ;
process_events ( ) ;
GtkWidget * prop = create_properties ( ) ;
config_read_file ( filepath ) ;
save_icon_cache ( icon_theme ) ;
gtk_window_present ( GTK_WINDOW ( prop ) ) ;
g_free ( filepath ) ;
destroy_please_wait ( ) ;
2017-03-26 13:46:10 +00:00
return FALSE ;
2015-04-25 13:45:15 +00:00
}
2016-03-20 12:08:40 +00:00
static void make_selected_theme_default ( )
2015-07-12 15:01:44 +00:00
{
2016-03-20 12:08:40 +00:00
gchar * filepath = get_selected_theme_or_warn ( ) ;
if ( ! filepath )
return ;
2015-07-12 15:01:44 +00:00
2016-03-20 12:08:40 +00:00
gchar * default_path = get_home_config_path ( ) ;
if ( g_str_equal ( filepath , default_path ) ) {
g_free ( filepath ) ;
g_free ( default_path ) ;
return ;
2015-07-12 15:01:44 +00:00
}
2016-03-20 12:08:40 +00:00
GtkWidget * w = gtk_message_dialog_new ( GTK_WINDOW ( g_window ) ,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
GTK_MESSAGE_QUESTION ,
GTK_BUTTONS_YES_NO ,
2016-03-20 12:45:06 +00:00
_ ( " Do you really want to replace the default theme with the selected theme? " ) ) ;
2016-03-20 12:08:40 +00:00
gint response = gtk_dialog_run ( GTK_DIALOG ( w ) ) ;
gtk_widget_destroy ( w ) ;
if ( response ! = GTK_RESPONSE_YES ) {
g_free ( filepath ) ;
g_free ( default_path ) ;
return ;
}
import_with_overwrite ( filepath , default_path ) ;
select_first_theme ( ) ;
g_free ( filepath ) ;
g_free ( default_path ) ;
2015-07-12 15:01:44 +00:00
}
2015-04-26 12:42:20 +00:00
static void viewRowActivated ( GtkTreeView * tree_view , GtkTreePath * path , GtkTreeViewColumn * column , gpointer user_data )
{
2017-03-26 13:46:10 +00:00
edit_theme ( NULL ) ;
2015-04-26 12:42:20 +00:00
}
2015-04-25 13:45:15 +00:00
// ====== Theme load/reload ======
2009-10-24 23:23:01 +00:00
2016-03-08 22:42:35 +00:00
static void ensure_default_theme_exists ( )
2015-07-12 15:01:44 +00:00
{
2016-03-08 22:42:35 +00:00
// Without a user tint2rc file, copy the default
2015-07-12 15:01:44 +00:00
gchar * path_home = g_build_filename ( g_get_user_config_dir ( ) , " tint2 " , " tint2rc " , NULL ) ;
if ( ! g_file_test ( path_home , G_FILE_TEST_EXISTS ) ) {
2016-03-20 12:08:40 +00:00
const gchar * const * system_dirs = g_get_system_config_dirs ( ) ;
2016-03-08 22:42:35 +00:00
for ( int i = 0 ; system_dirs [ i ] ; i + + ) {
2015-07-12 15:01:44 +00:00
gchar * path = g_build_filename ( system_dirs [ i ] , " tint2 " , " tint2rc " , NULL ) ;
if ( g_file_test ( path , G_FILE_TEST_EXISTS ) ) {
copy_file ( path , path_home ) ;
2016-03-08 22:42:35 +00:00
break ;
2015-07-12 15:01:44 +00:00
}
g_free ( path ) ;
}
}
g_free ( path_home ) ;
2016-03-08 22:42:35 +00:00
}
static gboolean load_user_themes ( )
{
// Load configs from home directory
gchar * tint2_config_dir = g_build_filename ( g_get_user_config_dir ( ) , " tint2 " , NULL ) ;
GDir * dir = g_dir_open ( tint2_config_dir , 0 , NULL ) ;
if ( dir = = NULL ) {
g_free ( tint2_config_dir ) ;
return FALSE ;
}
gboolean found_theme = FALSE ;
2015-07-12 15:01:44 +00:00
2016-03-08 22:42:35 +00:00
const gchar * file_name ;
while ( ( file_name = g_dir_read_name ( dir ) ) ) {
2016-03-20 12:08:40 +00:00
if ( ! g_file_test ( file_name , G_FILE_TEST_IS_DIR ) & & ! strstr ( file_name , " backup " ) & & ! strstr ( file_name , " copy " ) & &
! strstr ( file_name , " ~ " ) & & ( endswith ( file_name , " tint2rc " ) | | endswith ( file_name , " .conf " ) ) ) {
2016-03-08 22:42:35 +00:00
found_theme = TRUE ;
gchar * path = g_build_filename ( tint2_config_dir , file_name , NULL ) ;
2016-03-24 22:20:00 +00:00
theme_list_append ( path ) ;
2016-03-08 22:42:35 +00:00
g_free ( path ) ;
}
}
g_dir_close ( dir ) ;
g_free ( tint2_config_dir ) ;
return found_theme ;
}
2016-03-20 12:08:40 +00:00
static gboolean load_themes_from_dirs ( const gchar * const * dirs )
2016-03-08 22:42:35 +00:00
{
gboolean found_theme = FALSE ;
2016-03-20 12:08:40 +00:00
for ( int i = 0 ; dirs [ i ] ; i + + ) {
gchar * path_tint2 = g_build_filename ( dirs [ i ] , " tint2 " , NULL ) ;
2015-07-12 15:01:44 +00:00
GDir * dir = g_dir_open ( path_tint2 , 0 , NULL ) ;
if ( dir ) {
const gchar * file_name ;
while ( ( file_name = g_dir_read_name ( dir ) ) ) {
2016-03-20 12:08:40 +00:00
if ( ! g_file_test ( file_name , G_FILE_TEST_IS_DIR ) & & ! strstr ( file_name , " backup " ) & &
! strstr ( file_name , " copy " ) & & ! strstr ( file_name , " ~ " ) & &
( endswith ( file_name , " tint2rc " ) | | endswith ( file_name , " .conf " ) ) ) {
2016-03-08 22:42:35 +00:00
found_theme = TRUE ;
gchar * path = g_build_filename ( path_tint2 , file_name , NULL ) ;
2016-03-24 22:20:00 +00:00
theme_list_append ( path ) ;
2016-03-08 22:42:35 +00:00
g_free ( path ) ;
2015-07-12 15:01:44 +00:00
}
}
g_dir_close ( dir ) ;
}
g_free ( path_tint2 ) ;
}
2016-03-08 22:42:35 +00:00
return found_theme ;
2015-07-12 15:01:44 +00:00
}
2016-03-20 12:08:40 +00:00
static gboolean load_system_themes ( )
{
gboolean found_theme = FALSE ;
if ( load_themes_from_dirs ( g_get_system_config_dirs ( ) ) )
found_theme = TRUE ;
if ( load_themes_from_dirs ( g_get_system_data_dirs ( ) ) )
found_theme = TRUE ;
return found_theme ;
}
static gchar * find_theme_in_dirs ( const gchar * const * dirs , const gchar * given_name )
{
for ( int i = 0 ; dirs [ i ] ; i + + ) {
gchar * filepath = g_build_filename ( dirs [ i ] , " tint2 " , given_name , NULL ) ;
if ( g_file_test ( filepath , G_FILE_TEST_EXISTS ) ) {
return filepath ;
}
g_free ( filepath ) ;
}
return NULL ;
}
static gchar * find_theme_in_system_dirs ( const gchar * given_name )
{
gchar * result = find_theme_in_dirs ( g_get_system_config_dirs ( ) , given_name ) ;
if ( result )
return result ;
return find_theme_in_dirs ( g_get_system_data_dirs ( ) , given_name ) ;
}
2015-04-25 13:45:15 +00:00
static void load_all_themes ( )
{
2016-03-08 22:42:35 +00:00
ensure_default_theme_exists ( ) ;
2015-07-12 15:01:44 +00:00
2016-03-08 22:42:35 +00:00
gtk_list_store_clear ( GTK_LIST_STORE ( theme_list_store ) ) ;
2016-03-20 12:08:40 +00:00
theme_selection_changed ( NULL , NULL ) ;
2015-04-25 13:45:15 +00:00
2016-03-08 22:42:35 +00:00
gboolean found_themes = FALSE ;
if ( load_user_themes ( ) )
found_themes = TRUE ;
if ( load_system_themes ( ) )
found_themes = TRUE ;
2015-07-12 15:01:44 +00:00
2016-03-08 22:42:35 +00:00
if ( found_themes ) {
2015-04-25 13:45:15 +00:00
select_first_theme ( ) ;
2015-04-18 12:46:39 +00:00
2015-04-25 13:45:15 +00:00
GtkTreeIter iter ;
GtkTreeModel * model ;
gboolean have_iter ;
model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( g_theme_view ) ) ;
have_iter = gtk_tree_model_get_iter_first ( model , & iter ) ;
while ( have_iter ) {
2016-03-08 22:42:35 +00:00
gtk_list_store_set ( theme_list_store , & iter , COL_SNAPSHOT , NULL , - 1 ) ;
2015-04-25 13:45:15 +00:00
have_iter = gtk_tree_model_iter_next ( model , & iter ) ;
2015-04-18 12:46:39 +00:00
}
2015-04-25 13:45:15 +00:00
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , update_snapshot , NULL ) ;
2010-03-26 23:16:25 +00:00
}
2010-04-03 15:56:34 +00:00
}
2017-03-04 21:36:51 +00:00
static void reload_all_themes ( )
{
ensure_default_theme_exists ( ) ;
gtk_list_store_clear ( GTK_LIST_STORE ( theme_list_store ) ) ;
theme_selection_changed ( NULL , NULL ) ;
gboolean found_themes = FALSE ;
if ( load_user_themes ( ) )
found_themes = TRUE ;
if ( load_system_themes ( ) )
found_themes = TRUE ;
if ( found_themes ) {
select_first_theme ( ) ;
GtkTreeIter iter ;
GtkTreeModel * model ;
gboolean have_iter ;
model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( g_theme_view ) ) ;
have_iter = gtk_tree_model_get_iter_first ( model , & iter ) ;
while ( have_iter ) {
gtk_list_store_set ( theme_list_store , & iter , COL_SNAPSHOT , NULL , COL_FORCE_REFRESH , TRUE , - 1 ) ;
have_iter = gtk_tree_model_iter_next ( model , & iter ) ;
}
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , update_snapshot , NULL ) ;
2017-03-04 21:36:51 +00:00
}
}
2017-03-04 15:14:01 +00:00
static void load_specific_themes ( char * * paths , int count )
{
ensure_default_theme_exists ( ) ;
gboolean found_themes = FALSE ;
while ( count > 0 ) {
// Load configs
const char * file_name = paths [ 0 ] ;
paths + + , count - - ;
if ( g_file_test ( file_name , G_FILE_TEST_IS_REGULAR ) | | g_file_test ( file_name , G_FILE_TEST_IS_SYMLINK ) ) {
theme_list_append ( file_name ) ;
if ( ! found_themes ) {
select_theme ( file_name ) ;
found_themes = TRUE ;
}
}
}
if ( found_themes ) {
GtkTreeIter iter ;
GtkTreeModel * model ;
gboolean have_iter ;
model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( g_theme_view ) ) ;
have_iter = gtk_tree_model_get_iter_first ( model , & iter ) ;
while ( have_iter ) {
gtk_list_store_set ( theme_list_store , & iter , COL_SNAPSHOT , NULL , - 1 ) ;
have_iter = gtk_tree_model_iter_next ( model , & iter ) ;
}
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , update_snapshot , NULL ) ;
2017-03-04 15:14:01 +00:00
}
}
2016-03-20 12:08:40 +00:00
void refresh_current_theme ( )
2010-04-03 15:56:34 +00:00
{
2016-03-20 12:08:40 +00:00
GtkTreeSelection * sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( g_theme_view ) ) ;
2010-04-03 15:56:34 +00:00
GtkTreeIter iter ;
GtkTreeModel * model ;
2015-04-25 13:45:15 +00:00
if ( gtk_tree_selection_get_selected ( GTK_TREE_SELECTION ( sel ) , & model , & iter ) ) {
2016-03-08 22:42:35 +00:00
gtk_list_store_set ( theme_list_store , & iter , COL_SNAPSHOT , NULL , - 1 ) ;
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , update_snapshot , NULL ) ;
2010-04-01 21:25:11 +00:00
}
2016-03-20 12:08:40 +00:00
}
2010-04-01 21:25:11 +00:00
2016-03-20 12:08:40 +00:00
void refresh_theme ( const char * given_path )
{
GtkTreeModel * model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( g_theme_view ) ) ;
GtkTreeIter iter ;
gboolean have_iter = gtk_tree_model_get_iter_first ( model , & iter ) ;
while ( have_iter ) {
gchar * filepath ;
gtk_tree_model_get ( model , & iter , COL_THEME_FILE , & filepath , - 1 ) ;
if ( g_str_equal ( filepath , given_path ) ) {
gtk_list_store_set ( theme_list_store , & iter , COL_SNAPSHOT , NULL , - 1 ) ;
2017-03-26 13:46:10 +00:00
g_timeout_add ( SNAPSHOT_TICK , update_snapshot , NULL ) ;
2016-03-20 12:08:40 +00:00
g_free ( filepath ) ;
break ;
}
g_free ( filepath ) ;
have_iter = gtk_tree_model_iter_next ( model , & iter ) ;
}
}
void remove_theme ( const char * given_path )
{
GtkTreeModel * model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( g_theme_view ) ) ;
GtkTreeIter iter ;
gboolean have_iter = gtk_tree_model_get_iter_first ( model , & iter ) ;
while ( have_iter ) {
gchar * filepath ;
gtk_tree_model_get ( model , & iter , COL_THEME_FILE , & filepath , - 1 ) ;
if ( g_str_equal ( filepath , given_path ) ) {
gtk_list_store_remove ( GTK_LIST_STORE ( model ) , & iter ) ;
theme_selection_changed ( NULL , NULL ) ;
g_free ( filepath ) ;
break ;
}
g_free ( filepath ) ;
have_iter = gtk_tree_model_iter_next ( model , & iter ) ;
}
2009-10-25 16:36:40 +00:00
}