Logo Search packages:      
Sourcecode: pan version File versions  Download package

task-manager.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Pan - A Newsreader for Gtk+
 * Copyright (C) 2002  Charles Kerr <charles@rebelbase.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*********************
**********************  Includes
*********************/

#include <config.h>

#include <glib.h>
#include <gtk/gtk.h>

#include <pan/base/argset.h>
#include <pan/base/debug.h>
#include <pan/base/pan-i18n.h>
#include <pan/base/pan-glib-extensions.h>

#include <pan/gui.h>
#include <pan/prefs.h>
#include <pan/queue.h>
#include <pan/sockets.h>
#include <pan/task-manager.h>
#include <pan/util.h>

#include <pan/xpm/pan-pixbufs.h>

/*********************
**********************  Defines / Enumerated types
*********************/

/*********************
**********************  Macros
*********************/

/*********************
**********************  Structures / Typedefs
*********************/

typedef struct
{
      GtkWidget    * window;
      GtkWidget    * top;
      GtkWidget    * task_manager_tree_view;
      GtkListStore * list;

      guint          timeout_id;

      gboolean       dampen_move_feedback_loop;
}
ManagerUI;

enum {
      TASK_MANAGER_STATUS_COLUMN,
      TASK_MANAGER_PERCENTAGE_COLUMN,
      TASK_MANAGER_SERVER_COLUMN,
      TASK_MANAGER_TIME_COLUMN,
      TASK_MANAGER_DESCRIPTION_COLUMN,
      TASK_MANAGER_DATA_COLUMN,
      TASK_MANAGER_TASK_STATE_COLUMN,
      TASK_MANAGER_N_COLUMNS
};


/*********************
**********************  Variables
*********************/

extern GtkTooltips * ttips;

static ManagerUI * manager_ui = NULL;

/*********************
**********************  BEGINNING OF SOURCE
*********************/

/************
*************  PRIVATE ROUTINES
************/

/**
***  Internal Utility
**/

static void
task_list_fill_list (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
      Task * task;
      
      gtk_tree_model_get (model, iter, TASK_MANAGER_DATA_COLUMN, &task, -1);
      *(GSList **)data = g_slist_prepend (*(GSList **)data, task);
}


static GSList *
get_selected_task_list (ManagerUI * ui)
{
      GSList * tasks = NULL;

      gtk_tree_selection_selected_foreach (gtk_tree_view_get_selection (GTK_TREE_VIEW (ui->task_manager_tree_view)),
                                   task_list_fill_list, &tasks);

      return g_slist_reverse (tasks);
}

/**
***  User Interactions
**/

static int
find_task_index (GtkListStore * list, Task * task)
{
      GtkTreeIter iter;
      gboolean more_elements = TRUE;
      int index = 0;
            
      gtk_tree_model_get_iter_first (GTK_TREE_MODEL(list), &iter);
      
      while (more_elements) {
            Task * current_task;
      
            gtk_tree_model_get (GTK_TREE_MODEL(list), &iter, TASK_MANAGER_DATA_COLUMN, &current_task, -1);
            
            if (current_task == task) {
                  return index;
            }

            index++;
            
            more_elements =  gtk_tree_model_iter_next (GTK_TREE_MODEL(list), &iter);
      }

      /* We did not find the task */
      return -1;
}



static void
up_clicked_cb (GtkButton   * button,
               gpointer      user_data)
{
        ManagerUI * ui = (ManagerUI*) user_data;
      GSList * tasks = get_selected_task_list (ui);

      if (tasks != NULL) {
            const int index = find_task_index (ui->list, tasks->data);

            if (index > 0)
                  queue_move_tasks (tasks, index-1);
            else
                  g_slist_free (tasks);
      }
}

static void
down_clicked_cb (GtkButton   * button,
                 gpointer      user_data)
{
        ManagerUI * ui = (ManagerUI*) user_data;
      GSList * tasks = get_selected_task_list (ui);

      if (tasks != NULL) {
            const int index = find_task_index (ui->list, tasks->data);

            if (index < gtk_tree_model_iter_n_children (GTK_TREE_MODEL (ui->list), NULL) - 1)
                  queue_move_tasks (tasks, index+1);
            else
                  g_slist_free (tasks);
      }
}

static void
top_clicked_cb (GtkButton    * button,
                gpointer       user_data)
{
        ManagerUI * ui = (ManagerUI*) user_data;
      GSList * tasks = get_selected_task_list (ui);

      if (tasks)
            queue_move_tasks (tasks, 0);
}

static void
bottom_clicked_cb (GtkButton   * button,
                   gpointer      user_data)
{
        ManagerUI * ui = (ManagerUI*) user_data;
      GSList * tasks = get_selected_task_list (ui);

      if (tasks)
            queue_move_tasks (tasks, -1);
}

static void
stop_clicked_cb (GtkButton   * button,
                   gpointer      user_data)
{
        ManagerUI * ui = (ManagerUI*) user_data;
      GSList * tasks = get_selected_task_list (ui);

      if (tasks)
            queue_stop_tasks (tasks);
}

static void
delete_clicked_cb (GtkButton   * button,
                   gpointer      user_data)
{
        ManagerUI * ui = (ManagerUI*) user_data;
      GSList * tasks = get_selected_task_list (ui);

      if (tasks)
            queue_remove_tasks (tasks);
}


static void
requeue_cb (GtkButton   * button,
            gpointer      user_data)
{
      ManagerUI * ui = (ManagerUI*) user_data;
      GSList * tasks = get_selected_task_list (ui);

      if (tasks)
            queue_requeue_failed_tasks (tasks);
}


/**
***  Display
**/

static void
get_percent_str (const Task   * task,
                 gchar        * buf,
                 gint           buf_size)
{
      int percent = 0;

      if (task != NULL)
            percent = status_item_get_progress_of_100 (STATUS_ITEM(task));

      if (percent == 0)
            *buf = '\0';
      else
            g_snprintf (buf, buf_size, "%d%%", percent);
}

static void
get_xfer_str (const Task    * task,
              gchar         * buf,
              gint            buf_size)
{

      int seconds_remaining;
      guint i;
      gulong bytes_total;
      gulong bytes_left;
      double KB_left;
      double progress;
      double KBps = 0.0;
      GSList * l;

      /* get the current speed */
      KBps = 0.0;
      for (l=task->sockets; l!=NULL; l=l->next)
            KBps += pan_socket_get_xfer_rate_KBps (PAN_SOCKET(l->data));

      /* get the total byte count of the task */
      bytes_total = 0ul;
      for (i=0; i<task->identifiers->len; ++i)
            bytes_total += MESSAGE_IDENTIFIER (g_ptr_array_index (task->identifiers, i))->byte_qty;

      /* get the remaining byte count of the task */
      progress = status_item_get_progress_of_100 (STATUS_ITEM(task)) / 100.0;
      bytes_left = bytes_total * (1.0 - progress);
      KB_left = bytes_left / 1024.0;
      seconds_remaining = (int)(KB_left / KBps);

      /* write the string */
      if (seconds_remaining <= 0)
            *buf = '\0';
      else {
            const int h = seconds_remaining / 3600;
            const int m = (seconds_remaining % 3600) / 60;
            const int s = seconds_remaining % 60;
            g_snprintf (buf, buf_size, _("%d:%02d:%02d (%.2f KB/s)"), h, m, s, KBps);
      }
}

static void
get_status_str (const Task     * task,
                char           * buf,
                int              buf_size)
{
      const char* status_str;
      QueueTaskStatus status = queue_get_task_status(task);

      switch (status)
      {
            case QUEUE_TASK_STATUS_NOT_QUEUED:
                  status_str = _("Not Queued");
                  break;
            case QUEUE_TASK_STATUS_QUEUED:
                  status_str = _("Queued");
                  break;
            case QUEUE_TASK_STATUS_RUNNING:
                  status_str = _("Running");
                  break;
            case QUEUE_TASK_STATUS_STOPPED:
                  status_str = _("Stopped");
                  break;
            case QUEUE_TASK_STATUS_STOPPING:
                  status_str = _("Stopping");
                  break;
            case QUEUE_TASK_STATUS_REMOVING:
                  status_str = _("Removing");
                  break;
      }

      if (!queue_is_online() && status==QUEUE_TASK_STATUS_QUEUED)
            g_snprintf (buf, buf_size, _("Offline"));
      else
            g_snprintf (buf, buf_size, "%s", status_str);
}

static void
refresh_row_nolock (GtkListStore * model, GtkTreeIter * iter, Task * task)
{
      int row;
      char percentbuf[8];
      char statusbuf[64];
      char xferbuf[64];
      const char * text [5];
      char * description = status_item_describe(STATUS_ITEM(task));
      char * freeme[5] = { NULL, NULL, NULL, NULL, NULL };

      get_xfer_str (task, xferbuf, sizeof(xferbuf));
      get_status_str (task, statusbuf, sizeof(statusbuf));
      get_percent_str (task, percentbuf, sizeof(percentbuf));

      /* build the strings */
      text[0] = pan_utf8ize (statusbuf, -1, freeme+0);
      text[1] = pan_utf8ize (percentbuf, -1, freeme+1);
      text[2] = pan_utf8ize (task->server->name.str, -1, freeme+2);
      text[3] = pan_utf8ize (xferbuf, -1, freeme+3);
      text[4] = pan_utf8ize (description, -1, freeme+4);

      /* update the row */
      gtk_list_store_set (model, iter, TASK_MANAGER_STATUS_COLUMN, text[0],
                                       TASK_MANAGER_PERCENTAGE_COLUMN, text[1],
                                       TASK_MANAGER_SERVER_COLUMN, text[2],
                                       TASK_MANAGER_TIME_COLUMN, text[3],
                                       TASK_MANAGER_DESCRIPTION_COLUMN, text[4],
                                       TASK_MANAGER_DATA_COLUMN, task,
                                       TASK_MANAGER_TASK_STATE_COLUMN, (int)queue_get_task_status(task),
                                       -1);
                                    
      /* cleanup */
      g_free (description);
      for (row=0; row<G_N_ELEMENTS(freeme); ++row)
            if (freeme[row] != NULL)
                  g_free (freeme[row]);
}

static void
add_tasks_to_list (ManagerUI     * ui,
                   GSList        * tasks,
                   int             index)
{
      GSList * task_it;
      debug_enter ("add_tasks_to_list");

      if (index == -1)
            index = gtk_tree_model_iter_n_children (GTK_TREE_MODEL(ui->list), NULL);

      pan_lock ();      
      for (task_it=tasks; task_it!=NULL; task_it=task_it->next)
      {
            /* create the row */
            GtkTreeIter iter;
            Task * task = TASK(task_it->data);
            gtk_list_store_insert (ui->list, &iter, index++);

            /* populate it, and make a task ref for the model to hold */
            pan_object_ref (PAN_OBJECT (task));
            refresh_row_nolock (ui->list, &iter, task);
      }
      pan_unlock ();

      debug_exit ("add_tasks_to_list");
}


static void
ui_populate (ManagerUI *ui)
{
      guint i;
      GPtrArray * tasks;
      GSList * slist = NULL;

      /* add the tasks to the gui */
      tasks = queue_get_tasks ();
      for (i=0; i<tasks->len; ++i)
            slist = g_slist_prepend (slist, g_ptr_array_index(tasks,i));
      slist = g_slist_reverse (slist);
      add_tasks_to_list (ui, slist, 0);

      /* cleanup */
      g_slist_foreach (slist, (GFunc)pan_object_unref, NULL);
      g_slist_free (slist);
      g_ptr_array_free (tasks, TRUE);
}

/**
***  Queue Changes
**/

static void
tasks_added_idle_cleanup (gpointer argset_gpointer)
{
      ArgSet * argset = (ArgSet*) argset_gpointer;
      GSList * tasks = (GSList*) argset_get (argset, 1);

      g_slist_foreach (tasks, (GFunc)pan_object_unref, NULL);
      g_slist_free (tasks);
      argset_free (argset);
}
static int
tasks_added_idle (gpointer argset_gpointer)
{
      ArgSet * argset;
      ManagerUI * ui;
      GSList * tasks;
      int index;
      debug_enter ("tasks_added_idle");

      argset = (ArgSet*) argset_gpointer;
      ui = (ManagerUI*) argset_get (argset, 0);
      tasks = (GSList*) argset_get (argset, 1);
      index = GPOINTER_TO_INT (argset_get (argset, 2));

      /* insert the task */
      add_tasks_to_list (ui, tasks, index);

      /* cleanup */
      tasks_added_idle_cleanup (argset_gpointer);
      debug_exit ("tasks_added_idle");
      return 0;
}

static void
tasks_added_cb (gpointer call_obj, gpointer call_arg, gpointer client_arg)
{
      int index;
      GSList * tasks;
      ManagerUI * ui;
      debug_enter ("tasks_added_cb");

      index = GPOINTER_TO_INT(call_arg);
      tasks = (GSList*) call_obj;
      ui = (ManagerUI*) client_arg;

      tasks = g_slist_copy (tasks);
      g_slist_foreach (tasks, (GFunc)pan_object_ref, NULL);
      gui_queue_add_full_to_g_object (tasks_added_idle,
                                      argset_new3 (ui, tasks, GINT_TO_POINTER(index)),
                                      tasks_added_idle_cleanup,
                                      G_OBJECT(ui->window));

      debug_exit ("tasks_added_cb");
}

/***
****
***/

static void
tasks_removed_idle_cleanup (gpointer argset_gpointer)
{
      ArgSet * argset = (ArgSet*) argset_gpointer;
      GSList * tasks = (GSList*) argset_get (argset, 1);

      g_slist_foreach (tasks, (GFunc)pan_object_unref, NULL);
      g_slist_free (tasks);
      argset_free (argset);
}

static int
tasks_removed_idle (gpointer argset_gpointer)
{
      ArgSet * argset;
      ManagerUI * ui;
      GSList * tasks;
      GSList   * l;
      GtkTreeIter iter;
      debug_enter ("tasks_removed_idle");

      argset = (ArgSet*) argset_gpointer;
      ui = (ManagerUI*) argset_get (argset, 0);
      tasks = (GSList*) argset_get (argset, 1);

      /* remove tasks */
      pan_lock ();

      for (l=tasks; l!=NULL; l=l->next) {
            const int index = find_task_index (ui->list, l->data);

            if (index != -1)
            {
                  gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (ui->list), &iter, NULL, index);
                  gtk_list_store_remove (ui->list, &iter);
                  pan_object_unref (PAN_OBJECT (l->data));
            }
      }

      pan_unlock ();

      /* cleanup */
      tasks_removed_idle_cleanup (argset_gpointer);
      debug_exit ("tasks_removed_idle");
      return 0;
}

static void
tasks_removed_cb (gpointer call_obj, gpointer call_arg, gpointer client_arg)
{
      GSList * tasks;
      ManagerUI * ui;
      debug_enter ("tasks_removed_cb");

      tasks = (GSList*) call_obj;
      ui = (ManagerUI*) client_arg;

      tasks = g_slist_copy (tasks);
      g_slist_foreach (tasks, (GFunc)pan_object_ref, NULL);
      gui_queue_add_full_to_g_object (tasks_removed_idle,
                                      argset_new2 (ui, tasks),
                                      tasks_removed_idle_cleanup,
                                      G_OBJECT(ui->window));

      debug_exit ("tasks_removed_cb");
}

static void
tasks_moved_cb (gpointer call_obj, gpointer call_arg, gpointer client_arg)
{
      int i;
      GSList * l;
      GtkTreeIter iter;
      GtkTreeSelection * selection;
      GSList * tasks = (GSList*) call_obj;
      ManagerUI * ui = (ManagerUI*) client_arg;
      int index = GPOINTER_TO_INT(call_arg);

      /* extra ref to make sure the tasks don't get deleted while moving them */
      g_slist_foreach (tasks, (GFunc)pan_object_ref, NULL);

      /* remove the old rows */
      pan_lock ();
      for (l=tasks; l!=NULL; l=l->next) {
            const int index = find_task_index (ui->list, l->data);
            if (index != -1) {
                  Task * task = NULL;
                  gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (ui->list), &iter, NULL, index);
                  gtk_tree_model_get (GTK_TREE_MODEL (ui->list), &iter, TASK_MANAGER_DATA_COLUMN, &task, -1);
                  if (task != NULL)
                        pan_object_unref (PAN_OBJECT(task));
                  gtk_list_store_remove (ui->list, &iter);
            }
      }
      pan_unlock ();

      /* insert the new rows */
      add_tasks_to_list (ui, tasks, index);

      /* select the new rows */
      pan_lock ();
      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ui->task_manager_tree_view));
      if (index == -1)
            index = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (ui->list), NULL) - g_slist_length(tasks);
      for (l=tasks, i=index; l!=NULL; l=l->next, ++i) {
            gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (ui->list), &iter, NULL, i);
            gtk_tree_selection_select_iter (selection, &iter);
      }

      pan_unlock ();

      /* clear extra ref */
      g_slist_foreach (tasks, (GFunc)pan_object_unref, NULL);
}

static void
update_titlebar_lock (ManagerUI * ui)
{
      int running, queued, stopped;
      guint i;
      GPtrArray * tasks;
      char title[1024] = { '\0' };

      g_return_if_fail (ui!=NULL);

      /* get information about the tasks */
      running = queued = stopped = 0;
      tasks = queue_get_tasks ();
      for (i=0; i<tasks->len; ++i) {
            Task * t = TASK(g_ptr_array_index(tasks,i));
            QueueTaskStatus status = queue_get_task_status (t);
      
            if (status==QUEUE_TASK_STATUS_QUEUED)
                  ++queued;
            else if (status==QUEUE_TASK_STATUS_RUNNING)
                  ++running;
            else if (status==QUEUE_TASK_STATUS_STOPPED)
                  ++stopped;
      }

      /* create a titlebar */
      if (stopped)
            g_snprintf (title, sizeof(title), _("Pan %s Task Manager (%d Queued, %d Running, %d Stopped)"), VERSION, queued, running, stopped);
      else if (queued || running)
            g_snprintf (title, sizeof(title), _("Pan %s Task Manager (%d Queued, %d Running)"), VERSION, queued, running);
      else 
            g_snprintf (title, sizeof(title), _("Pan %s Task Manager"), VERSION);

      /* show the titlebar */
      pan_lock ();
      gtk_window_set_title (GTK_WINDOW(ui->window), title);
      pan_unlock ();

      /* cleanup */
      pan_g_ptr_array_foreach (tasks, (GFunc)pan_object_unref, NULL);
      g_ptr_array_free (tasks, TRUE);
}

static gboolean
periodic_update_timer_foreach (GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer unused)
{
      Task * task;
      int old_state, new_state;
      gtk_tree_model_get (model, iter, TASK_MANAGER_DATA_COLUMN, &task, TASK_MANAGER_TASK_STATE_COLUMN, &old_state, -1);
      new_state = queue_get_task_status(task);
      if (new_state!=old_state || new_state==QUEUE_TASK_STATUS_RUNNING)
            refresh_row_nolock ((GtkListStore*)model, iter, task);

      return FALSE;
}

static int
periodic_update_timer (gpointer user_data)
{
      ManagerUI * ui = (ManagerUI*) user_data;
      
      debug0 (DEBUG_QUEUE, "task manager periodic ui refresh");

      /* update the grid */
      pan_lock ();
      gtk_tree_model_foreach (GTK_TREE_MODEL(ui->list), periodic_update_timer_foreach, NULL);
      pan_unlock ();

      /* update the titlebar */     
      update_titlebar_lock (ui);

      return 1;
}

static gint
window_delete_event_cb (GtkWidget * w, GdkEvent * e, gpointer data)
{
      ManagerUI * ui = (ManagerUI*) data;
      gui_save_window_size (ui->window, "task_manager_2");
      gui_save_column_widths_tree_view (ui->task_manager_tree_view, "task_manager_2");
      return FALSE;
} 

static gboolean
ui_destroy_cb_tree_model_foreach_func (GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data)
{
      Task * task = NULL;
      gtk_tree_model_get (model, iter, TASK_MANAGER_DATA_COLUMN, &task, -1);
      if (task != NULL)
            pan_object_unref (PAN_OBJECT(task));
      return FALSE;
}
static void
ui_destroy_cb (GtkObject * o, gpointer user_data)
{
      ManagerUI *ui = (ManagerUI*) user_data;

      pan_callback_remove (queue_tasks_added, tasks_added_cb, ui);
      pan_callback_remove (queue_tasks_removed, tasks_removed_cb, ui);
      pan_callback_remove (queue_tasks_moved, tasks_moved_cb, ui);

      g_source_remove (ui->timeout_id);

      gtk_tree_model_foreach (GTK_TREE_MODEL(ui->list), ui_destroy_cb_tree_model_foreach_func, ui);

      pan_warn_if_fail (ui == manager_ui);
      g_free (manager_ui);
      manager_ui = NULL;
}

/**
***
**/

static ManagerUI*
task_manager_build_ui (GtkWidget * window)
{
      ManagerUI * ui = g_new0 (ManagerUI, 1);
      GtkWidget * w;
      GtkWidget * toolbar;
      GtkWidget * vbox;
      GtkTreeViewColumn *column;
      GtkTreeSelection * selection;
      GtkCellRenderer * renderer;

      ui->window = window;
      vbox = gtk_vbox_new (FALSE, GUI_PAD_SMALL);

      /* button bar */
      toolbar = gtk_toolbar_new ();
      gtk_toolbar_set_style (GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);

      gui_add_network_button_to_toolbar (toolbar);

      /* up */
      gtk_toolbar_insert_stock (GTK_TOOLBAR(toolbar), GTK_STOCK_GO_UP,
                                _("Move Selected Task(s) Up"), NULL,
                                G_CALLBACK(up_clicked_cb), ui, -1);
      /* top */
      gtk_toolbar_insert_stock (GTK_TOOLBAR(toolbar), GTK_STOCK_GOTO_TOP,
                                _("Move Selected Task(s) to Top"), NULL,
                                G_CALLBACK(top_clicked_cb), ui, -1);

      gtk_toolbar_insert_space (GTK_TOOLBAR(toolbar), -1);

      /* down */
      gtk_toolbar_insert_stock (GTK_TOOLBAR(toolbar), GTK_STOCK_GO_DOWN,
                                _("Move Selected Task(s) Down"), NULL,
                                G_CALLBACK(down_clicked_cb), ui, -1);
      /* bottom */
      gtk_toolbar_insert_stock (GTK_TOOLBAR(toolbar), GTK_STOCK_GOTO_BOTTOM,
                                _("Move Selected Task(s) to Bottom"), NULL,
                                G_CALLBACK(bottom_clicked_cb), ui, -1);

      gtk_toolbar_insert_space (GTK_TOOLBAR(toolbar), -1);

      /* redo */
      gtk_toolbar_insert_stock (GTK_TOOLBAR(toolbar), GTK_STOCK_REDO,
                                _("Restart Selected Task(s)"), NULL,
                                G_CALLBACK(requeue_cb), ui, -1);

        /* cancel */
      gtk_toolbar_insert_stock (GTK_TOOLBAR(toolbar), GTK_STOCK_STOP,
                                _("Stop Selected Task(s)"), NULL,
                                G_CALLBACK(stop_clicked_cb), ui, -1);

      /* remove */
      gtk_toolbar_insert_stock (GTK_TOOLBAR(toolbar), GTK_STOCK_DELETE,
                                _("Delete Selected Task(s)"), NULL,
                                G_CALLBACK(delete_clicked_cb), ui, -1);

      /* add button bar to the queued window */
      gtk_box_pack_start (GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);

      /* Create the list_store */
      ui->list = gtk_list_store_new (TASK_MANAGER_N_COLUMNS, G_TYPE_STRING,
                                                             G_TYPE_STRING,
                                                             G_TYPE_STRING,
                                                             G_TYPE_STRING,
                                                             G_TYPE_STRING,
                                                             G_TYPE_POINTER,
                                                             G_TYPE_INT);
            
      /* Create the tree_view */
      w = ui->task_manager_tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ui->list));

      /* Add the status column to the view */
      renderer = gtk_cell_renderer_text_new ();
      column = gtk_tree_view_column_new_with_attributes (_("Status"), renderer,
                                             "text", TASK_MANAGER_STATUS_COLUMN,
                                             NULL);
      gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column) ,GTK_TREE_VIEW_COLUMN_FIXED);
      gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 200);
      gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
      gtk_tree_view_append_column (GTK_TREE_VIEW (ui->task_manager_tree_view), column);

      /* Add the percentage done column to the view */
      renderer = gtk_cell_renderer_text_new ();
      column = gtk_tree_view_column_new_with_attributes (_("% Done"), renderer,
                                             "text", TASK_MANAGER_PERCENTAGE_COLUMN,
                                             NULL);
      gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column) ,GTK_TREE_VIEW_COLUMN_FIXED);
      gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 50);
      gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
      gtk_tree_view_append_column (GTK_TREE_VIEW (ui->task_manager_tree_view), column);

      /* Add the server column to the view */
      renderer = gtk_cell_renderer_text_new ();
      column = gtk_tree_view_column_new_with_attributes (_("Server"), renderer,
                                             "text", TASK_MANAGER_SERVER_COLUMN,
                                             NULL);
      gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column) ,GTK_TREE_VIEW_COLUMN_FIXED);
      gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 50);
      gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
      gtk_tree_view_append_column (GTK_TREE_VIEW (ui->task_manager_tree_view), column);

      /* Add the time remaining column to the view */
      renderer = gtk_cell_renderer_text_new ();
      column = gtk_tree_view_column_new_with_attributes (_("Time Remaining"), renderer,
                                             "text", TASK_MANAGER_TIME_COLUMN,
                                             NULL);
      gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column) ,GTK_TREE_VIEW_COLUMN_FIXED);
      gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 100);
      gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
      gtk_tree_view_append_column (GTK_TREE_VIEW (ui->task_manager_tree_view), column);

      /* Add the description column to the view */
      renderer = gtk_cell_renderer_text_new ();
      column = gtk_tree_view_column_new_with_attributes (_("Description"), renderer,
                                             "text", TASK_MANAGER_DESCRIPTION_COLUMN,
                                             NULL);
      gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column) ,GTK_TREE_VIEW_COLUMN_FIXED);
      gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 1500);
      gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
      gtk_tree_view_append_column (GTK_TREE_VIEW (ui->task_manager_tree_view), column);

      /* Set the selection mode */
      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ui->task_manager_tree_view));
      gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);

      gui_restore_column_widths_tree_view (ui->task_manager_tree_view, "task_manager_2");

      w = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(w), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(w), GTK_SHADOW_IN);
      gtk_container_add (GTK_CONTAINER(w), ui->task_manager_tree_view);
      gtk_box_pack_start (GTK_BOX(vbox), w, TRUE, TRUE, 0);

      pan_callback_add (queue_tasks_added, tasks_added_cb, ui);
      pan_callback_add (queue_tasks_removed, tasks_removed_cb, ui);
      pan_callback_add (queue_tasks_moved, tasks_moved_cb, ui);

      ui->timeout_id = pan_timeout_add (2000, periodic_update_timer, ui);
      ui->top = vbox;
        g_signal_connect (ui->top, "destroy", G_CALLBACK(ui_destroy_cb), ui);
      return ui;
}

/************
*************  PUBLIC ROUTINES
************/

void
task_manager_spawn (void)
{
      /* There can be only one */
      if (manager_ui != NULL)
      {
            pan_lock();
            if (!GTK_WIDGET_MAPPED(GTK_WIDGET(manager_ui->window)))
                  gtk_widget_map ( GTK_WIDGET(manager_ui->window));
            gdk_window_raise (manager_ui->window->window);
            gdk_window_show (manager_ui->window->window);
            pan_unlock();
            return;
      }

      manager_ui = task_manager_build_ui (gtk_window_new(GTK_WINDOW_TOPLEVEL));
      ui_populate (manager_ui);

      g_signal_connect (manager_ui->window, "delete_event",
                        G_CALLBACK(window_delete_event_cb), manager_ui);
      gtk_window_set_title (GTK_WINDOW(manager_ui->window), _("Pan: Task Manager"));
      gtk_window_set_role (GTK_WINDOW(manager_ui->window), "pan-task-manager");
      gtk_container_add (GTK_CONTAINER(manager_ui->window), manager_ui->top);

      gtk_window_set_default_size (GTK_WINDOW (manager_ui->window), 600, 400);
      gui_restore_window_size (manager_ui->window, "task_manager_2");
      gtk_widget_show_all (manager_ui->window);
}


Generated by  Doxygen 1.6.0   Back to index