tirilane
/
egon
Archived
1
0
Fork 0
This repository has been archived on 2024-07-04. You can view files and clone it, but cannot push or open issues or pull requests.
egon/egon.py

2184 lines
72 KiB
Python
Executable File

#!/usr/bin/env python
#coding: utf-8
# Copyright 2008, Tiril Anette Langfeldt Rødland
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import platform
import sys
import string
import datetime
import time
import random
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from pysqlite2 import dbapi2 as sqlite
from qrc_resources import *
__version__ = "1.1.0"
main = None
semesters = []
semester = None
courses = []
coursesString = []
books = []
booksString = []
colors = []
termList = None
### The main window
class MainWindow(QMainWindow):
# Initialize the main window
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
# The program name
self.title = self.trUtf8("Egon")
# The days
self.days = [self.trUtf8("Monday"), self.trUtf8("Tuesday"), self.trUtf8("Wednesday"), self.trUtf8("Thursday"), self.trUtf8("Friday")]
# The tabs
self.assignment = AssignmentTab()
self.reading = ReadingTab()
self.schedule = ScheduleTab()
# Set the tabs in the middle
self.tabs = QTabWidget()
self.tabs.addTab(self.assignment, self.trUtf8("&Assignment"))
self.tabs.addTab(self.reading, self.trUtf8("&Reading List"))
self.tabs.addTab(self.schedule, self.trUtf8("&Schedule"))
self.tabs.setTabShape(QTabWidget.Rounded)
self.tabs.setTabPosition(QTabWidget.North)
self.setCentralWidget(self.tabs)
# The calendar
self.calendarFrame = QFrame()
self.calendarFrame.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
self.calendarDockWidget = QDockWidget(self.trUtf8("Calendar"), self)
self.calendarDockWidget.setVisible(False)
self.calendarDockWidget.setObjectName("CalendarDockWidget")
self.calendarDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea|Qt.RightDockWidgetArea|Qt.BottomDockWidgetArea)
self.calendar = QCalendarWidget()
self.calendar.setFirstDayOfWeek(Qt.Monday)
self.calendarLayout = QVBoxLayout()
self.calendarLayout.addWidget(self.calendar)
self.calendarFrame.setLayout(self.calendarLayout)
self.calendarFrame.hide()
self.calendarDockWidget.setWidget(self.calendarFrame)
# The semesters
global semester, semesters, termList
termList = QStringList()
termList.append(self.trUtf8("Spring"))
termList.append(self.trUtf8("Autumn"))
semesters = getSemestersFromDB()
semester = self.getLatestSemester(semesters)
if semester:
self.load(semester)
# Actions
fileNewAction = self.createAction(self.trUtf8("&New"), self.fileNew, QKeySequence.New, "filenew", self.trUtf8("Create a new semester plan"))
fileOpenAction = self.createAction(self.trUtf8("&Open"), self.fileOpen, QKeySequence.Open, "fileopen", self.trUtf8("Open an existing semester plan"))
fileQuitAction = self.createAction(self.trUtf8("&Quit"), self.close, "Ctrl+Q", "filequit", self.trUtf8("Quit program"))
editAddCourse = self.createAction(self.trUtf8("Add &course"), self.addCourse, "Ctrl+C", None, self.trUtf8("Add a new course"))
editAddBook = self.createAction(self.trUtf8("Add &book"), self.addBook, "Ctrl+B", None, self.trUtf8("Add a new book"))
editAddAssignment = self.createAction(self.trUtf8("Add &assignment"), self.addAssignment, "Ctrl+A", None, self.trUtf8("Add a new assignment"))
editAddReading = self.createAction(self.trUtf8("Add &reading"), self.addReading, "Ctrl+R", None, self.trUtf8("Add a new reading"))
editAddLesson = self.createAction(self.trUtf8("Add &lesson"), self.addLesson, "Ctrl+L", None, self.trUtf8("Add a new lesson"))
editShowCalendar = self.createAction(self.trUtf8("Cal&endar"), self.showCalendar, "Ctrl+E", None, self.trUtf8("Show the calendar"))
helpAboutScheduler = self.createAction(self.trUtf8("&About Egon"))
# Menus
self.fileMenu = self.menuBar().addMenu(self.trUtf8("&File"))
self.editMenu = self.menuBar().addMenu(self.trUtf8("&Edit"))
self.helpMenu = self.menuBar().addMenu(self.trUtf8("&Help"))
# Add actions to the menus
self.addActions(self.fileMenu, (fileNewAction, fileOpenAction, None, fileQuitAction))
self.addActions(self.editMenu, (editAddCourse, editAddBook, None, editAddAssignment, None, editAddReading, None, editAddLesson, None, editShowCalendar))
self.addActions(self.helpMenu, (helpAboutScheduler, None))
# Connect statements
self.connect(editAddCourse, SIGNAL("triggered()"), self.addCourse)
self.connect(editAddBook, SIGNAL("triggered()"), self.addBook)
self.connect(editAddAssignment, SIGNAL("triggered()"), self.addAssignment)
self.connect(editAddReading, SIGNAL("triggered()"), self.addReading)
self.connect(editAddLesson, SIGNAL("triggered()"), self.addLesson)
self.connect(editShowCalendar, SIGNAL("pressed()"), self.showCalendar)
self.connect(helpAboutScheduler, SIGNAL("triggered()"), self.helpAbout)
self.connect(self.assignment.addAssignmentButton, SIGNAL("pressed()"), self.addAssignment)
self.connect(self.assignment.deleteAssignmentButton, SIGNAL("pressed()"), self.deleteAssignment)
self.connect(self.assignment.statusAssignmentBox, SIGNAL("currentIndexChanged(QString)"), self.statusAssignment)
self.connect(self.reading.addReadingButton, SIGNAL("pressed()"), self.addReading)
self.connect(self.reading.deleteReadingButton, SIGNAL("pressed()"), self.deleteReading)
self.connect(self.reading.readingDoneButton, SIGNAL("pressed()"), self.doneReading)
self.connect(self.schedule.addScheduleButton, SIGNAL("pressed()"), self.addLesson)
self.connect(self.schedule.deleteScheduleButton, SIGNAL("pressed()"), self.deleteLesson)
# The toolbars
fileToolbar = self.addToolBar(self.trUtf8("File"))
fileToolbar.setObjectName("FileToolBar")
self.addActions(fileToolbar, (fileNewAction, fileOpenAction, None, fileQuitAction))
editToolbar = self.addToolBar(self.trUtf8("Edit"))
editToolbar.setObjectName("EditToolBar")
self.addActions(editToolbar, (editAddCourse, editAddBook, None, editShowCalendar))
# Set the title
self.setMainWindowTitle()
# The courses
courses = getCourses()
makeCoursesString()
# This window
global main
main = self
# Semester
## Open the New dialog
def fileNew(self):
self.nsdlg = NewSemesterDlg()
self.nsdlg.show()
## Open the Open dialog
def fileOpen(self):
self.osdlg = OpenSemesterDlg()
self.osdlg.show()
## Return the latest semester
def getLatestSemester(self, semesters):
if len(semesters) == 0:
return None
global termList
max = semesters[0]
for s in semesters:
if s.getYear() > max.getYear():
max = s
if s.getYear() == max.getYear():
if s.getTerm() == self.trUtf8("Autumn"):
max = s
return max
# Return the list of terms
def getTermList(self):
global termList
return termList
# Assignment
## Open the Add Assignment dialog
def addAssignment(self):
self.adlg = AssignmentDlg()
self.adlg.show()
## Delete the assignment from the database and the table
def deleteAssignment(self):
course, number = self.getCourseAndNumber()
table, row = self.getAssignmentTableAndRow()
global semester
removeAssignmentFromDB(course, number)
table.removeRow(row)
table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
## Update the assignment's completion level to the specified level
def statusAssignment(self, completionLevel):
course, number = self.getCourseAndNumber()
table, row = self.getAssignmentTableAndRow()
updateAssignmentCompletion(course, number, completionLevel)
item = QTableWidgetItem(QString(completionLevel))
item.setBackground(self.assignment.makeBrush(completionLevel))
table.setItem(row, 4, item)
table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
## Return the assignment table and its current row
def getAssignmentTableAndRow(self):
table = self.assignment.assignmentTable
row = table.currentRow()
return table, row
## Return the course and number of the current assignment
def getCourseAndNumber(self):
table, row = self.getAssignmentTableAndRow()
courseItem = table.item(row, 1)
numberItem = table.item(row, 2)
courseFull = courseItem.text()
number = numberItem.text()
course = getCourseCode(courseFull)
return course, number
# Reading
## Open the Add Reading dialog
def addReading(self):
self.rdlg = ReadingDlg()
self.rdlg.show()
## Delete the reading from the database and the table
def deleteReading(self):
week, course, book, chapter = self.getWeekCourseBookAndChapter()
table, row = self.getReadingTableAndRow()
global semester
removeReadingFromDB(week, course, book, chapter)
table.removeRow(row)
table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
## Mark the reading as done
def doneReading(self):
table, row = self.getReadingTableAndRow()
if table.item(row, 6).text().compare(QString(self.trUtf8("Not done"))) == 0:
done = True
item = QTableWidgetItem(self.trUtf8("Done"))
item.setBackground(QBrush(Qt.green, Qt.SolidPattern))
else:
done = True
item = QTableWidgetItem(self.trUtf8("Not done"))
item.setBackground(QBrush(Qt.red, Qt.SolidPattern))
table.setItem(row, 6, item)
table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
week = (table.item(row, 0).text().toInt())[0]
courseFull = table.item(row, 1).text()
courseCode = QString(getCourseCode(courseFull))
bookTitle = table.item(row, 2).text()
book = getBookWithTitleFromDB(bookTitle)
bookIsbn = book.getIsbn()
chapter = table.item(row, 3).text()
updateReadingDone(week, courseCode, bookIsbn, chapter, done)
print week, courseCode, bookIsbn, chapter, done
## Return the reading table and its current row
def getReadingTableAndRow(self):
table = self.reading.readingTable
row = table.currentRow()
return table, row
## Return the week, course and book of the current reading
def getWeekCourseBookAndChapter(self):
table, row = self.getReadingTableAndRow()
weekItem = table.item(row, 0)
courseItem = table.item(row, 1)
bookItem = table.item(row, 2)
chapterItem = table.item(row, 3)
week = (weekItem.text().toInt())[0]
courseFull = courseItem.text()
courseCode = getCourseCode(courseFull)
book = getBookWithTitleFromDB(bookItem.text())
chapter = chapterItem.text()
return week, courseCode, book.getIsbn(), chapter
# Schedule
## Open the Add Lesson dialog
def addLesson(self):
self.sdlg = ScheduleDlg()
self.sdlg.show()
## Delete the lesson from the database and the table
def deleteLesson(self):
table, row, column = self.getScheduleTableRowAndColumn()
day, course, time = self.getDayCourseAndTime()
global semester
removeLessonFromDB(day, course, time)
table.setItem(row, column, QTableWidgetItem())
## Return the schedule table and the current row and column
def getScheduleTableRowAndColumn(self):
table = self.schedule.scheduleTable
row = table.currentRow()
column = table.currentColumn()
return table, row, column
## Return the day, course and time of the current lesson
def getDayCourseAndTime(self):
table, row, column = self.getScheduleTableRowAndColumn()
item = table.item(row, column)
text = item.text()
textlist = text.split('\n')
courseFull = textlist[0]
coursecode = getCourseCode(courseFull)
day = self.getDayFromTable(column)
time = row + 8
return day, coursecode, time
## Return the day belonging to the specified column
def getDayFromTable(self, column):
return self.days[column]
# Course
## Open the Add Course dialog
def addCourse(self):
self.cdlg = CourseDlg()
self.cdlg.show()
# Book
## Open the Add Book dialog
def addBook(self):
self.bdlg = BookDlg()
self.bdlg.show()
# Calendar
## Show the calendar
def showCalendar(self):
if self.calendarDockWidget.isVisible():
self.removeDockWidget(self.calendarDockWidget)
else:
self.addDockWidget(Qt.BottomDockWidgetArea, self.calendarDockWidget)
self.calendarDockWidget.setVisible(True)
# General
## Make and open the About dialo
def helpAbout(self):
QMessageBox.about(self, "About %s" % self.title, """
<b>%s</b> v %s
<p>Copyright &copy; 2008 Tiril Anette Langfeldt Roedland. No rights reserved.
<p>You may modify and redistribute the program under the terms of the GPL. The license can be found here: http://www.gnu.org/licenses/gpl.html
<p>This application is mainly for use by students, and can be used to keep track of assignments, planned readings and the schedule.
<p>Python %s - Qt %s - PyQt %s on %s
<p>Developer: Tiril Anette Langfeldt Roedland, tirilane@pvv.ntnu.no
""" % (self.title, __version__, platform.python_version(), QT_VERSION_STR, PYQT_VERSION_STR, platform.system()))
## Updates the File menu
def updateFileMenu(self):
self.fileMenu.clear()
self.addActions(self.fileMenu, self.fileMenuActions[:-1])
current = QString(self.filename) if self.filename is not None else None
## Create and return the action specified by the input
def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"):
action = QAction(text, self)
if icon is not None:
iconfile = ":/%s.png" % icon
action.setIcon(QIcon(iconfile))
if shortcut is not None:
action.setShortcut(shortcut)
if tip is not None:
action.setToolTip(tip)
action.setStatusTip(tip)
if slot is not None:
self.connect(action, SIGNAL(signal), slot)
if checkable:
action.setCheckable(True)
return action
## Add action to the target
def addActions(self, target, actions):
for action in actions:
if action is None:
target.addSeparator()
else:
target.addAction(action)
## Set the title on the main window, depending on the chosen semester
def setMainWindowTitle(self):
global semester
if semester:
self.setWindowTitle("%s : %s %i" % (self.title, semester.getTerm(), semester.getYear()))
else:
self.setWindowTitle(self.title)
## Load the assignments, readings and schedule from the specified semester
def load(self, semester):
self.assignment.updateTable(semester)
self.reading.updateTable(semester)
self.schedule.updateTable(semester)
### The New Semester dialog
class NewSemesterDlg(QDialog):
## Initialize the New Semester dialog
def __init__(self, parent=None):
super(NewSemesterDlg, self).__init__(parent)
# Labels
self.termLabel = QLabel(self.trUtf8("Semester"))
self.yearLabel = QLabel(self.trUtf8("Year"))
# Widgets
self.termEdit = QComboBox()
self.yearEdit = QSpinBox()
self.termEdit.addItems(getMain().getTermList())
self.yearEdit.setRange(2000, 2050)
self.yearEdit.setSingleStep(1)
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
# Layout
layout = QGridLayout()
layout.addWidget(self.termLabel, 0, 0)
layout.addWidget(self.termEdit, 0, 1)
layout.addWidget(self.yearLabel, 1, 0)
layout.addWidget(self.yearEdit, 1, 1)
layout.addWidget(self.buttonBox, 2, 1)
self.setLayout(layout)
# Connect statements
self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
# Set the title
self.setWindowTitle(self.trUtf8("New semester"))
## Accept the dialog and add the specified semester
def accept(self):
term = unicode(self.termEdit.currentText())
year = self.yearEdit.value()
global semester
semester = SemesterModel(term, year)
addNewSemesterToDB(term, year)
getMain().load(semester)
getMain().setMainWindowTitle()
self.close()
### The Open Semester dialog
class OpenSemesterDlg(QDialog):
## Initialize the Open Semester dialog
def __init__(self, parent=None):
super(OpenSemesterDlg, self).__init__(parent)
# Widgets
self.semesterList = QListWidget()
semesters = getSemestersFromDB()
semesterlist = QStringList()
for semester in semesters:
semesterlist.append("%s %i" % (semester.getTerm(), semester.getYear()))
self.semesterList.addItems(semesterlist)
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
# Layout
layout = QVBoxLayout()
layout.addWidget(self.semesterList)
layout.addStretch()
layout.addWidget(self.buttonBox)
self.setLayout(layout)
# Connect statements
self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
# Set the title
self.setWindowTitle(self.trUtf8("Open semester"))
## Accept the dialog and open the specified semester
def accept(self):
text = self.semesterList.currentItem().text()
textlist = text.split(' ')
term = textlist[0]
year = textlist[1].toInt()[0]
global semester
semester = SemesterModel(term, year)
semester.setAssignments(getAssignmentsFromDB(semester))
semester.setReadings(getReadingsFromDB(semester))
semester.setLessons(getLessonsFromDB(semester))
getMain().load(semester)
getMain().setMainWindowTitle()
self.close()
### The semester model
class SemesterModel():
term = ""
year = 0
assignments = []
readings = []
lessons = []
## Initialize the semester model
def __init__(self, term, year):
self.term = term
self.year = year
## Return the term of the semester
def getTerm(self):
return self.term
## Return the year of the semester
def getYear(self):
return self.year
## Add an assignment to the semester's list of assignments
def addAssignment(self, assignment):
self.assignments.append(assignment)
## Set the list of assignments
def setAssignments(self, assignments):
self.assignments = assignments
## Return the list of assignments
def getAssignments(self):
return self.assignments
## Add a reading to the semester's list of readings
def addReading(self, reading):
self.readings.append(reading)
## Set the list of readings
def setReadings(self, readings):
self.readings = readings
## Return the list of readings
def getReadings(self):
return self.readings
## Add a lesson to the semester's list of lessons
def addLesson(self, lesson):
self.lessons.append(lesson)
## Set the list of lessons
def setLessons(self, lessons):
self.lessons = lessons
## Return the list of lessons
def getLessons(self):
return self.lessons
### The contents of the Assignment tab
class AssignmentTab(QWidget):
## Initialize the Assignment tab
def __init__(self, parent=None):
super(AssignmentTab, self).__init__(parent)
# Widgets
self.addAssignmentButton = QPushButton("Add assignment")
self.statusAssignmentBox = QComboBox()
self.deleteAssignmentButton = QPushButton("Delete assignment")
statusTypes = [self.trUtf8("Not available"), self.trUtf8("Available"), self.trUtf8("Begun"), self.trUtf8("Finished"), self.trUtf8("Delivered"), self.trUtf8("Approved"), self.trUtf8("Not approved")]
self.statusAssignmentBox.addItems(statusTypes)
# Make the table
self.makeTable()
# Layout
self.vlayout = QVBoxLayout()
self.hlayout = QHBoxLayout()
self.hlayout.addWidget(self.addAssignmentButton)
self.hlayout.addWidget(self.deleteAssignmentButton)
self.hlayout.addWidget(self.statusAssignmentBox)
self.hlayout.addStretch()
self.vlayout.addWidget(self.assignmentTable)
self.vlayout.addLayout(self.hlayout)
self.setLayout(self.vlayout)
## Make an empty assignment table
def makeTable(self, current=None):
self.assignmentTable = QTableWidget(0, 5, self)
self.assignmentTable.clear()
self.assignmentHeaderList = QStringList()
self.assignmentHeaderList.append(self.trUtf8("Date"))
self.assignmentHeaderList.append(self.trUtf8("Course"))
self.assignmentHeaderList.append(self.trUtf8("Number"))
self.assignmentHeaderList.append(self.trUtf8("Description"))
self.assignmentHeaderList.append(self.trUtf8("Status"))
self.assignmentTable.setHorizontalHeaderLabels(self.assignmentHeaderList)
self.assignmentTable.setAlternatingRowColors(True)
self.assignmentTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.assignmentTable.setSelectionBehavior(QAbstractItemView.SelectRows)
self.assignmentTable.setSelectionMode(QAbstractItemView.SingleSelection)
selected = None
## Add the assignments of the semester to the table
def updateTable(self, semester, current=None):
self.assignments = getAssignmentsFromDB(semester)
rows = len(self.assignments)
self.assignmentTable.setRowCount(rows)
for row in range(rows):
self.addAssignmentToTable(row)
self.assignmentTable.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.assignmentTable.sortItems(0, Qt.AscendingOrder)
## Add new assignment to Table
def addAssignmentToTable(self, row, assignment=None):
if assignment == None:
assignment = self.assignments[row]
status = QString(assignment.getStatus())
brush = self.makeBrush(status)
self.assignmentTable.setItem(row, 0, QTableWidgetItem(QString(assignment.getDate().toString("yyyy-MM-dd hh:mm, ddd"))))
self.assignmentTable.setItem(row, 1, QTableWidgetItem(QString(assignment.getCourse().getFull())))
self.assignmentTable.setItem(row, 2, QTableWidgetItem(QString("%i" % assignment.getNumber())))
self.assignmentTable.setItem(row, 3, QTableWidgetItem(QString("%s" % assignment.getDescription())))
statusItem = QTableWidgetItem(status)
statusItem.setBackground(brush)
self.assignmentTable.setItem(row, 4, statusItem)
## Set the right brush and color for the assignment, depending on level of completion
def makeBrush(self, status):
brush = QBrush(Qt.NoBrush)
if status.compare(QString(self.trUtf8("Available"))) == 0:
brush.setStyle(Qt.Dense7Pattern)
brush.setColor(QColor(Qt.cyan))
elif status.compare(QString(self.trUtf8("Begun"))) == 0:
brush.setStyle(Qt.Dense5Pattern)
brush.setColor(QColor(Qt.cyan))
elif status.compare(QString(self.trUtf8("Finished"))) == 0:
brush.setStyle(Qt.Dense3Pattern)
brush.setColor(QColor(Qt.cyan))
elif status.compare(QString(self.trUtf8("Delivered"))) == 0:
brush.setStyle(Qt.Dense1Pattern)
brush.setColor(QColor(Qt.cyan))
elif status.compare(QString(self.trUtf8("Approved"))) == 0:
brush.setStyle(Qt.SolidPattern)
brush.setColor(QColor(Qt.green))
elif status.compare(QString(self.trUtf8("Not approved"))) == 0:
brush.setStyle(Qt.SolidPattern)
brush.setColor(QColor(Qt.red))
else:
brush.setStyle(Qt.NoBrush)
return brush
### The Add Assignment dialog
class AssignmentDlg(QDialog):
## Initialize the Add Assignment dialog
def __init__(self, parent=None):
super(AssignmentDlg, self).__init__(parent)
# Labels
self.dateLabel = QLabel(self.trUtf8("&Date"))
self.courseLabel = QLabel(self.trUtf8("&Course"))
self.numberLabel = QLabel(self.trUtf8("&Number"))
self.descriptionLabel = QLabel(self.trUtf8("De&scription"))
self.statusLabel = QLabel(self.trUtf8("&Status"))
# Widgets
self.dateEdit = QLineEdit("DD.MM.YYYY HH:MM")
self.dateEdit.setSelection(0, 16)
self.courseEdit = QComboBox()
self.courseEdit.addItems(makeCoursesString())
self.numberEdit = QSpinBox()
self.numberEdit.setRange(1, 20)
self.descriptionEdit = QLineEdit()
self.statusEdit = QComboBox()
statusTypes = [self.trUtf8("Not available"), self.trUtf8("Available"), self.trUtf8("Begun"), self.trUtf8("Finished"), self.trUtf8("Delivered"), self.trUtf8("Approved"), self.trUtf8("Not approved")]
self.statusEdit.addItems(statusTypes)
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
# Buddies
self.dateLabel.setBuddy(self.dateEdit)
self.courseLabel.setBuddy(self.courseEdit)
self.numberLabel.setBuddy(self.numberEdit)
self.descriptionLabel.setBuddy(self.descriptionEdit)
self.statusLabel.setBuddy(self.statusEdit)
# Layout
self.layout = QGridLayout()
self.layout.addWidget(self.dateLabel, 0, 0)
self.layout.addWidget(self.courseLabel, 1, 0)
self.layout.addWidget(self.numberLabel, 2, 0)
self.layout.addWidget(self.descriptionLabel, 3, 0)
self.layout.addWidget(self.statusLabel, 4, 0)
self.layout.addWidget(self.dateEdit, 0, 1)
self.layout.addWidget(self.courseEdit, 1, 1)
self.layout.addWidget(self.numberEdit, 2, 1)
self.layout.addWidget(self.descriptionEdit, 3, 1)
self.layout.addWidget(self.statusEdit, 4, 1)
self.layout.addWidget(self.buttonBox, 5, 0, 1, 2)
self.setLayout(self.layout)
# Connect statements
self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
# Set the title
self.setWindowTitle(self.trUtf8("Add new assignment"))
## Return an array with the values of the widgets
def getValues(self):
assignment = []
assignment.append(unicode(self.dateEdit.text()))
assignment.append(unicode(self.courseEdit.currentText()))
assignment.append(self.numberEdit.value())
assignment.append(unicode(self.descriptionEdit.text()))
assignment.append(unicode(self.statusEdit.currentText()))
return assignment
## Accept the dialog and add the specified assignment
def accept(self):
assignmentList = self.getValues()
dateString = assignmentList[0]
courseFull = assignmentList[1]
number = assignmentList[2]
description = assignmentList[3]
status = assignmentList[4]
regex = QRegExp(r"[01-31].[01-12].[2000-2050] [00-23]:[00-60]")
validator = QRegExpValidator(regex, self)
valid = validator.validate(dateString, 16)
if valid == QValidator.Invalid:
regexMessage = QErrorMessage()
regexMessage.showMessage(QString(self.trUtf8("The date is not in a correct format.")))
if len(dateString) <= 11:
dateList = dateString.split('.')
timeList = ['00', '00']
else:
dateTime = dateString.split()
dateList = dateTime[0].split('.')
timeList = dateTime[1].split(':')
if dateList[1] > '13':
dateMessage = QErrorMessage()
elif dateList[0] > '31':
dateMessage = QErrorMessage()
dateMessage.showMessage(QString(self.trUtf8("The day is not valid. Please enter a valid date.")))
elif timeList[0] > '23':
dateMessage = QErrorMessage()
dateMessage.showMessage(QString(self.trUtf8("The hour is not valid. Please enter a valid time.")))
elif timeList[1] > '59':
dateMessage = QErrorMessage()
dateMessage.showMessage(QString(self.trUtf8("The minutes are not valid. Please enter a valid time.")))
else:
try:
date = QDate(string.atoi(dateList[2]), string.atoi(dateList[1]), string.atoi(dateList[0]))
time = QTime(string.atoi(timeList[0]), string.atoi(timeList[1]))
datetime = QDateTime(date, time)
except ValueError, e:
valueMessage = QErrorMessage()
valueMessage.showMessage(QString(self.trUtf8("The date is not valid. Please enter a date on the DD.MM.YYYY HH:MM form.")))
course = getCourseFromDB(getCourseCode(courseFull))
try:
global semester
addNewAssignmentToDB(semester, datetime, course, number, description, status)
assignment = AssignmentModel(datetime, course, number, description, status)
except UnboundLocalError, e:
pass
table = getMain().assignment.assignmentTable
row = table.rowCount()
table.insertRow(row)
getMain().assignment.addAssignmentToTable(row, assignment)
table.sortItems(0, Qt.AscendingOrder)
self.close()
### The assignment model
class AssignmentModel():
date = None
course = None
number = 0
description = ""
status = ""
## Initialize the assignment model
def __init__(self, date, course, number, description, status):
self.date = date
self.course = course
self.number = number
self.description = description
self.status = status
## Return the date the assignment is due
def getDate(self):
return self.date
## Return the course the assignment is given in
def getCourse(self):
return self.course
## Return the number of the assignment
def getNumber(self):
return self.number
## Return the description of the assignment
def getDescription(self):
return self.description
## Return the level of completion for the assignment
def getStatus(self):
return self.status
### The contents of the Reading tab
class ReadingTab(QWidget):
## Initialize the Reading tab
def __init__(self, parent=None):
super(ReadingTab, self).__init__(parent)
# Widgets
self.addReadingButton = QPushButton(self.trUtf8("Add pages to read"))
self.deleteReadingButton = QPushButton(self.trUtf8("Delete pages"))
self.readingDoneButton = QPushButton(self.trUtf8("Done"))
# Make the table
self.makeTable()
# Layout
self.vlayout = QVBoxLayout()
self.hlayout = QHBoxLayout()
self.hlayout.addWidget(self.addReadingButton)
self.hlayout.addWidget(self.deleteReadingButton)
self.hlayout.addWidget(self.readingDoneButton)
self.hlayout.addStretch()
self.vlayout.addWidget(self.readingTable)
self.vlayout.addLayout(self.hlayout)
self.setLayout(self.vlayout)
## Make an empty reading table
def makeTable(self, current=None):
self.readingTable = QTableWidget(0, 7, self)
self.readingTable.clear()
self.readingHeaderList = QStringList()
self.readingHeaderList.append(self.trUtf8("Week"))
self.readingHeaderList.append(self.trUtf8("Course"))
self.readingHeaderList.append(self.trUtf8("Book"))
self.readingHeaderList.append(self.trUtf8("Chapter"))
self.readingHeaderList.append(self.trUtf8("Pages"))
self.readingHeaderList.append(self.trUtf8("Number of pages"))
self.readingHeaderList.append(self.trUtf8("Done"))
self.readingTable.setHorizontalHeaderLabels(self.readingHeaderList)
self.readingTable.setAlternatingRowColors(True)
self.readingTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.readingTable.setSelectionBehavior(QAbstractItemView.SelectRows)
self.readingTable.setSelectionMode(QAbstractItemView.SingleSelection)
selected = None
## Add the readings of the semester to the table
def updateTable(self, semester):
self.readings = getReadingsFromDB(semester)
rows = len(self.readings)
self.readingTable.setRowCount(rows)
for row in range(rows):
self.addReadingToTable(row)
self.readingTable.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.readingTable.sortItems(0, Qt.AscendingOrder)
## Add a new reading to the table
def addReadingToTable(self, row, reading=None):
if reading == None:
reading = self.readings[row]
brush = QBrush(Qt.NoBrush)
brush.setStyle(Qt.SolidPattern)
if reading.getDone():
doneString = self.trUtf8("Done")
brush.setColor(Qt.green)
else:
doneString = self.trUtf8("Not done")
brush.setColor(Qt.red)
self.readingTable.setItem(row, 0, QTableWidgetItem(QString("%02s" % reading.getWeek())))
self.readingTable.setItem(row, 1, QTableWidgetItem(QString(reading.getCourse().getFull())))
self.readingTable.setItem(row, 2, QTableWidgetItem(QString(reading.getBook().getTitle())))
self.readingTable.setItem(row, 3, QTableWidgetItem(QString(reading.getChapter())))
self.readingTable.setItem(row, 4, QTableWidgetItem(QString(reading.getPages())))
self.readingTable.setItem(row, 5, QTableWidgetItem(QString("%i" % reading.getNumberOfPages())))
item = QTableWidgetItem(QString(doneString))
item.setBackground(brush)
self.readingTable.setItem(row, 6, item)
### The Add Reading dialog
class ReadingDlg(QDialog):
## Initialize the Add Reading dialog
def __init__(self, parent=None):
super(ReadingDlg, self).__init__(parent)
# Labels
self.weekLabel = QLabel(self.trUtf8("&Week"))
self.courseLabel = QLabel(self.trUtf8("&Course"))
self.bookLabel = QLabel(self.trUtf8("&Book"))
self.chapterLabel = QLabel(self.trUtf8("Cha&pter"))
self.pagesLabel = QLabel(self.trUtf8("&Pages"))
# Widgets
self.weekEdit = QSpinBox()
self.weekEdit.setRange(1, 52)
self.courseEdit = QComboBox()
coursesStringList = QStringList()
courses = makeCoursesString()
for course in courses:
coursesStringList.append(course)
self.courseEdit.addItems(coursesStringList)
self.bookEdit = QComboBox()
booksStringList = QStringList()
books = makeBooksString()
for book in books:
booksStringList.append(book)
self.bookEdit.addItems(booksStringList)
self.chapterEdit = QLineEdit()
self.pagesEdit = QLineEdit()
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
# Buddies
self.weekLabel.setBuddy(self.weekEdit)
self.courseLabel.setBuddy(self.courseEdit)
self.bookLabel.setBuddy(self.bookEdit)
self.chapterLabel.setBuddy(self.chapterEdit)
self.pagesLabel.setBuddy(self.pagesEdit)
# Layout
self.layout = QGridLayout()
self.layout.addWidget(self.weekLabel, 0, 0)
self.layout.addWidget(self.courseLabel, 1, 0)
self.layout.addWidget(self.bookLabel, 2, 0)
self.layout.addWidget(self.chapterLabel, 3, 0)
self.layout.addWidget(self.pagesLabel, 4, 0)
self.layout.addWidget(self.weekEdit, 0, 1)
self.layout.addWidget(self.courseEdit, 1, 1)
self.layout.addWidget(self.bookEdit, 2, 1)
self.layout.addWidget(self.chapterEdit, 3, 1)
self.layout.addWidget(self.pagesEdit, 4, 1)
self.layout.addWidget(self.buttonBox, 5, 0, 1, 2)
self.setLayout(self.layout)
# Connect statements
self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
# Set the title
self.setWindowTitle(self.trUtf8("Add new reading"))
## Accept the dialog and add the specified reading
def accept(self):
week = unicode(self.weekEdit.value())
courseFull = unicode(self.courseEdit.currentText())
bookTitle = unicode(self.bookEdit.currentText())
chapter = unicode(self.chapterEdit.text())
pages = unicode(self.pagesEdit.text())
self.close()
course = getCourseFromDB(getCourseCode(courseFull))
book = getBookWithTitleFromDB(bookTitle)
global semester
addNewReadingToDB(semester, week, course, book, chapter, pages, False)
reading = ReadingModel(week, course, book, chapter, pages, False)
table = getMain().reading.readingTable
row = table.rowCount()
table.insertRow(row)
getMain().reading.addReadingToTable(row, reading)
table.sortItems(0, Qt.AscendingOrder)
### The reading model
class ReadingModel():
week = 0
course = None
book = None
chapter = ""
pages = ""
numberOfPages = 0
done = False
## Initialize the reading model
def __init__(self, week, course, book, chapter, pages, done=False):
self.week = week
self.course = course
self.book = book
self.chapter = chapter
self.pages = pages
self.numberOfPages = self.getNumberOfPages()
self.done = done
## Return the week the reading shall be done
def getWeek(self):
return self.week
## Return the course the reading is in
def getCourse(self):
return self.course
## Return the book to be read in
def getBook(self):
return self.book
## Return the chapter to be read
def getChapter(self):
return self.chapter
## Return the pages to be read
def getPages(self):
return self.pages
## Return the number of pages to be read
def getNumberOfPages(self):
pages = self.getPages()
pagesArray = pages.split(",")
nextArray = []
sum = 0
for p in pagesArray:
p.strip()
nextArray.append(p.split("-"))
for n in nextArray:
sum += int(n[1]) - int(n[0]) + 1
return sum
## Return whether the reading has been done or not
def getDone(self):
return self.done
### The contents of the Schedule tab
class ScheduleTab(QWidget):
## Initialize the Schedule tab
def __init__(self, parent=None):
super(ScheduleTab, self).__init__(parent)
# Widgets
self.addScheduleButton = QPushButton("Add lesson")
self.deleteScheduleButton = QPushButton("Delete lesson")
# Make the table
self.makeTable()
# Layout
self.vlayout = QVBoxLayout()
self.hlayout = QHBoxLayout()
self.hlayout.addWidget(self.addScheduleButton)
self.hlayout.addWidget(self.deleteScheduleButton)
self.hlayout.addStretch()
self.vlayout.addWidget(self.scheduleTable)
self.vlayout.addLayout(self.hlayout)
self.setLayout(self.vlayout)
## Make an empty schedule table
def makeTable(self, current=None):
self.scheduleTable = QTableWidget(12, 5, self)
self.scheduleTable.setRowCount(12)
self.scheduleTable.clear()
self.updateHeaders()
self.scheduleTable.setAlternatingRowColors(False)
self.scheduleTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.scheduleTable.setSelectionBehavior(QAbstractItemView.SelectItems)
self.scheduleTable.setSelectionMode(QAbstractItemView.SingleSelection)
selected = None
def updateHeaders(self):
self.scheduleHorizontalHeaderList = QStringList()
self.scheduleHorizontalHeaderList.append(self.trUtf8("Monday"))
self.scheduleHorizontalHeaderList.append(self.trUtf8("Tuesday"))
self.scheduleHorizontalHeaderList.append(self.trUtf8("Wednesday"))
self.scheduleHorizontalHeaderList.append(self.trUtf8("Thursday"))
self.scheduleHorizontalHeaderList.append(self.trUtf8("Friday"))
self.scheduleVerticalHeaderList = QStringList()
for i in range(8, 20):
self.scheduleVerticalHeaderList.append(self.trUtf8("%i" % i))
self.scheduleTable.setHorizontalHeaderLabels(self.scheduleHorizontalHeaderList)
self.scheduleTable.setVerticalHeaderLabels(self.scheduleVerticalHeaderList)
## Add the lessons of the semester to the table
def updateTable(self, semester):
self.schedule = getLessonsFromDB(semester)
rows = len(self.schedule)
self.scheduleTable.clear()
for l in range(rows):
self.addLessonToTable(self.schedule[l])
self.scheduleTable.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.scheduleTable.verticalHeader().setResizeMode(QHeaderView.ResizeToContents)
self.updateHeaders()
## Add a new lesson to the table
def addLessonToTable(self, lesson):
row = lesson.getTime() - 8
column = self.getColumn(lesson.getDay())
code = lesson.getCourse().getCode()
title = lesson.getCourse().getTitle()
type = lesson.getType()
room = lesson.getRoom()
olditem = self.scheduleTable.item(row, column)
newtext = "%s\n%s\n%s\n%s" % (code, title, type, room)
if olditem:
oldtext = olditem.text()
text = QString(oldtext + "\n" + newtext)
collision = True
else:
text = QString(newtext)
collision = False
item = QTableWidgetItem(text)
item.setBackground(self.getBackground(QString("%s" % type), lesson.getCourse(), collision))
self.scheduleTable.setItem(row, column, item)
## Return the column specified by the day
def getColumn(self, dayString):
day = QString("%s" % dayString)
if day.compare(QString(self.trUtf8("Monday"))) == 0:
return 0
elif day.compare(QString(self.trUtf8("Tuesday"))) == 0:
return 1
elif day.compare(QString(self.trUtf8("Wednesday"))) == 0:
return 2
elif day.compare(QString(self.trUtf8("Thursday"))) == 0:
return 3
elif day.compare(QString(self.trUtf8("Friday"))) == 0:
return 4
else:
return -1
## Set the right brush and color for the lesson, depending on type of lesson
def getBackground(self, type, course, collision):
if type.compare(QString(self.trUtf8("Lecture"))) == 0:
brush = QBrush(Qt.SolidPattern)
elif type.compare(QString(self.trUtf8("Assignment lecture"))) == 0:
brush = QBrush(Qt.Dense2Pattern)
elif type.compare(QString(self.trUtf8("Assignment help"))) == 0:
brush = QBrush(Qt.Dense3Pattern)
elif type.compare(QString(self.trUtf8("Lab"))) == 0:
brush = QBrush(Qt.Dense1Pattern)
elif type.compare(QString(self.trUtf8("Seminar"))) == 0:
brush = QBrush(Qt.Dense4Pattern)
elif type.compare(QString(self.trUtf8("Other"))) == 0:
brush = QBrush(Qt.Dense5Pattern)
else:
brush = QBrush(Qt.NoBrush)
if not collision:
brush.setColor(course.getColor())
else:
brush.setColor(Qt.red)
return brush
### The Add Lesson dialog
class ScheduleDlg(QDialog):
## Initialize the Add Lesson dialog
def __init__(self, parent=None):
super(ScheduleDlg, self).__init__(parent)
# Labels
self.dayLabel = QLabel(self.trUtf8("&Day"))
self.fromLabel = QLabel(self.trUtf8("&From"))
self.toLabel = QLabel(self.trUtf8("&To"))
self.courseLabel = QLabel(self.trUtf8("&Course"))
self.typeLabel = QLabel(self.trUtf8("Ty&pe"))
self.roomLabel = QLabel(self.trUtf8("&Room"))
# Widgets
self.dayEdit = QComboBox()
self.dayEdit.addItems(getMain().days)
self.fromEdit = QSpinBox()
self.fromEdit.setRange(08.15, 18.15)
self.fromEdit.setSingleStep(01.00)
self.toEdit = QSpinBox()
self.toEdit.setRange(09.00, 19.00)
self.toEdit.setSingleStep(01.00)
self.courseEdit = QComboBox()
courses = makeCoursesString()
coursesStringList = QStringList()
for course in courses:
coursesStringList.append(course)
self.courseEdit.addItems(coursesStringList)
self.typeEdit = QComboBox()
types = [self.trUtf8("Lecture"), self.trUtf8("Assignment lecture"), self.trUtf8("Assignment help"), self.trUtf8("Lab"), self.trUtf8("Seminar"), self.trUtf8("Other")]
self.typeEdit.addItems(types)
self.roomEdit = QLineEdit()
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
# Buddies
self.dayLabel.setBuddy(self.dayEdit)
self.fromLabel.setBuddy(self.fromEdit)
self.toLabel.setBuddy(self.toEdit)
self.courseLabel.setBuddy(self.courseEdit)
self.typeLabel.setBuddy(self.typeEdit)
self.roomLabel.setBuddy(self.roomEdit)
# Layout
self.layout = QGridLayout()
self.layout.addWidget(self.dayLabel, 0, 0)
self.layout.addWidget(self.fromLabel, 1, 0)
self.layout.addWidget(self.toLabel, 2, 0)
self.layout.addWidget(self.courseLabel, 3, 0)
self.layout.addWidget(self.typeLabel, 4, 0)
self.layout.addWidget(self.roomLabel, 5, 0)
self.layout.addWidget(self.dayEdit, 0, 1)
self.layout.addWidget(self.fromEdit, 1, 1)
self.layout.addWidget(self.toEdit, 2, 1)
self.layout.addWidget(self.courseEdit, 3, 1)
self.layout.addWidget(self.typeEdit, 4, 1)
self.layout.addWidget(self.roomEdit, 5, 1)
self.layout.addWidget(self.buttonBox, 6, 0, 1, 2)
self.setLayout(self.layout)
# Connect statements
self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
# Set the title
self.setWindowTitle(self.trUtf8("Add new lesson"))
## Accept the dialog and add the specified lesson
def accept(self):
day = unicode(self.dayEdit.currentText())
fromtime = self.fromEdit.value()
totime = self.toEdit.value()
courseFull = unicode(self.courseEdit.currentText())
type = unicode(self.typeEdit.currentText())
room = unicode(self.roomEdit.text())
course = getCourseFromDB(getCourseCode(courseFull))
global semester
for t in range(fromtime, totime):
addNewLessonToDB(semester, day, t, course, type, room)
getMain().schedule.addLessonToTable(ScheduleModel(day, t, course, type, room))
self.close()
### The schedule model
class ScheduleModel():
day = ""
time = 0
course = None
type = ""
room = ""
## Initialize the schedule model
def __init__(self, day, time, course, type, room):
self.day = day
self.time = time
self.course = course
self.type = type
self.room = room
## Return the day of the lesson
def getDay(self):
return self.day
## Return the start time of the lesson
def getTime(self):
return self.time
## Return the course of the lesson
def getCourse(self):
return self.course
## Return the type of the lesson
def getType(self):
return self.type
## Return the room the lesson is in
def getRoom(self):
return self.room
### The Add Course dialog
class CourseDlg(QDialog):
## Initialize the Add Course dialog
def __init__(self, parent=None):
super(CourseDlg, self).__init__(parent)
# The books
self.books = []
# Labels
self.codeLabel = QLabel(self.trUtf8("&Code"))
self.titleLabel = QLabel(self.trUtf8("&Title"))
self.shortLabel = QLabel(self.trUtf8("&Short form"))
self.booksLabel = QLabel(self.trUtf8("&Books"))
# Widgets
self.codeEdit = QLineEdit()
self.titleEdit = QLineEdit()
self.shortEdit = QLineEdit()
self.booksEdit = QListWidget()
self.updateList()
self.booksEdit.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.newBook = QPushButton("Add new book")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
# Buddies
self.codeLabel.setBuddy(self.codeEdit)
self.titleLabel.setBuddy(self.titleEdit)
self.shortLabel.setBuddy(self.shortEdit)
self.booksLabel.setBuddy(self.booksEdit)
# Layout
self.layout = QGridLayout()
self.layout.addWidget(self.codeLabel, 0, 0)
self.layout.addWidget(self.titleLabel, 1, 0)
self.layout.addWidget(self.shortLabel, 2, 0)
self.layout.addWidget(self.booksLabel, 3, 0)
self.layout.addWidget(self.codeEdit, 0, 1)
self.layout.addWidget(self.titleEdit, 1, 1)
self.layout.addWidget(self.shortEdit, 2, 1)
self.layout.addWidget(self.booksEdit, 3, 1)
self.layout.addWidget(self.newBook, 4, 0)
self.layout.addWidget(self.buttonBox, 4, 1, 1, 2)
self.setLayout(self.layout)
# Connect statements
self.connect(self.newBook, SIGNAL("pressed()"), getMain().addBook)
self.connect(getMain(), SIGNAL("newBook"), self.updateList)
self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
# Set the title
self.setWindowTitle(self.trUtf8("Add new course"))
## Update the book list
def updateList(self):
self.booksEdit.clear()
booksDB = getBooksFromDB()
booksStringList = QStringList()
for book in booksDB:
booksStringList.append(book.getAuthor() + u" : " + book.getTitle() + u", " + str(book.getEdition()) + self.trUtf8(". edition"))
self.booksEdit.addItems(booksStringList)
self.booksEdit.sortItems()
## Add a new book to the course
def addNewBookToCourse(self):
book = getBookWithTitleFromDB(booktitle)
self.books.append(book)
## Accept the dialog and add the specified course
def accept(self):
courseCode = unicode(self.codeEdit.text())
courseTitle = unicode(self.titleEdit.text())
courseShort = unicode(self.shortEdit.text())
courseBooks = self.booksEdit.selectedItems()
color = getRandomColor()
global colors
while color in colors:
color = getRandomColor()
colors.append(color)
books = []
for book in courseBooks:
books.append(getBookWithTitleFromDB("%s" % book.text()))
course = CourseModel(courseCode, courseTitle, courseShort, color, books)
addNewCourseToDB(courseCode, courseTitle, courseShort, color, books)
self.close()
### The course model
class CourseModel():
code = ""
title = ""
short = ""
full = ""
books = []
## Initialize the course model
def __init__(self, code, title, short, color, books):
self.code = code
self.title = title
self.short = short
self.setFull(code, title)
self.color = color
self.books = books
## Return the code of the course
def getCode(self):
return self.code
## Return the title of the course
def getTitle(self):
return self.title
## Return the short form of the course
def getShort(self):
return self.short
## Set the full form of the course
def setFull(self, code, title):
self.full = code + ' ' + title
## Return the full form of the course
def getFull(self):
return self.full
## Return the color of the course
def getColor(self):
return self.color
## Add a book to the course
def addBook(self, book):
books.append(book)
## Return the books of the course
def getBooks(self):
return self.books
### The Add Book dialog
class BookDlg(QDialog):
## Initialize the Add Book dialog
def __init__(self, parent=None):
super(BookDlg, self).__init__(parent)
# Labels
self.titleLabel = QLabel(self.trUtf8("&Title"))
self.authorLabel = QLabel(self.trUtf8("&Author"))
self.editionLabel = QLabel(self.trUtf8("&Edition"))
self.isbnLabel = QLabel(self.trUtf8("&ISBN"))
# Widgets
self.titleEdit = QLineEdit()
self.authorEdit = QLineEdit()
self.editionEdit = QSpinBox()
self.editionEdit.setRange(1, 50)
self.isbnEdit = QLineEdit()
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
# Buddies
self.titleLabel.setBuddy(self.titleEdit)
self.authorLabel.setBuddy(self.authorEdit)
self.editionLabel.setBuddy(self.editionEdit)
self.isbnLabel.setBuddy(self.isbnEdit)
# Layout
self.layout = QGridLayout()
self.layout.addWidget(self.titleLabel, 0, 0)
self.layout.addWidget(self.authorLabel, 1, 0)
self.layout.addWidget(self.editionLabel, 2, 0)
self.layout.addWidget(self.isbnLabel, 3, 0)
self.layout.addWidget(self.titleEdit, 0, 1)
self.layout.addWidget(self.authorEdit, 1, 1)
self.layout.addWidget(self.editionEdit, 2, 1)
self.layout.addWidget(self.isbnEdit, 3, 1)
self.layout.addWidget(self.buttonBox, 4, 0, 1, 2)
self.setLayout(self.layout)
# Connect statements
self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))
# Set the title
self.setWindowTitle(self.trUtf8("Add new book"))
# Accept the dialog and add the specified book
def accept(self):
bookTitle = unicode(self.titleEdit.text())
bookAuthor = unicode(self.authorEdit.text())
bookEdition = self.editionEdit.value()
bookIsbn = unicode(self.isbnEdit.text())
addNewBookToDB(bookIsbn, bookTitle, bookAuthor, bookEdition)
getMain().emit(SIGNAL("newBook"))
self.close()
### The book model
class BookModel():
title = ""
author = ""
edition = 0
isbn = ""
## Initialize the book model
def __init__(self, isbn, title, author, edition):
self.isbn = isbn
self.title = title
self.author = author
self.edition = edition
# Return the ISBN number of the book
def getIsbn(self):
return self.isbn
# Return the title of the book
def getTitle(self):
return self.title
# Return the author(s) of the book
def getAuthor(self):
return self.author
# Return the edition of the book
def getEdition(self):
return self.edition
# Database
# Initialization
## Connect to the database and return the cursor and connection
def initDB():
if 'HOME' in os.environ:
home = os.environ['HOME']
else:
home = ""
path = home+"/.egon/egon.db"
conn = sqlite.connect(path)
cursor = conn.cursor()
cursor.execute('''
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name
''')
if cursor.fetchall() == []:
initSemesterDB(cursor)
initAssignmentDB(cursor)
initReadingDB(cursor)
initScheduleDB(cursor)
initBookDB(cursor)
initCourseDB(cursor)
initCourseUsesBook(cursor)
return cursor, conn
exitDB(conn)
# Create the database
## Create the Semester table
def initSemesterDB(cursor):
cursor.execute('''
CREATE TABLE Semester (
term TEXT,
year INT,
PRIMARY KEY (term, year)
)
''')
## Create the Assignment table
def initAssignmentDB(cursor):
cursor.execute('''
CREATE TABLE Assignment (
date DATETIME,
course TEXT,
number INT,
description TEXT,
status TEXT,
term TEXT,
year INT,
PRIMARY KEY (course, number)
)
''')
## Create the Reading table
def initReadingDB(cursor):
cursor.execute('''
CREATE TABLE Reading (
week INT,
course TEXT,
book INT,
chapter TEXT,
pages TEXT,
done BOOLEAN,
term TEXT,
year INT,
PRIMARY KEY (week, course, book, chapter)
)
''')
## Create the Lesson table
def initScheduleDB(cursor):
cursor.execute('''
CREATE TABLE Lesson (
day TEXT,
time INT,
course TEXT,
type TEXT,
room TEXT,
term TEXT,
year INT,
PRIMARY KEY (course, day, time)
)
''')
## Create the Course table
def initCourseDB(cursor):
cursor.execute('''
CREATE TABLE Course (
code TEXT PRIMARY KEY,
title TEXT,
short TEXT,
red INT,
green INT,
blue INT
)
''')
## Create the Book table
def initBookDB(cursor):
cursor.execute('''
CREATE TABLE Book (
isbn TEXT PRIMARY KEY,
title TEXT,
author TEXT,
edition INTEGER
)
''')
## Create the Course-Book relation
def initCourseUsesBook(cursor):
cursor.execute('''
CREATE TABLE CourseUsesBook (
courseCode TEXT,
bookIsbn TEXT,
PRIMARY KEY (courseCode, bookIsbn)
)
''')
# Add things to the database
## Add new semester to the database
def addNewSemesterToDB(term, year):
cursor, conn = initDB()
cursor.execute('''
INSERT INTO Semester (term, year)
VALUES (?, ?)
''', (term, year))
exitDB(conn)
## Add new assignment to the database
def addNewAssignmentToDB(semester, datetime, course, number, description, status):
cursor, conn = initDB()
day = datetime.date().day()
month = datetime.date().month()
year = datetime.date().year()
hour = datetime.time().hour()
minute = datetime.time().minute()
timestring = "%02i-%02i-%02i %02i:%02i" % (year, month, day, hour, minute)
term = "%s" % semester.getTerm()
year = semester.getYear()
cursor.execute('''
INSERT INTO Assignment (date, course, number, description, status, term, year)
VALUES (datetime(?), ?, ?, ?, ?, ?, ?)
''', (timestring, course.getCode(), number, description, status, term, year))
exitDB(conn)
## Add new reading to the database
def addNewReadingToDB(semester, week, course, book, chapter, pages, done):
cursor, conn = initDB()
term = "%s" % semester.getTerm()
year = semester.getYear()
cursor.execute('''
INSERT INTO Reading (week, course, book, chapter, pages, done, term, year)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''', (week, course.getCode(), book.getIsbn(), chapter, pages, done, term, year))
exitDB(conn)
## Add new lesson to the database
def addNewLessonToDB(semester, day, time, course, type, room):
cursor, conn = initDB()
term = "%s" % semester.getTerm()
year = semester.getYear()
cursor.execute('''
INSERT INTO Lesson (day, time, course, type, room, term, year)
VALUES (?, ?, ?, ?, ?, ?, ?)
''', (day, time, course.getCode(), type, room, term, year))
exitDB(conn)
## Add new course to the database
def addNewCourseToDB(code, title, short, color, books):
cursor, conn = initDB()
red = color.red()
green = color.green()
blue = color.blue()
cursor.execute('''
INSERT INTO Course (code, title, short, red, green, blue)
VALUES (?, ?, ?, ?, ?, ?)
''', (code, title, short, red, green, blue))
for book in books:
cursor.execute('''
INSERT INTO CourseUsesBook (courseCode, bookIsbn)
VALUES (?, ?)
''', (code, book))
exitDB(conn)
## Add new book to the database
def addNewBookToDB(isbn, title, author, edition):
cursor, conn = initDB()
cursor.execute('''
INSERT INTO Book
VALUES (?, ?, ?, ?)
''', (isbn, title, author, edition))
exitDB(conn)
# Get things from the database
## Get all the semesters form the database
def getSemestersFromDB():
cursor, conn = initDB()
cursor.execute('''
SELECT *
FROM Semester
''')
semesters = []
for row in cursor.fetchall():
semesters.append(SemesterModel(row[0], row[1]))
exitDB(conn)
return semesters
## Get the assignments of the specified semester from the database
def getAssignmentsFromDB(semester):
cursor, conn = initDB()
term = "%s" % semester.getTerm()
year = (semester.getYear())
cursor.execute('''
SELECT *
FROM Assignment
WHERE term = ?
AND year = ?
''', (term, year))
assignments = []
for row in cursor.fetchall():
assignments.append(AssignmentModel(getQDateTime(row[0]), getCourseFromDB(row[1]), row[2], row[3], row[4]))
exitDB(conn)
return assignments
## Get the readings of the specified semester from the database
def getReadingsFromDB(semester):
cursor, conn = initDB()
term = "%s" % semester.getTerm()
year = semester.getYear()
cursor.execute('''
SELECT *
FROM Reading
WHERE term = ?
AND year = ?
''', (term, year))
readings = []
for row in cursor.fetchall():
readings.append(ReadingModel(row[0], getCourseFromDB(row[1]), getBookFromDB(row[2]), row[3], row[4], row[5]))
exitDB(conn)
return readings
## Get the lessons of the specified semester from the database
def getLessonsFromDB(semester):
cursor, conn = initDB()
term = "%s" % semester.getTerm()
year = semester.getYear()
cursor.execute('''
SELECT *
FROM Lesson
WHERE term = ?
AND year = ?
''', (term, year))
lessons = []
for row in cursor.fetchall():
lessons.append(ScheduleModel(row[0], row[1], getCourseFromDB(row[2]), row[3], row[4]))
exitDB(conn)
return lessons
## Get all the courses from the database
def getCoursesFromDB():
cursor, conn = initDB()
cursor.execute('''
SELECT *
FROM Course
''')
courses = []
for row in cursor.fetchall():
courses.append(CourseModel(row[0], row[1], row[2], QColor(row[3], row[4], row[5]), []))
for course in courses:
cursor.execute('''
SELECT bookIsbn
FROM CourseUsesBook
WHERE courseCode = ?
''', (course.getCode(),))
fetched = cursor.fetchall()
for fetchedRow in fetched:
cursor.execute('''
SELECT *
FROM Book
WHERE isbn = ?
''', (fetchedRow[0],))
for row in cursor:
course.addBook(BookModel(row[0], row[1], row[2], row[3]))
return courses
## Get the course specified by the course code from the database
def getCourseFromDB(courseCode):
cursor, conn = initDB()
cursor.execute('''
SELECT *
FROM Course
WHERE code = ?
''', (courseCode,))
course = None
for row in cursor.fetchall():
course = CourseModel(row[0], row[1], row[2], QColor(row[3], row[4], row[5]), [])
cursor.execute('''
SELECT bookIsbn
FROM CourseUsesBook
WHERE courseCode = ?
''', (courseCode,))
fetched = cursor.fetchall()
for fetchedRow in fetched:
cursor.execute('''
SELECT *
FROM Book
WHERE isbn = ?
''', (fetchedRow[0],))
for row in cursor:
course.addBook(BookModel(row[0], row[1], row[2], row[3]))
exitDB(conn)
return course
## Get all the books from the database
def getBooksFromDB():
cursor, conn = initDB()
cursor.execute('''
SELECT *
FROM Book
''')
books = []
for row in cursor.fetchall():
books.append(BookModel(row[0], row[1], row[2], row[3]))
exitDB(conn)
return books
## Get the book specified by the ISBN number from the database
def getBookFromDB(isbn):
cursor, conn = initDB()
cursor.execute('''
SELECT *
FROM Book
WHERE isbn = ?
''', (isbn,))
for row in cursor.fetchall():
book = BookModel(row[0], row[1], row[2], row[3])
exitDB(conn)
return book
## Get the book specified by the title from the database
def getBookWithTitleFromDB(booktitle):
cursor, conn = initDB()
book = "%s" % booktitle
cursor.execute('''
SELECT *
FROM Book
WHERE title = ?
''', (book,))
for row in cursor.fetchall():
book = BookModel(row[0], row[1], row[2], row[3])
exitDB(conn)
return book
# Update things in the database
## Update the completion level of the specified assignment
def updateAssignmentCompletion(coursecode, num, completion):
cursor, conn = initDB()
status = "%s" % completion
course = "%s" % coursecode
number = (num.toInt())[0]
cursor.execute('''
UPDATE Assignment
SET complete = ?
WHERE course = ?
AND number = ?
''', (status, course, number))
exitDB(conn)
## Update whether the specified reading is done or not
def updateReadingDone(week, coursecode, bookisbn, chapter, done):
cursor, conn = initDB()
course = "%s" % coursecode
book = "%s" % bookisbn
ch = "%s" % chapter
cursor.execute('''
UPDATE Reading
SET done = ?
WHERE week = ?
AND course = ?
AND book = ?
AND chapter = ?
''', (done, week, course, book, ch))
exitDB(conn)
# Remove things from the database
## Remove the specified assignment from the database
def removeAssignmentFromDB(coursecode, num):
cursor, conn = initDB()
course = "%s" % coursecode
number = (num.toInt())[0]
cursor.execute('''
DELETE
FROM Assignment
WHERE course = ?
AND number = ?
''', (course, number))
exitDB(conn)
## Remove the specified reading from the database
def removeReadingFromDB(week, coursecode, bookisbn, chapter):
cursor, conn = initDB()
course = "%s" % coursecode
book = "%s" % bookisbn
ch = "%s" % chapter
cursor.execute('''
DELETE
FROM Reading
WHERE week = ?
AND course = ?
AND book = ?
AND chapter = ?
''', (week, course, book, ch))
exitDB(conn)
## Remove the specified lesson from the database
def removeLessonFromDB(daystring, coursecode, fromTime):
cursor, conn = initDB()
day = "%s" % daystring
course = "%s" % coursecode
time = "%s" % fromTime
cursor.execute('''
DELETE
FROM Lesson
WHERE day = ?
AND course = ?
AND time = ?
''', (day, course, time))
exitDB(conn)
# Exit the database
## Commit and close the connection
def exitDB(conn):
conn.commit()
conn.close()
# Course
## Get the course code from the full name of the course
def getCourseCode(courseFull):
course = courseFull.split(' ')
return course[0]
## Add a new course to the list of courses
def addNewCourse(course):
courses.append(course)
addNewCourseToDB(course.getCode(), course.getTitle(), course.getShort(), course.getColor(), course.getBooks())
addNewCourseString(course)
## Return the list of courses
def getCourses():
global courses
return courses
## Add the course as a course string
def addNewCourseString(course):
global coursesString
coursesString.append(course.getFull())
## Make the courses string list and return it
def makeCoursesString():
emptyCourses()
cs = getCoursesFromDB()
if cs:
for c in cs:
addNewCourseString(c)
s = getCoursesString()
return s
## Return the courses string list
def getCoursesString():
global coursesString
return coursesString
## Empty the courses list and the courses string list
def emptyCourses():
global courses
global coursesString
courses = []
coursesString = []
# Book
## Add a new book to the list of books
def addNewBook(book):
books.append(book)
addNewBookToDB(book.getISBN(), book.getTitle(), book.getAuthor(), book.getEdition(), book.getCourse())
addNewBookString(book)
## Return the list of books
def getBooks():
global books
return books
## Add the book as a book string
def addNewBookString(book):
global booksString
booksString.append(book.getTitle())
## Make the books string list and return it
def makeBooksString():
emptyBooks()
bs = getBooksFromDB()
if bs:
for b in bs:
addNewBookString(b)
s = getBooksString()
return s
## Return the books string list
def getBooksString():
global booksString
return booksString
## Empty the books list and the books string list
def emptyBooks():
global books
global booksString
books = []
booksString = []
# Color
## Return a random color, RGB
def getRandomColor():
return QColor(getRandomColorPart(), getRandomColorPart(), getRandomColorPart())
## Return a random number between 0 and 255
def getRandomColorPart():
return random.random()*256
# General
## Convert a SQL timestamp to a QDateTime object
def getQDateTime(timestamp):
if not timestamp:
return None
datetimeList = timestamp.split()
dateString = datetimeList[0]
timeString = datetimeList[1]
dateList = dateString.split('-')
timeList = timeString.split(':')
year = string.atoi(dateList[0])
month = string.atoi(dateList[1])
day = string.atoi(dateList[2])
hour = string.atoi(timeList[0])
minute = string.atoi(timeList[1])
date = QDate(year, month, day)
time = QTime(hour, minute)
datetime = QDateTime(date, time)
return datetime
## Return the main window
def getMain():
global main
return main
## Run the program
def main():
app = QApplication(sys.argv)
locale = QLocale.system().name()
qtTranslator = QTranslator()
if qtTranslator.load("qt_" + locale, ":/"):
app.installTranslator(qtTranslator)
appTranslator = QTranslator()
if appTranslator.load("imagechanger_" + locale, ":/"):
app.installTranslator(appTranslator)
form = MainWindow()
app.setOrganizationName("PVV")
app.setOrganizationDomain("pvv.ntnu.no")
app.setApplicationName(form.title)
form.show()
app.exec_()
main()
#initNewDB()