wvstreams a7889bc...c53e3f1: wvdbusserver: implement NameHasOwner request.
[versaplex.git] / veranda / Resulter.py
blob7cdb56042d9c4121058742183d9ef878be108a3e
1 #!/usr/bin/python
3 #------------------------------------------------------------------------------
4 # Veranda
5 # *Resulter
6 # ~--------------~
8 # Original Author: Andrei "Garoth" Thorp <garoth@gmail.com>
10 # Description: This module makes handling of my multi-widget result viewer
11 # easier. What this class does is track a set of widgets and keeps
12 # them all updated. At any point, the main method can ask the
13 # resulter to return a specific widget so that main can display it.
14 # The Resulter is not a frame or box of any kind that can be
15 # displayed -- it only holds pointers to the objects that it
16 # manages.
18 # Notes:
19 # Indentation: I use tabs only, 4 spaces per tab.
20 #------------------------------------------------------------------------------
21 import sys
22 import pygtk
23 import gtk
24 import gtksourceview2 as gtksourceview
25 import time
26 import pango
27 import os
28 #------------------------------------------------------------------------------
29 class Resulter:
30 #------------------------------------------------------------------------------
31 #--------------------------
32 def __init__(self, parser):
33 #--------------------------
34 """Initializes the instance variables (and as such, the various
35 gtk widgets that would be used)"""
36 # Given parser, set up with the dbus info
37 self.parser = parser
38 # Iterator for the data, able to go row by row
39 self.iterator = self.parser.getTableIterator()
40 self.titles = self.parser.getColumnTitles()
41 self.message = parser.getOriginalMessage()
42 self.dbusMessages = time.ctime(time.time())+"\n\n"+ str(self.message)
43 self.dbusMessages = self.__formatDbusMessage__(self.dbusMessage, 100)
45 # Set up these objects
46 self.__initTableView__()
47 self.__initDbusView__()
48 self.__initTextView__()
50 # Reorganize this if you want the program to change through the views
51 # in a different order
52 self.viewOrder = [self.getTableView(),
53 self.getTextView(),
54 self.getDbusView()]
55 self.currentView = self.viewOrder[0]
57 #------------------
58 def __init__(self):
59 #------------------
60 """Initializes a blank resulter with no... results. This construct
61 would be used with later calls to the update method."""
62 self.dbusMessages = ""
64 #---------------------------
65 def __initTableView__(self):
66 #---------------------------
67 """Generates a gtk.TreeView based table"""
68 # FIXME: STUPID PANGO MARKDOWN WTH
69 if len(self.parser.getColumnTitles()) >= 1:
70 self.tableViewModel = gtk.ListStore(*self.parser
71 .getColumnTypesAsStrings())
73 while self.iterator.hasNext():
74 item = self.iterator.getNext()
75 self.tableViewModel.append(item)
77 self.tableView = gtk.TreeView(self.tableViewModel)
78 self.cellRenderer = gtk.CellRendererText()
80 x = 0
81 for title in self.titles:
82 treeviewcolumn = gtk.TreeViewColumn(title, self.cellRenderer, text=x)
83 treeviewcolumn.set_resizable(True)
84 self.tableView.append_column(treeviewcolumn)
85 x += 1
87 self.tableView.show()
89 #--------------------------
90 def __initDbusView__(self):
91 #--------------------------
92 """Generates a gtksourceview with the original dbus message inside"""
93 self.dbusBuffer = gtksourceview.Buffer()
94 self.dbusView = gtksourceview.View(self.dbusBuffer)
96 self.configureEditor(self.dbusView, self.dbusBuffer)
97 self.dbusView.set_editable(False)
99 self.dbusBuffer.set_text(self.dbusMessages)
101 self.dbusView.show()
103 #--------------------------
104 def __initTextView__(self):
105 #--------------------------
106 """Generates a textual table of the data"""
107 # Well, not yet.
108 self.textView = ""
109 self.textBuffer = gtksourceview.Buffer()
110 self.textView = gtksourceview.View(self.textBuffer)
112 self.configureEditor(self.textView, self.textBuffer)
113 self.textView.set_editable(False)
114 self.textView.set_wrap_mode(gtk.WRAP_NONE)
116 self.textBuffer.set_text(self.__formatTextTable__())
118 self.textView.show()
120 #-----------------------------
121 def __formatTextTable__(self):
122 #-----------------------------
123 """Formats the textual table to look nice"""
124 output = "" # Final Output to send back
125 numColumns = self.parser.numColumns() # Number of columns in table
126 numRows = self.parser.numRows() # Number of rows in the table
127 maxColWidth = 20 # Max width of 1 column
128 padding = " | " # The space between columns
129 table = self.parser.getTable() # the full table of values
130 iterator = self.parser.getTableIterator() # iterator for the rows
131 format = ""
133 # 1) Get max widths of the columns
134 widths = []
135 for y in range(numColumns):
136 max = len(self.titles[y])
137 for x in range(numRows):
138 if len(table[x][y]) > max:
139 max = len(table[x][y])
140 if max > maxColWidth:
141 max = maxColWidth
142 widths.append(max)
144 # 2) Generate format string
145 for width in widths:
146 if width != widths[len(widths)-1]:
147 format += r"%-" + str(width) + r"." + str(width) + r"s"+padding
148 else:
149 format += r"%-" + str(width) + r"." + str(width) + r"s"
151 # 3) Print a table
152 output += format % tuple(self.titles) + os.linesep
154 # 4) Print a divider
155 totalWidth = 0
156 for width in widths:totalWidth += width
157 totalWidth += len(padding * (numColumns - 1))
158 output += "-" * totalWidth + os.linesep
160 # 5) Print the body
161 while iterator.hasNext():
162 output += format % tuple(iterator.getNext()) + os.linesep
164 return output
166 #--------------------------------------------
167 def __formatDbusMessage__(self, text, width):
168 #--------------------------------------------
169 """Slices up the Dbus Message so that hopefully gtksourceview doesn't"""
170 return reduce(lambda line, word, width=width: '%s%s%s' %
171 (line,
172 ' \n'[(len(line)-line.rfind('\n')-1
173 + len (word.split('\n', 1)[0]
174 ) >= width)],
175 word),
176 text.split(' ')
180 #-------------------------
181 def __makeScrolls__(self):
182 #-------------------------
183 """Generates scroll bars for widgets that want them"""
184 scrolls = gtk.ScrolledWindow(gtk.Adjustment(), gtk.Adjustment())
185 scrolls.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
186 scrolls.show()
187 return scrolls
189 #------------------------
190 def update(self, parser):
191 #------------------------
192 """Updates widgets with a new dbus message.
193 * TableView replaces its old content
194 * DbusView appends text to its old content
195 * TextView replaces its old content
196 Note: this will create new objects. The old won't update."""
197 self.parser = parser
198 self.iterator = self.parser.getTableIterator()
199 self.titles = self.parser.getColumnTitles()
200 self.message = parser.getOriginalMessage()
201 self.dbusMessages = time.ctime(time.time())+ os.linesep + os.linesep + \
202 str(self.message)
203 self.dbusMessages = self.__formatDbusMessage__(self.dbusMessages, 100)
205 # Set up these objects
206 self.__initTableView__()
207 self.__initDbusView__()
208 self.__initTextView__()
210 #set up viewing
211 self.viewOrder = [self.getTableView(),
212 self.getTextView(),
213 self.getDbusView()]
214 self.currentView = self.viewOrder[0]
216 #---------------------------------------------
217 def configureEditor(self, editor, textbuffer):
218 #---------------------------------------------
219 """Sets up a gtksourceview with the common options I want."""
220 languagemanager = gtksourceview.LanguageManager()
221 textbuffer.set_language(languagemanager.get_language("sql"))
222 textbuffer.set_highlight_syntax(True)
223 editor.set_show_line_numbers(True)
224 editor.set_wrap_mode(gtk.WRAP_WORD_CHAR)
225 editor.modify_font(pango.FontDescription("monospace 10"))
227 #------------------------
228 def getCurrentView(self):
229 #------------------------
230 """Returns the view that was most recently retrieved"""
231 return self.currentView
233 #---------------------
234 def getNextView(self):
235 #---------------------
236 """Returns the next view that is on the self.viewOrder list"""
237 self.currentView = self.viewOrder[(self.viewOrder
238 .index(self.getCurrentView())+1)%3]
239 return self.currentView
241 #----------------------
242 def getTableView(self):
243 #----------------------
244 """Returns self.tableView widget"""
245 scrolls = self.__makeScrolls__()
246 scrolls.add(self.tableView)
247 self.currentView = scrolls
248 return scrolls
250 #---------------------
251 def getDbusView(self):
252 #---------------------
253 """Returns self.dbusView widget"""
254 scrolls = self.__makeScrolls__()
255 scrolls.add(self.dbusView)
256 self.currentView = scrolls
257 return scrolls
259 #---------------------
260 def getTextView(self):
261 #---------------------
262 """Returns self.textView widget"""
263 scrolls = self.__makeScrolls__()
264 scrolls.add(self.textView)
265 self.currentView = scrolls
266 return scrolls