Re: turn on italics in TextView

2017-08-15 Thread Doug McCasland
Indeed, gtk_text_buffer_insert_with_tags_by_name() does what it says.  What
I was talking about was (in some future Textview) applying the tag to an
iter, then whenever the insert point was on that iter, it would inherit the
tag properties set there.  So typing at that point gets the formatting.

I don't have my code in front of me, but as I recall the jumpy-cursor thing
happened with this:

   1. Insert some text in a line.
   2. Apply indent 50px to whole line.  The line will be indented on the
   screen.
   3. Start typing at the beginning of line, which will not inherit the
   indent tag.  The indent will disappear on the screen.
   4. Move the cursor to the region with the applied indent -- the indent
   comes back.



On Tue, Aug 15, 2017 at 2:27 PM,  wrote:

>
> Have you tried gtk_text_buffer_insert_with_tags_by_name() to insert text
> with a tag at an iter?
>
> What tag combo do you use to get the cursor to bounce around? If I test
> having two indent tags on the same line, the first one applied wins out.
> This is what I tested with.
>
> Eric
>
>
> /*
>   gcc -Wall move_cursor1.c -o move_cursor1 `pkg-config --cflags --libs
> gtk+-3.0`
>   Tested on GTK3.18 and Ubuntu16.04
> */
>
> #include
>
> static void get_style(GtkTextView *tv, GtkMovementStep step, gint count,
> gboolean extend, gpointer *user_data)
>   {
> static int i=1;
> GtkTextIter start;
> GtkTextMark *mark;
> GtkTextBuffer *buf;
>
> buf=gtk_text_view_get_buffer(GTK_TEXT_VIEW(tv));
>
> mark=gtk_text_buffer_get_insert(buf);
> gtk_text_buffer_get_iter_at_mark (buf, , mark);
> g_print("Iter %i\n", gtk_text_iter_get_offset());
>
> GSList *tlist=NULL;
> GSList *p=NULL;
> tlist=gtk_text_iter_get_tags();
> g_print("%i. List %p p %p\n", i, tlist, p);
> i++;
> for(p=tlist;p;p=p->next)
>   {
> gchar *string=NULL;
> g_object_get(G_OBJECT(p->data), "name", , NULL);
> g_print("p %p %s\n", p, string);
> g_free(string);
>   }
>
> g_print("List %p\n", tlist);
> if(tlist!=NULL) g_slist_free(tlist);
>   }
> int main (int argc, char *argv[])
>   {
> gtk_init(, );
>
> GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
> gtk_window_set_title(GTK_WINDOW(window), "Move Cursor");
> gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
> gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
> g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
>
> GtkWidget *textview=gtk_text_view_new();
> gtk_widget_set_vexpand(textview, TRUE);
> gtk_widget_set_hexpand(textview, TRUE);
> g_signal_connect(textview, "move-cursor", G_CALLBACK(get_style), NULL);
>
> GtkTextBuffer *buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)
> );
> gtk_text_buffer_create_tag(buffer, "ital", "style",
> PANGO_STYLE_ITALIC, NULL);
> gtk_text_buffer_create_tag(buffer, "bold", "weight",
> PANGO_WEIGHT_BOLD, NULL);
> gtk_text_buffer_create_tag(buffer, "uline", "underline",
> PANGO_UNDERLINE_SINGLE, NULL);
> gtk_text_buffer_create_tag(buffer, "indent", "indent", 20, NULL);
> gtk_text_buffer_create_tag(buffer, "indent2", "indent", 40, NULL);
> gtk_text_buffer_create_tag(buffer, "left-margin", "left-margin", 20,
> NULL);
> gtk_text_buffer_create_tag(buffer, "left-margin2", "left-margin", 40,
> NULL);
>
> GtkTextIter iter;
> gtk_text_buffer_get_start_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "ital ", -1,
> "ital", NULL);
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "bold ", -1,
> "bold", NULL);
> gtk_text_buffer_get_end_iter(buffer, );
> //Check a newline for a tag.
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "uline \n",
> -1, "uline", NULL);
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "all\n", -1,
> "ital", "bold", "uline", NULL);
> //Check indents in the same line.
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "indent ",
> -1, "indent", NULL);
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "indent2\n",
> -1, "indent2", NULL);
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "indent2\n",
> -1, "indent2", NULL);
> //Check left-margin in the same line.
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, , "left-margin
> ", -1, "left-margin", NULL);
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, ,
> "left-margin2\n", -1, "left-margin2", NULL);
> gtk_text_buffer_get_end_iter(buffer, );
> gtk_text_buffer_insert_with_tags_by_name(buffer, ,
> "left-margin2", -1, "left-margin2", NULL);
>
> GtkWidget 

Re: turn on italics in TextView

2017-08-15 Thread Eric Cashon via gtk-app-devel-list

Have you tried gtk_text_buffer_insert_with_tags_by_name() to insert text with a 
tag at an iter?

What tag combo do you use to get the cursor to bounce around? If I test having 
two indent tags on the same line, the first one applied wins out. This is what 
I tested with.

Eric


/*
  gcc -Wall move_cursor1.c -o move_cursor1 `pkg-config --cflags --libs gtk+-3.0`
  Tested on GTK3.18 and Ubuntu16.04
*/

#include

static void get_style(GtkTextView *tv, GtkMovementStep step, gint count, 
gboolean extend, gpointer *user_data)
  {
static int i=1;
GtkTextIter start;
GtkTextMark *mark;
GtkTextBuffer *buf;

buf=gtk_text_view_get_buffer(GTK_TEXT_VIEW(tv));

mark=gtk_text_buffer_get_insert(buf);
gtk_text_buffer_get_iter_at_mark (buf, , mark);
g_print("Iter %i\n", gtk_text_iter_get_offset());

GSList *tlist=NULL;
GSList *p=NULL;
tlist=gtk_text_iter_get_tags();
g_print("%i. List %p p %p\n", i, tlist, p);
i++;
for(p=tlist;p;p=p->next)
  {
gchar *string=NULL;
g_object_get(G_OBJECT(p->data), "name", , NULL);
g_print("p %p %s\n", p, string);
g_free(string);
  }

g_print("List %p\n", tlist);
if(tlist!=NULL) g_slist_free(tlist);
  }
int main (int argc, char *argv[])
  {
gtk_init(, );

GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Move Cursor");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

GtkWidget *textview=gtk_text_view_new();
gtk_widget_set_vexpand(textview, TRUE);
gtk_widget_set_hexpand(textview, TRUE);
g_signal_connect(textview, "move-cursor", G_CALLBACK(get_style), NULL);

GtkTextBuffer *buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
gtk_text_buffer_create_tag(buffer, "ital", "style", PANGO_STYLE_ITALIC, 
NULL);
gtk_text_buffer_create_tag(buffer, "bold", "weight", PANGO_WEIGHT_BOLD, 
NULL);
gtk_text_buffer_create_tag(buffer, "uline", "underline", 
PANGO_UNDERLINE_SINGLE, NULL);
gtk_text_buffer_create_tag(buffer, "indent", "indent", 20, NULL);
gtk_text_buffer_create_tag(buffer, "indent2", "indent", 40, NULL);
gtk_text_buffer_create_tag(buffer, "left-margin", "left-margin", 20, NULL); 
gtk_text_buffer_create_tag(buffer, "left-margin2", "left-margin", 40, 
NULL); 

GtkTextIter iter;
gtk_text_buffer_get_start_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "ital ", -1, 
"ital", NULL);
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "bold ", -1, 
"bold", NULL);
gtk_text_buffer_get_end_iter(buffer, );
//Check a newline for a tag.
gtk_text_buffer_insert_with_tags_by_name(buffer, , "uline \n", -1, 
"uline", NULL);
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "all\n", -1, 
"ital", "bold", "uline", NULL);
//Check indents in the same line.
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "indent ", -1, 
"indent", NULL);
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "indent2\n", -1, 
"indent2", NULL);
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "indent2\n", -1, 
"indent2", NULL);
//Check left-margin in the same line.
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "left-margin ", -1, 
"left-margin", NULL);
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "left-margin2\n", 
-1, "left-margin2", NULL);
gtk_text_buffer_get_end_iter(buffer, );
gtk_text_buffer_insert_with_tags_by_name(buffer, , "left-margin2", -1, 
"left-margin2", NULL);

GtkWidget *grid=gtk_grid_new();
gtk_container_set_border_width(GTK_CONTAINER(grid), 8);
gtk_grid_attach(GTK_GRID(grid), textview, 0, 0, 1, 1);

gtk_container_add(GTK_CONTAINER(window), grid);

gtk_widget_show_all(window);

gtk_main();

return 0;
  }
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: turn on italics in TextView

2017-08-15 Thread Doug McCasland
Heh-heh, yes that for loop does look better :-)  I'll use that.

Textview is awesome and will save me thousands of lines of code, but not
being able to apply a tag to an iter -- that has been a big drawback for
me.  You can discover a tag at an iter, but only apply/remove it to a
range.  It would be great to be able to apply a style tag at an iter
(including in a blank line) and then have text inserted their use that tag.

One more suggestion for GTK Textview -- this is about the margin and indent
tags.  I found that you can apply those tags anywhere in a line and even
multiple times.  So in a 100-char line, you can have chars 33-45 with an
indent of 100px, and chars 63-88 with an indent of -50px, etc.  And in
addition various left-margins.  When you move the cursor through such a
line, the cursor bounces around like crazy and the line is reformatted back
and forth.  I cannot imagine why anyone would want this.  Such tags should
only apply to whole lines, and only one indent or left-margin tag per
line.  As it is, the applied indent and margin tags are hard to manage and
cause too much trouble.


On Tue, Aug 15, 2017 at 11:34 AM,  wrote:

>
>
> Hi Doug,
>
> I made a bit of a pointer mess there. Not the best of answers or way to go
> about iterating through a list. Looking at some GTK code, this is better
> done with a for loop. As usual, you don't want to move the pointer you get
> from gtk_text_iter_get_tags() and then free it. This will cause you grief
> later on along with buggy code that may not be so easy to debug.
>
> Very glad you got things working well even with a less than good answer.
> Need to be careful of the pointers myself.
>
> Eric
>
>
> GSList *tlist=NULL;
> GSList *p=NULL;
> tlist=gtk_text_iter_get_tags();
> g_print("List %p p %p\n", tlist, p);
> for(p=tlist;p;p=p->next)
>   {
> gchar *string=NULL;
> g_object_get(G_OBJECT(p->data), "name", , NULL);
> g_print("p %p %s\n", p, string);
> g_free(string);
>   }
>
> g_print("List %p\n", tlist);
> if(tlist!=NULL) g_slist_free(tlist);
>



-- 
Doug McCasland   
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: turn on italics in TextView

2017-08-15 Thread Eric Cashon via gtk-app-devel-list

 


Hi Doug,

I made a bit of a pointer mess there. Not the best of answers or way to go 
about iterating through a list. Looking at some GTK code, this is better done 
with a for loop. As usual, you don't want to move the pointer you get from 
gtk_text_iter_get_tags() and then free it. This will cause you grief later on 
along with buggy code that may not be so easy to debug.

Very glad you got things working well even with a less than good answer. Need 
to be careful of the pointers myself.

Eric


GSList *tlist=NULL;
GSList *p=NULL;
tlist=gtk_text_iter_get_tags();
g_print("List %p p %p\n", tlist, p);
for(p=tlist;p;p=p->next)
  {
gchar *string=NULL;
g_object_get(G_OBJECT(p->data), "name", , NULL);
g_print("p %p %s\n", p, string);
g_free(string);
  }

g_print("List %p\n", tlist);
if(tlist!=NULL) g_slist_free(tlist);
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: turn on italics in TextView

2017-08-15 Thread Doug McCasland
Eric, thanks again.

I ended up using g_signal_connect() on "key-press-event" (instead of
"insert-text").  This makes it easier IMO to handle specific cases, since
the callback fn can return TRUE if it did anything or FALSE to get GTK
default behavior, unlike void insert-text fn.  Plus if you paste 2
chars, the insert-text callback will process every one of them, whereas
key-press-event will get none of them.

I think I tried to do my own version of the move-cursor and change
italic/bold state buttons, but abandoned it, don't remember why.  But I
took the advice to "store" the italic/bold states in the toolbar button
states.  It's a little quirky since the text cursor can move away from an
italic/bold region and still the i/b tutton, if already pressed, stays that
way and so typing at the new cursor location is i/b.

Anyway, with Italic button pressed, for example, I get the char via
key-press-event.  (If style tool button not pressed, then return FALSE).
The characters are just keycodes at this point, so need to kick back most
of them to default:

switch (event->keyval)  {
case GDK_KEY_Return:
case GDK_KEY_Delete:
case GDK_KEY_Shift_L:
case GDK_KEY_Shift_R:
case GDK_KEY_Alt_L:
case GDK_KEY_Alt_R:
case GDK_KEY_Control_L:
case GDK_KEY_Up:
case GDK_KEY_Down:
case GDK_KEY_Left:
case GDK_KEY_Right:
case GDK_KEY_End:
case GDK_KEY_Home:
// case GDK_KEY_BackSpace:
return FALSE;
}

or you get the first letter after "GDK_KEY_".  Still haven't fixed up the
backspace case.  Then call

text = gdk_keyval_name(event->keyval);

If strlen(text) > 1, then go through this exercise:

switch (event->keyval)  {
case GDK_KEY_exclam: text = "!"; break;
case GDK_KEY_quotedbl: text = "\""; break;
case GDK_KEY_numbersign: text = "#"; break;
case GDK_KEY_dollar: text = "$"; break;
case GDK_KEY_percent: text = "%"; break;
case GDK_KEY_ampersand: text = "&"; break;
case GDK_KEY_apostrophe: text = "'"; break;
case GDK_KEY_parenleft: text = "("; break;
case GDK_KEY_parenright: text = ")"; break;
case GDK_KEY_asterisk: text = "*"; break;
case GDK_KEY_plus: text = "+"; break;
case GDK_KEY_colon: text = ":"; break;
case GDK_KEY_less: text = "<"; break;
case GDK_KEY_greater: text = ">"; break;
case GDK_KEY_question: text = "?"; break;
case GDK_KEY_at: text = "@"; break;
case GDK_KEY_underscore: text = "_"; break;
case GDK_KEY_braceleft: text = "{"; break;
case GDK_KEY_bar: text = "|"; break;
case GDK_KEY_braceright: text = "}"; break;
case GDK_KEY_asciitilde: text = "~"; break;
}

Then after all that malarkey, simply insert the char, get the iters around
it, and apply the style to it.  Then return TRUE.

So this works pretty good (good enough :-) ).

Even though I didn't use your suggested code

GSList *tlist=NULL;
GSList *next=NULL;
tlist=gtk_text_iter_get_tags();
if(tlist!=NULL)
  {
do
  {
next=tlist->next;
gchar *string=NULL;
g_object_get(G_OBJECT(tlist->data), "name", , NULL);
g_print("%s\n", string);
g_free(string);
tlist=g_slist_next(tlist);
  }while(next!=NULL);
   }
else g_print("No Tags\n");

if(tlist!=NULL) g_slist_free(tlist);

after cursor motion, I did deploy that elsewhere to find format tags (for
example in exporting to HTML, for which I have a crude version).  Once
again thanks for that do-while tlist loop -- I *never* would've figured out
how to write that!

--Doug


On Tue, Jun 20, 2017 at 10:47 PM,  wrote:

>
> On that last post, I think that I have some bad pointer arithmetic. Moving
> a pointer past the end and freeing a moved pointer. Not so good.
>
> Eric
>
> ...
> GSList *tlist=NULL;
> GSList *p=NULL;
> GSList *next=NULL;
> tlist=gtk_text_iter_get_tags();
> p=tlist;
> if(tlist!=NULL)
>   {
> do
>   {
> next=p->next;
> gchar *string=NULL;
> g_object_get(G_OBJECT(p->data), "name", , NULL);
> g_print("%s\n", string);
> g_free(string);
> if(next!=NULL)p=g_slist_next(p);
>   }while(next!=NULL);
>}
> else g_print("No Tag\n");
>
> if(tlist!=NULL) g_slist_free(tlist);
> ...
>
>
> -Original Message-
> From: Eric Cashon via gtk-app-devel-list 
> To: dougm 
> Cc: gtk-app-devel-list 
> Sent: Tue, Jun 20, 2017 4:48 pm
> Subject: Re: turn on italics in TextView
>
>
>
> Another