/*
     This file is part of GNUnet.
     Copyright (C) 2010, 2011, 2012 GNUnet e.V.

     GNUnet is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 3, or (at your
     option) any later version.

     GNUnet is distributed in the hope that it will be useful, but
     WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with GNUnet; see the file COPYING.  If not, write to the
     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     Boston, MA 02110-1301, USA.
*/

/**
 * @file src/fs/gnunet-fs-gtk_main-window-meta-data-context-menu.c
 * @brief context menu for the 'meta data' tree view in the main window
 * @author Christian Grothoff
 */
#include "gnunet-fs-gtk.h"
#include "gnunet-fs-gtk_download-save-as.h"
#include "gnunet-fs-gtk_event-handler.h"
#include <string.h>


/**
 * Helper function of GNUNET_GTK_FS_metadata_copy_selection_activated
 * which copies the (selected) entries from the tree view to the
 * GList.
 *
 * @param model the tree model with the data
 * @param path unused
 * @param iter position in the model to access
 * @param user_data 'GList**' where we should store the types and values found
 */
static void
copy_metadata_to_clipboard (GtkTreeModel *model,
                            GtkTreePath *path,
                            GtkTreeIter *iter,
                            gpointer user_data)
{
  GList **l = user_data;
  gchar *type;
  gchar *value;

  gtk_tree_model_get (model,
                      iter,
                      GNUNET_GTK_FS_MAIN_WINDOW_META_DATA_MC_META_TYPE_STRING,
                      &type,
                      GNUNET_GTK_FS_MAIN_WINDOW_META_DATA_MC_META_VALUE,
                      &value,
                      -1);
  *l = g_list_prepend (*l, type);
  *l = g_list_prepend (*l, value);
}


/**
 * User activated metadata pop up menu "Copy selection" entry.
 *
 * @param menuitem the 'copy selection' menu item
 * @param user_data the GtkBuilder of the main window
 */
void
GNUNET_GTK_FS_metadata_copy_selection_activated (GtkMenuItem *menuitem,
                                                 gpointer user_data)
{
  struct GNUNET_GTK_MainWindowContext *main_ctx = user_data;
  GtkTreeView *tree;
  GtkClipboard *cb;
  GList *pairs;
  GList *pos;
  GList *value;
  GList *type;
  guint total_len;
  gchar *s;
  gchar *p;

  tree = main_ctx->md_treeview;
  pairs = NULL;
  gtk_tree_selection_selected_foreach (gtk_tree_view_get_selection (tree),
                                       &copy_metadata_to_clipboard,
                                       &pairs);
  if (NULL == pairs)
    return; /* nothing selected */
  total_len = 0;
  pairs = g_list_reverse (pairs);
  for (pos = pairs; NULL != pos; pos = value->next)
  {
    type = pos;
    value = pos->next;
    GNUNET_assert (NULL != value);
    total_len += strlen ((gchar *) type->data) +
                 strlen ((gchar *) value->data) + 2 /* ": " */ +
                 ((NULL != value->next) ? 1 : 0) /* "\n" */;
  }
  GNUNET_assert (total_len > 0);
  total_len++; /* "\0" */
  s = g_new0 (gchar, total_len);
  if (NULL == s)
  {
    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc");
    return;
  }
  p = s;
  for (pos = pairs; NULL != pos; pos = value->next)
  {
    type = pos;
    value = pos->next;
    GNUNET_assert (NULL != value);
    p = g_stpcpy (p, (gchar *) type->data);
    p = g_stpcpy (p, ": ");
    p = g_stpcpy (p, (gchar *) value->data);
    if (NULL != value->next)
      p = g_stpcpy (p, "\n");
  }
  g_list_foreach (pairs, (GFunc) &g_free, NULL);
  g_list_free (pairs);
  cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
  gtk_clipboard_set_text (cb, s, -1);
  gtk_clipboard_store (cb);
  g_free (s);
}


/**
 * Got a button press event on the metadata treeview in the main window.
 * If it was a right click, pop up the context menu.
 *
 * @param widget the tree view widget
 * @param event the button press event
 * @param user_data the gtk builder of the main window
 */
gboolean
GNUNET_GTK_main_window_metadata_treeview_button_press_event_cb (
  GtkWidget *widget,
  GdkEvent *event,
  gpointer user_data)
{
  struct GNUNET_GTK_MainWindowContext *main_ctx = user_data;
  GdkEventButton *event_button = (GdkEventButton *) event;
  GtkMenu *menu;

  /* Ignore double-clicks and triple-clicks */
  if ((event_button->button != 3) || (event_button->type != GDK_BUTTON_PRESS))
    return FALSE;
  menu = GTK_MENU (
    gtk_builder_get_object (main_ctx->builder, "metadata_popup_menu"));
  if (NULL == menu)
    return FALSE;
  gtk_menu_popup_at_pointer (menu, event);
  return FALSE;
}


/**
 * Metadata treeview in the main window got the 'popup-menu' signal.
 * Pop up the menu.
 *
 * @param widget the tree view widget
 * @param user_data the gtk builder of the main window
 * @return TRUE we did it
 */
gboolean
GNUNET_GTK_main_window_metadata_treeview_popup_menu_cb (GtkWidget *widget,
                                                        gpointer user_data)
{
  struct GNUNET_GTK_MainWindowContext *main_ctx = user_data;
  GtkMenu *menu;

  menu = GTK_MENU (
    gtk_builder_get_object (main_ctx->builder, "metadata_popup_menu"));
  if (NULL == menu)
    return FALSE;
  gtk_menu_popup_at_widget (menu,
                            widget,
                            GDK_GRAVITY_CENTER,
                            GDK_GRAVITY_CENTER,
                            NULL);
  return TRUE;
}

/* end of gnunet-fs-gtk_meta-data-context-menu.c */
