Posts

Showing posts from 2011

More on Pango Markup Strings

Image
I don't like fiddling around with markup strings, even at the best of times. So, any convienient way of producing the right formatting is welcome news to me. Gtk widgets allow markupstrings for various text elements. So, I thought, how about creating strings on the fly using familiar Tcl means. Hence the following two procs below. One will create markup and the other remove it. The removal method is still basic, it will also strip out markup-like items such as <b> so its use is limited. It is also assumed that there will only be one "<span"  entry per string. Modifying the code to remove more that one <span group should not be too much of an issue.

The need behind creating these procs comes from wanting to quickly add/remove markup strings from tree/listview cells.

#---------------
# pango_string.tcl
#---------------
# !/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"
package require Gnocl

#---------------
# Create Pango formatte…

gnocl::list add

Image
I've finished taking a look at enhancing the add sub-command ensuring bakcward compatibility with the legacy effects. This snippet shows how it works:

widget-idadd rowNum data options

$list add    { "A" 1 } -singleRow 1    ;# 1
$list add {} { "B" 2 } -singleRow 1    ;# 2
$list add  0 { "C" 3 } -singleRow 1    ;# 3
$list add -1 { "D" 4 } -singleRow 1    ;# 4
$list add  3 { "E" 5 } -singleRow 1    ;# 5

In order for the interpretor to know which row to use the second argument needs to be an integer. '0' means insert at the top of the list with -1 the bottom. In a pre-existing list, any other positive value in between will insert at the appropriate level. If the specified row is a value that exceeds the length of the list, the item will be appended to the end.
The command returns the number of the row just inserted.

Finally, providing a non integer values will also result in appending the value to the bottom of the list unless an empty…

**NEW COMMAND** gnocl::showURI

Image
A simple wrapper around the gtk_show_uri utility function. This will launch the GNOME default applications for mailing and browsing.

Rather than explicitly calling a browser with:

$m4 configure -onClicked "
        exec firefox http://www.buddhism-dict.net/cgi-bin/xpr-ddb.pl?q=[$w get selectionStart selectionEnd] &
        "

The same effect can be achieved with

$m4 configure -onClicked "
        gnocl::showURI "http://www.buddhism-dict.net/cgi-bin/xpr-ddb.pl?q=[$w get selectionStart selectionEnd]
        "

gnocl::text new option -data, new command cget

Image
Been adding a few tweaks to the code today. Added the -data option and the cget command. Also slightly modified the percentage substitution strings for the gnocl::entry -onIconPress event handler. Hitherto %t would have provided details about a the mousebutton event. It makes more sense to us %b allowing %t to be used to substitute the contents of the entry buffer.

Finally, I'm working on a simple text editing widget to add to the gnocl::megawidgets package. Its nothing fancy, no rich text editing, just a simple scribble pad to embed in those app which might need it!

gnocl::paned

Image
Ok, there's not much left to do with this one but... Added a cget command which enable some simple querying. Still working on the binding for the handle move. For some reason there's no binding for mouse operations, just keyboard adjustment.

gnocl::calendar

Had some feedback today on the gnocl::calendar. I've taken a look at the developement sources and have now wrapped my debugging/testing lines in #ifdef blocks. This means that users will not be inundated with debugging messages. There will still be cases, however, when the Gtk+ libraries write warning and error messages to the console.The revised version is now available from SourceForge.

gnocl::fileChooser completed support for multiple file type filters

Image
Wanted to fix this one for some time. Basically, this allows multiple file filters to be set for the dialog. The sample script explains all.


# basic Tcl/Gnocl Script
#!/bin/sh \
exec tclsh "$0" "$@"
package require Gnocl

set ff1 [gnocl::fileFilter -name "Source Code" -pattern {*.tcl *.c} ]
set ff2 [gnocl::fileFilter -name "Text Files" -pattern {*.odt *.doc *.rtf *.abw} ]
set ff3 [gnocl::fileFilter -name "Image Files" -pattern {*.png *.jpg *.bmp *.tif} ]

gnocl::fileChooserDialog \
            -fileFilters [list $ff1 $ff2 $ff3]
            -currentFolder [pwd] \
            -title "Open Jiumoluo Project File"

15mins later....

Urgh, something always goes wrong. It looks like the destruction of the dialog window also results in the destuction of the file filters object too! I'll rework the code so that the filters are maintained as a list on the Tcl side; something along the lines of:

set filters {Filter1Name {*.A  *.B *.C} Fi…

gnocl::text getting tag names and properties

Image
Just added another useful tag sub-command: properties. This command is pretty useful for obtaining the non-default property settings for text tags. For example;

foreach t [lsort [$::petxt tag names]] {
    puts "$t [$::petxt tag properties $t]"
}



Displaying pango strings in a gnocl::text widget.

Image
After deciding that I'd wasted enough time looking at C coding to convert pango markup strings to text tags, I decided to script in Tcl. Got the project completed in less than an hour! Ok, there are some trade-offs, this is why the GtkText does not handle pango. It relies upon tags, and not markup strings. There is some code out there to render pango in a textview but, it will create new tags each and every time a text attribute changes. What I want to achieve is pango in and pango out. I've now got something working in Tcl which meets my needs but makes some compromises. In order to use tags, and not markup, only a limited range of settings are available. As I want the basics to change the font styling and the fg/bg colours for highlighting, I can be satisfied with a limited tag set. To make life easier, I've also named these after the pango markup. These make for some pretty unusual markup-strings, but hey - they work!

The following script reveals all.



# test-pango-text-…

Return to coding!

Image
Its been almost a month since a last posting. How time flies. Most of my time has been taken up between making some final adjustments to my Ph.D thesis prior to submission and chasing up a whole pile of work related matters. But now, for a while at least, I can give some more attention to Gnocl. The last issue that I was working was inserting/retrieving Pango markup strings with a GtkTextBuffer. After solving something of a glitch in adding tags to single characters (I'd completely forgotten that iters are invalid after changes to the content of text buffer. Resolved the problem through the use of markers as in function that I've just added to the code:

        GtkTextMark *tagStart, *tagEnd;
        GtkTextIter start, end;

        tagStart  = gtk_text_buffer_create_mark (buffer,"tagStart", iter, 1);           

        gtk_text_buffer_insert  (buffer, iter, txt, -1);

        tagEnd = gtk_text_buffer_get_insert(buffer);

        applyTags (buffer, tag, tagStart, ta…

More on generating pango strings...

This is not so easy a 'nut to crack'. I've noticed that the solution that I've come up with so far fails to implement nested markup, ie <b> <s> text </s></b>. Conversely, getting the <span> </span> block is an issue too! Clearly there is a need for this functionality, but there is no clear solution that I can find. The Gimp developers are working on something similar but I notice that they have problems with <span> too!

So, I've gone back to basics. Rather than relying the pango string parser, I'll put something together of my own. Today I've been working on some extra string funcs. Here's what I've produced so far:

/*
gcc -o first first.c
*/

#include <stdio.h>
#include <string.h>

/**
    search for first occurance of p in s, starting from i
    done
**/
int strnfrst(char *s, char *p, int i)
{
        char *f;
        int l;

        l = strlen(p);  /* length of search string */
        f = s+i;

        /* search …

gnocl::rtf

Just created a binding to the Osxcart module which provided rtf import and export for GtkTextBuffers. Its a lot of coding for what is effectively a couple of library calls! The API allows for loading from files, but it seems more appropriate to import and export strings.

#--------------- # test-rtf.tcl #--------------- # Created by William J Giddings # 07-August-2011 #--------------- # Description: # Import/Export rtf formatted files from gnocl::text widgets. #---------------
#!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@"
package require Gnocl package require GnoclOsxCart
set txt [gnocl::text]
gnocl::window -child $txt
gnocl::rtf register $txt
set fp1 [open "p006a_hello_world.rtf" "r"] set fp2 [open "test.rtf" "w"]
gnocl::rtf import $txt [read $fp1] close $fp1
puts $fp2 [gnocl::rtf export $txt] close $fp2

New Sourcecode Module textTag.c

Added a new module to the core source, textTag.c. The creation of this module is simply to separate out tag related functions from the the text.c module. It looks like this will be a hefty file. The tag object has a great number of properties that need to be wrapped.

The timing of this corresponds to expanding the gnocl::text widget functionality to enable the 'dump' of buffer contents in a manner similar to Tk. Got most of it working now.

Loading a simple tag table

Here's a quick way of creating multiple tags in one go.

set tagTable {     {{Header 1} -font {Sans 12 Bold} }     {{Header 2} -font {Sans 10 Bold} }     {{Body} -font {Serif 10} -wrapMode word } }
foreach {a} $tagTable {     eval "$txt tag create $a" }
$txt insert end \n $txt insert end MANTRA\n -tags { {Header 1} } $txt insert end "Om Ah Hum\n" -tags Body

gnocl::text tags

Still working on extending the text tag functionality. Its quite interesting really as it requires more understanding of the really powerful Tcl command libraries to build lists etc. Today I've added some extra functionality which pretty well follows the same guidelines of the Tk text widget, i.e.  tag names, raise and lower.

I'm still working on the robust parsing of tag options. One little tip for those out there, who like me, want spaces in names. Use the following to create tags:

$txt tag create [list {Heading 1}]

or,

$txt tag create {{Heading 1}}

If tags need to created proceedurally, then try:

$txt tag create [list [list $tagName]]



gnocl::text -markupTags

Extending pango markup string support is something of a challenge. One option that I've just added to the gnocl::text widget is -markupTags. This will specify whether to implement a set of tags corresponding to the 'Convenience Tags' listed in the Gnocl docs. Apart from saving time when scripting, this will allow the parsing of the text buffer for names tags for output of text blocks in pango markup. For example:
$txt insert end "APPLE" -tags {b}
can be parsed and output as:

<b>APPLE<\b>
The same should be possible for span attributes too:

$txt insert end "APPLE" -tags {b fg=r bg=y}
could be parsed and output as:

<span fgcolor="red" bgcolor="yellow"<b>APPLE<\b><\span>

gnocl::text - tag dumping

Now that its possible create tags by either direct specification or through the use of Pango markup strings, its feasible to require the conversion of text buffer contents back into some form of markup format. Saving off large amounts of text as markup is ill-advised, use serialization to save/reload large buffers. What is in mind here is the ability to edit some rich text in a text buffer and then submit it for display in a list cell or label. Might sound an odd thing to do, but my translation editor does just this. A large body of writing is converted from a text file to a list, one entry per paragraph. These paragraphs are displayed in a gnocl::list in one column and their English translations in a second column alongside. Pango markup would allow those areas in the translation to be highlighted for future review.

Previously I had the bare bones of a widget 'dump' command in place and am now making further headway. Last night I added a 'ranges' sub-command to return …

gnocl::text now supports pango markup

Image
Spent some time today looking at how to implement the rendering Pango markup strings in the gnocl::text widget. Found a module in the StarDict app that was exactly what was needed! It took a couple of minutes to added it to the gnocl sources, modify the makefile text.c module.

Screenshot:




Test script.

# test-text-pango.tcl #!/bin/sh #\ exec tclsh "$0" "$@"
package require Gnocl
set pango_string(0)  {%<<span foreground="blue">Hello</span> <span foreground="red">World</span>} set pango_string(1)  {<span foreground="blue">Hello</span> <span foreground="red">World</span>} set pango_string(2)  {%<<span foreground="blue">Hello</span> <span foreground="red">World</span>}
set txt [gnocl::text] gnocl::window -child $txt -width 600 -height 150
# the string is parse, and the leading %< stripped $txt insert end $pango_string(0)\n $txt insert end $pa…

gnocl::listPicker -done

Completed this megawidget. Here's the script:

# test-listPicker.tcl #!/ bin/sh #\ exec tclsh "%0" "$@" package require Gnocl
#--------------- # megawidget to contain Ok/Cancel buttons #--------------- proc gnocl::listPicker { args } {     set titles {"Item" data}     set types {string string}     set ls(from) [gnocl::list \         -titles $titles \         -types $types ]     set ls(to) [gnocl::list \         -titles $titles \         -types $types ]        # are any names data?     set i [lsearch $titles data ]     $ls(from) columnConfigure $i -visible 0     $ls(to) columnConfigure $i -visible 0     #~~~~~~~~~~~~~~~     # move items between two lists     #~~~~~~~~~~~~~~~            proc ::moveItem { from to i} {         set active [$from getSelection]         if {$active == ""} {return}         set rows [$from getNumChildren]         set a [$from get $active 0]         set b [$from get $active 1]         $from erase $active         set rows [$from getNumChildren]     …

gnocl::listPicker

Image
Things on the Gnocl front have been quiet these past few days. My work load has been heavy and my second hard-drive on my workstations (ie HOME) started giving me sector errors which, is always bad news. Coupled with this, my workstation has parts in it dating back to the mid-1990s and so spares are scarce! Well, as luck would have it I still have spare drives floating around from a pile of old Acer laptops one of which will soon me in my OpenSUSE workstation. At the moment, running on a totally reliable (yet very noisy) 8.5GB IBM PATA hard drive circa 1998 so space is tight. However, spent a couple of hours this evening putting the basics together for a scripted listchooser widget. Here's a screenshot:



My prototype in running ok at the moment and, once finished, I'll post the code to the Gnocl website.


cget -data

One of the great features of Tk/Gnocl widgets is data association. For some time now its been possible to set the -data options but not to extract it. The reason for this is that such associations are not gtk widget properties although support for the feature is via the Gdk libraries. I'm currently working on a Gnocl scripted megawidget which needs extra items of data passes to its events handlers, the -data option is ideal for this. Implementing the feature is a simple process, as the following code extract from the entry.c module cget function shows.

static const int variableIdx = 0; static const int onChangedIdx = 1; static const int valueIdx = 2; static const int cursorIdx = 3; static const int primaryIconIdx = 4; static const int secondaryIconIdx = 5; static const int dataIdx = 6;
static GnoclOption entryOptions[] = {     /* gnocl unique and complex options handled through configure */     { "-variable", GNOCL_STRING, NULL },        /* 0 */     { "-onChanged", GNOCL…

gnocl::text - obtaining names of tags applied to specific locations

The following script shows how to obtain details of which tag applies to a particular position in a block of text.

#---------------
# test-tag-get.tcl
#---------------
#!/bin/sh
#\
exec tclsh "$0" "$@"

package require Gnocl

set txt [gnocl::text -baseFont {Serif 14}]
$txt tag create red -foreground red
$txt tag create black -foreground black
$txt tag create bold -fontWeight bold

gnocl::window -child $txt -setSize 0.25

$txt insert end "the quick brown fox " -tags red
$txt insert end "jumps " -tags {red bold black}
$txt insert end "over the lazy dog" -tags red

$txt configure -onKeyRelease {
    puts [%w tag get [%w getCursor]]
    }

$txt configure -onButtonRelease {
    puts [%w tag get [%w getCursor]]
    }