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