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