A Django site.
April 17, 2008

John Anderson
sontek
sontek ( John M. Anderson )
» Printing in GTK#

I just finished porting Tomboy’s print code to GTK so that we would be more portable and I thought other Mono apps looking to move from libgnomeprint or wanting to add printing support might find a code example helpful.

First, To start printing you do something like:

private void PrintButtonClicked (object sender, EventArgs args)
{
Gtk.PrintOperation op = new PrintOperation ();
op.BeginPrint += new BeginPrintHandler (OnBeginPrint);
op.DrawPage += new DrawPageHandler(OnDrawPage);

op.Run (Gtk.PrintOperationAction.PrintDialog, this.Window);
}

after the PrintOperation is set off you need to handle the BeginPrint event. The main things that need to be done are finding out how many lines will fit on a page and how many lines you have:

public void OnBeginPrint(object sender, Gtk.BeginPrintArgs args)
{
PrintOperation op = (PrintOperation)sender;
lines_per_page = (int)Math.Floor ((double)args.Context.Height / (double)font_size);
Gtk.TextIter start_iter, end_iter;
this.Buffer.GetBounds (out start_iter, out end_iter);
lines = this.Buffer.GetText (start_iter, end_iter, false).Split ('\n');
op.NPages = (int)Math.Ceiling ((double)lines.Length / (double)lines_per_page);
}

Finally, now that you have the printing setup, you need to actually render the data to be printed:

public void OnDrawPage(object sender, Gtk.DrawPageArgs args)
{
PrintOperation op = (PrintOperation)sender;
Cairo.Context cr = args.Context.CairoContext;

int line = args.PageNr * lines_per_page;
int num_lines = 0;
if (args.PageNr+1 != op.NPages)
num_lines = line + lines_per_page;
else
num_lines = lines.Length;

cr.MoveTo (0, 0);

for (int i = 0; i < lines_per_page && line < num_lines; i++)
{
Pango.Layout layout = args.Context.CreatePangoLayout ();
Pango.FontDescription desc = Pango.FontDescription.FromString (”sans ” + font_size);
desc.Size = (int)(font_size * Pango.Scale.PangoScale);
layout.FontDescription = desc;

layout.SetText (lines[line]);
Pango.CairoHelper.ShowLayout (cr, layout);
cr.RelMoveTo (0, font_size);
line++;
}
}

This does not take into account styles but will give you the basic idea of what needs to be done.

December 14, 2007

Kevin Kubasik
nonic
For Once I Oneder
» Tomboy Tagging: A Third Try

Ok, I replaced our original autocomplete system with something a little more reserved, and based on a Gtk.Entry. Stealing heavily from a little-known F-Spot widget, I concocted a simple tagbar. Tab cycles through the completions and Enter selects. To give a rough idea of whats going on I made a quick screencast.

Google Vids

OGG

Xvid - Avi 

Let me know what you all think, if this is what we want to base our work on, then I'll clear out the almost 500 lines of commented code from our past revisions. If we need to try something new, we can do that to.

December 13, 2007

Kevin Kubasik
nonic
For Once I Oneder
» Tomboy Hackfest: Part 2

Alright! Some cool news! The Mono Hackfest at the Novell OSTC in Provo, Utah was a success ( I would say, people showed up and we talked about features ;) )  And while I took several photos in the hope that I might have another photo-riffic blog post, but alas, my flash wasn’t on, and they are all pretty much worthless.  That aside, it was pretty cool to root around more of the Novell OSTC campus.

As a by-product of the ‘Hack’ing portion of the hackfest, I am happy to report the enabling of tagging in Tomboy, while we are still working out the specifics of the tagging interface, a super-experimental version of our newest iteration (based somewhat strongly on the Blogger.com tagging interface which we all agreed was somewhat well designed). While this is mostly implemented, there are a few issues (mostly based on my lack of Gtk knowledge/experience) with some of the autocomplete logic. I basically created a new Gtk Window which is composed of a ListView and hovers over the entry area (actually a GtkTextView, as a GtkEntry wouldn’t handle text markup). There are 2 real problems at the moment.

  1. I need to handle keyboard input intelligently enough to allow selection of an autocomplete option, I just need someone more familiar with how keypress events are handled to take a look at my code and figure out what widgets I should listen to the keypress events on etc.
  2. I need to get the autocomplete popup widget to show in the right place (should be easy enough to get, again I just need someone a little more familiar with the Gtk API so I don’t spend another hour looking for the window positioning information.) and the widget needs to close when a note is closed. (Right now the autocomplete box hangs around, should again just be subscribing to a window destroy event, but my previous attempts have resulted in some messes.)

Anyways, if anyone has the time to offer a hand/check any of this out, just drop by #tomboy (I’ll be in and out due to exams, but I’ll do my best to answer any questions) or feel free to just fix it right off the bat ;) Here’s a quick and dirty screenshot of the problem as it exists (you can see the autocomplete dropdown isn’t quite right).

Tomboy Tagging Screenshot

In addition to traditional tags, we have added a new little tidbit for Addin Developers, the concept of System Tags. In short, any tag added to a Tomboy note with the system: prefix will not be displayed. While this seems a little stupid at first glance, this allows us to easily implement things like Tasks, and allow Addins to associate their own data with tags while not implementing their own data store, and still maintaining backwards compatibility. For example if I wanted to implement ‘Contacts’ in Tomboy (NOT A FEATURE THAT SHOULD BE IMPLEMENTED IMHO)  I could simply add the following tags to store all the information I needed for my Addin:

  • system:Contact
  • system:FirstName:Kevin
  • system:LastName:Kubasik
  • system:EMail:KevinAtKubasikDotNet

And so on, anything with the ’system:’ prefix will be hidden from the user, but still stored with each note.