can now add categories from the category viewer
[public/library.git] / browser.py
1 import sys
2 import curses
3 import dbLayer as db
4 from form import bookForm,categoryForm
5
6 class browserWindow:
7     hl=0
8     entries = []
9     topline = 0
10     # column definitions are in (label, weight, specified width) triples
11     columnDefs = [('something',1,None)]
12     mx = my = 0
13
14
15     def clear(self):
16         self.w.erase()
17         self.w.refresh()
18
19     def __init__(self,window):
20         self.w = window
21         self.updateGeometry()
22
23     def sortByColumn(self, col):
24         self.entries.sort() # key=dict.get(col))
25
26     def updateGeometry(self):
27         (self.my,self.mx)=self.w.getmaxyx()
28         self.pageSize = self.my-3
29         self.calcColWidths()
30
31     def calcColWidths(self):
32         total_weights = 0
33         available_space = self.mx - len(self.columnDefs)
34         cols = []
35         for label,weight,value in self.columnDefs:
36             if value!=None:
37                 available_space -= value
38             else:
39                 total_weights+=weight
40
41         for label,weight,value in self.columnDefs:
42             if value!=None:
43                 cols.append((label,value))
44             else:
45                 cols.append((label,available_space*weight/total_weights))
46         self.columns=cols
47
48     def refresh(self):
49         self.displayHeader()
50         for r in range(0,self.pageSize):
51             self.displayRow(r)
52         self.w.refresh()
53         self.highlight()
54
55     def displayHeader(self):
56         cursor = 0
57         for header,width in self.columns:
58             self.w.addnstr(0,cursor,header+" "*width,width)
59             self.w.addstr(1,cursor,"-"*width)
60             cursor += width+1
61
62     def displayRow(self,row):
63         if self.topline+row < len(self.entries):
64             entry = self.entries[self.topline+row]
65             cursor = 0
66             for k,width in self.columns:
67                 if k.lower() in entry:
68                     self.w.addnstr(row+2,cursor,str(entry[k.lower()])+" "*width,width)
69                 cursor += width+1
70         else:
71             self.w.addstr(row+2,0," "*self.mx)
72
73     def highlight(self):
74         row = self.hl-self.topline+2
75         if row > 1 and row < self.my:
76             self.w.chgat(row,0,self.mx,curses.A_REVERSE)
77
78     def unHighlight(self):
79         row = self.hl-self.topline+2
80         if row > 1 and row < self.my:
81             self.w.chgat(row,0,self.mx,curses.A_NORMAL)
82
83     def mvHighlight(self,delta):
84         new = self.hl+delta
85         new = max(new,0)
86         new = min(new,len(self.entries)-1)
87         self.unHighlight()
88         self.hl = new
89         self.highlight()
90     
91     def scroll(self,delta):
92         self.unHighlight()
93         self.topline += delta
94         self.topline = max(self.topline,0)
95         self.topline = min(self.topline,len(self.entries)-1)
96         self.refresh()
97
98     def eventLoop(self):
99         self.w.keypad(1)
100         self.refresh()
101
102         ch = self.w.getch()
103         while ch != 27 and ch != 113:
104             self.handleInput(ch)
105             self.w.refresh()
106             ch = self.w.getch()
107
108     def handleInput(self,ch):
109         if ch == curses.KEY_UP or ch == 107 or ch == 16:
110             if self.hl == self.topline:
111                 self.scroll(-self.pageSize/2-1)
112             self.mvHighlight(-1)
113         elif ch == curses.KEY_DOWN or ch == 106 or ch == 14:
114             if self.hl == self.topline+self.pageSize-1:
115                 self.scroll(+self.pageSize/2+1)
116             self.mvHighlight(+1)
117         elif ch == curses.KEY_PPAGE:
118             self.scroll(-self.pageSize)
119             self.mvHighlight(-self.pageSize)
120         elif ch == curses.KEY_NPAGE:
121             self.scroll(+self.pageSize)
122             self.mvHighlight(+self.pageSize)
123
124
125
126 class bookBrowser(browserWindow):
127     columnDefs = [('ID',0,3),
128                   ('ISBN',0,13),
129                   ('Authors',30,None),
130                   ('Title',60,None)]
131     # redefinable functions
132     def updateSelection(self,book):
133         bookid = book['id']
134         
135         w=curses.newwin(1,1,20,20)
136         bf=bookForm(w)
137         bf.caption='Update Book '+str(bookid)
138         bf.blabel='update'
139         bf.updateEntries(book)
140         newbook = bf.eventLoop()
141         if len(newbook)!=0:
142             db.updateBook(newbook,bookid)
143         bf.clear()
144
145     def viewSelection(self,book):
146         bookid = book['id']
147         w=curses.newwin(1,1,20,20)
148         bf = bookForm(w)
149         bf.caption='Viewing Book '+str(bookid)
150         bf.blabel='done'
151         bf.updateEntries(book)
152         bf.eventLoop()
153         bf.clear()
154
155     def refreshBooks(self):
156         self.entries = db.getBooks()
157
158     def handleInput(self,ch):
159         browserWindow.handleInput(self,ch)
160         if ch == 117: #update on 'u'
161             book = self.entries[self.hl]
162             self.updateSelection(entries)
163             self.entries[self.hl]=db.getBookByID(book['id'])
164             self.refresh()
165         elif ch == 10:
166             book = self.entries[self.hl]
167             self.viewSelection(book)
168             self.refresh()
169
170 class categoryBrowser(browserWindow):
171     columnDefs = [('Category',100,None)]
172
173
174     def refreshCategories(self):
175         self.entries = []
176         cats = db.getCategories()
177         for c in cats:
178             self.entries.append({'category':c})
179         self.sortByColumn('category')
180
181     def addCategory(self):
182         w = curses.newwin(1,1,10,10)
183         cf = categoryForm(w)
184         cats = cf.eventLoop()
185         print >> sys.stderr, cats
186         for c in cats:
187             print >> sys.stderr, "adding "+str(c)
188             db.addCategory(c)
189         cf.clear()
190
191     def handleInput(self,ch):
192         browserWindow.handleInput(self,ch)
193         if ch==97:
194             self.addCategory()
195             self.refreshCategories()
196             self.refresh()
197