GmpcStatsLabel: Port to Vala
[gmpc.git] / src / gmpc-profiles.gob
blob73c85e7fab18abf5ae3c675eef2251e796a8b51b
1 /* Gnome Music Player Client (GMPC)
2  * Copyright (C) 2004-2012 Qball Cow <qball@gmpclient.org>
3  * Project homepage: http://gmpclient.org/
4  
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 requires 2.0.0
21 %ht{
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <time.h>
25 #include <libmpd/libmpd.h>
26 #include "config1.h"
28 %privateheader{
29     #include "main.h"
30         #include "plugin.h"
31     #include "playlist3-messages.h"
32     #define LOG_DOMAIN "Profiles"
34 %h{
35   enum {
36         PROFILE_ADDED,
37         PROFILE_REMOVED,
38         PROFILE_COL_CHANGED,
39     PROFILE_CURRENT
40         };
41   enum {
42     PROFILE_COL_NAME,
43     PROFILE_COL_HOSTNAME,
44     PROFILE_COL_PORT,
45     PROFILE_COL_DO_AUTH,
46     PROFILE_COL_PASSWORD,
47     PROFILE_COL_MUSIC_DIRECTORY,
48     PROFILE_COL_DB_UPDATE_TIME,
49     PROFILE_NUM_COLS
50   };
52   typedef struct {
53     gchar     *id;
54     gchar     *name;
55     gchar     *hostname;
56     int       port;
57     gboolean  do_auth;
58     gchar     *password;
59     gchar     *music_directory;
60     int    db_update_time;
61   }Profile;
64 class Gmpc:Profiles from G:Object
66   private config_obj *profiles = {NULL}; 
67   private Profile **list = {NULL};
68   private int num_profiles = {0};
71     public 
72     int 
73     get_number_of_profiles(self)
74     {
75         return self->_priv->num_profiles;
76     }
78     /* Connect on button press event */
79     private 
80     void
81     connect_to_profile_button(self, GtkWidget *button)
82     {
83         gchar *id = g_object_get_data(G_OBJECT(button), "profile-id");
84         if(id)
85         {
86             self_set_current(self, id);
87             mpd_disconnect(connection);
88             connect_to_mpd();
89         }
90     }
91   /* signal with (self, id) */
92   signal last NONE (INT, INT,STRING)
93   void
94   changed(self,const int changed, const int col, const char * id)
95   {
96         if(changed == PROFILE_ADDED)
97     {
98         GtkWidget *connect_button = gtk_button_new_from_stock(GTK_STOCK_CONNECT);
99         gchar *message = g_markup_printf_escaped("<b>%s:</b> '%s'", _("Added profile"),self_get_name(self,id));
100         playlist3_show_error_message(message, ERROR_INFO);
102         g_object_set_data_full(G_OBJECT(connect_button), "profile-id", g_strdup(id), (GDestroyNotify)g_free);
103         g_signal_connect_swapped(G_OBJECT(connect_button), "clicked", G_CALLBACK(self_connect_to_profile_button), self);
104         playlist3_error_add_widget(connect_button);
105         q_free(message);
107         g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG,"Item %s added\n", id);
108     }
109     else if(changed == PROFILE_REMOVED)
110     {
111                 g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG,"Item %s removed\n", id);
112     }
113         else if(changed == PROFILE_COL_CHANGED)
114         {
115         /* Disabled because of grand spamming charges */
116     /*    
117         gchar *message = g_markup_printf_escaped("<b>%s:</b> '%s'", _("Changed profile"),self_get_name(self,id));
118         playlist3_show_error_message(message, ERROR_INFO);
119         q_free(message);
120         */
121         g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG,"Item %s changed col: %i\n", id, col);
122     }
123   }
126   /**
127    * New
128    */
129   public 
130   GmpcProfiles *
131   new(void)
132   {
133     return (GmpcProfiles *)GET_NEW;
134   }
137   /** 
138    * init 
139    * */
140   init(self)
141   {
142       gchar *url;
143       /**
144        * Get Profile
145        */
146       url = gmpc_get_user_path("profiles.cfg");
147       self->_priv->profiles = cfg_open(url);
148       if(self->_priv->profiles == NULL)
149       {
150           /**
151            * Show gtk error message and quit 
152            */
153           g_log(LOG_DOMAIN, G_LOG_LEVEL_ERROR,"Failed to save/load Profile file:\n%s\n",url);
154           abort();
155       }
156       g_free(url);
157       self_load_from_config(self);
158       if(self->_priv->num_profiles == 0)
159       {
160           self_add_default(self);
161           self_load_from_config(self);
162       }
163   }
164   /**
165    * Add default values
166    */
167   private 
168   void
169   add_default(self)
170   {
171     cfg_set_single_value_as_string(config, "connection", "currentprofile", "Default"); 
172     cfg_set_single_value_as_string(self->_priv->profiles, "Default", "hostname", "localhost");
173     cfg_set_single_value_as_string(self->_priv->profiles, "Default", "name", "Default");
174     cfg_set_single_value_as_string(self->_priv->profiles, "Default", "password","");
175     cfg_set_single_value_as_int(self->_priv->profiles, "Default", "portnumber",6600);
176     cfg_set_single_value_as_int(self->_priv->profiles, "Default", "useauth",FALSE);
178     cfg_set_single_value_as_string(self->_priv->profiles, "Default", "music directory","");
179   }
181   /*********
182    * PROFILE
183    */
184   /* free a profile */
185   public 
186   void
187   free_profile(Profile *profile)
188   {
189     if(profile->name)
190       g_free(profile->name);
191     if(profile->id)
192       g_free(profile->id);
193     if(profile->hostname)
194       g_free(profile->hostname);
195     if(profile->password)
196       g_free(profile->password); 
197     if(profile->music_directory)
198         g_free(profile->music_directory);
200     profile->db_update_time = 0;
201     g_free(profile);
202   }
204   public 
205   Profile * 
206   new_profile(void)
207   {
208     Profile *retv = g_malloc0(sizeof(*retv));
209     /* Init values */
210     retv->name      = NULL;
211     retv->id        = NULL;
212     retv->password  = NULL;
213     retv->hostname  = NULL;
214     retv->port      = 6600;
215     retv->do_auth   = FALSE; 
216     retv->music_directory = NULL;
217     retv->db_update_time = 0;
219     return retv;
220   }
222   private 
223   void
224   load_from_config(self)
225   {
226     conf_mult_obj *iter,*mult = cfg_get_class_list(self->_priv->profiles);
227     /* free the old list */
228     for(iter = mult;iter;iter = iter->next)
229     {
230       Profile *prof = self_new_profile();
232       self->_priv->num_profiles++;
233       self->_priv->list = g_realloc(self->_priv->list, (self->_priv->num_profiles+1)*sizeof(Profile *)); 
234       self->_priv->list[self->_priv->num_profiles] = NULL;
235       self->_priv->list[self->_priv->num_profiles-1] = prof;
237       prof->id = g_strdup(iter->key);
238       prof->name = cfg_get_single_value_as_string(self->_priv->profiles, prof->id, "name");
239       prof->hostname = cfg_get_single_value_as_string(self->_priv->profiles, prof->id, "hostname");
240       prof->password = cfg_get_single_value_as_string(self->_priv->profiles, prof->id, "password");
241       prof->port = cfg_get_single_value_as_int(self->_priv->profiles, prof->id, "portnumber");
242       prof->do_auth = cfg_get_single_value_as_int(self->_priv->profiles, prof->id, "useauth");
244       prof->music_directory = cfg_get_single_value_as_string(self->_priv->profiles, prof->id, "music directory");
245       prof->db_update_time = cfg_get_single_value_as_int_with_default(self->_priv->profiles, prof->id, "db update time",0);
246     }
247     cfg_free_multiple(mult);
248   }
250   /**
251    * get profile
252    */
253   private
254   Profile *
255   get_profile(self , const gchar *id(check null))
256   {
257     int i = 0;
258     if(self->_priv->list)
259     {
260       for(i=0;self->_priv->list[i]; i++)
261       {
262         if(!strcmp(self->_priv->list[i]->id, id))
263           return self->_priv->list[i];
264       }
265     } 
266     return NULL;
267   }
269   /**
270    * get hostname 
271    */
272   public 
273   gchar *
274   get_hostname(self,const gchar *id (check null))
275   {
276     Profile *prof = self_get_profile(self, id);
277     if(!prof)
278       return NULL;
279     return prof->hostname;
280   }
281   /**
282    * get name  
283    */
284   public 
285   const gchar *                                 
286   get_name(self, const gchar *id (check null))
287   {
288     Profile *prof = self_get_profile(self, id);
289     if(!prof)
290       return NULL;
291     return prof->name;
292   }
293   /**
294    * get id 
295    */
296   public 
297   const gchar *                                 
298   get_id(self, const gchar *id (check null))
299   {
300     Profile *prof = self_get_profile(self, id);
301     if(!prof)
302       return NULL;
303     return prof->id;
304   }
305   /**
306    * get password 
307    */
308   public 
309   gchar *                                 
310   get_password(self, const gchar *id (check null))
311   {
312     Profile *prof = self_get_profile(self, id);
313     if(!prof)
314       return NULL;
315     return prof->password;
316   }
318   /**
319    * get music directory 
320    */
321   public 
322   const gchar *                                 
323   get_music_directory(self, const gchar *id (check null))
324   {
325     Profile *prof = self_get_profile(self, id);
326     if(!prof)
327       return NULL;
328     return prof->music_directory;
329   }
330   /**
331    * get music directory 
332    */
333   public 
334   int
335   get_db_update_time(self, const gchar *id (check null))
336   {
337     Profile *prof = self_get_profile(self, id);
338     if(!prof)
339       return 0;
340     return prof->db_update_time;
341   }
342   /**
343    * get port 
344    */
345   public 
346   int                     
347   get_port(self, const gchar *id (check null))
348   {
349     Profile *prof = self_get_profile(self, id);
350     if(!prof)
351       return -1;
352     return prof->port;
353   }
355   /**
356    * get do_auth 
357    */
358   public 
359   gboolean 
360   get_do_auth(self, const gchar *id (check null))
361   {
362     Profile *prof = self_get_profile(self, id);
363     if(!prof)
364       return FALSE;
365     return prof->do_auth;
366   }
368   /**
369    * Create new item
370    */
371   public 
372   gchar *
373   create_new_item(self, const gchar *id)
374   {
375         return self_create_new_item_with_name(self, id, "New Profile");
376   }
377   public 
378   gchar*
379   create_new_item_with_name(self, const gchar *id, const gchar *name)
380   {
381     Profile *prof = g_malloc0(sizeof(*prof));
382     if(!id)
383       prof->id = g_strdup_printf("%u",g_random_int());
384     else
385       prof->id = g_strdup(id);
386     if(!name)
387         prof->name = g_strdup("New Profile");
388     else
389         prof->name = g_strdup(name);
390     prof->hostname = g_strdup("localhost");
391     prof->password= g_strdup("");
392     prof->port = 6600;
393     prof->do_auth = 0;
394    
395         /* safe this to the config file */ 
396     cfg_set_single_value_as_string(self->_priv->profiles, prof->id, "name", prof->name);
397     cfg_set_single_value_as_string(self->_priv->profiles, prof->id, "hostname", prof->hostname);
398     cfg_set_single_value_as_string(self->_priv->profiles, prof->id, "password", prof->password);
399     cfg_set_single_value_as_int(self->_priv->profiles, prof->id, "portnumber", prof->port);
400     cfg_set_single_value_as_int(self->_priv->profiles, prof->id, "useauth", prof->do_auth);
401     cfg_set_single_value_as_string(self->_priv->profiles, prof->id, "music directory", prof->music_directory);
403     cfg_get_single_value_as_int_with_default(self->_priv->profiles, prof->id, "db update time",(int)(prof->db_update_time));
405     self->_priv->num_profiles++;
406     self->_priv->list = g_realloc(self->_priv->list, (self->_priv->num_profiles+1)*sizeof(Profile *));     
407     self->_priv->list[self->_priv->num_profiles] = NULL;
408     self->_priv->list[self->_priv->num_profiles-1] = prof;
409     /* propagate */
410     self_changed(self,PROFILE_ADDED,-1, prof->id);
411     return prof->id;
412   }
413   public
414   void
415   remove_item(self, const gchar *id)
416   {
417     gchar *message = NULL;
418     int i=0;
419     Profile *prof =  self_get_profile(self, id);
420     if(!prof)
421     {
422         g_log(LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Trying to remove not-existing profile: %s\n", id);
423       return;
424     }
425     /* Generate removal message before the actual profile is destroyed */
426     message = g_markup_printf_escaped("<b>%s:</b> '%s'", _("Removed profile"),self_get_name(self,id));
428     for(i=0; self->_priv->list[i] && self->_priv->list[i] != prof;i++);
429     if(self->_priv->list[i] == prof)
430     {
431       for(; self->_priv->list[i] ;i++)
432       {
433         self->_priv->list[i] = self->_priv->list[i+1];
434       }
435       self->_priv->num_profiles--;
436       self->_priv->list = g_realloc(self->_priv->list, (self->_priv->num_profiles+1)*sizeof(Profile *));     
437       
438       cfg_remove_class(self->_priv->profiles, (char *)id);
439       self_free_profile(prof);
440     }
442     /* Display the message */
443     playlist3_show_error_message(message, ERROR_INFO);
444     q_free(message);
446     self_changed(self,PROFILE_REMOVED,-1, id);
447   }
449   /**
450    * GET CURRENT
451    */
452   public
453   gchar *
454   get_current(self)
455   {
456                 gchar *id = cfg_get_single_value_as_string_with_default(config, "connection", "currentprofile", "Default");
457                 Profile *prof = self_get_profile(self, id);
458                 /* if not available get the first one */
459                 if(!prof)
460                 {
461                         g_free(id);
462             if(self->_priv->list != NULL && self->_priv->list[0])
463             {
464                             self_set_current(self, self->_priv->list[0]->id);
465             } else {
466                 self_add_default(self);    
467                 self_load_from_config(self);
468                 self_changed(self, PROFILE_ADDED, -1,"Default");
469             }
470                         id = cfg_get_single_value_as_string_with_default(config, "connection", "currentprofile", "Default");
471                 }
472                 return id; 
473   }
475   signal last NONE (STRING) 
476   void
477   set_current(self, const gchar *id(check null))
478   {
479     Profile *prof = self_get_profile(self, id);
480     if(prof){
481         cfg_set_single_value_as_string(config, "connection", "currentprofile", (char *)id);
483         self_changed(self, PROFILE_CURRENT,0, id); 
484     }
486   }
487   public
488   GList *
489   get_profiles_ids(self)
490   {
491     GList *list = NULL;
492     int i=0;
493     for(i=0; self->_priv->list[i] ; i++)
494     {
495       list = g_list_append(list,g_strdup(self->_priv->list[i]->id));
496     }
497     return list;
498   }
500   /**
501    * set field
502    */
503   public
504   void
505   set_name(self, const gchar *id (check null), const gchar *value (check null))
506   {
507     Profile *prof = self_get_profile(self, id);
509     if(!prof)
510       return ;                              
511         
512     if((value && prof->name &&  g_utf8_collate(value, prof->name) == 0)|| (value == NULL && prof->name == NULL))
513         return;
515     if(prof->name)
516       g_free(prof->name);
518     prof->name = g_strdup(value);
519     cfg_set_single_value_as_string(self->_priv->profiles, (char *)id, "name",prof->name);
520     self_changed(self,PROFILE_COL_CHANGED, PROFILE_COL_NAME,id);
521   }
523   public
524   void
525   set_hostname(self, const gchar *id (check null), const gchar *value (check null))
526   {
527     Profile *prof = self_get_profile(self, id);
528     if(!prof)
529       return ;                              
531     if((value && prof->hostname &&  g_utf8_collate(value, prof->hostname) == 0)|| (value == NULL && prof->hostname == NULL))
532         return;
534     if(prof->hostname)
535       g_free(prof->hostname);
536     prof->hostname = g_strdup(value);
537     cfg_set_single_value_as_string(self->_priv->profiles, (char *)id, "hostname",prof->hostname);
538     self_changed(self,PROFILE_COL_CHANGED, PROFILE_COL_HOSTNAME,id);
539   }
540         /**
541          * Set Password
542          */
543   public
544   void
545   set_password(self,const gchar *id (check null), gchar *value)
546   {
547     Profile *prof = self_get_profile(self, id);
548     if(!prof)
549       return ;                              
551     if((value && prof->password &&  g_utf8_collate(value, prof->password) == 0)|| (value == NULL && prof->password == NULL))
552         return;
554     if(prof->password)
555       g_free(prof->password);
556     if(value)
557       prof->password = g_strdup(value);
558     else
559       prof->password = g_strdup("");
560     cfg_set_single_value_as_string(self->_priv->profiles, (char *)id, "password",prof->password);
561     self_changed(self,PROFILE_COL_CHANGED, PROFILE_COL_PASSWORD,id);
562   }
564         /**
565          * Set Port
566          */
567   public
568   void
569   set_port(self, const gchar *id (check null), int value)
570   {
571     Profile *prof = self_get_profile(self, id);
572     if(!prof)
573       return ;                              
574     if(value == prof->port)
575             return;
576     prof->port = value;
577     cfg_set_single_value_as_int(self->_priv->profiles, (char *)id, "portnumber",prof->port);
578     self_changed(self,PROFILE_COL_CHANGED, PROFILE_COL_PORT,id);
579   }
581   /**
582    * Set music directory 
583    */
584   public
585   void
586   set_music_directory(self,const gchar *id (check null), gchar *value)
587   {
588       Profile *prof = self_get_profile(self, id);
589       if(!prof)
590           return ;                              
592       if((value && prof->music_directory &&  g_utf8_collate(value, prof->music_directory) == 0)|| (value == NULL && prof->music_directory == NULL))
593           return;
595       if(prof->music_directory)
596           g_free(prof->music_directory);
597       if(value)
598           prof->music_directory = g_strdup(value);
599       else
600           prof->music_directory = g_strdup("");
601       cfg_set_single_value_as_string(self->_priv->profiles, (char *)id, "music directory",prof->music_directory);
602       self_changed(self,PROFILE_COL_CHANGED, PROFILE_COL_MUSIC_DIRECTORY,id);
603   }
606     public 
607     void 
608     set_db_update_time(self, const gchar *id (check null), int value)
609     {
611         Profile *prof = self_get_profile(self, id);
612         if(!prof)
613           return ;                              
615         if(value == prof->db_update_time)  return;
616     
617         cfg_set_single_value_as_int(self->_priv->profiles, (char *)id, "db update time",(int)value);
618         self_changed(self,PROFILE_COL_CHANGED, PROFILE_COL_DB_UPDATE_TIME,id);
619     }
620         /**
621          * Set do auth
622          */
623   public
624   void
625   set_do_auth(self,const gchar *id (check null), int value)
626   {
627     Profile *prof = self_get_profile(self, id);
628     if(!prof)
629       return ;                              
630     if(prof->do_auth == value)
631             return;
632     prof->do_auth = value;
633     cfg_set_single_value_as_int(self->_priv->profiles,(char *)id, "useauth",prof->do_auth);
634     self_changed(self,PROFILE_COL_CHANGED, PROFILE_COL_DO_AUTH,id);
635   }
636         /**
637    * Has profile with id
638    */
639         public
640         gboolean        
641         has_profile(self, const gchar *id (check null))
642         {
643                 Profile *prof = self_get_profile(self, id);
644                 if(!prof)
645                         return FALSE;
646                 else 
647                         return TRUE;                                    
649         }
650         override (G:Object)
651         void
652         finalize (G:Object *obj)
653         {
654                 Self *self = GMPC_PROFILES(obj);
655                 if(self->_priv->list)
656                 {
657                         int i = 0;
658                         do{
659                                 Profile * prof = self->_priv->list[i];
660                                 self_free_profile(prof);
661                                 self->_priv->list[i] = NULL;
662                                 i++;
663                         }while(self->_priv->list[i]);
664                         g_free(self->_priv->list);
665                         self->_priv->list = NULL;
666                 }
667                 if(self->_priv->profiles)
668                 {
669                         cfg_close(self->_priv->profiles);
670                         self->_priv->profiles=  NULL;
671                 }
672                 PARENT_HANDLER(obj);
673         }
674         
675         public
676         void
677         set_profile_from_name(self, const gchar *name (check null))
678         {
679         GList *iter, *items = gmpc_profiles_get_profiles_ids(gmpc_profiles);
680         for (iter = g_list_first(items); iter; iter = g_list_next(iter))
681         {
682                         const char *pname = gmpc_profiles_get_name(gmpc_profiles, 
683                                         (const gchar *)iter->data);
684                         if (pname != NULL && 
685                                 g_utf8_collate(name, pname) == 0)
686             {
687                 connection_set_current_profile((const gchar *)iter->data);
688                 break;
689             }
690         }
691         g_list_foreach(items, (GFunc) g_free, NULL);
692         g_list_free(items);
693         }