Example #1
0
void
ide_workbench_remove_perspective (IdeWorkbench   *self,
                                  IdePerspective *perspective)
{
  guint n_items;
  guint i;

  g_assert (IDE_IS_WORKBENCH (self));
  g_assert (IDE_IS_PERSPECTIVE (perspective));
  g_assert (gtk_widget_get_parent (GTK_WIDGET (perspective)) ==
            GTK_WIDGET (self->perspectives_stack));

  n_items = g_list_model_get_n_items (G_LIST_MODEL (self->perspectives));

  for (i = 0; i < n_items; i++)
    {
      g_autoptr(IdePerspective) item = NULL;

      item = g_list_model_get_item (G_LIST_MODEL (self->perspectives), i);

      if (item == perspective)
        {
          g_list_store_remove (self->perspectives, i);
          break;
        }
    }

  gtk_container_remove (GTK_CONTAINER (self->perspectives_stack),
                        GTK_WIDGET (perspective));
}
Example #2
0
static void
ide_frame_page_added (IdeFrame *self,
                      IdePage  *page)
{
  IdeFramePrivate *priv = ide_frame_get_instance_private (self);
  guint position;

  g_assert (IDE_IS_FRAME (self));
  g_assert (IDE_IS_PAGE (page));

  /*
   * Make sure that the header has dismissed all of the popovers immediately.
   * We don't want them lingering while we do other UI work which might want to
   * grab focus, etc.
   */
  _ide_frame_header_popdown (priv->header);

  /* Notify GListModel consumers of the new page and it's position within
   * our stack of page widgets.
   */
  position = priv->pages->len;
  g_ptr_array_add (priv->pages, page);
  g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);

  /*
   * Now ensure that the page is displayed and focus the widget so the
   * user can immediately start typing.
   */
  ide_frame_set_visible_child (self, page);
  gtk_widget_grab_focus (GTK_WIDGET (page));
}
Example #3
0
/**
 * gstyle_palette_remove_at_index:
 * @self: a #GstylePalette
 * @position: A position to remove the #GstyleColor from
 *
 * Try to remove the #GstyleColor at @position from the palette
 *
 * Returns: %TRUE on succes, %FALSE otherwise.
 */
gboolean
gstyle_palette_remove_at_index (GstylePalette  *self,
                                gint            position)
{
  GstyleColor *color;

  g_return_val_if_fail (GSTYLE_IS_PALETTE (self), FALSE);

  if (0 <= position && position < self->colors->len)
    {
      color = GSTYLE_COLOR (g_ptr_array_index (self->colors, position));
      remove_color_to_names_sets (self, color);
      g_ptr_array_remove_index (self->colors, position);
      g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
      gstyle_palette_set_changed (self, TRUE);

      return TRUE;
    }
  else
    {
      g_warning ("Trying to remove a Color in palette '%s' at out-of-bounds position %i in (0, %i)\n",
                 gstyle_palette_get_name (self),
                 position, self->colors->len - 1);

      return FALSE;
     }
}
Example #4
0
/**
 * gstyle_palette_remove:
 * @self: a #GstylePalette
 * @color: A #GstyleColor
 *
 * Try to remove a #GstyleColor from the palette.
 *
 * Returns: %TRUE on succes, %FALSE otherwise.
 */
gboolean
gstyle_palette_remove (GstylePalette  *self,
                       GstyleColor    *color)
{
  GPtrArray *array;

  g_return_val_if_fail (GSTYLE_IS_PALETTE (self), FALSE);
  g_return_val_if_fail (GSTYLE_IS_COLOR (color), FALSE);

  array = self->colors;
  for (gint i = 0; i < array->len; ++i)
    {
      if (array->pdata[i] == color)
        {
          remove_color_to_names_sets (self, color);
          g_ptr_array_remove_index (array, i);
          g_list_model_items_changed (G_LIST_MODEL (self), i, 1, 0);
          gstyle_palette_set_changed (self, TRUE);

          return TRUE;
        }
    }

  return FALSE;
}
Example #5
0
static void
ide_frame_destroy (GtkWidget *widget)
{
  IdeFrame *self = (IdeFrame *)widget;
  IdeFramePrivate *priv = ide_frame_get_instance_private (self);

  g_assert (IDE_IS_FRAME (self));

  g_clear_object (&priv->addins);

  g_clear_pointer (&priv->in_transition, g_ptr_array_unref);

  if (priv->pages != NULL)
    {
      g_list_model_items_changed (G_LIST_MODEL (self), 0, priv->pages->len, 0);
      g_clear_pointer (&priv->pages, g_ptr_array_unref);
    }

  if (priv->bindings != NULL)
    {
      dzl_binding_group_set_source (priv->bindings, NULL);
      g_clear_object (&priv->bindings);
    }

  if (priv->signals != NULL)
    {
      dzl_signal_group_set_target (priv->signals, NULL);
      g_clear_object (&priv->signals);
    }

  g_clear_object (&priv->pan);

  GTK_WIDGET_CLASS (ide_frame_parent_class)->destroy (widget);
}
static void
ide_recent_projects_added (IdeRecentProjects *self,
                           IdeProjectInfo    *project_info)
{
  g_autofree gchar *uri = NULL;
  GFile *file;

  g_assert (IDE_IS_RECENT_PROJECTS (self));
  g_assert (IDE_IS_PROJECT_INFO (project_info));

  file = ide_project_info_get_file (project_info);
  uri = g_file_get_uri (file);

  if (!g_hash_table_contains (self->recent_uris, uri))
    {
      GSequenceIter *iter;
      gint position;

      iter = g_sequence_insert_sorted (self->projects,
                                       g_object_ref (project_info),
                                       (GCompareDataFunc)ide_project_info_compare,
                                       NULL);
      position = g_sequence_iter_get_position (iter);
      g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
    }
}
Example #7
0
gint
main (gint   argc,
      gchar *argv[])
{
  g_autoptr (DummyProvider) dummy_provider = NULL;
  GtdTaskModel *model = NULL;
  GtkWidget *scrolledwindow = NULL;
  GtkWindow *window = NULL;
  GtkWidget *listbox = NULL;

  g_set_prgname ("test-task-model");
  g_set_application_name ("GNOME To Do | Task Model Test");

  gtk_init ();
  gtd_log_init ();

  /* Create a DumbProvider and pre-populate it */
  dummy_provider = dummy_provider_new ();
  dummy_provider_generate_task_lists (dummy_provider);

  /* Inject a dumb fake provider */
  _gtd_manager_inject_provider (gtd_manager_get_default (), GTD_PROVIDER (dummy_provider));

  /* Now create the model - the initial providers must be there already */
  model = _gtd_task_model_new (gtd_manager_get_default ());

  /* Listbox */
  listbox = gtk_list_box_new ();
  gtk_list_box_bind_model (GTK_LIST_BOX (listbox),
                           G_LIST_MODEL (model),
                           create_task_cb,
                           NULL,
                           NULL);

  gtk_list_box_set_header_func (GTK_LIST_BOX (listbox), header_func, NULL, NULL);

  /* Scrolled window */
  scrolledwindow = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
                                 "propagate-natural-height", TRUE,
                                 "max-content-height", 600,
                                 "hscrollbar-policy", GTK_POLICY_NEVER,
                                 NULL);
  gtk_container_add (GTK_CONTAINER (scrolledwindow), listbox);

  /* Window */
  window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
  gtk_window_set_default_size (window, 800, 600);
  gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
  gtk_window_present (window);

  /* Now, generate more tasks and lists after injecting to the manager */
  dummy_provider_generate_task_lists (dummy_provider);

  /* Schedule a live removal of tasks */
  dummy_provider_schedule_remove_task (dummy_provider);

  gtk_main ();

  return 0;
}
Example #8
0
static void
on_clear_all_button_clicked (GtkButton *button,
                             gpointer   user_data)
{
  PpJobsDialog *dialog = user_data;
  guint num_items;
  guint i;

  num_items = g_list_model_get_n_items (G_LIST_MODEL (dialog->store));

  for (i = 0; i < num_items; i++)
    {
      PpJob *job = PP_JOB (g_list_model_get_item (G_LIST_MODEL (dialog->store), i));

      pp_job_cancel_purge_async (job, FALSE);
    }
}
void
egg_app_info_model_changed (GAppInfoMonitor *monitor,
                            gpointer         user_data)
{
  EggKeyedListStore *store = user_data;
  GHashTable *old_app_ids;
  GList *new_apps;
  GList *it;
  guint n_items;
  gint i;
  GHashTableIter iter;
  const gchar *id;

  old_app_ids = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
  n_items = g_list_model_get_n_items (G_LIST_MODEL (store));
  for (i = 0; i < n_items; i++)
    {
      GAppInfo *info;

      info = g_list_model_get_item (G_LIST_MODEL (store), i);
      g_hash_table_insert (old_app_ids, (gpointer) g_app_info_get_id (info), info);
    }

  new_apps = g_app_info_get_all ();
  for (it = new_apps; it; it = it->next)
    {
      GAppInfo *info = it->data;

      if (!g_app_info_should_show (info))
        continue;

      id = g_app_info_get_id (info);

      /* only add the application if we didn't have it before */
      if (!g_hash_table_remove (old_app_ids, id))
        egg_keyed_list_store_insert (store, id, info);
    }

  /* remove app ids that aren't in new_apps */
  g_hash_table_iter_init (&iter, old_app_ids);
  while (g_hash_table_iter_next (&iter, (gpointer) &id, NULL))
    egg_keyed_list_store_remove (store, id);

  g_list_free_full (new_apps, g_object_unref);
  g_hash_table_destroy (old_app_ids);
}
Example #10
0
static inline void
emit_items_changed (CbTweetModel *self,
                    guint         position,
                    guint         removed,
                    guint         added)
{
  g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
}
Example #11
0
static void
photos_base_model_refresh (PhotosBaseModel *self)
{
  g_autoptr (GMenu) section = NULL;
  const gchar *action_id;
  const gchar *title;
  guint i;
  guint n_items;

  g_menu_remove_all (self->model);

  title = photos_base_manager_get_title (self->mngr);
  action_id = photos_base_manager_get_action_id (self->mngr);

  section = g_menu_new ();
  g_menu_append_section (self->model, title, G_MENU_MODEL (section));

  n_items = g_list_model_get_n_items (G_LIST_MODEL (self->mngr));
  for (i = 0; i < n_items; i++)
    {
      g_autoptr (GMenuItem) menu_item = NULL;
      g_autoptr (GObject) object = NULL;
      const gchar *id;
      g_autofree gchar *name = NULL;

      object = g_list_model_get_object (G_LIST_MODEL (self->mngr), i);
      if (!photos_filterable_is_search_criterion (PHOTOS_FILTERABLE (object)))
        continue;

      id = photos_filterable_get_id (PHOTOS_FILTERABLE (object));
      g_object_get (object, "name", &name, NULL);

      menu_item = g_menu_item_new (name, NULL);
      g_menu_item_set_action_and_target (menu_item, action_id, "s", id);
      g_menu_append_item (section, menu_item);
    }
}
static void
bind_buffer_manager (GbpEditorWorkspaceAddin *self,
                     IdeBufferManager        *buffer_manager,
                     DzlSignalGroup          *signal_group)
{
  guint n_items;

  g_assert (GBP_IS_EDITOR_WORKSPACE_ADDIN (self));
  g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
  g_assert (DZL_IS_SIGNAL_GROUP (signal_group));

  if (self->surface == NULL)
    return;

  n_items = g_list_model_get_n_items (G_LIST_MODEL (buffer_manager));

  for (guint i = 0; i < n_items; i++)
    {
      g_autoptr(IdeBuffer) buffer = NULL;

      buffer = g_list_model_get_item (G_LIST_MODEL (buffer_manager), i);
      ide_editor_surface_focus_buffer (self->surface, buffer);
    }
}
Example #13
0
static void
photos_base_manager_objects_changed (PhotosBaseManager *self, guint position, guint removed, guint added)
{
  PhotosBaseManagerPrivate *priv;

  priv = photos_base_manager_get_instance_private (self);

  if (position <= priv->last_position)
    {
      priv->last_iter = NULL;
      priv->last_position = G_MAXUINT;
    }

  g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
}
Example #14
0
static void
animation_state_complete (gpointer data)
{
  IdeFramePrivate *priv;
  AnimationState *state = data;

  g_assert (state != NULL);
  g_assert (IDE_IS_FRAME (state->source));
  g_assert (IDE_IS_FRAME (state->dest));
  g_assert (IDE_IS_PAGE (state->page));

  /* Add the widget to the new stack */
  if (state->dest != state->source)
    {
      gtk_container_add (GTK_CONTAINER (state->dest), GTK_WIDGET (state->page));

      /* Now remove it from our temporary transition. Be careful in case we were
       * destroyed in the mean time.
       */
      priv = ide_frame_get_instance_private (state->source);

      if (priv->in_transition != NULL)
        {
          guint position = 0;

          if (g_ptr_array_find_with_equal_func (priv->pages, state->page, NULL, &position))
            {
              g_ptr_array_remove (priv->in_transition, state->page);
              g_ptr_array_remove_index (priv->pages, position);
              g_list_model_items_changed (G_LIST_MODEL (state->source), position, 1, 0);
            }
        }
    }

  /*
   * We might need to reshow the widget in cases where we are in a
   * three-finger-swipe of the page. There is also a chance that we
   * aren't the proper visible child and that needs to be restored now.
   */
  gtk_widget_show (GTK_WIDGET (state->page));
  ide_frame_set_visible_child (state->dest, state->page);

  g_clear_object (&state->source);
  g_clear_object (&state->dest);
  g_clear_object (&state->page);
  g_clear_object (&state->theatric);
  g_slice_free (AnimationState, state);
}
Example #15
0
static gboolean
gb_vim_command_bprevious (GtkWidget      *active_widget,
                          const gchar    *command,
                          const gchar    *options,
                          GError        **error)
{
  IdeFrame *frame_;

  g_assert (GTK_IS_WIDGET (active_widget));

  if ((frame_ = (IdeFrame *)gtk_widget_get_ancestor (active_widget, IDE_TYPE_FRAME)) &&
      g_list_model_get_n_items (G_LIST_MODEL (frame_)) > 0)
    dzl_gtk_widget_action (GTK_WIDGET (active_widget), "frame", "previous-page", NULL);

  return TRUE;
}
GListModel *
egg_app_info_model_new ()
{
  EggKeyedListStore *store;
  GAppInfoMonitor *monitor;

  store = egg_keyed_list_store_new (G_TYPE_APP_INFO);
  egg_keyed_list_store_set_sort_func (store, egg_compare_app_infos, NULL);

  monitor = g_app_info_monitor_get ();
  g_signal_connect (monitor, "changed", G_CALLBACK (egg_app_info_model_changed), store);
  egg_app_info_model_changed (monitor, store);

  g_object_set_data_full (G_OBJECT (store), "egg-app-info-model-monitor", monitor, g_object_unref);

  return G_LIST_MODEL (store);
}
Example #17
0
static void
ide_editor_perspective_init (IdeEditorPerspective *self)
{
  IdeEditorSidebar *sidebar;

  gtk_widget_init_template (GTK_WIDGET (self));

  _ide_editor_perspective_init_actions (self);
  _ide_editor_perspective_init_shortcuts (self);

  g_signal_connect_swapped (self->grid,
                            "notify::current-view",
                            G_CALLBACK (ide_editor_perspective_notify_current_view),
                            self);

  g_signal_connect_swapped (self->grid,
                            "create-view",
                            G_CALLBACK (ide_editor_perspective_create_view),
                            self);

  sidebar = ide_editor_perspective_get_sidebar (self);
  _ide_editor_sidebar_set_open_pages (sidebar, G_LIST_MODEL (self->grid));
}
Example #18
0
static void
ide_frame_page_removed (IdeFrame *self,
                        IdePage  *page)
{
  IdeFramePrivate *priv = ide_frame_get_instance_private (self);

  g_assert (IDE_IS_FRAME (self));
  g_assert (IDE_IS_PAGE (page));

  if (priv->pages != NULL)
    {
      guint position = 0;

      /* If this is the last page, hide the popdown now.  We use our hide
       * variant instead of popdown so that we don't have jittery animations.
       */
      if (priv->pages->len == 1)
        _ide_frame_header_hide (priv->header);

      /*
       * Only remove the page if it is not in transition. We hold onto the
       * page during the transition so that we keep the list stable.
       */
      if (!g_ptr_array_find_with_equal_func (priv->in_transition, page, NULL, &position))
        {
          for (guint i = 0; i < priv->pages->len; i++)
            {
              if ((gpointer)page == g_ptr_array_index (priv->pages, i))
                {
                  g_ptr_array_remove_index (priv->pages, i);
                  g_list_model_items_changed (G_LIST_MODEL (self), i, 1, 0);
                }
            }
        }
    }
}
Example #19
0
/**
 * gstyle_palette_add_at_index:
 * @self: a #GstylePalette
 * @color: A #GstyleColor
 * @position: Position to insert the new color, from 0 to gstyle_palette_get_len() -1,
 *   or -1 to append it
 * @error: (nullable): a #GError location or %NULL
 *
 * Add a #GstyleColor to the palette.
 *
 * Returns: %TRUE on succes, %FALSE otherwise.
 */
gboolean
gstyle_palette_add_at_index (GstylePalette  *self,
                             GstyleColor    *color,
                             gint            position,
                             GError        **error)
{
  g_return_val_if_fail (GSTYLE_IS_PALETTE (self), FALSE);
  g_return_val_if_fail (GSTYLE_IS_COLOR (color), FALSE);

  /* If we are just after the last position, we in fact do an append */
  if (position == self->colors->len)
    position = -1;

  if (position == -1 ||
      (position == 0 && self->colors->len == 0) ||
      (0 <= position && position < self->colors->len))
    {
      g_object_ref (color);
      g_ptr_array_insert (self->colors, position, color);
      add_color_to_names_sets (self, color);
      gstyle_palette_set_changed (self, TRUE);

      position = (position == -1) ? self->colors->len - 1 : position;
      g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);

      return TRUE;
    }
  else
    {
      g_warning ("Color inserted in palette '%s' at out-of-bounds position %i in (0, %i)\n",
                 gstyle_palette_get_name (self),
                 position, self->colors->len - 1);

      return FALSE;
     }
}
Example #20
0
static void
ide_frame_init (IdeFrame *self)
{
  IdeFramePrivate *priv = ide_frame_get_instance_private (self);

  gtk_widget_init_template (GTK_WIDGET (self));

  _ide_frame_init_actions (self);
  _ide_frame_init_shortcuts (self);

  priv->pages = g_ptr_array_new ();
  priv->in_transition = g_ptr_array_new_with_free_func (g_object_unref);

  priv->signals = dzl_signal_group_new (IDE_TYPE_PAGE);

  dzl_signal_group_connect_swapped (priv->signals,
                                    "notify::failed",
                                    G_CALLBACK (ide_frame_page_failed),
                                    self);

  priv->bindings = dzl_binding_group_new ();

  g_signal_connect_object (priv->bindings,
                           "notify::source",
                           G_CALLBACK (ide_frame_bindings_notify_source),
                           self,
                           G_CONNECT_SWAPPED);

  dzl_binding_group_bind (priv->bindings, "title",
                          priv->header, "title",
                          G_BINDING_SYNC_CREATE);

  dzl_binding_group_bind (priv->bindings, "modified",
                          priv->header, "modified",
                          G_BINDING_SYNC_CREATE);

  dzl_binding_group_bind (priv->bindings, "primary-color-bg",
                          priv->header, "background-rgba",
                          G_BINDING_SYNC_CREATE);

  dzl_binding_group_bind (priv->bindings, "primary-color-fg",
                          priv->header, "foreground-rgba",
                          G_BINDING_SYNC_CREATE);

  g_signal_connect_object (priv->stack,
                           "notify::visible-child",
                           G_CALLBACK (ide_frame_notify_visible_child),
                           self,
                           G_CONNECT_SWAPPED);

  g_signal_connect_object (priv->stack,
                           "add",
                           G_CALLBACK (ide_frame_page_added),
                           self,
                           G_CONNECT_SWAPPED | G_CONNECT_AFTER);

  g_signal_connect_object (priv->stack,
                           "remove",
                           G_CALLBACK (ide_frame_page_removed),
                           self,
                           G_CONNECT_SWAPPED);

  _ide_frame_header_set_pages (priv->header, G_LIST_MODEL (self));
  _ide_frame_header_update (priv->header, NULL);
}
static void
photos_share_point_manager_refresh_share_points (PhotosSharePointManager *self)
{
  GHashTable *new_share_points;
  GList *extensions;
  GList *l;
  guint i;
  guint n_items;

  new_share_points = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);

  extensions = g_io_extension_point_get_extensions (self->extension_point);
  for (l = extensions; l != NULL; l = l->next)
    {
      GError *error;
      GIOExtension *extension = (GIOExtension *) l->data;
      GType type;
      PhotosSharePoint *share_point;
      const gchar *id;

      type = g_io_extension_get_type (extension);
      if (g_type_is_a (type, G_TYPE_INITABLE))
        {
          error = NULL;
          share_point = PHOTOS_SHARE_POINT (g_initable_new (type, NULL, &error, NULL));
          if (share_point == NULL)
            {
              const gchar *name;

              name = g_io_extension_get_name (extension);
              g_debug ("Unable to initialize share point %s: %s", name, error->message);
              g_error_free (error);
              continue;
            }
        }
      else
        {
          share_point = PHOTOS_SHARE_POINT (g_object_new (type, NULL));
        }

      id = photos_filterable_get_id (PHOTOS_FILTERABLE (share_point));
      g_hash_table_insert (new_share_points, g_strdup (id), g_object_ref (share_point));
      g_object_unref (share_point);
    }

  n_items = g_list_model_get_n_items (G_LIST_MODEL (self->src_mngr));
  for (i = 0; i < n_items; i++)
    {
      PhotosSharePoint *share_point = NULL;
      PhotosSource *source;

      source = PHOTOS_SOURCE (g_list_model_get_object (G_LIST_MODEL (self->src_mngr), i));
      share_point = photos_share_point_manager_create_share_point_online (self, source);
      if (share_point != NULL)
        {
          const gchar *id;

          id = photos_filterable_get_id (PHOTOS_FILTERABLE (share_point));
          g_hash_table_insert (new_share_points, g_strdup (id), g_object_ref (share_point));
        }

      g_clear_object (&share_point);
      g_object_unref (source);
    }

  photos_base_manager_process_new_objects (PHOTOS_BASE_MANAGER (self), new_share_points);
  g_hash_table_unref (new_share_points);
}
Example #22
0
PpJobsDialog *
pp_jobs_dialog_new (GtkWindow            *parent,
                    UserResponseCallback  user_callback,
                    gpointer              user_data,
                    gchar                *printer_name)
{
  PpJobsDialog    *dialog;
  GtkButton       *clear_all_button;
  GError          *error = NULL;
  gchar           *objects[] = { "jobs-dialog", NULL };
  guint            builder_result;
  gchar           *title;

  dialog = g_new0 (PpJobsDialog, 1);

  dialog->builder = gtk_builder_new ();
  dialog->parent = GTK_WIDGET (parent);

  builder_result = gtk_builder_add_objects_from_resource (dialog->builder,
                                                          "/org/gnome/control-center/printers/jobs-dialog.ui",
                                                          objects, &error);

  if (builder_result == 0)
    {
      g_warning ("Could not load ui: %s", error->message);
      g_error_free (error);
      return NULL;
    }

  dialog->dialog = (GtkWidget *) gtk_builder_get_object (dialog->builder, "jobs-dialog");
  dialog->user_callback = user_callback;
  dialog->user_data = user_data;
  dialog->printer_name = g_strdup (printer_name);
  dialog->ref_count = 0;

  /* connect signals */
  g_signal_connect (dialog->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
  g_signal_connect (dialog->dialog, "response", G_CALLBACK (jobs_dialog_response_cb), dialog);

  clear_all_button = GTK_BUTTON (gtk_builder_get_object (dialog->builder, "jobs-clear-all-button"));
  g_signal_connect (clear_all_button, "clicked", G_CALLBACK (on_clear_all_button_clicked), dialog);

  /* Translators: This is the printer name for which we are showing the active jobs */
  title = g_strdup_printf (C_("Printer jobs dialog title", "%s — Active Jobs"), printer_name);
  gtk_window_set_title (GTK_WINDOW (dialog->dialog), title);
  g_free (title);

  dialog->listbox = GTK_LIST_BOX (gtk_builder_get_object (dialog->builder, "jobs-listbox"));
  gtk_list_box_set_header_func (dialog->listbox,
                                cc_list_box_update_header_func, NULL, NULL);
  dialog->store = g_list_store_new (pp_job_get_type ());
  gtk_list_box_bind_model (dialog->listbox, G_LIST_MODEL (dialog->store),
                           create_listbox_row, NULL, NULL);

  update_jobs_list (dialog);

  gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), GTK_WINDOW (parent));
  gtk_window_present (GTK_WINDOW (dialog->dialog));
  gtk_widget_show_all (GTK_WIDGET (dialog->dialog));

  return dialog;
}