2008-06-22 14:28:52 +00:00
|
|
|
#include "config.h"
|
2000-10-18 15:50:13 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
2001-05-18 18:30:59 +00:00
|
|
|
#include <stdlib.h>
|
2000-10-18 15:50:13 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
2004-12-05 12:47:42 +00:00
|
|
|
#include <glib/gstdio.h>
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2008-12-26 21:57:55 +00:00
|
|
|
#include "demos.h"
|
2000-10-18 15:50:13 +00:00
|
|
|
|
|
|
|
static GtkTextBuffer *info_buffer;
|
|
|
|
static GtkTextBuffer *source_buffer;
|
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
static gchar *current_file = NULL;
|
|
|
|
|
2012-05-18 04:48:57 +00:00
|
|
|
static GtkWidget *notebook;
|
2001-11-23 21:46:44 +00:00
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
enum {
|
|
|
|
TITLE_COLUMN,
|
|
|
|
FILENAME_COLUMN,
|
|
|
|
FUNC_COLUMN,
|
2006-08-16 23:32:07 +00:00
|
|
|
STYLE_COLUMN,
|
2000-10-26 00:36:47 +00:00
|
|
|
NUM_COLUMNS
|
|
|
|
};
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2000-11-18 23:59:30 +00:00
|
|
|
typedef struct _CallbackData CallbackData;
|
|
|
|
struct _CallbackData
|
|
|
|
{
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreePath *path;
|
|
|
|
};
|
|
|
|
|
2003-09-25 18:48:06 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
|
|
|
|
#undef DEMOCODEDIR
|
|
|
|
|
|
|
|
static char *
|
|
|
|
get_democodedir (void)
|
|
|
|
{
|
|
|
|
static char *result = NULL;
|
|
|
|
|
|
|
|
if (result == NULL)
|
|
|
|
{
|
2009-02-17 18:57:05 +00:00
|
|
|
result = g_win32_get_package_installation_directory_of_module (NULL);
|
2003-09-25 18:48:06 +00:00
|
|
|
if (result == NULL)
|
2011-09-02 03:55:47 +00:00
|
|
|
result = "unknown-location";
|
2003-09-25 18:48:06 +00:00
|
|
|
|
2011-08-14 12:14:14 +00:00
|
|
|
result = g_strconcat (result, "\\share\\gtk-3.0\\demo", NULL);
|
2003-09-25 18:48:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define DEMOCODEDIR get_democodedir ()
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2001-11-23 21:46:44 +00:00
|
|
|
/**
|
|
|
|
* demo_find_file:
|
|
|
|
* @base: base filename
|
|
|
|
* @err: location to store error, or %NULL.
|
2011-09-02 03:55:47 +00:00
|
|
|
*
|
2001-11-23 21:46:44 +00:00
|
|
|
* Looks for @base first in the current directory, then in the
|
|
|
|
* location GTK+ where it will be installed on make install,
|
|
|
|
* returns the first file found.
|
2011-09-02 03:55:47 +00:00
|
|
|
*
|
2001-11-23 21:46:44 +00:00
|
|
|
* Return value: the filename, if found or %NULL
|
2011-09-02 03:55:47 +00:00
|
|
|
*/
|
2001-11-23 21:46:44 +00:00
|
|
|
gchar *
|
|
|
|
demo_find_file (const char *base,
|
2011-09-02 03:55:47 +00:00
|
|
|
GError **err)
|
2001-11-23 21:46:44 +00:00
|
|
|
{
|
2003-03-06 19:49:53 +00:00
|
|
|
g_return_val_if_fail (err == NULL || *err == NULL, NULL);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2003-04-02 23:06:16 +00:00
|
|
|
if (g_file_test ("gtk-logo-rgb.gif", G_FILE_TEST_EXISTS) &&
|
|
|
|
g_file_test (base, G_FILE_TEST_EXISTS))
|
2001-11-23 21:46:44 +00:00
|
|
|
return g_strdup (base);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *filename = g_build_filename (DEMOCODEDIR, base, NULL);
|
|
|
|
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
g_set_error (err, G_FILE_ERROR, G_FILE_ERROR_NOENT,
|
|
|
|
"Cannot find demo data file \"%s\"", base);
|
|
|
|
g_free (filename);
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-11-23 21:46:44 +00:00
|
|
|
return filename;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-11-18 23:59:30 +00:00
|
|
|
static void
|
|
|
|
window_closed_cb (GtkWidget *window, gpointer data)
|
|
|
|
{
|
|
|
|
CallbackData *cbdata = data;
|
|
|
|
GtkTreeIter iter;
|
2006-08-16 23:32:07 +00:00
|
|
|
PangoStyle style;
|
2000-11-18 23:59:30 +00:00
|
|
|
|
|
|
|
gtk_tree_model_get_iter (cbdata->model, &iter, cbdata->path);
|
2001-02-17 00:16:08 +00:00
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (cbdata->model), &iter,
|
2011-09-02 03:55:47 +00:00
|
|
|
STYLE_COLUMN, &style,
|
|
|
|
-1);
|
2006-08-16 23:32:07 +00:00
|
|
|
if (style == PANGO_STYLE_ITALIC)
|
2000-11-18 23:59:30 +00:00
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (cbdata->model), &iter,
|
2011-09-02 03:55:47 +00:00
|
|
|
STYLE_COLUMN, PANGO_STYLE_NORMAL,
|
|
|
|
-1);
|
2000-11-18 23:59:30 +00:00
|
|
|
|
|
|
|
gtk_tree_path_free (cbdata->path);
|
|
|
|
g_free (cbdata);
|
|
|
|
}
|
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
gboolean
|
|
|
|
read_line (FILE *stream, GString *str)
|
|
|
|
{
|
|
|
|
int n_read = 0;
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2002-05-16 19:11:43 +00:00
|
|
|
#ifdef HAVE_FLOCKFILE
|
2000-10-18 15:50:13 +00:00
|
|
|
flockfile (stream);
|
2001-11-25 23:36:29 +00:00
|
|
|
#endif
|
2000-10-18 15:50:13 +00:00
|
|
|
|
|
|
|
g_string_truncate (str, 0);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
int c;
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2004-02-28 20:00:24 +00:00
|
|
|
#ifdef HAVE_FLOCKFILE
|
2000-10-18 15:50:13 +00:00
|
|
|
c = getc_unlocked (stream);
|
2001-11-25 23:36:29 +00:00
|
|
|
#else
|
|
|
|
c = getc (stream);
|
|
|
|
#endif
|
2000-10-18 15:50:13 +00:00
|
|
|
|
|
|
|
if (c == EOF)
|
2011-09-02 03:55:47 +00:00
|
|
|
goto done;
|
2000-10-18 15:50:13 +00:00
|
|
|
else
|
2011-09-02 03:55:47 +00:00
|
|
|
n_read++;
|
2000-10-18 15:50:13 +00:00
|
|
|
|
|
|
|
switch (c)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
|
|
|
{
|
2002-05-16 19:11:43 +00:00
|
|
|
#ifdef HAVE_FLOCKFILE
|
2011-09-02 03:55:47 +00:00
|
|
|
int next_c = getc_unlocked (stream);
|
2001-11-25 23:36:29 +00:00
|
|
|
#else
|
2011-09-02 03:55:47 +00:00
|
|
|
int next_c = getc (stream);
|
2001-11-25 23:36:29 +00:00
|
|
|
#endif
|
2011-09-02 03:55:47 +00:00
|
|
|
|
|
|
|
if (!(next_c == EOF ||
|
|
|
|
(c == '\r' && next_c == '\n') ||
|
|
|
|
(c == '\n' && next_c == '\r')))
|
|
|
|
ungetc (next_c, stream);
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
g_string_append_c (str, c);
|
|
|
|
}
|
2000-10-18 15:50:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
2002-05-16 19:11:43 +00:00
|
|
|
#ifdef HAVE_FLOCKFILE
|
2000-10-18 15:50:13 +00:00
|
|
|
funlockfile (stream);
|
2001-11-25 23:36:29 +00:00
|
|
|
#endif
|
2000-10-18 15:50:13 +00:00
|
|
|
|
|
|
|
return n_read > 0;
|
|
|
|
}
|
|
|
|
|
2001-05-18 16:28:30 +00:00
|
|
|
|
|
|
|
/* Stupid syntax highlighting.
|
|
|
|
*
|
|
|
|
* No regex was used in the making of this highlighting.
|
|
|
|
* It should only work for simple cases. This is good, as
|
|
|
|
* that's all we should have in the demos.
|
|
|
|
*/
|
|
|
|
/* This code should not be used elsewhere, except perhaps as an example of how
|
|
|
|
* to iterate through a text buffer.
|
|
|
|
*/
|
|
|
|
enum {
|
|
|
|
STATE_NORMAL,
|
2002-02-23 00:13:17 +00:00
|
|
|
STATE_IN_COMMENT
|
2001-05-18 16:28:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static gchar *tokens[] =
|
|
|
|
{
|
|
|
|
"/*",
|
|
|
|
"\"",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static gchar *types[] =
|
|
|
|
{
|
|
|
|
"static",
|
|
|
|
"const ",
|
|
|
|
"void",
|
|
|
|
"gint",
|
2008-07-06 07:24:02 +00:00
|
|
|
" int ",
|
|
|
|
" char ",
|
2001-05-18 16:28:30 +00:00
|
|
|
"gchar ",
|
|
|
|
"gfloat",
|
|
|
|
"float",
|
2008-07-06 07:24:02 +00:00
|
|
|
"double",
|
2001-05-18 16:28:30 +00:00
|
|
|
"gint8",
|
|
|
|
"gint16",
|
|
|
|
"gint32",
|
|
|
|
"guint",
|
|
|
|
"guint8",
|
|
|
|
"guint16",
|
|
|
|
"guint32",
|
|
|
|
"guchar",
|
|
|
|
"glong",
|
|
|
|
"gboolean" ,
|
|
|
|
"gshort",
|
|
|
|
"gushort",
|
|
|
|
"gulong",
|
|
|
|
"gdouble",
|
|
|
|
"gldouble",
|
|
|
|
"gpointer",
|
|
|
|
"NULL",
|
|
|
|
"GList",
|
|
|
|
"GSList",
|
|
|
|
"FALSE",
|
|
|
|
"TRUE",
|
|
|
|
"FILE ",
|
|
|
|
"GtkColorSelection ",
|
|
|
|
"GtkWidget ",
|
|
|
|
"GtkButton ",
|
|
|
|
"GdkColor ",
|
|
|
|
"GdkRectangle ",
|
|
|
|
"GdkEventExpose ",
|
|
|
|
"GdkGC ",
|
|
|
|
"GdkPixbufLoader ",
|
|
|
|
"GdkPixbuf ",
|
|
|
|
"GError",
|
|
|
|
"size_t",
|
2008-07-06 07:24:02 +00:00
|
|
|
"GtkAboutDialog ",
|
|
|
|
"GtkAction ",
|
|
|
|
"GtkActionEntry ",
|
|
|
|
"GtkRadioActionEntry ",
|
|
|
|
"GtkIconFactory ",
|
|
|
|
"GtkStockItem ",
|
|
|
|
"GtkIconSet ",
|
|
|
|
"GtkTextBuffer ",
|
|
|
|
"GtkStatusbar ",
|
|
|
|
"GtkTextIter ",
|
|
|
|
"GtkTextMark ",
|
|
|
|
"GdkEventWindowState ",
|
|
|
|
"GtkActionGroup ",
|
|
|
|
"GtkUIManager ",
|
|
|
|
"GtkRadioAction ",
|
|
|
|
"GtkActionClass ",
|
|
|
|
"GtkToggleActionEntry ",
|
|
|
|
"GtkAssistant ",
|
|
|
|
"GtkBuilder ",
|
|
|
|
"GtkSizeGroup ",
|
|
|
|
"GtkTreeModel ",
|
|
|
|
"GtkTreeSelection ",
|
|
|
|
"GdkDisplay ",
|
|
|
|
"GdkScreen ",
|
|
|
|
"GdkWindow ",
|
|
|
|
"GdkEventButton ",
|
|
|
|
"GdkCursor ",
|
|
|
|
"GtkTreeIter ",
|
|
|
|
"GtkTreeViewColumn ",
|
|
|
|
"GdkDisplayManager ",
|
|
|
|
"GtkClipboard ",
|
|
|
|
"GtkIconSize ",
|
|
|
|
"GtkImage ",
|
|
|
|
"GdkDragContext ",
|
|
|
|
"GtkSelectionData ",
|
|
|
|
"GtkDialog ",
|
|
|
|
"GtkMenuItem ",
|
|
|
|
"GtkListStore ",
|
|
|
|
"GtkCellLayout ",
|
|
|
|
"GtkCellRenderer ",
|
|
|
|
"GtkTreePath ",
|
|
|
|
"GtkTreeStore ",
|
|
|
|
"GtkEntry ",
|
|
|
|
"GtkEditable ",
|
2010-09-11 02:12:42 +00:00
|
|
|
"GtkEditableInterface ",
|
2008-07-06 07:24:02 +00:00
|
|
|
"GdkPixmap ",
|
|
|
|
"GdkEventConfigure ",
|
|
|
|
"GdkEventMotion ",
|
|
|
|
"GdkModifierType ",
|
|
|
|
"GtkEntryCompletion ",
|
|
|
|
"GtkToolItem ",
|
|
|
|
"GDir ",
|
|
|
|
"GtkIconView ",
|
|
|
|
"GtkCellRendererText ",
|
|
|
|
"GtkContainer ",
|
|
|
|
"GtkAccelGroup ",
|
|
|
|
"GtkPaned ",
|
|
|
|
"GtkPrintOperation ",
|
|
|
|
"GtkPrintContext ",
|
|
|
|
"cairo_t ",
|
|
|
|
"PangoLayout "
|
|
|
|
"PangoFontDescription ",
|
|
|
|
"PangoRenderer ",
|
|
|
|
"PangoMatrix ",
|
|
|
|
"PangoContext ",
|
|
|
|
"PangoLayout ",
|
|
|
|
"GtkTable ",
|
|
|
|
"GtkToggleButton ",
|
|
|
|
"GString ",
|
|
|
|
"GtkIconSize ",
|
|
|
|
"GtkTreeView ",
|
|
|
|
"GtkTextTag ",
|
|
|
|
"GdkEvent ",
|
|
|
|
"GdkEventKey ",
|
|
|
|
"GtkTextView ",
|
|
|
|
"GdkEventVisibility ",
|
|
|
|
"GdkBitmap ",
|
|
|
|
"GtkTextChildAnchor ",
|
|
|
|
"GArray ",
|
|
|
|
"GtkCellEditable ",
|
|
|
|
"GtkCellRendererToggle ",
|
2001-05-18 16:28:30 +00:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static gchar *control[] =
|
|
|
|
{
|
|
|
|
" if ",
|
|
|
|
" while ",
|
|
|
|
" else",
|
|
|
|
" do ",
|
|
|
|
" for ",
|
|
|
|
"?",
|
|
|
|
":",
|
|
|
|
"return ",
|
|
|
|
"goto ",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
void
|
|
|
|
parse_chars (gchar *text,
|
2011-09-02 03:55:47 +00:00
|
|
|
gchar **end_ptr,
|
|
|
|
gint *state,
|
|
|
|
gchar **tag,
|
|
|
|
gboolean start)
|
2001-05-18 16:28:30 +00:00
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
gchar *next_token;
|
|
|
|
|
|
|
|
/* Handle comments first */
|
|
|
|
if (*state == STATE_IN_COMMENT)
|
|
|
|
{
|
|
|
|
*end_ptr = strstr (text, "*/");
|
|
|
|
if (*end_ptr)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
*end_ptr += 2;
|
|
|
|
*state = STATE_NORMAL;
|
|
|
|
*tag = "comment";
|
|
|
|
}
|
2001-05-18 16:28:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*tag = NULL;
|
|
|
|
*end_ptr = NULL;
|
|
|
|
|
|
|
|
/* check for comment */
|
|
|
|
if (!strncmp (text, "/*", 2))
|
|
|
|
{
|
|
|
|
*end_ptr = strstr (text, "*/");
|
|
|
|
if (*end_ptr)
|
2011-09-02 03:55:47 +00:00
|
|
|
*end_ptr += 2;
|
2001-05-18 16:28:30 +00:00
|
|
|
else
|
2011-09-02 03:55:47 +00:00
|
|
|
*state = STATE_IN_COMMENT;
|
2001-05-18 16:28:30 +00:00
|
|
|
*tag = "comment";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check for preprocessor defines */
|
|
|
|
if (*text == '#' && start)
|
|
|
|
{
|
|
|
|
*end_ptr = NULL;
|
|
|
|
*tag = "preprocessor";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* functions */
|
|
|
|
if (start && * text != '\t' && *text != ' ' && *text != '{' && *text != '}')
|
|
|
|
{
|
|
|
|
if (strstr (text, "("))
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
*end_ptr = strstr (text, "(");
|
|
|
|
*tag = "function";
|
|
|
|
return;
|
|
|
|
}
|
2001-05-18 16:28:30 +00:00
|
|
|
}
|
|
|
|
/* check for types */
|
|
|
|
for (i = 0; types[i] != NULL; i++)
|
2008-07-06 07:24:02 +00:00
|
|
|
if (!strncmp (text, types[i], strlen (types[i])) ||
|
|
|
|
(start && types[i][0] == ' ' && !strncmp (text, types[i] + 1, strlen (types[i]) - 1)))
|
2001-05-18 16:28:30 +00:00
|
|
|
{
|
2011-09-02 03:55:47 +00:00
|
|
|
*end_ptr = text + strlen (types[i]);
|
|
|
|
*tag = "type";
|
|
|
|
return;
|
2001-05-18 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check for control */
|
|
|
|
for (i = 0; control[i] != NULL; i++)
|
|
|
|
if (!strncmp (text, control[i], strlen (control[i])))
|
|
|
|
{
|
2011-09-02 03:55:47 +00:00
|
|
|
*end_ptr = text + strlen (control[i]);
|
|
|
|
*tag = "control";
|
|
|
|
return;
|
2001-05-18 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check for string */
|
|
|
|
if (text[0] == '"')
|
|
|
|
{
|
|
|
|
gint maybe_escape = FALSE;
|
|
|
|
|
|
|
|
*end_ptr = text + 1;
|
|
|
|
*tag = "string";
|
|
|
|
while (**end_ptr != '\000')
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
if (**end_ptr == '\"' && !maybe_escape)
|
|
|
|
{
|
|
|
|
*end_ptr += 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (**end_ptr == '\\')
|
|
|
|
maybe_escape = TRUE;
|
|
|
|
else
|
|
|
|
maybe_escape = FALSE;
|
|
|
|
*end_ptr += 1;
|
|
|
|
}
|
2001-05-18 16:28:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* not at the start of a tag. Find the next one. */
|
|
|
|
for (i = 0; tokens[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
next_token = strstr (text, tokens[i]);
|
|
|
|
if (next_token)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
if (*end_ptr)
|
|
|
|
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
|
|
|
else
|
|
|
|
*end_ptr = next_token;
|
|
|
|
}
|
2001-05-18 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; types[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
next_token = strstr (text, types[i]);
|
|
|
|
if (next_token)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
if (*end_ptr)
|
|
|
|
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
|
|
|
else
|
|
|
|
*end_ptr = next_token;
|
|
|
|
}
|
2001-05-18 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; control[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
next_token = strstr (text, control[i]);
|
|
|
|
if (next_token)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
if (*end_ptr)
|
|
|
|
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
|
|
|
else
|
|
|
|
*end_ptr = next_token;
|
|
|
|
}
|
2001-05-18 16:28:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
|
|
|
|
static void
|
2004-10-28 15:00:05 +00:00
|
|
|
fontify (void)
|
2001-05-18 16:28:30 +00:00
|
|
|
{
|
|
|
|
GtkTextIter start_iter, next_iter, tmp_iter;
|
|
|
|
gint state;
|
|
|
|
gchar *text;
|
|
|
|
gchar *start_ptr, *end_ptr;
|
|
|
|
gchar *tag;
|
|
|
|
|
|
|
|
state = STATE_NORMAL;
|
|
|
|
|
|
|
|
gtk_text_buffer_get_iter_at_offset (source_buffer, &start_iter, 0);
|
|
|
|
|
|
|
|
next_iter = start_iter;
|
|
|
|
while (gtk_text_iter_forward_line (&next_iter))
|
|
|
|
{
|
|
|
|
gboolean start = TRUE;
|
|
|
|
start_ptr = text = gtk_text_iter_get_text (&start_iter, &next_iter);
|
|
|
|
|
|
|
|
do
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
parse_chars (start_ptr, &end_ptr, &state, &tag, start);
|
|
|
|
|
|
|
|
start = FALSE;
|
|
|
|
if (end_ptr)
|
|
|
|
{
|
|
|
|
tmp_iter = start_iter;
|
|
|
|
gtk_text_iter_forward_chars (&tmp_iter, end_ptr - start_ptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp_iter = next_iter;
|
|
|
|
}
|
|
|
|
if (tag)
|
|
|
|
gtk_text_buffer_apply_tag_by_name (source_buffer, tag, &start_iter, &tmp_iter);
|
|
|
|
|
|
|
|
start_iter = tmp_iter;
|
|
|
|
start_ptr = end_ptr;
|
|
|
|
}
|
2001-05-18 16:28:30 +00:00
|
|
|
while (end_ptr);
|
|
|
|
|
|
|
|
g_free (text);
|
|
|
|
start_iter = next_iter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-18 04:48:57 +00:00
|
|
|
static GtkWidget *create_text (GtkTextBuffer **buffer, gboolean is_source);
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_data_tab (const gchar *filename)
|
|
|
|
{
|
|
|
|
GtkTextBuffer *buffer = NULL;
|
|
|
|
gchar *full_filename;
|
|
|
|
GError *err = NULL;
|
|
|
|
gchar *text;
|
|
|
|
GtkWidget *widget, *label;
|
|
|
|
|
|
|
|
full_filename = demo_find_file (filename, &err);
|
|
|
|
if (!full_filename ||
|
|
|
|
!g_file_get_contents (full_filename, &text, NULL, &err))
|
|
|
|
{
|
|
|
|
g_warning ("%s", err->message);
|
|
|
|
g_error_free (err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
widget = create_text (&buffer, FALSE);
|
|
|
|
gtk_widget_show_all (widget);
|
|
|
|
label = gtk_label_new (filename);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
|
|
|
|
|
|
|
|
gtk_text_buffer_set_text (buffer, text, -1);
|
|
|
|
|
|
|
|
g_free (full_filename);
|
|
|
|
g_free (text);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
remove_data_tabs (void)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) - 1; i > 1; i--)
|
|
|
|
gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), i);
|
|
|
|
}
|
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
void
|
2000-10-26 00:36:47 +00:00
|
|
|
load_file (const gchar *filename)
|
2000-10-18 15:50:13 +00:00
|
|
|
{
|
|
|
|
FILE *file;
|
|
|
|
GtkTextIter start, end;
|
2001-11-23 21:46:44 +00:00
|
|
|
char *full_filename;
|
|
|
|
GError *err = NULL;
|
2000-10-18 15:50:13 +00:00
|
|
|
GString *buffer = g_string_new (NULL);
|
|
|
|
int state = 0;
|
|
|
|
gboolean in_para = 0;
|
2012-05-18 04:48:57 +00:00
|
|
|
gchar **names;
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
remove_data_tabs ();
|
|
|
|
|
|
|
|
names = g_strsplit (filename, " ", -1);
|
|
|
|
|
|
|
|
for (i = 1; names[i]; i++)
|
|
|
|
add_data_tab (names[i]);
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2012-05-18 04:48:57 +00:00
|
|
|
if (current_file && !strcmp (current_file, names[0]))
|
2001-02-13 05:44:47 +00:00
|
|
|
{
|
|
|
|
g_string_free (buffer, TRUE);
|
|
|
|
return;
|
|
|
|
}
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
g_free (current_file);
|
2012-05-18 04:48:57 +00:00
|
|
|
current_file = g_strdup (names[0]);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
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);
|
|
|
|
|
2012-05-18 04:48:57 +00:00
|
|
|
full_filename = demo_find_file (names[0], &err);
|
2001-11-23 21:46:44 +00:00
|
|
|
if (!full_filename)
|
|
|
|
{
|
|
|
|
g_warning ("%s", err->message);
|
|
|
|
g_error_free (err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-12-05 12:47:42 +00:00
|
|
|
file = g_fopen (full_filename, "r");
|
2000-11-13 04:36:38 +00:00
|
|
|
|
|
|
|
if (!file)
|
2001-11-23 21:46:44 +00:00
|
|
|
g_warning ("Cannot open %s: %s\n", full_filename, g_strerror (errno));
|
2000-11-13 04:36:38 +00:00
|
|
|
|
2001-11-23 21:46:44 +00:00
|
|
|
g_free (full_filename);
|
2000-11-13 04:36:38 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
if (!file)
|
2001-11-23 21:46:44 +00:00
|
|
|
return;
|
2000-10-18 15:50:13 +00:00
|
|
|
|
|
|
|
gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
|
|
|
|
while (read_line (file, buffer))
|
|
|
|
{
|
|
|
|
gchar *p = buffer->str;
|
|
|
|
gchar *q;
|
2001-10-02 18:54:05 +00:00
|
|
|
gchar *r;
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
switch (state)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
/* Reading title */
|
|
|
|
while (*p == '/' || *p == '*' || g_ascii_isspace (*p))
|
|
|
|
p++;
|
|
|
|
r = p;
|
2012-05-26 00:39:59 +00:00
|
|
|
while (*r != '\0')
|
|
|
|
{
|
|
|
|
while (*r != '/' && *r != ':' && *r != '\0')
|
|
|
|
r++;
|
|
|
|
if (*r == '/')
|
|
|
|
{
|
|
|
|
r++;
|
|
|
|
p = r;
|
|
|
|
}
|
|
|
|
if (r[0] == ':' && r[1] == ':')
|
|
|
|
*r = '\0';
|
|
|
|
}
|
2011-09-02 03:55:47 +00:00
|
|
|
q = p + strlen (p);
|
|
|
|
while (q > p && g_ascii_isspace (*(q - 1)))
|
|
|
|
q--;
|
|
|
|
|
2012-05-18 04:48:57 +00:00
|
|
|
|
2011-09-02 03:55:47 +00:00
|
|
|
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;
|
|
|
|
|
2012-05-23 17:39:47 +00:00
|
|
|
while (*p && *p != '\n') p++;
|
2012-05-18 04:48:57 +00:00
|
|
|
|
2011-09-02 03:55:47 +00:00
|
|
|
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;
|
|
|
|
}
|
2000-10-18 15:50:13 +00:00
|
|
|
}
|
|
|
|
|
2007-01-11 14:26:51 +00:00
|
|
|
fclose (file);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2001-05-18 16:28:30 +00:00
|
|
|
fontify ();
|
2001-02-13 05:44:47 +00:00
|
|
|
|
|
|
|
g_string_free (buffer, TRUE);
|
2012-05-18 04:48:57 +00:00
|
|
|
|
|
|
|
g_strfreev (names);
|
2000-10-18 15:50:13 +00:00
|
|
|
}
|
|
|
|
|
2001-04-18 18:09:18 +00:00
|
|
|
void
|
2001-03-16 23:22:46 +00:00
|
|
|
row_activated_cb (GtkTreeView *tree_view,
|
2001-04-18 18:09:18 +00:00
|
|
|
GtkTreePath *path,
|
2011-09-02 03:55:47 +00:00
|
|
|
GtkTreeViewColumn *column)
|
2001-03-16 23:22:46 +00:00
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
2006-08-16 23:32:07 +00:00
|
|
|
PangoStyle style;
|
2001-03-16 23:22:46 +00:00
|
|
|
GDoDemoFunc func;
|
|
|
|
GtkWidget *window;
|
2001-04-18 18:09:18 +00:00
|
|
|
GtkTreeModel *model;
|
|
|
|
|
|
|
|
model = gtk_tree_view_get_model (tree_view);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2001-03-16 23:22:46 +00:00
|
|
|
gtk_tree_model_get_iter (model, &iter, path);
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (model),
|
2011-09-02 03:55:47 +00:00
|
|
|
&iter,
|
|
|
|
FUNC_COLUMN, &func,
|
|
|
|
STYLE_COLUMN, &style,
|
|
|
|
-1);
|
2001-04-18 18:09:18 +00:00
|
|
|
|
2001-10-02 18:54:05 +00:00
|
|
|
if (func)
|
2001-03-16 23:22:46 +00:00
|
|
|
{
|
2001-10-02 18:54:05 +00:00
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (model),
|
2011-09-02 03:55:47 +00:00
|
|
|
&iter,
|
|
|
|
STYLE_COLUMN, (style == PANGO_STYLE_ITALIC ? PANGO_STYLE_NORMAL : PANGO_STYLE_ITALIC),
|
|
|
|
-1);
|
2003-11-08 22:08:05 +00:00
|
|
|
window = (func) (gtk_widget_get_toplevel (GTK_WIDGET (tree_view)));
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2001-10-02 18:54:05 +00:00
|
|
|
if (window != NULL)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
CallbackData *cbdata;
|
|
|
|
|
|
|
|
cbdata = g_new (CallbackData, 1);
|
|
|
|
cbdata->model = model;
|
|
|
|
cbdata->path = gtk_tree_path_copy (path);
|
|
|
|
|
|
|
|
g_signal_connect (window, "destroy",
|
|
|
|
G_CALLBACK (window_closed_cb), cbdata);
|
|
|
|
}
|
2001-03-16 23:22:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
static void
|
|
|
|
selection_cb (GtkTreeSelection *selection,
|
2011-09-02 03:55:47 +00:00
|
|
|
GtkTreeModel *model)
|
2000-10-18 15:50:13 +00:00
|
|
|
{
|
2000-10-26 00:36:47 +00:00
|
|
|
GtkTreeIter iter;
|
2011-09-30 15:31:04 +00:00
|
|
|
GValue value = G_VALUE_INIT;
|
2000-10-26 00:36:47 +00:00
|
|
|
|
2000-11-09 16:52:17 +00:00
|
|
|
if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
|
2000-10-26 00:36:47 +00:00
|
|
|
return;
|
|
|
|
|
2000-10-27 23:34:58 +00:00
|
|
|
gtk_tree_model_get_value (model, &iter,
|
2011-09-02 03:55:47 +00:00
|
|
|
FILENAME_COLUMN,
|
|
|
|
&value);
|
2001-10-02 18:54:05 +00:00
|
|
|
if (g_value_get_string (&value))
|
|
|
|
load_file (g_value_get_string (&value));
|
2000-10-26 00:36:47 +00:00
|
|
|
g_value_unset (&value);
|
2000-10-18 15:50:13 +00:00
|
|
|
}
|
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
static GtkWidget *
|
2000-10-18 15:50:13 +00:00
|
|
|
create_text (GtkTextBuffer **buffer,
|
2011-09-02 03:55:47 +00:00
|
|
|
gboolean is_source)
|
2000-10-18 15:50:13 +00:00
|
|
|
{
|
|
|
|
GtkWidget *scrolled_window;
|
|
|
|
GtkWidget *text_view;
|
|
|
|
PangoFontDescription *font_desc;
|
|
|
|
|
|
|
|
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
|
2011-09-02 03:55:47 +00:00
|
|
|
GTK_POLICY_AUTOMATIC,
|
|
|
|
GTK_POLICY_AUTOMATIC);
|
2000-10-18 15:50:13 +00:00
|
|
|
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
|
2011-09-02 03:55:47 +00:00
|
|
|
GTK_SHADOW_IN);
|
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
text_view = gtk_text_view_new ();
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
*buffer = gtk_text_buffer_new (NULL);
|
|
|
|
gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), *buffer);
|
|
|
|
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
|
|
|
|
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_view), FALSE);
|
|
|
|
|
2001-06-14 22:25:23 +00:00
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
if (is_source)
|
|
|
|
{
|
2005-01-13 15:55:57 +00:00
|
|
|
font_desc = pango_font_description_from_string ("monospace");
|
2010-11-25 03:40:19 +00:00
|
|
|
gtk_widget_override_font (text_view, font_desc);
|
2000-10-18 15:50:13 +00:00
|
|
|
pango_font_description_free (font_desc);
|
2001-04-18 18:09:18 +00:00
|
|
|
|
|
|
|
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view),
|
|
|
|
GTK_WRAP_NONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Make it a bit nicer for text. */
|
|
|
|
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view),
|
|
|
|
GTK_WRAP_WORD);
|
|
|
|
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (text_view),
|
|
|
|
2);
|
|
|
|
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (text_view),
|
|
|
|
2);
|
2000-10-18 15:50:13 +00:00
|
|
|
}
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
return scrolled_window;
|
|
|
|
}
|
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
static GtkWidget *
|
|
|
|
create_tree (void)
|
|
|
|
{
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
GtkCellRenderer *cell;
|
|
|
|
GtkWidget *tree_view;
|
2000-11-13 06:08:17 +00:00
|
|
|
GtkTreeViewColumn *column;
|
|
|
|
GtkTreeStore *model;
|
2000-10-26 00:36:47 +00:00
|
|
|
GtkTreeIter iter;
|
2005-06-28 03:42:55 +00:00
|
|
|
GtkWidget *box, *label, *scrolled_window;
|
2001-10-02 18:54:05 +00:00
|
|
|
|
2012-01-14 23:22:33 +00:00
|
|
|
Demo *d = gtk_demos;
|
2000-10-26 00:36:47 +00:00
|
|
|
|
2006-08-16 23:32:07 +00:00
|
|
|
model = gtk_tree_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT);
|
2001-12-04 23:42:27 +00:00
|
|
|
tree_view = gtk_tree_view_new ();
|
|
|
|
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (model));
|
2000-10-26 00:36:47 +00:00
|
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
|
|
|
|
|
2001-01-05 19:09:38 +00:00
|
|
|
gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
|
2011-09-02 03:55:47 +00:00
|
|
|
GTK_SELECTION_BROWSE);
|
fix a typo.
2001-08-07 Havoc Pennington <hp@pobox.com>
* gtk/gtkfilesel.c (open_ref_dir): fix a typo.
* gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
some fixage is needed here, but nothing simple. Owen understands
it. ;-)
* gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
sizing and positioning. Also, fix bug in compute_geometry_hints
(width/height confusion for setting min size).
(gtk_window_move): new function
(gtk_window_resize): new function
(gtk_window_get_size): new function
(gtk_window_get_position): new function
(gtk_window_parse_geometry): new function
* gtk/gtkwidget.c (gtk_widget_set_size_request): new function
(gtk_widget_get_size_request): new function
(gtk_widget_get_usize): delete, that was a short-lived function
;-)
(gtk_widget_set_usize): deprecate
(gtk_widget_set_uposition): deprecate, make it a trivial
gtk_window_move() wrapper
(gtk_widget_class_init): remove x/y/width/height properties,
add width_request height_request
* demos/*: update to avoid deprecated functions
* gtk/gtklayout.c: add x/y child properties
* gtk/gtkfixed.c: add x/y child properties, and get rid of
uses of "gint16"
* tests/testgtk.c (create_window_sizing): lots of tweaks to window
sizing test
* gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
configure events on toplevel windows are always in root window
coordinates, following ICCCM spec that all synthetic events
are in root window coords already, while real events are
in parent window coords. Previously the code assumed that
coords of 0,0 were parent window coords, which was
really broken.
* gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
warning
* gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
and GDK_HINT_USER_SIZE so we can set USSize and USPosition
hints in gtk_window_parse_geometry()
* gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
new USER_POS USER_SIZE hints
2001-08-10 03:46:08 +00:00
|
|
|
gtk_widget_set_size_request (tree_view, 200, -1);
|
2000-10-26 00:36:47 +00:00
|
|
|
|
2001-10-02 18:54:05 +00:00
|
|
|
/* this code only supports 1 level of children. If we
|
|
|
|
* want more we probably have to use a recursing function.
|
|
|
|
*/
|
|
|
|
while (d->title)
|
2000-10-26 00:36:47 +00:00
|
|
|
{
|
2001-10-02 18:54:05 +00:00
|
|
|
Demo *children = d->children;
|
|
|
|
|
2000-10-27 23:34:58 +00:00
|
|
|
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
|
|
|
|
|
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (model),
|
2011-09-02 03:55:47 +00:00
|
|
|
&iter,
|
|
|
|
TITLE_COLUMN, d->title,
|
|
|
|
FILENAME_COLUMN, d->filename,
|
|
|
|
FUNC_COLUMN, d->func,
|
|
|
|
STYLE_COLUMN, PANGO_STYLE_NORMAL,
|
|
|
|
-1);
|
2001-10-02 18:54:05 +00:00
|
|
|
|
|
|
|
d++;
|
|
|
|
|
|
|
|
if (!children)
|
2011-09-02 03:55:47 +00:00
|
|
|
continue;
|
|
|
|
|
2001-10-02 18:54:05 +00:00
|
|
|
while (children->title)
|
2011-09-02 03:55:47 +00:00
|
|
|
{
|
|
|
|
GtkTreeIter child_iter;
|
|
|
|
|
|
|
|
gtk_tree_store_append (GTK_TREE_STORE (model), &child_iter, &iter);
|
|
|
|
|
|
|
|
gtk_tree_store_set (GTK_TREE_STORE (model),
|
|
|
|
&child_iter,
|
|
|
|
TITLE_COLUMN, children->title,
|
|
|
|
FILENAME_COLUMN, children->filename,
|
|
|
|
FUNC_COLUMN, children->func,
|
|
|
|
STYLE_COLUMN, PANGO_STYLE_NORMAL,
|
|
|
|
-1);
|
|
|
|
|
|
|
|
children++;
|
|
|
|
}
|
2000-10-26 00:36:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cell = gtk_cell_renderer_text_new ();
|
remove validation idle
2001-02-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
validation idle
* demos/gtk-demo/main.c (create_tree): adjust to changes in text
cell renderer
* demos/pixbuf-demo.c (timeout): remove deprecated
gtk_widget_draw
* demos/testpixbuf-save.c (main): remove deprecated
gtk_drawing_area_size
* gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
buttons even if the model isn't setup. gtk_tree_view_check_dirty()
at the start of the allocation.
(gtk_tree_view_check_dirty): handle column->button == NULL, handle
unsetup or NULL model.
* gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the
even/odd/sorted cells in the tree view.
* gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
bugfixes
* gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
backgrounds with draw_flat_box using different detail for even/odd
rows.
* gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
row, so we can draw the alternating colors thing
* gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
property from a synonym property, notify for the synonym.
Also, nuke the background_gdk_set and foreground_gdk_set synonyms
(gtk_text_tag_get_property): Always return the font, even if
all its fields aren't set
* gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
store the attr list; it leaves us with no way to change attributes
in _render according to the render flags, and no way to implement
get_property. Instead store all the specific text attributes.
Separate whether an attribute is enabled from its value. Sync all
properties with GtkTextTag, make them all consistent, etc.
* gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
renderers can highlight the sort row/column
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
accessor functions to get values; this has the side effect of
showing up which accessor functions were missing. Added those.
* gtk/gtktreeviewcolumn.h: Replace set_justification with
set_alignment, to be consistent with GtkLabel, GtkMisc
* gtk/gtktreeviewcolumn.c: Added code to display sort indicator
arrow.
* gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
* gtk/gtktreesortable.h: updates in here
2001-02-08 23:36:53 +00:00
|
|
|
|
2000-11-13 06:08:17 +00:00
|
|
|
column = gtk_tree_view_column_new_with_attributes ("Widget (double click for demo)",
|
2011-09-02 03:55:47 +00:00
|
|
|
cell,
|
|
|
|
"text", TITLE_COLUMN,
|
|
|
|
"style", STYLE_COLUMN,
|
|
|
|
NULL);
|
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
|
2011-09-02 03:55:47 +00:00
|
|
|
GTK_TREE_VIEW_COLUMN (column));
|
2000-10-26 00:36:47 +00:00
|
|
|
|
2005-06-28 03:42:55 +00:00
|
|
|
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
|
|
|
|
gtk_tree_selection_select_iter (GTK_TREE_SELECTION (selection), &iter);
|
|
|
|
|
2001-10-20 23:39:32 +00:00
|
|
|
g_signal_connect (selection, "changed", G_CALLBACK (selection_cb), model);
|
|
|
|
g_signal_connect (tree_view, "row_activated", G_CALLBACK (row_activated_cb), model);
|
2000-10-26 00:36:47 +00:00
|
|
|
|
2005-06-28 03:42:55 +00:00
|
|
|
gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
|
|
|
|
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2005-06-28 03:42:55 +00:00
|
|
|
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
|
2011-09-02 03:55:47 +00:00
|
|
|
GTK_POLICY_NEVER,
|
|
|
|
GTK_POLICY_AUTOMATIC);
|
2005-06-28 03:42:55 +00:00
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Widget (double click for demo)");
|
|
|
|
|
|
|
|
box = gtk_notebook_new ();
|
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (box), scrolled_window, label);
|
|
|
|
|
|
|
|
gtk_widget_grab_focus (tree_view);
|
|
|
|
|
2006-12-23 02:39:45 +00:00
|
|
|
g_object_unref (model);
|
|
|
|
|
2005-06-28 03:42:55 +00:00
|
|
|
return box;
|
2000-10-26 00:36:47 +00:00
|
|
|
}
|
|
|
|
|
2001-08-29 02:20:02 +00:00
|
|
|
static void
|
|
|
|
setup_default_icon (void)
|
|
|
|
{
|
|
|
|
GdkPixbuf *pixbuf;
|
2001-11-23 21:46:44 +00:00
|
|
|
char *filename;
|
|
|
|
GError *err;
|
|
|
|
|
|
|
|
err = NULL;
|
2001-08-29 02:20:02 +00:00
|
|
|
|
2001-11-23 21:46:44 +00:00
|
|
|
pixbuf = NULL;
|
|
|
|
filename = demo_find_file ("gtk-logo-rgb.gif", &err);
|
|
|
|
if (filename)
|
2001-08-29 02:20:02 +00:00
|
|
|
{
|
2001-11-23 21:46:44 +00:00
|
|
|
pixbuf = gdk_pixbuf_new_from_file (filename, &err);
|
|
|
|
g_free (filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ignoring this error (passing NULL instead of &err above)
|
|
|
|
* would probably be reasonable for most apps. We're just
|
|
|
|
* showing off.
|
|
|
|
*/
|
|
|
|
if (err)
|
|
|
|
{
|
|
|
|
GtkWidget *dialog;
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2001-11-23 21:46:44 +00:00
|
|
|
dialog = gtk_message_dialog_new (NULL, 0,
|
2011-09-02 03:55:47 +00:00
|
|
|
GTK_MESSAGE_ERROR,
|
|
|
|
GTK_BUTTONS_CLOSE,
|
|
|
|
"Failed to read icon file: %s",
|
|
|
|
err->message);
|
2001-11-23 21:46:44 +00:00
|
|
|
g_error_free (err);
|
|
|
|
|
|
|
|
g_signal_connect (dialog, "response",
|
2011-09-02 03:55:47 +00:00
|
|
|
G_CALLBACK (gtk_widget_destroy), NULL);
|
2001-08-29 02:20:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pixbuf)
|
|
|
|
{
|
2011-09-02 03:55:47 +00:00
|
|
|
GList *list;
|
2001-09-14 21:24:57 +00:00
|
|
|
GdkPixbuf *transparent;
|
|
|
|
|
|
|
|
/* The gtk-logo-rgb icon has a white background, make it transparent */
|
|
|
|
transparent = gdk_pixbuf_add_alpha (pixbuf, TRUE, 0xff, 0xff, 0xff);
|
2001-08-29 02:20:02 +00:00
|
|
|
|
|
|
|
list = NULL;
|
2001-09-14 21:24:57 +00:00
|
|
|
list = g_list_append (list, transparent);
|
2001-08-29 02:20:02 +00:00
|
|
|
gtk_window_set_default_icon_list (list);
|
|
|
|
g_list_free (list);
|
2002-09-29 21:24:24 +00:00
|
|
|
g_object_unref (pixbuf);
|
|
|
|
g_object_unref (transparent);
|
2001-08-29 02:20:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
GtkWidget *window;
|
|
|
|
GtkWidget *hbox;
|
2000-10-26 00:36:47 +00:00
|
|
|
GtkWidget *tree;
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2001-05-07 15:58:47 +00:00
|
|
|
/* Most code in gtk-demo is intended to be exemplary, but not
|
|
|
|
* these few lines, which are just a hack so gtk-demo will work
|
|
|
|
* in the GTK tree without installing it.
|
|
|
|
*/
|
2012-01-14 23:22:33 +00:00
|
|
|
if (g_file_test ("../../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
|
2001-05-07 15:58:47 +00:00
|
|
|
{
|
2010-05-18 23:23:06 +00:00
|
|
|
g_setenv ("GTK_IM_MODULE_FILE", "../../modules/input/immodules.cache", TRUE);
|
2001-05-07 15:58:47 +00:00
|
|
|
}
|
|
|
|
/* -- End of hack -- */
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
gtk_init (&argc, &argv);
|
2001-08-29 02:20:02 +00:00
|
|
|
|
|
|
|
setup_default_icon ();
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
2001-04-18 18:09:18 +00:00
|
|
|
gtk_window_set_title (GTK_WINDOW (window), "GTK+ Code Demos");
|
2006-12-23 02:39:45 +00:00
|
|
|
g_signal_connect_after (window, "destroy",
|
2011-09-02 03:55:47 +00:00
|
|
|
G_CALLBACK (gtk_main_quit), NULL);
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2010-10-31 17:07:20 +00:00
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
2000-10-18 15:50:13 +00:00
|
|
|
gtk_container_add (GTK_CONTAINER (window), hbox);
|
|
|
|
|
2000-10-26 00:36:47 +00:00
|
|
|
tree = create_tree ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), tree, FALSE, FALSE, 0);
|
2000-10-18 15:50:13 +00:00
|
|
|
|
|
|
|
notebook = gtk_notebook_new ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0);
|
|
|
|
|
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
2011-09-02 03:55:47 +00:00
|
|
|
create_text (&info_buffer, FALSE),
|
|
|
|
gtk_label_new_with_mnemonic ("_Info"));
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2011-05-27 02:21:57 +00:00
|
|
|
gtk_text_buffer_create_tag (info_buffer, "title",
|
|
|
|
"font", "Sans 18",
|
|
|
|
NULL);
|
|
|
|
g_object_unref (info_buffer);
|
2006-12-23 02:39:45 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
2011-09-02 03:55:47 +00:00
|
|
|
create_text (&source_buffer, TRUE),
|
|
|
|
gtk_label_new_with_mnemonic ("_Source"));
|
2000-10-18 15:50:13 +00:00
|
|
|
|
2001-03-16 19:32:20 +00:00
|
|
|
|
2011-05-27 02:21:57 +00:00
|
|
|
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);
|
|
|
|
g_object_unref (source_buffer);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
|
|
|
gtk_widget_show_all (window);
|
|
|
|
|
2012-01-14 23:22:33 +00:00
|
|
|
load_file (gtk_demos[0].filename);
|
2011-09-02 03:55:47 +00:00
|
|
|
|
2000-10-18 15:50:13 +00:00
|
|
|
gtk_main ();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|