commit 52c50c8dbe94b5f8504fc0572b68749b9cd8bbc9 Author: Kamran Riaz Khan krkhan@inspirated.com Date: Thu Jul 14 15:12:30 2011 +0500
The mass gtk cleanup.
Add toolbar, move "sticky" panel to the notebook (the application looks much more consistent this way), add about dialog and fix various width/height issues. --- src/gui/arm.xml | 327 ++++++++++++++------------------------- src/gui/controller.py | 17 ++- src/gui/generalPanel.py | 123 +++++++++++++++ src/gui/graphing/graphStats.py | 2 + src/gui/stickyPanel.py | 123 --------------- 5 files changed, 257 insertions(+), 335 deletions(-)
diff --git a/src/gui/arm.xml b/src/gui/arm.xml index f71d0b7..edcc42a 100644 --- a/src/gui/arm.xml +++ b/src/gui/arm.xml @@ -2,7 +2,7 @@ <interface> <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy project-wide --> - <object class="GtkListStore" id="liststore_sticky"> + <object class="GtkListStore" id="liststore_general"> <columns> <!-- column-name key --> <column type="gchararray"/> @@ -100,46 +100,10 @@ <object class="GtkMenu" id="menu_file"> <property name="visible">True</property> <child> - <object class="GtkImageMenuItem" id="imagemenuitem_new"> - <property name="label">gtk-new</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_open"> - <property name="label">gtk-open</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_save"> - <property name="label">gtk-save</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_saveas"> - <property name="label">gtk-save-as</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkSeparatorMenuItem" id="separatormenuitem_file"> - <property name="visible">True</property> - </object> - </child> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_exit"> + <object class="GtkImageMenuItem" id="imagemenuitem_quit"> <property name="label">gtk-quit</property> <property name="visible">True</property> + <property name="related_action">action_quit</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> @@ -149,57 +113,6 @@ </object> </child> <child> - <object class="GtkMenuItem" id="menuitem_edit"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Edit</property> - <property name="use_underline">True</property> - <child type="submenu"> - <object class="GtkMenu" id="menu_edit"> - <property name="visible">True</property> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_cut"> - <property name="label">gtk-cut</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_copy"> - <property name="label">gtk-copy</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_paste"> - <property name="label">gtk-paste</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkImageMenuItem" id="imagemenuitem_delete"> - <property name="label">gtk-delete</property> - <property name="visible">True</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </object> - </child> - </object> - </child> - </object> - </child> - <child> - <object class="GtkMenuItem" id="menuitem_view"> - <property name="visible">True</property> - <property name="label" translatable="yes">_View</property> - <property name="use_underline">True</property> - </object> - </child> - <child> <object class="GtkMenuItem" id="menuitem_help"> <property name="visible">True</property> <property name="label" translatable="yes">_Help</property> @@ -211,6 +124,7 @@ <object class="GtkImageMenuItem" id="imagemenuitem_about"> <property name="label">gtk-about</property> <property name="visible">True</property> + <property name="related_action">action_about</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> @@ -231,13 +145,48 @@ <property name="can_focus">True</property> <property name="orientation">vertical</property> <child> - <object class="GtkHPaned" id="hpaned_main"> - <property name="height_request">300</property> + <object class="GtkVBox" id="vbox_notebook"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkToolbar" id="toolbar_main"> + <property name="visible">True</property> + <child> + <object class="GtkToolButton" id="toolbutton_about"> + <property name="visible">True</property> + <property name="related_action">action_about</property> + <property name="use_action_appearance">True</property> + <property name="label" translatable="yes">About</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-about</property> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <child> + <object class="GtkToolButton" id="toolbutton_quit"> + <property name="visible">True</property> + <property name="related_action">action_quit</property> + <property name="use_action_appearance">True</property> + <property name="label" translatable="yes">Quit</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-quit</property> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> <child> <object class="GtkNotebook" id="notebook_main"> - <property name="width_request">300</property> <property name="visible">True</property> <property name="can_focus">True</property> <child> @@ -461,81 +410,44 @@ </packing> </child> <child> - <object class="GtkVBox" id="vbox_config"> + <object class="GtkScrolledWindow" id="scrolledwindow_general"> <property name="visible">True</property> - <property name="orientation">vertical</property> - <child> - <object class="GtkLabel" id="label_config_top"> - <property name="visible">True</property> - <property name="label" translatable="yes"><span foreground="#368918"><u>RelayBandwidthBurst</u> (General Option) -<b>Value</b>: 0 B (default, DataSize, usage: N bytes|KB|MB|GB|TB) -<b>Description</b>: Limit the maximum token bucket size (also known as -the burst) for <i>relayed traffic</i> to the given number of bytes in -each direction. (Default: 0) </span></property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> <child> - <object class="GtkScrolledWindow" id="scrolledwindow_config"> + <object class="GtkTreeView" id="treeview_general"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> + <property name="model">liststore_general</property> + <property name="headers_visible">False</property> + <property name="headers_clickable">False</property> + <property name="rules_hint">True</property> + <property name="search_column">0</property> <child> - <object class="GtkTreeView" id="treeview_config"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="model">liststore_config</property> - <property name="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="search_column">0</property> + <object class="GtkTreeViewColumn" id="treeviewcolumn_general_key"> + <property name="title">column</property> <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn_key"> - <property name="title">column</property> - <child> - <object class="GtkCellRendererText" id="cellrenderertext_config_key"/> - <attributes> - <attribute name="foreground">3</attribute> - <attribute name="markup">0</attribute> - </attributes> - </child> - </object> + <object class="GtkCellRendererText" id="cellrenderertext_general_key"/> + <attributes> + <attribute name="markup">0</attribute> + </attributes> </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn_general_value"> + <property name="title">column</property> <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn_value"> - <property name="title">column</property> - <child> - <object class="GtkCellRendererText" id="cellrenderertext_config_value"/> - <attributes> - <attribute name="foreground">3</attribute> - <attribute name="markup">1</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn_desc"> - <property name="title">column</property> - <child> - <object class="GtkCellRendererText" id="cellrenderertext_config_desc"/> - <attributes> - <attribute name="foreground">3</attribute> - <attribute name="markup">2</attribute> - </attributes> - </child> - </object> + <object class="GtkCellRendererText" id="cellrenderertext_general_value"/> + <attributes> + <attribute name="foreground">2</attribute> + <attribute name="markup">1</attribute> + </attributes> </child> </object> </child> </object> - <packing> - <property name="position">1</property> - </packing> </child> </object> <packing> @@ -543,9 +455,9 @@ each direction. (Default: 0) </span></property> </packing> </child> <child type="tab"> - <object class="GtkLabel" id="label_notebook_config"> + <object class="GtkLabel" id="label_general"> <property name="visible">True</property> - <property name="label" translatable="yes">Configuration</property> + <property name="label" translatable="yes">General</property> </object> <packing> <property name="position">2</property> @@ -554,54 +466,7 @@ each direction. (Default: 0) </span></property> </child> </object> <packing> - <property name="resize">True</property> - <property name="shrink">False</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow_sticky"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <child> - <object class="GtkTreeView" id="treeview_sticky"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="model">liststore_sticky</property> - <property name="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="rules_hint">True</property> - <property name="search_column">0</property> - <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn_sticky_key"> - <property name="title">column</property> - <child> - <object class="GtkCellRendererText" id="cellrenderertext_sticky_key"/> - <attributes> - <attribute name="markup">0</attribute> - </attributes> - </child> - </object> - </child> - <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn_sticky_value"> - <property name="title">column</property> - <child> - <object class="GtkCellRendererText" id="cellrenderertext_sticky_value"/> - <attributes> - <attribute name="foreground">2</attribute> - <attribute name="markup">1</attribute> - </attributes> - </child> - </object> - </child> - </object> - </child> - </object> - <packing> - <property name="resize">True</property> - <property name="shrink">False</property> + <property name="position">1</property> </packing> </child> </object> @@ -612,7 +477,6 @@ each direction. (Default: 0) </span></property> </child> <child> <object class="GtkScrolledWindow" id="scrolledwindow_log"> - <property name="height_request">100</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="hscrollbar_policy">automatic</property> @@ -622,10 +486,13 @@ each direction. (Default: 0) </span></property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="model">liststore_log</property> + <property name="headers_clickable">False</property> <property name="rules_hint">True</property> + <property name="search_column">0</property> <child> <object class="GtkTreeViewColumn" id="treeviewcolumn_log_timestamp"> <property name="title">Time</property> + <property name="clickable">True</property> <property name="sort_indicator">True</property> <property name="sort_order">descending</property> <property name="sort_column_id">1</property> @@ -666,7 +533,7 @@ each direction. (Default: 0) </span></property> </child> </object> <packing> - <property name="resize">True</property> + <property name="resize">False</property> <property name="shrink">False</property> </packing> </child> @@ -678,4 +545,46 @@ each direction. (Default: 0) </span></property> </object> </child> </object> + <object class="GtkAboutDialog" id="aboutdialog"> + <property name="border_width">5</property> + <property name="type_hint">normal</property> + <property name="program_name">garm</property> + <property name="version">0.1</property> + <property name="copyright" translatable="yes">Copyright (C) 2011 Kamran Riaz Khan</property> + <property name="website">http://inspirated.com/</property> + <property name="website_label" translatable="yes">Blog</property> + <signal name="response" handler="on_aboutdialog_response"/> + <child internal-child="vbox"> + <object class="GtkVBox" id="aboutdialog_vbox"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="aboutdialog_action_area"> + <property name="visible">True</property> + <property name="layout_style">end</property> + </object> + <packing> + <property name="expand">False</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + </object> + <object class="GtkAction" id="action_quit"> + <property name="label">Quit</property> + <property name="short_label">Quit</property> + <property name="tooltip">Quit</property> + <property name="stock_id">gtk-quit</property> + <signal name="activate" handler="on_action_quit_activate"/> + </object> + <object class="GtkAction" id="action_about"> + <property name="label">About</property> + <property name="short_label">About</property> + <property name="tooltip">About</property> + <property name="stock_id">gtk-about</property> + <signal name="activate" handler="on_action_about_activate"/> + </object> </interface> diff --git a/src/gui/controller.py b/src/gui/controller.py index 854e388..5736def 100644 --- a/src/gui/controller.py +++ b/src/gui/controller.py @@ -6,7 +6,7 @@ import time
from util import log, torTools from connections import connPanel -from gui import logPanel, stickyPanel +from gui import logPanel, generalPanel from gui.graphing import bandwidthStats
gobject.threads_init() @@ -29,8 +29,8 @@ class GuiController: self.connPanel.pack_widgets() self.connPanel.start()
- self.stickyPanel = stickyPanel.StickyPanel(self.builder) - self.stickyPanel.pack_widgets() + self.generalPanel = generalPanel.GeneralPanel(self.builder) + self.generalPanel.pack_widgets()
def run(self): window = self.builder.get_object('window_main') @@ -38,6 +38,17 @@ class GuiController: window.show_all() gtk.main()
+ def on_action_about_activate(self, widget, data=None): + dialog = self.builder.get_object('aboutdialog') + dialog.run() + + def on_aboutdialog_response(self, widget, responseid, data=None): + dialog = self.builder.get_object('aboutdialog') + dialog.hide() + + def on_action_quit_activate(self, widget, data=None): + gtk.main_quit() + def on_window_main_delete_event(self, widget, data=None): gtk.main_quit()
diff --git a/src/gui/generalPanel.py b/src/gui/generalPanel.py new file mode 100644 index 0000000..b16cac5 --- /dev/null +++ b/src/gui/generalPanel.py @@ -0,0 +1,123 @@ +""" +General panel. +""" + +import random +import sys +import time + +from collections import deque + +import gobject +import gtk + +from cli.headerPanel import (HeaderPanel as CliHeaderPanel, VERSION_STATUS_COLORS) +from TorCtl import TorCtl +from util import connections, sysTools, gtkTools, uiTools, torTools + +class GeneralPanel(CliHeaderPanel): + def __init__(self, builder): + CliHeaderPanel.__init__(self, None, time.time()) + + self.builder = builder + self.filled = False + + gobject.idle_add(self._fill_entries) + gobject.timeout_add(3000, self._timeout_fill_entries) + + def pack_widgets(self): + pass + + def _timeout_fill_entries(self): + self._fill_entries() + + return True + + def _fill_entries(self): + self.valsLock.acquire() + + liststore = self.builder.get_object('liststore_general') + theme = gtkTools.Theme() + + liststore.clear() + + key = "arm" + value = "%s (%s %s)" % (self.vals['sys/hostname'], self.vals['sys/os'], self.vals['sys/version']) + row = (key, value, theme.colors['active']) + liststore.append(row) + + versionColor = VERSION_STATUS_COLORS[self.vals["tor/versionStatus"]] if \ + self.vals["tor/versionStatus"] in VERSION_STATUS_COLORS else "black" + key = "Tor" + value = "%s (<span foreground="%s">%s</span>)" % (self.vals['tor/version'], versionColor, self.vals['tor/versionStatus']) + row = (key, value, theme.colors['active']) + liststore.append(row) + + includeControlPort = True + key = "Relaying" + if self.vals["tor/orPort"]: + myAddress = "Unknown" + if self.vals["tor/orListenAddr"]: myAddress = self.vals["tor/orListenAddr"] + elif self.vals["tor/address"]: myAddress = self.vals["tor/address"] + + dirPortLabel = ", Dir Port: %s" % self.vals["tor/dirPort"] if self.vals["tor/dirPort"] != "0" else "" + + value = "%s%s%s" % (self.vals["tor/nickname"], " - " + myAddress, ":" + self.vals["tor/orPort"], dirPortLabel) + else: + if self._isTorConnected: + value = "Disabled" + else: + statusTime = torTools.getConn().getStatus()[1] + + if statusTime: + statusTimeLabel = time.strftime("%H:%M %m/%d/%Y, ", time.localtime(statusTime)) + else: statusTimeLabel = "" + + value = "%s%s" % ("Tor Disconnected", statusTimeLabel) + includeControlPort = False + row = (key, value, theme.colors['active']) + liststore.append(row) + + key = "Control Port" + if includeControlPort: + if self.vals["tor/isAuthPassword"]: authType = "password" + elif self.vals["tor/isAuthCookie"]: authType = "cookie" + else: authType = "open" + + authColor = "red" if authType == "open" else "green" + value = "%s (<span foreground="%s">%s</span>)" % (self.vals['tor/controlPort'], authColor, authType) + row = (key, value, theme.colors['active']) + liststore.append(row) + + + if self.vals["stat/rss"] != "0": memoryLabel = uiTools.getSizeLabel(int(self.vals["stat/rss"])) + else: memoryLabel = "0" + + if self.vals["tor/startTime"]: + if self.isPaused() or not self._isTorConnected: + uptimeLabel = uiTools.getShortTimeLabel(self.getPauseTime() - self.vals["tor/startTime"]) + else: + uptimeLabel = uiTools.getShortTimeLabel(time.time() - self.vals["tor/startTime"]) + + key = "CPU" + value = "%s%% Tor, %s%% arm" % (self.vals["stat/%torCpu"], self.vals["stat/%armCpu"]) + row = (key, value, theme.colors['active']) + liststore.append(row) + + key = "Memory" + value = "%s (%s%%)" % (memoryLabel, self.vals["stat/%mem"]) + row = (key, value, theme.colors['active']) + liststore.append(row) + + key = "PID" + value = "%s" % (self.vals["tor/pid"] if self._isTorConnected else "") + row = (key, value, theme.colors['active']) + liststore.append(row) + + key = "Uptime" + value = uptimeLabel + row = (key, value, theme.colors['active']) + liststore.append(row) + + self.valsLock.release() + diff --git a/src/gui/graphing/graphStats.py b/src/gui/graphing/graphStats.py index 250503d..c7d24bb 100644 --- a/src/gui/graphing/graphStats.py +++ b/src/gui/graphing/graphStats.py @@ -46,6 +46,8 @@ class GraphStats(TorCtl.PostEventListener):
def _pack_graph_widget(self, name): graph = CaGraph() + graph.set_size_request(200, 200) + placeholder = self.builder.get_object('placeholder_graph_%s' % name) placeholder.pack_start(graph)
diff --git a/src/gui/stickyPanel.py b/src/gui/stickyPanel.py deleted file mode 100644 index 145c452..0000000 --- a/src/gui/stickyPanel.py +++ /dev/null @@ -1,123 +0,0 @@ -""" -Sticky panel. -""" - -import random -import sys -import time - -from collections import deque - -import gobject -import gtk - -from cli.headerPanel import (HeaderPanel as CliHeaderPanel, VERSION_STATUS_COLORS) -from TorCtl import TorCtl -from util import connections, sysTools, gtkTools, uiTools, torTools - -class StickyPanel(CliHeaderPanel): - def __init__(self, builder): - CliHeaderPanel.__init__(self, None, time.time()) - - self.builder = builder - self.filled = False - - gobject.idle_add(self._fill_entries) - gobject.timeout_add(3000, self._timeout_fill_entries) - - def pack_widgets(self): - pass - - def _timeout_fill_entries(self): - self._fill_entries() - - return True - - def _fill_entries(self): - self.valsLock.acquire() - - liststore = self.builder.get_object('liststore_sticky') - theme = gtkTools.Theme() - - liststore.clear() - - key = "arm" - value = "%s (%s %s)" % (self.vals['sys/hostname'], self.vals['sys/os'], self.vals['sys/version']) - row = (key, value, theme.colors['active']) - liststore.append(row) - - versionColor = VERSION_STATUS_COLORS[self.vals["tor/versionStatus"]] if \ - self.vals["tor/versionStatus"] in VERSION_STATUS_COLORS else "black" - key = "Tor" - value = "%s (<span foreground="%s">%s</span>)" % (self.vals['tor/version'], versionColor, self.vals['tor/versionStatus']) - row = (key, value, theme.colors['active']) - liststore.append(row) - - includeControlPort = True - key = "Relaying" - if self.vals["tor/orPort"]: - myAddress = "Unknown" - if self.vals["tor/orListenAddr"]: myAddress = self.vals["tor/orListenAddr"] - elif self.vals["tor/address"]: myAddress = self.vals["tor/address"] - - dirPortLabel = ", Dir Port: %s" % self.vals["tor/dirPort"] if self.vals["tor/dirPort"] != "0" else "" - - value = "%s%s%s" % (self.vals["tor/nickname"], " - " + myAddress, ":" + self.vals["tor/orPort"], dirPortLabel) - else: - if self._isTorConnected: - value = "Disabled" - else: - statusTime = torTools.getConn().getStatus()[1] - - if statusTime: - statusTimeLabel = time.strftime("%H:%M %m/%d/%Y, ", time.localtime(statusTime)) - else: statusTimeLabel = "" - - value = "%s%s" % ("Tor Disconnected", statusTimeLabel) - includeControlPort = False - row = (key, value, theme.colors['active']) - liststore.append(row) - - key = "Control Port" - if includeControlPort: - if self.vals["tor/isAuthPassword"]: authType = "password" - elif self.vals["tor/isAuthCookie"]: authType = "cookie" - else: authType = "open" - - authColor = "red" if authType == "open" else "green" - value = "%s (<span foreground="%s">%s</span>)" % (self.vals['tor/controlPort'], authColor, authType) - row = (key, value, theme.colors['active']) - liststore.append(row) - - - if self.vals["stat/rss"] != "0": memoryLabel = uiTools.getSizeLabel(int(self.vals["stat/rss"])) - else: memoryLabel = "0" - - if self.vals["tor/startTime"]: - if self.isPaused() or not self._isTorConnected: - uptimeLabel = uiTools.getShortTimeLabel(self.getPauseTime() - self.vals["tor/startTime"]) - else: - uptimeLabel = uiTools.getShortTimeLabel(time.time() - self.vals["tor/startTime"]) - - key = "CPU" - value = "%s%% Tor, %s%% arm" % (self.vals["stat/%torCpu"], self.vals["stat/%armCpu"]) - row = (key, value, theme.colors['active']) - liststore.append(row) - - key = "Memory" - value = "%s (%s%%)" % (memoryLabel, self.vals["stat/%mem"]) - row = (key, value, theme.colors['active']) - liststore.append(row) - - key = "PID" - value = "%s" % (self.vals["tor/pid"] if self._isTorConnected else "") - row = (key, value, theme.colors['active']) - liststore.append(row) - - key = "Uptime" - value = uptimeLabel - row = (key, value, theme.colors['active']) - liststore.append(row) - - self.valsLock.release() -
tor-commits@lists.torproject.org