aboutsummaryrefslogtreecommitdiffstats
path: root/interfaces/gui
diff options
context:
space:
mode:
authorW. Trevor King <wking@drexel.edu>2009-07-14 15:18:07 -0400
committerW. Trevor King <wking@drexel.edu>2009-07-14 15:18:07 -0400
commite7d150fd7ca22b01defd0c615000b6bfc367aacf (patch)
treeeacb8fbc153b3b15b48cc5d2ddfee9608d431c23 /interfaces/gui
parentc38907c85bbb62a2b3bb00dd05eeb588ecc6845d (diff)
downloadbugseverywhere-e7d150fd7ca22b01defd0c615000b6bfc367aacf.tar.gz
Reorganized directory structure, mostly to put all the interfaces in
one place and make things clearer to the uninitiated. Here's my current understanding: . |-- libbe (the guts of BE) |-- becommands (plugins for all "be *" commands) |-- doc (documentation, currently just the man page) |-- interfaces (non-commandline interface implementations) | |-- web | | |-- Bugs-Everywhere-Web (in Turbogears) | |-- gui | | |-- beg (in Tkinter) | | `-- wxbe (in WX) | |-- email | `-- xml (xml <-> whatever conversion) `-- misc (random odds and ends) `-- completion (shell completion scripts) Note that I haven't attempted to use the web or gui interfaces in a while, so I'm not sure how well they're holding vs the core development.
Diffstat (limited to 'interfaces/gui')
-rwxr-xr-xinterfaces/gui/beg/beg12
-rw-r--r--interfaces/gui/beg/table.py97
-rwxr-xr-xinterfaces/gui/wxbe/wxbe87
3 files changed, 196 insertions, 0 deletions
diff --git a/interfaces/gui/beg/beg b/interfaces/gui/beg/beg
new file mode 100755
index 0000000..55e537d
--- /dev/null
+++ b/interfaces/gui/beg/beg
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+import table
+from Tkinter import *
+from libbe import bugdir
+
+tk = Tk()
+Label(tk, text="Bug list").pack()
+mlb = table.MultiListbox(tk, (('Severity', 4), ('Creator', 8), ('Summary', 40)))
+for bug in [b for b in bugdir.tree_root(".").list() if b.active]:
+ mlb.insert(END, (bug.severity, bug.creator, bug.summary))
+mlb.pack(expand=YES,fill=BOTH)
+tk.mainloop()
diff --git a/interfaces/gui/beg/table.py b/interfaces/gui/beg/table.py
new file mode 100644
index 0000000..2865f28
--- /dev/null
+++ b/interfaces/gui/beg/table.py
@@ -0,0 +1,97 @@
+from Tkinter import *
+
+class MultiListbox(Frame):
+ def __init__(self, master, lists):
+ Frame.__init__(self, master)
+ self.lists = []
+ for l,w in lists:
+ frame = Frame(self); frame.pack(side=LEFT, expand=YES, fill=BOTH)
+ Label(frame, text=l, borderwidth=1, relief=RAISED).pack(fill=X)
+ lb = Listbox(frame, width=w, borderwidth=0, selectborderwidth=0,
+ relief=FLAT, exportselection=FALSE)
+ lb.pack(expand=YES, fill=BOTH)
+ self.lists.append(lb)
+ lb.bind('<B1-Motion>', lambda e, s=self: s._select(e.y))
+ lb.bind('<Button-1>', lambda e, s=self: s._select(e.y))
+ lb.bind('<Leave>', lambda e: 'break')
+ lb.bind('<B2-Motion>', lambda e, s=self: s._b2motion(e.x, e.y))
+ lb.bind('<Button-2>', lambda e, s=self: s._button2(e.x, e.y))
+ frame = Frame(self); frame.pack(side=LEFT, fill=Y)
+ Label(frame, borderwidth=1, relief=RAISED).pack(fill=X)
+ sb = Scrollbar(frame, orient=VERTICAL, command=self._scroll)
+ sb.pack(expand=YES, fill=Y)
+ self.lists[0]['yscrollcommand']=sb.set
+
+ def _select(self, y):
+ row = self.lists[0].nearest(y)
+ self.selection_clear(0, END)
+ self.selection_set(row)
+ return 'break'
+
+ def _button2(self, x, y):
+ for l in self.lists: l.scan_mark(x, y)
+ return 'break'
+
+ def _b2motion(self, x, y):
+ for l in self.lists: l.scan_dragto(x, y)
+ return 'break'
+
+ def _scroll(self, *args):
+ for l in self.lists:
+ apply(l.yview, args)
+
+ def curselection(self):
+ return self.lists[0].curselection()
+
+ def delete(self, first, last=None):
+ for l in self.lists:
+ l.delete(first, last)
+
+ def get(self, first, last=None):
+ result = []
+ for l in self.lists:
+ result.append(l.get(first,last))
+ if last: return apply(map, [None] + result)
+ return result
+
+ def index(self, index):
+ self.lists[0].index(index)
+
+ def insert(self, index, *elements):
+ for e in elements:
+ i = 0
+ for l in self.lists:
+ l.insert(index, e[i])
+ i = i + 1
+
+ def size(self):
+ return self.lists[0].size()
+
+ def see(self, index):
+ for l in self.lists:
+ l.see(index)
+
+ def selection_anchor(self, index):
+ for l in self.lists:
+ l.selection_anchor(index)
+
+ def selection_clear(self, first, last=None):
+ for l in self.lists:
+ l.selection_clear(first, last)
+
+ def selection_includes(self, index):
+ return self.lists[0].selection_includes(index)
+
+ def selection_set(self, first, last=None):
+ for l in self.lists:
+ l.selection_set(first, last)
+
+if __name__ == '__main__':
+ tk = Tk()
+ Label(tk, text='MultiListbox').pack()
+ mlb = MultiListbox(tk, (('Subject', 40), ('Sender', 20), ('Date', 10)))
+ for i in range(1000):
+ mlb.insert(END, ('Important Message: %d' % i, 'John Doe', '10/10/%04d' % (1900+i)))
+ mlb.pack(expand=YES,fill=BOTH)
+ tk.mainloop()
+
diff --git a/interfaces/gui/wxbe/wxbe b/interfaces/gui/wxbe/wxbe
new file mode 100755
index 0000000..e71ae0c
--- /dev/null
+++ b/interfaces/gui/wxbe/wxbe
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+import wx
+from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
+import sys, os.path
+from libbe import bugdir, names
+from libbe.bug import cmp_status, cmp_severity, cmp_time, cmp_full
+
+class MyApp(wx.App):
+ def OnInit(self):
+ frame = BugListFrame(None, title="Bug List")
+ frame.Show(True)
+ self.SetTopWindow(frame)
+ return True
+
+class BugListFrame(wx.Frame):
+ def __init__(self, *args, **kwargs):
+ wx.Frame.__init__(self, *args, **kwargs)
+ bugs = BugList(self)
+
+ # Widgets to display/sort/edit will go in this panel
+ # for now it is just a placeholder
+ panel = wx.Panel(self)
+ panel.SetBackgroundColour("RED")
+
+ vbox = wx.BoxSizer(wx.VERTICAL)
+ vbox.Add(panel, 0, wx.EXPAND)
+ vbox.Add(bugs, 1, wx.EXPAND)
+
+ self.SetAutoLayout(True)
+ self.SetSizer(vbox)
+ self.Layout()
+
+class BugList(wx.ListCtrl, ListCtrlAutoWidthMixin):
+ def __init__(self, parent):
+ wx.ListCtrl.__init__(self, parent,
+ style=wx.LC_REPORT)
+ ListCtrlAutoWidthMixin.__init__(self)
+
+ self.bugdir = bugdir.tree_root(".")
+ self.buglist = list(self.bugdir.list())
+ self.buglist.sort()
+ self.columns = ("id", "status", "severity", "summary")
+
+ dataIndex = 0
+ for x in range(len(self.columns)):
+ self.InsertColumn(x, self.columns[x].capitalize())
+ self.SetColumnWidth(x, wx.LIST_AUTOSIZE_USEHEADER)
+ for bug in [b for b in self.buglist if b.active]:
+ name = names.unique_name(bug, self.buglist)
+ id = self.InsertStringItem(self.GetItemCount(), name)
+ self.SetStringItem(id, 1, bug.status)
+ self.SetStringItem(id, 2, bug.severity)
+ self.SetStringItem(id, 3, bug.summary)
+ self.SetItemData(id, dataIndex) # set keys for each line
+ dataIndex += 1
+ self.EnsureVisible(id)
+ for x in range(len(self.columns)):
+ self.SetColumnWidth(x, wx.LIST_AUTOSIZE)
+ conts_width = self.GetColumnWidth(x)
+ self.SetColumnWidth(x, wx.LIST_AUTOSIZE_USEHEADER)
+ if conts_width > self.GetColumnWidth(x):
+ self.SetColumnWidth(x, conts_width)
+
+ self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColumnClick)
+ self.bugcmp_fn = cmp_full
+ # For reasons I don't understant, sorting is broken...
+ #self.SortItems(self.Sorter)
+ #self.Refresh()
+ def Sorter(self, key1, key2):
+ """Get bug info from the keys and pass to self.bugcmp_fn"""
+ bug1 = self.buglist[key1-1]
+ bug2 = self.buglist[key2-1]
+ # Another way of getting bug information
+ #bug1uuid = self.GetItem(key1, 0).GetText()
+ #bug2uuid = self.GetItem(key2, 0).GetText()
+ #print bug1uuid, bug2uuid
+ #bug1 = self.bugdir.get_bug(bug1uuid)
+ #bug2 = self.bugdir.get_bug(bug1uuid)
+ print self.bugcmp_fn(bug1,bug2)
+ return self.bugcmp_fn(bug1,bug2)
+ def OnColumnClick(self, event):
+ """Resort bug list depending on which column was clicked"""
+ print "TODO: sort by column %d" % event.Column
+ # change self.bugcmp_fn and resort, but I can't get it working
+
+app = MyApp()
+app.MainLoop()