static void
poll_with_variant (GPid pid,
                   GVariant *info,
                   GError *error,
                   gpointer user_data)
{
    StoragedLinuxVolumeGroupObject *object = user_data;
    StoragedDaemon *daemon;
    GVariantIter *iter;
    gboolean needs_polling;

    if (pid != object->poll_pid)
    {
        g_object_unref (object);
        return;
    }

    object->poll_pid = 0;

    if (error)
    {
        storaged_warning ("Failed to poll LVM volume group %s: %s",
                          storaged_linux_volume_group_object_get_name (object),
                          error->message);
        g_object_unref (object);
        return;
    }

    daemon = storaged_linux_volume_group_object_get_daemon (object);

    storaged_linux_volume_group_update (STORAGED_LINUX_VOLUME_GROUP (object->iface_volume_group), info, &needs_polling);

    if (g_variant_lookup (info, "lvs", "aa{sv}", &iter))
    {
        GVariant *lv_info = NULL;
        while (g_variant_iter_loop (iter, "@a{sv}", &lv_info))
        {
            const gchar *name;
            StoragedLinuxLogicalVolumeObject *volume;

            g_variant_lookup (lv_info, "name", "&s", &name);
            update_operations (daemon, name, lv_info, &needs_polling);
            volume = g_hash_table_lookup (object->logical_volumes, name);
            if (volume)
                storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling);
        }
        g_variant_iter_free (iter);
    }

    g_object_unref (object);
}
static gboolean
on_remove_finished_operations_timeout (NautilusToolbar *self)
{
        nautilus_progress_info_manager_remove_finished_or_cancelled_infos (self->priv->progress_manager);
        if (should_hide_operations_button (self)) {
                gtk_revealer_set_reveal_child (GTK_REVEALER (self->priv->operations_revealer),
                                               FALSE);
        } else {
                update_operations (self);
        }

        self->priv->remove_finished_operations_timeout_id = 0;

        return G_SOURCE_REMOVE;
}
static gboolean
on_progress_info_started_timeout (NautilusToolbar *self)
{
        update_operations (self);

        /* In case we didn't show the operations button because the operation total
         * time stimation is not good enough, update again to make sure we don't miss
         * a long time operation because of that */
        if (!nautilus_progress_manager_are_all_infos_finished_or_cancelled (self->priv->progress_manager)) {
                return G_SOURCE_CONTINUE;
        } else {
                self->priv->start_operations_timeout_id = 0;
                return G_SOURCE_REMOVE;
        }
}
Esempio n. 4
0
static void
poll_with_variant (GPid pid,
                   GVariant *info,
                   GError *error,
                   gpointer user_data)
{
  StorageVolumeGroup *self = user_data;
  GVariantIter *iter;
  gboolean needs_polling;

  if (pid != self->poll_pid)
    {
      g_object_unref (self);
      return;
    }

  self->poll_pid = 0;

  if (error)
    {
      g_message ("Failed to poll LVM volume group %s: %s",
                 storage_volume_group_get_name (self), error->message);
      g_object_unref (self);
      return;
    }

  volume_group_update_props (self, info, &needs_polling);

  if (g_variant_lookup (info, "lvs", "aa{sv}", &iter))
    {
      GVariant *lv_info = NULL;
      while (g_variant_iter_loop (iter, "@a{sv}", &lv_info))
        {
          const gchar *name;
          StorageLogicalVolume *volume;

          g_variant_lookup (lv_info, "name", "&s", &name);
          update_operations (name, lv_info, &needs_polling);
          volume = g_hash_table_lookup (self->logical_volumes, name);
          if (volume)
            storage_logical_volume_update (volume, self, lv_info, &needs_polling);
        }
      g_variant_iter_free (iter);
    }

  g_object_unref (self);
}
static gboolean
on_progress_info_started_timeout (NautilusToolbar *self)
{
        GList *progress_infos;
        GList *filtered_progress_infos;

        update_operations (self);

        /* In case we didn't show the operations button because the operation total
         * time stimation is not good enough, update again to make sure we don't miss
         * a long time operation because of that */

        progress_infos = nautilus_progress_info_manager_get_all_infos (self->priv->progress_manager);
        filtered_progress_infos = get_filtered_progress_infos (self);
        if (!nautilus_progress_manager_are_all_infos_finished_or_cancelled (self->priv->progress_manager) &&
            g_list_length (progress_infos) != g_list_length (filtered_progress_infos)) {
                g_list_free (filtered_progress_infos);
                return G_SOURCE_CONTINUE;
        } else {
                g_list_free (filtered_progress_infos);
                self->priv->start_operations_timeout_id = 0;
                return G_SOURCE_REMOVE;
        }
}
static void
update_with_variant (GPid pid,
                     GVariant *info,
                     GError *error,
                     gpointer user_data)
{
    StoragedLinuxVolumeGroupObject *object = user_data;
    StoragedDaemon *daemon;
    GDBusObjectManagerServer *manager;
    GVariantIter *iter;
    GHashTableIter volume_iter;
    gpointer key, value;
    GHashTable *new_lvs;
    GHashTable *new_pvs;
    GList *objects, *l;
    gboolean needs_polling = FALSE;

    daemon = storaged_linux_volume_group_object_get_daemon (object);
    manager = storaged_daemon_get_object_manager (daemon);

    if (error)
    {
        storaged_warning ("Failed to update LVM volume group %s: %s",
                          storaged_linux_volume_group_object_get_name (object),
                          error->message);
        g_object_unref (object);
        return;
    }

    storaged_linux_volume_group_update (STORAGED_LINUX_VOLUME_GROUP (object->iface_volume_group), info, &needs_polling);

    if (!g_dbus_object_manager_server_is_exported (manager, G_DBUS_OBJECT_SKELETON (object)))
        g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (object));

    new_lvs = g_hash_table_new (g_str_hash, g_str_equal);

    if (g_variant_lookup (info, "lvs", "aa{sv}", &iter))
    {
        GVariant *lv_info = NULL;
        while (g_variant_iter_loop (iter, "@a{sv}", &lv_info))
        {
            const gchar *name;
            StoragedLinuxLogicalVolumeObject *volume;

            g_variant_lookup (lv_info, "name", "&s", &name);

            update_operations (daemon, name, lv_info, &needs_polling);

            if (lv_is_pvmove_volume (name))
                needs_polling = TRUE;

            if (storaged_daemon_util_lvm2_name_is_reserved (name))
                continue;

            volume = g_hash_table_lookup (object->logical_volumes, name);
            if (volume == NULL)
            {
                volume = storaged_linux_logical_volume_object_new (daemon, object, name);
                storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling);
                storaged_linux_logical_volume_object_update_etctabs (volume);
                g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (volume));
                g_hash_table_insert (object->logical_volumes, g_strdup (name), g_object_ref (volume));
            }
            else
                storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling);

            g_hash_table_insert (new_lvs, (gchar *)name, volume);
        }
        g_variant_iter_free (iter);
    }

    g_hash_table_iter_init (&volume_iter, object->logical_volumes);
    while (g_hash_table_iter_next (&volume_iter, &key, &value))
    {
        const gchar *name = key;
        StoragedLinuxLogicalVolumeObject *volume = value;

        if (!g_hash_table_contains (new_lvs, name))
        {
            g_dbus_object_manager_server_unexport (manager,
                                                   g_dbus_object_get_object_path (G_DBUS_OBJECT (volume)));
            g_hash_table_iter_remove (&volume_iter);

            g_object_unref (G_OBJECT (volume));
        }
    }

    storaged_volume_group_set_needs_polling (STORAGED_VOLUME_GROUP (object->iface_volume_group),
            needs_polling);

    /* Update block objects. */

    new_pvs = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_variant_unref);
    if (g_variant_lookup (info, "pvs", "aa{sv}", &iter))
    {
        const gchar *name;
        GVariant *pv_info;
        while (g_variant_iter_next (iter, "@a{sv}", &pv_info))
        {
            if (g_variant_lookup (pv_info, "device", "&s", &name))
                g_hash_table_insert (new_pvs, (gchar *)name, pv_info);
            else
                g_variant_unref (pv_info);
        }
    }

    objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager));
    for (l = objects; l != NULL; l = l->next)
    {
        if (STORAGED_IS_LINUX_BLOCK_OBJECT (l->data))
            update_block (STORAGED_LINUX_BLOCK_OBJECT (l->data), object, new_lvs, new_pvs);
    }
    g_list_free_full (objects, g_object_unref);

    g_hash_table_destroy (new_lvs);
    g_hash_table_destroy (new_pvs);

    g_object_unref (object);
}
Esempio n. 7
0
static void
update_with_variant (GPid pid,
                     GVariant *info,
                     GError *error,
                     gpointer user_data)
{
  struct UpdateData *data = user_data;
  StorageVolumeGroup *self = data->self;
  GVariantIter *iter;
  GHashTableIter volume_iter;
  gpointer key, value;
  GHashTable *new_lvs;
  gboolean needs_polling = FALSE;
  StorageDaemon *daemon;
  gchar *path;

  daemon = storage_daemon_get ();

  if (!error)
      volume_group_update_props (self, info, &needs_polling);

  /* After basic props, publish group, if not already done */
  if (self->need_publish)
    {
      self->need_publish = FALSE;
      path = storage_util_build_object_path ("/org/freedesktop/UDisks2/lvm",
                                        storage_volume_group_get_name (self), NULL);
      storage_daemon_publish (daemon, path, FALSE, self);
      g_free (path);
    }

  if (error)
    {
      g_message ("Failed to update LVM volume group %s: %s",
                 storage_volume_group_get_name (self), error->message);
      g_object_unref (self);
      return;
    }

  if (self->info && g_variant_equal (self->info, info))
    {
      g_debug ("%s updated without changes", self->name);
      g_object_unref (self);
      return;
    }

  if (self->info)
    g_variant_unref (self->info);
  self->info = g_variant_ref (info);

  new_lvs = g_hash_table_new (g_str_hash, g_str_equal);

  if (g_variant_lookup (info, "lvs", "aa{sv}", &iter))
    {
      GVariant *lv_info = NULL;
      while (g_variant_iter_loop (iter, "@a{sv}", &lv_info))
        {
          const gchar *name;
          StorageLogicalVolume *volume;

          g_variant_lookup (lv_info, "name", "&s", &name);

          update_operations (name, lv_info, &needs_polling);

          if (lv_is_pvmove_volume (name))
            needs_polling = TRUE;

          if (!lv_is_visible (name))
            continue;

          volume = g_hash_table_lookup (self->logical_volumes, name);
          if (volume == NULL)
            {
              volume = storage_logical_volume_new (self, name);
              storage_logical_volume_update (volume, self, lv_info, &needs_polling);

              g_hash_table_insert (self->logical_volumes, g_strdup (name), g_object_ref (volume));
            }
          else
            storage_logical_volume_update (volume, self, lv_info, &needs_polling);

          g_hash_table_insert (new_lvs, (gchar *)name, volume);
        }
      g_variant_iter_free (iter);
    }

  g_hash_table_iter_init (&volume_iter, self->logical_volumes);
  while (g_hash_table_iter_next (&volume_iter, &key, &value))
    {
      const gchar *name = key;
      StorageLogicalVolume *volume = value;

      if (!g_hash_table_contains (new_lvs, name))
        {
          /* Volume unpublishes itself */
          g_object_run_dispose (G_OBJECT (volume));
          g_hash_table_iter_remove (&volume_iter);
        }
    }

  lvm_volume_group_set_needs_polling (LVM_VOLUME_GROUP (self), needs_polling);

  /* Update physical volumes. */

  g_hash_table_remove_all (self->physical_volumes);

  if (g_variant_lookup (info, "pvs", "aa{sv}", &iter))
    {
      const gchar *name;
      GVariant *pv_info;
      while (g_variant_iter_next (iter, "@a{sv}", &pv_info))
        {
          if (g_variant_lookup (pv_info, "device", "&s", &name))
            g_hash_table_insert (self->physical_volumes, g_strdup (name), pv_info);
          else
            g_variant_unref (pv_info);
        }
    }

  /* Make sure above is published before updating blocks to point at volume group */
  update_all_blocks (self);

  if (data->done)
    data->done (self, data->done_user_data);

  g_hash_table_destroy (new_lvs);
  g_object_unref (self);
  g_free (data);
}
static void
on_operations_icon_draw (GtkWidget       *widget,
                         cairo_t         *cr,
                         NautilusToolbar *self)
{
        gfloat elapsed_progress = 0;
        gint remaining_progress = 0;
        gint total_progress;
        gdouble ratio;
        GList *progress_infos;
        GList *l;
        guint width;
        guint height;
        gboolean all_cancelled;
        GdkRGBA background = {.red = 0, .green = 0, .blue = 0, .alpha = 0.2 };
        GdkRGBA foreground = {.red = 0, .green = 0, .blue = 0, .alpha = 0.7 };

        all_cancelled = TRUE;
        progress_infos = get_filtered_progress_infos (self);
        for (l = progress_infos; l != NULL; l = l->next) {
                if (!nautilus_progress_info_get_is_cancelled (l->data)) {
                        all_cancelled = FALSE;
                        remaining_progress += nautilus_progress_info_get_remaining_time (l->data);
                        elapsed_progress += nautilus_progress_info_get_elapsed_time (l->data);
                }
        }

        g_list_free (progress_infos);

        total_progress = remaining_progress + elapsed_progress;

        if (all_cancelled) {
                ratio = 1.0;
        } else {
                if (total_progress > 0) {
                        ratio = MAX (0.05, elapsed_progress / total_progress);
                } else {
                        ratio = 0.05;
                }
        }


        width = gtk_widget_get_allocated_width (widget);
        height = gtk_widget_get_allocated_height (widget);

        gdk_cairo_set_source_rgba(cr, &background);
        cairo_arc (cr,
                   width / 2.0, height / 2.0,
                   MIN (width, height) / 2.0,
                   0, 2 *G_PI);
        cairo_fill (cr);
        cairo_move_to (cr, width / 2.0, height / 2.0);
        gdk_cairo_set_source_rgba (cr, &foreground);
        cairo_arc (cr,
                   width / 2.0, height / 2.0,
                   MIN (width, height) / 2.0,
                   -G_PI / 2.0, ratio * 2 * G_PI - G_PI / 2.0);

        cairo_fill (cr);
}

static void
on_operations_button_toggled (NautilusToolbar *self)
{
        unschedule_remove_finished_operations (self);
        if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->operations_button))) {
                schedule_remove_finished_operations (self);
        } else {
                update_operations (self);
        }
}

static void
nautilus_toolbar_init (NautilusToolbar *self)
{
	GtkBuilder *builder;

	self->priv = nautilus_toolbar_get_instance_private (self);
	gtk_widget_init_template (GTK_WIDGET (self));

	self->priv->path_bar = g_object_new (NAUTILUS_TYPE_PATH_BAR, NULL);
	gtk_container_add (GTK_CONTAINER (self->priv->path_bar_container),
					  self->priv->path_bar);

	self->priv->location_entry = nautilus_location_entry_new ();
	gtk_container_add (GTK_CONTAINER (self->priv->location_entry_container),
					  self->priv->location_entry);

	builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-action-menu.xml");
	self->priv->action_menu = G_MENU (gtk_builder_get_object (builder, "action-menu"));
	gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (self->priv->action_button),
					G_MENU_MODEL (self->priv->action_menu));
	g_object_unref (builder);

        self->priv->progress_manager = nautilus_progress_info_manager_dup_singleton ();
	g_signal_connect (self->priv->progress_manager, "new-progress-info",
			  G_CALLBACK (on_new_progress_info), self);
        update_operations (self);

	g_object_set_data (G_OBJECT (self->priv->back_button), "nav-direction",
			   GUINT_TO_POINTER (NAUTILUS_NAVIGATION_DIRECTION_BACK));
	g_object_set_data (G_OBJECT (self->priv->forward_button), "nav-direction",
			   GUINT_TO_POINTER (NAUTILUS_NAVIGATION_DIRECTION_FORWARD));
	g_signal_connect (self->priv->back_button, "button-press-event",
			  G_CALLBACK (navigation_button_press_cb), self);
	g_signal_connect (self->priv->back_button, "button-release-event",
			  G_CALLBACK (navigation_button_release_cb), self);
	g_signal_connect (self->priv->forward_button, "button-press-event",
			  G_CALLBACK (navigation_button_press_cb), self);
	g_signal_connect (self->priv->forward_button, "button-release-event",
			  G_CALLBACK (navigation_button_release_cb), self);

	gtk_widget_show_all (GTK_WIDGET (self));
	toolbar_update_appearance (self);
}