Logo Search packages:      
Sourcecode: gtkatlantic version File versions  Download package

theme.c

/*
 *     gtkatlantic - the gtk+ monopd client, enjoy network monopoly games
 *
 *
 *  Copyright (C) 2002-2004 Rochet Sylvain
 *
 *  gtkatlantic 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <gtk/gtk.h>

#include <dirent.h>

#include "global.h"
#include "theme.h"
#include "parser.h"
#include "interface.h"
#include "callback.h"
#include "readpng.h"

#include "config.h"


/* refresh themes database */
void theme_build_database()   {

      DIR *d;
      struct dirent *dir;
      guchar *path, *path2;
      guint32 i;

      /* first free all the database */
      for(i = 0; i < MAX_THEMES; i++)  {

            if(!data->theme[i].open)  continue;
            theme_del_entry(i);
      }

      /* user home theme */
      path = g_strconcat(global->path_home, "themes/", NULL);
      d = opendir (path);

      if(d)  {

            while (1) {

                  dir = readdir(d);
                  if(!dir) break;

                  if(dir->d_name[0] == '.')  continue;

                  path2 = g_strconcat(path, dir->d_name, "/", NULL);
                  theme_add_entry(path2);
                  g_free(path2);
            }
            closedir (d);
      }
      g_free(path);

      /* global theme */
      path = g_strconcat(PACKAGE_DATA_DIR, "/themes/", NULL);
      d = opendir (path);

      if(d)  {

            while (1) {

                  dir = readdir(d);
                  if(!dir) break;

                  if(dir->d_name[0] == '.')  continue;

                  path2 = g_strconcat(path, dir->d_name, "/", NULL);
                  theme_add_entry(path2);
                  g_free(path2);
            }
            closedir (d);
      }
      g_free(path);
}


gboolean theme_get_valid_slot(guint32 *themeslot)  {

      guint32 i;

      if(!data) return(FALSE);

      for(i = 0; i < MAX_THEMES; i++)
            if(!data->theme[i].open) {

                  *themeslot = i;
                  return(TRUE);
            }

      return(FALSE);
}


void theme_del_entry(guint32 slot) {

      if(!data->theme[slot].open) return;

      g_free(data->theme[slot].path);
      g_free(data->theme[slot].path_preview);
      g_free(data->theme[slot].path_conf);

      g_free(data->theme[slot].name);
      g_free(data->theme[slot].type);
      g_free(data->theme[slot].version);
      g_free(data->theme[slot].author);
      g_free(data->theme[slot].email);

      data->theme[slot].open = FALSE;
}


void theme_add_entry(guchar *path)  {

      guint32 slot, area = 0;
      guchar *path2, *str, *ident;
      struct stat s;
      FILE *file;

      guchar *name = 0, *type = 0, *version = 0, *author = 0, *email = 0, *preview = 0;

      /* get properties of this theme, name, author, preview file, ... */
      path2 = g_strconcat(path, "theme.conf", NULL);

      /* detect invalid theme */
      if(stat(path2, &s) < 0)  {

            g_free(path2);
            return;
      }

      /* parse general group */
      file = fopen(path2, "r");
      if (!file) return;

      str = g_malloc0(512);

      for( fgets(str, 512, file) ; !feof(file) ; fgets(str, 512, file) )
      {

            if (str[0] == '[')  {

                  if(! strncmp(str, "[general]", 9) )  area = THEME_FILE_SECTION_GENERAL;
                  else area = 0;
            }

            else  if(area == THEME_FILE_SECTION_GENERAL)  {

                  ident = parser_get_identifier(str);
                  if(!ident)  continue;

                  if(! strcmp(ident, "theme") )  {

                        name = parser_get_data(str, "name");
                        type = parser_get_data(str, "type");
                        version = parser_get_data(str, "version");

                  } else if(! strcmp(ident, "author") )  {

                        author = parser_get_data(str, "name");
                        email = parser_get_data(str, "email");

                  } else if(! strcmp(ident, "misc") )  {

                        preview = parser_get_data(str, "preview");
                  }

                  g_free(ident);
            }
      }
      fclose(file);

      g_free(str);


      /* giving up if theme provide no name or no type */
      if(!name  ||  !type)  return;


      /* fill the theme database */
      if(! theme_get_valid_slot(&slot) )  return;

      data->theme[slot].path = g_strdup(path);
      data->theme[slot].path_preview = g_strconcat(path, preview, NULL);
      g_free(preview);
      data->theme[slot].path_conf = g_strconcat(path, "theme.conf", NULL);

      data->theme[slot].open = TRUE;
      data->theme[slot].name = name;
      data->theme[slot].type = type;
      data->theme[slot].version = version;
      data->theme[slot].author = author;
      data->theme[slot].email = email;
}


void theme_build_selection_win()  {

      GtkWidget *ThemeWin;
            GtkWidget *VBox;
                  GtkWidget *HBox;
                        GtkWidget *VBoxLeft;
                              GtkWidget *ScrollThemeList;
                                    GtkWidget *ThemeCList;
                              GtkWidget *HBoxButtons;
                                    GtkWidget *Button;
                        GtkWidget *VBoxInfo;
                              GtkWidget *TableInfo;
                                    GtkWidget *Alignment;
                                          GtkWidget *Label;
                        GtkWidget *PreviewFrame;

      GtkWidget *tmp;
      guchar *str;

      if(global->ThemeWin)  return;

      global->ThemeWin = ThemeWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title(GTK_WINDOW(ThemeWin), "GtkAtlantic: Theme Selection");
      gtk_window_set_policy(GTK_WINDOW(ThemeWin), FALSE, TRUE, TRUE);
      gtk_widget_realize(ThemeWin);
      gdk_window_set_icon(ThemeWin->window, NULL, global->icon_pixmap, global->icon_mask);
      gtk_signal_connect(GTK_OBJECT(ThemeWin), "delete_event", (GtkSignalFunc)CallBack_ThemeWin_Delete, NULL);
      gtk_signal_connect(GTK_OBJECT(ThemeWin), "destroy", (GtkSignalFunc)CallBack_ThemeWin_Destroyed, NULL);

      VBox = gtk_vbox_new(FALSE, 0);
      gtk_container_set_border_width(GTK_CONTAINER(VBox), 5);
      gtk_container_add(GTK_CONTAINER(ThemeWin), VBox);

      HBox = gtk_hbox_new(FALSE, 5);
      gtk_box_pack_start(GTK_BOX(VBox), HBox, TRUE, TRUE, 0);

      VBoxLeft = gtk_vbox_new(FALSE, 5);
      gtk_box_pack_start(GTK_BOX(HBox), VBoxLeft, TRUE, TRUE, 0);

      /* theme list */
      ScrollThemeList = gtk_scrolled_window_new(NULL, NULL);
      gtk_widget_set_usize(ScrollThemeList, 140, 0);
      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ScrollThemeList), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_box_pack_start(GTK_BOX(VBoxLeft), ScrollThemeList, TRUE, TRUE, 0);

      ThemeCList = gtk_clist_new(2);
      gtk_clist_set_column_auto_resize(GTK_CLIST(ThemeCList), 0, TRUE);
      gtk_clist_set_column_auto_resize(GTK_CLIST(ThemeCList), 1, TRUE);
      gtk_clist_set_column_visibility(GTK_CLIST(ThemeCList), 1, FALSE);
      gtk_clist_column_titles_passive(GTK_CLIST(ThemeCList));
      gtk_clist_set_reorderable(GTK_CLIST(ThemeCList), TRUE);
      gtk_clist_set_selection_mode(GTK_CLIST(ThemeCList), GTK_SELECTION_SINGLE);
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_list", ThemeCList);
      gtk_container_add(GTK_CONTAINER(ScrollThemeList), ThemeCList);

      gtk_signal_connect(GTK_OBJECT(ThemeCList), "unselect_row", (GtkSignalFunc)Callback_ThemeList_Unselect, NULL);
      gtk_signal_connect_after(GTK_OBJECT(ThemeCList), "select_row", (GtkSignalFunc)Callback_ThemeList_Select, NULL);

      /* hbox for buttons */
      HBoxButtons = gtk_hbox_new(FALSE, 5);
      gtk_box_pack_start(GTK_BOX(VBoxLeft), HBoxButtons, FALSE, FALSE, 0);

      Button = gtk_button_new_with_label("Apply");
      gtk_signal_connect(GTK_OBJECT(Button), "clicked", (GtkSignalFunc)CallBack_Theme_Apply, NULL);
      gtk_box_pack_start(GTK_BOX(HBoxButtons), Button, TRUE, TRUE, 0);

      Button = gtk_button_new_with_label("Cancel");
      gtk_signal_connect(GTK_OBJECT(Button), "clicked", (GtkSignalFunc)CallBack_ThemeWin_Delete, NULL);
      gtk_box_pack_start(GTK_BOX(HBoxButtons), Button, TRUE, TRUE, 0);

      /* vbox for themes */
      VBoxInfo = gtk_vbox_new(FALSE, 5);
      gtk_box_pack_start(GTK_BOX(HBox), VBoxInfo, TRUE, TRUE, 0);

      /* table which contain theme infos */
      TableInfo = gtk_table_new (6, 2, FALSE);
      gtk_table_set_col_spacings(GTK_TABLE(TableInfo), 5);
      gtk_table_set_row_spacings(GTK_TABLE(TableInfo), 2);
      gtk_box_pack_start(GTK_BOX(VBoxInfo), TableInfo, FALSE, FALSE, 0);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
//    gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 0, 1, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("Name:");
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("");
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_name", Label);
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 0, 1, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("Type:");
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 1, 2, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("");
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_type", Label);
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 0, 1, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("Version:");
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 1, 2, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("");
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_version", Label);
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 0, 1, 3, 4, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("Author:");
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 1, 2, 3, 4, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("");
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_author", Label);
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 0, 1, 4, 5, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("Email:");
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 1, 2, 4, 5, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("");
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_email", Label);
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 0, 1, 5, 6, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("Location:");
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      Alignment = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
      gtk_table_attach(GTK_TABLE(TableInfo), Alignment, 1, 2, 5, 6, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
      Label = gtk_label_new("");
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_location", Label);
      gtk_container_add(GTK_CONTAINER(Alignment), Label);

      /* preview */
      PreviewFrame = gtk_frame_new("Preview");  
      gtk_box_pack_start(GTK_BOX(VBoxInfo), PreviewFrame, TRUE, TRUE, 0);

      Alignment = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_preview_container", Alignment);
      gtk_widget_set_usize(Alignment, 400, 245);
      gtk_container_add(GTK_CONTAINER(PreviewFrame), Alignment);

      tmp = gtk_label_new("No preview available");
      gtk_object_set_data(GTK_OBJECT(ThemeWin), "theme_preview_data", tmp);
      gtk_container_add(GTK_CONTAINER(Alignment), tmp);

      gtk_object_set_data(GTK_OBJECT(global->ThemeWin), "theme_preview_image", 0);
      str = g_strdup_printf("%d", -1);
      gtk_object_set_data_full(GTK_OBJECT(global->ThemeWin), "theme_preview_selected", str, g_free);

      gtk_widget_show_all(ThemeWin);
}


void theme_fill_selection_list()  {

      guint32 i;
      gint32 row;
      gchar *txt[10];
      GtkWidget *List;

      List = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_list");

      /* build theme list */
      gtk_clist_freeze(GTK_CLIST(List));
      gtk_clist_clear(GTK_CLIST(List));

      for(i = 0 ; i < MAX_THEMES ; i++)  {

            if(data->theme[i].open)  {

                  txt[0] = data->theme[i].name;
                  txt[1] = g_strdup_printf("%d", i);
                  row = gtk_clist_append(GTK_CLIST(List), txt);
                  gtk_clist_set_selectable(GTK_CLIST(List), row, TRUE);
                  g_free(txt[1]);
            }
      }

      gtk_clist_thaw(GTK_CLIST(List));
}


void theme_preview_free()  {

      GtkWidget *Alignment;
      GtkWidget *Preview;
      guchar *buf = 0;

      /* free all preview data */
      Alignment = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_preview_container");
      Preview = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_preview_data");

      gtk_widget_destroy(Preview);

      buf = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_preview_image");
      if(buf) g_free(buf);
      gtk_object_set_data(GTK_OBJECT(global->ThemeWin), "theme_preview_image", 0);
}


void theme_display(gint32 themeid)  {

      GtkWidget *Label;
      GtkWidget *Alignment;
      GtkWidget *Preview;
      guchar *buf = 0, *tmp;
      guint32 width, height;

      if(! data->theme[themeid].open)  return;

      Label = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_name");
      gtk_label_set_text(GTK_LABEL(Label), data->theme[themeid].name);

      Label = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_type");
      gtk_label_set_text(GTK_LABEL(Label), data->theme[themeid].type);

      Label = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_version");
      gtk_label_set_text(GTK_LABEL(Label), data->theme[themeid].version);

      Label = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_author");
      gtk_label_set_text(GTK_LABEL(Label), data->theme[themeid].author);

      Label = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_email");
      gtk_label_set_text(GTK_LABEL(Label), data->theme[themeid].email);

      Label = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_location");
      gtk_label_set_text(GTK_LABEL(Label), data->theme[themeid].path);

      tmp = g_strdup_printf("%d", themeid);
      gtk_object_set_data_full(GTK_OBJECT(global->ThemeWin), "theme_preview_selected", tmp, g_free);


      /* free all preview data */
      Alignment = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_preview_container");
      Preview = gtk_object_get_data(GTK_OBJECT(global->ThemeWin), "theme_preview_data");

      theme_preview_free();   

      /* put new preview data */
      if(! (buf = theme_preview_read(themeid, &width, &height)) )  {

            Preview = gtk_label_new("No preview available");
            gtk_object_set_data(GTK_OBJECT(global->ThemeWin), "theme_preview_data", Preview);
            gtk_container_add(GTK_CONTAINER(Alignment), Preview);
            gtk_widget_show_all(Alignment);
            return;
      }

      /* put preview image */
      gtk_object_set_data(GTK_OBJECT(global->ThemeWin), "theme_preview_image", buf);

      tmp = g_strdup_printf("%d", width);
      gtk_object_set_data_full(GTK_OBJECT(global->ThemeWin), "theme_preview_width", tmp, g_free);
      tmp = g_strdup_printf("%d", height);
      gtk_object_set_data_full(GTK_OBJECT(global->ThemeWin), "theme_preview_height", tmp, g_free);

      Preview = gtk_drawing_area_new();
      gtk_drawing_area_size( GTK_DRAWING_AREA (Preview), width, height);
      gtk_object_set_data(GTK_OBJECT(global->ThemeWin), "theme_preview_data", Preview);
      gtk_container_add(GTK_CONTAINER(Alignment), Preview);
      gtk_signal_connect (GTK_OBJECT (Preview), "expose_event", GTK_SIGNAL_FUNC (on_theme_preview_expose), NULL);
      gtk_widget_show_all(Alignment);
}


guchar* theme_preview_read(gint32 themeid, guint32 *width, guint32 *height)  {

      struct stat s;
      guchar *path = data->theme[themeid].path_preview;
      guchar *buf;

      png_structp png_ptr;
      png_infop info_ptr;
      _png_imagedata png_imagedata;
      FILE *infile;


      if(! data->theme[themeid].open)  return FALSE;

      /* simple test */
      if(! path)  return FALSE;

      if(stat(path, &s) < 0)  {

            return FALSE;
      }


      /* load preview image */
      if (! (infile = fopen(path, "rb")) ) {

            fprintf(stderr, "can't open file [%s]\n", path);
            return FALSE;
      }

      if (! readpng_init(infile, &png_ptr, &info_ptr, &png_imagedata) != 0) {

            fprintf(stderr, "[%s] is not a valid PNG file\n", path);
            fclose(infile);
            return FALSE;
      }

      *width = png_imagedata.width;
      *height = png_imagedata.height;

      if(! readpng_decode_image(&png_ptr, &info_ptr, &png_imagedata, TRUE) )  {

            fprintf(stderr, "Unable to decode PNG image: [%s]\n", path);
            return FALSE;
      }
      fclose(infile);

      buf = readpng_get_image(&png_imagedata);

      readpng_cleanup(&png_ptr, &info_ptr, &png_imagedata);

      return buf;
}


void theme_load(gint32 themeid)  {

      printf("%d\n", themeid);
      return;
}

Generated by  Doxygen 1.6.0   Back to index