1 /*
2 ** TleenX2 (Tlen.pl Client)
3 ** Copyright (c) 2002-2003 Hubert Soko�owski <who_ami@tlen.pl>
4 ** Pawe� Bili�ski <rael@fr.pl>
5 **
6 ** This code is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU General Public License.
8 **
9 */
10
11
12 #include "main.h"
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <unistd.h>
19
20 #include "archive.h"
21 #include "support.h"
22 #include "utils.h"
23
24 GList *mesgsent_list;
25 GList *mesgsent2_list;
26 GList *mesgrecv_list;
27 GList *mesgrecv2_list;
28 GList *chat2_list;
29 GList *arch_list;
30
31
treeview_chat_selection_cb(GtkTreeSelection * selection,gpointer nic)32 void treeview_chat_selection_cb (GtkTreeSelection *selection, gpointer nic)
33 {
34 GtkTreeIter iter;
35 GtkTreeView *treeview;
36 GtkTreeModel *model;
37 GtkWidget *widget2;
38 struct arch_mesg *m;
39 struct arch_mesg *mesg;
40 GList *l = chat2_list;
41 gchar *s;
42 gboolean jid;
43
44 treeview = (GtkTreeView*)lookup_widget(window_archive, "treeview_chat");
45 selection = gtk_tree_view_get_selection(treeview);
46 if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
47 return;
48 model = gtk_tree_view_get_model (treeview);
49 gtk_tree_model_get (model, &iter, 2, &jid, -1);
50
51 if(!jid)
52 {
53 gtk_tree_model_get (model, &iter, 1, &mesg, -1);
54 widget2 = lookup_widget(window_archive, "textview_chat");
55 textview_clear(widget2);
56 while(l)
57 {
58 m = (struct arch_mesg *) l->data;
59 if((!strcmp(mesg->jid, m->jid)) && (!strncmp(mesg->date, m->date, 10)))
60 {
61 gchar *tag = NULL;
62
63 if(m->from)
64 tag="text";
65 textview_append(widget2, m->date, 0, "date", NULL);
66 textview_append(widget2, " ", 0, tag, NULL);
67 s = utf(m->message);
68 textview_append(widget2, s, 0, tag, NULL);
69 g_free(s);
70 textview_append(widget2, "\n", 0, NULL, NULL);
71 }
72 l = l->next;
73 }
74 }
75 }
76
77
78 static
jid_added(GList * l,gchar * jid)79 gint jid_added(GList *l, gchar *jid)
80 {
81 while(l)
82 {
83 if(!strcmp(jid, (gchar *)l->data))
84 return 1;
85 l=l->next;
86 }
87 return 0;
88 }
89
90 static
date_added(GList * l,gchar * date)91 gint date_added(GList *l, gchar *date)
92 {
93 while(l)
94 {
95 if(!strncmp(date, (gchar *)l->data, 10))
96 return 1;
97 l=l->next;
98 }
99 return 0;
100 }
101
102 static
create_model(void)103 GtkTreeModel *create_model(void)
104 {
105 GtkListStore *store;
106 GtkTreeIter iter;
107 GList *l;
108 struct arch_file *a;
109
110 store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
111 l=arch_list;
112 while(l)
113 {
114 a=(struct arch_file*) l->data;
115 gtk_list_store_append (store, &iter);
116 gtk_list_store_set (store, &iter,
117 0, strrchr(a->filename,'/')+1,
118 1, a->date,
119 2, a->filename,
120 -1);
121 l = l->next;
122 }
123
124
125 return GTK_TREE_MODEL (store);
126 }
127
128 static
create_model2(void)129 GtkTreeModel *create_model2 (void)
130 {
131 GtkTreeStore *model;
132 GtkTreeIter iter;
133 GList *l=chat2_list, *l2=NULL;
134 struct arch_mesg *mesg;
135 gchar *item;
136
137 model = gtk_tree_store_new (3,G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
138 while(l)
139 {
140 mesg=(struct arch_mesg*)l->data;
141 item=g_strdup(mesg->jid);
142 if(!jid_added(l2,item))
143 {
144 l2=g_list_append(l2,(gpointer)item);
145 gtk_tree_store_append (model, &iter, NULL);
146 gtk_tree_store_set (model, &iter,0,item,1,NULL,2,TRUE,-1);
147
148 //dodaj podrzedne elementy
149 {
150 GList *l=chat2_list,*l2=NULL;
151 struct arch_mesg *m;
152 GtkTreeIter child_iter;
153
154 while(l)
155 {
156 m=(struct arch_mesg*)l->data;
157 if(!strcmp(mesg->jid,m->jid))
158 {
159 item=g_strdup(m->date);
160 if(!date_added(l2,item))
161 {
162 l2=g_list_append(l2,(gpointer)item);
163 gtk_tree_store_append (model, &child_iter, &iter);
164 gtk_tree_store_set (model, &child_iter,0,item, 1, m,2,FALSE, -1);
165 }
166 else//FIXME
167 g_free(item);
168 }
169 l=l->next;
170 }
171 //FIXME sprawdz to!!!
172 // l=l2;
173 // while(l)
174 // {
175 // g_free((gchar*)l->data);
176 // l=l->next;
177 // }
178 g_list_free(l2);
179 }
180 }
181 else//FIXME
182 g_free(item);
183 l=l->next;
184 }
185 // l=l2;
186 // while(l)
187 // {
188 // g_free((gchar*)l->data);
189 // l=l->next;
190 // }
191 g_list_free(l2);
192 return GTK_TREE_MODEL (model);
193 }
194
treeview_chat_refresh()195 void treeview_chat_refresh()
196 {
197 GtkTreeView *treeview;
198 GtkTreeModel *model;
199
200 treeview = (GtkTreeView *) lookup_widget(window_archive, "treeview_chat");
201 model = create_model2();
202 gtk_tree_view_set_model(treeview, model);
203 g_object_unref (G_OBJECT (model));
204 }
205
arch_list_load()206 void arch_list_load()
207 {
208 gchar *filename;
209 gint i;
210 struct arch_file *arch;
211 struct stat buf;
212
213 filename = g_strdup_printf("%s/.tleenx/rozmowy.%s", getenv("HOME"),
214 pname);
215 if(!file_exists(filename) || stat(filename, &buf))
216 {
217 g_free(filename);
218 return;
219 }
220 arch = (struct arch_file *) g_malloc(sizeof(*arch));
221 arch->filename = filename;
222 arch->date = get_localtime(&(buf.st_mtime));
223 arch_list = g_list_append(arch_list, arch);
224 for(i=1;;i++)
225 {
226 filename=g_strdup_printf("%s/.tleenx/rozmowy.%s.%d", getenv("HOME"),
227 pname, i);
228 if(!file_exists(filename) || stat(filename,&buf))
229 {
230 g_free(filename);
231 break;
232 }
233 arch = (struct arch_file *) g_malloc(sizeof(*arch));
234 arch->filename = filename;
235 arch->date = get_localtime(&(buf.st_mtime));
236 arch_list = g_list_append(arch_list, arch);
237 }
238 }
239
free_arch_mesg(struct arch_mesg * mesg)240 void free_arch_mesg(struct arch_mesg *mesg)
241 {
242 g_free(mesg->jid);
243 g_free(mesg->date);
244 g_free(mesg->message);
245 g_free(mesg);
246 }
247
248 static
free_arch_file(struct arch_file * arch)249 void free_arch_file(struct arch_file *arch)
250 {
251 g_free(arch->filename);
252 g_free(arch->date);
253 g_free(arch);
254 }
255
256 static
arch_list_clear()257 void arch_list_clear()
258 {
259 GList *l = arch_list;
260 struct arch_file *a;
261
262 while(l)
263 {
264 a = (struct arch_file *) l->data;
265 free_arch_file(a);
266 l = l->next;
267 }
268 g_list_free(arch_list);
269 arch_list = NULL;
270 }
271
clean_archive()272 void clean_archive()
273 {
274 if(arch_list)
275 arch_list_clear();
276 if(mesgsent_list)
277 {
278 mesgsent_list_clear(mesgsent_list);
279 mesgsent_list=NULL;
280 }
281 if(mesgsent2_list)
282 {
283 g_list_free(mesgsent2_list);
284 mesgsent2_list=NULL;
285 }
286 if(mesgrecv_list)
287 {
288 mesgsent_list_clear(mesgrecv_list);
289 mesgrecv_list=NULL;
290 }
291 if(mesgrecv2_list)
292 {
293 g_list_free(mesgrecv2_list);
294 mesgrecv2_list=NULL;
295 }
296 if(chat2_list)
297 {
298 mesgsent_list_clear(chat2_list);
299 chat2_list=NULL;
300 }
301 }
302
mesgsent_list_clear(GList * list)303 void mesgsent_list_clear(GList *list)
304 {
305 GList *l=list;
306 struct arch_mesg *mesg;
307
308 while(l)
309 {
310 mesg=(struct arch_mesg*)l->data;
311 free_arch_mesg(mesg);
312 l=l->next;
313 }
314 g_list_free(list);
315 }
316
317 static
read_message(FILE * f)318 gchar *read_message(FILE *f)
319 {
320 gchar c, *s=NULL, *message;
321 gint i=0,l;
322
323 l=30;
324 s=(gchar*)g_malloc(l*sizeof(gchar));
325 while(1)
326 {
327 fscanf(f,"%c",&c);
328 if(feof(f))
329 break;
330 if(c != '#')
331 break;
332 for(;1;i++)
333 {
334 fread(&c,1,1,f);
335 if(i==l)
336 s=(gchar *)g_realloc(s,(l+=30)*sizeof(gchar));
337 s[i]=c;
338 if(c == '\n')
339 break;
340 }
341 }
342 s[i]='\0';
343 message=g_strdup(s);
344 if(s)
345 g_free(s);
346 return message;
347 }
348
349 static
read_mesg(FILE * f,struct arch_mesg * mesg)350 void read_mesg(FILE *f, struct arch_mesg *mesg)
351 {
352 gchar jid[40];
353 gint D,M,Y,h,m,s;
354 gchar sD[3],sM[3],sh[3],sm[3],ss[3];
355
356 fscanf(f,"%s\n",jid);
357 fscanf(f,"%d %d %d\n",&D,&M,&Y);
358 fscanf(f,"%d %d %d\n",&h,&m,&s);
359 if(D<10)
360 sprintf(sD,"0%d",D);
361 else
362 sprintf(sD,"%d",D);
363 if(M<10)
364 sprintf(sM,"0%d",M);
365 else
366 sprintf(sM,"%d",M);
367 if(h<10)
368 sprintf(sh,"0%d",h);
369 else
370 sprintf(sh,"%d",h);
371 if(m<10)
372 sprintf(sm,"0%d",m);
373 else
374 sprintf(sm,"%d",m);
375 if(s<10)
376 sprintf(ss,"0%d",s);
377 else
378 sprintf(ss,"%d",s);
379 mesg->jid=g_strdup(jid);
380 mesg->date=g_strdup_printf("%d.%2s.%2s %2s:%2s:%2s",Y,sM,sD,sh,sm,ss);
381 mesg->message = read_message(f);
382 }
383
archive_read_mesgsent()384 int archive_read_mesgsent()
385 {
386 struct arch_mesg *mesg;
387 FILE *f;
388 gchar *filename,c;
389
390 filename=g_strdup_printf("%s/.tleenx/wiadomosci.%s",getenv("HOME"), pname);
391 f=fopen(filename, "r");
392 g_free(filename);
393 if(!f)
394 {
395 // g_print("b��d: nie mo�na utworzy� pliku\n");
396 // gtk_exit(1);
397 return 2;
398 }
399 while(!feof(f))
400 {
401 fscanf(f,"%c\n",&c);
402 mesg=(struct arch_mesg *)g_malloc(sizeof(*mesg));
403 read_mesg(f,mesg);
404 if(c == '>')
405 mesgsent_list=g_list_append(mesgsent_list,(gpointer)mesg);
406 else
407 mesgrecv_list=g_list_append(mesgrecv_list,(gpointer)mesg);
408 // skip_mesg(f);
409 if(feof(f))
410 break;
411 fseek(f,-1,SEEK_CUR);
412 }
413 fclose(f);
414 return 0;
415 }
416
archive_read_chat(const gchar * filename)417 int archive_read_chat(const gchar *filename)
418 {
419 struct arch_mesg *mesg;
420 FILE *f;
421 gchar c;
422
423 f=fopen(filename, "r");
424 if(!f)
425 {
426 // g_print("b��d: nie mo�na utworzy� pliku\n");
427 // gtk_exit(1);
428 return 2;
429 }
430 if(chat2_list)
431 {
432 mesgsent_list_clear(chat2_list);
433 chat2_list=NULL;
434 }
435 while(!feof(f))
436 {
437 fscanf(f,"%c\n",&c);
438 mesg=(struct arch_mesg *)g_malloc(sizeof(*mesg));
439 read_mesg(f,mesg);
440 if(c == '>')
441 mesg->from=0;
442 else
443 mesg->from=1;
444 chat2_list=g_list_append(chat2_list,(gpointer)mesg);
445 // skip_mesg(f);
446 if(feof(f))
447 break;
448 fseek(f,-1,SEEK_CUR);
449 }
450 fclose(f);
451 return 0;
452 }
453
454 static
treeview_sent_create_model(GList * l)455 GtkTreeModel *treeview_sent_create_model(GList *l)
456 {
457 GtkTreeStore *model;
458 GtkTreeIter iter;
459 struct arch_mesg *a;
460
461 model = gtk_tree_store_new(3, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING);
462 while(l)
463 {
464 a = (struct arch_mesg *) l->data;
465 gtk_tree_store_append (model, &iter, NULL);
466 gtk_tree_store_set (model, &iter,
467 0, a,
468 1, a->jid,
469 2, a->date,
470 -1);
471 l = l->next;
472 }
473
474 return GTK_TREE_MODEL (model);
475 }
476
477 static
treeview_sent_selection_cb(GtkTreeSelection * selection,gpointer list)478 void treeview_sent_selection_cb (GtkTreeSelection *selection,
479 gpointer list)
480 {
481 GtkTreeIter iter;
482 GtkTreeModel *model;
483 GtkWidget *treeview, *textview;
484 struct arch_mesg *mesg;
485 gchar *s;
486 GList *l = (GList *)list;
487
488 if((l == mesgsent_list) || (l == mesgsent2_list))
489 {
490 treeview = lookup_widget(window_archive, "treeview_sent");
491 textview = lookup_widget(window_archive, "textview_sent");
492 }
493 else
494 {
495 treeview = lookup_widget(window_archive, "treeview_received");
496 textview = lookup_widget(window_archive, "textview_received");
497 }
498
499 if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
500 return;
501 model = gtk_tree_view_get_model (GTK_TREE_VIEW(treeview));
502 gtk_tree_model_get (model, &iter, 0, &mesg, -1);
503
504 textview_clear(textview);
505 s = utf(mesg->message);
506 textview_append(textview, s, 0, NULL, NULL);
507 g_free(s);
508 }
509
510 static
refresh_treeview_sent(GtkWidget * treeview,GList * l)511 void refresh_treeview_sent(GtkWidget *treeview, GList *l)
512 {
513 GtkTreeSelection *selection;
514 GtkTreeModel *model;
515
516 model = treeview_sent_create_model(l);
517 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), model);
518 g_object_unref (G_OBJECT (model));
519 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
520 g_signal_connect (selection, "changed",
521 G_CALLBACK (treeview_sent_selection_cb), l);
522 }
523
treeview_sent_sort_by_name()524 void treeview_sent_sort_by_name()
525 {
526 GtkWidget *treeview;
527
528 treeview = lookup_widget(window_archive, "treeview_sent");
529 refresh_treeview_sent(treeview, mesgsent_list);
530 }
531
treeview_sent_sort_by_date()532 void treeview_sent_sort_by_date()
533 {
534 GtkWidget *treeview;
535
536 treeview = lookup_widget(window_archive, "treeview_sent");
537 refresh_treeview_sent(treeview, mesgsent2_list);
538 }
539
treeview_received_sort_by_name()540 void treeview_received_sort_by_name()
541 {
542 GtkWidget *treeview;
543
544 treeview = lookup_widget(window_archive, "treeview_received");
545 refresh_treeview_sent(treeview, mesgrecv_list);
546 }
547
treeview_received_sort_by_date()548 void treeview_received_sort_by_date()
549 {
550 GtkWidget *treeview;
551
552 treeview = lookup_widget(window_archive, "treeview_received");
553 refresh_treeview_sent(treeview, mesgrecv2_list);
554 }
555
treeview_archives_refresh()556 void treeview_archives_refresh()
557 {
558 GtkTreeView *treeview;
559 GtkTreeModel *model;
560
561 treeview = (GtkTreeView *) lookup_widget(window_archive,"treeview_archives");
562 model = create_model();
563 gtk_tree_view_set_model(treeview, model);
564 g_object_unref (G_OBJECT (model));
565 }
566
567 static
compare_func(gconstpointer d1,gconstpointer d2)568 gint compare_func(gconstpointer d1, gconstpointer d2)
569 {
570 struct arch_mesg *mesg1,*mesg2;
571
572 mesg1=(struct arch_mesg*)d1;
573 mesg2=(struct arch_mesg*)d2;
574 return strcmp(mesg1->jid,mesg2->jid);
575 }
576
577 static
mesglist_sort(GList * l,GList ** l2)578 void mesglist_sort(GList *l, GList **l2)
579 {
580 struct arch_mesg *mesg;
581
582 while(l)
583 {
584 if(!(l->next))
585 break;
586 l=l->next;
587 }
588 while(l)
589 {
590 mesg=(struct arch_mesg*)l->data;
591 *l2=g_list_insert_sorted(*l2,(gpointer)mesg,compare_func);
592 l=l->prev;
593 }
594 }
595
mesgsent_sort_by_date()596 void mesgsent_sort_by_date()
597 {
598 if(!mesgsent2_list)
599 mesglist_sort(mesgsent_list, &mesgsent2_list);
600 }
601
mesgrecv_sort_by_date()602 void mesgrecv_sort_by_date()
603 {
604 if(!mesgrecv2_list)
605 mesglist_sort(mesgrecv_list, &mesgrecv2_list);
606 }
607
608 static
mesg_delete(GList ** list,gchar * jid,gchar * date)609 void mesg_delete(GList **list, gchar *jid, gchar *date)
610 {
611 struct arch_mesg *mesg;
612 GList *l;
613
614 l = *list;
615 while(l)
616 {
617 mesg = (struct arch_mesg*) l->data;
618 if(!strcmp(mesg->jid, jid) && !strcmp(mesg->date, date))
619 {
620 // free_arch_mesg(mesg);
621 // *list = g_list_remove(*list, l->data);
622 g_print("link deleted\n");
623 if(*list)
624 g_print("list ok\n");
625 else
626 g_print("list NULL\n");
627 break;
628 }
629 l=l->next;
630 }
631 }
632
mesgsent_delete(gchar * jid,gchar * date)633 void mesgsent_delete(gchar *jid, gchar *date)
634 {
635 mesg_delete(&mesgsent_list, jid, date);
636 // g_list_free(mesgsent2_list);
637 // mesgsent2_list=NULL;
638 mesgsent_sort_by_date();
639 }
640
mesgrecv_delete(gchar * jid,gchar * date)641 void mesgrecv_delete(gchar *jid, gchar *date)
642 {
643 mesg_delete(&mesgrecv_list, jid, date);
644 g_list_free(mesgrecv2_list);
645 mesgrecv2_list=NULL;
646 }
647