Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  listbox.c

  Sprache: C
 

/* List Box/Complex
 *
 * GtkListBox allows lists with complicated layouts, using
 * regular widgets supporting sorting and filtering.
 */


#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>

static GdkTexture *avatar_texture_other;
static GtkWidget *window = NULL;

#define GTK_TYPE_MESSAGE    (gtk_message_get_type ())
#define GTK_MESSAGE(message)    (G_TYPE_CHECK_INSTANCE_CAST ((message), GTK_TYPE_MESSAGE, GtkMessage))
#define GTK_MESSAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MESSAGE, GtkMessageClass))
#define GTK_IS_MESSAGE(message)    (G_TYPE_CHECK_INSTANCE_TYPE ((message), GTK_TYPE_MESSAGE))
#define GTK_IS_MESSAGE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MESSAGE))
#define GTK_MESSAGE_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MESSAGE, GtkMessageClass))

#define GTK_TYPE_MESSAGE_ROW    (gtk_message_row_get_type ())
#define GTK_MESSAGE_ROW(message_row)    (G_TYPE_CHECK_INSTANCE_CAST ((message_row), GTK_TYPE_MESSAGE_ROW, GtkMessageRow))
#define GTK_MESSAGE_ROW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MESSAGE_ROW, GtkMessageRowClass))
#define GTK_IS_MESSAGE_ROW(message_row)    (G_TYPE_CHECK_INSTANCE_TYPE ((message_row), GTK_TYPE_MESSAGE_ROW))
#define GTK_IS_MESSAGE_ROW_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MESSAGE_ROW))
#define GTK_MESSAGE_ROW_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MESSAGE_ROW, GtkMessageRowClass))

typedef struct _GtkMessage   GtkMessage;
typedef struct _GtkMessageClass  GtkMessageClass;
typedef struct _GtkMessageRow   GtkMessageRow;
typedef struct _GtkMessageRowClass  GtkMessageRowClass;
typedef struct _GtkMessageRowPrivate  GtkMessageRowPrivate;


struct _GtkMessage
{
  GObject parent;

  guint id;
  char *sender_name;
  char *sender_nick;
  char *message;
  gint64 time;
  guint reply_to;
  char *resent_by;
  int n_favorites;
  int n_reshares;
};

struct _GtkMessageClass
{
  GObjectClass parent_class;
};

struct _GtkMessageRow
{
  GtkListBoxRow parent;

  GtkMessageRowPrivate *priv;
};

struct _GtkMessageRowClass
{
  GtkListBoxRowClass parent_class;
};

struct _GtkMessageRowPrivate
{
  GtkMessage *message;
  GtkRevealer *details_revealer;
  GtkImage *avatar_image;
  GtkWidget *extra_buttons_box;
  GtkLabel *content_label;
  GtkLabel *source_name;
  GtkLabel *source_nick;
  GtkLabel *short_time_label;
  GtkLabel *detailed_time_label;
  GtkBox *resent_box;
  GtkLinkButton *resent_by_button;
  GtkLabel *n_favorites_label;
  GtkLabel *n_reshares_label;
  GtkButton *expand_button;
};

GType      gtk_message_get_type  (void) G_GNUC_CONST;
GType      gtk_message_row_get_type  (void) G_GNUC_CONST;

G_DEFINE_TYPE (GtkMessage, gtk_message, G_TYPE_OBJECT);

static void
gtk_message_finalize (GObject *obj)
{
  GtkMessage *msg = GTK_MESSAGE (obj);

  g_free (msg->sender_name);
  g_free (msg->sender_nick);
  g_free (msg->message);
  g_free (msg->resent_by);

  G_OBJECT_CLASS (gtk_message_parent_class)->finalize (obj);
}
static void
gtk_message_class_init (GtkMessageClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  object_class->finalize = gtk_message_finalize;
}

static void
gtk_message_init (GtkMessage *msg)
{
}

static void
gtk_message_parse (GtkMessage *msg, const char *str)
{
  char **strv;
  int i;

  strv = g_strsplit (str, "|"0);

  i = 0;
  msg->id = strtol (strv[i++], NULL, 10);
  msg->sender_name = g_strdup (strv[i++]);
  msg->sender_nick = g_strdup (strv[i++]);
  msg->message = g_strdup (strv[i++]);
  msg->time = strtol (strv[i++], NULL, 10);
  if (strv[i])
    {
      msg->reply_to = strtol (strv[i++], NULL, 10);
      if (strv[i])
        {
          if (*strv[i])
            msg->resent_by = g_strdup (strv[i]);
          i++;
          if (strv[i])
            {
              msg->n_favorites = strtol (strv[i++], NULL, 10);
              if (strv[i])
                {
                  msg->n_reshares = strtol (strv[i++], NULL, 10);
                }

            }
        }
    }

  g_strfreev (strv);
}

static GtkMessage *
gtk_message_new (const char *str)
{
  GtkMessage *msg;
  msg = g_object_new (gtk_message_get_type (), NULL);
  gtk_message_parse (msg, str);
  return msg;
}

G_DEFINE_TYPE_WITH_PRIVATE (GtkMessageRow, gtk_message_row, GTK_TYPE_LIST_BOX_ROW);


static void
gtk_message_row_update (GtkMessageRow *row)
{
  GtkMessageRowPrivate *priv = row->priv;
  GDateTime *t;
  char *s;

  gtk_label_set_text (priv->source_name, priv->message->sender_name);
  gtk_label_set_text (priv->source_nick, priv->message->sender_nick);
  gtk_label_set_text (priv->content_label, priv->message->message);
  t = g_date_time_new_from_unix_utc (priv->message->time);
  s = g_date_time_format (t, "%e %b %y");
  gtk_label_set_text (priv->short_time_label, s);
  g_free (s);
  s = g_date_time_format (t, "%X - %e %b %Y");
  gtk_label_set_text (priv->detailed_time_label, s);
  g_free (s);
  g_date_time_unref (t);

  gtk_widget_set_visible (GTK_WIDGET(priv->n_favorites_label),
                          priv->message->n_favorites != 0);
  s = g_strdup_printf ("<b>%d</b>\nFavorites", priv->message->n_favorites);
  gtk_label_set_markup (priv->n_favorites_label, s);
  g_free (s);

  gtk_widget_set_visible (GTK_WIDGET(priv->n_reshares_label),
                          priv->message->n_reshares != 0);
  s = g_strdup_printf ("<b>%d</b>\nReshares", priv->message->n_reshares);
  gtk_label_set_markup (priv->n_reshares_label, s);
  g_free (s);

  gtk_widget_set_visible (GTK_WIDGET (priv->resent_box), priv->message->resent_by != NULL);
  if (priv->message->resent_by)
    gtk_button_set_label (GTK_BUTTON (priv->resent_by_button), priv->message->resent_by);

  if (strcmp (priv->message->sender_nick, "GTKtoolkit") == 0)
    gtk_image_set_from_icon_name (priv->avatar_image, "org.gtk.Demo4");
  else
    gtk_image_set_from_paintable (priv->avatar_image, GDK_PAINTABLE (avatar_texture_other));

}

static void
gtk_message_row_expand (GtkMessageRow *row)
{
  GtkMessageRowPrivate *priv = row->priv;
  gboolean expand;

  expand = !gtk_revealer_get_reveal_child (priv->details_revealer);

  gtk_revealer_set_reveal_child (priv->details_revealer, expand);
  if (expand)
    gtk_button_set_label (priv->expand_button, "Hide");
  else
    gtk_button_set_label (priv->expand_button, "Expand");
}

static void
expand_clicked (GtkMessageRow *row,
                GtkButton *button)
{
  gtk_message_row_expand (row);
}

static void
reshare_clicked (GtkMessageRow *row,
                 GtkButton *button)
{
  GtkMessageRowPrivate *priv = row->priv;

  priv->message->n_reshares++;
  gtk_message_row_update (row);
}

static void
favorite_clicked (GtkMessageRow *row,
                  GtkButton *button)
{
  GtkMessageRowPrivate *priv = row->priv;

  priv->message->n_favorites++;
  gtk_message_row_update (row);
}

static void
gtk_message_row_state_flags_changed (GtkWidget    *widget,
                                     GtkStateFlags previous_state_flags)
{
  GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (widget)->priv;
  GtkStateFlags flags;
  gboolean visible;

  flags = gtk_widget_get_state_flags (widget);

  visible = flags & (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED) ? TRUE : FALSE;
  gtk_widget_set_visible (priv->extra_buttons_box, visible);

  GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags);
}

static void
gtk_message_row_dispose (GObject *obj)
{
  gtk_widget_dispose_template (GTK_WIDGET (obj), GTK_TYPE_MESSAGE_ROW);
  G_OBJECT_CLASS (gtk_message_row_parent_class)->dispose (obj);
}

static void
gtk_message_row_finalize (GObject *obj)
{
  GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (obj)->priv;
  g_object_unref (priv->message);
  G_OBJECT_CLASS (gtk_message_row_parent_class)->finalize (obj);
}

static void
gtk_message_row_class_init (GtkMessageRowClass *klass)
{
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->dispose = gtk_message_row_dispose;
  object_class->finalize = gtk_message_row_finalize;

  gtk_widget_class_set_template_from_resource (widget_class, "/listbox/listbox.ui");
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, content_label);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, source_name);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, source_nick);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, short_time_label);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, detailed_time_label);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, extra_buttons_box);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, details_revealer);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, avatar_image);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, resent_box);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, resent_by_button);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, n_reshares_label);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, n_favorites_label);
  gtk_widget_class_bind_template_child_private (widget_class, GtkMessageRow, expand_button);
  gtk_widget_class_bind_template_callback (widget_class, expand_clicked);
  gtk_widget_class_bind_template_callback (widget_class, reshare_clicked);
  gtk_widget_class_bind_template_callback (widget_class, favorite_clicked);

  widget_class->state_flags_changed = gtk_message_row_state_flags_changed;
}

static void
gtk_message_row_init (GtkMessageRow *row)
{
  row->priv = gtk_message_row_get_instance_private (row);

  gtk_widget_init_template (GTK_WIDGET (row));
}

static GtkMessageRow *
gtk_message_row_new (GtkMessage *message)
{
  GtkMessageRow *row;

  row = g_object_new (gtk_message_row_get_type (), NULL);
  row->priv->message = message;
  gtk_message_row_update (row);

  return row;
}

static int
gtk_message_row_sort (GtkMessageRow *a, GtkMessageRow *b, gpointer data)
{
  return b->priv->message->time - a->priv->message->time;
}

static void
row_activated (GtkListBox *listbox, GtkListBoxRow *row)
{
  gtk_message_row_expand (GTK_MESSAGE_ROW (row));
}

GtkWidget *
do_listbox (GtkWidget *do_widget)
{
  GtkWidget *scrolled, *listbox, *vbox, *label;
  GtkMessage *message;
  GtkMessageRow *row;
  GBytes *data;
  char **lines;
  int i;

  if (!window)
    {
      avatar_texture_other = gdk_texture_new_from_resource ("/listbox/apple-red.png");

      window = gtk_window_new ();
      gtk_window_set_display (GTK_WINDOW (window),
                              gtk_widget_get_display (do_widget));
      gtk_window_set_title (GTK_WINDOW (window), "List Box — Complex");
      gtk_window_set_default_size (GTK_WINDOW (window), 400600);
      g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);

      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
      gtk_window_set_child (GTK_WINDOW (window), vbox);
      label = gtk_label_new ("Messages from GTK and friends");
      gtk_box_append (GTK_BOX (vbox), label);
      scrolled = gtk_scrolled_window_new ();
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
      gtk_widget_set_vexpand (scrolled, TRUE);
      gtk_box_append (GTK_BOX (vbox), scrolled);
      listbox = gtk_list_box_new ();
      gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), listbox);

      gtk_list_box_set_sort_func (GTK_LIST_BOX (listbox), (GtkListBoxSortFunc)gtk_message_row_sort, listbox, NULL);
      gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (listbox), FALSE);
      g_signal_connect (listbox, "row-activated", G_CALLBACK (row_activated), NULL);

      data = g_resources_lookup_data ("/listbox/messages.txt"0, NULL);
      lines = g_strsplit (g_bytes_get_data (data, NULL), "\n"0);

      for (i = 0; lines[i] != NULL && *lines[i]; i++)
        {
          message = gtk_message_new (lines[i]);
          row = gtk_message_row_new (message);
          gtk_list_box_insert (GTK_LIST_BOX (listbox), GTK_WIDGET (row), -1);
        }

      g_strfreev (lines);
      g_bytes_unref (data);
    }

  if (!gtk_widget_get_visible (window))
    gtk_widget_set_visible (window, TRUE);
  else
    gtk_window_destroy (GTK_WINDOW (window));

  return window;
}

Messung V0.5 in Prozent
C=100 H=99 G=99

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-07-03) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik