gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r19152 - in gnunet-gtk: contrib src/fs


From: gnunet
Subject: [GNUnet-SVN] r19152 - in gnunet-gtk: contrib src/fs
Date: Sun, 15 Jan 2012 13:13:05 +0100

Author: grothoff
Date: 2012-01-15 13:13:05 +0100 (Sun, 15 Jan 2012)
New Revision: 19152

Modified:
   gnunet-gtk/contrib/Makefile.am
   gnunet-gtk/src/fs/gnunet-fs-gtk-main_window_file_publish.c
Log:
-LRN: use progress dialog and dirmetascanner

Modified: gnunet-gtk/contrib/Makefile.am
===================================================================
--- gnunet-gtk/contrib/Makefile.am      2012-01-15 11:59:08 UTC (rev 19151)
+++ gnunet-gtk/contrib/Makefile.am      2012-01-15 12:13:05 UTC (rev 19152)
@@ -27,6 +27,7 @@
   gnunet_fs_gtk_publish_tab.glade \
   gnunet_fs_gtk_search_tab.glade \
   gnunet_fs_gtk_select_pseudonym_dialog.glade \
+  gnunet_fs_gtk_progress_dialog.glade \
   gnunet_gtk_status_bar_menu.glade \
   gnunet_peerinfo_gtk_about_window.glade \
   gnunet_peerinfo_gtk_main_window.glade \

Modified: gnunet-gtk/src/fs/gnunet-fs-gtk-main_window_file_publish.c
===================================================================
--- gnunet-gtk/src/fs/gnunet-fs-gtk-main_window_file_publish.c  2012-01-15 
11:59:08 UTC (rev 19151)
+++ gnunet-gtk/src/fs/gnunet-fs-gtk-main_window_file_publish.c  2012-01-15 
12:13:05 UTC (rev 19152)
@@ -30,6 +30,8 @@
 
 #define MARKER_DIR_FILE_SIZE "-"
 
+struct AddDirClientContext;
+
 struct MainPublishingDialogContext
 {
   GtkBuilder *builder;
@@ -44,6 +46,7 @@
   GtkWidget *delete_button;
   GtkWidget *edit_button;
   GtkWidget *execute_button;
+  GtkWidget *cancel_button;
   GtkTreeView *file_info_treeview;
   GtkTreeSelection *file_info_selection;
   GtkTreeModel *file_info_treemodel;
@@ -51,10 +54,55 @@
 
   gulong open_directory_handler_id;
   GtkBuilder *open_directory_builder;
-  GtkBuilder *open_file_builder;
+
   gulong open_file_handler_id;
+  GtkBuilder *open_file_builder;
+
+  /* To keep multiple scanners running */
+  struct AddDirClientContext *adddir_head;
+  struct AddDirClientContext *adddir_tail;
 };
 
+/* One of these is kept for every directory being opened */
+struct AddDirClientContext
+{
+  struct AddDirClientContext *prev;
+  struct AddDirClientContext *next;
+
+  /**
+   * GNUNET_YES if the user asked to cancel the processing.
+   * If so, wrap up as fast as possible and close the progress dialog.
+   */
+  int cancelling;
+
+  /**
+   * GNUNET_YES if there was something during the scan that might
+   * need user's attention. Prevents the dialog from closing, unless
+   * the process was cancelled.
+   */
+  int keep;
+
+  struct ProcessMetadataContext *pmc;
+
+  struct MainPublishingDialogContext *ctx;
+  struct GNUNET_FS_DirScanner *ds;
+
+  struct ShareTreeItem *directory_scan_result;
+  struct ShareTreeItem *directory_scan_intermediary_result;
+
+  struct GNUNET_FS_BlockOptions directory_scan_bo;
+  int directory_scan_do_index;
+
+  GtkBuilder *progress_dialog_builder;
+  GtkWidget *progress_dialog;
+  GtkProgressBar *progress_dialog_bar;
+  GtkButton *progress_dialog_ok;
+  GtkButton *progress_dialog_cancel;
+  GtkTextView *progress_dialog_textview;
+  GtkTextBuffer *progress_dialog_textbuffer;
+  GtkTextMark *progress_dialog_textmark;
+};
+
 void
 GNUNET_GTK_publish_file_dialog_response_cb (GtkDialog * dialog,
                                             gint response_id,
@@ -87,6 +135,7 @@
   return (0 == ret) ? GNUNET_YES : GNUNET_NO;
 }
 
+/* Fill out the main publishing dialog context structure */
 static void
 init_ctx (struct MainPublishingDialogContext *ctx)
 {
@@ -107,6 +156,8 @@
       (ctx->builder, "GNUNET_GTK_master_publish_dialog_edit_button"));
   ctx->execute_button = GTK_WIDGET (gtk_builder_get_object
       (ctx->builder, "GNUNET_GTK_master_publish_dialog_execute_button"));
+  ctx->cancel_button = GTK_WIDGET (gtk_builder_get_object
+      (ctx->builder , "GNUNET_GTK_master_publish_dialog_cancel_button"));
   ctx->file_info_treeview = GTK_TREE_VIEW (gtk_builder_get_object
       (ctx->builder, 
"GNUNET_GTK_master_publish_dialog_file_information_tree_view"));
 
@@ -148,10 +199,18 @@
     else
       g_free (namespace_id);
   }
-  if ((gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter)) && 
(ns_ok == GNUNET_YES))
+  /* Don't let the user close the dialog until all scanners are finished and
+   * their windows are closed
+   */
+  if ((gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter))
+      && (ns_ok == GNUNET_YES) && ctx->adddir_head == NULL)
     gtk_widget_set_sensitive (ctx->execute_button, TRUE);
   else
     gtk_widget_set_sensitive (ctx->execute_button, FALSE);
+  if (ctx->adddir_head == NULL)
+    gtk_widget_set_sensitive (ctx->cancel_button, TRUE);
+  else
+    gtk_widget_set_sensitive (ctx->cancel_button, FALSE);
   if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, 
&iter))
   {
     gtk_widget_set_sensitive (ctx->up_button, FALSE);
@@ -239,6 +298,10 @@
   const char *ss;
   struct stat sbuf;
 
+  /* TODO: make directory scanner capable of scanning single files and use
+   * it instead
+   */
+
   if (0 != STAT (filename, &sbuf))
     return;
   if (S_ISDIR (sbuf.st_mode))
@@ -332,735 +395,12 @@
   update_selectivity (ctx);
 }
 
-
-/* ************ code for adding directories starts ************* */
-
-
-/**
- * Data we keep when calculating the publication details for a file.
- */
-struct PublishData
-{
-  /**
-   * Metadata for the file.
-   */
-  struct GNUNET_CONTAINER_MetaData *meta;
-
-  /**
-   * Keywords for the file (derived from metadata).
-   */
-  struct GNUNET_FS_Uri *ksk_uri;
-
-  /**
-   * Iterator for the entry.
-   */
-  GtkTreeIter iter;
-};
-
-
-/**
- * Entry for each unique keyword to track how often
- * it occured.  Contains the keyword and the counter.
- */
-struct KeywordCounter
-{
-
-  /**
-   * Keyword that was found.
-   */
-  const char *value;
-
-  /**
-   * How many files have meta entries matching this value?
-   * (type and format do not have to match).
-   */
-  unsigned int count;
-
-};
-
-
-/**
- * Execution context for 'add_dir'
- */
-struct AddDirContext
-{
-  /**
-   * While scanning, 'parent' is the iter entry for the
-   * parent, or NULL for top-level.
-   */
-  GtkTreeIter *parent;
-
-  /**
-   * Pointer to the context of the parent directory, or NULL
-   * for top-level.
-   */
-  struct AddDirContext *parent_ctx;
-
-  /**
-   * Directory iterator of the parent directory, or NULL
-   * for top-level.
-   */
-  struct GNUNET_DISK_DirectoryIterator *parent_iter;
-
-  /**
-   * Filename parent directory was processing (filename of THIS directory)
-   * when it started child directory iterator. NULL for top-level.
-   */
-  char *parent_filename;
-
-  /**
-   * Publication data for this directory.
-   */
-  struct PublishData *pd;
-
-  /**
-   * Master publication dialog context (used to access treestore)
-   */
-  struct MainPublishingDialogContext *ctx;
-
-  /**
-   * Map from the hash over the keyword to an 'struct KeywordCounter'
-   * counter that says how often this keyword was
-   * encountered in the current directory.
-   */
-  struct GNUNET_CONTAINER_MultiHashMap *keywordcounter;
-
-  /**
-   * Map from the hash of a filename in the current directory
-   * to the 'struct PublishData*' for the file.
-   */
-  struct GNUNET_CONTAINER_MultiHashMap *metamap;
-
-  /**
-   * Keywords to exclude from using for KSK since they'll be associated
-   * with the parent as well.  NULL for nothing blocked.
-   */
-  struct GNUNET_FS_Uri *exclude_ksk;
-
-  /**
-   * Block options to use.
-   */
-  struct GNUNET_FS_BlockOptions bo;
-
-  /**
-   * Index or insert?
-   */
-  int do_index;
-
-  /**
-   * Number of files in the current directory.
-   */
-  unsigned int dir_entry_count;
-};
-
-
-/**
- * Add the given keyword to the
- * keyword statistics tracker.
- *
- * @param cls closure (user-defined)
- * @param keyword the keyword to count
- * @param is_mandatory ignored
- * @return always GNUNET_OK
- */
-static int
-add_to_keyword_counter (void *cls, const char *keyword, int is_mandatory)
-{
-  struct GNUNET_CONTAINER_MultiHashMap *mcm = cls;
-  struct KeywordCounter *cnt;
-  GNUNET_HashCode hc;
-  size_t klen;
-
-  klen = strlen (keyword) + 1;
-  GNUNET_CRYPTO_hash (keyword, klen - 1, &hc);
-  cnt = GNUNET_CONTAINER_multihashmap_get (mcm, &hc);
-  if (cnt == NULL)
-  {
-    cnt = GNUNET_malloc (sizeof (struct KeywordCounter) + klen);
-    cnt->count = 1;
-    cnt->value = (const char *) &cnt[1];
-    memcpy (&cnt[1], keyword, klen);
-    GNUNET_CONTAINER_multihashmap_put (mcm, &hc, cnt,
-                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-  }
-  else
-  {
-    cnt->count++;
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Extract metadata from a file and add it to the metamap and
- * the keywordcounter.
- *
- * @param adc context to modify
- * @param filename name of the file to process
- */
 static void
-extract_file (struct AddDirContext *adc, const char *filename)
-{
-  struct PublishData *pd;
-  GNUNET_HashCode hc;
-  const char *short_fn;
-  const char *ss;
-
-  adc->dir_entry_count++;
-  pd = GNUNET_malloc (sizeof (struct PublishData));
-  pd->meta = GNUNET_CONTAINER_meta_data_create ();
-  GNUNET_FS_meta_data_extract_from_file (pd->meta, filename,
-                                         GNUNET_FS_GTK_get_le_plugins ());
-  GNUNET_CONTAINER_meta_data_delete (pd->meta, EXTRACTOR_METATYPE_FILENAME,
-                                     NULL, 0);
-  short_fn = filename;
-  while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR)))
-    short_fn = 1 + ss;
-  GNUNET_CONTAINER_meta_data_insert (pd->meta, "<gnunet-gtk>",
-                                     EXTRACTOR_METATYPE_FILENAME,
-                                     EXTRACTOR_METAFORMAT_UTF8, "text/plain",
-                                     short_fn, strlen (short_fn) + 1);
-
-  gtk_tree_store_insert_before (GTK_TREE_STORE 
(adc->ctx->file_info_treemodel), &pd->iter, adc->parent, NULL);
-
-  GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
-  GNUNET_CONTAINER_multihashmap_put (adc->metamap, &hc, pd,
-                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-  /* FIXME: what if this put fails? I think it actually can... Why unique 
only? */
-  pd->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (pd->meta);
-  GNUNET_FS_uri_ksk_get_keywords (pd->ksk_uri, &add_to_keyword_counter, 
adc->keywordcounter);
-}
-
-
-/**
- * Remove  the keyword from the ksk URI.
- *
- * @param cls the ksk uri
- * @param keyword the word to remove
- * @param is_mandatory ignored
- * @return always GNUNET_OK
- */
-static int
-remove_keyword (void *cls, const char *keyword, int is_mandatory)
-{
-  struct GNUNET_FS_Uri *ksk = cls;
-
-  GNUNET_FS_uri_ksk_remove_keyword (ksk, keyword);
-  return GNUNET_OK;
-}
-
-
-/**
- * Add the specifics of the given entry to the tree store.
- * Use keywords from ksk_uri, but exclude the ones given in
- * "md_no_ksk".
- *
- * @param ts tree store to modify
- * @param iter position in the tree store for this file
- * @param filename file to add
- * @param bo block options
- * @param do_index should we index or insert?
- * @param ksk_uri keywords to use. Will be destroyed at the end.
- * @param exclude_ksk keywords NOT to use. Won't be modified.
- * @param meta metadata for the file. Will be destroyed at the end.
- */
-static void
-add_entry_to_ts (GtkTreeStore * ts, GtkTreeIter * iter, const char *filename,
-                 const struct GNUNET_FS_BlockOptions *bo, int do_index,
-                 struct GNUNET_FS_Uri *ksk_uri, struct GNUNET_FS_Uri 
*exclude_ksk,
-                 struct GNUNET_CONTAINER_MetaData *meta)
-{
-  char *file_size_fancy;
-  struct GNUNET_FS_FileInformation *fi;
-  GtkTreeRowReference *row_reference;
-  GtkTreePath *path;
-  uint64_t file_size;
-  const char *ss;
-  const char *short_fn;
-  struct stat sbuf;
-
-  if (0 != STAT (filename, &sbuf))
-    return;
-  if (S_ISDIR (sbuf.st_mode))
-  {
-    file_size = 0;
-  }
-  else
-  {
-    if (GNUNET_OK != GNUNET_DISK_file_size (filename, &file_size, GNUNET_YES))
-    {
-      GNUNET_break (0);
-      return;
-    }
-  }
-  if (exclude_ksk != NULL)
-  {
-    GNUNET_FS_uri_ksk_get_keywords (exclude_ksk, &remove_keyword, ksk_uri);
-  }
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), iter);
-  row_reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), path);
-  gtk_tree_path_free (path);
-  if (S_ISDIR (sbuf.st_mode))
-  {
-    GNUNET_CONTAINER_meta_data_delete (meta, EXTRACTOR_METATYPE_MIMETYPE, NULL,
-                                       0);
-    GNUNET_FS_meta_data_make_directory (meta);
-    GNUNET_FS_uri_ksk_add_keyword (ksk_uri, GNUNET_FS_DIRECTORY_MIME,
-                                   GNUNET_NO);
-    fi = GNUNET_FS_file_information_create_empty_directory
-        (GNUNET_FS_GTK_get_fs_handle (), row_reference, ksk_uri, meta, bo, 
filename);
-  }
-  else
-  {
-    fi = GNUNET_FS_file_information_create_from_file
-        (GNUNET_FS_GTK_get_fs_handle (), row_reference, filename, ksk_uri, 
meta,
-         do_index, bo);
-  }
-  GNUNET_CONTAINER_meta_data_destroy (meta);
-  GNUNET_FS_uri_destroy (ksk_uri);
-  if (S_ISDIR (sbuf.st_mode))
-    file_size_fancy = GNUNET_strdup (MARKER_DIR_FILE_SIZE);
-  else
-    file_size_fancy = GNUNET_STRINGS_byte_size_fancy (file_size);
-  short_fn = filename;
-  while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR)))
-    short_fn = 1 + ss;
-  gtk_tree_store_set (ts, iter, 0, file_size_fancy, 1, (gboolean) do_index, 2,
-                      short_fn, 3, (guint) bo->anonymity_level, 4,
-                      (guint) bo->content_priority, 5, fi, 
-                     6, (guint64) bo->expiration_time.abs_value,
-                     7, (guint) bo->replication_level, -1);
-  GNUNET_free (file_size_fancy);
-}
-
-
-#if DEAD_CODE
-/**
- * Function called by the directory iterator to
- * (recursively) add all of the files in the
- * directory to the tree.
- *
- * @param cls the 'struct AddDirContext*' we're in
- * @param filename file or directory to scan
- */
-static int
-publish_entry (void *cls, const char *filename)
-{
-  struct AddDirContext *adc = cls;
-  struct PublishData *pd;
-  GNUNET_HashCode hc;
-
-  GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
-  pd = GNUNET_CONTAINER_multihashmap_get (adc->metamap, &hc);
-  add_entry_to_ts (GTK_TREE_STORE (adc->ctx->file_info_treemodel), &pd->iter, 
filename, &adc->bo, adc->do_index,
-                   pd->ksk_uri, adc->exclude_ksk, pd->meta);
-  GNUNET_CONTAINER_multihashmap_remove (adc->metamap, &hc, pd);
-  GNUNET_free (pd);
-  return GNUNET_OK;
-}
-#endif
-
-
-/**
- * Context passed to 'migrate_and_drop'.
- */
-struct KeywordProcessContext
-{
-  /**
-   * All the keywords we migrated to the parent.
-   */
-  struct GNUNET_FS_Uri *ksk;
-
-  /**
-   * How often does a keyword have to occur to be
-   * migrated to the parent?
-   */
-  unsigned int threshold;
-};
-
-
-/**
- * Copy "frequent" keywords over to the
- * target ksk uri, free the counters.
- *
- */
-static int
-migrate_and_drop (void *cls, const GNUNET_HashCode * key, void *value)
-{
-  struct KeywordProcessContext *kpc = cls;
-  struct KeywordCounter *counter = value;
-
-  if (counter->count >= kpc->threshold && counter->count > 1)
-  {
-    GNUNET_FS_uri_ksk_add_keyword (kpc->ksk, counter->value, GNUNET_NO);
-  }
-  GNUNET_free (counter);
-  return GNUNET_YES;
-}
-
-
-/**
- * Go over the collected keywords from all entries in the
- * directory and push common keywords up one level (by
- * adding it to the returned struct).
- *
- * @param adc collection of child meta data
- * @return meta data to moved to parent
- */
-static struct GNUNET_FS_Uri *
-process_keywords (struct AddDirContext *adc)
-{
-  struct KeywordProcessContext kpc;
-  struct GNUNET_CONTAINER_MetaData *tmp;
-
-  tmp = GNUNET_CONTAINER_meta_data_create ();
-
-  /* Surprisingly, it's impossible to create a ksk with 0 keywords directly.
-   * But we can create one from an empty metadata set
-   */
-  kpc.ksk = GNUNET_FS_uri_ksk_create_from_meta_data (tmp);
-  GNUNET_CONTAINER_meta_data_destroy (tmp);
-  kpc.threshold = (adc->dir_entry_count + 1) / 2;       /* 50% */
-  GNUNET_CONTAINER_multihashmap_iterate (adc->keywordcounter, 
&migrate_and_drop,
-                                         &kpc);
-  GNUNET_CONTAINER_multihashmap_destroy (adc->keywordcounter);
-  return kpc.ksk;
-}
-
-
-#if DEAD_CODE
-/**
- * Function called by the directory iterator to
- * (recursively) add all of the files in the
- * directory to the tree.
- *
- * @param cls the 'struct AddDirContext*' we're in
- * @param filename file or directory to scan
- */
-static int
-scan_directory (void *cls, const char *filename)
-{
-  struct AddDirContext *adc = cls;
-  struct stat sbuf;
-  GtkTreeIter *parent;
-  struct PublishData *pd;
-  GNUNET_HashCode hc;
-  struct GNUNET_CONTAINER_MultiHashMap *mhm;
-  struct GNUNET_CONTAINER_MultiHashMap *kcm;
-  unsigned int pc;
-  const char *ss;
-  const char *short_fn;
-  const char *user;
-
-  if (0 != STAT (filename, &sbuf))
-    return GNUNET_OK;
-  if (S_ISDIR (sbuf.st_mode))
-  {
-    parent = adc->parent;
-    mhm = adc->metamap;
-    kcm = adc->keywordcounter;
-    pc = adc->dir_entry_count;
-    adc->metamap = GNUNET_CONTAINER_multihashmap_create (1024);
-    adc->keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024);
-    adc->dir_entry_count = 0;
-    pd = GNUNET_malloc (sizeof (struct PublishData));
-    gtk_tree_store_insert_before (GTK_TREE_STORE 
(adc->ctx->file_info_treemodel), &pd->iter, parent, NULL);
-    adc->parent = &pd->iter;
-    GNUNET_DISK_directory_scan (filename, &scan_directory, adc);
-    pd->ksk_uri = process_keywords (adc);
-    pd->meta = GNUNET_CONTAINER_meta_data_create ();
-    adc->exclude_ksk = GNUNET_FS_uri_dup (pd->ksk_uri);
-    GNUNET_DISK_directory_scan (filename, &publish_entry, adc);
-    GNUNET_CONTAINER_multihashmap_destroy (adc->metamap);
-    adc->metamap = mhm;
-    adc->keywordcounter = kcm;
-    adc->parent = parent;
-    adc->dir_entry_count = pc + 1;
-    short_fn = filename;
-    while ( (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR))) && 
-           (ss[1] != '\0') )
-      short_fn = 1 + ss;
-    user = getenv ("USER");
-    if ( (user == NULL) ||
-        (0 != strncasecmp (user,
-                           short_fn,
-                           strlen(user))) )
-    {
-      /* only use filename if it doesn't match $USER */
-      GNUNET_CONTAINER_meta_data_insert (pd->meta, "<gnunet-gtk>",
-                                        EXTRACTOR_METATYPE_FILENAME,
-                                        EXTRACTOR_METAFORMAT_UTF8,
-                                        "text/plain", short_fn,
-                                        strlen (short_fn) + 1);
-      GNUNET_CONTAINER_meta_data_insert (pd->meta, "<gnunet-gtk>",
-                                        
EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
-                                        EXTRACTOR_METAFORMAT_UTF8,
-                                        "text/plain", short_fn,
-                                        strlen (short_fn) + 1);
-    }
-    if (adc->metamap != NULL)
-    {
-      GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
-      GNUNET_CONTAINER_multihashmap_put (adc->metamap, &hc, pd,
-                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-      /* FIXME: what if this put fails? I think it actually can... Why unique 
only? */
-      GNUNET_FS_uri_ksk_get_keywords (pd->ksk_uri, &add_to_keyword_counter, 
kcm);
-    }
-    else
-    {
-      GNUNET_assert (kcm == NULL);
-      add_entry_to_ts (GTK_TREE_STORE (adc->ctx->file_info_treemodel), 
&pd->iter, filename, &adc->bo, adc->do_index,
-                       pd->ksk_uri, NULL, pd->meta);
-    }
-    GNUNET_FS_uri_destroy (adc->exclude_ksk);
-  }
-  else
-  {
-    GNUNET_assert (adc->metamap != NULL);
-    extract_file (adc, filename);
-  }
-  return GNUNET_OK;
-}
-#endif
-
-
-static void
-add_dir_callback (void *cls, struct GNUNET_DISK_DirectoryIterator * di,
-    const char *filename, const char *dirname);
-
-
-static void
-child_dir_finished_publishing (struct AddDirContext *adc)
-{
-  const char *ss;
-  const char *short_fn;
-  const char *user;
-  GNUNET_HashCode hc;
-
-  GNUNET_CONTAINER_multihashmap_destroy (adc->metamap);
-  if (adc->parent_ctx)
-    adc->parent_ctx->dir_entry_count += 1;
-  short_fn = adc->parent_filename;
-  while ( (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR))) && 
-   (ss[1] != '\0') )
-      short_fn = 1 + ss;
-  user = getenv ("USER");
-  if ((user == NULL) || (0 != strncasecmp (user, short_fn, strlen(user))))
-  {
-    /* only use filename if it doesn't match $USER */
-    GNUNET_CONTAINER_meta_data_insert (adc->pd->meta, "<gnunet-gtk>",
-        EXTRACTOR_METATYPE_FILENAME,
-        EXTRACTOR_METAFORMAT_UTF8,
-        "text/plain", short_fn,
-        strlen (short_fn) + 1);
-    GNUNET_CONTAINER_meta_data_insert (adc->pd->meta, "<gnunet-gtk>",
-        EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
-        EXTRACTOR_METAFORMAT_UTF8,
-        "text/plain", short_fn,
-        strlen (short_fn) + 1);
-  }
-  if (adc->parent_ctx != NULL)
-  {
-    if (adc->parent_ctx->metamap != NULL)
-    {
-      GNUNET_CRYPTO_hash (adc->parent_filename, strlen (adc->parent_filename), 
&hc);
-      GNUNET_CONTAINER_multihashmap_put (adc->parent_ctx->metamap, &hc, 
adc->pd,
-                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-      /* FIXME: what if this put fails? I think it actually can... Why unique 
only? */
-      GNUNET_FS_uri_ksk_get_keywords (adc->pd->ksk_uri, 
&add_to_keyword_counter, adc->parent_ctx->keywordcounter);
-    }
-    else
-    {
-      GNUNET_assert (adc->parent_ctx->keywordcounter == NULL);
-      add_entry_to_ts (GTK_TREE_STORE (adc->ctx->file_info_treemodel),
-          &adc->pd->iter, adc->parent_filename, &adc->bo, adc->do_index,
-          adc->pd->ksk_uri, NULL, adc->pd->meta);
-    }
-  }
-  GNUNET_FS_uri_destroy (adc->exclude_ksk);
-  if (adc->parent_ctx != NULL)
-    add_dir_callback (adc->parent_ctx, adc->parent_iter,
-      adc->parent_filename, NULL);
-  GNUNET_free_non_null (adc->parent_filename);
-  GNUNET_free (adc);
-}
-
-static void
-publish_dir_callback (void *cls, struct GNUNET_DISK_DirectoryIterator *di,
-    const char *filename, const char *dirname)
-{
-  struct AddDirContext *adc = cls;
-  struct PublishData *pd;
-  GNUNET_HashCode hc;
-  struct stat sbuf;
-
-  GNUNET_CRYPTO_hash (filename, strlen (filename), &hc);
-  pd = GNUNET_CONTAINER_multihashmap_get (adc->metamap, &hc);
-  /* stat() is needed here to match the stat() call add_dir_callback() does */
-  if ((pd != NULL) && (0 == STAT (filename, &sbuf)))
-  {
-    add_entry_to_ts (GTK_TREE_STORE (adc->ctx->file_info_treemodel),
-        &pd->iter, filename, &adc->bo, adc->do_index,
-        pd->ksk_uri, adc->exclude_ksk, pd->meta);
-  }
-  if (pd != NULL)
-  {
-    GNUNET_CONTAINER_multihashmap_remove (adc->metamap, &hc, pd);
-    GNUNET_free (pd);
-  }
-  if (GNUNET_DISK_directory_iterator_next (di, GNUNET_NO) != GNUNET_YES)
-  {
-    child_dir_finished_publishing (adc);
-  }
-}
-
-static void
-child_dir_finished_scanning (struct AddDirContext *adc)
-{
-  adc->pd->ksk_uri = process_keywords (adc);
-  adc->pd->meta = GNUNET_CONTAINER_meta_data_create ();
-  adc->exclude_ksk = GNUNET_FS_uri_dup (adc->pd->ksk_uri);
-  if (GNUNET_YES != GNUNET_DISK_directory_iterator_start 
(GNUNET_SCHEDULER_PRIORITY_IDLE,
-      adc->parent_filename, &publish_dir_callback, adc))
-    child_dir_finished_publishing (adc);
-}
-
-/**
- * Function called by directory iterator.
- *
- * @param cls closure
- * @param di argument to pass to "GNUNET_DISK_directory_iterator_next" to
- *           get called on the next entry (or finish cleanly);
- *           NULL on error (will be the last call in that case)
- * @param filename complete filename (absolute path)
- * @param dirname directory name (absolute path)
- */
-static void
-add_dir_callback (void *cls, struct GNUNET_DISK_DirectoryIterator * di,
-    const char *filename, const char *dirname)
-{
-  struct AddDirContext *adc = cls, *child_adc;
-  struct stat sbuf;
-  int will_continue;
-
-  /* dirname == NULL is a special case when add_dir_callback() is called by
-   * the child directory iterator callback.
-   */
-  if (dirname == NULL)
-  {
-    if (di == NULL)
-    {
-      /* This is the top-level entry, hook the treemodel back */
-      gtk_tree_view_set_model (adc->ctx->file_info_treeview, 
adc->ctx->file_info_treemodel);
-      return;
-    }
-    else
-      will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
-  }
-  else if (0 != STAT (filename, &sbuf))
-  {
-    GNUNET_assert (di != NULL);
-    will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
-  }
-  else
-  {
-    if (!S_ISDIR (sbuf.st_mode))
-    {
-      GNUNET_assert (adc->metamap != NULL);
-      extract_file (adc, filename);
-      will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
-    }
-    else
-    {
-      child_adc = GNUNET_malloc (sizeof (struct AddDirContext));
-      will_continue = GNUNET_DISK_directory_iterator_start 
(GNUNET_SCHEDULER_PRIORITY_IDLE,
-          filename, &add_dir_callback, child_adc);
-      if (will_continue != GNUNET_YES)
-      {
-        /* Ignore empty directories for now */
-        GNUNET_free (child_adc);
-        will_continue = GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
-      }
-      else
-      {
-        child_adc->metamap = GNUNET_CONTAINER_multihashmap_create (1024);
-        child_adc->keywordcounter = GNUNET_CONTAINER_multihashmap_create 
(1024);
-        child_adc->dir_entry_count = 0;
-        child_adc->parent_ctx = adc;
-        child_adc->parent_iter = di;
-        child_adc->bo = adc->bo;
-        child_adc->do_index = adc->do_index;
-        child_adc->ctx = adc->ctx;
-        child_adc->pd = GNUNET_malloc (sizeof (struct PublishData));
-        child_adc->parent_filename = GNUNET_strdup (filename);
-        gtk_tree_store_insert_before (GTK_TREE_STORE 
(adc->ctx->file_info_treemodel),
-            &child_adc->pd->iter, adc->parent, NULL);
-        child_adc->parent = &child_adc->pd->iter;
-        /* Don't advance directory iterator here, child iterator will call
-         * us with dirname == NULL for that later.
-         */
-      }
-    }
-  }
-  if (will_continue != GNUNET_YES)
-  {
-    child_dir_finished_scanning (adc);
-  }
-  return;
-}
-
-
-/**
- * Add a directory to the tree model.
- *
- * @param filename directory name to add
- * @param bo block options
- * @param do_index should we index?
- */
-static void
-add_dir (struct MainPublishingDialogContext *ctx, const char *filename,
-         const struct GNUNET_FS_BlockOptions *bo, int do_index)
-{
-  struct stat sbuf;
-  struct AddDirContext *scan_ctx;
-  char *filename_expanded;
-
-  if (0 != STAT (filename, &sbuf))
-    return;
-  if (!S_ISDIR (sbuf.st_mode))
-  {
-    GNUNET_break (0);
-    return;
-  }
-  filename_expanded = GNUNET_STRINGS_filename_expand (filename);
-  if (filename_expanded == NULL)
-    return;
-  scan_ctx = GNUNET_malloc (sizeof (struct AddDirContext));
-  scan_ctx->bo = *bo;
-  scan_ctx->do_index = do_index;
-  scan_ctx->ctx = ctx;
-
-  /* Disconnect treestore from the treeview to prevent GTK from trying
-   * to update it on the fly.
-   */
-  gtk_tree_view_set_model (ctx->file_info_treeview, NULL);
-
-  /* just make sure that dirname is not NULL, it's not really used */
-  add_dir_callback (scan_ctx, NULL, filename_expanded, filename_expanded);
-  GNUNET_free (filename_expanded);
-}
-
-
-/* ************ code for adding directories ends here ************* */
-
-
-static void
 selection_changed_cb (GtkTreeSelection * ts, struct 
MainPublishingDialogContext *ctx)
 {
   update_selectivity (ctx);
 }
 
-
 static void
 remove_old_entry (GtkTreeStore * ts, GtkTreeIter * root)
 {
@@ -1348,6 +688,7 @@
    * anonymity, priority and expiration prior
    * to calling this function (currently we
    * use default values for those).
+   * Or getting these values from the configuration.
    */
   bo.anonymity_level = 1;
   bo.content_priority = 1000;
@@ -1377,6 +718,17 @@
   ad = GTK_WIDGET (gtk_builder_get_object
                    (ctx->open_file_builder, "GNUNET_GTK_publish_file_dialog"));
 
+  /* FIXME: Use some kind of adjustable defaults instead of 1000, 0 and TRUE */
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (
+      ctx->open_file_builder,
+      "GNUNET_GTK_publish_file_dialog_priority_spin_button")), 1000);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (
+      ctx->open_file_builder,
+      "GNUNET_GTK_publish_file_dialog_replication_spin_button")), 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (
+      ctx->open_file_builder,
+      "GNUNET_GTK_publish_file_dialog_do_index_checkbutton")), TRUE);
+
   ctx->open_file_handler_id = g_signal_connect (G_OBJECT (ad), "response", 
G_CALLBACK (GNUNET_GTK_publish_file_dialog_response_cb), ctx);
 
   anon_treemodel = GTK_TREE_MODEL (gtk_builder_get_object 
(ctx->main_window_builder,
@@ -1518,8 +870,339 @@
   update_selectivity (ctx);
 }
 
+static void
+insert_progress_dialog_text (struct AddDirClientContext *adcc,
+   char *text)
+{
+  GtkTextIter iter;
+  
+  gtk_text_buffer_get_iter_at_mark (adcc->progress_dialog_textbuffer,
+      &iter, adcc->progress_dialog_textmark);
+  gtk_text_buffer_insert (adcc->progress_dialog_textbuffer,
+      &iter, text, -1);
+  gtk_text_view_scroll_to_mark (adcc->progress_dialog_textview,
+      adcc->progress_dialog_textmark,
+      0.0, FALSE, 1.0, 1.0);
 
+}
+
+/**
+ * Does the same freeing and destorying "add_item" does,
+ * without doing anything else
+ */
 void
+discard_item (struct ShareTreeItem *item)
+{
+  GNUNET_CONTAINER_meta_data_destroy (item->meta);
+  GNUNET_FS_uri_destroy (item->ksk_uri);
+  GNUNET_free (item->short_filename);
+  GNUNET_free (item->filename);
+}
+
+void
+add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts,
+  struct ShareTreeItem *item, GtkTreeIter *parent, GtkTreeIter *sibling,
+  GtkTreeIter *item_iter)
+{
+  char *file_size_fancy;
+  struct GNUNET_FS_FileInformation *fi;
+  GtkTreeRowReference *row_reference;
+  GtkTreePath *path;
+
+  gtk_tree_store_insert_after (ts, item_iter, parent, sibling);
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), item_iter);
+  row_reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), path);
+  gtk_tree_path_free (path);
+
+  if (item->is_directory)
+  {
+    GNUNET_CONTAINER_meta_data_delete (item->meta,
+        EXTRACTOR_METATYPE_MIMETYPE, NULL, 0);
+    GNUNET_FS_meta_data_make_directory (item->meta);
+    GNUNET_FS_uri_ksk_add_keyword (item->ksk_uri, GNUNET_FS_DIRECTORY_MIME,
+        GNUNET_NO);
+    fi = GNUNET_FS_file_information_create_empty_directory (
+        GNUNET_FS_GTK_get_fs_handle (), row_reference, item->ksk_uri,
+        item->meta, &adcc->directory_scan_bo, item->filename);
+  }
+  else
+  {
+    fi = GNUNET_FS_file_information_create_from_file (
+        GNUNET_FS_GTK_get_fs_handle (), row_reference, item->filename,
+        item->ksk_uri, item->meta, adcc->directory_scan_do_index,
+        &adcc->directory_scan_bo);
+  }
+  GNUNET_CONTAINER_meta_data_destroy (item->meta);
+  GNUNET_FS_uri_destroy (item->ksk_uri);
+  if (item->is_directory)
+    file_size_fancy = GNUNET_strdup (MARKER_DIR_FILE_SIZE);
+  else
+    file_size_fancy = GNUNET_STRINGS_byte_size_fancy (item->file_size);
+  gtk_tree_store_set (ts, item_iter, 0, file_size_fancy,
+      1, (gboolean) adcc->directory_scan_do_index,
+      2, item->short_filename,
+      3, (guint) adcc->directory_scan_bo.anonymity_level,
+      4, (guint) adcc->directory_scan_bo.content_priority,
+      5, fi,
+      6, (guint64) adcc->directory_scan_bo.expiration_time.abs_value,
+      7, (guint) adcc->directory_scan_bo.replication_level, -1);
+  GNUNET_free (file_size_fancy);
+  GNUNET_free (item->short_filename);
+  GNUNET_free (item->filename);
+}
+
+/* Used to avoid recursion */
+struct AddShareItemsStack
+{
+  struct AddShareItemsStack *parent;
+  GtkTreeIter last_added;
+};
+
+/**
+ * Traverse the share tree and add it to the tree store
+ * Set "discard" to GNUNET_YES to force the tree to be destroyed
+ * without processing (it is destroyed either way).
+ */
+void
+add_share_items_to_treestore (struct AddDirClientContext *adcc,
+    struct ShareTreeItem *toplevel, int discard)
+{
+  struct MainPublishingDialogContext *ctx = adcc->ctx;
+  GtkTreeStore *ts = GTK_TREE_STORE (ctx->file_info_treemodel);
+  GtkTreeIter *parent_iter;
+  GtkTreeIter *sibling_iter;
+  struct ShareTreeItem *item, *next;
+  struct AddShareItemsStack *stack;
+
+  if (!discard)
+  {
+    stack = GNUNET_malloc (sizeof (struct AddShareItemsStack));
+    parent_iter = NULL;
+    sibling_iter = NULL;
+  }
+  for (item = toplevel; item != NULL; item = next)
+  {
+    if (!discard)
+    {
+      add_item (adcc, ts, item, parent_iter, sibling_iter, &stack->last_added);
+      sibling_iter = &stack->last_added;
+    }
+    else
+      discard_item (item);
+    if (item->is_directory)
+    {
+      if (item->children_head != NULL)
+      {
+        if (!discard)
+        {
+          struct AddShareItemsStack *child = GNUNET_malloc (sizeof (struct 
AddShareItemsStack));
+          child->parent = stack;
+          sibling_iter = NULL;
+          parent_iter = &stack->last_added;
+          stack = child;
+        }
+        next = item->children_head;
+        continue;
+      }
+    }
+    while ((next = item->next) == NULL)
+    {
+      if (item->parent != NULL)
+      {
+        next = item->parent;
+        if (!discard)
+        {
+          struct AddShareItemsStack *child;
+          sibling_iter = &stack->parent->last_added;
+          parent_iter = stack->parent->parent != NULL ? 
&stack->parent->parent->last_added : NULL;
+          child = stack;
+          stack = stack->parent;
+          GNUNET_free (child);
+        }
+        GNUNET_free (item);
+        item = next;
+      }
+      else
+        break;
+    }
+    GNUNET_free (item);
+  }
+  if (!discard)
+    GNUNET_free (stack);
+}
+
+static void
+close_scan (struct AddDirClientContext *adcc)
+{
+  gtk_widget_destroy (adcc->progress_dialog);
+  g_object_unref (G_OBJECT (adcc->progress_dialog_builder));  
+  GNUNET_CONTAINER_DLL_remove (adcc->ctx->adddir_head,
+      adcc->ctx->adddir_tail, adcc);
+  update_selectivity (adcc->ctx);
+  GNUNET_free (adcc);
+}
+
+static void
+complete_scan (struct AddDirClientContext *adcc)
+{
+  /* Pressing OK shouldn't work until we have the results */
+  if (adcc->directory_scan_result != NULL)
+  {
+    add_share_items_to_treestore (adcc, adcc->directory_scan_result,
+        adcc->cancelling ? GNUNET_YES : GNUNET_NO);
+    adcc->directory_scan_result = NULL;
+    update_selectivity (adcc->ctx);
+    close_scan (adcc);
+  }
+}
+
+static int
+cancel_scan (struct AddDirClientContext *adcc)
+{
+  int result = GNUNET_YES;
+  /* User wants to cancel */
+  adcc->cancelling = GNUNET_YES;
+  if (adcc->ds != NULL)
+  {
+    /* Still scanning - signal the scanner to finish */
+    GNUNET_FS_directory_scan_finish (adcc->ds, GNUNET_NO);
+    result = GNUNET_NO;
+  }
+  if (adcc->directory_scan_result != NULL)
+  {
+    /* Not scanning anymore - discard the results of the scan and close */
+    add_share_items_to_treestore (adcc, adcc->directory_scan_result, 
GNUNET_YES);
+    adcc->directory_scan_result = NULL;
+    close_scan (adcc);
+    result = GNUNET_YES;
+  }
+  return result;
+}
+
+void
+GNUNET_FS_GTK_progress_dialog_ok_button_clicked_cb (GtkButton *button,
+    struct AddDirClientContext *adcc)
+{
+  complete_scan (adcc);
+}
+
+void
+GNUNET_FS_GTK_progress_dialog_cancel_button_clicked_cb (GtkButton *button,
+    struct AddDirClientContext *adcc)
+{
+  cancel_scan (adcc);
+}
+
+gboolean
+GNUNET_FS_GTK_progress_dialog_delete_event_cb (GtkWidget *widget,
+    GdkEvent * event, struct AddDirClientContext *adcc)
+{
+  /* Don't allow GTK to kill the window, until the scan is finished */
+  return cancel_scan (adcc) == GNUNET_NO;
+}
+
+static void
+directory_trim_complete (void *cls,
+    const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct AddDirClientContext *adcc = cls;
+  adcc->directory_scan_result = adcc->directory_scan_intermediary_result;
+  if (adcc->cancelling)
+  {
+    cancel_scan (adcc);
+  }
+  else
+  {
+    gtk_widget_set_sensitive (GTK_WIDGET (adcc->progress_dialog_ok), TRUE);
+    gtk_widget_set_visible (GTK_WIDGET (adcc->progress_dialog_bar), FALSE);
+    if (!adcc->keep)
+      complete_scan (adcc);
+  }
+}
+
+static int
+directory_scan_cb (void *cls, struct GNUNET_FS_DirScanner *ds,
+    const char *filename, char is_directory,
+    enum GNUNET_DirScannerProgressUpdateReason reason)
+{
+  struct AddDirClientContext *adcc = cls;
+  char *s;
+  gtk_progress_bar_pulse (adcc->progress_dialog_bar);
+  switch (reason)
+  {
+    case GNUNET_DIR_SCANNER_NEW_FILE:
+      if (filename != NULL)
+      {
+        if (is_directory)
+          GNUNET_asprintf (&s, _("Scanning directory `%s'.\n"), filename);
+        else
+          GNUNET_asprintf (&s, _("Scanning file `%s'.\n"), filename);
+        insert_progress_dialog_text (adcc, s);
+        GNUNET_free (s);
+      }
+      break;
+    case GNUNET_DIR_SCANNER_DOES_NOT_EXIST:
+      if (filename != NULL)
+      {
+        GNUNET_asprintf (&s,
+            _("Failed to scan `%s', because it does not exist.\n"),
+            filename);
+        adcc->keep = 1;
+        insert_progress_dialog_text (adcc, s);
+        GNUNET_free (s);
+      }
+      break;
+    case GNUNET_DIR_SCANNER_ASKED_TO_STOP:
+      if (filename != NULL)
+      {
+        GNUNET_asprintf (&s,
+            _("Scanner was about to scan `%s', but is now stopping.\n"),
+            filename);
+        insert_progress_dialog_text (adcc, s);
+        GNUNET_free (s);
+      }
+      else
+        insert_progress_dialog_text (adcc, _("Scanner is stopping.\n"));
+      break;
+    case GNUNET_DIR_SCANNER_SHUTDOWN:
+      insert_progress_dialog_text (adcc, _("Client is shutting down.\n"));
+      break;
+    case GNUNET_DIR_SCANNER_FINISHED:
+      insert_progress_dialog_text (adcc, _("Scanner has finished.\n"));
+      break;
+    case GNUNET_DIR_SCANNER_PROTOCOL_ERROR:
+      insert_progress_dialog_text (adcc,
+          _("There was a failure communicating with the scanner.\n"));
+      adcc->keep = 1;
+      break;
+    default:
+      GNUNET_asprintf (&s,_("Got unknown scanner update with filename 
`%s'.\n"),
+          filename);
+      insert_progress_dialog_text (adcc, s);
+      GNUNET_free (s);
+      adcc->keep = 1;
+      break;
+  }
+  if ((filename == NULL && GNUNET_DIR_SCANNER_FINISHED)
+      || reason == GNUNET_DIR_SCANNER_PROTOCOL_ERROR
+      || reason == GNUNET_DIR_SCANNER_SHUTDOWN)
+  {
+    /* Any of this causes us to try to clean up the scanner */
+    adcc->directory_scan_intermediary_result = 
GNUNET_FS_directory_scan_cleanup (ds);
+    adcc->pmc = GNUNET_FS_trim_share_tree 
(adcc->directory_scan_intermediary_result,
+      &directory_trim_complete, adcc);
+
+    adcc->ds = NULL;
+    /* FIXME: change the tree processor to be able to free untrimmed trees
+     * right here instead of waiting for trimming to complete, if we need to
+     * cancel everything.
+     */
+  }
+  return 0;
+}
+
+void
 GNUNET_GTK_publish_directory_dialog_response_cb (GtkDialog * dialog,
                                                  gint response_id,
                                                  struct 
MainPublishingDialogContext *ctx)
@@ -1529,6 +1212,8 @@
   GtkSpinButton *sb;
   struct GNUNET_FS_BlockOptions bo;
   GtkWidget *ad;
+  GtkTextIter iter;
+  struct AddDirClientContext *adcc;
 
   if (g_signal_handler_is_connected (G_OBJECT (dialog), 
ctx->open_directory_handler_id))
     g_signal_handler_disconnect (G_OBJECT (dialog), 
ctx->open_directory_handler_id);
@@ -1563,8 +1248,45 @@
                                        (ctx->open_directory_builder,
                                         
"GNUNET_GTK_publish_directory_dialog_do_index_checkbutton")));
 
-    /* FIXME: open progress dialog here... */
-    add_dir (ctx, filename, &bo, do_index);
+    adcc = GNUNET_malloc (sizeof (struct AddDirClientContext));
+    adcc->ctx = ctx;
+    GNUNET_CONTAINER_DLL_insert_tail (ctx->adddir_head, ctx->adddir_tail, 
adcc);
+    adcc->ds = GNUNET_FS_directory_scan_start (filename,
+        GNUNET_NO, NULL, directory_scan_cb, adcc);
+    adcc->directory_scan_bo = bo;
+    adcc->directory_scan_do_index = do_index;
+
+    adcc->progress_dialog_builder = GNUNET_GTK_get_new_builder (
+        "gnunet_fs_gtk_progress_dialog.glade", adcc);
+    adcc->progress_dialog = GTK_WIDGET (gtk_builder_get_object (
+        adcc->progress_dialog_builder,
+        "GNUNET_FS_GTK_progress_dialog"));
+    adcc->progress_dialog_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (
+        adcc->progress_dialog_builder,
+        "GNUNET_FS_GTK_progress_dialog_progressbar"));
+    adcc->progress_dialog_ok = GTK_BUTTON (gtk_builder_get_object (
+        adcc->progress_dialog_builder,
+        "GNUNET_FS_GTK_progress_dialog_ok_button"));
+    adcc->progress_dialog_cancel = GTK_BUTTON (gtk_builder_get_object (
+        adcc->progress_dialog_builder,
+        "GNUNET_FS_GTK_progress_dialog_cancel_button"));
+    adcc->progress_dialog_textview = GTK_TEXT_VIEW (
+        gtk_builder_get_object (adcc->progress_dialog_builder,
+        "GNUNET_FS_GTK_progress_dialog_textview"));
+    adcc->progress_dialog_textbuffer = GTK_TEXT_BUFFER (
+        gtk_builder_get_object (adcc->progress_dialog_builder,
+        "GNUNET_FS_GTK_progress_dialog_textbuffer"));
+    gtk_widget_set_sensitive (GTK_WIDGET (adcc->progress_dialog_ok), FALSE);
+
+    gtk_text_buffer_get_end_iter (adcc->progress_dialog_textbuffer,
+        &iter);
+    adcc->progress_dialog_textmark = gtk_text_buffer_create_mark (
+        adcc->progress_dialog_textbuffer, "scroll",
+        &iter, FALSE);
+
+    gtk_window_set_transient_for (GTK_WINDOW (adcc->progress_dialog), 
adcc->ctx->master_pubdialog);
+    gtk_window_present (GTK_WINDOW (adcc->progress_dialog));
+
     g_free (filename);
     update_selectivity (ctx);
   }
@@ -1584,6 +1306,18 @@
 
   ctx->open_directory_builder = GNUNET_GTK_get_new_builder 
("gnunet_fs_gtk_publish_directory_dialog.glade", ctx);
   GNUNET_FS_GTK_setup_expiration_year_adjustment (ctx->open_directory_builder);
+
+  /* FIXME: Use some kind of adjustable defaults instead of 1000, 0 and TRUE */
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (
+      ctx->open_directory_builder,
+      "GNUNET_GTK_publish_directory_dialog_priority_spin_button")), 1000);
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (
+      ctx->open_directory_builder,
+      "GNUNET_GTK_publish_directory_dialog_replication_spin_button")), 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (
+      ctx->open_directory_builder,
+      "GNUNET_GTK_publish_directory_dialog_do_index_checkbutton")), TRUE);
+
   ad = GTK_WIDGET (gtk_builder_get_object
                    (ctx->open_directory_builder, 
"GNUNET_GTK_publish_directory_dialog"));
 
@@ -1839,15 +1573,7 @@
   }
 }
 
-
-void
-GNUNET_GTK_master_publish_dialog_realize_cb (GtkWidget * widget,
-                                             struct 
MainPublishingDialogContext *ctx)
-{
-}
-
-
-static void
+static int
 hide_master_publish_dialog (struct MainPublishingDialogContext *ctx, gint ret)
 {
   GtkTreeIter iter;
@@ -1856,6 +1582,10 @@
   gchar *namespace_uid;
   struct GNUNET_FS_FileInformation *fi;
 
+  /* Don't close until all scanners are finished */
+  if (ctx->adddir_head != NULL)
+    return GNUNET_NO;
+
   if (ret == GTK_RESPONSE_OK)
   {
     if (TRUE == gtk_tree_selection_get_selected (ctx->pseudonym_selection, 
NULL, &iter))
@@ -1903,6 +1633,7 @@
   gtk_widget_destroy (GTK_WIDGET (ctx->master_pubdialog));
   g_object_unref (G_OBJECT (ctx->builder));
   GNUNET_free (ctx);
+  return GNUNET_YES;
 }
 
 
@@ -1927,8 +1658,9 @@
                                                   GdkEvent * event,
                                                   struct 
MainPublishingDialogContext *ctx)
 {
-  hide_master_publish_dialog (ctx, GTK_RESPONSE_CANCEL);
-  return TRUE;
+  if (GNUNET_NO == hide_master_publish_dialog (ctx, GTK_RESPONSE_CANCEL))
+    return TRUE;
+  return FALSE;
 }
 
 




reply via email to

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