Beispiel #1
0
void
load_file (const gchar *filename)
{
    FILE *file;
    GtkTextIter start, end;
    char *full_filename;
    GError *err = NULL;
    GString *buffer = g_string_new (NULL);
    int state = 0;
    gboolean in_para = 0;

    if (current_file && !strcmp (current_file, filename))
    {
        g_string_free (buffer, TRUE);
        return;
    }

    g_free (current_file);
    current_file = g_strdup (filename);

    gtk_text_buffer_get_bounds (info_buffer, &start, &end);
    gtk_text_buffer_delete (info_buffer, &start, &end);

    gtk_text_buffer_get_bounds (source_buffer, &start, &end);
    gtk_text_buffer_delete (source_buffer, &start, &end);

    full_filename = demo_find_file (filename, &err);
    if (!full_filename)
    {
        g_warning ("%s", err->message);
        g_error_free (err);
        return;
    }

    file = g_fopen (full_filename, "r");

    if (!file)
        g_warning ("Cannot open %s: %s\n", full_filename, g_strerror (errno));

    g_free (full_filename);

    if (!file)
        return;

    gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
    while (read_line (file, buffer))
    {
        gchar *p = buffer->str;
        gchar *q;
        gchar *r;

        switch (state)
        {
        case 0:
            /* Reading title */
            while (*p == '/' || *p == '*' || g_ascii_isspace (*p))
                p++;
            r = p;
            while (*r != '/' && strlen (r))
                r++;
            if (strlen (r) > 0)
                p = r + 1;
            q = p + strlen (p);
            while (q > p && g_ascii_isspace (*(q - 1)))
                q--;

            if (q > p)
            {
                int len_chars = g_utf8_pointer_to_offset (p, q);

                end = start;

                g_assert (strlen (p) >= q - p);
                gtk_text_buffer_insert (info_buffer, &end, p, q - p);
                start = end;

                gtk_text_iter_backward_chars (&start, len_chars);
                gtk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end);

                start = end;

                state++;
            }
            break;

        case 1:
            /* Reading body of info section */
            while (g_ascii_isspace (*p))
                p++;
            if (*p == '*' && *(p + 1) == '/')
            {
                gtk_text_buffer_get_iter_at_offset (source_buffer, &start, 0);
                state++;
            }
            else
            {
                int len;

                while (*p == '*' || g_ascii_isspace (*p))
                    p++;

                len = strlen (p);
                while (g_ascii_isspace (*(p + len - 1)))
                    len--;

                if (len > 0)
                {
                    if (in_para)
                        gtk_text_buffer_insert (info_buffer, &start, " ", 1);

                    g_assert (strlen (p) >= len);
                    gtk_text_buffer_insert (info_buffer, &start, p, len);
                    in_para = 1;
                }
                else
                {
                    gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
                    in_para = 0;
                }
            }
            break;

        case 2:
            /* Skipping blank lines */
            while (g_ascii_isspace (*p))
                p++;
            if (*p)
            {
                p = buffer->str;
                state++;
                /* Fall through */
            }
            else
                break;

        case 3:
            /* Reading program body */
            gtk_text_buffer_insert (source_buffer, &start, p, -1);
            gtk_text_buffer_insert (source_buffer, &start, "\n", 1);
            break;
        }
    }

    fclose (file);

    fontify ();

    g_string_free (buffer, TRUE);
}
Beispiel #2
0
void
load_file (const gchar *demoname,
           const gchar *filename)
{
  GtkTextBuffer *info_buffer, *source_buffer;
  GtkTextIter start, end;
  char *resource_filename;
  GError *err = NULL;
  int state = 0;
  gboolean in_para = 0;
  gchar **lines;
  GBytes *bytes;
  gint i;

  if (!g_strcmp0 (current_file, filename))
    return;

  remove_data_tabs ();

  add_data_tab (demoname);

  g_free (current_file);
  current_file = g_strdup (filename);

  info_buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_create_tag (info_buffer, "title",
                              "font", "Sans 18",
                              "pixels-below-lines", 10,
                              NULL);

  source_buffer = gtk_text_buffer_new (NULL);
  gtk_text_buffer_create_tag (source_buffer, "comment",
                              "foreground", "DodgerBlue",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "type",
                              "foreground", "ForestGreen",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "string",
                              "foreground", "RosyBrown",
                              "weight", PANGO_WEIGHT_BOLD,
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "control",
                              "foreground", "purple",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "preprocessor",
                              "style", PANGO_STYLE_OBLIQUE,
                              "foreground", "burlywood4",
                              NULL);
  gtk_text_buffer_create_tag (source_buffer, "function",
                              "weight", PANGO_WEIGHT_BOLD,
                              "foreground", "DarkGoldenrod4",
                              NULL);

  resource_filename = g_strconcat ("/sources/", filename, NULL);
  bytes = g_resources_lookup_data (resource_filename, 0, &err);
  g_free (resource_filename);

  if (bytes == NULL)
    {
      g_warning ("Cannot open source for %s: %s\n", filename, err->message);
      g_error_free (err);
      return;
    }

  lines = g_strsplit (g_bytes_get_data (bytes, NULL), "\n", -1);
  g_bytes_unref (bytes);

  gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
  for (i = 0; lines[i] != NULL; i++)
    {
      gchar *p;
      gchar *q;
      gchar *r;

      /* Make sure \r is stripped at the end for the poor windows people */
      lines[i] = g_strchomp (lines[i]);

      p = lines[i];
      switch (state)
        {
        case 0:
          /* Reading title */
          while (*p == '/' || *p == '*' || g_ascii_isspace (*p))
            p++;
          r = p;
          while (*r != '\0')
            {
              while (*r != '/' && *r != ':' && *r != '\0')
                r++;
              if (*r == '/')
                {
                  r++;
                  p = r;
                }
              if (r[0] == ':' && r[1] == ':')
                *r = '\0';
            }
          q = p + strlen (p);
          while (q > p && g_ascii_isspace (*(q - 1)))
            q--;


          if (q > p)
            {
              int len_chars = g_utf8_pointer_to_offset (p, q);

              end = start;

              g_assert (strlen (p) >= q - p);
              gtk_text_buffer_insert (info_buffer, &end, p, q - p);
              start = end;

              gtk_text_iter_backward_chars (&start, len_chars);
              gtk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end);

              start = end;

              while (*p && *p != '\n') p++;

              state++;
            }
          break;

        case 1:
          /* Reading body of info section */
          while (g_ascii_isspace (*p))
            p++;
          if (*p == '*' && *(p + 1) == '/')
            {
              gtk_text_buffer_get_iter_at_offset (source_buffer, &start, 0);
              state++;
            }
          else
            {
              int len;

              while (*p == '*' || g_ascii_isspace (*p))
                p++;

              len = strlen (p);
              while (g_ascii_isspace (*(p + len - 1)))
                len--;

              if (len > 0)
                {
                  if (in_para)
                    gtk_text_buffer_insert (info_buffer, &start, " ", 1);

                  g_assert (strlen (p) >= len);
                  gtk_text_buffer_insert (info_buffer, &start, p, len);
                  in_para = 1;
                }
              else
                {
                  gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
                  in_para = 0;
                }
            }
          break;

        case 2:
          /* Skipping blank lines */
          while (g_ascii_isspace (*p))
            p++;
          if (*p)
            {
              p = lines[i];
              state++;
              /* Fall through */
            }
          else
            break;

        case 3:
          /* Reading program body */
          gtk_text_buffer_insert (source_buffer, &start, p, -1);
          gtk_text_buffer_insert (source_buffer, &start, "\n", 1);
          break;
        }
    }

  fontify (source_buffer);

  g_strfreev (lines);

  gtk_text_view_set_buffer (GTK_TEXT_VIEW (info_view), info_buffer);
  g_object_unref (info_buffer);
  gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer);
  g_object_unref (source_buffer);
}
Beispiel #3
0
static void
add_data_tab (const gchar *demoname)
{
  gchar *resource_dir, *resource_name;
  gchar **resources;
  GtkWidget *widget, *label;
  guint i;

  resource_dir = g_strconcat ("/", demoname, NULL);
  resources = g_resources_enumerate_children (resource_dir, 0, NULL);
  if (resources == NULL)
    {
      g_free (resource_dir);
      return;
    }

  for (i = 0; resources[i]; i++)
    {
      resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);

      widget = gtk_image_new_from_resource (resource_name);
      if (gtk_image_get_pixbuf (GTK_IMAGE (widget)) == NULL &&
          gtk_image_get_animation (GTK_IMAGE (widget)) == NULL)
        {
          GBytes *bytes;

          /* So we've used the best API available to figure out it's
           * not an image. Let's try something else then.
           */
          g_object_ref_sink (widget);
          g_object_unref (widget);

          bytes = g_resources_lookup_data (resource_name, 0, NULL);
          g_assert (bytes);

          if (g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
            {
              /* Looks like it parses as text. Dump it into a textview then! */
              GtkTextBuffer *buffer;
              GtkWidget *textview;

              widget = create_text (&textview, FALSE);
              buffer = gtk_text_buffer_new (NULL);
              gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
              if (g_str_has_suffix (resource_name, ".c"))
                fontify (buffer);
              gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
            }
          else
            {
              g_warning ("Don't know how to display resource '%s'", resource_name);
              widget = NULL;
            }

          g_bytes_unref (bytes);
        }

      gtk_widget_show_all (widget);
      label = gtk_label_new (resources[i]);
      gtk_widget_show (label);
      gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
      gtk_container_child_set (GTK_CONTAINER (notebook),
                               GTK_WIDGET (widget),
                               "tab-expand", TRUE,
                               NULL);

      g_free (resource_name);
    }

  g_strfreev (resources);
  g_free (resource_dir);
}