eca0c96b29bc23bb08588749d55cb49a928d9b9b
[tbo.git] / src / comic.c
1 #include <stdio.h>
2 #include <errno.h>
3 #include <string.h>
4 #include <gtk/gtk.h>
5 #include <glib/gi18n.h>
6 #include <malloc.h>
7 #include <string.h>
8 #include "comic.h"
9 #include "tbo-types.h"
10 #include "tbo-window.h"
11 #include "page.h"
12 #include "comic-load.h"
13 #include "tbo-utils.h"
14
15 Comic *
16 tbo_comic_new (const char *title, int width, int height)
17 {
18     Comic *new_comic;
19
20     new_comic = malloc(sizeof(Comic));
21     snprintf (new_comic->title, 255, "%s", title);
22     new_comic->width = width;
23     new_comic->height = height;
24     new_comic->pages = NULL;
25     tbo_comic_new_page (new_comic);
26
27     return new_comic;
28 }
29
30 void
31 tbo_comic_free (Comic *comic)
32 {
33     GList *p;
34
35     for (p=g_list_first (comic->pages); p; p = g_list_next(p))
36     {
37         tbo_page_free ((Page *) p->data);
38     }
39
40     g_list_free (g_list_first (comic->pages));
41     free (comic);
42 }
43
44 Page *
45 tbo_comic_new_page (Comic *comic){
46     Page *page;
47
48     page = tbo_page_new (comic);
49     comic->pages = g_list_append (comic->pages, page);
50
51     return page;
52 }
53
54 void
55 tbo_comic_del_page (Comic *comic, int nth)
56 {
57     Page *page;
58
59     page = (Page *) g_list_nth_data (g_list_first (comic->pages), nth);
60     comic->pages = g_list_remove (g_list_first (comic->pages), page);
61     tbo_page_free (page);
62 }
63
64 int
65 tbo_comic_len (Comic *comic)
66 {
67     return g_list_length (g_list_first (comic->pages));
68 }
69
70 int
71 tbo_comic_page_index (Comic *comic)
72 {
73     return g_list_position ( g_list_first (comic->pages), comic->pages);
74 }
75
76 int
77 tbo_comic_page_nth (Comic *comic, Page *page)
78 {
79     return g_list_index (g_list_first (comic->pages), page);
80 }
81
82 Page *
83 tbo_comic_next_page (Comic *comic)
84 {
85     if (comic->pages->next)
86     {
87         comic->pages = comic->pages->next;
88         return tbo_comic_get_current_page (comic);
89     }
90     return NULL;
91 }
92
93 Page *
94 tbo_comic_prev_page (Comic *comic)
95 {
96     if (comic->pages->prev)
97     {
98         comic->pages = comic->pages->prev;
99         return tbo_comic_get_current_page (comic);
100     }
101     return NULL;
102 }
103
104 Page *
105 tbo_comic_get_current_page (Comic *comic)
106 {
107     return (Page *)comic->pages->data;
108 }
109
110 void
111 tbo_comic_set_current_page (Comic *comic, Page *page)
112 {
113     comic->pages = g_list_find (g_list_first (comic->pages), page);
114 }
115
116 void
117 tbo_comic_set_current_page_nth (Comic *comic, int nth)
118 {
119     comic->pages = g_list_nth (g_list_first (comic->pages), nth);
120 }
121
122 gboolean
123 tbo_comic_page_first (Comic *comic)
124 {
125     if (tbo_comic_page_index (comic) == 0)
126         return TRUE;
127     return FALSE;
128 }
129
130 gboolean
131 tbo_comic_page_last (Comic *comic)
132 {
133     if (tbo_comic_page_index (comic) == tbo_comic_len (comic) - 1)
134         return TRUE;
135     return FALSE;
136 }
137
138 gboolean
139 tbo_comic_del_current_page (Comic *comic)
140 {
141     int nth;
142     Page *page;
143
144     if (tbo_comic_len (comic) == 1)
145         return FALSE;
146     nth = tbo_comic_page_index (comic);
147
148     page = tbo_comic_next_page (comic);
149     if (page == NULL)
150         page = tbo_comic_prev_page (comic);
151     tbo_comic_del_page (comic, nth);
152     tbo_comic_set_current_page (comic, page);
153     return TRUE;
154 }
155
156 void
157 tbo_comic_save (TboWindow *tbo, char *filename)
158 {
159     GList *p;
160     char buffer[255];
161     FILE *file = fopen (filename, "w");
162     Comic *comic = tbo->comic;
163
164     if (!file)
165     {
166         snprintf (buffer, 255, _("Failed saving: %s"), strerror (errno));
167         GtkWidget *dialog = gtk_message_dialog_new (NULL,
168                                                     GTK_DIALOG_MODAL,
169                                                     GTK_MESSAGE_ERROR,
170                                                     GTK_BUTTONS_CLOSE,
171                                                     buffer);
172         perror (_("failed saving"));
173         gtk_dialog_run (GTK_DIALOG (dialog));
174         gtk_widget_destroy ((GtkWidget *) dialog);
175         return;
176     }
177     get_base_name (filename, comic->title, 255);
178     gtk_window_set_title (GTK_WINDOW (tbo->window), comic->title);
179
180     snprintf (buffer, 255, "<tbo width=\"%d\" height=\"%d\">\n",
181                                                     comic->width,
182                                                     comic->height);
183     fwrite (buffer, sizeof (char), strlen (buffer), file);
184
185     for (p=g_list_first (comic->pages); p; p = g_list_next(p))
186     {
187         tbo_page_save ((Page *) p->data, file);
188     }
189
190     snprintf (buffer, 255, "</tbo>\n");
191     fwrite (buffer, sizeof (char), strlen (buffer), file);
192     fclose (file);
193 }
194
195 void
196 tbo_comic_open (TboWindow *window, char *filename)
197 {
198     Comic *newcomic = tbo_comic_load (filename);
199     int nth;
200     if (newcomic)
201     {
202         tbo_comic_free (window->comic);
203         window->comic = newcomic;
204         gtk_window_set_title (GTK_WINDOW (window->window), window->comic->title);
205
206         for (nth=gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); nth>0; nth--)
207         {
208             gtk_notebook_remove_page (GTK_NOTEBOOK (window->notebook), nth);
209         }
210
211         for (nth=1; nth<tbo_comic_len (window->comic); nth++)
212         {
213             gtk_notebook_insert_page (GTK_NOTEBOOK (window->notebook),
214                                       create_darea (window),
215                                       NULL,
216                                       nth);
217         }
218     }
219 }