can now add categories from the category viewer
[public/library.git] / form.py
1 import curses
2
3 class formWindow:
4     mx = my = 0
5     hl = 0
6     bt = -1
7     cursor = 0
8     textStart = 0
9     left = 0
10     top = 2
11     row = 2
12     caption = "Form"
13     blabel = "Done"
14     labels = ["label1"]
15     entries = []
16
17     def clear(self):
18         self.w.erase()
19         self.w.refresh()
20
21     def __init__(self,window,book={}):
22         self.w = window
23         self.w.resize(len(self.labels)+6,50)
24         self.updateEntries(book)
25         self.updateGeometry()
26
27     def updateGeometry(self):
28         (self.my, self.mx) = self.w.getmaxyx()
29         self.left=0
30         for l in self.labels:
31             self.left = max(len(l),self.left)
32         self.left += 4
33         self.width = self.mx-self.left-2
34         self.top = 2
35         # next, the buttons
36         self.bcol = [self.mx-len(self.blabel)-14, self.mx-len(self.blabel)-4]
37         self.bwidth = [8,len(self.blabel)+2]
38
39     def updateEntries(self,book):
40         self.entries=[]
41         for l in self.labels:
42             if l.lower() in book:
43                 self.entries.append(str(book[l.lower()]))
44             else:
45                 self.entries.append("")
46
47     def refresh(self):
48         self.updateGeometry()
49         self.w.box()
50         self.w.addstr(0,(self.mx-len(self.caption))/2,self.caption)
51         r=self.top
52         for l in self.labels:
53             c = self.left-len(l)-2
54             self.w.addstr(r,c,l+":")
55             self.drawRow(r-self.top)
56             r+=1
57         self.w.addstr(r+1,self.bcol[0], "<cancel>  <"+self.blabel+">")
58         self.w.refresh()
59
60     def drawRow(self,row):
61         r = self.top + row
62         self.w.addnstr(r,self.left, self.entries[row]+" "*self.width, self.width)
63
64     def highlight(self):
65         if self.bt == -1:
66             self.w.chgat(self.row, self.left, self.width, curses.A_UNDERLINE)
67             self.mvCursor(0)
68             curses.curs_set(1)
69         else:
70             self.w.chgat(self.row, self.bcol[self.bt], self.bwidth[self.bt], curses.A_REVERSE)
71             curses.curs_set(0)
72
73     def unHighlight(self):
74         self.w.chgat(self.row,1,self.mx-2,curses.A_NORMAL)
75
76     def mvHighlight(self,delta):
77         self.unHighlight()
78         new = self.hl+delta
79         new = max(new,0)
80         new = min(new,len(self.labels))   # the extra is for the buttons
81         self.hl = new
82         self.row = self.hl + self.top
83         if new == len(self.labels):
84             self.bt+=1
85             self.bt = min(self.bt,1)
86             self.row+=1
87         else:
88             self.mvCursor(+len(self.entries[self.hl]))
89             self.bt=-1
90         self.highlight()
91
92     def mvCursor(self,delta):
93         n = self.cursor + delta
94         n = max(n,0)
95         n = min(n,len(self.entries[self.hl]))
96         self.cursor = n
97         col = self.left + self.cursor - self.textStart
98         if col >= self.left and col < self.left+self.width:
99             self.w.move(self.row,col)
100
101     def insert(self,ch):
102         c = self.cursor
103         self.entries[self.hl]=self.entries[self.hl][:c] +ch+  self.entries[self.hl][c:]
104         self.drawRow(self.hl)
105         self.mvCursor(+1)
106         self.highlight()
107
108     def backspace(self):
109         if self.cursor>0:
110             self.entries[self.hl]=self.entries[self.hl][:self.cursor-1] + self.entries[self.hl][self.cursor:]
111             self.drawRow(self.hl)
112             self.mvCursor(-1)
113             self.highlight()
114
115     def delete(self):
116         c = self.cursor
117         self.entries[self.hl]=self.entries[self.hl][:c] + self.entries[self.hl][c+1:]
118         self.drawRow(self.hl)
119         self.highlight()
120
121     def returnValues(self):
122         book = {}
123         for k,v in zip(self.labels, self.entries):
124             if v!="" and k.lower()!="publish date":
125                 book[k.lower()]=v
126         return book
127
128     def eventLoop(self):
129         self.w.keypad(1)
130         self.refresh()
131         self.mvCursor(+len(self.entries[self.hl]))
132         self.highlight()
133
134         ch = self.w.getch()
135         while ch != 27:
136             self.handleInput(ch)
137             if ch==10 or ch==curses.KEY_ENTER:
138                 if self.bt==0:
139                     return {}
140                 elif self.bt==1:
141                     return self.returnValues()
142                 self.mvHighlight(+1)
143             self.w.refresh()
144             ch = self.w.getch()
145         curses.curs_set(0)
146         return {}
147
148
149     def handleInput(self,ch):
150         if ch==curses.KEY_UP:
151             self.mvHighlight(-1)
152         elif ch==curses.KEY_PPAGE:
153             self.mvHighlight(-len(self.labels))
154         elif ch==curses.KEY_DOWN:
155             self.mvHighlight(+1)
156         elif ch==curses.KEY_NPAGE:
157             self.mvHighlight(+len(self.labels))
158
159         elif ch==curses.KEY_LEFT:
160             if self.bt==-1:
161                 self.mvCursor(-1)
162             else:
163                 self.bt=0
164         elif ch==curses.KEY_HOME:
165             if self.bt==-1:
166                 self.mvCursor(-len(self.entries[self.hl]))
167         elif ch==curses.KEY_RIGHT:
168             if self.bt==-1:
169                 self.mvCursor(+1)
170             else:
171                 self.bt=1
172         elif ch==curses.KEY_END:
173             if self.bt==-1:
174                 self.mvCursor(+len(self.entries[self.hl]))
175
176         elif ch>=32 and ch<=126:
177             if self.bt==-1:
178                 self.insert(curses.keyname(ch))
179         elif ch==curses.KEY_BACKSPACE:
180             if self.bt==-1:
181                 self.backspace()
182         elif ch==curses.KEY_DC:
183             if self.bt==-1:
184                 self.delete()
185         
186         
187
188 class bookForm(formWindow):
189     caption = "Add a Book"
190     blabel = "Add"
191     labels = ["ISBN", "LCCN", "Title", "Subtitle", "Authors", "Edition",
192               "Publisher", "Publish Date", "Publish Year", "Publish Month", "Publish location",
193               "Pages", "Pagination", "Weight"]
194     
195
196     # redefineable functions lookup is called when 'enter' is pressed on ISBN
197     # and returns the looked-up book. Default returns nothing
198     def lookup(self,isbn):
199         return {'isbn':isbn}
200
201     def returnBook(self):
202         return self.returnValues()
203
204     def handleInput(self,ch):
205         if ch==10 or ch==curses.KEY_ENTER:
206             if self.hl==0:
207                 book = self.lookup(self.entries[0])
208                 if book != {}:
209                     self.updateEntries(book)
210                 self.refresh()
211         formWindow.handleInput(self,ch)
212
213 class categoryForm(formWindow):
214     caption = "Add a Category"
215     blabel = "Add"
216     labels = ["Category"]
217
218     def returnValues(self):
219         return self.entries