#!/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 . 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__ = "0.9.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 = "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, "&Assignments") self.tabs.addTab(self.reading, "&Reading List") self.tabs.addTab(self.schedule, "&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("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("&New", self.fileNew, QKeySequence.New, "filenew", "Create a new semester plan") fileOpenAction = self.createAction("&Open", self.fileOpen, QKeySequence.Open, "fileopen", "Open an existing semester plan") fileQuitAction = self.createAction("&Quit", self.close, "Ctrl+Q", "filequit", "Quit program") editAddCourse = self.createAction("Add &course", self.addCourse, "Ctrl+C", None, "Add a new course") editAddBook = self.createAction("Add &book", self.addBook, "Ctrl+B", None, "Add a new book") editAddAssignment = self.createAction("Add &assignment", self.addAssignment, "Ctrl+A", None, "Add a new assignment") editAddReading = self.createAction("Add &reading", self.addReading, "Ctrl+R", None, "Add a new reading") editAddLesson = self.createAction("Add &lesson", self.addLesson, "Ctrl+L", None, "Add a new lesson") editShowCalendar = self.createAction("Cal&endar", self.showCalendar, "Ctrl+E", None, "Show the calendar") helpAboutScheduler = self.createAction("&About %s" % self.title) # Menus self.fileMenu = self.menuBar().addMenu("&File") self.editMenu = self.menuBar().addMenu("&Edit") self.helpMenu = self.menuBar().addMenu("&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.completeAssignmentBox, SIGNAL("currentIndexChanged(QString)"), self.completeAssignment) 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("File") fileToolbar.setObjectName("FileToolBar") self.addActions(fileToolbar, (fileNewAction, fileOpenAction, None, fileQuitAction)) editToolbar = self.addToolBar("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 completeAssignment(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 = self.getWeekCourseAndBook() table, row = self.getReadingTableAndRow() global semester removeReadingFromDB(week, course, book) 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 = False 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() updateReadingDone(week, courseCode, bookIsbn, True) ## 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 getWeekCourseAndBook(self): table, row = self.getReadingTableAndRow() weekItem = table.item(row, 0) courseItem = table.item(row, 1) bookItem = table.item(row, 2) week = (weekItem.text().toInt())[0] courseFull = courseItem.text() courseCode = getCourseCode(courseFull) book = getBookWithTitleFromDB(bookItem.text()) return week, courseCode, book.getIsbn() # 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 dialog def helpAbout(self): QMessageBox.about(self, "About %s" % self.title, u""" %s v %s

Copyright © 2008 Tiril Anette Langfeldt Rødland. No rights reserved.

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

This application is mainly for use by students, and can be used to keep track of assignments, planned readings and the schedule.

Python %s - Qt %s - PyQt %s on %s

Developer: Tiril Anette Langfeldt Rødland, 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("Term")) 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.completeAssignmentBox = QComboBox() self.deleteAssignmentButton = QPushButton("Delete assignment") completeTypes = [self.trUtf8("Not available"), self.trUtf8("Available"), self.trUtf8("Begun"), self.trUtf8("Finished"), self.trUtf8("Delivered"), self.trUtf8("Approved"), self.trUtf8("Not approved")] self.completeAssignmentBox.addItems(completeTypes) # 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.completeAssignmentBox) 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("Complete")) 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] complete = QString(assignment.getComplete()) brush = self.makeBrush(complete) 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()))) completeItem = QTableWidgetItem(complete) completeItem.setBackground(brush) self.assignmentTable.setItem(row, 4, completeItem) ## Set the right brush and color for the assignment, depending on level of completion def makeBrush(self, complete): brush = QBrush(Qt.NoBrush) if complete.compare(QString(self.trUtf8("Available"))) == 0: brush.setStyle(Qt.Dense7Pattern) brush.setColor(QColor(Qt.cyan)) elif complete.compare(QString(self.trUtf8("Begun"))) == 0: brush.setStyle(Qt.Dense5Pattern) brush.setColor(QColor(Qt.cyan)) elif complete.compare(QString(self.trUtf8("Finished"))) == 0: brush.setStyle(Qt.Dense3Pattern) brush.setColor(QColor(Qt.cyan)) elif complete.compare(QString(self.trUtf8("Delivered"))) == 0: brush.setStyle(Qt.Dense1Pattern) brush.setColor(QColor(Qt.cyan)) elif complete.compare(QString(self.trUtf8("Approved"))) == 0: brush.setStyle(Qt.SolidPattern) brush.setColor(QColor(Qt.green)) elif complete.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.completeLabel = QLabel(self.trUtf8("&Complete")) # 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.completeEdit = QComboBox() completeTypes = [self.trUtf8("Not available"), self.trUtf8("Available"), self.trUtf8("Begun"), self.trUtf8("Finished"), self.trUtf8("Delivered"), self.trUtf8("Approved"), self.trUtf8("Not approved")] self.completeEdit.addItems(completeTypes) 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.completeLabel.setBuddy(self.completeEdit) # 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.completeLabel, 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.completeEdit, 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.completeEdit.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] complete = 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(':') print dateList, timeList if dateList[1] > '13': dateMessage = QErrorMessage() dateMessage.showMessage(QString(self.trUtf8("The month is not valid. Please enter a valid date."))) print dateList[1] elif dateList[0] > '31': dateMessage = QErrorMessage() dateMessage.showMessage(QString(self.trUtf8("The day is not valid. Please enter a valid date."))) print dateList[0] elif timeList[0] > '23': dateMessage = QErrorMessage() dateMessage.showMessage(QString(self.trUtf8("The hour is not valid. Please enter a valid time."))) print timeList[0] elif timeList[1] > '59': dateMessage = QErrorMessage() dateMessage.showMessage(QString(self.trUtf8("The minutes are not valid. Please enter a valid time."))) print timeList[1] 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, complete) assignment = AssignmentModel(datetime, course, number, description, complete) 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 = "" complete = "" ## Initialize the assignment model def __init__(self, date, course, number, description, complete): self.date = date self.course = course self.number = number self.description = description self.complete = complete ## 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 getComplete(self): return self.complete ### 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]) 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(11) self.scheduleTable.clear() 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) self.scheduleTable.setAlternatingRowColors(False) self.scheduleTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.scheduleTable.setSelectionBehavior(QAbstractItemView.SelectItems) self.scheduleTable.setSelectionMode(QAbstractItemView.SingleSelection) selected = None ## Add the lessons of the semester to the table def updateTable(self, semester): self.schedule = getLessonsFromDB(semester) rows = len(self.schedule) for l in range(rows): self.addLessonToTable(self.schedule[l]) self.scheduleTable.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) self.scheduleTable.verticalHeader().setResizeMode(QHeaderView.ResizeToContents) ## Add a new lesson to the table def addLessonToTable(self, lesson): row = lesson.getTime() - 8 column = self.getColumn(lesson.getDay()) course = lesson.getCourse().getFull() type = lesson.getType() room = lesson.getRoom() olditem = self.scheduleTable.item(row, column) newtext = "%s\n%s\n%s" % (course, 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(buttonBox, SIGNAL("accepted()"), self, SLOT("accept()")) self.connect(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.getTitle()) 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(): conn = sqlite.connect('egon.db') curs = conn.cursor() return curs, conn ## Initialize the tables def initNewDB(): cursor, conn = initDB() initSemesterDB(cursor) initAssignmentDB(cursor) initReadingDB(cursor) initScheduleDB(cursor) initBookDB(cursor) initCourseDB(cursor) initCourseUsesBook(cursor) 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, complete 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) ) ''') ## 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, complete): 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, complete, term, year) VALUES (datetime(?), ?, ?, ?, ?, ?, ?) ''', (timestring, course.getCode(), number, description, complete, 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.getIsbn())) 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() complete = "%s" % completion course = "%s" % coursecode number = (num.toInt())[0] cursor.execute(''' UPDATE Assignment SET complete = ? WHERE course = ? AND number = ? ''', (complete, course, number)) exitDB(conn) ## Update whether the specified reading is done or not def updateReadingDone(week, coursecode, bookisbn, done): cursor, conn = initDB() course = "%s" % coursecode book = "%s" % bookisbn cursor.execute(''' UPDATE Reading SET done = ? WHERE week = ? AND course = ? AND book = ? ''', (done, week, course, book)) 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): cursor, conn = initDB() course = "%s" % coursecode book = "%s" % bookisbn cursor.execute(''' DELETE FROM Reading WHERE week = ? AND course = ? AND book = ? ''', (week, course, book)) 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()) 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) form = MainWindow() app.setOrganizationName("PVV") app.setOrganizationDomain("pvv.ntnu.no") app.setApplicationName(form.title) form.show() app.exec_() main() #initNewDB()