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