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