00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00027 #include <ctype.h>
00028 #include "erGtkEntryFilter.h"
00029 
00030 static int is_ipv4(const char *ip)
00031 {
00032     int i;
00033     int n;
00034     int field;
00035     int ok = TRUE;
00036     const char *cp;
00037 
00038     cp = ip;
00039     for (field = 0 ; field < 4 && ok ; field++)
00040     {
00041         i = 0;
00042         n = 0;
00043         while (isdigit(*cp)  &&  n < 4)
00044         {
00045             i = (10 * i) + (*cp - '0');
00046             n = n + 1;
00047             cp++;
00048         }
00049         if (n < 1  ||  n > 3  ||  i > 255)
00050         {
00051             ok = FALSE;
00052         }
00053 
00054         if (field < 3)
00055         {
00056             if (*cp == '.')
00057             {
00058                 cp++;
00059                 if (!isdigit(*cp))
00060                 {
00061                     ok = FALSE;
00062                 }
00063             }
00064             else
00065             {
00066                 ok = FALSE;
00067             }
00068         }
00069         else
00070         {
00071             if (*cp)
00072             {
00073                 ok = FALSE;
00074             }
00075         }
00076     }
00077 
00078     return ok;
00079 }
00080 
00081 static int is_ipv4_incomplete(const char *ip)
00082 {
00083     int i;
00084     int n;
00085     int field;
00086     int ok = TRUE;
00087     const char *cp;
00088 
00089     cp = ip;
00090     for (field = 0 ; field < 4 && *cp && ok ; field++)
00091     {
00092 
00093         i = 0;
00094         n = 0;
00095         while (isdigit(*cp)  &&  n < 4)
00096         {
00097             i = (10 * i) + (*cp - '0');
00098             n = n + 1;
00099             cp++;
00100         }
00101         if (n < 1  ||  n > 3  ||  i > 255)
00102         {
00103             ok = FALSE;
00104         }
00105 
00106         if (*cp)
00107         {
00108             if (field < 3)
00109             {
00110                 if (*cp == '.')
00111                 {
00112                     cp++;
00113                 }
00114                 else
00115                 {
00116                     ok = FALSE;
00117                 }
00118             }
00119             else
00120             {
00121                 if (*cp)
00122                 {
00123                     ok = FALSE;
00124                 }
00125             }
00126         }
00127     }
00128 
00129     return ok;
00130 }
00131 
00132 ipAddress_t ipv4_filter_check_address (const gchar *text)
00133 {
00134     if (!text)
00135     {
00136         return ipv4Incomplete_e;
00137     }
00138 
00139     if (is_ipv4(text))
00140     {
00141         return ipv4Complete_e;
00142     }
00143 
00144     if (is_ipv4_incomplete(text))
00145     {
00146         return ipv4Incomplete_e;
00147     }
00148     
00149     return ipv4Error_e;
00150 }
00151 
00152 static gboolean check_string (gint filter, const gchar *str)
00153 {
00154     ipAddress_t ret;
00155     
00156     ret = ipv4_filter_check_address (str);
00157     if ((ret == ipv4Complete_e) || (ret == ipv4Incomplete_e))
00158     {
00159         return TRUE;
00160     }
00161     else
00162     {
00163         return FALSE;
00164     }
00165 }
00166 
00167 static void insert_filter (GtkEditable *editable, 
00168                            const gchar *text, 
00169                            gint length, 
00170                            gint *pos, 
00171                            gpointer data)
00172 {
00173     gint   filter;
00174     gchar *str, *pre, *post;
00175 
00176     filter = GPOINTER_TO_INT (data);
00177     pre  = gtk_editable_get_chars (editable, 0, *pos);
00178     post = gtk_editable_get_chars (editable, *pos, -1);
00179 
00180     str = g_strconcat (pre, text, post, NULL);
00181 
00182     if (!check_string (filter, str))
00183     {
00184         g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
00185     }
00186 
00187     g_free (pre);
00188     g_free (post);
00189     g_free (str);
00190 }
00191 
00192 static void delete_filter (GtkEditable *editable, 
00193                            gint start, 
00194                            gint end, 
00195                            gpointer data)
00196 {
00197     gint   filter;
00198     gchar *str, *pre, *post;
00199 
00200     filter = GPOINTER_TO_INT (data);
00201     pre  = gtk_editable_get_chars (editable, 0, start);
00202     post = gtk_editable_get_chars (editable, end, -1);
00203 
00204     str = g_strconcat (pre, post, NULL);
00205 
00206     if (!check_string (filter, str))
00207     {
00208         g_signal_stop_emission_by_name (G_OBJECT (editable), "delete-text");
00209     }
00210 
00211     g_free (pre);
00212     g_free (post);
00213     g_free (str);
00214 }
00215 
00216 void ipv4_filter_init(GtkEntry *entry)
00217 {
00218     g_signal_connect (G_OBJECT (entry), "insert-text",
00219                     G_CALLBACK (insert_filter), NULL);
00220 
00221     g_signal_connect (G_OBJECT (entry), "delete-text",
00222                     G_CALLBACK (delete_filter), NULL);
00223 
00224 }
00225 
00226 static void insert_integer_filter(GtkEditable *editable, 
00227                                 const gchar *text, 
00228                                 gint text_length, 
00229                                 gint *pos, 
00230                                 gpointer data)
00231 {
00232      int i, j; 
00233      gchar *result;
00234 
00235      if (text_length > 0)
00236      {
00237          
00238          result = g_new( gchar, text_length ); 
00239          for ( i = 0, j = 0; i < text_length; ++i )
00240          {
00241              if ( isdigit(text[i]) )  
00242              {
00243                  result[j++] = text[i]; 
00244              }
00245          }
00246          result[j] = '\0'; 
00247 
00248          if ( j > 0 ) 
00249          { 
00250              gtk_signal_handler_block_by_func( GTK_OBJECT(editable), 
00251                      GTK_SIGNAL_FUNC(insert_integer_filter), data ); 
00252              gtk_editable_insert_text( editable, result, j, pos ); 
00253              gtk_signal_handler_unblock_by_func( GTK_OBJECT(editable), 
00254                      GTK_SIGNAL_FUNC(insert_integer_filter), data ); 
00255          } 
00256          gtk_signal_emit_stop_by_name( GTK_OBJECT(editable), 
00257                                        "insert-text" ); 
00258       
00259          g_free(result); 
00260      }
00261 }
00262 
00263 
00264 void integer_filter_init(GtkEntry *entry)
00265 {
00266     g_signal_connect (G_OBJECT (entry), "insert-text",
00267                     G_CALLBACK (insert_integer_filter), NULL);
00268 }
00269