browser has scrolling now
[public/library.git] / librarian.py
1 #!/usr/bin/env python
2
3 import curses
4 import dbLayer as db
5 import browser
6
7 stdscr=0
8
9 def menutest(s, l):
10     global stdscr
11     stdscr=s
12     curses.curs_set(0)
13     (rows,cols)=stdscr.getmaxyx()
14     w = curses.newwin(10,40,(rows-10)/2, (cols-40)/2)
15
16     menu(w, l)
17     
18     curses.curs_set(1)
19
20 # item is a list of (string, callable) tuples
21 def menu(w, items):
22     w.keypad(1)
23     highlight=0
24     redrawMenu(w,items,highlight)
25
26     w.refresh()
27     ch=w.getch()
28     while (ch!=113 and ch!=27): # leave on q or ESC
29         if ch==curses.KEY_UP:
30             if highlight!=0:
31                 w.chgat(highlight,0, 0)
32                 highlight -= 1
33                 while(items[highlight][0]==""):
34                     highlight -=1
35                 w.chgat(highlight,0, curses.A_REVERSE)
36         if ch==curses.KEY_DOWN:
37             if highlight!=len(items)-1:
38                 w.chgat(highlight,0, 0)
39                 highlight += 1
40                 while(items[highlight][0]==""):
41                     highlight +=1
42                 w.chgat(highlight,0, curses.A_REVERSE)
43         if ch==curses.KEY_PPAGE:
44             w.chgat(highlight,0, 0)
45             highlight = 0
46             w.chgat(highlight,0, curses.A_REVERSE)
47         if ch==curses.KEY_NPAGE:
48             w.chgat(highlight,0, 0)
49             highlight = len(items)-1
50             w.chgat(highlight,0, curses.A_REVERSE)
51         if ch==114 or ch==10:
52             (s,f)=items[highlight]
53             f()
54             redrawMenu(w,items,highlight)
55         w.refresh()
56         ch = w.getch()
57
58 def redrawMenu(w,items,highlight):
59     i=0
60     for (mitem,fun) in items:
61         w.addstr(i,0, mitem)
62         i +=1
63     w.chgat(highlight, 0, curses.A_REVERSE)
64     w.refresh()
65
66 # items is a list of (label, value) pairs
67 def redrawForm(w, caption, items, buttonlabel, m):
68     (y,x)=w.getmaxyx()
69     w.border()
70     curses.curs_set(1)
71     w.addstr(1,1,caption)
72     r=3
73     for l,v in items:
74         c = m-len(l)-2
75         w.addstr(r,c,l+":")
76         w.addstr(r,m,v)
77         r+=2
78     w.addstr(r,x-len(buttonlabel)-len("<cancel>")-6, "<cancel>  <"+buttonlabel+">")
79     w.refresh()
80
81 def lists_to_dict(l1, l2):
82     book = {}
83     for k,v in zip(l1,l2):
84         if v!="" and k.lower()!="publish date":
85             book[k.lower()]=v
86     return book
87
88
89 #the final form for book data entry - takes caption and book info.
90 def bookForm(caption, book, buttonlabel):
91     labels = ["ISBN", "LCCN", "Title", "Subtitle", "Authors", "Edition",
92               "Publisher", "Publish Date", "Publish Year", "Publish Month", "Publish location",
93               "Pages", "Pagination", "Weight"]
94     entries = []
95     m = 0
96     for l in labels:
97         m = max(len(l),m)
98         if l.lower() in book:
99             entries.append(book[l.lower()])
100         else:
101             entries.append("")
102     m+=4
103
104     w=curses.newwin(34,70,1,10)
105     (y,x)=w.getmaxyx()
106     w.keypad(1)
107     redrawForm(w,caption,zip(labels,entries),buttonlabel,m)
108     bcol = [x-len(buttonlabel)-len("<cancel>")-6, x-len(buttonlabel)-4]
109     bwidth = [8,len(buttonlabel)+2]
110     
111     highlight=0
112     b = -1
113     r=3
114     w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
115     w.move(r,m+len(entries[highlight]))
116     cursor = len(entries[highlight])
117     ch = w.getch()
118     while (1==1):
119         if ch==27: #escape key
120             curses.curs_set(0)
121             w.clear()
122             w.refresh()
123             return {}
124         if ch==curses.KEY_UP:
125             if highlight == len(labels):
126                 w.chgat(r,bcol[b],bwidth[b],curses.A_NORMAL)
127                 highlight = len(labels)-1
128                 b = -1
129                 r=3+2*highlight
130                 w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
131                 cursor = len(entries[highlight])
132                 w.move(r,m+cursor)
133                 curses.curs_set(1)
134             elif highlight!=0:
135                 w.chgat(r,m,x-m-2,curses.A_NORMAL)
136                 highlight -= 1
137                 r=3+2*highlight
138                 w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
139                 cursor = len(entries[highlight])
140                 w.move(r,m+cursor)
141         elif ch==curses.KEY_PPAGE:
142             w.chgat(r,m,x-m-2,curses.A_NORMAL)
143             highlight=0
144             b=-1
145             r=3+2*highlight
146             w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
147             cursor = len(entries[highlight])
148             w.move(r,m+cursor)
149             curses.curs_set(1)
150         elif ch==curses.KEY_DOWN:
151             if highlight >= len(labels) -1:
152                 highlight = len(labels)
153                 b += 1
154                 b = min(b,1)
155                 curses.curs_set(0)
156                 w.chgat(r,m,x-m-2,curses.A_NORMAL)
157                 r = y-3
158                 w.chgat(r,bcol[b],bwidth[b],curses.A_REVERSE)
159             else:
160                 w.chgat(r,m,x-m-2,curses.A_NORMAL)
161                 highlight += 1
162                 r=3+2*highlight
163                 w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
164                 cursor = len(entries[highlight])
165                 w.move(r,m+cursor)
166         elif ch==curses.KEY_NPAGE:
167             if highlight!=len(labels):
168                 highlight = len(labels)
169                 b += 1
170                 b = min(b,1)
171                 curses.curs_set(0)
172                 w.chgat(r,m,x-m-2,curses.A_NORMAL)
173                 r = y-3
174                 w.chgat(r,bcol[b],bwidth[b],curses.A_REVERSE)
175         elif ch==curses.KEY_LEFT:
176             if highlight == len(labels):
177                 w.chgat(r,bcol[b],bwidth[b],curses.A_NORMAL)
178                 b=0
179                 w.chgat(r,bcol[b],bwidth[b],curses.A_REVERSE)
180             else:
181                 if cursor>0:
182                     cursor-=1
183                     w.move(r,m+cursor)
184         elif ch==curses.KEY_RIGHT:
185             if highlight == len(labels):
186                 w.chgat(r,bcol[b],bwidth[b],curses.A_NORMAL)
187                 b=1
188                 w.chgat(r,bcol[b],bwidth[b],curses.A_REVERSE)
189             else:
190                 if cursor < len(entries[highlight]):
191                     cursor+=1
192                     w.move(r,m+cursor)
193         elif ch>31 and ch<127:
194             if highlight != len(labels):
195                 entries[highlight]=entries[highlight][:cursor] + curses.keyname(ch) + entries[highlight][cursor:]
196                 cursor+=1
197                 w.addnstr(r,m, entries[highlight]+(" "*40), x-m-2)
198                 w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
199                 w.move(r,m+cursor)
200         elif ch==curses.KEY_BACKSPACE:
201             if highlight != len(labels) and cursor!=0:
202                 cursor-=1
203                 entries[highlight]=entries[highlight][:cursor] + entries[highlight][cursor+1:]
204                 w.addnstr(r,m, entries[highlight]+(" "*40), x-m-2)
205                 w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
206                 w.move(r,m+cursor)
207         elif ch==curses.KEY_DC:
208             if highlight != len(labels):
209                 entries[highlight]=entries[highlight][:cursor] + entries[highlight][cursor+1:]
210                 w.addnstr(r,m, entries[highlight]+(" "*40), x-m-2)
211                 w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
212                 w.move(r,m+cursor)
213         elif ch==curses.KEY_HOME:
214             if highlight != len(labels):
215                 cursor=0
216                 w.move(r,m+cursor)
217         elif ch==curses.KEY_END:
218             if highlight != len(labels):
219                 cursor=len(entries[highlight])
220                 w.move(r,m+cursor)
221         elif ch==10:
222             if b != -1:
223                 if b == 0:
224                     w.clear()
225                     w.refresh()
226                     return {}
227                 elif b == 1:
228                     w.clear()
229                     w.refresh()
230                     return lists_to_dict(labels,entries)
231             elif highlight == len(labels)-1:
232                 highlight = len(labels)
233                 b=0
234                 curses.curs_set(0)
235                 w.chgat(r,m,x-m-2,curses.A_NORMAL)
236                 r = y-3
237                 w.chgat(r,bcol[b],bwidth[b],curses.A_REVERSE)
238             else:
239                 w.chgat(r,m,x-m-2,curses.A_NORMAL)
240                 highlight += 1
241                 r=3+2*highlight
242                 w.chgat(r,m,x-m-2,curses.A_UNDERLINE)
243                 cursor = len(entries[highlight])
244                 w.move(r,m+cursor)
245
246
247         w.refresh()
248         ch = w.getch()
249
250     curses.curs_set(0)
251     w.clear()
252     w.refresh()
253     return {}
254
255
256 def addForm():
257     book = {"title":"A Book of Tests", "pages":"123"}
258     book = bookForm("Add a book", book, "add")
259     #bookForm("View the book", book, "done")
260     if len(book)!=0:
261         db.addBook(book)
262
263
264 def updateMenu():
265     w=curses.newwin(1,50,10,10)
266     w.addstr("I will be used to update or modify book records")
267     w.refresh()
268
269 def deleteMenu():
270     w=curses.newwin(1,50,10,10)
271     w.addstr("I will be used to delete book records")
272     w.refresh()
273
274 def browseMenu():
275     w=curses.newwin(10,80,20,20)
276     b = browser.browserWindow(w)
277     b.startBrowser()
278     w.box()
279     w.refresh()
280     w.getch()
281
282
283 m = [("Browse Library", browseMenu),
284      ("Add Book or other item", addForm),
285      ("Modify/Update record", updateMenu),
286      ("Remove book from catalogue", deleteMenu),
287      ("",exit),
288      ("Exit", exit)]
289 curses.wrapper(menutest, m)