GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Tue Sep 30, 2014 10:21 am

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: gaptcache -- newbie project
PostPosted: Sat Apr 04, 2009 11:08 am 
Offline
Familiar Face

Joined: Sun Mar 29, 2009 1:24 pm
Posts: 20
Location: New York
I have a working version of this program I was working on. I'm calling it "gaptcache" for now, as it is a gui that runs the debian apt-cache program. It runs the program as a regular user so that you can do things like run aptitude from a separate command line and not have to worry about locking (or that's the idea anyway). It doesn't have a command line input itself. It's still pretty new, so if you see bugs, like memory leaks etc, let me know. I'm brand new to gtk.

I had a lot of help from a GTK+ tutorial and from Tadeboro. It's 331 lines now, all in one file, and of course it's only usefull on debian systems with apt-cache.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
   
typedef struct _Data Data;
struct _Data
{
    GtkEntry    *entry;
    GtkTreeView *tree;
    GtkTextView *text;
};
   
/* function definitions */
static void
search_click(  GtkWidget *widget,
               Data *data );

static GtkWidget *
create_list(   Data *data );
   
static GtkWidget *
create_text(   Data *data );

static void
insert_description ( Data *data );
   
/* Function Implementation */
static void search_click(    GtkWidget *widget,
                                Data *data )
{

    /* Tree view vars */
    GtkListStore  *store;
    GtkTreeIter    tree_iter;
   
    const gchar *entry_text;
   
    /* g_spawn_command_line_sync variables*/
    gchar *command_line;
    gchar * standard_output;
    GError **gerror;
   
    entry_text = gtk_entry_get_text (data->entry);
   
    /* attempt at running apt-cache */
    command_line =  g_strconcat( "/usr/bin/apt-cache search " , entry_text, NULL);
    g_spawn_command_line_sync (  command_line,
                        &standard_output,
                        NULL,
                        NULL,
                        gerror );
     
    g_free(command_line);
       
    store = GTK_LIST_STORE( gtk_tree_view_get_model( data->tree ) );
    gtk_list_store_clear(store);
   
    /* parse standard_output */
    gint x = 0;
    while ('\0' != standard_output[x] && '\n' != standard_output[x]) {
   
        GString * package;
        GString * description;
   
        package = g_string_new("");
        description = g_string_new("");
   
        while ( ' ' != standard_output[x] &&
                '\0' != standard_output[x])
        {
           
            g_string_append_c ( package,
                                (gchar) standard_output[x]);
            x++;
        }
       
        /* advance past unused characters */
        x = x + 3;
       
        while ( '\n' != standard_output[x] &&
                '\0' != standard_output[x] )
        {
            g_string_append_c (description,
                                (gchar) standard_output[x]);
            x++;
        }
       
        x++;
       
        gtk_list_store_append( store, &tree_iter );
        gtk_list_store_set( store, &tree_iter,
                        0, package->str,
                        1, description->str,
                        -1 );
       
        g_string_free(package, TRUE);
        g_string_free(description, TRUE);
    }
   
    GtkTextBuffer *buffer;
    buffer = gtk_text_view_get_buffer( data->text );
    gtk_text_buffer_set_text( buffer, "Select a package...", -1);

}

/* Create the list of packages */
static GtkWidget *
create_list(   Data *data)
{

    GtkWidget *scrolled_window;
    GtkWidget *tree;
    GtkListStore *store;
    GtkCellRenderer *cell;
    GtkTreeViewColumn *column1, *column2;
    GtkTreeSelection *sel;

    const gchar *entry_text;
    if (data != NULL) {
        entry_text = gtk_entry_get_text (data->entry);
    }
    else {
        entry_text = "";
    }
   
    /* Create a new scrolled window, with scrollbars only if needed */
    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
                GTK_POLICY_AUTOMATIC,
                GTK_POLICY_AUTOMATIC);
   
    store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
   
    tree = gtk_tree_view_new_with_model ( GTK_TREE_MODEL(store));

    g_object_unref(G_OBJECT(store));
   
    gtk_container_add(GTK_CONTAINER( scrolled_window), tree);
   
    cell = gtk_cell_renderer_text_new ();

    column1 = gtk_tree_view_column_new_with_attributes ("Packages",
                                                       cell,
                                                       "text", 0,
                                                       NULL);
    column2 = gtk_tree_view_column_new_with_attributes ("Description",
                                                       cell,
                                                       "text", 1,
                                                       NULL);
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (tree),
                    column1);
    gtk_tree_view_append_column (GTK_TREE_VIEW (tree),
                    column2);
   
    sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW (tree));
    gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
   
    g_signal_connect_swapped( sel, "changed",
                                G_CALLBACK(insert_description),
                                data);
   
    data->tree = GTK_TREE_VIEW(tree);
   
    return (scrolled_window);
}


/*  */
static void
insert_description( Data *data )
{
    GtkTextBuffer *buffer;
    GtkTreeIter selected_row;
    GtkTreeModel *model;
    gchar *selected;
    GtkTreeSelection *sel;
   
    sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW (data->tree));
   
    if( gtk_tree_selection_get_selected(sel, &model, &selected_row) )
    {
        /* find which selection was pressed */
        gtk_tree_model_get ( GTK_TREE_MODEL( model ),
                        &selected_row,
                        0,
                        &selected,
                        -1);
                       
        /* g_spawn_command_line_sync variables*/
        gchar *command_line;
        gchar * standard_output;
        GError **gerror;
       
        /* attempt at running apt-cache */
        command_line =  g_strconcat( "/usr/bin/apt-cache show " , selected, NULL);
        g_spawn_command_line_sync (  command_line,
                        &standard_output,
                        NULL,
                        NULL,
                        gerror );
     
        g_free(command_line);
        g_free(selected);
       
        /* Add this text to text view */
        buffer = gtk_text_view_get_buffer( data->text );
        gtk_text_buffer_set_text( buffer, standard_output, -1);
       
        g_free(standard_output);
    }
     
}
   
/* Create a scrolled text area that displays a "package description" */
static GtkWidget *
create_text( Data *data )
{
    GtkWidget *text;
    GtkWidget *swindow;

    /* Text view vars */
    GtkTextBuffer *buffer;
    GtkTextIter    text_iter;

    /* Create scrolled window */
    swindow = gtk_scrolled_window_new( NULL, NULL );
    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( swindow ),
                                    GTK_POLICY_AUTOMATIC,
                                    GTK_POLICY_AUTOMATIC );

    /* Text view */
    text = gtk_text_view_new();
    gtk_text_view_set_editable ( GTK_TEXT_VIEW (text) , FALSE);
    gtk_container_add( GTK_CONTAINER( swindow ), text );
    data->text = GTK_TEXT_VIEW( text );

    /* Append this text to the text already present in text view */
    buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(text) );
    gtk_text_buffer_get_iter_at_offset( buffer, &text_iter, -1 );
    gtk_text_buffer_insert( buffer, &text_iter,
                                        "Package description will appear here\n"
                                        , -1 );
   
    //data->text = GTK_TEXT_VIEW( text );
   
    return( swindow );
}

   
/*   main   */
   
int main( int   argc,
          char *argv[] )
{
    GtkWidget *window;
    GtkWidget *vpaned;
    GtkWidget *text;
    GtkWidget *vbox, *hbox;
    GtkWidget *button;
    GtkWidget *entry;
    GtkWidget *list;

    Data        data;

    gtk_init (&argc, &argv);
   
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "Gaptcache");
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    gtk_window_set_default_size (GTK_WINDOW (window), 550, 400);
    g_signal_connect (G_OBJECT (window), "destroy",
                 G_CALLBACK (gtk_main_quit), NULL);
   
    /* create a vpaned widget and add it to  window */
   
    vbox = gtk_vbox_new(FALSE, 5);
    gtk_container_add (GTK_CONTAINER (window), vbox);
   
    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start( GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

    /* Create Text Entry Widget and callback */
    entry = gtk_entry_new();
    g_signal_connect(   G_OBJECT(entry), "activate",
                        G_CALLBACK (search_click),
                        &data);
   
    g_signal_connect_swapped(   G_OBJECT(entry), "activate",
                        G_CALLBACK (insert_description),
                        &data);
   
    /* Pack Entry Widget into horizontal box  */
    gtk_box_pack_start( GTK_BOX (hbox), entry, TRUE, TRUE, 0);
   
    /* point data.entry at Entry Widget */
    data.entry = GTK_ENTRY(entry);
   
    /* make button and callback */
    button = gtk_button_new_from_stock( GTK_STOCK_FIND );
    g_signal_connect (  G_OBJECT (button), "clicked",
                        G_CALLBACK (search_click),
                        &data );
   
    g_signal_connect_swapped (   G_OBJECT(button), "clicked",
                        G_CALLBACK (insert_description),
                        &data);
   
   
    /* Pack Button Widget into horizontal box */
    gtk_box_pack_start( GTK_BOX (hbox), button, TRUE, TRUE, 0);
   
    vpaned = gtk_vpaned_new ();
    gtk_paned_set_position( GTK_PANED(vpaned), 125);
    gtk_box_pack_start( GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
     
    gtk_entry_set_text( GTK_ENTRY (entry), "packagename" );
   
    list = create_list(&data);                         
    gtk_paned_add1 (GTK_PANED (vpaned),  list );
   
    text = create_text (&data);
    gtk_paned_add2 (GTK_PANED (vpaned), text);
   
    gtk_widget_show_all(window);
   
    gtk_main ();

    return 0;
}

this is the makefile:
[code=]

CC = gcc

CFLAGS = -Wall \
-DG_DISABLE_DEPRECATED \
-DGDK_DISABLE_DEPRECATED \
-DGDK_PIXBUF_DISABLE_DEPRECATED \
-DGTK_DISABLE_DEPRECATED

gaptcache: gaptcache.c
$(CC) gaptcache.c -o gaptcache $(CFLAGS) `pkg-config gtk+-2.0 --cflags --libs`

clean:
rm -f *.o gaptcache
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 06, 2009 1:03 am 
Offline
GTK+ Geek

Joined: Mon Nov 10, 2008 6:54 am
Posts: 64
Thanks radiodee1. Very helpful and straight forward to some newbie like me :D ! Hope you will write more something like this in the future. Awesome work T_T ! 8)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 07, 2009 2:34 am 
Offline
Familiar Face

Joined: Sun May 24, 2009 9:03 pm
Posts: 13
That is indeed a very nice little piece of code!
Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 07, 2009 10:56 am 
Offline
Familiar Face

Joined: Sun Mar 29, 2009 1:24 pm
Posts: 20
Location: New York
...glad you like. I made some further changes to the code, used glade and several other apt tools to create interesting output, but it has become very long (relatively). I'm not sure if I should try to post it here as the glade file is 370 lines and the main program file is some 800 lines. I don't know if the mods want to see something that big. Anyway, thanks for checking this project out.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 12, 2009 12:53 am 
Offline
Never Seen the Sunlight

Joined: Thu Jun 14, 2007 11:02 pm
Posts: 923
Location: Falun, WI USA
You might want to have your project hosted somewhere like SourceForge or Launchpad so you can link to the project page rather than posting ~1170 lines of code.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 13, 2009 2:22 pm 
Offline
Familiar Face

Joined: Sun Mar 29, 2009 1:24 pm
Posts: 20
Location: New York
Hi,

Anyone who's interested can find my gtk apt project on launchpad. I'm calling it "gaptsearch" now and it's obviously pretty basic, but it's there if you want to look at it.

https://launchpad.net/gaptsearch/0.1.0/initial

Thanks to everybody who helped me out. I really appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 15, 2009 1:54 pm 
Offline
Familiar Face

Joined: Sun Mar 29, 2009 1:24 pm
Posts: 20
Location: New York
Hi again,

I've made some improvements, and so I'm including another link here to the new tarball for the gaptsearch project. If you click on this it will download the source code from launchpad.

http://launchpad.net/gaptsearch/0.1.0/n ... -15.tar.gz

Thanks Again


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group