/* This file is part of GNUnet. (C) 2005 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * @file src/plugins/fs/namespace.c * @brief code for operations with namespaces * @author Christian Grothoff */ #include "platform.h" #include "gnunetgtk_common.h" #include "fs.h" #include "helper.h" #include "meta.h" #include "namespace.h" #include #define UPDATE_CONTENT_LIST_FREQUENCY (5 * cronMINUTES) /** * @brief linked list of pages in the search notebook */ typedef struct NL { struct NL * next; GtkWidget * treeview; GtkWidget * namespacepage; GtkTreeModel * model; GtkWidget * anonymityButton; char * name; HashCode512 id; struct ECRS_MetaData * meta; } NamespaceList; static NamespaceList * head; static GladeXML * metaXML; static GtkWidget * makeNamespaceFrame(GtkWidget ** treeview, GtkWidget ** anonSpin) { GtkWidget * window; GtkWidget * child; GtkWidget * resultList; GtkCellRenderer * renderer; GtkListStore * model; GladeXML * namespaceXML; namespaceXML = glade_xml_new(getGladeFileName(), "namespaceContentFrame", PACKAGE_NAME); connectGladeWithPlugins(namespaceXML); window = glade_xml_get_widget(namespaceXML, "namespaceContentFrame"); resultList = glade_xml_get_widget(namespaceXML, "namespaceContentFrameTreeView"); *anonSpin = glade_xml_get_widget(namespaceXML, "namespaceAnonymitySpinButton"); if (treeview != NULL) (*treeview) = GTK_WIDGET(GTK_TREE_VIEW(resultList)); model = gtk_list_store_new(IN_NAMESPACE_NUM, G_TYPE_STRING, /* (file)name */ G_TYPE_UINT64, /* size */ G_TYPE_STRING, /* description */ G_TYPE_STRING, /* mime-type */ G_TYPE_STRING, /* last-ID */ G_TYPE_STRING, /* next-ID */ G_TYPE_STRING, /* pub-freq */ G_TYPE_STRING, /* next pub date */ G_TYPE_POINTER, /* URI */ G_TYPE_POINTER); /* META */ gtk_tree_view_set_model(GTK_TREE_VIEW(resultList), GTK_TREE_MODEL(model)); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Filename"), renderer, "text", IN_NAMESPACE_FILENAME, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Filesize"), renderer, "text", IN_NAMESPACE_SIZE, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Description"), renderer, "text", IN_NAMESPACE_DESCRIPTION, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Mime-type"), renderer, "text", IN_NAMESPACE_MIMETYPE, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Last ID"), renderer, "text", IN_NAMESPACE_LAST_STRING, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Next ID"), renderer, "text", IN_NAMESPACE_NEXT_STRING, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Publication Frequency"), renderer, "text", IN_NAMESPACE_PUB_FREQ_STRING, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList), -1, _("Next Publication Date"), renderer, "text", IN_NAMESPACE_PUB_DATE_STRING, NULL); child = gtk_bin_get_child(GTK_BIN(window)); gtk_widget_ref(GTK_WIDGET(child)); gtk_container_remove(GTK_CONTAINER(window), child); gtk_widget_destroy(window); UNREF(namespaceXML); return child; } /** * Add the given content to the globally available * content model. Check that it is not already * present! */ static int updateView(const ECRS_FileInfo * fi, const HashCode512 * key, void * closure) { GtkTreeModel * model = GTK_TREE_MODEL(closure); struct ECRS_URI * euri; GtkTreeIter iter; char * filename; char * uriString; unsigned long long size; if (gtk_tree_model_get_iter_first(model, &iter)) { do { gtk_tree_model_get(model, &iter, NAMESPACE_URI, &euri, -1); if (ECRS_equalsUri(euri, fi->uri)) return OK; /* already listed */ } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter)); } filename = ECRS_getFirstFromMetaData(fi->meta, EXTRACTOR_FILENAME, EXTRACTOR_TITLE, EXTRACTOR_DESCRIPTION, EXTRACTOR_SUBJECT, EXTRACTOR_ARTIST, EXTRACTOR_AUTHOR, EXTRACTOR_PUBLISHER, EXTRACTOR_CREATOR, EXTRACTOR_PRODUCER, EXTRACTOR_UNKNOWN, -1); if (filename == NULL) filename = STRDUP(_("no name given")); size = ECRS_fileSize(fi->uri); uriString = ECRS_uriToString(fi->uri); gtk_list_store_append(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, NAMESPACE_FILENAME, filename, NAMESPACE_SIZE, size, NAMESPACE_URISTRING, uriString, NAMESPACE_URI, ECRS_dupUri(fi->uri), NAMESPACE_META, ECRS_dupMetaData(fi->meta), -1); FREE(filename); FREE(uriString); return OK; } static void clearContentList(void * mdl) { GtkTreeModel * model = GTK_TREE_MODEL(mdl); struct ECRS_URI * uri; struct ECRS_MetaData * meta; GtkTreeIter iter; if (gtk_tree_model_get_iter_first(model, &iter)) { do { gtk_tree_model_get(model, &iter, NAMESPACE_URI, &uri, NAMESPACE_META, &meta, -1); ECRS_freeUri(uri); ECRS_freeMetaData(meta); } while (gtk_list_store_remove(GTK_LIST_STORE(model), &iter)); } } /** * Update the list of the globally available content. */ static void doUpdateContentList(void * unused) { GtkWidget * contentList; GtkTreeModel * model; contentList = glade_xml_get_widget(getMainXML(), "availableContentList"); model = gtk_tree_view_get_model(GTK_TREE_VIEW(contentList)); FSUI_listURIs(&updateView, model); } static void updateContentList(void * unused) { gtkSaveCall(&doUpdateContentList, NULL); } void on_refreshContentListButton_clicked(gpointer dummy, gpointer dummy1) { updateContentList(NULL); } /** * Update the model that lists the content of a namespace: * add this content. * * @param uri URI of the last content published * @param lastId the ID of the last publication * @param nextId the ID of the next update * @param publicationFrequency how often are updates scheduled? * @param nextPublicationTime the scheduled time for the * next update (0 for sporadic updates) * @return OK to continue iteration, SYSERR to abort */ static int addNamespaceContentToModel(void * cls, const ECRS_FileInfo * fi, const HashCode512 * lastId, const HashCode512 * nextId, TIME_T publicationFrequency, TIME_T nextPublicationTime) { GtkListStore * model = GTK_LIST_STORE(cls); GtkTreeIter iter; char * filename; char * desc; char * mime; char * uriString; EncName last; EncName next; char * freq; char * date; unsigned long long size; TIME_T t; filename = ECRS_getFirstFromMetaData(fi->meta, EXTRACTOR_FILENAME, EXTRACTOR_TITLE, EXTRACTOR_ARTIST, EXTRACTOR_AUTHOR, EXTRACTOR_PUBLISHER, EXTRACTOR_CREATOR, EXTRACTOR_PRODUCER, EXTRACTOR_UNKNOWN, -1); if (filename == NULL) filename = STRDUP(_("no name given")); desc = ECRS_getFirstFromMetaData(fi->meta, EXTRACTOR_DESCRIPTION, EXTRACTOR_GENRE, EXTRACTOR_ALBUM, EXTRACTOR_COMMENT, EXTRACTOR_SUBJECT, EXTRACTOR_FORMAT, EXTRACTOR_SIZE, EXTRACTOR_KEYWORDS, -1); if (desc == NULL) desc = STRDUP(""); mime = ECRS_getFromMetaData(fi->meta, EXTRACTOR_MIMETYPE); if (mime == NULL) mime = STRDUP(_("unknown")); size = ECRS_fileSize(fi->uri); uriString = ECRS_uriToString(fi->uri); hash2enc(lastId, &last); hash2enc(nextId, &next); t = nextPublicationTime; date = GN_CTIME(&t); freq = timeIntervalToFancyString(publicationFrequency * cronSECONDS); gtk_list_store_append(model, &iter); gtk_list_store_set(model, &iter, IN_NAMESPACE_FILENAME, filename, IN_NAMESPACE_SIZE, size, IN_NAMESPACE_DESCRIPTION, desc, IN_NAMESPACE_MIMETYPE, mime, IN_NAMESPACE_LAST_STRING, &last, IN_NAMESPACE_NEXT_STRING, &next, IN_NAMESPACE_PUB_FREQ_STRING, freq, IN_NAMESPACE_PUB_DATE_STRING, date, IN_NAMESPACE_URI, ECRS_dupUri(fi->uri), IN_NAMESPACE_META, ECRS_dupMetaData(fi->meta), -1); FREE(filename); FREE(uriString); FREE(freq); FREE(date); FREE(mime); return OK; } /** * Add a tab for the given namespace. */ static int addTabForNamespace(void * unused, const char * namespaceName, const HashCode512 * namespaceId, const struct ECRS_MetaData * md, int rating) { NamespaceList * list; GtkWidget * label; GtkWidget * spin; GtkWidget * notebook; GtkListStore * model; label = gtk_label_new(namespaceName); list = MALLOC(sizeof(NamespaceList)); list->name = STRDUP(namespaceName); list->id = *namespaceId; list->meta = ECRS_dupMetaData(md); list->namespacepage = makeNamespaceFrame(&list->treeview, &spin); list->anonymityButton = spin; model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list->treeview))); list->model = GTK_TREE_MODEL(model); list->next = head; head = list; notebook = glade_xml_get_widget(getMainXML(), "localNamespacesNotebook"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), list->namespacepage, label); gtk_widget_show(notebook); FSUI_listNamespaceContent (ctx, namespaceName, &addNamespaceContentToModel, model); return OK; } void on_namespacemetaDataDialogKeywordAddButton_clicked(gpointer dummy, GtkWidget * uploadButton) { handleKeywordListUpdate(metaXML, "namespaceKeywordEntry", "namespaceMetaDataDialogKeywordList"); } void on_namespacemetaDataDialogMetaDataAddButton_clicked(gpointer dummy, GtkWidget * uploadButton) { handleMetaDataListUpdate(metaXML, "namespaceMetaDataDialogMetaTypeComboBox", "namespaceMetaDataValueEntry", "namespaceMetaDataDialogMetaDataList"); } void create_namespace_clicked(GtkWidget * dummy1, GtkWidget * dummy2) { const char * namespaceName; GtkWidget * nameLine; GtkWidget * dialog; GtkWidget * spin; struct ECRS_MetaData * meta; struct ECRS_URI * keywordURI; struct ECRS_URI * root; HashCode512 namespaceId; HashCode512 rootEntry; metaXML = glade_xml_new(getGladeFileName(), "namespaceMetaDataDialog", PACKAGE_NAME); connectGladeWithPlugins(metaXML); dialog = glade_xml_get_widget(metaXML, "namespaceMetaDataDialog"); createMetaDataListTreeView(metaXML, "namespaceMetaDataDialogMetaDataList", NULL, NULL); createKeywordListTreeView(metaXML, "namespaceMetaDataDialogKeywordList", NULL); createMetaTypeComboBox(metaXML, "namespaceMetaDataDialogMetaTypeComboBox"); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { meta = getMetaDataFromList(metaXML, "namespaceMetaDataDialogMetaDataList", NULL); keywordURI = getKeywordURIFromList(metaXML, "namespaceMetaDataDialogKeywordList"); spin = glade_xml_get_widget(metaXML, "namespaceAnonymityspinbutton"); nameLine = glade_xml_get_widget(metaXML, "namespaceRootEntry"); namespaceName = gtk_entry_get_text(GTK_ENTRY(nameLine)); if (namespaceName == NULL) namespaceName = "root"; /* do NOT translate "root"! */ hash(namespaceName, strlen(namespaceName), &rootEntry); nameLine = glade_xml_get_widget(metaXML, "namespaceNameEntry"); namespaceName = gtk_entry_get_text(GTK_ENTRY(nameLine)); root = FSUI_createNamespace(ctx, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin)), namespaceName, meta, keywordURI, &rootEntry); if (root != NULL) { ECRS_getNamespaceId(root, &namespaceId); addTabForNamespace(NULL, namespaceName, &namespaceId, meta, 0); ECRS_freeUri(root); } else { GtkWidget * dialog; dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Failed to create namespace `%s'." "Consult logs, most likely error is" " that a namespace with that name " "already exists."), namespaceName); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } ECRS_freeMetaData(meta); ECRS_freeUri(keywordURI); } gtk_widget_destroy(dialog); UNREF(metaXML); metaXML = NULL; } void namespaceDelete_clicked(GtkWidget * dummy1, GtkWidget * dummy2) { GtkWidget * notebook; NamespaceList * list; NamespaceList * prev; gint num; GtkWidget * page; GtkWidget * dialog; gint ret; notebook = glade_xml_get_widget(getMainXML(), "localNamespacesNotebook"); num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); if (num == -1) { /* IMPROVE-ME: disable the menu item as long as this may happen! */ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("No local namespaces available that could be deleted!")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); list = head; prev = NULL; while ( (list != NULL) && (list->namespacepage != page) ) { prev = list; list = list->next; } if (list == NULL) { BREAK(); return; } /* open window to ask for confirmation, only then delete */ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, _("Should the namespace `%s' really be deleted?"), list->name); ret = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); if (GTK_RESPONSE_YES != ret) return; gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), num); if (prev == NULL) head = list->next; else prev->next = list->next; FSUI_deleteNamespace(list->name); FREE(list->name); ECRS_freeMetaData(list->meta); FREE(list); } typedef struct { unsigned int anonymityLevel; char * namespaceName; TIME_T updateInterval; HashCode512 * lastId; HashCode512 thisId; HashCode512 * nextId; struct ECRS_MetaData * meta; } IUC; /** * Publish the selected file in the * selected namespace. */ static void initiateUpload(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data) { IUC * cls = data; struct ECRS_URI * resultURI; struct ECRS_URI * dst; struct ECRS_MetaData * ometa; struct ECRS_MetaData * meta; NamespaceList * list; ECRS_FileInfo fi; dst = NULL; meta = cls->meta; gtk_tree_model_get(model, iter, NAMESPACE_URI, &dst, NAMESPACE_META, &ometa, -1); /* FIXME: we may want to optionally combine the metadata from the original file ID (ometa) with the new metadata (cls->meta) here; or if we limit us to one file at a time, show the original metadata immediately with the dialog. */ if (dst == NULL) { BREAK(); return; } resultURI = FSUI_addToNamespace(ctx, cls->anonymityLevel, cls->namespaceName, cls->updateInterval, cls->lastId, &cls->thisId, cls->nextId, dst, meta); if (resultURI != NULL) { list = head; while ( (list != NULL) && (0 != strcmp(cls->namespaceName, list->name)) ) list = list->next; if (list == NULL) { BREAK(); } else { /* update namespace content list! */ fi.uri = resultURI; fi.meta = meta; addNamespaceContentToModel(list->model, &fi, &cls->thisId, cls->nextId, cls->updateInterval, cls->updateInterval + TIME(NULL)); } ECRS_freeUri(resultURI); } else { infoMessage(YES, _("Failed to insert content into namespace " "(consult logs).\n")); } } void on_namespaceInsertButton_clicked(GtkWidget * dummy1, GtkWidget * dummy2) { const char * identifierName; const char * timeSpec; NamespaceList * list; GtkWidget * nameLine; GtkWidget * page; GtkWidget * notebook; GtkWidget * metaList; GtkWidget * dialog; GtkWidget * spin; GtkWidget * update; GtkListStore * metamodel; GtkCellRenderer * renderer; GtkTreeIter iter; struct ECRS_MetaData * meta; EXTRACTOR_KeywordType type; char * mvalue; HashCode512 nextId; GtkWidget * contentList; GtkTreeSelection * selection; IUC cls; gint num; contentList = glade_xml_get_widget(getMainXML(), "availableContentList"); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(contentList)); if (0 == gtk_tree_selection_count_selected_rows(selection)) { /* IMPROVE-ME: disable the menu item as long as this may happen! */ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("You must select some available content for publication first!")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } notebook = glade_xml_get_widget(getMainXML(), "localNamespacesNotebook"); num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); GNUNET_ASSERT(num != -1); page =gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); list = head; while ( (list != NULL) && (list->namespacepage != page) ) list = list->next; if (list == NULL) { BREAK(); return; } cls.namespaceName = list->name; metaXML = glade_xml_new(getGladeFileName(), "namespaceMetaDataDialog", PACKAGE_NAME); connectGladeWithPlugins(metaXML); dialog = glade_xml_get_widget(metaXML, "namespaceMetaDataDialog"); metamodel = gtk_list_store_new(META_NUM, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING); metaList = glade_xml_get_widget(metaXML, "namespaceMetaDataDialogMetaDataList"); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(metaList), -1, _("Category"), renderer, "text", META_STYPE, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(metaList), -1, _("Value"), renderer, "text", META_VALUE, NULL); gtk_tree_view_set_model(GTK_TREE_VIEW(metaList), GTK_TREE_MODEL(metamodel)); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { update = glade_xml_get_widget(metaXML, "updateIntervalComboBoxEntry"); timeSpec = gtk_entry_get_text(GTK_ENTRY(update)); if (0 == strcmp(_("--sporadic update--"), timeSpec)) cls.updateInterval = ECRS_SBLOCK_UPDATE_SPORADIC; else if (0 == strcmp(_("--no update--"), timeSpec)) cls.updateInterval = ECRS_SBLOCK_UPDATE_NONE; else if (OK != parseTime(timeSpec, &cls.updateInterval)) { gtk_widget_destroy(dialog); UNREF(metaXML); metaXML = NULL; dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Failed to parse given time interval!")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } meta = ECRS_createMetaData(); if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(metamodel), &iter)) { do { gtk_tree_model_get(GTK_TREE_MODEL(metamodel), &iter, META_TYPE, &type, META_VALUE, &mvalue, -1); ECRS_addToMetaData(meta, type, mvalue); } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(metamodel), &iter)); } spin = glade_xml_get_widget(metaXML, "anonymitySpinButton"); cls.anonymityLevel = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin)); nameLine = glade_xml_get_widget(metaXML, "namespaceContentIdentifierEntry"); identifierName = gtk_entry_get_text(GTK_ENTRY(nameLine)); if (identifierName == NULL) identifierName = ""; hash(identifierName, strlen(identifierName), &cls.thisId); cls.lastId = NULL; nameLine = glade_xml_get_widget(metaXML, "nextIdentifierEntry"); identifierName = gtk_entry_get_text(GTK_ENTRY(nameLine)); if ( (identifierName == NULL) || (strlen(identifierName) == 0)) { cls.nextId = NULL; } else { hash(identifierName, strlen(identifierName), &nextId); cls.nextId = &nextId; } cls.meta = meta; gtk_tree_selection_selected_foreach (selection, &initiateUpload, &cls); ECRS_freeMetaData(meta); } gtk_widget_destroy(dialog); UNREF(metaXML); metaXML = NULL; } void on_namespaceUpdateButton_clicked(GtkWidget * dummy1, GtkWidget * dummy2) { GtkWidget * dialog; /* FIXME: implement update! */ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Not implemented!")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void on_clearAvailableContentButton_clicked(GtkWidget * dummy1, GtkWidget * dummy2) { GtkWidget * contentList; GtkTreeModel * model; contentList = glade_xml_get_widget(getMainXML(), "availableContentList"); model = gtk_tree_view_get_model(GTK_TREE_VIEW(contentList)); FSUI_clearTrackedURIS(); gtkSaveCall(&clearContentList, model); updateContentList(NULL); } void on_trackingCheckButton_toggled(GtkWidget * dummy1, GtkWidget * dummy2) { GtkWidget * trackCheckButton; trackCheckButton = glade_xml_get_widget(getMainXML(), "trackingCheckButton"); FSUI_trackURIS(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(trackCheckButton)) == TRUE ? YES : NO); } void fs_namespace_start() { GtkWidget * contentList; GtkListStore * model; GtkCellRenderer * renderer; GtkWidget * trackCheckButton; trackCheckButton = glade_xml_get_widget(getMainXML(), "trackingCheckButton"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trackCheckButton), FSUI_trackStatus() == YES ? TRUE : FALSE); contentList = glade_xml_get_widget(getMainXML(), "availableContentList"); model = gtk_list_store_new(NAMESPACE_NUM, G_TYPE_STRING, /* name */ G_TYPE_UINT64, /* size */ G_TYPE_STRING, /* uri-string */ G_TYPE_POINTER, G_TYPE_POINTER); /* uri */ gtk_tree_view_set_model(GTK_TREE_VIEW(contentList), GTK_TREE_MODEL(model)); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(contentList), -1, _("Filename"), renderer, "text", NAMESPACE_FILENAME, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(contentList), -1, _("Filesize"), renderer, "text", NAMESPACE_SIZE, NULL); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(contentList), -1, _("URI"), renderer, "text", NAMESPACE_URISTRING, NULL); addCronJob(&updateContentList, 0, UPDATE_CONTENT_LIST_FREQUENCY, NULL); FSUI_listNamespaces(ctx, YES, &addTabForNamespace, NULL); } #if 0 void on_availableContentList_destroy(GtkWidget * dummy1, GtkWidget * dummy2) { GtkWidget * contentList; GtkTreeModel * model; delCronJob(&updateContentList, UPDATE_CONTENT_LIST_FREQUENCY, NULL); contentList = glade_xml_get_widget(getMainXML(), "availableContentList"); model = gtk_tree_view_get_model(GTK_TREE_VIEW(contentList)); clearContentList(model); } void on_localNamespacesNotebook_destroy(GtkWidget * dummy1, GtkWidget * dummy2) { NamespaceList * pos; GtkTreeIter iter; struct ECRS_URI * u; struct ECRS_MetaData * m; while (head != NULL) { pos = head->next; FREE(head->name); ECRS_freeMetaData(head->meta); if (gtk_tree_model_get_iter_first(head->model, &iter)) { do { gtk_tree_model_get(head->model, &iter, IN_NAMESPACE_URI, &u, IN_NAMESPACE_META, &m, -1); gtk_list_store_set(GTK_LIST_STORE(head->model), &iter, IN_NAMESPACE_URI, NULL, IN_NAMESPACE_META, NULL, -1); if (u != NULL) ECRS_freeUri(u); if (m != NULL) ECRS_freeMetaData(m); } while (gtk_tree_model_iter_next(head->model, &iter)); } FREE(head); head = pos; } } #endif void fs_namespace_stop() { } /* end of namespace.c */