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