Add "error windows", stop crashing when editing empty list of books
This commit is contained in:
parent
89c66c8188
commit
1690ac87a8
10
librarian
10
librarian
|
@ -31,7 +31,17 @@ def menutest(s, l):
|
||||||
hb.refresh()
|
hb.refresh()
|
||||||
w = curses.newwin(15,40,(rows-10)//2, (cols-40)//2)
|
w = curses.newwin(15,40,(rows-10)//2, (cols-40)//2)
|
||||||
|
|
||||||
|
try:
|
||||||
menu(w, l)
|
menu(w, l)
|
||||||
|
except SystemExit: pass
|
||||||
|
except:
|
||||||
|
text = """An unexpected error occured.
|
||||||
|
You can contact the librarian (librarian@csclub.uwaterloo.ca),
|
||||||
|
but given the history of the library system, it seems unlikely
|
||||||
|
that somebody will be around to care.
|
||||||
|
The program will now quit."""
|
||||||
|
form.error_form(text, stdscr, hb)
|
||||||
|
raise
|
||||||
|
|
||||||
curses.curs_set(1)
|
curses.curs_set(1)
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,6 @@ class PermissionsError(LibrarianException):
|
||||||
@property
|
@property
|
||||||
def error_msg(self):
|
def error_msg(self):
|
||||||
return "Need privilege level {}".format(self.permission_string)
|
return "Need privilege level {}".format(self.permission_string)
|
||||||
|
|
||||||
|
class NoHighlightedEntry(LibrarianException):
|
||||||
|
error_msg = "No highlighted entry"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import curses
|
import curses
|
||||||
import library.database as db
|
import library.database as db
|
||||||
from library.interface.form import BookForm,CategoryForm
|
from library.interface.form import BookForm,CategoryForm,error_form,catch_error
|
||||||
|
from library.exceptions import NoHighlightedEntry
|
||||||
|
|
||||||
class browserWindow:
|
class browserWindow:
|
||||||
# These are actually class variables, not member variables? :<
|
# These are actually class variables, not member variables? :<
|
||||||
|
@ -118,12 +119,18 @@ class browserWindow:
|
||||||
|
|
||||||
def mvHighlight(self,delta):
|
def mvHighlight(self,delta):
|
||||||
new = self.hl+delta
|
new = self.hl+delta
|
||||||
new = max(new,0)
|
|
||||||
new = min(new,len(self.entries)-1)
|
new = min(new,len(self.entries)-1)
|
||||||
|
new = max(new,0)
|
||||||
self.unHighlight()
|
self.unHighlight()
|
||||||
self.hl = new
|
self.hl = new
|
||||||
self.highlight()
|
self.highlight()
|
||||||
|
|
||||||
|
def highlightedEntry(self):
|
||||||
|
try:
|
||||||
|
return self.entries[self.hl]
|
||||||
|
except:
|
||||||
|
raise NoHighlightedEntry()
|
||||||
|
|
||||||
def scroll(self,delta):
|
def scroll(self,delta):
|
||||||
self.unHighlight()
|
self.unHighlight()
|
||||||
self.topline += delta
|
self.topline += delta
|
||||||
|
@ -277,6 +284,7 @@ class trashBrowser(browserWindow):
|
||||||
bf.event_loop()
|
bf.event_loop()
|
||||||
bf.clear()
|
bf.clear()
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def restoreSelected(self):
|
def restoreSelected(self):
|
||||||
books = []
|
books = []
|
||||||
for sel,book in zip(self.selected, self.entries):
|
for sel,book in zip(self.selected, self.entries):
|
||||||
|
@ -284,6 +292,7 @@ class trashBrowser(browserWindow):
|
||||||
books.append(book)
|
books.append(book)
|
||||||
db.restoreBooks(books)
|
db.restoreBooks(books)
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def delSelected(self):
|
def delSelected(self):
|
||||||
books = []
|
books = []
|
||||||
for sel,book in zip(self.selected, self.entries):
|
for sel,book in zip(self.selected, self.entries):
|
||||||
|
@ -294,10 +303,11 @@ class trashBrowser(browserWindow):
|
||||||
def refreshBooks(self):
|
def refreshBooks(self):
|
||||||
self.load_data(db.getRemovedBooks())
|
self.load_data(db.getRemovedBooks())
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def handleInput(self,ch):
|
def handleInput(self,ch):
|
||||||
browserWindow.handleInput(self,ch)
|
browserWindow.handleInput(self,ch)
|
||||||
if ch == 10:
|
if ch == 10:
|
||||||
book = self.entries[self.hl]
|
book = self.highlightedEntry()
|
||||||
self.viewSelection(book)
|
self.viewSelection(book)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
if ch==114: #restore books
|
if ch==114: #restore books
|
||||||
|
@ -332,6 +342,7 @@ class bookBrowser(browserWindow):
|
||||||
|
|
||||||
|
|
||||||
# redefinable functions
|
# redefinable functions
|
||||||
|
@catch_error
|
||||||
def updateSelection(self,book):
|
def updateSelection(self,book):
|
||||||
bookid = book['id']
|
bookid = book['id']
|
||||||
|
|
||||||
|
@ -341,9 +352,9 @@ class bookBrowser(browserWindow):
|
||||||
bf.caption='Update Book '+str(bookid)
|
bf.caption='Update Book '+str(bookid)
|
||||||
bf.blabel='update'
|
bf.blabel='update'
|
||||||
newbook = bf.event_loop()
|
newbook = bf.event_loop()
|
||||||
|
bf.clear()
|
||||||
if len(newbook)!=0:
|
if len(newbook)!=0:
|
||||||
db.updateBook(newbook,bookid)
|
db.updateBook(newbook,bookid)
|
||||||
bf.clear()
|
|
||||||
|
|
||||||
def viewSelection(self,book):
|
def viewSelection(self,book):
|
||||||
bookid = book['id']
|
bookid = book['id']
|
||||||
|
@ -363,7 +374,9 @@ class bookBrowser(browserWindow):
|
||||||
cs.refreshCategories()
|
cs.refreshCategories()
|
||||||
cs.eventLoop()
|
cs.eventLoop()
|
||||||
cs.clear()
|
cs.clear()
|
||||||
|
self.refreshBooks()
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def delSelected(self):
|
def delSelected(self):
|
||||||
books = []
|
books = []
|
||||||
for sel,book in zip(self.selected, self.entries):
|
for sel,book in zip(self.selected, self.entries):
|
||||||
|
@ -390,22 +403,23 @@ class bookBrowser(browserWindow):
|
||||||
self.refreshBooks = lambda : self.load_data(db.get_onshelf_books())
|
self.refreshBooks = lambda : self.load_data(db.get_onshelf_books())
|
||||||
self.refreshBooks()
|
self.refreshBooks()
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def handleInput(self,ch):
|
def handleInput(self,ch):
|
||||||
browserWindow.handleInput(self,ch)
|
browserWindow.handleInput(self,ch)
|
||||||
if ch == 117: #update on 'u'
|
if ch == 117: #update on 'u'
|
||||||
book = self.entries[self.hl]
|
book = self.highlightedEntry()
|
||||||
self.updateSelection(book)
|
self.updateSelection(book)
|
||||||
self.entries[self.hl]=db.get_book(book['id'])
|
self.entries[self.hl]=db.get_book(book['id'])
|
||||||
self.refresh()
|
self.refresh()
|
||||||
elif ch == 10:
|
elif ch == 10:
|
||||||
book = self.entries[self.hl]
|
book = self.highlightedEntry()
|
||||||
self.viewSelection(book)
|
self.viewSelection(book)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
elif ch == 99:
|
elif ch == 99: #c
|
||||||
book = self.entries[self.hl]
|
book = self.highlightedEntry()
|
||||||
self.categorizeSelection(book)
|
self.categorizeSelection(book)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
if ch==100:
|
if ch == 100:
|
||||||
count=0
|
count=0
|
||||||
for s in self.selected[0:self.hl-1]:
|
for s in self.selected[0:self.hl-1]:
|
||||||
if s:
|
if s:
|
||||||
|
@ -425,22 +439,24 @@ class categoryBrowser(browserWindow):
|
||||||
self.load_data(db.getCategories())
|
self.load_data(db.getCategories())
|
||||||
self.sortByColumn('category')
|
self.sortByColumn('category')
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def addCategory(self):
|
def addCategory(self):
|
||||||
w = curses.newwin(1,1,10,10)
|
w = curses.newwin(1,1,10,10)
|
||||||
cf = CategoryForm(w,self.hb)
|
cf = CategoryForm(w,self.hb)
|
||||||
self.centreChild(w)
|
self.centreChild(w)
|
||||||
cat = cf.event_loop()
|
cat = cf.event_loop()
|
||||||
db.addCategory(cat)
|
|
||||||
cf.clear()
|
cf.clear()
|
||||||
|
db.addCategory(cat)
|
||||||
|
|
||||||
def viewCategory(self):
|
def viewCategory(self):
|
||||||
w = curses.newwin(3,5)
|
w = curses.newwin(3,5)
|
||||||
b = bookBrowser(w,self.hb)
|
b = bookBrowser(w,self.hb)
|
||||||
self.centreChild(w)
|
self.centreChild(w)
|
||||||
b.refreshBooksInCategory(self.entries[self.hl])
|
b.refreshBooksInCategory(self.highlightedEntry())
|
||||||
b.eventLoop()
|
b.eventLoop()
|
||||||
b.clear()
|
b.clear()
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def delSelected(self):
|
def delSelected(self):
|
||||||
categories = []
|
categories = []
|
||||||
for sel,cat in zip(self.selected, self.entries):
|
for sel,cat in zip(self.selected, self.entries):
|
||||||
|
@ -496,7 +512,7 @@ class categorySelector(browserWindow):
|
||||||
j+=1
|
j+=1
|
||||||
self.selected = self.original[:]
|
self.selected = self.original[:]
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def addCategory(self):
|
def addCategory(self):
|
||||||
w = curses.newwin(1,1,10,10)
|
w = curses.newwin(1,1,10,10)
|
||||||
cf = CategoryForm(w,self.hb)
|
cf = CategoryForm(w,self.hb)
|
||||||
|
@ -506,6 +522,7 @@ class categorySelector(browserWindow):
|
||||||
db.addCategory(c)
|
db.addCategory(c)
|
||||||
cf.clear()
|
cf.clear()
|
||||||
|
|
||||||
|
@catch_error
|
||||||
def updateCategories(self):
|
def updateCategories(self):
|
||||||
# first removed the deselected ones
|
# first removed the deselected ones
|
||||||
uncats = []
|
uncats = []
|
||||||
|
@ -558,8 +575,8 @@ class columnSelector(browserWindow):
|
||||||
ch = self.w.getch()
|
ch = self.w.getch()
|
||||||
while ch != 27 and ch != 113:
|
while ch != 27 and ch != 113:
|
||||||
ch = self.handleInput(ch)
|
ch = self.handleInput(ch)
|
||||||
if ch==10:
|
if ch == 10:
|
||||||
col = self.entries[self.hl]
|
col = self.highlightedEntry()
|
||||||
return col['column']
|
return col['column']
|
||||||
self.w.refresh()
|
self.w.refresh()
|
||||||
ch = self.w.getch()
|
ch = self.w.getch()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import curses
|
import curses
|
||||||
|
from library.exceptions import LibrarianException
|
||||||
|
|
||||||
|
|
||||||
class TextEntry:
|
class TextEntry:
|
||||||
|
@ -316,3 +317,54 @@ class CategoryForm(FormWindow):
|
||||||
|
|
||||||
def _return_values(self):
|
def _return_values(self):
|
||||||
return self.entries[0].value
|
return self.entries[0].value
|
||||||
|
|
||||||
|
class DummyTextEntry(TextEntry):
|
||||||
|
def redraw(self): pass
|
||||||
|
|
||||||
|
class ErrorForm(FormWindow):
|
||||||
|
caption = "Error"
|
||||||
|
blabel = "OK"
|
||||||
|
def __init__(self,window,helpbar,errortext,width=50):
|
||||||
|
self.labels = errortext.split("\n")
|
||||||
|
super().__init__(window, helpbar, width=width)
|
||||||
|
self.bt = 1
|
||||||
|
|
||||||
|
def _make_entries(self):
|
||||||
|
self.entries = []
|
||||||
|
for e in range(len(self.labels)):
|
||||||
|
self.entries.append(DummyTextEntry(self.w))
|
||||||
|
|
||||||
|
def redraw(self):
|
||||||
|
self.w.box()
|
||||||
|
self.w.addstr(0,(self.mx-len(self.caption))//2,self.caption)
|
||||||
|
r=0
|
||||||
|
for l in self.labels:
|
||||||
|
c = 2
|
||||||
|
self.w.addstr(r+self.top,c,l)
|
||||||
|
self.entries[r].redraw()
|
||||||
|
r+=1
|
||||||
|
self.w.addstr(self.brow,self.bcol[1], "<"+self.blabel+">")
|
||||||
|
self.w.chgat(self.brow, self.bcol[1], len(self.blabel)+2, curses.A_REVERSE)
|
||||||
|
self.w.refresh()
|
||||||
|
|
||||||
|
def _mv_focus(self,delta): pass
|
||||||
|
|
||||||
|
def error_form(text, w, hb):
|
||||||
|
width = max([len(l) for l in text.split("\n")]) + 4
|
||||||
|
child=curses.newwin(1,1)
|
||||||
|
f = ErrorForm(child, hb, text, width)
|
||||||
|
(my,mx)=w.getmaxyx()
|
||||||
|
(r,c)=child.getmaxyx()
|
||||||
|
child.mvwin((my-r)//2,(mx-c)//2)
|
||||||
|
w.refresh()
|
||||||
|
f.event_loop()
|
||||||
|
f.clear()
|
||||||
|
|
||||||
|
def catch_error(fn):
|
||||||
|
def wrapper_fun(self, *args, **kwd):
|
||||||
|
try:
|
||||||
|
return fn(self, *args, **kwd)
|
||||||
|
except LibrarianException as e:
|
||||||
|
error_form(str(e), self.w, self.hb)
|
||||||
|
self.refresh()
|
||||||
|
return wrapper_fun
|
||||||
|
|
Loading…
Reference in New Issue