Move capture_globals.h from ui/gtk/ to ui/. Show interface activity
authorGerald Combs <gerald@wireshark.org>
Fri, 3 Aug 2012 23:30:47 +0000 (23:30 -0000)
committerGerald Combs <gerald@wireshark.org>
Fri, 3 Aug 2012 23:30:47 +0000 (23:30 -0000)
using sparklines in the qtshark main window.

svn path=/trunk/; revision=44253

16 files changed:
ui/capture_globals.h [moved from ui/gtk/capture_globals.h with 100% similarity]
ui/gtk/capture_dlg.c
ui/gtk/capture_if_dlg.c
ui/gtk/drag_and_drop.c
ui/gtk/gtk_iface_monitor.c
ui/gtk/main.c
ui/gtk/main_menubar.c
ui/gtk/main_welcome.c
ui/gtk/prefs_capture.c
ui/gtk/summary_dlg.c
ui/qt/QtShark.pro
ui/qt/interface_tree.cpp
ui/qt/interface_tree.h
ui/qt/main.cpp
ui/qt/sparkline_delegate.cpp [new file with mode: 0644]
ui/qt/sparkline_delegate.h [new file with mode: 0644]

index beab15e6f07644119a127000bde262288a684b9e..4d66a54866319fb0d5ce5c9d470d4cc4c5b3707f 100644 (file)
@@ -46,6 +46,7 @@
 #include "../capture_ui_utils.h"
 #include "../ringbuffer.h"
 
+#include "ui/capture_globals.h"
 #include "ui/iface_lists.h"
 #include "ui/recent.h"
 #include "ui/recent_utils.h"
@@ -61,7 +62,6 @@
 #include "ui/gtk/capture_file_dlg.h"
 #include "ui/gtk/help_dlg.h"
 #include "ui/gtk/gtkglobals.h"
-#include "ui/gtk/capture_globals.h"
 #include "ui/gtk/cfilter_combo_utils.h"
 #include "ui/gtk/capture_if_dlg.h"
 #include "ui/gtk/main_welcome.h"
index f59ac82fab5f50b2cc46a61d7891253ac6c43c70..afbf7879687df653f56125eace91d0f0e2ed9123 100644 (file)
@@ -41,6 +41,7 @@
 #include "wsutil/file_util.h"
 #include <wiretap/wtap.h>
 
+#include "ui/capture_globals.h"
 #include "ui/recent.h"
 #include "ui/simple_dialog.h"
 
@@ -59,7 +60,6 @@
 #include "ui/gtk/help_dlg.h"
 #include "ui/gtk/keys.h"
 #include "ui/gtk/webbrowser.h"
-#include "ui/gtk/capture_globals.h"
 #include "ui/gtk/network_icons.h"
 #include "ui/gtk/pipe_icon.h"
 #include "ui/gtk/main_welcome.h"
index e3cb6428804a7930defee2bf8a5bbe76b16e9833..90811ed18b4826ace4cbe2ebafbdb05bee738a6c 100644 (file)
@@ -39,6 +39,9 @@
 #include "../capture.h"
 #endif
 
+#ifdef HAVE_LIBPCAP
+#include "ui/capture_globals.h"
+#endif
 #include "ui/recent_utils.h"
 #include "ui/simple_dialog.h"
 
@@ -46,9 +49,6 @@
 #include "ui/gtk/capture_file_dlg.h"
 #include "ui/gtk/drag_and_drop.h"
 #include "ui/gtk/main.h"
-#ifdef HAVE_LIBPCAP
-#include "ui/gtk/capture_globals.h"
-#endif
 
 #include "ui/gtk/old-gtk-compat.h"
 
index 99aaa4e95a330f7564529031a8fcf5191ea0b622..64508e77f10a23e2db37a052890eb9c37a4c154b 100644 (file)
@@ -36,9 +36,9 @@
 
 #include "capture_opts.h"
 
+#include "ui/capture_globals.h"
 #include "ui/iface_lists.h"
 
-#include "ui/gtk/capture_globals.h"
 #include "ui/gtk/capture_dlg.h"
 
 GIOChannel *iface_mon_channel;
index 22cb36830ad1a56e9d642839337409c314b5cde0..6c90932a91ef0c3957427b992bd0b98f52f6cb57 100644 (file)
 #include "ui/ui_util.h"
 
 #ifdef HAVE_LIBPCAP
+#include "ui/capture_globals.h"
 #include "ui/iface_lists.h"
 #endif
 
 #include <wsutil/file_util.h>
 
 #ifdef HAVE_LIBPCAP
-#include "../capture_ui_utils.h"
-#include "../capture-pcap-util.h"
-#include "../capture_ifinfo.h"
-#include "../capture.h"
-#include "../capture_sync.h"
+#include "capture_ui_utils.h"
+#include "capture-pcap-util.h"
+#include "capture_ifinfo.h"
+#include "capture.h"
+#include "capture_sync.h"
 #endif
 
 #ifdef _WIN32
-#include "../capture-wpcap.h"
-#include "../capture_wpcap_packet.h"
+#include "capture-wpcap.h"
+#include "capture_wpcap_packet.h"
 #include <tchar.h> /* Needed for Unicode */
 #include <wsutil/unicode-utils.h>
 #include <commctrl.h>
 #include "ui/gtk/webbrowser.h"
 #include "ui/gtk/capture_dlg.h"
 #include "ui/gtk/capture_if_dlg.h"
-#include "ui/gtk/capture_globals.h"
 #include "ui/gtk/tap_param_dlg.h"
 #include "ui/gtk/prefs_column.h"
 #include "ui/gtk/prefs_dlg.h"
index fc992e968e17fbbad1b53a108d14e9a688caa548..0008a50f518534adedf95f4582f58344be3abadb 100644 (file)
 
 #ifdef HAVE_LIBPCAP
 #include "capture_opts.h"
-#include "ui/gtk/capture_globals.h"
+#include "ui/capture_globals.h"
 #endif
 #ifdef HAVE_IGE_MAC_INTEGRATION
 #include <ige-mac-menu.h>
index 2ea159592000140a52fd0efcf432654175a995ee..8e51d9a41dad010955e5c79b35b1bbf745f70bcf 100644 (file)
 
 #include <wsutil/file_util.h>
 
+#ifdef HAVE_LIBPCAP
 #include "ui/iface_lists.h"
+#include "ui/capture_globals.h"
+#endif
 #include "ui/recent.h"
 #include "ui/simple_dialog.h"
 #include "ui/utf8_entities.h"
@@ -58,7 +61,6 @@
 #ifdef HAVE_LIBPCAP
 #include "ui/gtk/capture_dlg.h"
 #include "ui/gtk/capture_if_dlg.h"
-#include "ui/gtk/capture_globals.h"
 #if GTK_CHECK_VERSION(2,18,0)
 #include "ui/gtk/webbrowser.h"
 #endif
index 646338540588c9e06290de4e9e02c6ecc815d13e..6257aeee6e950eac7aa50fdd14e9e6ef0c74d29f 100644 (file)
 
 #include <epan/prefs.h>
 
+#include "capture_opts.h"
+#include "capture_ifinfo.h"
+#include "capture_ui_utils.h"
+#include "ui/capture_globals.h"
 #include "ui/iface_lists.h"
 #include "ui/simple_dialog.h"
-#include "../capture_ifinfo.h"
-#include "../capture_ui_utils.h"
 
 #include "ui/gtk/prefs_capture.h"
 #include "ui/gtk/prefs_dlg.h"
 #include "ui/gtk/gui_utils.h"
 #include "ui/gtk/dlg_utils.h"
-#include "ui/gtk/capture_globals.h"
 #include "ui/gtk/main_welcome.h"
 #include "ui/gtk/help_dlg.h"
 #include "ui/gtk/stock_icons.h"
index 0c3e93426c539f5cddfa9dadee0ffe010237feb7..a0184502e03585ef5960a62ef78f42d87e59c109 100644 (file)
@@ -41,7 +41,7 @@
 #include "../capture-pcap-util.h"
 #ifdef HAVE_LIBPCAP
 #include "../capture.h"
-#include "ui/gtk/capture_globals.h"
+#include "ui/capture_globals.h"
 #endif
 #include "ui/gtk/main.h"
 #include "ui/gtk/summary_dlg.h"
index 3826a8769df8dcfa3178ef0d3ad5a66d06ac9fb0..93eff33a5619880e3c46481c65aa72635ce1a929 100644 (file)
@@ -9,6 +9,9 @@ QT += core gui
 TARGET = qtshark
 TEMPLATE = app
 
+# XXX - Need to autogenerate Info.plist from Info.plist.in
+# QMAKE_INFO_PLIST = ../../packaging/macosx/Info.plist
+
 xxx {
     message( )
     message(CONFIG:)
@@ -89,6 +92,9 @@ win32:INCLUDEPATH += \
 # We have to manually trigger relinking each time one of these is modified.
 # Is there any way to do this automatically?
 SOURCES_WS_C = \
+    ../alert_box.c  \
+    ../iface_lists.c \
+    ../util.c  \
     ../../airpcap_loader.c \
     ../../capture-pcap-util.c     \
     ../../capture.c       \
@@ -119,8 +125,6 @@ SOURCES_WS_C = \
     ../../tempfile.c      \
     ../../timestats.c     \
     ../../u3.c \
-    ../../ui/alert_box.c  \
-    ../../ui/util.c  \
     ../../version_info.c
 
 unix:SOURCES_WS_C += ../../capture-pcap-util-unix.c
@@ -318,3 +322,9 @@ ICON = ../../packaging/macosx/Resources/Wireshark.icns
 RC_FILE = qtshark.rc
 
 win32: QMAKE_CLEAN += *.pdb
+
+HEADERS += \
+    sparkline_delegate.h
+
+SOURCES += \
+    sparkline_delegate.cpp
index afdf059836e4b04cccc509489c9b11cc6623ff66..8a5a5d2e4adafaec79b0885a494fa8b95eba3d82 100644 (file)
 
 #include "interface_tree.h"
 
-#include "config.h"
+#include "ui/capture_globals.h"
+#include "ui/iface_lists.h"
 
-#ifdef HAVE_LIBPCAP
-#include "capture.h"
-#include "capture-pcap-util.h"
-#include "capture_opts.h"
-#include "capture_ui_utils.h"
-#endif
+#include "epan/prefs.h"
+
+#include "sparkline_delegate.h"
 
 #include <QLabel>
 #include <QHeaderView>
+#include <QTimer>
+
+#include <QDebug>
 
 InterfaceTree::InterfaceTree(QWidget *parent) :
     QTreeWidget(parent)
@@ -46,10 +47,12 @@ InterfaceTree::InterfaceTree(QWidget *parent) :
     header()->setVisible(false);
     setRootIsDecorated(false);
     setUniformRowHeights(true);
+    setColumnCount(2);
 #ifdef Q_WS_MAC
     setAttribute(Qt::WA_MacShowFocusRect, false);
 #endif
     setAccessibleName(tr("Welcome screen list"));
+    setColumnWidth(1, 10);
 
     setStyleSheet(
             "QTreeWidget {"
@@ -57,9 +60,14 @@ InterfaceTree::InterfaceTree(QWidget *parent) :
             "}"
             );
 
+    m_statCache = NULL;
+    m_statTimer = new QTimer(this);
+    connect(m_statTimer, SIGNAL(timeout()), this, SLOT(updateStatistics()));
+
+    setItemDelegateForColumn(1, new SparkLineDelegate());
+
     if_list = capture_interface_list(&err, &err_str);
-    g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: move if_list_comparator_alph out of ui/gtk/");
-//    if_list = g_list_sort(if_list, if_list_comparator_alph);
+    if_list = g_list_sort(if_list, if_list_comparator_alph);
 
     if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
         ti = new QTreeWidgetItem();
@@ -81,16 +89,100 @@ InterfaceTree::InterfaceTree(QWidget *parent) :
         setDisabled(false);
 
         for (curr = g_list_first(if_list); curr; curr = g_list_next(curr)) {
+            QList<int> *points;
+            QVariant v;
+
             if_info = (if_info_t *) curr->data;
             /* Continue if capture device is hidden */
-//            if (prefs_is_capture_device_hidden(if_info->name)) {
-//                continue;
-//            }
+            if (prefs_is_capture_device_hidden(if_info->name)) {
+                continue;
+            }
 
             ti = new QTreeWidgetItem();
             ti->setText(0, QString().fromUtf8(if_info->description ? if_info->description : if_info->name));
+            points = new QList<int>();
+            v.setValue(points);
+            ti->setData(1, Qt::UserRole, v);
             addTopLevelItem(ti);
+
         }
     }
     free_interface_list(if_list);
 }
+
+InterfaceTree::~InterfaceTree() {
+    QTreeWidgetItemIterator iter(this);
+
+    if (m_statCache) {
+      capture_stat_stop(m_statCache);
+      m_statCache = NULL;
+    }
+
+    while (*iter) {
+        QList<int> *points;
+        QVariant v;
+
+        v = (*iter)->data(1, Qt::UserRole);
+        points = v.value<QList<int> *>();
+        delete(points);
+    }
+}
+
+void InterfaceTree::hideEvent(QHideEvent *evt) {
+    Q_UNUSED(evt);
+
+    m_statTimer->stop();
+    if (m_statCache) {
+        capture_stat_stop(m_statCache);
+        m_statCache = NULL;
+    }
+}
+
+void InterfaceTree::showEvent(QShowEvent *evt) {
+    Q_UNUSED(evt);
+
+    m_statTimer->start(1000);
+}
+
+void InterfaceTree::updateStatistics(void) {
+    interface_t device;
+    guint diff, if_idx;
+    struct pcap_stat stats;
+
+    if (!m_statCache) {
+        // Start gathering statistics using dumpcap
+        // We crash (on OS X at least) if we try to do this from ::showEvent.
+        m_statCache = capture_stat_start(&global_capture_opts);
+    }
+    if (!m_statCache) return;
+
+    QTreeWidgetItemIterator iter(this);
+    while (*iter) {
+        QList<int> *points;
+        QVariant v;
+
+        for (if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
+            device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
+
+            if ((*iter)->text(0).compare(QString().fromUtf8(device.name)) || device.hidden || device.type == IF_PIPE)
+                continue;
+
+            diff = 0;
+            if (capture_stats(m_statCache, device.name, &stats)) {
+                if ((int)(stats.ps_recv - device.last_packets) >= 0) {
+                    diff = stats.ps_recv - device.last_packets;
+                }
+                device.last_packets = stats.ps_recv;
+            }
+
+            v = (*iter)->data(1, Qt::UserRole);
+            points = v.value<QList<int> *>();
+            points->append(diff);
+            update(indexFromItem((*iter), 1));
+            global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, if_idx);
+            g_array_insert_val(global_capture_opts.all_ifaces, if_idx, device);
+
+        }
+        iter++;
+    }
+}
index 4cb259d5e0999aa25652b4244a6f89850a92da05..2794cb75dafa2ae214358beebf65b2c90874a206 100644 (file)
 #ifndef INTERFACE_TREE_H
 #define INTERFACE_TREE_H
 
+#include "config.h"
+
 #include <glib.h>
 
+#ifdef HAVE_LIBPCAP
+#include "capture.h"
+#include "capture-pcap-util.h"
+#include "capture_opts.h"
+#include "capture_ui_utils.h"
+#endif
+
 #include <QTreeWidget>
 
 class InterfaceTree : public QTreeWidget
@@ -33,11 +42,22 @@ class InterfaceTree : public QTreeWidget
     Q_OBJECT
 public:
     explicit InterfaceTree(QWidget *parent = 0);
+    ~InterfaceTree();
+
+protected:
+    void hideEvent(QHideEvent *evt);
+    void showEvent(QShowEvent *evt);
+
+private:
+    if_stat_cache_t *m_statCache;
+    QTimer *m_statTimer;
 
 signals:
 
 public slots:
 
+private slots:
+    void updateStatistics(void);
 };
 
 #endif // INTERFACE_TREE_H
index f15c936552446fb424d554bf64cc499b65776d54..4ee04e86578b3cc322f9902f3b9a4c5da15a5580 100644 (file)
@@ -83,6 +83,7 @@
 #include <wsutil/file_util.h>
 
 #include "ui/alert_box.h"
+#include "ui/iface_lists.h"
 #include "ui/main_statusbar.h"
 #include "ui/recent.h"
 #include "ui/simple_dialog.h"
@@ -146,7 +147,7 @@ static void console_log_handler(const char *log_domain,
 void create_console(void);
 
 #ifdef HAVE_LIBPCAP
-capture_options global_capture_opts;
+extern capture_options global_capture_opts;
 #endif
 
 // Copied from ui/gtk/gui_utils.c
@@ -953,8 +954,144 @@ int main(int argc, char *argv[])
 
 /////////
 
+#ifdef HAVE_LIBPCAP
+    fill_in_local_interfaces();
+//  if (start_capture && list_link_layer_types) {
+//    /* Specifying *both* is bogus. */
+//    cmdarg_err("You can't specify both -L and a live capture.");
+//    exit(1);
+//  }
+
+//  if (list_link_layer_types) {
+//    /* We're supposed to list the link-layer types for an interface;
+//       did the user also specify a capture file to be read? */
+//    if (cf_name) {
+//      /* Yes - that's bogus. */
+//      cmdarg_err("You can't specify -L and a capture file to be read.");
+//      exit(1);
+//    }
+//    /* No - did they specify a ring buffer option? */
+//    if (global_capture_opts.multi_files_on) {
+//      cmdarg_err("Ring buffer requested, but a capture isn't being done.");
+//      exit(1);
+//    }
+//  } else {
+//    /* We're supposed to do a live capture; did the user also specify
+//       a capture file to be read? */
+//    if (start_capture && cf_name) {
+//      /* Yes - that's bogus. */
+//      cmdarg_err("You can't specify both a live capture and a capture file to be read.");
+//      exit(1);
+//    }
+
+//    /* No - was the ring buffer option specified and, if so, does it make
+//       sense? */
+//    if (global_capture_opts.multi_files_on) {
+//      /* Ring buffer works only under certain conditions:
+//      a) ring buffer does not work with temporary files;
+//      b) real_time_mode and multi_files_on are mutually exclusive -
+//         real_time_mode takes precedence;
+//      c) it makes no sense to enable the ring buffer if the maximum
+//         file size is set to "infinite". */
+//      if (global_capture_opts.save_file == NULL) {
+//        cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
+//        global_capture_opts.multi_files_on = FALSE;
+//      }
+//      if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
+//        cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
+//        /* XXX - this must be redesigned as the conditions changed */
+//      }
+//    }
+//  }
+
+//  if (start_capture || list_link_layer_types) {
+//    /* Did the user specify an interface to use? */
+//    if (!capture_opts_trim_iface(&global_capture_opts,
+//        (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
+//        exit(2);
+//    }
+//  }
+
+//  if (list_link_layer_types) {
+//    /* Get the list of link-layer types for the capture devices. */
+//    if_capabilities_t *caps;
+//    guint i;
+//    interface_t device;
+//    for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+
+//      device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+//      if (device.selected) {
+//#if defined(HAVE_PCAP_CREATE)
+//        caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
+//#else
+//        caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
+//#endif
+//        if (caps == NULL) {
+//          cmdarg_err("%s", err_str);
+//          g_free(err_str);
+//          exit(2);
+//        }
+//        if (caps->data_link_types == NULL) {
+//          cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
+//          exit(2);
+//        }
+//#if defined(HAVE_PCAP_CREATE)
+//        capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
+//#else
+//        capture_opts_print_if_capabilities(caps, device.name, FALSE);
+//#endif
+//        free_if_capabilities(caps);
+//      }
+//    }
+//    exit(0);
+//  }
+
+    capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
+    capture_opts_trim_ring_num_files(&global_capture_opts);
+#endif /* HAVE_LIBPCAP */
+
+  /* Notify all registered modules that have had any of their preferences
+     changed either from one of the preferences file or from the command
+     line that their preferences have changed. */
+    prefs_apply_all();
+
+#ifdef HAVE_LIBPCAP
+    if ((global_capture_opts.num_selected == 0) &&
+            (prefs.capture_device != NULL)) {
+        guint i;
+        interface_t device;
+        for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+            device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+            if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
+                device.selected = TRUE;
+                global_capture_opts.num_selected++;
+                global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+                g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+                break;
+            }
+        }
+    }
+#endif
+
+    /* disabled protocols as per configuration file */
+    if (gdp_path == NULL && dp_path == NULL) {
+        set_disabled_protos_list();
+    }
+
     build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
 
+//    /* read in rc file from global and personal configuration paths. */
+//    rc_file = get_datafile_path(RC_FILE);
+//  #if GTK_CHECK_VERSION(3,0,0)
+//    /* XXX resolve later */
+//  #else
+//    gtk_rc_parse(rc_file);
+//    g_free(rc_file);
+//    rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
+//    gtk_rc_parse(rc_file);
+//  #endif
+//    g_free(rc_file);
+
     font_init();
 
 ////////
diff --git a/ui/qt/sparkline_delegate.cpp b/ui/qt/sparkline_delegate.cpp
new file mode 100644 (file)
index 0000000..f62c095
--- /dev/null
@@ -0,0 +1,63 @@
+#include "sparkline_delegate.h"
+
+#include <QPainter>
+
+#include <QDebug>
+
+#define MIN_WIDTH 10
+
+// XXX - Should we use a style sheet for this?
+#define SL_MARGIN 2
+
+void SparkLineDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+                              const QModelIndex &index) const
+{
+    QList<int> *points = qvariant_cast<QList<int> *>(index.data(Qt::UserRole));
+    int max = 1;
+    int content_w = option.rect.width() - (SL_MARGIN * 2);
+    int content_h = option.rect.height() - (SL_MARGIN * 2);
+    int val;
+    qreal idx = 0.0;
+    QVector<QPointF> fpoints;
+
+    if (!points || points->isEmpty() || content_w <= 0 || content_h <= 0) {
+        return;
+    }
+
+    while(points->length() > content_w) {
+        points->removeFirst();
+    }
+
+    foreach (val, *points) {
+        if (val > max) max = val;
+    }
+    foreach (val, *points) {
+        fpoints.append(QPointF(idx, (qreal) content_h - (val * content_h / max) ));
+        idx = idx + 1;
+    }
+
+    if (fpoints.count() > 0) {
+    }
+
+    painter->save();
+    painter->setRenderHint(QPainter::Antialiasing, true);
+    painter->translate(option.rect.x() + SL_MARGIN, option.rect.y() + SL_MARGIN);
+
+    painter->setPen(Qt::ForegroundRole);
+    painter->setBrush(option.palette.foreground());
+    painter->drawPolyline(QPolygonF(fpoints));
+
+//    painter->setPen(Qt::NoPen);
+//    painter->setBrush(option.palette.foreground());
+//    painter->drawEllipse(fpoints.first(), 2, 2);
+
+//    painter->setBrush(Qt::red);
+//    painter->drawEllipse(fpoints.last(), 2, 2);
+
+    painter->restore();
+}
+
+QSize SparkLineDelegate::sizeHint(const QStyleOptionViewItem &option,
+                                  const QModelIndex &index) const {
+    return QSize(MIN_WIDTH, QStyledItemDelegate::sizeHint(option, index).height());
+}
diff --git a/ui/qt/sparkline_delegate.h b/ui/qt/sparkline_delegate.h
new file mode 100644 (file)
index 0000000..7022590
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef SPARKLINE_DELEGATE_H
+#define SPARKLINE_DELEGATE_H
+
+#include <QStyledItemDelegate>
+
+class SparkLineDelegate : public QStyledItemDelegate
+{
+    Q_OBJECT
+public:
+    SparkLineDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {}
+
+    void paint(QPainter *painter, const QStyleOptionViewItem &option,
+               const QModelIndex &index) const;
+    QSize sizeHint(const QStyleOptionViewItem &option,
+                   const QModelIndex &index) const;
+
+signals:
+    
+public slots:
+    
+};
+
+Q_DECLARE_METATYPE(QList<int> *)
+
+#endif // SPARKLINE_DELEGATE_H