| static gint verboseLevel=0; |
| |
| void G_DEBUG_MSG(gint level, const char *format, ...){ |
| va_list ap; |
| if (level<verboseLevel){ |
| va_start(ap, format); |
| g_logv("MakerDialog",G_LOG_LEVEL_DEBUG, format, ap); |
| va_end(ap); |
| } |
| } |
| |
| static PropertyContext *propertyContext_new(PropertySpec *spec, gpointer userData){ |
| PropertyContext *ctx=g_new(PropertyContext,1); |
| ctx->spec=spec; |
| ctx->userData=userData; |
| return ctx; |
| } |
| |
| |
| static void propertyContext_free(gpointer ctx_ptr){ |
| PropertyContext *ctx=(PropertyContext *) ctx_ptr; |
| g_free(ctx); |
| } |
| |
| static void listStore_append(GtkListStore *listStore,const gchar *str, |
| const gchar *translationContext, |
| MakerDialogPropertyFlags propertyFlags){ |
| GtkTreeIter iter; |
| gtk_list_store_append (listStore, &iter); |
| |
| if (propertyFlags & MAKER_DIALOG_PROPERTY_FLAG_HAS_TRANSLATION){ |
| if (translationContext || propertyFlags & MAKER_DIALOG_PROPERTY_FLAG_TRANSLATION_WITH_CONTEXT){ |
| G_DEBUG_MSG(5,"*** str=%s, _(str)=%s",str,g_dpgettext2(NULL,translationContext,str)); |
| gtk_list_store_set (listStore, &iter, |
| 0, str, |
| 1, g_dpgettext2(NULL,translationContext,str), |
| -1); |
| }else{ |
| G_DEBUG_MSG(5,"*** str=%s, _(str)=%s",str,_(str)); |
| gtk_list_store_set (listStore, &iter, |
| 0, str, |
| 1, _(str), |
| -1); |
| } |
| }else{ |
| G_DEBUG_MSG(5,"*** str=%s",str); |
| gtk_list_store_set (listStore, &iter, |
| 0, str, |
| -1); |
| } |
| |
| } |
| |
| static gint listStore_find_string(GtkListStore *listStore,const gchar *str, |
| const gchar *translationContext, |
| MakerDialogPropertyFlags propertyFlags){ |
| g_assert(str); |
| G_DEBUG_MSG(4,"*** listStore_find_string(%s,%u)",str,propertyFlags); |
| int i=0,index=-1; |
| GtkTreeIter iter; |
| GValue gValue={0}; |
| if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStore), &iter)){ |
| do{ |
| gtk_tree_model_get_value (GTK_TREE_MODEL(listStore), &iter,0,&gValue); |
| if (strcmp(str,g_value_get_string(&gValue))==0){ |
| index= i; |
| break; |
| } |
| i++; |
| g_value_unset(&gValue); |
| }while(gtk_tree_model_iter_next (GTK_TREE_MODEL(listStore), &iter)); |
| } |
| if (index<0 && !(propertyFlags & MAKER_DIALOG_PROPERTY_FLAG_INEDITABLE)){ |
| /* Add new item*/ |
| listStore_append(listStore, str,translationContext,propertyFlags); |
| index=i; |
| } |
| G_DEBUG_MSG(4,",listStore_find_string(%s,%u) index=%d",str,propertyFlags,index); |
| return index; |
| } |
| |
| static gint combo_find_string_index(GtkComboBox *combo,const gchar *str, |
| const gchar *translationContext, |
| MakerDialogPropertyFlags propertyFlags){ |
| GtkListStore *listStore=GTK_LIST_STORE(gtk_combo_box_get_model(combo)); |
| return listStore_find_string(listStore,str, translationContext,propertyFlags); |
| } |
| |
| static const gchar *combo_get_active_text(GtkComboBox *combo,GValue *gValue){ |
| GtkTreeIter iter; |
| if (!gtk_combo_box_get_active_iter(combo,&iter)){ |
| return NULL; |
| } |
| GtkListStore *listStore=GTK_LIST_STORE(gtk_combo_box_get_model(combo)); |
| gtk_tree_model_get_value (GTK_TREE_MODEL(listStore), &iter,0,gValue); |
| return g_value_get_string(gValue); |
| } |
| |
| |
| static void propList_free_deep_callback(gpointer data, gpointer user_data){ |
| propertyContext_free(data); |
| } |
| |
| static gchar *widget_get_id(gchar *buffer, gint buffer_size, |
| const gchar *widget_label, const gchar *widget_type){ |
| g_snprintf(buffer,buffer_size,"%s%s%s%s", |
| WIDGET_ID_PREFIX, widget_label, |
| (widget_type)? "_" : "", |
| (widget_type)? widget_type : "" |
| ); |
| return buffer; |
| } |
| |
| /*===== Widget Callback function wraps =====*/ |
| |
| static void on_comboBox_changed_wrap (GtkComboBox *comboBox, gpointer user_data) |
| { |
| PropertyContext *ctx=(PropertyContext *)user_data; |
| GValue value={0}; |
| combo_get_active_text(comboBox, &value); |
| G_DEBUG_MSG(2,"on_comboBox_changed_wrap(), key=%s value=%s",ctx->spec->key,g_value_get_string(&value)); |
| ctx->spec->setFunc(ctx,&value); |
| } |
| |
| static void on_entry_activate_wrap (GtkEntry *entry, gpointer user_data) |
| { |
| PropertyContext *ctx=(PropertyContext *)user_data; |
| GValue value={0}; |
| g_value_init(&value, ctx->spec->valueType); |
| g_value_set_string(&value,gtk_entry_get_text(entry)); |
| G_DEBUG_MSG(2,"on_entry_activate_wrap(), key=%s value=%s",ctx->spec->key,g_value_get_string(&value)); |
| ctx->spec->setFunc(ctx,&value); |
| } |
| |
| static void on_spinButton_value_changed_wrap (GtkSpinButton *button, gpointer user_data) |
| { |
| PropertyContext *ctx=(PropertyContext *)user_data; |
| GValue value={0}; |
| g_value_init(&value, ctx->spec->valueType); |
| switch(ctx->spec->valueType){ |
| case G_TYPE_INT: |
| g_value_set_int(&value,(gint) gtk_spin_button_get_value(button)); |
| G_DEBUG_MSG(2,"on_spinButton_value_changed_wrap(), key=%s value=%d", |
| ctx->spec->key,g_value_get_int(&value)); |
| break; |
| case G_TYPE_UINT: |
| g_value_set_uint(&value,(guint) gtk_spin_button_get_value(button)); |
| G_DEBUG_MSG(2,"on_spinButton_value_changed_wrap(), key=%s value=%u", |
| ctx->spec->key,g_value_get_uint(&value)); |
| break; |
| case G_TYPE_DOUBLE: |
| g_value_set_uint(&value, gtk_spin_button_get_value(button)); |
| G_DEBUG_MSG(2,"on_spinButton_value_changed_wrap(), key=%s value=%g", |
| ctx->spec->key,g_value_get_double(&value)); |
| break; |
| default: |
| break; |
| } |
| ctx->spec->setFunc(ctx,&value); |
| } |
| |
| static void on_toggleButton_toggled_wrap (GtkToggleButton *button, gpointer user_data) |
| { |
| PropertyContext *ctx=(PropertyContext *)user_data; |
| GValue value={0}; |
| g_value_init(&value, ctx->spec->valueType); |
| g_value_set_boolean(&value, gtk_toggle_button_get_active(button)); |
| G_DEBUG_MSG(2,"on_entry_activate_wrap(), key=%s value=%s",ctx->spec->key,g_value_get_string(&value)); |
| ctx->spec->setFunc(ctx,&value); |
| } |
| |
| /*===== End of Widget Callback function wraps =====*/ |
| static gboolean isEmptyString(const gchar *str){ |
| if (!str) |
| return TRUE; |
| if (str[0]=='\0') |
| return TRUE; |
| return FALSE; |
| } |
| |
| typedef enum{ |
| XML_TAG_TYPE_NO_TAG, |
| XML_TAG_TYPE_EMPTY, |
| XML_TAG_TYPE_SHORT, |
| XML_TAG_TYPE_LONG, |
| XML_TAG_TYPE_BEGIN_ONLY, |
| XML_TAG_TYPE_END_ONLY, |
| } XmlTagsType; |
| #define INDENT_SPACES 4 |
| |
| static void append_indent_space(GString *strBuf, gint indentLevel){ |
| int i,indentLen=indentLevel*INDENT_SPACES; |
| for(i=0;i<indentLen;i++){ |
| g_string_append_c(strBuf,' '); |
| } |
| } |
| |
| static GString *xml_tags_to_string(const gchar *tagName, XmlTagsType type, |
| const gchar *attribute, const gchar *value,gint indentLevel){ |
| GString *strBuf=g_string_new(NULL); |
| append_indent_space(strBuf,indentLevel); |
| |
| if(type!=XML_TAG_TYPE_NO_TAG){ |
| g_string_append_printf(strBuf,"<%s%s%s%s%s>", |
| (type==XML_TAG_TYPE_END_ONLY) ? "/": "", |
| (!isEmptyString(tagName))? tagName : "", |
| (!isEmptyString(attribute)) ? " ":"", (!isEmptyString(attribute))? attribute : "", |
| (type==XML_TAG_TYPE_EMPTY) ? "/": "" |
| ); |
| } |
| if (type==XML_TAG_TYPE_EMPTY) |
| return strBuf; |
| if (type==XML_TAG_TYPE_BEGIN_ONLY) |
| return strBuf; |
| if (type==XML_TAG_TYPE_END_ONLY) |
| return strBuf; |
| |
| if (type==XML_TAG_TYPE_LONG){ |
| g_string_append_c(strBuf,'\n'); |
| } |
| |
| if (value){ |
| if (type==XML_TAG_TYPE_LONG || type==XML_TAG_TYPE_NO_TAG){ |
| append_indent_space(strBuf,indentLevel+1); |
| int i, valueLen=strlen(value); |
| for(i=0;i<valueLen;i++){ |
| g_string_append_c(strBuf,value[i]); |
| if (value[i]=='\n'){ |
| append_indent_space(strBuf,indentLevel+1); |
| } |
| } |
| g_string_append_c(strBuf,'\n'); |
| if (type==XML_TAG_TYPE_LONG){ |
| append_indent_space(strBuf,indentLevel); |
| } |
| }else{ |
| g_string_append(strBuf,value); |
| } |
| } |
| |
| if (type==XML_TAG_TYPE_LONG || type==XML_TAG_TYPE_SHORT){ |
| g_string_append_printf(strBuf,"</%s>",tagName); |
| } |
| return strBuf; |
| } |
| |
| static void xml_tags_write(FILE *outF, const gchar *tagName, XmlTagsType type, |
| const gchar *attribute, const gchar *value){ |
| static int indentLevel=0; |
| if (type==XML_TAG_TYPE_END_ONLY) |
| indentLevel--; |
| |
| GString *strBuf=xml_tags_to_string(tagName, type, attribute, value, indentLevel); |
| G_DEBUG_MSG(3,",xml_tags_write:%s",strBuf->str); |
| fprintf(outF,"%s\n",strBuf->str); |
| |
| if (type==XML_TAG_TYPE_BEGIN_ONLY) |
| indentLevel++; |
| g_string_free(strBuf,TRUE); |
| } |
| |
| typedef struct{ |
| const gchar *schemasHome; |
| const gchar *owner; |
| const gchar *locales; |
| FILE *outF; |
| } SchemasFileData; |
| |
| static void ctx_write_locale(PropertyContext *ctx, SchemasFileData *sData, const gchar *localeStr){ |
| gchar buf[50]; |
| g_snprintf(buf,50,"name=\"%s\"",localeStr); |
| setlocale(LC_MESSAGES,localeStr); |
| xml_tags_write(sData->outF,"locale",XML_TAG_TYPE_BEGIN_ONLY,buf,NULL); |
| xml_tags_write(sData->outF,"short",XML_TAG_TYPE_SHORT,NULL, gettext(ctx->spec->label)); |
| xml_tags_write(sData->outF,"long",XML_TAG_TYPE_LONG,NULL, gettext(ctx->spec->tooltip)); |
| xml_tags_write(sData->outF,"locale",XML_TAG_TYPE_END_ONLY,NULL,NULL); |
| } |
| |
| static void ctx_write_callback(gpointer data, gpointer user_data){ |
| PropertyContext *ctx=(PropertyContext *) data; |
| SchemasFileData *sData=(SchemasFileData *) user_data; |
| xml_tags_write(sData->outF,"schema",XML_TAG_TYPE_BEGIN_ONLY,NULL,NULL); |
| gchar buf[STRING_BUFFER_SIZE_DEFAULT]; |
| g_snprintf(buf,STRING_BUFFER_SIZE_DEFAULT,"/schemas%s/%s",sData->schemasHome,ctx->spec->key); |
| xml_tags_write(sData->outF,"key",XML_TAG_TYPE_SHORT,NULL,buf); |
| xml_tags_write(sData->outF,"applyto",XML_TAG_TYPE_SHORT,NULL,buf+strlen("/schemas")); |
| xml_tags_write(sData->outF,"owner",XML_TAG_TYPE_SHORT,NULL,sData->owner); |
| switch(ctx->spec->valueType){ |
| case G_TYPE_BOOLEAN: |
| xml_tags_write(sData->outF,"type",XML_TAG_TYPE_SHORT,NULL,"bool"); |
| break; |
| case G_TYPE_INT: |
| case G_TYPE_UINT: |
| xml_tags_write(sData->outF,"type",XML_TAG_TYPE_SHORT,NULL,"int"); |
| break; |
| case G_TYPE_STRING: |
| xml_tags_write(sData->outF,"type",XML_TAG_TYPE_SHORT,NULL,"string"); |
| break; |
| default: |
| break; |
| } |
| if (ctx->spec->defaultValue){ |
| xml_tags_write(sData->outF,"default",XML_TAG_TYPE_SHORT,NULL,ctx->spec->defaultValue); |
| } |
| gchar **localeArray=g_strsplit_set(sData->locales,":;",-1); |
| int i; |
| for(i=0;localeArray[i]!=NULL;i++){ |
| ctx_write_locale(ctx,sData,localeArray[i]); |
| } |
| setlocale(LC_ALL,NULL); |
| xml_tags_write(sData->outF,"schema",XML_TAG_TYPE_END_ONLY,NULL,NULL); |
| } |
| |
| typedef struct{ |
| MakerDialog *self; |
| gint currentMaxWidth; |
| const gchar *pageName; |
| gfloat xalign; |
| gfloat yalign; |
| } WidgetAlignment; |
| |
| static void caculate_max_label_width_callback(gpointer key, gpointer value, gpointer user_data){ |
| WidgetAlignment *wAlignment=(WidgetAlignment *) user_data; |
| if (!isEmptyString(wAlignment->pageName)){ |
| if (isEmptyString(value) || strcmp(wAlignment->pageName,value)!=0) |
| return; |
| } |
| gchar *keyStr=(gchar *) keyStr; |
| |
| GtkWidget *widget=maker_dialog_get_widget(wAlignment->self,key,"label"); |
| GtkRequisition requisition; |
| gtk_widget_size_request (widget,&requisition); |
| wAlignment->currentMaxWidth=MAX(wAlignment->currentMaxWidth, requisition.width); |
| } |
| |
| static void set_label_width_callback(gpointer key, gpointer value, gpointer user_data){ |
| WidgetAlignment *wAlignment=(WidgetAlignment *) user_data; |
| if (!isEmptyString(wAlignment->pageName)){ |
| if (isEmptyString(value) || strcmp(wAlignment->pageName,value)!=0) |
| return; |
| } |
| gchar *keyStr=(gchar *) keyStr; |
| GtkWidget *widget=maker_dialog_get_widget(wAlignment->self,key,"label"); |
| gtk_widget_set_size_request(widget, wAlignment->currentMaxWidth,-1); |
| gtk_misc_set_alignment (GTK_MISC(widget),wAlignment->xalign,wAlignment->yalign); |
| } |
| |
| /** |
| * atob: |
| * @string: A string. |
| * @returns: Boolean value represented by @string. |
| * |
| * String to boolean. |
| * It returns FALSE if: |
| * 1. @string is NULL or have 0 length. |
| * 2. @string starts with 'F', 'f', 'N' or 'n'. |
| * 3. @string can be converted to a numeric 0. |
| * |
| * Everything else is TRUE. |
| */ |
| gboolean atob(const gchar *string){ |
| if (!string) |
| return FALSE; |
| if (strlen(string)<=0) |
| return FALSE; |
| if (string[0]=='F' || string[0]=='f' || string[0]=='N' || string[0]=='n') |
| return FALSE; |
| char *endPtr=NULL; |
| long int longValue=strtol(string, &endPtr, 10); |
| |
| if (longValue==0 && *endPtr=='\0'){ |
| // 0 |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |