int
get_property_page (ThunarxProviderFactory* f,
		   GList *flist,
		   const char *class_name,
		   GtkWidget **pp,
		   char *title,
		   int tlen,
		   GtkWindow *win)
{
  GList *ps, *lp;

  ps = thunarx_provider_factory_list_providers(f, THUNARX_TYPE_PROPERTY_PAGE_PROVIDER);

  *pp = NULL;
  for (lp = ps; lp != NULL; lp = lp->next) {
    GList *pgs, *lpg;

    pgs = thunarx_property_page_provider_get_pages(lp->data, flist);
    for (lpg = pgs; lpg != NULL && *pp == NULL; lpg = lpg->next) {
      if (strncmp(class_name, G_OBJECT_TYPE_NAME(lpg->data), 256) == 0) {
	*pp = GTK_WIDGET(g_object_ref(lpg->data));
      }
    }

    g_list_foreach (pgs, (GFunc) g_object_ref_sink, NULL);
    g_list_foreach (pgs, (GFunc) g_object_unref, NULL);
    g_list_free (pgs);
  }

  g_list_foreach (ps, (GFunc) g_object_unref, NULL);
  g_list_free (ps);

  if (*pp != NULL)
    {
      if (g_list_length(flist) == 1)
	{
	  snprintf(title,
		   tlen,
		   "%s: %s",
		   gtk_label_get_text(GTK_LABEL(thunarx_property_page_get_label_widget(THUNARX_PROPERTY_PAGE(*pp)))),
		   thunarx_file_info_get_name(THUNARX_FILE_INFO(flist->data)));
      }
    else
      {
	snprintf(title,
		 tlen,
		 "%s",
		 gtk_label_get_text(GTK_LABEL(thunarx_property_page_get_label_widget(THUNARX_PROPERTY_PAGE(*pp)))));
      }

      /* Try to adjust some buttons to close the window on click */
      gtk_container_foreach (*pp, adjust_destroy, win);
    }

  return *pp != NULL;
}
int
get_actions_page (ThunarxProviderFactory* f,
		  GList *flist,
		  gboolean dirs_as_files,
		  GtkWindow *win,
		  const char *class_name,
		  GtkWidget **page,
		  char *title,
		  int tlen)
{
  GList *ps, *lp, *files, *dirs, *fas, *das, *as;
  GtkWidget *vbox;

  files = NULL;
  dirs = NULL;

  if (! dirs_as_files)
    {
      for (flist; flist != NULL; flist = flist->next)
	{
	  if (thunarx_file_info_is_directory(THUNARX_FILE_INFO(flist->data)))
	    {
	      dirs = g_list_append(dirs, flist->data);
	    }
	  else
	    {
	      files = g_list_append(files, flist->data);
	    }
	}
    }
  else
    {
      files = flist;
    }

  ps = thunarx_provider_factory_list_providers(f, THUNARX_TYPE_MENU_PROVIDER);

  snprintf(title, tlen, "Choose an action for the %i selected object(s)\n",
	   g_list_length(files) + g_list_length(dirs));
  
  *page = gtk_frame_new (title);
  gtk_container_set_border_width (GTK_CONTAINER(*page), 10);
  vbox = gtk_vbox_new(TRUE, 10);
  gtk_container_set_border_width (GTK_CONTAINER(vbox), 10);
  gtk_container_add(GTK_CONTAINER(*page), GTK_WIDGET(vbox));

  fas = NULL;
  das = NULL;
  for (lp = ps; lp != NULL; lp = lp->next)
    {
      GList *dp, *as;
      if (strncmp(class_name, G_OBJECT_TYPE_NAME(lp->data), 256) == 0) {
	as = thunarx_menu_provider_get_file_actions(lp->data,
						    GTK_WIDGET(win),
						    files);
	fas = g_list_merge(fas, as);
	for (dp = dirs; dp != NULL; dp = dp->next)
	  {
	    GList *as;
	    as = thunarx_menu_provider_get_folder_actions(lp->data,
							  GTK_WIDGET(win),
							  dp->data);
	    das = g_list_merge(das, as);
	    g_list_foreach (as, (GFunc) g_object_unref, NULL);
	    g_list_free (as);
	  }
	g_list_foreach (as, (GFunc) g_object_unref, NULL);
	g_list_free (as);
      }
    }

  g_list_foreach (ps, (GFunc) g_object_unref, NULL);
  g_list_free (ps);

  fas = g_list_merge(fas, das);
  g_list_foreach (das, (GFunc) g_object_unref, NULL);
  g_list_free (das);
  
  if (g_list_length(fas) > 0)
    {
      GList *ap;

      for (ap = fas; ap != NULL; ap = ap->next)
	{
	  GtkWidget *b;

	  b = gtk_button_new ();
	  gtk_action_connect_proxy (GTK_ACTION(ap->data), b);
	  gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(b));
	  g_signal_connect_object (G_OBJECT(b),
				   "clicked",
				   G_CALLBACK(gtk_widget_destroy),
				   win,
				   G_CONNECT_AFTER | G_CONNECT_SWAPPED);
	}
      return 1;
    }
  else
    {
      gtk_container_add(GTK_CONTAINER(vbox), gtk_label_new ("No actions available"));
      return 1;
    }
}
示例#3
0
/**
 * thunar_dnd_ask:
 * @widget    : the widget on which the drop was performed.
 * @folder    : the #ThunarFile to which the @path_list is being dropped.
 * @path_list : the #GFile<!---->s of the files being dropped to @file.
 * @timestamp : the time of the drop event.
 * @actions   : the list of actions supported for the drop.
 *
 * Pops up a menu that asks the user to choose one of the
 * @actions or to cancel the drop. If the user chooses a
 * valid #GdkDragAction from @actions, then this action is
 * returned. Else if the user cancels the drop, 0 will be
 * returned.
 *
 * This method can be used to implement a response to the
 * #GDK_ACTION_ASK action on drops.
 *
 * Return value: the selected #GdkDragAction or 0 to cancel.
 **/
GdkDragAction
thunar_dnd_ask (GtkWidget    *widget,
                ThunarFile   *folder,
                GList        *path_list,
                guint         timestamp,
                GdkDragAction dnd_actions)
{
  static const GdkDragAction dnd_action_items[] = { GDK_ACTION_COPY, GDK_ACTION_MOVE, GDK_ACTION_LINK };
  static const gchar        *dnd_action_names[] = { N_ ("_Copy here"), N_ ("_Move here"), N_ ("_Link here") };
  static const gchar        *dnd_action_icons[] = { "stock_folder-copy", "stock_folder-move", NULL };

  ThunarxProviderFactory *factory;
  GdkDragAction           dnd_action = 0;
  ThunarFile             *file;
  GtkWidget              *window;
  GtkWidget              *image;
  GtkWidget              *menu;
  GtkWidget              *item;
  GList                  *file_list = NULL;
  GList                  *providers = NULL;
  GList                  *actions = NULL;
  GList                  *lp;
  guint                   n;

  _thunar_return_val_if_fail (thunar_file_is_directory (folder), 0);
  _thunar_return_val_if_fail (GTK_IS_WIDGET (widget), 0);

  /* connect to the provider factory */
  factory = thunarx_provider_factory_get_default ();

  /* prepare the popup menu */
  menu = gtk_menu_new ();

  /* append the various items */
  for (n = 0; n < G_N_ELEMENTS (dnd_action_items); ++n)
    if (G_LIKELY ((dnd_actions & dnd_action_items[n]) != 0))
      {
        item = gtk_image_menu_item_new_with_mnemonic (_(dnd_action_names[n]));
        g_object_set_data (G_OBJECT (item), I_("dnd-action"), GUINT_TO_POINTER (dnd_action_items[n]));
        g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (dnd_action_selected), &dnd_action);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
        gtk_widget_show (item);

        /* add image to the menu item */
        if (G_LIKELY (dnd_action_icons[n] != NULL))
          {
            image = gtk_image_new_from_icon_name (dnd_action_icons[n], GTK_ICON_SIZE_MENU);
            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
          }
      }

  /* append the separator */
  item = gtk_separator_menu_item_new ();
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  gtk_widget_show (item);

  /* determine the toplevel window the widget belongs to */
  window = gtk_widget_get_toplevel (widget);
  if (G_LIKELY (window != NULL && gtk_widget_get_toplevel (window)))
    {
      /* check if we can resolve all paths */
      for (lp = path_list; lp != NULL; lp = lp->next)
        {
          /* try to resolve this path */
          file = thunar_file_cache_lookup (lp->data);
          if (G_LIKELY (file != NULL))
            file_list = g_list_prepend (file_list, file);
          else
            break;
        }

      /* check if we resolved all paths (and have atleast one file) */
      if (G_LIKELY (file_list != NULL && lp == NULL))
        {
          /* load the menu providers from the provider factory */
          providers = thunarx_provider_factory_list_providers (factory, THUNARX_TYPE_MENU_PROVIDER);

          /* load the dnd actions offered by the menu providers */
          for (lp = providers; lp != NULL; lp = lp->next)
            {
              /* merge the actions from this provider */
              actions = g_list_concat (actions, thunarx_menu_provider_get_dnd_actions (lp->data, window, THUNARX_FILE_INFO (folder), file_list));
              g_object_unref (G_OBJECT (lp->data));
            }
          g_list_free (providers);

          /* check if we have atleast one action */
          if (G_UNLIKELY (actions != NULL))
            {
              /* add menu items for all actions */
              for (lp = actions; lp != NULL; lp = lp->next)
                {
                  /* add a menu item for the action */
                  item = gtk_action_create_menu_item (lp->data);
                  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
                  g_object_unref (G_OBJECT (lp->data));
                  gtk_widget_show (item);
                }
              g_list_free (actions);

              /* append another separator */
              item = gtk_separator_menu_item_new ();
              gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
              gtk_widget_show (item);
            }
        }
    }

  /* append the cancel item */
  item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CANCEL, NULL);
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  gtk_widget_show (item);

  /* run the menu on the widget's screen (takes over the floating reference of menu) */
  thunar_gtk_menu_run (GTK_MENU (menu), widget, NULL, NULL, 3, timestamp);

  /* cleanup */
  g_object_unref (G_OBJECT (factory));
  g_list_free_full (file_list, g_object_unref);

  return dnd_action;
}