Back to index

lshw  02.16
Defines | Enumerations | Functions | Variables
engine.cc File Reference
#include "engine.h"
#include "hw.h"
#include "main.h"
#include "print-gui.h"
#include "print.h"
#include "osutils.h"
#include "options.h"
#include <iostream>
#include <fstream>
#include <sys/utsname.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include "support.h"

Go to the source code of this file.

Defines

#define AUTOMATIC   "automatic file format"
#define LSHW_XML   "lshw XML format (.lshw, .xml)"
#define PLAIN_TEXT   "plain text document (.text, .txt)"
#define JSON   "JavaScript Object Notation document (.json)"
#define HTML   "HTML document (.html, .htm)"
#define YIELD()   while(gtk_events_pending()) gtk_main_iteration()

Enumerations

enum  {
  COL_NAME = 0, COL_NODE, COL_WEIGHT, COL_CONTINUATION,
  NUM_COLS
}

Functions

static void clear_list (GtkWidget *list1)
static void populate_sublist (GtkWidget *list1, hwNode *root, hwNode *current=NULL)
static void create_tags (GtkTextBuffer *buffer)
static void display (GtkWidget *mainwindow)
void status (const char *message)
void refresh (GtkWidget *mainwindow)
void change_selection (unsigned list, GtkTreeView *treeview)
static hwNodefind_parent (hwNode *n, hwNode *sub)
void browse (unsigned list, GtkTreeView *treeview)
void go_back (GtkWidget *mainwindow)
static const char * guess_format (char *s)
static char * fix_filename (char *s, const char *extension)
static void redirect_cout (std::ofstream &out, bool enable=true)
void save_as (GtkWidget *mainwindow)

Variables

static const char * id = "@(#) $Id: engine.cc 2433 2012-01-10 22:01:30Z lyonel $"
static hwNode container ("container", hw::generic)
static hwNodedisplayed = NULL
static hwNodeselected1 = NULL
static hwNodeselected2 = NULL
static hwNodeselected3 = NULL
GtkWidget * mainwindow
GtkWidget * list1
GtkWidget * list2
GtkWidget * list3
GtkWidget * description
GtkWidget * go_up_button
GtkWidget * save_button
GtkWidget * statusbar

Define Documentation

#define AUTOMATIC   "automatic file format"

Definition at line 23 of file engine.cc.

#define HTML   "HTML document (.html, .htm)"

Definition at line 27 of file engine.cc.

#define JSON   "JavaScript Object Notation document (.json)"

Definition at line 26 of file engine.cc.

#define LSHW_XML   "lshw XML format (.lshw, .xml)"

Definition at line 24 of file engine.cc.

#define PLAIN_TEXT   "plain text document (.text, .txt)"

Definition at line 25 of file engine.cc.

#define YIELD ( )    while(gtk_events_pending()) gtk_main_iteration()

Definition at line 29 of file engine.cc.


Enumeration Type Documentation

anonymous enum
Enumerator:
COL_NAME 
COL_NODE 
COL_WEIGHT 
COL_CONTINUATION 
NUM_COLS 

Definition at line 44 of file engine.cc.


Function Documentation

void browse ( unsigned  list,
GtkTreeView *  treeview 
)

Definition at line 331 of file engine.cc.

{
  GtkTreeSelection *selection;
  GtkTreeModel     *model;
  GtkTreeIter       iter;
  hwNode *n = NULL;

  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
  if (gtk_tree_selection_get_selected(selection, &model, &iter))
    gtk_tree_model_get (model, &iter, COL_NODE, &n, -1);

  if(n)
    switch(list)
    {
      case 1:
//if(n!=selected1)
        {
          selected1 = n;
          selected2 = NULL;
          selected3 = NULL;
          populate_sublist(list2, selected1, selected2);
          populate_sublist(list3, selected2, selected3);
        }
      break;
    case 2:
//if(n!=selected2)
      {
        selected2 = n;
        selected3 = NULL;
        populate_sublist(list3, selected2, selected3);
      }
      break;
    case 3:
//if(n!=selected3)
      {
        selected3 = n;
        if(n->countChildren()>0)
        {
          hwNode *oldselected1 = selected1;
          selected1 = selected2;
          selected2 = n;
          selected3 = NULL;
          populate_sublist(list1, oldselected1, selected1);
          populate_sublist(list2, selected1, selected2);
          populate_sublist(list3, selected2, selected3);
        }
      }
      break;
  }

  if(selected1 && (find_parent(selected1, &container)!= &container))
    gtk_widget_set_sensitive(go_up_button, 1);
  else
    gtk_widget_set_sensitive(go_up_button, 0);

  (void) &::id;                                   // avoid warning "id defined but not used"
}

Here is the call graph for this function:

Here is the caller graph for this function:

void change_selection ( unsigned  list,
GtkTreeView *  treeview 
)

Definition at line 292 of file engine.cc.

{
  GtkTreeSelection *selection;
  GtkTreeModel *model;
  GtkTreeIter   iter;

  model = gtk_tree_view_get_model(treeview);

  displayed = NULL;

  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
  if (gtk_tree_selection_get_selected(selection, &model, &iter))
    gtk_tree_model_get (model, &iter, COL_NODE, &displayed, -1);

  if(list<2) populate_sublist(list2, NULL);
  if(list<3) populate_sublist(list3, NULL);

  display(mainwindow);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void clear_list ( GtkWidget *  list1) [static]

Definition at line 53 of file engine.cc.

{
  GtkTreeViewColumn *col;

  while((col = gtk_tree_view_get_column(GTK_TREE_VIEW(list1), 0)))
    gtk_tree_view_remove_column(GTK_TREE_VIEW(list1), col);
}

Here is the caller graph for this function:

static void create_tags ( GtkTextBuffer *  buffer) [static]

Definition at line 124 of file engine.cc.

{
  static bool initialized = false;

  if(initialized) return;

  initialized = true;

  gtk_text_buffer_create_tag (buffer, "heading",
    "weight", PANGO_WEIGHT_BOLD,
    "size", 15 * PANGO_SCALE,
    NULL);

  gtk_text_buffer_create_tag (buffer, "italic",
    "style", PANGO_STYLE_ITALIC, NULL);

  gtk_text_buffer_create_tag (buffer, "bold",
    "weight", PANGO_WEIGHT_BOLD, NULL);

  gtk_text_buffer_create_tag (buffer, "big",
/* points times the PANGO_SCALE factor */
    "size", 20 * PANGO_SCALE, NULL);

  gtk_text_buffer_create_tag (buffer, "xx-small",
    "scale", PANGO_SCALE_XX_SMALL, NULL);

  gtk_text_buffer_create_tag (buffer, "x-large",
    "scale", PANGO_SCALE_X_LARGE, NULL);

  gtk_text_buffer_create_tag (buffer, "monospace",
    "family", "monospace", NULL);

  gtk_text_buffer_create_tag (buffer, "blue_foreground",
    "foreground", "blue", NULL);

  gtk_text_buffer_create_tag (buffer, "red_background",
    "background", "red", NULL);

  gtk_text_buffer_create_tag (buffer, "big_gap_before_line",
    "pixels_above_lines", 30, NULL);

  gtk_text_buffer_create_tag (buffer, "big_gap_after_line",
    "pixels_below_lines", 30, NULL);

  gtk_text_buffer_create_tag (buffer, "double_spaced_line",
    "pixels_inside_wrap", 10, NULL);

  gtk_text_buffer_create_tag (buffer, "not_editable",
    "editable", FALSE, NULL);

  gtk_text_buffer_create_tag (buffer, "word_wrap",
    "wrap_mode", GTK_WRAP_WORD, NULL);

  gtk_text_buffer_create_tag (buffer, "char_wrap",
    "wrap_mode", GTK_WRAP_CHAR, NULL);

  gtk_text_buffer_create_tag (buffer, "no_wrap",
    "wrap_mode", GTK_WRAP_NONE, NULL);

  gtk_text_buffer_create_tag (buffer, "center",
    "justification", GTK_JUSTIFY_CENTER, NULL);

  gtk_text_buffer_create_tag (buffer, "right_justify",
    "justification", GTK_JUSTIFY_RIGHT, NULL);

  gtk_text_buffer_create_tag (buffer, "wide_margins",
    "left_margin", 50, "right_margin", 50,
    NULL);

  gtk_text_buffer_create_tag (buffer, "strikethrough",
    "strikethrough", TRUE, NULL);

  gtk_text_buffer_create_tag (buffer, "underline",
    "underline", PANGO_UNDERLINE_SINGLE, NULL);

  gtk_text_buffer_create_tag (buffer, "double_underline",
    "underline", PANGO_UNDERLINE_DOUBLE, NULL);

  gtk_text_buffer_create_tag (buffer, "superscript",
    "rise", 10 * PANGO_SCALE,                     /* 10 pixels */
    "size", 8 * PANGO_SCALE,                      /* 8 points */
    NULL);

  gtk_text_buffer_create_tag (buffer, "subscript",
    "rise", -10 * PANGO_SCALE,                    /* 10 pixels */
    "size", 8 * PANGO_SCALE,                      /* 8 points */
    NULL);
}

Here is the caller graph for this function:

static void display ( GtkWidget *  mainwindow) [static]

Definition at line 214 of file engine.cc.

{
  GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (description));

  gtk_text_buffer_set_text(buffer, "", -1);

  if(!displayed)
    gtk_text_buffer_set_text(buffer, "Please select a node to display.", -1);
  else
  {
    create_tags(buffer);

    string hwpath = gethwpath(*displayed, container);
    printmarkup(*displayed, GTK_TEXT_VIEW(description), hwpath);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static hwNode* find_parent ( hwNode n,
hwNode sub 
) [static]

Definition at line 313 of file engine.cc.

{
  if(!n) return NULL;

  if(n == sub) return n;

  for(unsigned i=0; i<sub->countChildren(); i++)
  {
    if(sub->getChild(i) == n) return sub;

    hwNode *r = find_parent(n, sub->getChild(i));
    if(r) return r;
  }

  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* fix_filename ( char *  s,
const char *  extension 
) [static]

Definition at line 433 of file engine.cc.

{
  char *dot = strrchr(s, '.');

  if(dot)
    return s;

  s = (char*)realloc(s, strlen(s) + 1 + strlen(extension) + 1);
  strcat(s, ".");
  strcat(s, extension);

  return s;
}

Here is the caller graph for this function:

void go_back ( GtkWidget *  mainwindow)

Definition at line 390 of file engine.cc.

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* guess_format ( char *  s) [static]

Definition at line 414 of file engine.cc.

{
  char *dot = strrchr(s, '.');

  if(!dot)
    return LSHW_XML;

  if(!strcasecmp(".html", dot) || !strcasecmp(".htm", dot))
    return HTML;

  if(!strcasecmp(".text", dot) || !strcasecmp(".txt", dot))
    return PLAIN_TEXT;

  if(!strcasecmp(".json", dot))
    return JSON;

  return LSHW_XML;
}

Here is the caller graph for this function:

static void populate_sublist ( GtkWidget *  list1,
hwNode root,
hwNode current = NULL 
) [static]

Definition at line 62 of file engine.cc.

{
  GtkListStore *list_store = NULL;
  GtkTreeViewColumn   *col = NULL;
  GtkCellRenderer     *renderer = NULL;
  GtkTreeIter iter;
  GtkTreeIter current_iter;

  clear_list(list1);

  if(!root) return;

  list_store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING);

  for(unsigned i = 0; i<root->countChildren(); i++)
  {
    string text;

    gtk_list_store_append(list_store, &iter);

    if(root->getChild(i) == current) current_iter = iter;

    text = root->getChild(i)->getDescription();
    if(text == "")
      text = root->getChild(i)->getProduct();
    if(text == "")
      text = root->getChild(i)->getId();

    gtk_list_store_set (list_store, &iter,
      COL_NAME, text.c_str(),
      COL_NODE, root->getChild(i),
      COL_WEIGHT, (root->getChild(i)->countChildren()>0)?PANGO_WEIGHT_BOLD:PANGO_WEIGHT_NORMAL,
      COL_CONTINUATION, (root->getChild(i)->countChildren()>0)?"\342\226\270":"",
      -1);
  }

  col = gtk_tree_view_column_new();
  gtk_tree_view_append_column(GTK_TREE_VIEW(list1), col);

  renderer = gtk_cell_renderer_text_new();

  gtk_tree_view_column_pack_start(col, renderer, TRUE);
  gtk_tree_view_column_add_attribute(col, renderer, "text", COL_NAME);
  gtk_tree_view_column_add_attribute(col, renderer, "weight", COL_WEIGHT);

  col = gtk_tree_view_column_new();
  gtk_tree_view_append_column(GTK_TREE_VIEW(list1), col);
  renderer = gtk_cell_renderer_text_new();
  g_object_set(renderer, "xalign", (gfloat)1, NULL);
  gtk_tree_view_column_pack_start(col, renderer, TRUE);
  gtk_tree_view_column_add_attribute(col, renderer, "text", COL_CONTINUATION);
  gtk_tree_view_column_add_attribute(col, renderer, "weight", COL_WEIGHT);

  gtk_tree_view_set_model(GTK_TREE_VIEW(list1), GTK_TREE_MODEL(list_store));
  g_object_unref(list_store);

  gtk_tree_selection_set_mode(GTK_TREE_SELECTION(gtk_tree_view_get_selection(GTK_TREE_VIEW(list1))), GTK_SELECTION_BROWSE);
  if(current)
    gtk_tree_selection_select_iter(GTK_TREE_SELECTION(gtk_tree_view_get_selection(GTK_TREE_VIEW(list1))), &current_iter);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void redirect_cout ( std::ofstream &  out,
bool  enable = true 
) [static]

Definition at line 447 of file engine.cc.

{
  static std::streambuf* old_cout;
  
  if(enable)
  {
    old_cout = cout.rdbuf();
    cout.rdbuf(out.rdbuf());
  }
  else
    cout.rdbuf(old_cout);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void refresh ( GtkWidget *  mainwindow)

Definition at line 249 of file engine.cc.

{
  hwNode computer("computer", hw::system);
  static bool lock = false;
  //GtkWidget * menu = lookup_widget(mainwindow, "menu");
  //GtkWidget * save_menuitem = lookup_widget(menu, "save");

  if(lock) return;

  lock = true;
  gtk_widget_set_sensitive(save_button, FALSE);
  //gtk_widget_set_sensitive(save_menuitem, FALSE);

  populate_sublist(list1, NULL);
  populate_sublist(list2, NULL);
  populate_sublist(list3, NULL);
  displayed = NULL;
  gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(description)), "scanning...", -1);

  disable("output:sanitize");
  container = hwNode("container", hw::generic);
  status("Scanning...");
  scan_system(computer);
  status(NULL);
  displayed = container.addChild(computer);

  gtk_widget_set_sensitive(go_up_button, FALSE);
  gtk_widget_set_sensitive(save_button, TRUE);
  //gtk_widget_set_sensitive(save_menuitem, TRUE);

  selected1 = NULL;
  selected2 = NULL;
  selected3 = NULL;

  populate_sublist(list1, &container);
  populate_sublist(list2, NULL);
  populate_sublist(list3, NULL);
  display(mainwindow);

  lock = false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void save_as ( GtkWidget *  mainwindow)

Definition at line 460 of file engine.cc.

{
  struct utsname buf;
  GtkWidget *dialog = NULL;
  GtkWidget *sanitize = NULL;
  GtkFileFilter *filter = NULL;
  bool proceed = true;
  hwNode *computer = container.getChild(0);

  if(!computer)             // nothing to save
    return;

  dialog = gtk_file_chooser_dialog_new ("Save hardware configuration",
                                  GTK_WINDOW(mainwindow),
                                  GTK_FILE_CHOOSER_ACTION_SAVE,
                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                                  NULL);
  //gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
  sanitize = gtk_check_button_new_with_label("Anonymize output");
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sanitize), enabled("output:sanitize")?TRUE:FALSE);
  gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), sanitize);

  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name(filter, AUTOMATIC);
  gtk_file_filter_add_pattern(filter, "*");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name(filter, LSHW_XML);
  gtk_file_filter_add_pattern(filter, "*.lshw");
  gtk_file_filter_add_pattern(filter, "*.xml");
  gtk_file_filter_add_mime_type(filter, "text/xml");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name(filter, HTML);
  gtk_file_filter_add_pattern(filter, "*.html");
  gtk_file_filter_add_pattern(filter, "*.htm");
  gtk_file_filter_add_mime_type(filter, "text/html");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name(filter, PLAIN_TEXT);
  gtk_file_filter_add_pattern(filter, "*.text");
  gtk_file_filter_add_pattern(filter, "*.txt");
  gtk_file_filter_add_mime_type(filter, "text/plain");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name(filter, JSON);
  gtk_file_filter_add_pattern(filter, "*.json");
  gtk_file_filter_add_mime_type(filter, "application/json");
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

  if(uname(&buf)==0)
    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), buf.nodename);

  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
  {
    char *filename;

    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sanitize)))
      enable("output:sanitize");
    else
      disable("output:sanitize");

    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
    filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
    if(filename && filter)
    {
      const gchar *filtername = gtk_file_filter_get_name(filter);

      if(strcmp(filtername, AUTOMATIC)==0)
        filtername = guess_format(filename);

      if(!exists(filename))        // creating a new file
      {
        if(strcmp(filtername, LSHW_XML)==0)
          filename = fix_filename(filename, "lshw");
        else
        if(strcmp(filtername, HTML)==0)
          filename = fix_filename(filename, "html");
        else
        if(strcmp(filtername, PLAIN_TEXT)==0)
          filename = fix_filename(filename, "txt");
        else
        if(strcmp(filtername, JSON)==0)
          filename = fix_filename(filename, "json");
      }

      if(exists(filename))         // existing file
      {
        char * buffer1 = g_strdup(filename);
        char * buffer2 = g_strdup(filename);

        GtkWidget *dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW(mainwindow),
                                  GTK_DIALOG_DESTROY_WITH_PARENT,
                                  GTK_MESSAGE_WARNING,
                                  GTK_BUTTONS_NONE,
                                  "A file named <i><tt>%s</tt></i> already exists in folder <tt>%s</tt>.\n\nDo you want to overwrite it?",
                                  basename(buffer1), dirname(buffer2));
        gtk_dialog_add_buttons(GTK_DIALOG(dialog), 
                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                              "Overwrite", GTK_RESPONSE_ACCEPT,
                                  NULL);
        proceed = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT);
        gtk_widget_destroy (dialog);
        g_free(buffer1);
        g_free(buffer2);
      }

      if(proceed)
      {
        if(strcmp(filtername, LSHW_XML)==0)
        {
          std::ofstream out(filename);
          redirect_cout(out);
          cout << computer->asXML();
          redirect_cout(out, false);
        }
        else
        if(strcmp(filtername, HTML)==0)
        {
          std::ofstream out(filename);
          redirect_cout(out);
          print(*computer, true);
          redirect_cout(out, false);
        }
        else
        if(strcmp(filtername, PLAIN_TEXT)==0)
        {
          std::ofstream out(filename);
          redirect_cout(out);
          print(*computer, false);
          redirect_cout(out, false);
        }
       else
        if(strcmp(filtername, JSON)==0)
        {
          std::ofstream out(filename);
          redirect_cout(out);
          cout << computer->asJSON() << endl;
          redirect_cout(out, false);
        }
      }
      g_free (filename);
    }
  }

  gtk_widget_destroy (dialog);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void status ( const char *  message)

Definition at line 232 of file engine.cc.

{
  static guint context_id = 0;

  if(!GTK_IS_WIDGET(statusbar)) return;

  if(!context_id)
    context_id = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "scanning");
  else
    gtk_statusbar_pop(GTK_STATUSBAR(statusbar), context_id);

  if(message) gtk_statusbar_push(GTK_STATUSBAR(statusbar), context_id, message);

  YIELD();
}

Variable Documentation

hwNode container("container", hw::generic) [static]
GtkWidget* description

Definition at line 15 of file stock.c.

hwNode* displayed = NULL [static]

Definition at line 32 of file engine.cc.

GtkWidget* go_up_button

Definition at line 16 of file stock.c.

const char* id = "@(#) $Id: engine.cc 2433 2012-01-10 22:01:30Z lyonel $" [static]

Definition at line 16 of file engine.cc.

GtkWidget* list1

Definition at line 12 of file stock.c.

GtkWidget * list2

Definition at line 13 of file stock.c.

GtkWidget * list3

Definition at line 14 of file stock.c.

GtkWidget* mainwindow

Definition at line 10 of file stock.c.

GtkWidget* save_button

Definition at line 17 of file stock.c.

hwNode* selected1 = NULL [static]

Definition at line 33 of file engine.cc.

hwNode* selected2 = NULL [static]

Definition at line 34 of file engine.cc.

hwNode* selected3 = NULL [static]

Definition at line 35 of file engine.cc.

GtkWidget* statusbar

Definition at line 18 of file stock.c.