gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r32173 - in gnunet-gtk: contrib src/fs
Date: Mon, 3 Feb 2014 22:07:23 +0100

Author: grothoff
Date: 2014-02-03 22:07:23 +0100 (Mon, 03 Feb 2014)
New Revision: 32173

Modified:
   gnunet-gtk/contrib/gnunet_fs_gtk_main_window.glade
   gnunet-gtk/contrib/gnunet_fs_gtk_search_tab.glade
   gnunet-gtk/src/fs/gnunet-fs-gtk.c
   gnunet-gtk/src/fs/gnunet-fs-gtk_download-save-as.c
   gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.c
   gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.h
Log:
implementing #2522

Modified: gnunet-gtk/contrib/gnunet_fs_gtk_main_window.glade
===================================================================
--- gnunet-gtk/contrib/gnunet_fs_gtk_main_window.glade  2014-02-03 20:35:37 UTC 
(rev 32172)
+++ gnunet-gtk/contrib/gnunet_fs_gtk_main_window.glade  2014-02-03 21:07:23 UTC 
(rev 32173)
@@ -12,6 +12,50 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
+  <object class="GtkTreeStore" 
id="GNUNET_GTK_file_sharing_downloads_tree_store">
+    <columns>
+      <!-- column-name metadata -->
+      <column type="gpointer"/>
+      <!-- column-name uri -->
+      <column type="gpointer"/>
+      <!-- column-name filesize -->
+      <column type="guint64"/>
+      <!-- column-name preview -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name percent_progress -->
+      <column type="guint"/>
+      <!-- column-name percent_availability -->
+      <column type="guint"/>
+      <!-- column-name filename -->
+      <column type="gchararray"/>
+      <!-- column-name uri_as_string -->
+      <column type="gchararray"/>
+      <!-- column-name status_colour -->
+      <column type="gchararray"/>
+      <!-- column-name struct_search_result -->
+      <column type="gpointer"/>
+      <!-- column-name mimetype -->
+      <column type="gchararray"/>
+      <!-- column-name applicability_rank -->
+      <column type="guint"/>
+      <!-- column-name availability_certainty -->
+      <column type="guint"/>
+      <!-- column-name availability_rank -->
+      <column type="gint"/>
+      <!-- column-name completed -->
+      <column type="guint64"/>
+      <!-- column-name downloaded_filename -->
+      <column type="gchararray"/>
+      <!-- column-name downloaded_anonymity -->
+      <column type="gint"/>
+      <!-- column-name status_icon -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name unknown_availability -->
+      <column type="gint"/>
+      <!-- column-name show_ns_association -->
+      <column type="gboolean"/>
+    </columns>
+  </object>
   <object class="GtkTreeStore" 
id="GNUNET_GTK_file_sharing_publishing_tree_store">
     <columns>
       <!-- column-name filesize -->
@@ -32,6 +76,18 @@
       <column type="guint"/>
     </columns>
   </object>
+  <object class="GtkListStore" id="GNUNET_GTK_meta_data_list_store">
+    <columns>
+      <!-- column-name extractor_meta_type -->
+      <column type="guint"/>
+      <!-- column-name extractor_meta_format -->
+      <column type="guint"/>
+      <!-- column-name extractor_meta_type_string -->
+      <column type="gchararray"/>
+      <!-- column-name extracotr_meta_value -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkWindow" id="GNUNET_GTK_main_window">
     <property name="can_focus">False</property>
     <property name="events">GDK_BUTTON_PRESS_MASK | 
GDK_STRUCTURE_MASK</property>
@@ -569,8 +625,205 @@
                   <object class="GtkNotebook" 
id="GNUNET_GTK_main_window_notebook">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="scrollable">True</property>
                     <signal name="switch-page" 
handler="GNUNET_GTK_main_window_notebook_switch_page_cb" after="yes" 
swapped="no"/>
+                    <child>
+                      <object class="GtkTreeView" 
id="GNUNET_GTK_download_frame">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property 
name="model">GNUNET_GTK_file_sharing_downloads_tree_store</property>
+                        <property name="headers_clickable">False</property>
+                        <property name="search_column">6</property>
+                        <property 
name="enable_grid_lines">horizontal</property>
+                        <property name="enable_tree_lines">True</property>
+                        <signal name="cursor-changed" 
handler="GNUNET_FS_GTK_download_frame_treeview_cursor_changed_cb" swapped="no"/>
+                        <signal name="button-press-event" 
handler="GNUNET_GTK_download_frame_button_press_event_cb" swapped="no"/>
+                        <signal name="popup-menu" 
handler="GNUNET_FS_GTK_search_treeview_popup_menu" swapped="no"/>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_description_column">
+                            <property name="title">Description</property>
+                            <property name="expand">True</property>
+                            <property name="clickable">True</property>
+                            <property name="reorderable">True</property>
+                            <property name="sort_indicator">True</property>
+                            <property name="sort_column_id">6</property>
+                            <child>
+                              <object class="GtkCellRendererText" 
id="GNUNET_GTK_download_description_renderer_text"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="text">6</attribute>
+                              </attributes>
+                            </child>
+                            <child>
+                              <object class="GtkCellRendererPixbuf" 
id="GNUNET_GTK_download_description_renderer_pixbuf">
+                                <property name="xalign">1</property>
+                                <property 
name="icon_name">gnunet-fs-gtk-ns-association</property>
+                              </object>
+                              <attributes>
+                                <attribute name="visible">19</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_pixbuf_column">
+                            <property name="title" 
translatable="yes">Status</property>
+                            <child>
+                              <object class="GtkCellRendererPixbuf" 
id="GNUNET_GTK_download_status_cellrendererpixbuf"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="pixbuf">17</attribute>
+                                <attribute name="stock-id">8</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_availability_column">
+                            <property name="title">Availability</property>
+                            <property name="clickable">True</property>
+                            <property name="reorderable">True</property>
+                            <property name="sort_indicator">True</property>
+                            <property name="sort_column_id">5</property>
+                            <child>
+                              <object class="GtkCellRendererProgress" 
id="GNUNET_GTK_download_availability_renderer"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="pulse">18</attribute>
+                                <attribute name="value">5</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_mime_column">
+                            <property name="visible">False</property>
+                            <property name="title">Format</property>
+                            <property name="clickable">True</property>
+                            <property name="reorderable">True</property>
+                            <property name="sort_indicator">True</property>
+                            <property name="sort_column_id">10</property>
+                            <child>
+                              <object class="GtkCellRendererText" 
id="GNUNET_GTK_download_mime_renderer"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="text">10</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_completed_column">
+                            <property name="visible">False</property>
+                            <property name="title">Completed (bytes)</property>
+                            <property name="clickable">True</property>
+                            <property name="reorderable">True</property>
+                            <property name="sort_indicator">True</property>
+                            <property name="sort_column_id">14</property>
+                            <child>
+                              <object class="GtkCellRendererText" 
id="GNUNET_GTK_download_completed_renderer"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="text">14</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_size_column">
+                            <property name="title">Size</property>
+                            <property name="clickable">True</property>
+                            <property name="reorderable">True</property>
+                            <property name="sort_indicator">True</property>
+                            <property name="sort_column_id">2</property>
+                            <child>
+                              <object class="GtkCellRendererText" 
id="GNUNET_GTK_download_size_renderer"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="text">2</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_progress_column">
+                            <property name="title">Progress</property>
+                            <property name="clickable">True</property>
+                            <property name="reorderable">True</property>
+                            <property name="sort_indicator">True</property>
+                            <property name="sort_column_id">4</property>
+                            <child>
+                              <object class="GtkCellRendererProgress" 
id="GNUNET_GTK_download_progress_renderer"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="text">4</attribute>
+                                <attribute name="value">4</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" 
id="GNUNET_GTK_download_applicability_column">
+                            <property name="visible">False</property>
+                            <property name="title">#</property>
+                            <property name="clickable">True</property>
+                            <property name="reorderable">True</property>
+                            <property name="sort_indicator">True</property>
+                            <property name="sort_column_id">11</property>
+                            <child>
+                              <object class="GtkCellRendererText" 
id="GNUNET_GTK_download_applicability_renderer"/>
+                              <attributes>
+                                <attribute name="cell-background">8</attribute>
+                                <attribute name="text">11</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="tab">
+                      <object class="GtkHBox" 
id="GNUNET_GTK_download_frame_hbox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkImage" 
id="GNUNET_GTK_main_window_notebook_download_image">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="stock">gtk-go-down</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="padding">5</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" 
id="_search_result_label_clear_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <signal name="clicked" 
handler="GNUNET_FS_GTK_downloads_clear_button_clicked" swapped="no"/>
+                            <child>
+                              <object class="GtkImage" 
id="clear_icon_stock_image">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="stock">gtk-clear</property>
+                                <property name="icon-size">2</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="padding">5</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="tab_fill">False</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">True</property>
@@ -890,18 +1143,6 @@
       </object>
     </child>
   </object>
-  <object class="GtkListStore" id="GNUNET_GTK_meta_data_list_store">
-    <columns>
-      <!-- column-name extractor_meta_type -->
-      <column type="guint"/>
-      <!-- column-name extractor_meta_format -->
-      <column type="guint"/>
-      <!-- column-name extractor_meta_type_string -->
-      <column type="gchararray"/>
-      <!-- column-name extracotr_meta_value -->
-      <column type="gchararray"/>
-    </columns>
-  </object>
   <object class="GtkListStore" id="GNUNET_GTK_peer_info_list_store">
     <columns>
       <!-- column-name peer_identity -->
@@ -916,6 +1157,13 @@
       <column type="guint64"/>
     </columns>
   </object>
+  <object class="GtkSizeGroup" 
id="GNUNET_GTK_download_frame_labels_size_group">
+    <widgets>
+      <widget name="GNUNET_GTK_search_frame_download_location_label"/>
+      <widget name="GNUNET_GTK_search_frame_download_anonymity_label"/>
+      <widget name="GNUNET_GTK_search_frame_download_filename_label"/>
+    </widgets>
+  </object>
   <object class="GtkListStore" id="GNUNET_GTK_select_pseudonym_liststore">
     <columns>
       <!-- column-name namespace_name -->
@@ -1018,27 +1266,6 @@
     <property name="can_focus">False</property>
     <property name="stock">gtk-index</property>
   </object>
-  <object class="GtkSizeGroup" id="GNUNET_FS_GTK_download_frame_vsize_group">
-    <property name="mode">vertical</property>
-    <property name="ignore_hidden">True</property>
-    <widgets>
-      <widget name="GNUNET_GTK_search_frame_download_location_label"/>
-      <widget name="GNUNET_GTK_search_frame_download_filename_label"/>
-      <widget name="GNUNET_GTK_search_frame_download_anonymity_label"/>
-      <widget name="GNUNET_GTK_search_frame_download_location_chooser"/>
-      <widget name="GNUNET_GTK_search_frame_download_filename_entry"/>
-      <widget name="GNUNET_GTK_search_frame_download_filename_change_button"/>
-      <widget name="main_window_download_anonymity_combobox_alignment"/>
-      <widget name="GNUNET_GTK_search_frame_download_recursive_checkbox"/>
-    </widgets>
-  </object>
-  <object class="GtkSizeGroup" 
id="GNUNET_GTK_download_frame_labels_size_group">
-    <widgets>
-      <widget name="GNUNET_GTK_search_frame_download_location_label"/>
-      <widget name="GNUNET_GTK_search_frame_download_anonymity_label"/>
-      <widget name="GNUNET_GTK_search_frame_download_filename_label"/>
-    </widgets>
-  </object>
   <object class="GtkSizeGroup" id="enties_and_comboboxes_sizegroup">
     <property name="mode">vertical</property>
   </object>
@@ -1230,6 +1457,20 @@
     <property name="can_focus">False</property>
     <property name="stock">gtk-open</property>
   </object>
+  <object class="GtkSizeGroup" id="GNUNET_FS_GTK_download_frame_vsize_group">
+    <property name="mode">vertical</property>
+    <property name="ignore_hidden">True</property>
+    <widgets>
+      <widget name="GNUNET_GTK_search_frame_download_location_label"/>
+      <widget name="GNUNET_GTK_search_frame_download_filename_label"/>
+      <widget name="GNUNET_GTK_search_frame_download_anonymity_label"/>
+      <widget name="GNUNET_GTK_search_frame_download_location_chooser"/>
+      <widget name="GNUNET_GTK_search_frame_download_filename_entry"/>
+      <widget name="GNUNET_GTK_search_frame_download_filename_change_button"/>
+      <widget name="main_window_download_anonymity_combobox_alignment"/>
+      <widget name="GNUNET_GTK_search_frame_download_recursive_checkbox"/>
+    </widgets>
+  </object>
   <object class="GtkAdjustment" id="priority_adjustment">
     <property name="upper">10000000</property>
     <property name="value">1000</property>

Modified: gnunet-gtk/contrib/gnunet_fs_gtk_search_tab.glade
===================================================================
--- gnunet-gtk/contrib/gnunet_fs_gtk_search_tab.glade   2014-02-03 20:35:37 UTC 
(rev 32172)
+++ gnunet-gtk/contrib/gnunet_fs_gtk_search_tab.glade   2014-02-03 21:07:23 UTC 
(rev 32173)
@@ -285,28 +285,6 @@
           </packing>
         </child>
         <child>
-          <object class="GtkButton" id="_search_result_label_clear_button">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <signal name="clicked" 
handler="GNUNET_FS_GTK_search_result_clear_button_clicked" swapped="no"/>
-            <child>
-              <object class="GtkImage" id="clear_icon_stock_image">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="stock">gtk-clear</property>
-                <property name="icon-size">2</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="padding">5</property>
-            <property name="position">3</property>
-          </packing>
-        </child>
-        <child>
           <object class="GtkButton" id="_search_result_label_close_button">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
@@ -325,7 +303,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">False</property>
-            <property name="position">4</property>
+            <property name="position">3</property>
           </packing>
         </child>
       </object>
@@ -333,11 +311,5 @@
   </object>
   <object class="GtkSizeGroup" id="_search_result_label_buttons_size_group">
     <property name="mode">both</property>
-    <widgets>
-      <widget name="_search_result_label_close_button"/>
-      <widget name="_search_result_label_clear_button"/>
-      <widget name="_search_result_label_pause_button"/>
-      <widget name="_search_result_label_play_button"/>
-    </widgets>
   </object>
 </interface>

Modified: gnunet-gtk/src/fs/gnunet-fs-gtk.c
===================================================================
--- gnunet-gtk/src/fs/gnunet-fs-gtk.c   2014-02-03 20:35:37 UTC (rev 32172)
+++ gnunet-gtk/src/fs/gnunet-fs-gtk.c   2014-02-03 21:07:23 UTC (rev 32173)
@@ -47,6 +47,12 @@
 #define SERVICE_LIST_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 1)
 
 /**
+ * The GNUNET_GTK_file_sharing_downloads_tree_store with the
+ * information about active (or completed) downloads.
+ */
+GtkTreeStore *downloads_treestore;
+
+/**
  * Should gnunet-fs-gtk start in tray mode?
  */
 static int tray_only;
@@ -700,6 +706,7 @@
 
   main_context.search_entry = GTK_ENTRY (GNUNET_FS_GTK_get_main_window_object 
("main_window_search_entry"));
 
+  downloads_treestore = GTK_TREE_STORE (GNUNET_FS_GTK_get_main_window_object 
("GNUNET_GTK_file_sharing_downloads_tree_store"));
   main_context.anonymity_combo = GTK_COMBO_BOX 
(GNUNET_FS_GTK_get_main_window_object 
("main_window_search_anonymity_combobox"));
   main_context.anonymity_level_liststore = GTK_LIST_STORE 
(GNUNET_FS_GTK_get_main_window_object ("anonymity_level_liststore"));
 

Modified: gnunet-gtk/src/fs/gnunet-fs-gtk_download-save-as.c
===================================================================
--- gnunet-gtk/src/fs/gnunet-fs-gtk_download-save-as.c  2014-02-03 20:35:37 UTC 
(rev 32172)
+++ gnunet-gtk/src/fs/gnunet-fs-gtk_download-save-as.c  2014-02-03 21:07:23 UTC 
(rev 32173)
@@ -94,6 +94,9 @@
 void
 GNUNET_FS_GTK_free_download_entry (struct DownloadEntry *de)
 {
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
   GNUNET_assert (NULL == de->dc);
   if (NULL != de->sr)
   {
@@ -103,6 +106,17 @@
   }
   GNUNET_free_non_null (de->filename);
   GNUNET_FS_uri_destroy (de->uri);
+  if (NULL != de->rr)
+  {
+    path = gtk_tree_row_reference_get_path (de->rr);
+    GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL 
(downloads_treestore),
+                                            &iter, path));
+    gtk_tree_path_free (path);
+    gtk_tree_row_reference_free (de->rr);
+    de->rr = NULL;
+    gtk_tree_store_remove (downloads_treestore,
+                           &iter);
+  }
   GNUNET_free (de);
 }
 
@@ -253,7 +267,7 @@
       }
       else
       {
-       dlc->dirname = dirname; 
+       dlc->dirname = dirname;
       }
     }
     gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dlc->dialog), 
dirname);

Modified: gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.c
===================================================================
--- gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.c     2014-02-03 20:35:37 UTC 
(rev 32172)
+++ gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.c     2014-02-03 21:07:23 UTC 
(rev 32173)
@@ -266,8 +266,8 @@
 static struct SearchTab *search_tab_tail;
 
 /**
- * Special tab we use to for downloads-by-URIs and downloads
- * where the search tab has been closed ("parent lost").
+ * Special tab we use to for downloads-by-URIs and
+ * opened directory files.
  */
 static struct SearchTab *uri_tab;
 
@@ -284,7 +284,7 @@
 /**
  * Currently selected row in a search tab.
  */
-static GtkTreePath *current_selected_search_result = NULL;
+static GtkTreePath *current_selected_search_result;
 
 /**
  * Animation to display while publishing.
@@ -655,7 +655,8 @@
 struct SearchListPopupContext
 {
   /**
-   * Tab where the search list popup was created.
+   * Tab where the search list popup was created, NULL for
+   * the downloads list.
    */
   struct SearchTab *tab;
 
@@ -703,7 +704,75 @@
 
 
 /**
+ * Setup an entry for the download in the download list.
+ * Initializes the 'rr' field of @a de.
  *
+ * @param de the download entry to initialize
+ * @param pde download entry of the parent, or NULL for top-level
+ * @param sr associated search result to add to the model
+ */
+static void
+setup_download_list_entry (struct DownloadEntry *de,
+                           struct DownloadEntry *pde,
+                           struct SearchResult *sr)
+{
+  GtkTreeIter download_iter;
+  GtkTreeIter download_piter;
+  GtkTreePath *path;
+
+  /* created row in download list */
+  if (NULL == pde)
+  {
+    /* top level */
+    gtk_tree_store_insert (downloads_treestore,
+                           &download_iter,
+                           NULL,
+                           G_MAXINT);
+  }
+  else
+  {
+    /* below parent */
+    path = gtk_tree_row_reference_get_path (pde->rr);
+    GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL 
(downloads_treestore),
+                                            &download_piter, path));
+    gtk_tree_path_free (path);
+    gtk_tree_store_insert (downloads_treestore,
+                           &download_iter,
+                           &download_piter,
+                           G_MAXINT);
+  }
+  gtk_tree_store_set (downloads_treestore, &download_iter,
+                      SEARCH_TAB_MC_SEARCH_RESULT, sr,
+                      -1);
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (downloads_treestore),
+                                  &download_iter);
+  de->rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (downloads_treestore),
+                                       path);
+  gtk_tree_path_free (path);
+}
+
+
+/**
+ * Obtain the iterator for the respective download entry.
+ *
+ * @param de the download entry
+ * @param[OUT] iter set to the respective position in the #downloads_treestore
+ */
+static void
+get_download_list_entry (struct DownloadEntry *de,
+                         GtkTreeIter *iter)
+{
+  GtkTreePath *path;
+
+  path = gtk_tree_row_reference_get_path (de->rr);
+  GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (downloads_treestore),
+                                          iter, path));
+  gtk_tree_path_free (path);
+}
+
+
+/**
+ *
  * @param save_as #GNUNET_YES to open SaveAs dialog, #GNUNET_NO to start 
downloading.
  * @param download_directly #GNUNET_YES to make SaveAs dialog initiate the 
download,
  *                     #GNUNET_NO to only change names on the download panel.
@@ -774,9 +843,14 @@
       de->pde = psr->download;
   }
   /* else pde remains zero */
+  setup_download_list_entry (de, de->pde, sr);
 
   de->uri = GNUNET_FS_uri_dup (uri);
-  GNUNET_asprintf (&de->filename, "%s%s%s", downloaddir, DIR_SEPARATOR_STR, 
filename);
+  GNUNET_asprintf (&de->filename,
+                   "%s%s%s",
+                   downloaddir,
+                   DIR_SEPARATOR_STR,
+                   filename);
   de->sr = sr;
   sr->download = de;
   if (GNUNET_GTK_get_selected_anonymity_combo_level 
(mctx->download_anonymity_combo, &anonymity))
@@ -798,7 +872,9 @@
 
   if (!save_as)
   {
-    if (GNUNET_GTK_tree_model_get_next_flat_iter (model, &iter, !recursive, 
&next_item))
+    if (GNUNET_GTK_tree_model_get_next_flat_iter (model, &iter,
+                                                  ! recursive,
+                                                  &next_item))
       gtk_tree_selection_select_iter (sel, &next_item);
     GNUNET_FS_GTK_search_treeview_cursor_changed (tv, st);
   }
@@ -942,6 +1018,21 @@
 
 
 /**
+ * Selected row has changed in downloads tree view, update preview
+ * and metadata areas.
+ *
+ * @param tv the tree view in a search tab where the selection changed
+ * @param user_data unused
+ */
+void
+GNUNET_FS_GTK_download_frame_treeview_cursor_changed_cb (GtkTreeView *tv,
+                                                         gpointer user_data)
+{
+  GNUNET_FS_GTK_search_treeview_cursor_changed (tv, NULL);
+}
+
+
+/**
  * Download "abort" was selected in the current search context menu.
  *
  * @param item the 'abort' menu item
@@ -954,10 +1045,18 @@
   struct DownloadEntry *de = spc->sr->download;
   GtkTreeView *tv;
 
-  GNUNET_assert (de->dc != NULL);
+  GNUNET_assert (NULL != de->dc);
   GNUNET_FS_download_stop (de->dc, GNUNET_YES);
-  tv = GTK_TREE_VIEW (gtk_builder_get_object (spc->tab->builder, 
"_search_result_frame"));
-  GNUNET_FS_GTK_search_treeview_cursor_changed (tv, spc->tab);
+  if (NULL != spc->tab)
+  {
+    tv = GTK_TREE_VIEW (gtk_builder_get_object (spc->tab->builder, 
"_search_result_frame"));
+    GNUNET_FS_GTK_search_treeview_cursor_changed (tv, spc->tab);
+  }
+  else
+  {
+    tv = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object 
("GNUNET_GTK_download_frame"));
+    GNUNET_FS_GTK_download_frame_treeview_cursor_changed_cb (tv, NULL);
+  }
 }
 
 
@@ -980,9 +1079,12 @@
   GtkClipboard *cb;
 
   path = gtk_tree_row_reference_get_path (spc->rr);
-  tv = GTK_TREE_VIEW (gtk_builder_get_object
-                      (spc->tab->builder,
-                       "_search_result_frame"));
+  if (NULL != spc->tab)
+    tv = GTK_TREE_VIEW (gtk_builder_get_object
+                        (spc->tab->builder,
+                         "_search_result_frame"));
+  else
+    tv = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object 
("GNUNET_GTK_download_frame"));
   tm = gtk_tree_view_get_model (tv);
   if (! gtk_tree_model_get_iter (tm, &iter, path))
   {
@@ -1179,7 +1281,7 @@
  * an appropriate menu.
  *
  * @param tm tree model underlying the tree view where the event happened
- * @param tab tab where the event happened
+ * @param tab tab where the event happened, NULL for download tab
  * @param init_button which button triggered the popup, or 0 for none
  * @param event_time at what time was the popup triggered
  * @param iter location in the tree model selected at the time
@@ -1369,6 +1471,46 @@
 
 
 /**
+ * We got a right-click on the downloads list. Display the context
+ * menu.
+ *
+ * @param widget the GtkTreeView with the search result list
+ * @param event the event, we only care about button events
+ * @param user_data UNUSED
+ * @return FALSE to propagate the event further,
+ *         TRUE to stop the propagation
+ */
+gboolean
+GNUNET_GTK_download_frame_button_press_event_cb (GtkWidget * widget,
+                                                 GdkEvent * event,
+                                                 gpointer user_data)
+{
+  GtkTreeView *tv = GTK_TREE_VIEW (widget);
+  GdkEventButton *event_button = (GdkEventButton *) event;
+  GtkTreeModel *tm;
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  if ( (GDK_BUTTON_PRESS != event->type) ||
+       (3 != event_button->button) )
+    return FALSE; /* not a right-click */
+  if (! gtk_tree_view_get_path_at_pos (tv,
+                                      event_button->x, event_button->y,
+                                       &path, NULL, NULL, NULL))
+    return FALSE; /* click outside of area with values, ignore */
+  tm = gtk_tree_view_get_model (tv);
+  if (! gtk_tree_model_get_iter (tm, &iter, path))
+    return FALSE; /* not sure how we got a path but no iter... */
+  gtk_tree_path_free (path);
+  search_list_popup (tm, NULL,
+                    event_button->button,
+                    event_button->time,
+                    &iter);
+  return FALSE;
+}
+
+
+/**
  * Recalculate and update the label for a search, as we have
  * received additional search results.
  *
@@ -1464,223 +1606,21 @@
 
 
 /**
- * Copy all of the children of @a src_iter from the @a src_model to
- * become children of @a dst_iter in the @a dst_model.  The models are
- * both 'GNUNET_GTK_file_sharing_result_tree_store' models.
- *
- * Note that we also need to update the `struct SearchResult`
- * and (if it exists) the respective `struct DownloadEntry`
- * to refer to the new model.
- *
- * @param src_model source model
- * @param src_iter parent of the nodes to move
- * @param dst_tab destination tab
- * @param dst_iter new parent of the entries we are moving
- */
-static void
-copy_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
-              struct SearchTab *dst_tab,
-               GtkTreeIter * dst_iter)
-{
-  GtkTreeIter src_child;
-  GtkTreeIter dst_child;
-  GtkTreePath *path;
-  struct GNUNET_CONTAINER_MetaData *meta;
-  struct GNUNET_FS_Uri *uri;
-  guint64 filesize, completed;
-  GdkPixbuf *preview;
-  guint percent_progress;
-  guint percent_availability;
-  gint unknown_availability;
-  gchar *filename;
-  gchar *uri_as_string;
-  gchar *status_colour;
-  struct SearchResult *search_result_old;
-  struct SearchResult *search_result_new;
-  gchar *mimetype;
-  guint applicability_rank;
-  guint availability_certainty;
-  gint availability_rank;
-  gchar *downloaded_filename;
-  gint downloaded_anonymity;
-  gboolean show_ns_association;
-
-  if (! gtk_tree_model_iter_children (src_model, &src_child, src_iter))
-    return;
-  do
-  {
-    gtk_tree_model_get (src_model, &src_child,
-                        SEARCH_TAB_MC_METADATA, &meta,
-                        SEARCH_TAB_MC_URI, &uri,
-                        SEARCH_TAB_MC_FILESIZE, &filesize,
-                        SEARCH_TAB_MC_PREVIEW, &preview,
-                        SEARCH_TAB_MC_PERCENT_PROGRESS, &percent_progress,
-                        SEARCH_TAB_MC_PERCENT_AVAILABILITY, 
&percent_availability,
-                        SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, 
&unknown_availability,
-                        SEARCH_TAB_MC_FILENAME, &filename,
-                        SEARCH_TAB_MC_URI_AS_STRING, &uri_as_string,
-                        SEARCH_TAB_MC_STATUS_COLOUR, &status_colour,
-                        SEARCH_TAB_MC_SEARCH_RESULT, &search_result_old,
-                        SEARCH_TAB_MC_MIMETYPE, &mimetype,
-                        SEARCH_TAB_MC_APPLICABILITY_RANK, &applicability_rank,
-                        SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, 
&availability_certainty,
-                        SEARCH_TAB_MC_AVAILABILITY_RANK, &availability_rank,
-                        SEARCH_TAB_MC_COMPLETED, &completed,
-                        SEARCH_TAB_MC_DOWNLOADED_FILENAME, 
&downloaded_filename,
-                        SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, 
&downloaded_anonymity,
-                        SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, 
&show_ns_association,
-                        -1);
-    search_result_new = GNUNET_new (struct SearchResult);
-    search_result_new->tab = dst_tab;
-    search_result_new->probe = search_result_old->probe;
-    search_result_old->probe = NULL;
-    search_result_new->download = search_result_old->download;
-    if (NULL != search_result_old->download)
-    {
-      search_result_old->download = NULL;
-      search_result_new->download->sr = search_result_new;
-    }
-    gtk_tree_store_insert_with_values (dst_tab->ts, &dst_child,
-                                       dst_iter, G_MAXINT,
-                                       SEARCH_TAB_MC_METADATA, 
GNUNET_CONTAINER_meta_data_duplicate (meta),
-                                       SEARCH_TAB_MC_URI, GNUNET_FS_uri_dup 
(uri),
-                                       SEARCH_TAB_MC_FILESIZE, filesize,
-                                       SEARCH_TAB_MC_PREVIEW, preview,
-                                       SEARCH_TAB_MC_PERCENT_PROGRESS, 
percent_progress,
-                                       SEARCH_TAB_MC_PERCENT_AVAILABILITY, 
percent_availability,
-                                      SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, 
unknown_availability,
-                                       SEARCH_TAB_MC_FILENAME, filename,
-                                       SEARCH_TAB_MC_URI_AS_STRING, 
uri_as_string,
-                                       SEARCH_TAB_MC_STATUS_COLOUR, 
status_colour,
-                                       SEARCH_TAB_MC_SEARCH_RESULT, 
search_result_new,
-                                       SEARCH_TAB_MC_MIMETYPE, mimetype,
-                                       SEARCH_TAB_MC_APPLICABILITY_RANK, 
applicability_rank,
-                                       SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, 
availability_certainty,
-                                       SEARCH_TAB_MC_AVAILABILITY_RANK, 
availability_rank,
-                                       SEARCH_TAB_MC_COMPLETED, completed,
-                                      SEARCH_TAB_MC_DOWNLOADED_FILENAME, 
downloaded_filename,
-                                       SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, 
downloaded_anonymity,
-                                       SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, 
show_ns_association,
-                                       -1);
-    g_free (filename);
-    g_free (downloaded_filename);
-    g_free (uri_as_string);
-    g_free (status_colour);
-    g_free (mimetype);
-    if (preview != NULL)
-      g_object_unref (preview);
-
-    path = gtk_tree_model_get_path (GTK_TREE_MODEL (dst_tab->ts), &dst_child);
-    search_result_new->rr = gtk_tree_row_reference_new (GTK_TREE_MODEL 
(dst_tab->ts), path);
-    gtk_tree_path_free (path);
-
-    copy_children (src_model, &src_child, dst_tab, &dst_child);
-  }
-  while (gtk_tree_model_iter_next (src_model, &src_child));
-}
-
-
-/**
  * Handle the case where an active download lost its
- * search parent by moving it to the URI tab.
+ * search parent; need to remember that the respective
+ * tab and row reference no longer exist.
  *
  * @param de download where the parent (i.e. search) was lost
  */
 static void
 download_lost_parent (struct DownloadEntry *de)
 {
-  GtkTreeIter iter;
-  GtkTreePath *path;
-  GtkTreeModel *tm_old;
-  GtkTreeIter iter_old;
-  GtkTreeModel *model;
-  struct GNUNET_CONTAINER_MetaData *meta;
-  struct GNUNET_FS_Uri *uri;
-  guint64 completed;
-  guint percent_progress;
-  guint percent_availability;
-  gint unknown_availability;
-  gchar *filename;
-  gchar *status_colour;
-  guint applicability_rank;
-  guint availability_certainty;
-  gint availability_rank;
-  gchar *downloaded_filename;
-  gint downloaded_anonymity;
-  GdkPixbuf *status_animation;
-  gboolean show_ns_association;
-
-  /* find the 'old' root */
-  tm_old = GTK_TREE_MODEL (de->sr->tab->ts);
-  path = gtk_tree_row_reference_get_path (de->sr->rr);
-  if (! gtk_tree_model_get_iter (tm_old, &iter_old, path))
+  de->sr->tab = NULL;
+  if (NULL != de->sr->rr)
   {
-    GNUNET_break (0);
-    gtk_tree_path_free (path);
-    return;
+    gtk_tree_row_reference_free (de->sr->rr);
+    de->sr->rr = NULL;
   }
-  gtk_tree_path_free (path);
-  gtk_tree_model_get (tm_old, &iter_old,
-                      SEARCH_TAB_MC_METADATA, &meta,
-                      SEARCH_TAB_MC_URI, &uri,
-                      SEARCH_TAB_MC_PERCENT_PROGRESS, &percent_progress,
-                      SEARCH_TAB_MC_PERCENT_AVAILABILITY, 
&percent_availability,
-                     SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, &unknown_availability,
-                      SEARCH_TAB_MC_FILENAME, &filename,
-                      SEARCH_TAB_MC_STATUS_COLOUR, &status_colour,
-                      SEARCH_TAB_MC_APPLICABILITY_RANK, &applicability_rank,
-                      SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, 
&availability_certainty,
-                      SEARCH_TAB_MC_AVAILABILITY_RANK, &availability_rank,
-                      SEARCH_TAB_MC_COMPLETED, &completed,
-                      SEARCH_TAB_MC_DOWNLOADED_FILENAME, &downloaded_filename,
-                      SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, 
&downloaded_anonymity,
-                     SEARCH_TAB_MC_STATUS_ICON, &status_animation,
-                      SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, &show_ns_association,
-                      -1);
-  GNUNET_assert (GNUNET_YES == GNUNET_FS_uri_test_equal (uri, de->uri));
-  GNUNET_assert (de->sr->download == de);
-  de->sr->download = NULL;
-
-  /* create the target root */
-  de->sr = GNUNET_GTK_add_to_uri_tab (downloaded_anonymity,
-                                     meta, uri);
-  de->sr->download = de;
-
-  /* get positions of the 'new' root */
-  model = GTK_TREE_MODEL (de->sr->tab->ts);
-  path = gtk_tree_row_reference_get_path (de->sr->rr);
-  if (! gtk_tree_model_get_iter (model, &iter, path))
-  {
-    GNUNET_break (0);
-    gtk_tree_path_free (path);
-    g_free (filename);
-    g_free (downloaded_filename);
-    g_free (status_colour);
-    return;
-  }
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_set (de->sr->tab->ts, &iter,
-                      SEARCH_TAB_MC_PERCENT_PROGRESS, percent_progress,
-                      SEARCH_TAB_MC_PERCENT_AVAILABILITY, percent_availability,
-                     SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, unknown_availability,
-                      SEARCH_TAB_MC_FILENAME, filename,
-                      SEARCH_TAB_MC_STATUS_COLOUR, status_colour,
-                      SEARCH_TAB_MC_APPLICABILITY_RANK, applicability_rank,
-                      SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, 
availability_certainty,
-                      SEARCH_TAB_MC_AVAILABILITY_RANK, availability_rank,
-                      SEARCH_TAB_MC_COMPLETED, completed,
-                      SEARCH_TAB_MC_DOWNLOADED_FILENAME, downloaded_filename,
-                      SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, downloaded_anonymity,
-                     SEARCH_TAB_MC_STATUS_ICON, status_animation,
-                      SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, show_ns_association,
-                      -1);
-  g_free (filename);
-  g_free (downloaded_filename);
-  g_free (status_colour);
-
-  /* finally, move all children over as well */
-  copy_children (tm_old, &iter_old, de->sr->tab, &iter);
 }
 
 
@@ -1707,25 +1647,16 @@
   {
     do
     {
+      if (NULL != sr->download)
+      {
+        download_lost_parent (sr->download);
+        continue;
+      }
       gtk_tree_model_get (tm, &child,
                           SEARCH_TAB_MC_METADATA, &meta,
                           SEARCH_TAB_MC_URI, &uri,
                           SEARCH_TAB_MC_SEARCH_RESULT, &sr,
                           -1);
-      if (NULL != sr->download)
-      {
-       if (sr->download->is_done == GNUNET_YES)
-       {
-         /* got a finished download, stop it */
-         GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES);
-       }
-       else
-       {
-         /* got an active download, move to URI tab! */
-         download_lost_parent (sr->download);
-       }
-      }
-      GNUNET_assert (NULL == sr->download);
       move_downloads_in_subtree (tm, &child);
       GNUNET_FS_uri_destroy (uri);
       if (NULL != meta)
@@ -1747,7 +1678,7 @@
                           SEARCH_TAB_MC_SEARCH_RESULT, NULL,
                           -1);
     }
-    while (TRUE == gtk_tree_model_iter_next (tm, &child));
+    while (gtk_tree_model_iter_next (tm, &child));
   }
 }
 
@@ -1791,11 +1722,15 @@
                       SEARCH_TAB_MC_METADATA, &meta,
                       SEARCH_TAB_MC_URI, &uri,
                       -1);
-  if (uri != NULL)
+  if (NULL != uri)
     GNUNET_FS_uri_destroy (uri);
-  if (meta != NULL)
+  if (NULL != meta)
     GNUNET_CONTAINER_meta_data_destroy (meta);
-  gtk_tree_row_reference_free (sr->rr);
+  if (NULL != sr->rr)
+  {
+    gtk_tree_row_reference_free (sr->rr);
+    sr->rr = NULL;
+  }
   if (NULL != sr->probe)
   {
     GNUNET_FS_probe_stop (sr->probe);
@@ -1815,13 +1750,12 @@
  * and metadata areas.
  *
  * @param tv the tree view in a search tab where the selection changed
- * @param user_data the 'struct SearchTab' that contains the tree view
+ * @param user_data unused
  */
 void
 GNUNET_FS_GTK_search_treeview_cursor_changed (GtkTreeView *tv,
                                              gpointer user_data)
 {
-  struct SearchTab *tab = user_data;
   GtkTreeSelection *sel;
   GtkTreeModel *model;
   GtkTreeIter iter;
@@ -1832,7 +1766,6 @@
   struct GNUNET_FS_Uri *uri;
   struct GNUNET_GTK_MainWindowContext *mctx = GNUNET_FS_GTK_get_main_context 
();
 
-  GNUNET_assert (tab->query_txt != NULL);
   gtk_list_store_clear (mctx->md_liststore);
   sel = gtk_tree_view_get_selection (tv);
   if (! gtk_tree_selection_get_selected (sel, &model, &iter))
@@ -1948,7 +1881,7 @@
      clear meta data and preview widgets */
   gtk_image_clear (mctx->preview_image);
   gtk_list_store_clear (mctx->md_liststore);
-  if (current_selected_search_result != NULL)
+  if (NULL != current_selected_search_result)
     gtk_tree_path_free (current_selected_search_result);
   current_selected_search_result = NULL;
 }
@@ -2047,7 +1980,7 @@
                           SEARCH_TAB_MC_SEARCH_RESULT, &sr,
                           -1);
       if ( (NULL != sr->download) &&
-          (sr->download->is_done == GNUNET_YES) )
+          (GNUNET_YES == sr->download->is_done) )
       {
        /* got a finished download, stop it */
        GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES);
@@ -2058,32 +1991,30 @@
       if (GNUNET_YES != stop_downloads_in_subtree (tm, &child))
        ret = GNUNET_NO;
     }
-    while (TRUE == gtk_tree_model_iter_next (tm, &child));
+    while (gtk_tree_model_iter_next (tm, &child));
   }
   return ret;
 }
 
 
 /**
- * User clicked on the 'clean' button of a search tab.
+ * User clicked on the 'clean' button of the downloads tab.
  * Stop completed downloads (or those that failed).  Should
  * iterate over the underlying tree store and stop all
- * completed entries.  Furthermore, if the resulting tree
- * store is empty and has no search associated with it,
- * the tab should be closed.
+ * completed entries.
  *
  * @param button the button pressed by the user
- * @param user_data the `struct SearchTab` of the respective tab to clean up
+ * @param user_data
  */
 void
-GNUNET_FS_GTK_search_result_clear_button_clicked (GtkButton * button, gpointer 
user_data)
+GNUNET_FS_GTK_downloads_clear_button_clicked (GtkButton * button,
+                                              gpointer user_data)
 {
-  struct SearchTab *tab = user_data;
   struct SearchResult *sr;
   GtkTreeModel *tm;
   GtkTreeIter iter;
 
-  tm = GTK_TREE_MODEL (tab->ts);
+  tm = GTK_TREE_MODEL (downloads_treestore);
   if (! gtk_tree_model_get_iter_first (tm, &iter))
     return;
   do
@@ -2091,11 +2022,13 @@
     gtk_tree_model_get (tm, &iter,
                         SEARCH_TAB_MC_SEARCH_RESULT, &sr,
                         -1);
-    if ( (sr->download != NULL) &&
-        (sr->download->is_done == GNUNET_YES) )
+    if ( (NULL != sr->download) &&
+        (GNUNET_YES == sr->download->is_done) )
     {
       /* got a finished download, stop it */
       GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES);
+      if (! gtk_tree_model_get_iter_first (tm, &iter))
+       return;
     }
     if ( (NULL == sr->download) &&
         (NULL == sr->result) &&
@@ -2216,7 +2149,23 @@
                       SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, (guint) 
availability_certainty,
                       SEARCH_TAB_MC_AVAILABILITY_RANK, (gint) 
availability_rank,
                       -1);
-  if (pixbuf != NULL)
+  if (NULL != sr->download)
+  {
+    get_download_list_entry (sr->download, &iter);
+    gtk_tree_store_set (downloads_treestore, &iter,
+                        SEARCH_TAB_MC_METADATA, 
GNUNET_CONTAINER_meta_data_duplicate (meta),
+                        SEARCH_TAB_MC_PREVIEW, pixbuf,
+                        SEARCH_TAB_MC_PERCENT_AVAILABILITY, (guint) 
percent_avail,
+                        SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, (0 == 
availability_certainty) ? (gint) (probe_time.rel_value_us / 
GNUNET_FS_PROBE_UPDATE_FREQUENCY.rel_value_us) : -1,
+                        SEARCH_TAB_MC_FILENAME, desc,
+                        SEARCH_TAB_MC_MIMETYPE, mime,
+                        SEARCH_TAB_MC_APPLICABILITY_RANK, (guint) 
applicability_rank,
+                        SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, (guint) 
availability_certainty,
+                        SEARCH_TAB_MC_AVAILABILITY_RANK, (gint) 
availability_rank,
+                        -1);
+  }
+
+  if (NULL != pixbuf)
     g_object_unref (pixbuf);
   GNUNET_free (desc);
   GNUNET_free_non_null (mime);
@@ -2264,7 +2213,7 @@
  * not only for 'normal' search results but also for directories that
  * are being opened and if the user manually enters a URI.
  *
- * @param tab search tab to extend, never NULL
+ * @param tab search tab to extend, NULL if we are only in the download tab
  * @param anonymity anonymity level to use for probes for this result
  * @param parent_rr reference to parent entry in search tab, NULL for normal
  *                  search results,
@@ -2375,7 +2324,10 @@
   {
     /* top-level result */
     pitr = NULL;
-    ts = tab->ts;
+    if (NULL != tab)
+      ts = tab->ts;
+    else
+      ts = downloads_treestore;
   }
   gtk_tree_store_insert_with_values (ts, &iter, pitr, G_MAXINT,
                                      SEARCH_TAB_MC_METADATA, 
GNUNET_CONTAINER_meta_data_duplicate (meta),
@@ -2411,10 +2363,12 @@
 
   /* move up to the outermost tab, in case this is an 'inner'
      search (namespace update case) */
-  while (NULL != tab->parent)
-    tab = tab->parent->tab;
-  tab->num_results++;
-
+  if (NULL != tab)
+  {
+    while (NULL != tab->parent)
+      tab = tab->parent->tab;
+    tab->num_results++;
+  }
   return sr;
 }
 
@@ -2736,17 +2690,22 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Changing download DE=%p color to %s\n",
              de, color);
-  path = gtk_tree_row_reference_get_path (de->sr->rr);
-  if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 
path))
+  if (NULL != de->sr->tab)
   {
-    GNUNET_break (0);
+    path = gtk_tree_row_reference_get_path (de->sr->rr);
+    GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts),
+                                            &iter, path));
     gtk_tree_path_free (path);
-    return;
+    gtk_tree_store_set (de->sr->tab->ts, &iter,
+                        SEARCH_TAB_MC_STATUS_COLOUR, color,
+                        -1);
   }
-  gtk_tree_path_free (path);
-  gtk_tree_store_set (de->sr->tab->ts, &iter,
+  /* do the same update to the downloads tree store */
+  get_download_list_entry (de, &iter);
+  gtk_tree_store_set (downloads_treestore, &iter,
                       SEARCH_TAB_MC_STATUS_COLOUR, color,
                       -1);
+
 }
 
 
@@ -2763,15 +2722,18 @@
   GtkTreeIter iter;
   GtkTreePath *path;
 
-  path = gtk_tree_row_reference_get_path (de->sr->rr);
-  if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 
path))
+  if (NULL != de->sr->tab)
   {
-    GNUNET_break (0);
+    path = gtk_tree_row_reference_get_path (de->sr->rr);
+    GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), 
&iter, path));
     gtk_tree_path_free (path);
-    return;
+    gtk_tree_store_set (de->sr->tab->ts, &iter,
+                        SEARCH_TAB_MC_STATUS_ICON, icon,
+                        -1);
   }
-  gtk_tree_path_free (path);
-  gtk_tree_store_set (de->sr->tab->ts, &iter,
+  /* do the same update to the downloads tree store */
+  get_download_list_entry (de, &iter);
+  gtk_tree_store_set (downloads_treestore, &iter,
                      SEARCH_TAB_MC_STATUS_ICON, icon,
                       -1);
 }
@@ -2927,25 +2889,30 @@
                         unsigned int depth)
 {
   GtkTreeIter iter;
+  GtkTreeIter diter;
   GtkTreePath *path;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Marking download progress for DE=%p, %llu/%llu, address@hidden 
depth=%u\n",
              de, completed, size, block_size, offset, depth);
 
-  path = gtk_tree_row_reference_get_path (de->sr->rr);
-  if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 
path))
+  if (NULL != de->sr->tab)
   {
-    GNUNET_break (0);
+    path = gtk_tree_row_reference_get_path (de->sr->rr);
+    GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts),
+                                            &iter, path));
     gtk_tree_path_free (path);
-    return;
+    /* FIXME-DESIGN: should we replace the 'availability' with
+       'progress' once the download has started and re-use the
+       space in the display? Probably yes, at least once we have
+       a custom CellRenderer... */
+    gtk_tree_store_set (de->sr->tab->ts, &iter,
+                        SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ?  
(100 * completed / size) : 100),
+                        SEARCH_TAB_MC_COMPLETED, completed,
+                        -1);
   }
-  gtk_tree_path_free (path);
-  /* FIXME-DESIGN: should we replace the 'availability' with
-     'progress' once the download has started and re-use the
-     space in the display? Probably yes, at least once we have
-     a custom CellRenderer... */
-  gtk_tree_store_set (de->sr->tab->ts, &iter,
+  get_download_list_entry (de, &diter);
+  gtk_tree_store_set (downloads_treestore, &diter,
                       SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ?  
(100 * completed / size) : 100),
                       SEARCH_TAB_MC_COMPLETED, completed,
                       -1);
@@ -2969,7 +2936,11 @@
       {
        /* Mime type was wrong, this is not a directory, update model! */
        de->is_directory = GNUNET_SYSERR;
-        gtk_tree_store_set (de->sr->tab->ts, &iter,
+        if (NULL != de->sr->tab)
+          gtk_tree_store_set (de->sr->tab->ts, &iter,
+                              SEARCH_TAB_MC_MIMETYPE, "",
+                              -1);
+        gtk_tree_store_set (downloads_treestore, &diter,
                             SEARCH_TAB_MC_MIMETYPE, "",
                            -1);
       }
@@ -3012,20 +2983,24 @@
 
   change_download_color (de, "red");
   de->is_done = GNUNET_YES;
-  path = gtk_tree_row_reference_get_path (de->sr->rr);
-  if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 
path))
+  if (NULL == animation_error)
+    animation_error = load_animation ("error");
+  if (NULL != de->sr->tab)
   {
-    GNUNET_break (0);
+    path = gtk_tree_row_reference_get_path (de->sr->rr);
+    GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), 
&iter, path));
     gtk_tree_path_free (path);
-    return;
+    gtk_tree_store_set (de->sr->tab->ts, &iter,
+                        SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 0,
+                        SEARCH_TAB_MC_URI_AS_STRING, emsg,
+                        SEARCH_TAB_MC_STATUS_ICON,  
GNUNET_GTK_animation_context_get_pixbuf (animation_error),
+                        -1);
   }
-  gtk_tree_path_free (path);
-  if (NULL == animation_error)
-    animation_error = load_animation ("error");
-  gtk_tree_store_set (de->sr->tab->ts, &iter,
+  get_download_list_entry (de, &iter);
+  gtk_tree_store_set (downloads_treestore, &iter,
                       SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 0,
                       SEARCH_TAB_MC_URI_AS_STRING, emsg,
-                     SEARCH_TAB_MC_STATUS_ICON,  
GNUNET_GTK_animation_context_get_pixbuf (animation_error),
+                     SEARCH_TAB_MC_STATUS_ICON, 
GNUNET_GTK_animation_context_get_pixbuf (animation_error),
                       -1);
 }
 
@@ -3045,15 +3020,21 @@
 
   de->is_done = GNUNET_YES;
   change_download_color (de, "green");
-  path = gtk_tree_row_reference_get_path (de->sr->rr);
-  if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 
path))
+  if (NULL != de->sr->tab)
   {
-    GNUNET_break (0);
+    path = gtk_tree_row_reference_get_path (de->sr->rr);
+    GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts),
+                                            &iter, path));
     gtk_tree_path_free (path);
-    return;
+    gtk_tree_store_set (de->sr->tab->ts, &iter,
+                        SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 100,
+                        SEARCH_TAB_MC_PERCENT_AVAILABILITY, (guint) 100,
+                        SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, -1,
+                        SEARCH_TAB_MC_STATUS_ICON, 
GNUNET_GTK_animation_context_get_pixbuf (animation_downloaded),
+                        -1);
   }
-  gtk_tree_path_free (path);
-  gtk_tree_store_set (de->sr->tab->ts, &iter,
+  get_download_list_entry (de, &iter);
+  gtk_tree_store_set (downloads_treestore, &iter,
                       SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 100,
                       SEARCH_TAB_MC_PERCENT_AVAILABILITY, (guint) 100,
                       SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, -1,
@@ -3075,10 +3056,11 @@
  * @param meta metadata
  * @param size total size
  * @param completed current progress
- * @return download entry struct for the download (equal to 'de' if 'de' was 
not NULL)
+ * @return download entry struct for the download (equal to @a de if @a de was 
not NULL)
  */
 static struct DownloadEntry *
-setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
+setup_download (struct DownloadEntry *de,
+                struct DownloadEntry *pde,
                 struct SearchResult *sr,
                uint32_t anonymity,
                struct GNUNET_FS_DownloadContext *dc,
@@ -3088,6 +3070,7 @@
 {
   GtkTreeIter iter;
   GtkTreePath *path;
+  GtkTreeModel *tm;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Setting up download, initially DE=%p, PDE=%p for %p & %p into 
%llu/%llu `%s'\n",
@@ -3120,7 +3103,8 @@
     }
   }
   if ( (NULL == de->sr) &&
-       (NULL != pde) )
+       (NULL != pde) &&
+       (NULL != pde->sr->tab) )
   {
     /* child download, find appropriate search result from parent! */
     GtkTreePath *path;
@@ -3166,9 +3150,13 @@
   {
     /* Stand-alone download with no 'row'/search result affiliated
        with the download so far; create a fresh entry for this
-       download in the URI tab */
-    de->sr = GNUNET_GTK_add_to_uri_tab (anonymity,
-                                       meta, uri);
+       download */
+    de->sr = GNUNET_GTK_add_search_result (NULL,
+                                           anonymity,
+                                           NULL,
+                                           uri,
+                                           meta,
+                                           NULL, 0);
     GNUNET_FS_probe_stop (de->sr->probe);
     de->sr->probe = NULL;
     GNUNET_CONTAINER_DLL_remove (pl_head,
@@ -3176,7 +3164,9 @@
                                  de->sr);
     de->sr->download = de;
     path = gtk_tree_row_reference_get_path (de->sr->rr);
-    if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 
path))
+    tm = gtk_tree_row_reference_get_model (de->sr->rr);
+    if (! gtk_tree_model_get_iter (tm,
+                                   &iter, path))
     {
       GNUNET_break (0);
       gtk_tree_path_free (path);
@@ -3189,19 +3179,22 @@
 
    /* get metadata from existing tab, might have a mime type */
     path = gtk_tree_row_reference_get_path (de->sr->rr);
-    if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 
path))
+    tm = gtk_tree_row_reference_get_model (de->sr->rr);
+    if (! gtk_tree_model_get_iter (tm, &iter, path))
     {
       GNUNET_break (0);
       gtk_tree_path_free (path);
       return de;
     }
-    gtk_tree_model_get (GTK_TREE_MODEL (de->sr->tab->ts), &iter,
+    gtk_tree_model_get (tm, &iter,
                         SEARCH_TAB_MC_METADATA, &meta,
                         -1);
     de->is_directory = GNUNET_FS_meta_data_test_for_directory (meta);
   }
+  if (NULL == de->rr)
+    setup_download_list_entry (de, pde, de->sr);
   gtk_tree_path_free (path);
-  gtk_tree_store_set (de->sr->tab->ts, &iter,
+  gtk_tree_store_set (GTK_TREE_STORE (tm), &iter,
                       SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? 
(100 * completed / size) : 100),
                       SEARCH_TAB_MC_FILENAME, filename,
                       SEARCH_TAB_MC_STATUS_COLOUR, "blue",
@@ -3211,6 +3204,18 @@
                       SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, de->anonymity,
                      SEARCH_TAB_MC_STATUS_ICON, 
GNUNET_GTK_animation_context_get_pixbuf (animation_download_stalled),
                       -1);
+  /* also update downloads tab */
+  get_download_list_entry (de, &iter);
+  gtk_tree_store_set (downloads_treestore, &iter,
+                      SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? 
(100 * completed / size) : 100),
+                      SEARCH_TAB_MC_FILENAME, filename,
+                      SEARCH_TAB_MC_STATUS_COLOUR, "blue",
+                      SEARCH_TAB_MC_SEARCH_RESULT, de->sr,
+                      SEARCH_TAB_MC_COMPLETED, (guint64) completed,
+                      SEARCH_TAB_MC_DOWNLOADED_FILENAME, de->filename,
+                      SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, de->anonymity,
+                     SEARCH_TAB_MC_STATUS_ICON, 
GNUNET_GTK_animation_context_get_pixbuf (animation_download_stalled),
+                      -1);
   return de;
 }
 
@@ -3404,7 +3409,7 @@
   (void) gtk_tree_store_remove (pe->tab->ts, &iter);
   gtk_tree_path_free (path);
   gtk_tree_row_reference_free (pe->rr);
-  if (pe->uri != NULL)
+  if (NULL != pe->uri)
   {
     GNUNET_FS_uri_destroy (pe->uri);
     pe->uri = NULL;
@@ -3572,7 +3577,6 @@
    */
   GtkTreeRowReference *rr;
 
-
   /**
    * Publishing entry at the respective row.
    */

Modified: gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.h
===================================================================
--- gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.h     2014-02-03 20:35:37 UTC 
(rev 32172)
+++ gnunet-gtk/src/fs/gnunet-fs-gtk_event-handler.h     2014-02-03 21:07:23 UTC 
(rev 32173)
@@ -141,6 +141,12 @@
   struct SearchResult *sr;
 
   /**
+   * Where in the download tab is this result?  References the
+   * #downloads_treestore.
+   */
+  GtkTreeRowReference *rr;
+
+  /**
    * FS handle to control the download, NULL if the download
    * has not yet started.
    */
@@ -240,8 +246,14 @@
  */
 extern struct SearchResult *pl_tail;
 
+/**
+ * The "GNUNET_GTK_file_sharing_downloads_tree_store" with the
+ * information about active (or completed) downloads.
+ */
+extern GtkTreeStore *downloads_treestore;
 
 
+
 /**
  * Setup a new top-level entry in the URI/orphan tab.  If necessary, create
  * the URI tab first.




reply via email to

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