Add "error windows", stop crashing when editing empty list of books

This commit is contained in:
Felix Bauckholt 2016-01-30 21:20:38 -05:00
parent 89c66c8188
commit 1690ac87a8
4 changed files with 97 additions and 15 deletions

View File

@ -31,7 +31,17 @@ def menutest(s, l):
hb.refresh()
w = curses.newwin(15,40,(rows-10)//2, (cols-40)//2)
try:
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)

View File

@ -15,3 +15,6 @@ class PermissionsError(LibrarianException):
@property
def error_msg(self):
return "Need privilege level {}".format(self.permission_string)
class NoHighlightedEntry(LibrarianException):
error_msg = "No highlighted entry"

View File

@ -1,6 +1,7 @@
import curses
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:
# These are actually class variables, not member variables? :<
@ -118,12 +119,18 @@ class browserWindow:
def mvHighlight(self,delta):
new = self.hl+delta
new = max(new,0)
new = min(new,len(self.entries)-1)
new = max(new,0)
self.unHighlight()
self.hl = new
self.highlight()
def highlightedEntry(self):
try:
return self.entries[self.hl]
except:
raise NoHighlightedEntry()
def scroll(self,delta):
self.unHighlight()
self.topline += delta
@ -277,6 +284,7 @@ class trashBrowser(browserWindow):
bf.event_loop()
bf.clear()
@catch_error
def restoreSelected(self):
books = []
for sel,book in zip(self.selected, self.entries):
@ -284,6 +292,7 @@ class trashBrowser(browserWindow):
books.append(book)
db.restoreBooks(books)
@catch_error
def delSelected(self):
books = []
for sel,book in zip(self.selected, self.entries):
@ -294,10 +303,11 @@ class trashBrowser(browserWindow):
def refreshBooks(self):
self.load_data(db.getRemovedBooks())
@catch_error
def handleInput(self,ch):
browserWindow.handleInput(self,ch)
if ch == 10:
book = self.entries[self.hl]
book = self.highlightedEntry()
self.viewSelection(book)
self.refresh()
if ch==114: #restore books
@ -332,6 +342,7 @@ class bookBrowser(browserWindow):
# redefinable functions
@catch_error
def updateSelection(self,book):
bookid = book['id']
@ -341,9 +352,9 @@ class bookBrowser(browserWindow):
bf.caption='Update Book '+str(bookid)
bf.blabel='update'
newbook = bf.event_loop()
bf.clear()
if len(newbook)!=0:
db.updateBook(newbook,bookid)
bf.clear()
def viewSelection(self,book):
bookid = book['id']
@ -363,7 +374,9 @@ class bookBrowser(browserWindow):
cs.refreshCategories()
cs.eventLoop()
cs.clear()
self.refreshBooks()
@catch_error
def delSelected(self):
books = []
for sel,book in zip(self.selected, self.entries):
@ -390,19 +403,20 @@ class bookBrowser(browserWindow):
self.refreshBooks = lambda : self.load_data(db.get_onshelf_books())
self.refreshBooks()
@catch_error
def handleInput(self,ch):
browserWindow.handleInput(self,ch)
if ch == 117: #update on 'u'
book = self.entries[self.hl]
book = self.highlightedEntry()
self.updateSelection(book)
self.entries[self.hl]=db.get_book(book['id'])
self.refresh()
elif ch == 10:
book = self.entries[self.hl]
book = self.highlightedEntry()
self.viewSelection(book)
self.refresh()
elif ch == 99:
book = self.entries[self.hl]
elif ch == 99: #c
book = self.highlightedEntry()
self.categorizeSelection(book)
self.refresh()
if ch == 100:
@ -425,22 +439,24 @@ class categoryBrowser(browserWindow):
self.load_data(db.getCategories())
self.sortByColumn('category')
@catch_error
def addCategory(self):
w = curses.newwin(1,1,10,10)
cf = CategoryForm(w,self.hb)
self.centreChild(w)
cat = cf.event_loop()
db.addCategory(cat)
cf.clear()
db.addCategory(cat)
def viewCategory(self):
w = curses.newwin(3,5)
b = bookBrowser(w,self.hb)
self.centreChild(w)
b.refreshBooksInCategory(self.entries[self.hl])
b.refreshBooksInCategory(self.highlightedEntry())
b.eventLoop()
b.clear()
@catch_error
def delSelected(self):
categories = []
for sel,cat in zip(self.selected, self.entries):
@ -496,7 +512,7 @@ class categorySelector(browserWindow):
j+=1
self.selected = self.original[:]
@catch_error
def addCategory(self):
w = curses.newwin(1,1,10,10)
cf = CategoryForm(w,self.hb)
@ -506,6 +522,7 @@ class categorySelector(browserWindow):
db.addCategory(c)
cf.clear()
@catch_error
def updateCategories(self):
# first removed the deselected ones
uncats = []
@ -559,7 +576,7 @@ class columnSelector(browserWindow):
while ch != 27 and ch != 113:
ch = self.handleInput(ch)
if ch == 10:
col = self.entries[self.hl]
col = self.highlightedEntry()
return col['column']
self.w.refresh()
ch = self.w.getch()

View File

@ -1,4 +1,5 @@
import curses
from library.exceptions import LibrarianException
class TextEntry:
@ -316,3 +317,54 @@ class CategoryForm(FormWindow):
def _return_values(self):
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