gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r3553 - gnunet-gtk/src/plugins/fs


From: grothoff
Subject: [GNUnet-SVN] r3553 - gnunet-gtk/src/plugins/fs
Date: Wed, 25 Oct 2006 13:41:19 -0700 (PDT)

Author: grothoff
Date: 2006-10-25 13:41:15 -0700 (Wed, 25 Oct 2006)
New Revision: 3553

Added:
   gnunet-gtk/src/plugins/fs/search_namespace.c
Modified:
   gnunet-gtk/src/plugins/fs/fs.c
   gnunet-gtk/src/plugins/fs/helper.c
   gnunet-gtk/src/plugins/fs/helper.h
   gnunet-gtk/src/plugins/fs/search.c
   gnunet-gtk/src/plugins/fs/search.h
Log:
syn

Modified: gnunet-gtk/src/plugins/fs/fs.c
===================================================================
--- gnunet-gtk/src/plugins/fs/fs.c      2006-10-24 23:12:20 UTC (rev 3552)
+++ gnunet-gtk/src/plugins/fs/fs.c      2006-10-25 20:41:15 UTC (rev 3553)
@@ -27,7 +27,6 @@
 #include "platform.h"
 #include "gnunetgtk_common.h"
 #include "fs.h"
-#include "download.h"
 #include "search.h"
 #include "upload.h"
 #include "collection.h"
@@ -166,14 +165,12 @@
                   NULL);
   fs_collection_start(ectx, cfg);
   fs_search_start(ectx, cfg);
-  fs_download_start(ectx, cfg);
   fs_upload_start(ectx, cfg);
   fs_namespace_start(ectx, cfg);
 }
 
 void done_fs() {
   DEBUG_BEGIN();
-  fs_download_stop();
   fs_search_stop();
   fs_collection_stop();
   fs_namespace_stop();

Modified: gnunet-gtk/src/plugins/fs/helper.c
===================================================================
--- gnunet-gtk/src/plugins/fs/helper.c  2006-10-24 23:12:20 UTC (rev 3552)
+++ gnunet-gtk/src/plugins/fs/helper.c  2006-10-25 20:41:15 UTC (rev 3553)
@@ -205,3 +205,132 @@
 
   return hbox;
 }
+
+
+
+GtkWidget * makeSearchResultFrame(struct GC_Configuration * cfg,
+                                 GtkWidget ** treeview,
+                                 GtkWidget ** anonSpin) {
+  GtkWidget * window;
+  GtkWidget * child;
+  GtkWidget * resultList;
+  GtkTreeViewColumn * column;
+  GtkCellRenderer * renderer;
+  GtkTreeStore * tree;
+  GladeXML * searchXML;
+  int col;
+
+  DEBUG_BEGIN();
+  searchXML
+    = glade_xml_new(getGladeFileName(),
+                   "searchResultsFrame",
+                   PACKAGE_NAME);
+  connectGladeWithPlugins(searchXML);
+  window = glade_xml_get_widget(searchXML,
+                              "searchResultsFrame");
+  resultList = glade_xml_get_widget(searchXML,
+                                   "searchResults");
+  *anonSpin = glade_xml_get_widget(searchXML,
+                                  "downloadAnonymitySpinButton");
+  if (treeview != NULL)
+    (*treeview) = GTK_WIDGET(GTK_TREE_VIEW(resultList));
+  tree =
+    gtk_tree_store_new(SEARCH_NUM,
+                      G_TYPE_STRING, /* name */
+                      G_TYPE_UINT64,  /* size */
+                      G_TYPE_STRING,  /* human-readable size */
+                      G_TYPE_STRING, /* mime-type */
+                      G_TYPE_STRING, /* meta-data (some) */
+                      GDK_TYPE_PIXBUF, /* preview */   
+                      G_TYPE_POINTER,  /* url */
+                      G_TYPE_POINTER,  /* meta */
+                      G_TYPE_POINTER); /* internal: download info/NULL */
+  gtk_tree_view_set_model(GTK_TREE_VIEW(resultList),
+                         GTK_TREE_MODEL(tree));
+  renderer = gtk_cell_renderer_text_new();
+  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
+                                             -1,
+                                             _("Name"),
+                                             renderer,
+                                             "text", SEARCH_NAME,
+                                             NULL);
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+                                   col - 1);
+  gtk_tree_view_column_set_resizable(column, TRUE);
+  gtk_tree_view_column_set_clickable(column, TRUE);
+  gtk_tree_view_column_set_reorderable(column, TRUE);
+  gtk_tree_view_column_set_sort_column_id(column, SEARCH_NAME);
+  /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+  renderer = gtk_cell_renderer_text_new();
+  g_object_set (renderer, "xalign", 1.00, NULL);
+  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
+                                             -1,
+                                             _("Size"),
+                                             renderer,
+                                             "text", SEARCH_HSIZE,
+                                             NULL);
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+                                   col - 1);
+  gtk_tree_view_column_set_resizable(column, TRUE);
+  gtk_tree_view_column_set_clickable(column, TRUE);
+  gtk_tree_view_column_set_reorderable(column, TRUE);
+  gtk_tree_view_column_set_sort_column_id(column, SEARCH_SIZE);
+  /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+
+  renderer = gtk_cell_renderer_text_new();
+  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
+                                             -1,
+                                             _("Mime-type"),
+                                             renderer,
+                                             "text", SEARCH_MIME,
+                                             NULL);
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+                                   col - 1);
+  gtk_tree_view_column_set_resizable(column, TRUE);
+  gtk_tree_view_column_set_clickable(column, TRUE);
+  gtk_tree_view_column_set_reorderable(column, TRUE);
+  gtk_tree_view_column_set_sort_column_id(column, SEARCH_MIME);
+  /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+  
+  renderer = gtk_cell_renderer_text_new();
+  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
+                                             -1,
+                                             _("Meta-data"),
+                                             renderer,
+                                             "text", SEARCH_DESC,
+                                             NULL);
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+                                   col - 1);
+  gtk_tree_view_column_set_resizable(column, TRUE);
+  gtk_tree_view_column_set_clickable(column, TRUE);
+  gtk_tree_view_column_set_reorderable(column, TRUE);
+  gtk_tree_view_column_set_sort_column_id(column, SEARCH_DESC);
+  /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+  if (YES != GC_get_configuration_value_yesno(cfg,
+                                             "GNUNET-GTK",
+                                             "DISABLE-PREVIEWS",
+                                             NO)) {
+    renderer = gtk_cell_renderer_pixbuf_new();
+    col = 
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
+                                               -1,
+                                               _("Preview"),
+                                               renderer,
+                                               "pixbuf", SEARCH_PIXBUF,
+                                               NULL);
+    column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+                                     col - 1);
+    gtk_tree_view_column_set_resizable(column, TRUE);
+    gtk_tree_view_column_set_reorderable(column, TRUE);
+    
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+                                                col - 1),
+                                                TRUE);
+  }
+  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(searchXML);
+  DEBUG_END();
+  return child;
+}

Modified: gnunet-gtk/src/plugins/fs/helper.h
===================================================================
--- gnunet-gtk/src/plugins/fs/helper.h  2006-10-24 23:12:20 UTC (rev 3552)
+++ gnunet-gtk/src/plugins/fs/helper.h  2006-10-25 20:41:15 UTC (rev 3553)
@@ -36,10 +36,15 @@
  * @returns the created widget to pack into the page header
  */
 GtkWidget *
-buildSearchTabLabel (GtkWidget *searchPage, 
-                    const char *title);
+buildSearchTabLabel(GtkWidget *searchPage, 
+                   const char *title);
 
 
+GtkWidget *
+makeSearchResultFrame(struct GC_Configuration * cfg,
+                     GtkWidget ** treeview,
+                     GtkWidget ** anonSpin);
+
 /**
  * Parse a time given in the form
  * "XX seconds yy days zz months".

Modified: gnunet-gtk/src/plugins/fs/search.c
===================================================================
--- gnunet-gtk/src/plugins/fs/search.c  2006-10-24 23:12:20 UTC (rev 3552)
+++ gnunet-gtk/src/plugins/fs/search.c  2006-10-25 20:41:15 UTC (rev 3553)
@@ -41,32 +41,217 @@
   struct SL * next;
   GtkWidget * treeview;
   GtkWidget * searchpage;
-  GtkTreeModel * model;
-  GtkWidget * anonymityButton;
+  GtkWidget * anonymityButton; /* FIXME: initialize! */
   struct ECRS_URI * uri;
   struct FSUI_SearchList * fsui_list; /* FIXME: initialize! */
 } SearchList;
 
-static SearchList * head;
+static SearchList * search_head;
 
-static GtkListStore * summary;
+static GtkListStore * search_summary;
 
 static struct GE_Context * ectx;
 
 static struct GC_Configuration * cfg;
 
+typedef struct DL {
+  struct DL * next;
+  struct ECRS_URI * uri;
+  char * filename;
+  GtkTreeRowReference * rr;
+  GtkTreeModel * model;
+  struct FSUI_DownloadList * fsui_list;
+} DownloadList;
+
+static DownloadList * download_head;
+
+static GtkTreeStore * download_summary;
+
+
+void on_fssearchbutton_clicked_fs(gpointer dummy2,
+                                 GtkWidget * searchButton) {
+  struct ECRS_URI * uri;
+  const char * ss;
+  const char * ns;
+  gint pages;
+  char * tabtxt;
+  const char * descStr;
+  char * ustring;
+  gint i;
+  gint pages;
+  SearchList * list;
+
+  DEBUG_BEGIN();
+  searchKeywordGtkCB
+    = glade_xml_get_widget(getMainXML(),
+                          "fssearchKeywordComboBoxEntry");
+  entry = gtk_bin_get_child(GTK_BIN(searchKeywordGtkCB));
+  ss = gtk_entry_get_text(GTK_ENTRY(entry));
+  if (ss == NULL) {
+    GE_LOG(ectx,
+          GE_ERROR | GE_USER | GE_IMMEDIATE,
+          _("Need a keyword to search!\n"));
+    return;
+  }
+  i = gtk_combo_box_get_active(GTK_COMBO_BOX(searchKeywordGtkCB));
+  if (i == -1) {
+    model = GTK_LIST_STORE
+      (gtk_combo_box_get_model
+       (GTK_COMBO_BOX(searchKeywordGtkCB)));
+    gtk_list_store_prepend(model,
+                          &iter);
+    gtk_list_store_set(model,
+                      &iter,
+                      0, ss,
+                      -1);
+  }
+  searchNamespaceGtkCB
+    = glade_xml_get_widget(getMainXML(),
+                          "searchNamespaceComboBoxEntry");
+  tmodel = gtk_combo_box_get_model(GTK_COMBO_BOX(searchNamespaceGtkCB));
+  if (TRUE == 
gtk_combo_box_get_active_iter(GTK_COMBO_BOX(searchNamespaceGtkCB),
+                                           &iter)) {
+    ns = NULL;
+    descStr = NULL;
+    gtk_tree_model_get(tmodel,
+                      &iter,
+                      NS_SEARCH_DESCRIPTION, &descStr,
+                      NS_SEARCH_ENCNAME, &ns,
+                      -1);
+
+    if ( (descStr != NULL) &&
+        (0 == strcmp(descStr,
+                     _("globally"))) ) {
+      ns = NULL;
+    } else {
+      GE_ASSERT(ectx, strlen(ns) == sizeof(EncName) - 1);
+      if (descStr == NULL)
+       descStr = ns;
+    }
+  }
+  if (ns != NULL) {
+    ustring = MALLOC(strlen(ss) + sizeof(EncName) +
+                    strlen(ECRS_URI_PREFIX) +
+                    strlen(ECRS_SUBSPACE_INFIX) + 10);
+    strcpy(ustring, ECRS_URI_PREFIX);
+    strcat(ustring, ECRS_SUBSPACE_INFIX);
+    strcat(ustring, ns);
+    strcat(ustring, "/");
+    strcat(ustring, ss);
+    uri = ECRS_stringToUri(ectx, ustring);
+    if (uri == NULL) {
+      GE_LOG(ectx,
+            GE_ERROR | GE_BULK | GE_USER,
+            _("Failed to create namespace URI from `%s'.\n"),
+            ustring);
+    }
+    FREE(ustring);
+  } else {
+    uri = ECRS_parseCharKeywordURI(ectx, ss);
+  }
+  if (uri == NULL)
+    return;
+  /* check if search is already running */
+  pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
+  list = search_head;
+  while (list != NULL) {
+    if (ECRS_equalsUri(list->uri,
+                      uri)) {
+      for (i=0;i<pages;i++) {
+       page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
+                                        i);
+       if (page == list->searchpage) {
+         gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook),
+                                       i);
+         ECRS_freeUri(uri);
+         return;
+       }
+      }
+      GE_BREAK(ectx, 0);
+    }
+    list = list->next;
+  }
+  if (ns == NULL) {
+    tabtxt = STRDUP(ss);
+  } else {
+    GE_ASSERT(ectx, descStr != NULL);
+    tabtxt = MALLOC(strlen(ss) + strlen(descStr) + 2);
+    SNPRINTF(tabtxt,
+            strlen(ss) + strlen(descStr) + 2,
+            "%s/%s",
+            descStr,
+            ss);
+  }
+  FSUI_startSearch(ctx,
+                  getAnonymityLevel(getMainXML(),
+                                    "searchAnonymitySelectionSpinButton");
+                  1000, /* FIXME: max results */
+                  99 * cronYEARS, /* FIXME: timeout */
+                  uri);
+}
+
+void on_searchResults_destroy_fs(GtkWidget * dummy,
+                                GtkWidget * treeview) {
+  SearchList * list;
+
+  DEBUG_BEGIN();
+  list = search_head;
+  while (list != NULL) {
+    if (list->treeview == treeview)
+      break;
+    list = list->next;
+  }
+  GE_ASSERT(ectx, list != NULL);
+  FSUI_stopSearch(ctx,
+                 list->fsui_list);
+  DEBUG_END();
+}
+
+void on_closeSearchButton_clicked_fs(GtkWidget * searchPage,
+                                    GtkWidget * closeButton) {
+  SearchList * list;
+
+  DEBUG_BEGIN();
+  list = search_head;
+  while (list != NULL) {
+    if (list->searchpage == searchPage)
+      break;
+    list = list->next;
+  }
+  GE_ASSERT(ectx, list != NULL);
+  FSUI_stopSearch(ctx,
+                 list->fsui_list);
+  DEBUG_END();
+}
+
+void on_abortSearchButton_clicked_fs(GtkWidget * searchPage,
+                                    GtkWidget * closeButton) {
+  SearchList * list;
+
+  DEBUG_BEGIN();
+  list = search_head;
+  while (list != NULL) {
+    if (list->searchpage == searchPage)
+      break;
+    list = list->next;
+  }
+  GE_ASSERT(ectx, list != NULL);
+  FSUI_abortSearch(ctx,
+                  list->fsui_list);
+  DEBUG_END();
+}
+
 /**
- * Add an entry to the search tree.
- *
- * @param model the search model
- * @param pos the position to add the entry
- * @param uri the URI to add
- * @param meta metadata describing the URI
+ * Add the given result to the model (search result
+ * list).
+ * 
+ * @param info the information to add to the model
+ * @param uri the search URI
+ * @param searchContext identifies the search page
  */
-void addEntryToSearchTree(GtkTreeStore * model,
-                         GtkTreeIter * pos,
-                         const struct ECRS_URI * uri,
-                         const struct ECRS_MetaData * meta) {
+void fs_search_result_received(struct SL * searchContext,
+                              const ECRS_FileInfo * info,
+                              const struct ECRS_URI * uri) {
   char * name;
   char * mime;
   char * desc;
@@ -76,9 +261,19 @@
   GdkPixbufLoader * loader;
   unsigned long long size;
   char * size_h;
-  
+  GtkTreeStore * model;
+  GtkTreeIter iter;
+  GtkTreeIter parent;
+  GtkTreeIter * pparent;
+
   DEBUG_BEGIN();
-  mime = ECRS_getFromMetaData(meta,
+  model = GTK_TREE_STORE
+    (gtk_tree_view_get_model
+     (GTK_TREE_VIEW(searchContext->treeview)));
+  gtk_tree_store_append(model,
+                       &iter,
+                       NULL);  
+  mime = ECRS_getFromMetaData(info->meta,
                              EXTRACTOR_MIMETYPE);
   if (mime == NULL)
     mime = STRDUP(_("unknown"));
@@ -116,11 +311,10 @@
   }
   name = validate_utf8(name);
     
-  if (ECRS_isFileUri(uri)) {
-    size = ECRS_fileSize(uri);
-  } else {
+  if (ECRS_isFileUri(info->uri)) 
+    size = ECRS_fileSize(info->uri);
+  else 
     size = 0;
-  }
   thumb = NULL;
   ts = ECRS_getThumbnailFromMetaData(meta,
                                     &thumb);
@@ -148,30 +342,126 @@
                     SEARCH_MIME, mime,
                     SEARCH_DESC, desc,
                     SEARCH_PIXBUF, pixbuf,
-                    SEARCH_URI, ECRS_dupUri(uri),
-                    SEARCH_META, ECRS_dupMetaData(meta),
-                    SEARCH_INTERNAL, NULL, /* internal */
+                    SEARCH_URI, ECRS_dupUri(info->uri),
+                    SEARCH_META, ECRS_dupMetaData(info->meta),
+                    SEARCH_INTERNAL, searchContext,
                     -1);
   FREE(size_h);
   FREE(mime);
   FREE(desc);
   FREE(name);
   FREENONNULL(thumb);
-  DEBUG_END();
+
+  /* update tab title with the number of results */
+  file_count = (unsigned int *)
+      g_object_get_data(G_OBJECT(list->searchpage), "file_count");
+  (*file_count)++;
+  tab_label = (GtkWidget *)
+      g_object_get_data(G_OBJECT(list->searchpage), "label");
+  tab_title = (char *)
+      g_object_get_data(G_OBJECT(list->searchpage), "title");
+  new_title =
+      g_strdup_printf("%s%s%u%s", 
+                     tab_title, " (", *file_count, ")");
+  gtk_label_set(GTK_LABEL(tab_label), new_title);
+  FREE(new_title);
+
+  if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(search_summary),
+                                     &iter)) {
+    GE_BREAK(ectx, 0);
+    return;
+  }
+
+  do { 
+    gtk_tree_model_get(GTK_TREE_MODEL(search_summary),
+                      &iter,
+                      SER_SUM_URI, &euri,
+                      -1);
+    if (ECRS_equalsUri(euri,
+                      uri)) {
+      gtk_list_store_set(GTK_LIST_STORE(search_summary),
+                        &iter,
+                        SER_SUM_COUNT, *file_count,
+                        -1);
+      DEBUG_END();
+      return;
+    }
+
+  } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(search_summary),
+                                   &iter));
 }
-                       
 
-GtkWidget * getAnonymityButtonFromTM(GtkTreeModel * model) {
+static SearchList * 
+fs_search_started(struct FSUI_SearchList * fsui_list,
+                 const struct ECRS_URI * uri,
+                 unsigned int anonymityLevel,
+                 unsigned int resultCount,
+                 const ECRS_FileInfo * results) {
+  GtkWidget * notebook;
+  GtkWidget * label;
+  GtkTreeIter iter;
   SearchList * list;
+  char * tabtxt;
+  int i;
+  const char * dhead;
 
-  list = head;
-  while (list != NULL) {
-    if (list->model == model)
-      return list->anonymityButton;
-    list = list->next;
+  notebook
+    = glade_xml_get_widget(getMainXML(),
+                          "downloadNotebook");
+  list
+    = MALLOC(sizeof(SearchList));
+  list->searchpage
+    = makeSearchResultFrame(&list->treeview,
+                           &list->anonymityButton);
+  list->uri
+    = ECRS_dupUri(uri);
+  list->next
+    = search_head;
+  list->fsui_list 
+    = fsui_list;
+  search_head = list;
+
+  description = ECRS_uriToString(uri);
+  if (description == NULL) {
+    GE_BREAK(ectx, 0);
+    return SYSERR;
   }
-  GE_BREAK(ectx, 0);
-  return NULL;
+  GE_ASSERT(ectx,
+           strlen(description) >= strlen(ECRS_URI_PREFIX));
+  dhead = &description[strlen(ECRS_URI_PREFIX)];
+  if (0 == strncmp(dhead,
+                  ECRS_SEARCH_INFIX,
+                  strlen(ECRS_SEARCH_INFIX)))
+    dhead = &dhead[strlen(ECRS_SEARCH_INFIX)];
+  else if (0 == strncmp(dhead,
+                       ECRS_SUBSPACE_INFIX,
+                       strlen(ECRS_SUBSPACE_INFIX)))
+    dhead = &dhead[strlen(ECRS_SUBSPACE_INFIX)];
+
+  tabtxt = STRDUP("foo"); /* FIXME! */
+  gtk_list_store_append(search_summary,
+                       &iter);
+  gtk_list_store_set(search_summary,
+                    &iter,
+                    SER_SUM_NAME, dhead,
+                    SER_SUM_COUNT, 0,
+                    SER_SUM_URI, ECRS_dupUri(uri),
+                    -1);
+  label = buildSearchTabLabel(list->searchpage, 
+                             dhead);
+  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                          list->searchpage,
+                          label);
+  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook),
+                               pages);
+  gtk_widget_show(notebook);
+  FREE(description);
+  for (i=0;i<resultCount;i++)
+    fs_search_result_received(ret,
+                             &results[i],
+                             uri);
+  DEBUG_END();
+  return list;
 }
 
 /**
@@ -209,183 +499,23 @@
                                    iter));
 }
 
-void on_searchResults_destroy_fs(GtkWidget * dummy,
-                                GtkWidget * treeview) {
-  GtkTreeStore * tree;
-  GtkTreeIter iter;
-
-  tree = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)));
-  if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(tree),
-                                     &iter))
-    return; /* tree empty */
-  freeIterSubtree(GTK_TREE_MODEL(tree),
-                 &iter);
-}
-
-/**
- * Add the given result to the model (search result
- * list).
- * @param info the information to add to the model
- * @param treeview the page from which to obtain the model
- * @param path the tree path that selects where to add
- *        the information
- */
-static void addSearchResultToModel(const ECRS_FileInfo * info,
-                                  GtkWidget * treeview,
-                                  GtkTreeRowReference * row) {
-  GtkTreeStore * model;
-  GtkTreeIter iter;
-  GtkTreeIter parent;
-  GtkTreeIter * pparent;
-  GtkTreePath * path;
-
-  DEBUG_BEGIN();
-  if (! gtk_tree_row_reference_valid(row))
-    path = NULL;
-  else
-    path = gtk_tree_row_reference_get_path(row);
-  model = GTK_TREE_STORE
-    (gtk_tree_view_get_model
-     (GTK_TREE_VIEW(treeview)));
-  if (path != NULL) {
-    gtk_tree_model_get_iter(GTK_TREE_MODEL(model),
-                           &parent,
-                           path);
-    pparent = &parent;
-  } else
-    pparent = NULL;
-  gtk_tree_store_insert(model,
-                       &iter,
-                       pparent,
-                       0x7FFFFFFF); /* MAX-int => insert at end! */
-  addEntryToSearchTree(model,
-                      &iter,
-                      info->uri,
-                      info->meta);
-  DEBUG_END();
-}
-
-/**
- * Add the given result to the model (search result
- * list).
- * @param info the information to add to the model
- * @param uri the search URI
- * @param path the tree path that selects where to add
- *        the information, NULL for top-level
- */
-void displaySearchResult(const ECRS_FileInfo * info,
-                        const struct ECRS_URI * uri,
-                        GtkTreeRowReference * row) {
-  SearchList * list;
-  struct ECRS_URI * euri;
-  unsigned int *file_count;
-  GtkTreeIter iter;
-  GtkWidget *tab_label;
-  char *tab_title, *new_title;
-
-  DEBUG_BEGIN();
-  list = head;
-  while (list != NULL) {
-    if (ECRS_equalsUri(list->uri,
-                      uri))
-      break;
-    list = list->next;
-  }
-  if (list == NULL) 
-    return; /* search result received during shutdown */  
-  addSearchResultToModel(info,
-                        list->treeview,
-                        row);
-
-  /* update tab title with the number of results */
-  file_count = (unsigned int *)
-      g_object_get_data(G_OBJECT(list->searchpage), "file_count");
-  (*file_count)++;
-  tab_label = (GtkWidget *)
-      g_object_get_data(G_OBJECT(list->searchpage), "label");
-  tab_title = (char *)
-      g_object_get_data(G_OBJECT(list->searchpage), "title");
-  new_title =
-      g_strdup_printf("%s%s%u%s", tab_title, " (", *file_count, ")");
-  gtk_label_set(GTK_LABEL(tab_label), new_title);
-  FREE(new_title);
-
-  if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(summary),
-                                     &iter)) {
-    GE_BREAK(ectx, 0);
-    return;
-  }
-
-  do { 
-    gtk_tree_model_get(GTK_TREE_MODEL(summary),
-                      &iter,
-                      SER_SUM_URI, &euri,
-                      -1);
-    if (ECRS_equalsUri(euri,
-                      uri)) {
-      gtk_list_store_set(GTK_LIST_STORE(summary),
-                        &iter,
-                        SER_SUM_COUNT, *file_count,
-                        -1);
-      DEBUG_END();
-      return;
-    }
-
-  } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(summary),
-                                   &iter));
-  GE_BREAK(ectx, 0);
-}
-
-static void * stopSearch(void * u) {
-  struct FSUI_SearchList * search = u;
-
-  DEBUG_BEGIN();
-  FSUI_stopSearch(ctx,
-                 search);
-  DEBUG_END();
-  return NULL;
-}
-
-static void freeSearchModel(GtkTreeModel * model,
-                           GtkTreeIter * parent) {
-  struct ECRS_URI * u;
-  struct ECRS_MetaData * m;
-  GtkTreeIter iter;
-
-  DEBUG_BEGIN();
-  if (gtk_tree_model_iter_children(model,
-                                  &iter,
-                                  parent)) {
-    do {
-      gtk_tree_model_get(model,
-                        &iter,
-                        SEARCH_URI, &u,
-                        SEARCH_META, &m,
-                        -1);
-      gtk_tree_store_set(GTK_TREE_STORE(model),
-                        &iter,
-                        SEARCH_URI, NULL,
-                        SEARCH_META, NULL,
-                        -1);
-      if (u != NULL)
-       ECRS_freeUri(u);
-      if (m != NULL)
-       ECRS_freeMetaData(m);
-      freeSearchModel(model, &iter);
-    } while (gtk_tree_model_iter_next(model,
-                                     &iter));
-  }  
-  DEBUG_END();
-}
-
-static void closeSearchPage(SearchList * list) {
+void fs_search_stopped(SearchList * list) {
   GtkWidget * notebook;
   int index;
   int i;
   GtkTreeIter iter;
   struct ECRS_URI * euri;
+  SearchList * prev;
 
   DEBUG_BEGIN();
+  if (search_head == list) {
+    search_head = search_head->next;
+  } else {
+    prev = search_head;
+    while (prev->next != list) 
+      prev = prev->next;
+    prev->next = list->next;
+  }
   notebook
     = glade_xml_get_widget(getMainXML(),
                           "downloadNotebook");
@@ -394,666 +524,860 @@
     if (list->searchpage == gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
                                                      i))
       index = i;
-
-  if (index != -1) {
-    gtk_notebook_remove_page(GTK_NOTEBOOK(notebook),
-                            index);
-  } else {
-    GE_BREAK(ectx, 0);
-  }
+  gtk_notebook_remove_page(GTK_NOTEBOOK(notebook),
+                          index);
+  /* recursively free download tree */
+  if (gtk_tree_model_get_iter_first(list->model,
+                                   &iter))
+    freeIterSubtree(list->model,
+                   &iter);
   freeSearchModel(list->model, NULL);
-  list->model = NULL;
-
-  if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(summary),
+  if (! gtk_tree_model_get_iter_first(GTK_TREE_MODEL(search_summary),
                                      &iter)) {
     GE_BREAK(ectx, 0);
     ECRS_freeUri(list->uri);
-    list->uri = NULL;
+    FREE(list);
+    DEBUG_END();
     return;
   }
   do { 
-    gtk_tree_model_get(GTK_TREE_MODEL(summary),
+    gtk_tree_model_get(GTK_TREE_MODEL(search_summary),
                       &iter,
                       SER_SUM_URI, &euri,
                       -1);
     if (ECRS_equalsUri(euri,
                       list->uri)) {
-      gtk_list_store_remove(GTK_LIST_STORE(summary),
+      gtk_list_store_remove(GTK_LIST_STORE(search_summary),
                            &iter);
       ECRS_freeUri(euri);
-      ECRS_freeUri(list->uri);
-      list->uri = NULL;
-      DEBUG_END();
-      return;
+      break;
     }
-  } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(summary),
+  } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(search_summary),
                                    &iter));
   ECRS_freeUri(list->uri);
-  list->uri = NULL;
-  GE_BREAK(ectx, 0);
-}
-
-void on_closeSearchButton_clicked_fs(GtkWidget * searchPage,
-                                    GtkWidget * closeButton) {
-  SearchList * list;
-  SearchList * prev;
-
-  DEBUG_BEGIN();
-  list = head;
-  prev = NULL;
-  while (list != NULL) {
-    if (list->searchpage == searchPage)
-      break;
-    prev = list;
-    list = list->next;
-  }
-  if (list == NULL)
-    return;
-  if (prev == NULL)
-    head = list->next;
-  else
-    prev->next = list->next;
-
-  run_with_save_calls(&stopSearch,
-                     list->fsui_list);
-  closeSearchPage(list);
   FREE(list);
   DEBUG_END();
 }
 
-static GtkWidget * makeResultFrame(GtkWidget ** treeview,
-                                  GtkWidget ** anonSpin) {
-  GtkWidget * window;
-  GtkWidget * child;
-  GtkWidget * resultList;
+void fs_search_start(struct GE_Context * e,
+                    struct GC_Configuration * c) {
+  GtkWidget * searchCB;
+  GtkWidget * searchList;
+  GtkListStore * model;
+  GtkCellRenderer * renderer;
   GtkTreeViewColumn * column;
-  GtkCellRenderer * renderer;
-  GtkTreeStore * tree;
-  GladeXML * searchXML;
   int col;
+  GtkWidget * downloadList;
+  
+  ectx = e;
+  cfg = c;
+  DEBUG_BEGIN();
+  searchCB
+    = glade_xml_get_widget(getMainXML(),
+                          "fssearchKeywordComboBoxEntry");
 
-  DEBUG_BEGIN();
-  searchXML
-    = glade_xml_new(getGladeFileName(),
-                   "searchResultsFrame",
-                   PACKAGE_NAME);
-  connectGladeWithPlugins(searchXML);
-  window = glade_xml_get_widget(searchXML,
-                              "searchResultsFrame");
-  resultList = glade_xml_get_widget(searchXML,
-                                   "searchResults");
-  *anonSpin = glade_xml_get_widget(searchXML,
-                                  "downloadAnonymitySpinButton");
-  if (treeview != NULL)
-    (*treeview) = GTK_WIDGET(GTK_TREE_VIEW(resultList));
-  tree =
-    gtk_tree_store_new(SEARCH_NUM,
+  model = gtk_list_store_new(NS_SEARCH_NUM,
+                            G_TYPE_STRING, /* what we show */
+                            G_TYPE_STRING, /* EncName of namespace */
+                            G_TYPE_POINTER, /* ECRS MetaData */
+                            G_TYPE_POINTER, /* FSUI search list */
+                            G_TYPE_INT);  /* Meta-data about namespace */
+  gtk_combo_box_set_model(GTK_COMBO_BOX(searchCB),
+                         GTK_TREE_MODEL(model));
+  gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(searchCB),
+                                     NS_SEARCH_DESCRIPTION);
+  searchList = glade_xml_get_widget(getMainXML(),
+                                   "activeSearchesSummary");
+  search_summary =
+    gtk_list_store_new(SER_SUM_NUM,
                       G_TYPE_STRING, /* name */
-                      G_TYPE_UINT64,  /* size */
-                      G_TYPE_STRING,  /* human-readable size */
-                      G_TYPE_STRING, /* mime-type */
-                      G_TYPE_STRING, /* meta-data (some) */
-                      GDK_TYPE_PIXBUF, /* preview */   
-                      G_TYPE_POINTER,  /* url */
-                      G_TYPE_POINTER,  /* meta */
-                      G_TYPE_POINTER); /* internal: download info/NULL */
-  gtk_tree_view_set_model(GTK_TREE_VIEW(resultList),
-                         GTK_TREE_MODEL(tree));
+                      G_TYPE_INT,    /* # results */
+                      G_TYPE_POINTER,  /* internal: FSUI search list */
+                      G_TYPE_POINTER);  /* internal: uri */
+  gtk_tree_view_set_model(GTK_TREE_VIEW(searchList),
+                         GTK_TREE_MODEL(search_summary));
   renderer = gtk_cell_renderer_text_new();
-  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
+  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(searchList),
                                              -1,
-                                             _("Name"),
+                                             _("Query"),
                                              renderer,
-                                             "text", SEARCH_NAME,
+                                             "text", SER_SUM_NAME,
                                              NULL);
-  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
                                    col - 1);
   gtk_tree_view_column_set_resizable(column, TRUE);
   gtk_tree_view_column_set_clickable(column, TRUE);
   gtk_tree_view_column_set_reorderable(column, TRUE);
-  gtk_tree_view_column_set_sort_column_id(column, SEARCH_NAME);
-  /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+  gtk_tree_view_column_set_sort_column_id(column, SER_SUM_NAME);
+  
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
+                                              col - 1),
+                                              TRUE);
   renderer = gtk_cell_renderer_text_new();
-  g_object_set (renderer, "xalign", 1.00, NULL);
-  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
+  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(searchList),
                                              -1,
-                                             _("Size"),
+                                             _("Results"),
                                              renderer,
-                                             "text", SEARCH_HSIZE,
+                                             "text", SER_SUM_COUNT,
                                              NULL);
-  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
                                    col - 1);
   gtk_tree_view_column_set_resizable(column, TRUE);
   gtk_tree_view_column_set_clickable(column, TRUE);
   gtk_tree_view_column_set_reorderable(column, TRUE);
-  gtk_tree_view_column_set_sort_column_id(column, SEARCH_SIZE);
-  /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+  gtk_tree_view_column_set_sort_column_id(column, SER_SUM_COUNT);
+  
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
+                                              col - 1),
+                                              TRUE);
 
-  renderer = gtk_cell_renderer_text_new();
-  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
-                                             -1,
-                                             _("Mime-type"),
-                                             renderer,
-                                             "text", SEARCH_MIME,
-                                             NULL);
-  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+
+  downloadList = glade_xml_get_widget(getMainXML(),
+                                      "activeDownloadsList");
+  download_summary =
+    gtk_tree_store_new(DOWNLOAD_NUM,
+                       G_TYPE_STRING, /* name (full-path file name) */
+                       G_TYPE_STRING, /* name (user-friendly name) */
+                       G_TYPE_UINT64,  /* size */
+                      G_TYPE_STRING, /* human readable size */
+                       G_TYPE_INT,  /* progress */
+                       G_TYPE_STRING, /* uri */
+                       G_TYPE_POINTER,  /* url */
+                       G_TYPE_POINTER, /* internal: gtk tree path / NULL */
+                       G_TYPE_STRING); /* directory path if file is inside a 
dir */
+  gtk_tree_view_set_model(GTK_TREE_VIEW(downloadList),
+                          GTK_TREE_MODEL(download_summary));
+  renderer = gtk_cell_renderer_progress_new();
+  col = 
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(downloadList),
+                                              -1,
+                                              _("Name"),
+                                              renderer,
+                                              "value", DOWNLOAD_PROGRESS,
+                                              "text", DOWNLOAD_SHORTNAME,
+                                              NULL);
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(downloadList),
                                    col - 1);
   gtk_tree_view_column_set_resizable(column, TRUE);
   gtk_tree_view_column_set_clickable(column, TRUE);
   gtk_tree_view_column_set_reorderable(column, TRUE);
-  gtk_tree_view_column_set_sort_column_id(column, SEARCH_MIME);
+  gtk_tree_view_column_set_sort_column_id(column, DOWNLOAD_PROGRESS);
   /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+  
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(downloadList),
+                                              col - 1),
+                                              TRUE);
+  renderer = gtk_cell_renderer_text_new();
+  g_object_set (renderer, "xalign", 1.00, NULL);
+  col = 
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(downloadList),
+                                              -1,
+                                              _("Size"),
+                                              renderer,
+                                              "text", DOWNLOAD_HSIZE,
+                                              NULL);
   
-  renderer = gtk_cell_renderer_text_new();
-  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
-                                             -1,
-                                             _("Meta-data"),
-                                             renderer,
-                                             "text", SEARCH_DESC,
-                                             NULL);
-  column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(downloadList),
                                    col - 1);
   gtk_tree_view_column_set_resizable(column, TRUE);
   gtk_tree_view_column_set_clickable(column, TRUE);
   gtk_tree_view_column_set_reorderable(column, TRUE);
-  gtk_tree_view_column_set_sort_column_id(column, SEARCH_DESC);
+  gtk_tree_view_column_set_sort_column_id(column, DOWNLOAD_SIZE);
   /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
-  if (YES != GC_get_configuration_value_yesno(cfg,
-                                             "GNUNET-GTK",
-                                             "DISABLE-PREVIEWS",
-                                             NO)) {
-    renderer = gtk_cell_renderer_pixbuf_new();
-    col = 
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(resultList),
-                                               -1,
-                                               _("Preview"),
-                                               renderer,
-                                               "pixbuf", SEARCH_PIXBUF,
-                                               NULL);
-    column = gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
-                                     col - 1);
-    gtk_tree_view_column_set_resizable(column, TRUE);
-    gtk_tree_view_column_set_reorderable(column, TRUE);
-    
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(resultList),
-                                                col - 1),
-                                                TRUE);
-  }
-  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(searchXML);
+  
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(downloadList),
+                                              col - 1),
+                                              TRUE);
+  renderer = gtk_cell_renderer_text_new();
+  col = 
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(downloadList),
+                                              -1,
+                                              _("URI"),
+                                              renderer,
+                                              "text", DOWNLOAD_URISTRING,
+                                              NULL);
+  column = gtk_tree_view_get_column(GTK_TREE_VIEW(downloadList),
+                                   col - 1);
+  gtk_tree_view_column_set_resizable(column, TRUE);
+  gtk_tree_view_column_set_reorderable(column, TRUE);
+  /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
+  
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(downloadList),
+                                              col - 1),
+                                              TRUE);
   DEBUG_END();
-  return child;
 }
 
-typedef struct {
-  struct ECRS_URI * uri;
-  int anon;
-  struct FSUI_SearchList * ret;
-} StartSearchClosure;
+void fs_search_stop() {
+}
 
-static void * startSearch(void * cls) {
-  StartSearchClosure * ssc = cls;
 
-  ssc->ret = FSUI_startSearch(ctx,
-                             ssc->anon,
-                             1000, /* FIXME: max results */
-                             99 * cronYEARS, /* FIXME: timeout */
-                             ssc->uri);
-  return NULL;
-}
 
-void on_fssearchbutton_clicked_fs(gpointer dummy2,
-                                 GtkWidget * searchButton) {
-  GtkWidget * searchKeywordGtkCB;
-  GtkWidget * searchNamespaceGtkCB;
-  GtkWidget * notebook;
-  GtkWidget * page;
-  GtkWidget * label;
-  GtkWidget * entry;
-  GtkWidget * spin;
-  GtkListStore * model;
-  GtkTreeModel * tmodel;
+
+
+
+
+
+#if 0
+static int addFilesToDirectory
+  (const ECRS_FileInfo * fi,
+   const HashCode512 * key,
+   int isRoot,
+   void * closure) {
+  struct ECRS_URI * uri = closure;
+  DownloadList * pos;
   GtkTreeIter iter;
-  struct ECRS_URI * uri;
-  const char * ss;
-  const char * ns;
-  gint pages;
-  gint i;
-  char * tabtxt;
-  SearchList * list;
-  const char * descStr;
-  StartSearchClosure ssc;
+  GtkTreeIter child;
+  int i;
+  GtkTreePath * path;
 
+  if (isRoot == YES)
+    return OK;
   DEBUG_BEGIN();
-  searchKeywordGtkCB
-    = glade_xml_get_widget(getMainXML(),
-                          "fssearchKeywordComboBoxEntry");
-  entry = gtk_bin_get_child(GTK_BIN(searchKeywordGtkCB));
-  ss = gtk_entry_get_text(GTK_ENTRY(entry));
-  if (ss == NULL) {
-    GE_LOG(ectx,
-          GE_ERROR | GE_USER | GE_IMMEDIATE,
-          _("Need a keyword to search!\n"));
-    return;
+  pos = download_head;
+  while (pos != NULL) {
+    if (ECRS_equalsUri(uri,
+                       pos->uri))
+      break;
+    pos = pos->next;
   }
-  i = gtk_combo_box_get_active(GTK_COMBO_BOX(searchKeywordGtkCB));
-  if (i == -1) {
-    model = GTK_LIST_STORE
-      (gtk_combo_box_get_model
-       (GTK_COMBO_BOX(searchKeywordGtkCB)));
-    gtk_list_store_prepend(model,
-                          &iter);
-    gtk_list_store_set(model,
-                      &iter,
-                      0, ss,
-                      -1);
+  if (pos != NULL) {
+    if (! gtk_tree_row_reference_valid(pos->rr))
+      return SYSERR;
+    path = gtk_tree_row_reference_get_path(pos->rr);
+    gtk_tree_model_get_iter(GTK_TREE_MODEL(pos->model),
+                            &iter,
+                            path);
+    gtk_tree_path_free(path);
+    for (i=gtk_tree_model_iter_n_children(pos->model,
+                                          &iter)-1;i>=0;i--) {
+      if (TRUE == gtk_tree_model_iter_nth_child(pos->model,
+                                                &child,
+                                                &iter,
+                                                i)) {
+        struct ECRS_URI * uri;
+        uri = NULL;
+        gtk_tree_model_get(pos->model,
+                           &child,
+                           SEARCH_URI, &uri,
+                           -1);
+        if ( (uri != NULL) &&
+             (ECRS_equalsUri(uri,
+                             fi->uri)) )
+          return OK;
+      }
+    }
+    gtk_tree_store_append(GTK_TREE_STORE(pos->model),
+                          &child,
+                          &iter);
+    addEntryToSearchTree(GTK_TREE_STORE(pos->model),
+                         &child,
+                         fi->uri,
+                         fi->meta);
   }
+  DEBUG_END();
+  return OK;
+}
+#endif
 
-  searchNamespaceGtkCB
-    = glade_xml_get_widget(getMainXML(),
-                          "searchNamespaceComboBoxEntry");
+/**
+ * FIXME: somehow need way to pass
+ * tree path for search into this download!
+ */
+struct DL *
+fs_download_started(struct FSUI_DownloadList * fsui_dl,
+                   unsigned long long total,
+                   unsigned int anonymityLevel,
+                   const struct ECRS_FileInfo * fi,
+                   const char * filename,
+                   unsigned long long completed,
+                   cron_t eta) {
+  DownloadList * list;
+  GtkTreeIter iiter;
+  GtkTreePath *dirTreePath;
+  unsigned long long size;
+  char * size_h;
+  const char * idc_name;
+  
+  /* setup visualization */
+  list = MALLOC(sizeof(DownloadList));
+  list->download_list = fsui_dl;
+  list->rr = NULL;
+  list->model = NULL;
+  if (YES == ECRS_isDirectory(fi->meta)) {
+    list->rr = gtk_tree_row_reference_new(model, path);
+    list->model = model;
+  }
+  list->uri = ECRS_dupUri(fi->uri);
+  list->filename = STRDUP(filename);
+  size = ECRS_fileSize(fi->uri);
+  size_h = string_get_fancy_byte_size(size);
+  idc_name = "FIXME";
+  gtk_tree_store_append(download_summary,
+                        &iiter,
+                        NULL);
+  gtk_tree_store_set(download_summary,
+                     &iiter,
+                     DOWNLOAD_FILENAME, filename,
+                     DOWNLOAD_SHORTNAME, idc_name,
+                     DOWNLOAD_SIZE, size,
+                    DOWNLOAD_HSIZE, size_h,
+                     DOWNLOAD_PROGRESS, 0, /* progress */
+                     DOWNLOAD_URISTRING, uri_name,
+                     DOWNLOAD_URI, ECRS_dupUri(fi->uri),
+                     DOWNLOAD_TREEPATH, list->rr, /* internal: row reference! 
*/
+                     DOWNLOAD_DIRPATH, dirPath,                     
+                     -1);
+  FREE(size_h);
+  list->next = download_head;
+  download_head = list;
+  DEBUG_END();
+  return list;
+}
 
-  tmodel = gtk_combo_box_get_model(GTK_COMBO_BOX(searchNamespaceGtkCB));
-  if (TRUE == 
gtk_combo_box_get_active_iter(GTK_COMBO_BOX(searchNamespaceGtkCB),
-                                           &iter)) {
-    ns = NULL;
-    descStr = NULL;
-    gtk_tree_model_get(tmodel,
-                      &iter,
-                      NS_SEARCH_DESCRIPTION, &descStr,
-                      NS_SEARCH_ENCNAME, &ns,
-                      -1);
 
-    if ( (descStr != NULL) &&
-        (0 == strcmp(descStr,
-                     _("globally"))) ) {
-      ns = NULL;
+
+
+static void initiateDownload(GtkTreeModel * model,
+                             GtkTreePath * path,
+                             GtkTreeIter * iter,
+                             gpointer unused) {
+  char * uri_name;
+  char * final_download_dir;
+  DownloadList * list;
+  GtkTreeIter iiter;
+  GtkWidget * spin;
+  const char * oname;
+  const char * cname;
+  char * dname;
+  GtkTreePath *dirTreePath;
+  char *dirPath;
+  unsigned int dirPathLen;
+  char * size_h;
+  unsigned long long size;
+
+  struct ECRS_URI * idc_uri;
+  struct ECRS_MetaData * idc_meta;
+  const char * idc_name;
+  const char * idc_mime;
+  char * idc_final_download_destination;
+  unsigned int idc_anon;
+  struct FSUI_SearchList * idc_ret;
+  struct SL * searchContext;
+
+#ifdef WINDOWS
+  char *filehash = NULL;
+#endif
+
+  DEBUG_BEGIN();
+  idc_uri = NULL;
+  idc_meta = NULL;
+  idc_name = NULL;
+  idc_mime = NULL;
+  gtk_tree_model_get(model,
+                     iter,
+                     SEARCH_NAME, &idc_name,
+                     SEARCH_URI, &idc_uri,
+                     SEARCH_META, &idc_meta,
+                     SEARCH_MIME, &idc_mime,
+                    SEARCH_INTERNAL, &searchContext,
+                     -1);
+  if (idc_uri == NULL) {
+    GE_BREAK(ectx, 0);
+    return;
+  }
+
+  spin = searchContext->anonymityButton;
+  if (spin == NULL) {
+    GE_BREAK(ectx, 0);
+    idc_anon = 1;
+  } else {
+    idc_anon = gtk_spin_button_get_value_as_int
+      (GTK_SPIN_BUTTON(spin));
+  }
+  if (! ECRS_isFileUri(idc_uri)) {
+    if (ECRS_isNamespaceUri(idc_uri)) {
+      /* start namespace search; would probably be better
+        to add this as a subtree, but for simplicity
+        we'll just add it as a new tab for now */
+      FSUI_startSearch(ctx,
+                      idc_anon,
+                      1000, /* FIXME: max results */
+                      99 * cronYEARS, /* fixme: timeout */
+                      idc_uri);
+      return;
     } else {
-      GE_ASSERT(ectx, strlen(ns) == sizeof(EncName) - 1);
-      if (descStr == NULL)
-       descStr = ns;
+      GE_BREAK(ectx, 0); /* unsupported URI type (i.e. ksk or loc) */
+      return;
     }
   }
-  if (ns != NULL) {
-    char * ustring;
 
-    ustring = MALLOC(strlen(ss) + sizeof(EncName) +
-                    strlen(ECRS_URI_PREFIX) +
-                    strlen(ECRS_SUBSPACE_INFIX) + 10);
-    strcpy(ustring, ECRS_URI_PREFIX);
-    strcat(ustring, ECRS_SUBSPACE_INFIX);
-    strcat(ustring, ns);
-    strcat(ustring, "/");
-    strcat(ustring, ss);
-    uri = ECRS_stringToUri(ectx, ustring);
-    if (uri == NULL) {
-      GE_LOG(ectx,
-            GE_ERROR | GE_BULK | GE_USER,
-            _("Failed to create namespace URI from `%s'.\n"),
-            ustring);
-    }
-    FREE(ustring);
-  } else {
-    uri = ECRS_parseCharKeywordURI(ectx, ss);
-  }
-  if (uri == NULL)
+  uri_name = ECRS_uriToString(idc_uri);
+  if ( (uri_name == NULL) ||
+       (strlen(uri_name) <
+        strlen(ECRS_URI_PREFIX) +
+        strlen(ECRS_FILE_INFIX)) ) {
+    GE_BREAK(ectx, 0);
+    FREENONNULL(uri_name);
     return;
-  if (ns == NULL) {
-    tabtxt = STRDUP(ss);
-  } else {
-    GE_ASSERT(ectx, descStr != NULL);
-    tabtxt = MALLOC(strlen(ss) + strlen(descStr) + 2);
-    SNPRINTF(tabtxt,
-            strlen(ss) + strlen(descStr) + 2,
-            "%s/%s",
-            descStr,
-            ss);
   }
-  notebook
-    = glade_xml_get_widget(getMainXML(),
-                          "downloadNotebook");
-  list = head;
-  pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
-  while (list != NULL) {
-    if (ECRS_equalsUri(list->uri,
-                      uri)) {
-      for (i=0;i<pages;i++) {
-       page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook),
-                                        i);
-       if (page == list->searchpage) {
-         gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook),
-                                       i);
-         ECRS_freeUri(uri);
-         FREE(tabtxt);
-         return;
-       }
-      }
-      GE_BREAK(ectx, 0);
+
+  if (idc_name == NULL) {
+#ifdef WINDOWS
+    filehash = STRDUP(uri_name);
+    filehash[16] = 0;
+    idc_name = filehash;
+#else
+    idc_name = uri_name;
+#endif
+  } 
+
+  cname = idc_name;
+  oname = idc_name;
+  dname = MALLOC(strlen(idc_name)+1);
+  dname[0] = '\0';
+  while (*idc_name != '\0') {
+    if ( (*idc_name == DIR_SEPARATOR) &&
+        (idc_name[1] != '\0') ) {
+      memcpy(dname, oname, idc_name - oname);
+      dname[idc_name - oname] = '\0';
+      cname = &idc_name[1];
     }
-    list = list->next;
+    idc_name++;
   }
-  list
-    = MALLOC(sizeof(SearchList));
-  list->searchpage
-    = makeResultFrame(&list->treeview,
-                     &spin);
-  list->next
-    = head;
-  list->uri
-    = uri;
-  list->model
-    = gtk_tree_view_get_model(GTK_TREE_VIEW(list->treeview));
-  list->anonymityButton
-    = spin;
+  if (*cname == '\0') /* name ended in '/' - likely directory */
+    cname = oname;
+  idc_name = cname;
+  GC_get_configuration_value_filename(cfg,
+                                     "FS",
+                                     "INCOMINGDIR",
+                                     "$HOME/gnunet-downloads/",
+                                     &final_download_dir);
+  if (strlen(dname) > 0) {
+    char * tmp;
+    tmp = MALLOC(strlen(final_download_dir) + strlen(dname) + 2);
+    strcpy(tmp, final_download_dir);
+    if (tmp[strlen(tmp)] != DIR_SEPARATOR)
+      strcat(tmp, DIR_SEPARATOR_STR);
+    if (dname[0] == DIR_SEPARATOR)
+      strcat(tmp, &dname[1]);
+    else
+      strcat(tmp, dname);
+    FREE(final_download_dir);
+    final_download_dir = tmp;
+  }
+  FREE(dname);
+  disk_directory_create(ectx, final_download_dir);
 
-  head = list;
 
-  gtk_list_store_append(summary,
-                       &iter);
-  gtk_list_store_set(summary,
-                    &iter,
-                    SER_SUM_NAME, tabtxt,
-                    SER_SUM_COUNT, 0,
-                    SER_SUM_URI, ECRS_dupUri(uri),
-                    -1);
+  /* If file is inside a directory, get the full path */
+  dirTreePath = gtk_tree_path_copy(path);
+  dirPath = MALLOC(1);
+  dirPath[0] = '\0';
+  dirPathLen = 0;
+  while (gtk_tree_path_get_depth(dirTreePath) > 1) {
+    const char * dirname;
+    char * new;
 
-  label = buildSearchTabLabel(list->searchpage, tabtxt);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                          list->searchpage,
-                          label);
-  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook),
-                               pages);
-  gtk_widget_show(notebook);
-  ssc.anon = getAnonymityLevel(getMainXML(),
-                              "searchAnonymitySelectionSpinButton");
-  ssc.uri = uri;
-  run_with_save_calls(&startSearch,
-                     &ssc);
-  list->fsui_list = ssc.ret;
-  FREE(tabtxt);
-  DEBUG_END();
-}
+    if (! gtk_tree_path_up(dirTreePath))
+      break;
 
-static int addNamespace(void * arg,
-                       const char * namespaceName,
-                       const HashCode512 * namespaceId,
-                       const struct ECRS_MetaData * md,
-                       int rating) {
-  GtkListStore * model = arg;
-  GtkTreeIter iter;
-  EncName enc;
-  char * name;
-  struct ECRS_MetaData * dmd;
-  char * desc;
-  size_t n;
-
-  DEBUG_BEGIN();
-  hash2enc(namespaceId,
-          &enc);
-  if (md == NULL) {
-    dmd = NULL;
-    desc = STRDUP("");
-  } else {
-    dmd = ECRS_dupMetaData(md);
-    desc = ECRS_getFirstFromMetaData(md,
-                                    EXTRACTOR_DESCRIPTION,
-                                    EXTRACTOR_TITLE,
-                                    EXTRACTOR_AUTHOR,
-                                    EXTRACTOR_GENRE,
-                                    EXTRACTOR_SUBJECT,
-                                    EXTRACTOR_CREATOR,
-                                    EXTRACTOR_PRODUCER,
-                                    EXTRACTOR_GROUP,
-                                    EXTRACTOR_CREATED_FOR,
-                                    EXTRACTOR_SUMMARY,
-                                    EXTRACTOR_OWNER,
-                                    -1);
-    if (desc == NULL)
-      desc = STRDUP("");
+    if (!gtk_tree_model_get_iter(model,
+                                &iiter,
+                                dirTreePath))
+      break;
+    gtk_tree_model_get(model,
+                       &iiter,
+                       SEARCH_NAME, &dirname,
+                       -1);
+    dirPathLen = strlen(dirPath) + strlen(dirname) + strlen(DIR_SEPARATOR_STR) 
+ 1;
+    new = MALLOC(dirPathLen + 1);
+    strcpy(new, dirname);
+    if (new[strlen(new)-1] != DIR_SEPARATOR)
+      strcat(new, DIR_SEPARATOR_STR);
+    strcat(new, dirPath);
+    FREE(dirPath);
+    dirPath = new;
   }
+  gtk_tree_path_free(dirTreePath);
 
-  n = strlen(desc) + 64;
-  name = MALLOC(n);
-  SNPRINTF(name,
-          n,
-          "%s: %*.s",
-          desc,
-          20,
-          &enc);
-  gtk_list_store_append(model,
-                       &iter);
-  gtk_list_store_set(model,
-                    &iter,
-                    NS_SEARCH_DESCRIPTION, name,
-                    NS_SEARCH_ENCNAME, &enc,
-                    NS_SEARCH_METADATA, dmd,
-                    NS_SEARCH_RATING, rating,
-                    -1);
-  FREE(name);
-  DEBUG_END();
-  return OK;
+
+  /* construct completed/directory/real-filename */
+  idc_final_download_destination = MALLOC(strlen(final_download_dir) + 2 +
+                                         strlen(idc_name) + 
strlen(GNUNET_DIRECTORY_EXT) +
+                                         strlen(dirPath));
+  strcpy(idc_final_download_destination, final_download_dir);
+  if (idc_final_download_destination[strlen(idc_final_download_destination)-1] 
!= DIR_SEPARATOR)
+    strcat(idc_final_download_destination,
+           DIR_SEPARATOR_STR);
+  strcat(idc_final_download_destination, dirPath);
+  disk_directory_create(ectx,
+                       idc_final_download_destination);
+  strcat(idc_final_download_destination, idc_name);
+  if ( (idc_final_download_destination[strlen(idc_final_download_destination) 
- 1] == '/') ||
+       (idc_final_download_destination[strlen(idc_final_download_destination) 
- 1] == '\\') )
+    idc_final_download_destination[strlen(idc_final_download_destination) - 1] 
= '\0'; 
+  /* append ".gnd" if needed (== directory and .gnd not present) */
+  if ( (idc_mime != NULL) && 
+       (0 == strcmp(idc_mime, GNUNET_DIRECTORY_MIME)) &&
+       ( (strlen(idc_final_download_destination) < 
strlen(GNUNET_DIRECTORY_EXT)) ||
+        (0 != 
strcmp(&idc_final_download_destination[strlen(idc_final_download_destination) 
+                                                     - 
strlen(GNUNET_DIRECTORY_EXT)],
+                     GNUNET_DIRECTORY_EXT)) ) )
+    strcat(idc_final_download_destination, GNUNET_DIRECTORY_EXT);
+   
+  addLogEntry(_("Downloading `%s'"), idc_name);
+  FSUI_startDownload(ctx,
+                    idc->anon,
+                    NO, /* FIXME: isRecursive */
+                    idc_uri,
+                    idc_final_download_destination);
+  FREE(uri_name);
+  FREE(dirPath);
+  FREENONNULL(final_download_dir);
+#ifdef WINDOWS
+  FREENONNULL(filehash);
+#endif
 }
 
-#if 0
-/**
- * cron job that periodically updates the model for the
- * namespace selection in the search vbox.
- */
-static void updateNCBModelSafe(void * unused) {
-  GtkWidget * searchNamespaceCB;
-  GtkListStore * model;
-  GtkTreeIter iter;
+void on_downloadButton_clicked_fs(GtkWidget * treeview,
+                                 GtkWidget * downloadButton) {
+  GtkTreeSelection * selection;
 
-  model = gtk_list_store_new(NS_SEARCH_NUM,
-                            G_TYPE_STRING, /* what we show */
-                            G_TYPE_STRING, /* EncName of namespace */
-                            G_TYPE_POINTER,
-                            G_TYPE_INT);  /* Meta-data about namespace */
-  gtk_list_store_append(model,
-                       &iter);
-  gtk_list_store_set(model,
-                    &iter,
-                    NS_SEARCH_DESCRIPTION, _("globally"),
-                    NS_SEARCH_ENCNAME, NULL,
-                    NS_SEARCH_METADATA, NULL,          
-                    NS_SEARCH_RATING, 0,
-                    -1);
-  NS_listNamespaces(ectx,
-                   cfg,
-                   NO,
-                   &addNamespace,
-                   model);
-  searchNamespaceCB
-    = glade_xml_get_widget(getMainXML(),
-                          "searchNamespaceComboBoxEntry");
-  gtk_combo_box_set_model(GTK_COMBO_BOX(searchNamespaceCB),
-                         GTK_TREE_MODEL(model));
-  if 
(gtk_combo_box_entry_get_text_column(GTK_COMBO_BOX_ENTRY(searchNamespaceCB)) == 
-1)
-    gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(searchNamespaceCB),
-                                       0);
-  if (-1 == gtk_combo_box_get_active(GTK_COMBO_BOX(searchNamespaceCB)))
-    gtk_combo_box_set_active(GTK_COMBO_BOX(searchNamespaceCB),
-                            0);
+  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+  gtk_tree_selection_selected_foreach
+    (selection,
+     &initiateDownload,
+     NULL);
 }
 
-static void updateNCBModel(void * dummy) {
-  gtkSaveCall(&updateNCBModelSafe, NULL);
+
+void on_statusDownloadURIEntry_editing_done_fs(GtkWidget * entry,
+                                              GtkWidget * downloadButton) {
+  struct ECRS_URI * idc_uri;
+  struct ECRS_MetaData * idc_meta;
+  const char * idc_name;
+  const char * idc_mime;
+  char * idc_final_download_destination;
+  unsigned int idc_anon;
+  struct FSUI_SearchList * idc_ret;
+  const char * uris;
+  char * urid;
+  GtkWidget * spin;
+  char * final_download_dir;
+  const char * dname;
+  DownloadList * list;
+  GtkTreeIter iiter;
+  char * size_h;
+ 
+  uris = gtk_entry_get_text(GTK_ENTRY(entry));
+  urid = STRDUP(uris);
+  gtk_entry_set_text(GTK_ENTRY(entry),
+                    ECRS_URI_PREFIX);
+  idc_uri = ECRS_stringToUri(ectx, urid);
+  if (idc_uri == NULL) {
+    addLogEntry(_("Invalid URI `%s'"), urid);
+    FREE(urid);
+    return;
+  }
+  if (ECRS_isKeywordUri(idc_uri)) {
+    addLogEntry(_("Please use the search function for keyword (KSK) URIs!"));
+    FREE(urid);
+    ECRS_freeUri(idc_uri);
+    return;
+  } else if (ECRS_isLocationUri(idc_uri)) {
+    addLogEntry(_("Location URIs are not yet supported"));
+    FREE(urid);
+    ECRS_freeUri(idc_uri);
+    return;
+  }
+  GC_get_configuration_value_filename(cfg,
+                                     "FS",
+                                     "INCOMINGDIR",
+                                     "$HOME/gnunet-downloads/",
+                                     &final_download_dir);
+  disk_directory_create(ectx, final_download_dir);
+  dname = &uris[strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX)];
+  idc_final_download_destination = MALLOC(strlen(final_download_dir) + 
strlen(dname) + 2);
+  strcpy(idc_final_download_destination, final_download_dir);
+  FREE(final_download_dir);
+  if (idc_final_download_destination[strlen(idc_final_download_destination)] 
!= DIR_SEPARATOR)
+    strcat(idc_final_download_destination, DIR_SEPARATOR_STR);
+  strcat(idc_final_download_destination, dname);
+
+  /* setup visualization */
+  list = MALLOC(sizeof(DownloadList));
+  list->next = download_head;
+  list->rr = NULL;
+  list->model = NULL;
+  list->uri = idc_uri;
+  list->filename = idc_final_download_destination;
+  list->finalName = STRDUP(idc_final_download_destination);
+  download_head = list;
+  size_h = string_get_fancy_byte_size(ECRS_fileSize(idc_uri));
+  gtk_tree_store_insert(download_summary,
+                        &iiter,
+                        NULL,
+                        0);
+  gtk_tree_store_set(download_summary,
+                     &iiter,
+                     DOWNLOAD_FILENAME, idc_final_download_destination,
+                     DOWNLOAD_SHORTNAME, uris,
+                     DOWNLOAD_SIZE, ECRS_fileSize(idc_uri),
+                     DOWNLOAD_HSIZE, size_h,
+                     DOWNLOAD_PROGRESS, 0, /* progress */
+                     DOWNLOAD_URISTRING, uris,
+                     DOWNLOAD_URI, ECRS_dupUri(idc_uri),
+                     DOWNLOAD_TREEPATH, NULL, /* internal: row reference! */
+                     DOWNLOAD_DIRPATH, "",                     
+                     -1);
+  FREE(size_h);
+  /* get anonymity level */
+  spin = glade_xml_get_widget(getMainXML(),
+                             "fsstatusAnonymitySpin");
+  if (spin == NULL) {
+    GE_BREAK(ectx, 0);
+    idc_anon = 1;
+  } else {
+    idc_anon = gtk_spin_button_get_value_as_int
+      (GTK_SPIN_BUTTON(spin));
+  }
+  addLogEntry(_("Downloading `%s'"), uris);
+  FSUI_startDownload(ctx,
+                    idc_anon,
+                    NO, /* FIXME: isRecursive */
+                    idc_uri,
+                    idc_final_download_destination);
+  FREE(urid);
 }
-#endif
 
 
-/**
- * Open a tab for the given search
- * (and display the results).
- */
-int openTabForSearch(struct FSUI_SearchList * slist,
-                    const struct ECRS_URI * uri,
-                    unsigned int anonymityLevel,
-                    unsigned int resultCount,
-                    const ECRS_FileInfo * results) {
-  SearchList * list;
-  char * description;
-  char * dhead;
-  GtkWidget * label;
-  GtkWidget * spin;
-  GtkWidget * notebook;
-  GtkTreeStore * model;
+void fs_download_update(struct DL * downloadContext,
+                       unsigned long long completed,
+                       const char * data,
+                       unsigned int size) {
   GtkTreeIter iter;
-  int i;
-  unsigned int *file_count;
-  GtkWidget *tab_label;
-  char * tab_title;
-  char * new_title;
+  unsigned int val;
+  unsigned long long total;
+  struct ECRS_URI * u;
+  struct ECRS_MetaData * meta;
 
   DEBUG_BEGIN();
-  description = ECRS_uriToString(uri);
-  if (description == NULL) {
-    GE_BREAK(ectx, 0);
-    return SYSERR;
+  if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(download_summary),
+                                    &iter)) {
+    do {
+      gtk_tree_model_get(GTK_TREE_MODEL(download_summary),
+                         &iter,
+                         DOWNLOAD_SIZE, &total,
+                         DOWNLOAD_URI, &u,
+                         -1);
+      if (u == NULL)
+        return;
+      if (ECRS_equalsUri(u, uri)) {
+        if (total != 0)
+          val = completed * 100 / total;
+        else
+          val = 100;
+        gtk_tree_store_set(download_summary,
+                           &iter,
+                           DOWNLOAD_PROGRESS, val,
+                           -1);
+        break;
+      }
+    } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(download_summary),
+                                      &iter));
   }
-  GE_ASSERT(ectx,
-           strlen(description) >= strlen(ECRS_URI_PREFIX));
-  dhead = &description[strlen(ECRS_URI_PREFIX)];
-  if (0 == strncmp(dhead,
-                  ECRS_SEARCH_INFIX,
-                  strlen(ECRS_SEARCH_INFIX)))
-    dhead = &dhead[strlen(ECRS_SEARCH_INFIX)];
-  else if (0 == strncmp(dhead,
-                       ECRS_SUBSPACE_INFIX,
-                       strlen(ECRS_SUBSPACE_INFIX)))
-    dhead = &dhead[strlen(ECRS_SUBSPACE_INFIX)];
+  meta = NULL;
+  ECRS_listDirectory(ectx,
+                    data,
+                     size,
+                     &meta,
+                     &addFilesToDirectory,
+                     (void*)uri);
+  if (meta != NULL)
+    ECRS_freeMetaData(meta);
+  DEBUG_END();
+}
 
-  gtk_list_store_append(summary,
-                       &iter);
-  gtk_list_store_set(summary,
-                    &iter,
-                    SER_SUM_NAME, dhead,
-                    SER_SUM_COUNT, resultCount,
-                    SER_SUM_URI, ECRS_dupUri(uri),
-                    -1);
+void fs_download_completed(struct DL * downloadContext) {
+  unsigned long long size;
+  char * data;
+  int fd;
+  struct ECRS_MetaData * meta;
+  DownloadList * pos;
 
-  list = MALLOC(sizeof(SearchList));
-  list->uri = ECRS_dupUri(uri);
-  list->next = head;
-  list->searchpage
-    = makeResultFrame(&list->treeview,
-                     &spin);
-  list->anonymityButton
-    = spin;
-  model = GTK_TREE_STORE
-    (gtk_tree_view_get_model
-     (GTK_TREE_VIEW(list->treeview)));
-  list->model
-    = GTK_TREE_MODEL(model);
-  notebook
-    = glade_xml_get_widget(getMainXML(),
-                          "downloadNotebook");
-  label = buildSearchTabLabel(list->searchpage, dhead);
-  FREE(description);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                          list->searchpage,
-                          label);
-  gtk_widget_show(notebook);
-  head = list;
-  for (i=0;i<resultCount;i++) {
-    addSearchResultToModel(&results[i],
-                          list->treeview,
-                          NULL);
+  DEBUG_BEGIN();
+  GE_LOG(ectx,
+        GE_STATUS | GE_USER | GE_BULK,
+        _("Download '%s' complete.\n"),
+        filename);
+  pos = download_head;
+  while (pos != NULL) {
+    if (ECRS_equalsUri(uri,
+                       pos->uri))
+      break;
+    pos = pos->next;
   }
+  
+  /* Not available for resumed downloads */
+  if (pos != NULL) {
+    if ( (pos->rr != NULL) &&
+         (gtk_tree_row_reference_valid(pos->rr)) ) { 
+      /* update directory view (if applicable!) */
+      if (OK == disk_file_size(ectx,
+                              filename,
+                              &size,
+                              YES)) {
+       GE_LOG(ectx,
+              GE_DEBUG,
+              "Updating directory view of '%s'\n",
+              filename);
 
- /* update tab title with the number of results */
-  file_count = (unsigned int *)
-      g_object_get_data(G_OBJECT(list->searchpage), "file_count");
-  (*file_count) = resultCount;
-  tab_label = (GtkWidget *)
-      g_object_get_data(G_OBJECT(list->searchpage), "label");
-  tab_title = (char *)
-      g_object_get_data(G_OBJECT(list->searchpage), "title");
-  new_title =
-      g_strdup_printf("%s%s%u%s", tab_title, " (", *file_count, ")");
-  gtk_label_set(GTK_LABEL(tab_label), new_title);
-  FREE(new_title);
+       meta = NULL;
+       fd = disk_file_open(ectx,
+                           filename, 
+                           O_RDONLY);
+       if (fd != -1) {
+         data = MMAP(NULL,
+                     size,
+                     PROT_READ,
+                     MAP_SHARED,
+                     fd,
+                     0);
+         if (data == MAP_FAILED) {
+           GE_LOG_STRERROR_FILE(ectx,
+                                GE_ERROR | GE_ADMIN | GE_BULK,
+                                "mmap",
+                                filename);
+         } else {
+           if (data != NULL) {
+             ECRS_listDirectory(ectx,
+                                data,
+                                size,
+                                &meta,
+                                &addFilesToDirectory,
+                                (void*)uri);
+             MUNMAP(data, size);
+           }
+         }
+         CLOSE(fd);
+       }
+       if (meta != NULL)
+         ECRS_freeMetaData(meta);      
+      }
+    }
+  }
+  DEBUG_END();
+}
 
+void fs_download_stopped(struct DL * downloadContext) {
+  GtkTreeIter iter;
+  char * f;
+  char * fn;
+  struct ECRS_URI * u;
+
+  DEBUG_BEGIN();
+  if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(download_summary),
+                                    &iter)) {
+    do {
+      gtk_tree_model_get(GTK_TREE_MODEL(download_summary),
+                         &iter,
+                         DOWNLOAD_FILENAME, &f,
+                         DOWNLOAD_URI, &u,
+                         -1);
+                         
+      f = strrchr(f, DIR_SEPARATOR);
+      fn = strrchr(filename, DIR_SEPARATOR);
+                         
+      if ( (ECRS_equalsUri(u, uri)) &&
+           (0 == strcmp(f, fn)) ) {
+        gtk_tree_store_remove(download_summary,
+                              &iter);
+        break;
+      }
+    } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(download_summary),
+                                      &iter));
+  }
   DEBUG_END();
   return OK;
 }
 
-void fs_search_start(struct GE_Context * e,
-                    struct GC_Configuration * c) {
-  GtkWidget * searchCB;
-  GtkWidget * searchList;
-  GtkListStore * model;
-  GtkCellRenderer * renderer;
-  GtkTreeViewColumn * column;
-  int col;
-  
-  ectx = e;
-  cfg = c;
-  DEBUG_BEGIN();
-  searchCB
-    = glade_xml_get_widget(getMainXML(),
-                          "fssearchKeywordComboBoxEntry");
+void on_clearCompletedDownloadsButton_clicked_fs(void * unused,
+                                                GtkWidget * clearButton) {
+  /* FIXME */
+}
 
-  model = gtk_list_store_new(NS_SEARCH_NUM,
-                            G_TYPE_STRING, /* what we show */
-                            G_TYPE_STRING, /* EncName of namespace */
-                            G_TYPE_POINTER, /* ECRS MetaData */
-                            G_TYPE_POINTER, /* FSUI search list */
-                            G_TYPE_INT);  /* Meta-data about namespace */
-  gtk_combo_box_set_model(GTK_COMBO_BOX(searchCB),
-                         GTK_TREE_MODEL(model));
-  gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(searchCB),
-                                     NS_SEARCH_DESCRIPTION);
-  searchList = glade_xml_get_widget(getMainXML(),
-                                   "activeSearchesSummary");
-  summary =
-    gtk_list_store_new(SER_SUM_NUM,
-                      G_TYPE_STRING, /* name */
-                      G_TYPE_INT,    /* # results */
-                      G_TYPE_POINTER,  /* internal: FSUI search list */
-                      G_TYPE_POINTER);  /* internal: uri */
-  gtk_tree_view_set_model(GTK_TREE_VIEW(searchList),
-                         GTK_TREE_MODEL(summary));
-  renderer = gtk_cell_renderer_text_new();
-  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(searchList),
-                                             -1,
-                                             _("Query"),
-                                             renderer,
-                                             "text", SER_SUM_NAME,
-                                             NULL);
-  column = gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
-                                   col - 1);
-  gtk_tree_view_column_set_resizable(column, TRUE);
-  gtk_tree_view_column_set_clickable(column, TRUE);
-  gtk_tree_view_column_set_reorderable(column, TRUE);
-  gtk_tree_view_column_set_sort_column_id(column, SER_SUM_NAME);
-  
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
-                                              col - 1),
-                                              TRUE);
-  renderer = gtk_cell_renderer_text_new();
-  col = gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(searchList),
-                                             -1,
-                                             _("Results"),
-                                             renderer,
-                                             "text", SER_SUM_COUNT,
-                                             NULL);
-  column = gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
-                                   col - 1);
-  gtk_tree_view_column_set_resizable(column, TRUE);
-  gtk_tree_view_column_set_clickable(column, TRUE);
-  gtk_tree_view_column_set_reorderable(column, TRUE);
-  gtk_tree_view_column_set_sort_column_id(column, SER_SUM_COUNT);
-  
gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(searchList),
-                                              col - 1),
-                                              TRUE);
-  DEBUG_END();
+static void abortDownloadCallback(GtkTreeModel * model,
+                                  GtkTreePath * path,
+                                  GtkTreeIter * iter,
+                                  GtkTreeStore * tree) {
+  struct DL * dl;
+
+  GE_ASSERT(ectx, model == GTK_TREE_MODEL(download_summary));
+  gtk_tree_model_get(model,
+                     iter,
+                     DOWNLOAD_POS, &dl,
+                     -1);
+  FSUI_abortDownload(ctx,
+                    dl->fsui_list);
 }
 
-void fs_search_stop() {
+void on_abortDownloadButton_clicked_fs(void * unused,
+                                      GtkWidget * clearButton) {
+  GtkTreeSelection * selection;
+  GtkWidget * downloadList;
+
+  DEBUG_BEGIN();
+  downloadList = glade_xml_get_widget(getMainXML(),
+                                      "activeDownloadsList");
+  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(downloadList));
+  gtk_tree_selection_selected_foreach
+    (selection,
+     &abortDownloadCallback,
+     NULL);
+  DEBUG_END();
 }
 
 
+struct DL *
+fs_download_started(struct FSUI_DownloadList * fsui_dl,
+                   unsigned long long total,
+                   unsigned int anonymityLevel,
+                   const struct ECRS_FileInfo * fi,
+                   const char * filename,
+                   unsigned long long completed,
+                   cron_t eta) {
+  GtkTreeIter iiter;
+  int progress;
+  char * uriname;
+  const char * sname;
+  char * size_h;
+  struct DL * list;
 
+  DEBUG_BEGIN();
+  if (filesize != 0)
+    progress = bytesCompleted * 100 / filesize;
+  else
+    progress = 100;
+  uriname = ECRS_uriToString(uri);
+  gtk_tree_store_insert(download_summary,
+                        &iiter,
+                        NULL,
+                        0);
+  sname = &filename[strlen(filename)-1];
+  while ( (sname > filename) &&
+         (sname[-1] != '/') &&
+         (sname[-1] != '\\') )
+    sname--;
+  size_h = string_get_fancy_byte_size(filesize);
+  gtk_tree_store_set(download_summary,
+                     &iiter,
+                     DOWNLOAD_FILENAME, filename,
+                     DOWNLOAD_SHORTNAME, sname,
+                     DOWNLOAD_SIZE, filesize,
+                     DOWNLOAD_HSIZE, size_h,
+                     DOWNLOAD_PROGRESS, progress,
+                     DOWNLOAD_URISTRING, uriname,
+                     DOWNLOAD_URI, ECRS_dupUri(uri),
+                     DOWNLOAD_TREEPATH, NULL,
+                    DOWNLOAD_POS, list,
+                     -1);
+  FREE(size_h);
+  FREE(uriname);
+  DEBUG_END();
+  return list;
+}
+
 /* end of search.c */

Modified: gnunet-gtk/src/plugins/fs/search.h
===================================================================
--- gnunet-gtk/src/plugins/fs/search.h  2006-10-24 23:12:20 UTC (rev 3552)
+++ gnunet-gtk/src/plugins/fs/search.h  2006-10-25 20:41:15 UTC (rev 3553)
@@ -30,24 +30,29 @@
 #include <GNUnet/gnunet_ecrs_lib.h>
 #include <GNUnet/gnunet_fsui_lib.h>
 
-void * fs_download_started(void * downloadContext,
-                          unsigned long long total,
-                          unsigned int anonymityLevel,
-                          const struct ECRS_URI * uri,
-                          const char * filename,
-                          unsigned long long completed,
-                          cron_t eta);
+struct SL;
 
-void fs_download_update(void * downloadContext,
+struct DL;
+
+struct DL *
+fs_download_started(struct FSUI_DownloadList * fsui_dl,
+                   unsigned long long total,
+                   unsigned int anonymityLevel,
+                   const struct ECRS_FileInfo * fi,
+                   const char * filename,
+                   unsigned long long completed,
+                   cron_t eta);
+
+void fs_download_update(struct DL * downloadContext,
                        unsigned long long completed,
                        const char * data,
                        unsigned int size);
 
-void fs_download_completed(void * downloadContext);
+void fs_download_completed(struct DL * downloadContext);
 
-void fs_download_aborted(void * downloadContext);
+void fs_download_aborted(struct DL * downloadContext);
 
-void fs_download_stopped(void * downloadContext);
+void fs_download_stopped(struct DL * downloadContext);
 
 
 /**
@@ -58,7 +63,7 @@
  * @param path the tree path that selects where to add
  *        the information, NULL for top-level
  */
-void fs_search_result_received(void * searchContext,
+void fs_search_result_received(struct SL * searchContext,
                               const ECRS_FileInfo * info,
                               const struct ECRS_URI * uri);
 
@@ -67,21 +72,22 @@
  *
  * @return internal search context
  */
-void * fs_search_started(struct FSUI_SearchList * list,
-                        const struct ECRS_URI * uri,
-                        unsigned int anonymityLevel,
-                        unsigned int resultCount,
-                        const ECRS_FileInfo * results);
+struct SL * 
+fs_search_started(struct FSUI_SearchList * list,
+                 const struct ECRS_URI * uri,
+                 unsigned int anonymityLevel,
+                 unsigned int resultCount,
+                 const ECRS_FileInfo * results);
 
 /**
  * A search process has been aborted.  Update display.
  */
-void fs_search_aborted(void * searchContext);
+void fs_search_aborted(struct SL * searchContext);
 
 /**
  * A search process has stopped.  Clean up.
  */
-void fs_search_stopped(void * searchContext);
+void fs_search_stopped(struct SL * searchContext);
 
 
 /**

Added: gnunet-gtk/src/plugins/fs/search_namespace.c
===================================================================
--- gnunet-gtk/src/plugins/fs/search_namespace.c        2006-10-24 23:12:20 UTC 
(rev 3552)
+++ gnunet-gtk/src/plugins/fs/search_namespace.c        2006-10-25 20:41:15 UTC 
(rev 3553)
@@ -0,0 +1,106 @@
+static int addNamespace(void * arg,
+                       const char * namespaceName,
+                       const HashCode512 * namespaceId,
+                       const struct ECRS_MetaData * md,
+                       int rating) {
+  GtkListStore * model = arg;
+  GtkTreeIter iter;
+  EncName enc;
+  char * name;
+  struct ECRS_MetaData * dmd;
+  char * desc;
+  size_t n;
+
+  DEBUG_BEGIN();
+  hash2enc(namespaceId,
+          &enc);
+  if (md == NULL) {
+    dmd = NULL;
+    desc = STRDUP("");
+  } else {
+    dmd = ECRS_dupMetaData(md);
+    desc = ECRS_getFirstFromMetaData(md,
+                                    EXTRACTOR_DESCRIPTION,
+                                    EXTRACTOR_TITLE,
+                                    EXTRACTOR_AUTHOR,
+                                    EXTRACTOR_GENRE,
+                                    EXTRACTOR_SUBJECT,
+                                    EXTRACTOR_CREATOR,
+                                    EXTRACTOR_PRODUCER,
+                                    EXTRACTOR_GROUP,
+                                    EXTRACTOR_CREATED_FOR,
+                                    EXTRACTOR_SUMMARY,
+                                    EXTRACTOR_OWNER,
+                                    -1);
+    if (desc == NULL)
+      desc = STRDUP("");
+  }
+
+  n = strlen(desc) + 64;
+  name = MALLOC(n);
+  SNPRINTF(name,
+          n,
+          "%s: %*.s",
+          desc,
+          20,
+          &enc);
+  gtk_list_store_append(model,
+                       &iter);
+  gtk_list_store_set(model,
+                    &iter,
+                    NS_SEARCH_DESCRIPTION, name,
+                    NS_SEARCH_ENCNAME, &enc,
+                    NS_SEARCH_METADATA, dmd,
+                    NS_SEARCH_RATING, rating,
+                    -1);
+  FREE(name);
+  DEBUG_END();
+  return OK;
+}
+
+#if 0
+/**
+ * cron job that periodically updates the model for the
+ * namespace selection in the search vbox.
+ */
+static void updateNCBModelSafe(void * unused) {
+  GtkWidget * searchNamespaceCB;
+  GtkListStore * model;
+  GtkTreeIter iter;
+
+  model = gtk_list_store_new(NS_SEARCH_NUM,
+                            G_TYPE_STRING, /* what we show */
+                            G_TYPE_STRING, /* EncName of namespace */
+                            G_TYPE_POINTER,
+                            G_TYPE_INT);  /* Meta-data about namespace */
+  gtk_list_store_append(model,
+                       &iter);
+  gtk_list_store_set(model,
+                    &iter,
+                    NS_SEARCH_DESCRIPTION, _("globally"),
+                    NS_SEARCH_ENCNAME, NULL,
+                    NS_SEARCH_METADATA, NULL,          
+                    NS_SEARCH_RATING, 0,
+                    -1);
+  NS_listNamespaces(ectx,
+                   cfg,
+                   NO,
+                   &addNamespace,
+                   model);
+  searchNamespaceCB
+    = glade_xml_get_widget(getMainXML(),
+                          "searchNamespaceComboBoxEntry");
+  gtk_combo_box_set_model(GTK_COMBO_BOX(searchNamespaceCB),
+                         GTK_TREE_MODEL(model));
+  if 
(gtk_combo_box_entry_get_text_column(GTK_COMBO_BOX_ENTRY(searchNamespaceCB)) == 
-1)
+    gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(searchNamespaceCB),
+                                       0);
+  if (-1 == gtk_combo_box_get_active(GTK_COMBO_BOX(searchNamespaceCB)))
+    gtk_combo_box_set_active(GTK_COMBO_BOX(searchNamespaceCB),
+                            0);
+}
+
+static void updateNCBModel(void * dummy) {
+  gtkSaveCall(&updateNCBModelSafe, NULL);
+}
+#endif





reply via email to

[Prev in Thread] Current Thread [Next in Thread]