1804 lines
82 KiB
Python
1804 lines
82 KiB
Python
# Squidink7's Timetable, copyright Rafael Fryer 2022
|
|
|
|
import argparse, datetime, io, os, signal, sys, time, webbrowser
|
|
from random import randint as rand
|
|
from shutil import copy, rmtree
|
|
|
|
from PySide6.QtCore import Qt, QStandardPaths, QDate, QTime, QObject, QTimer, QPoint, QRectF, QBuffer, QPropertyAnimation, QEasingCurve
|
|
from PySide6.QtGui import QIcon, QColor, QCursor, QPixmap, QBrush, QPen, QPainter, QImage, QAction
|
|
from PySide6.QtWidgets import QMessageBox, QFileDialog, QColorDialog, QGraphicsDropShadowEffect, QApplication, QMainWindow, QDialog, QWidget, QPushButton, QSystemTrayIcon, QMenu, QSizePolicy, QGraphicsOpacityEffect, QGraphicsScene
|
|
|
|
#change to script directory
|
|
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
|
sys.path.append("lib")
|
|
sys.path.append("assets/ui")
|
|
if sys.platform == "win32":
|
|
sys.path.append("lib-win32")
|
|
|
|
import config, themecolors, termdates, lessonpoints
|
|
from notifypy import Notify
|
|
|
|
from assignment_ui import Ui_Form as assignment_ui_Form
|
|
from assignmentsadd_ui import Ui_Form as assignmentsadd_ui_Form
|
|
from assignmentswindow_ui import Ui_Dialog as assignmentswindow_ui_Dialog
|
|
from custom_ui import Ui_Form as custom_ui_Form
|
|
from settings_ui import Ui_Dialog as settings_ui_Dialog
|
|
from subject_ui import Ui_Dialog as subject_ui_Dialog
|
|
from themes_ui import Ui_Dialog as themes_ui_Dialog
|
|
from timetable_ui import Ui_MainWindow as timetable_ui_MainWindow
|
|
|
|
#################
|
|
### MISC INIT ###
|
|
#################
|
|
|
|
version = "6.0.1-alpha"
|
|
|
|
starttime = time.perf_counter()
|
|
|
|
#################
|
|
### ARGUMENTS ###
|
|
#################
|
|
|
|
parser = argparse.ArgumentParser(description="Timetable application")
|
|
parser.add_argument("timetable", help="Timetable to load (leave blank for default)", default="", nargs="?", const="")
|
|
parser.add_argument("--background", "-b", help="Launch application in background (Don't show the main window)", action="store_true")
|
|
parser.add_argument("--fusion", "-f", help="Use Fusion Qt style", action="store_true")
|
|
parser.add_argument("--debug", "-d", help="Enter debug mode", action="store_true")
|
|
parser.add_argument("--unlockall", help="Unlock all themes for free. Use when debugging", action="store_true")
|
|
args = parser.parse_args()
|
|
if args.background:
|
|
background = True
|
|
else:
|
|
background = False
|
|
|
|
print("Created by squidink7, 2022.")
|
|
|
|
if sys.platform != "linux":
|
|
import themekey
|
|
from buy_ui import Ui_Dialog as buy_ui_Dialog
|
|
else:
|
|
if "iLoveBirb" in sys.argv:
|
|
print("IKR, she's awesome")
|
|
print("Hello fellow linux user, all options have been unlocked.")
|
|
print("Starting v" + version + " on " + str.capitalize(sys.platform) + " at " + str(datetime.date.today()) + ", " + datetime.datetime.now().strftime("%H:%M") + " system time.")
|
|
|
|
app = QApplication(sys.argv)
|
|
app.setAttribute(Qt.AA_UseHighDpiPixmaps)
|
|
if args.fusion or sys.platform != "linux":
|
|
app.setStyle("Fusion")
|
|
|
|
#################
|
|
### SET ICONS ###
|
|
#################
|
|
|
|
def createIcons(forecolor="rgb(255, 255, 255)", refresh=False):
|
|
global icons, app
|
|
|
|
forecolors = []
|
|
splitforecolor = forecolor.split(",")
|
|
|
|
for j in range(len(splitforecolor)):
|
|
number = ""
|
|
for i in list(splitforecolor[j]):
|
|
if i.isdigit():
|
|
number = number + i
|
|
forecolors.append(int(number))
|
|
|
|
icons = {"settings": QImage("./assets/ui/icons/settings.png"), "add": QImage("./assets/ui/icons/add.png"), "edit": QImage("./assets/ui/icons/edit.png"), "notif": QImage("./assets/ui/icons/notifications.png"), "notifdisable": QImage("./assets/ui/icons/notifications-disabled.png"), "close": QImage("./assets/ui/icons/view-close.png"), "due": QImage("./assets/ui/icons/emblem-warning.png"), "overdue": QImage("./assets/ui/icons/emblem-error.png"), "exit": QImage("./assets/ui/icons/application-exit.png"), "copy": QImage("./assets/ui/icons/edit-copy.png"), "paste": QImage("./assets/ui/icons/edit-paste.png")}
|
|
|
|
for i in icons:
|
|
if not "emblem" in i:
|
|
tmp = icons[i]
|
|
tmp.setColor(1, QColor.rgb(QColor(forecolors[0], forecolors[1], forecolors[2])))
|
|
icons[i] = QPixmap.fromImage(tmp)
|
|
|
|
if refresh:
|
|
timetable.buttonSettings.setIcon(icons["settings"])
|
|
subject.buttonCopy.setIcon(icons["copy"])
|
|
subject.buttonPaste.setIcon(icons["paste"])
|
|
themes.buttonCustom.setIcon(icons["edit"])
|
|
mapview.window.buttonClose.setIcon(icons["close"])
|
|
assignmentsView.buttonAdd.setIcon(icons["add"])
|
|
assignmentsView.buttonClose.setIcon(icons["close"])
|
|
subject.buttonCopy.setIcon(icons["copy"])
|
|
subject.buttonPaste.setIcon(icons["paste"])
|
|
|
|
createIcons()
|
|
|
|
#####################
|
|
### CONFIGURATION ###
|
|
#####################
|
|
|
|
config.load(args.timetable)
|
|
|
|
#########################
|
|
### DECLARE VARIABLES ###
|
|
#########################
|
|
|
|
tFore = ""
|
|
tBack = ""
|
|
tBackAlt = ""
|
|
tPic = "view"
|
|
tPicBack = ""
|
|
|
|
class TimeOfDay:
|
|
day = 0
|
|
lesson = 0
|
|
selectedTime = TimeOfDay()
|
|
|
|
copiedsubject = ""
|
|
|
|
dayslist = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
|
|
currentdate = datetime.date.today()
|
|
|
|
###############
|
|
### LOAD UI ###
|
|
###############
|
|
|
|
viewShadow = QGraphicsDropShadowEffect()
|
|
viewShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
viewShadow.setBlurRadius(15)
|
|
viewShadow.setOffset(0)
|
|
editShadow = QGraphicsDropShadowEffect()
|
|
editShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
editShadow.setBlurRadius(15)
|
|
editShadow.setOffset(0)
|
|
settingsShadow = QGraphicsDropShadowEffect()
|
|
settingsShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
settingsShadow.setBlurRadius(15)
|
|
settingsShadow.setOffset(0)
|
|
themesShadow = QGraphicsDropShadowEffect()
|
|
themesShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
themesShadow.setBlurRadius(15)
|
|
themesShadow.setOffset(0)
|
|
assignmentsViewShadow = QGraphicsDropShadowEffect()
|
|
assignmentsViewShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
assignmentsViewShadow.setBlurRadius(15)
|
|
assignmentsViewShadow.setOffset(0)
|
|
assignmentsAddShadow = QGraphicsDropShadowEffect()
|
|
assignmentsAddShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
assignmentsAddShadow.setBlurRadius(15)
|
|
assignmentsAddShadow.setOffset(0)
|
|
mapShadow = QGraphicsDropShadowEffect()
|
|
mapShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
mapShadow.setBlurRadius(15)
|
|
mapShadow.setOffset(0)
|
|
|
|
timetableWindow = QMainWindow()
|
|
timetable = timetable_ui_MainWindow()
|
|
timetable.setupUi(timetableWindow)
|
|
timetableWindow.setWindowTitle("Timetable")
|
|
timetableWindow.setWindowIcon(QIcon(":/backgrounds/timetable"))
|
|
timetableWindow.resize(timetableWindow.width(), 520)
|
|
timetable.labelVersion.setText("v" + version)
|
|
|
|
if not args.debug:
|
|
import singleinstance
|
|
singleinstance.start(config.confdir)
|
|
def showFromNewInstance():
|
|
timetableWindow.show()
|
|
timetableWindow.showNormal()
|
|
singleinstance.showWindow.show.connect(showFromNewInstance)
|
|
|
|
subjectWindow = QDialog()
|
|
subject = subject_ui_Dialog()
|
|
subject.setupUi(subjectWindow)
|
|
subjectWindow.setWindowTitle("Subject info")
|
|
subjectWindow.setWindowIcon(QIcon(":/backgrounds/timetable"))
|
|
subjectWindow.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
|
|
subjectWindow.setAttribute(Qt.WA_TranslucentBackground)
|
|
subjectWindow.setFixedWidth(395)
|
|
subject.frameEdit.hide()
|
|
def resetSubjectColors():
|
|
subject.editColor.clear()
|
|
subject.editColor.addItem("None")
|
|
subject.editColor.addItem("Red")
|
|
subject.editColor.addItem("Orange")
|
|
subject.editColor.addItem("Yellow")
|
|
subject.editColor.addItem("Green")
|
|
subject.editColor.addItem("Blue")
|
|
subject.editColor.addItem("Purple")
|
|
subject.editColor.addItem("Pink")
|
|
subject.editColor.addItem("Gray")
|
|
subject.editColor.addItem("Custom")
|
|
resetSubjectColors()
|
|
subject.frameView.setGraphicsEffect(viewShadow)
|
|
subject.frameEdit.setGraphicsEffect(editShadow)
|
|
|
|
settingsWindow = QDialog()
|
|
settings = settings_ui_Dialog()
|
|
settings.setupUi(settingsWindow)
|
|
settingsWindow.setWindowTitle("Settings")
|
|
settingsWindow.setWindowIcon(QIcon(":/backgrounds/timetable"))
|
|
settingsWindow.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
|
|
settingsWindow.setAttribute(Qt.WA_TranslucentBackground)
|
|
settings.frame.setGraphicsEffect(settingsShadow)
|
|
|
|
if sys.platform != "linux":
|
|
settings.checkBorder.hide()
|
|
|
|
themesWindow = QDialog()
|
|
themes = themes_ui_Dialog()
|
|
themes.setupUi(themesWindow)
|
|
themesWindow.setWindowTitle("Themes")
|
|
themesWindow.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
|
|
themes.buttonOK.setFixedWidth(90)
|
|
themes.buttonOK.setFixedHeight(30)
|
|
themesWindow.setAttribute(Qt.WA_TranslucentBackground)
|
|
themes.frameBack.setGraphicsEffect(themesShadow)
|
|
|
|
customWindow = QWidget()
|
|
custom = custom_ui_Form()
|
|
custom.setupUi(customWindow)
|
|
customWindow.setWindowTitle("Custom Theme")
|
|
|
|
assignmentsViewWindow = QDialog()
|
|
assignmentsView = assignmentswindow_ui_Dialog()
|
|
assignmentsView.setupUi(assignmentsViewWindow)
|
|
assignmentsViewWindow.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
|
|
assignmentsViewWindow.setAttribute(Qt.WA_TranslucentBackground)
|
|
assignmentsView.frame.setGraphicsEffect(assignmentsViewShadow)
|
|
assignmentsViewWindow.setWindowTitle("Assignments")
|
|
|
|
assignmentsAddWindow = QWidget()
|
|
assignmentsAdd = assignmentsadd_ui_Form()
|
|
assignmentsAdd.setupUi(assignmentsAddWindow)
|
|
assignmentsAddWindow.setAttribute(Qt.WA_TranslucentBackground)
|
|
assignmentsAddWindow.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
|
|
assignmentsAdd.frame.setGraphicsEffect(assignmentsAddShadow)
|
|
assignmentsAddWindow.setWindowTitle("Add Assignment")
|
|
|
|
import mapview
|
|
|
|
mapview.app = app
|
|
mapview.selectedTime = selectedTime
|
|
mapview.window.buttonClose.show()
|
|
mapview.window.buttonClose.setIcon(icons["close"])
|
|
|
|
subject.room.clicked.connect(lambda: mapview.showMap(1))
|
|
timetable.buttonMap.clicked.connect(lambda: mapview.showMap(0))
|
|
|
|
if sys.platform != "linux":
|
|
buyWindow = QDialog()
|
|
buy = buy_ui_Dialog()
|
|
buy.setupUi(buyWindow)
|
|
buyWindow.setWindowTitle("Purchase key")
|
|
buy.frameInfo.hide()
|
|
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Default"] == "True":
|
|
themes.frameDefault.setEnabled(False)
|
|
themes.frameDefault.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageDefault.setStyleSheet("image: url(:/screenshots/defaultlck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Galaxy"] == "True":
|
|
themes.frameGalaxy.setEnabled(False)
|
|
themes.frameGalaxy.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageGalaxy.setStyleSheet("image: url(:/screenshots/galaxylck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Meenu"] == "True":
|
|
themes.frameMeenu.setEnabled(False)
|
|
themes.frameMeenu.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageMeenu.setStyleSheet("image: url(:/screenshots/meenulck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Keely"] == "True":
|
|
themes.frameKeely.setEnabled(False)
|
|
themes.frameKeely.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageKeely.setStyleSheet("image: url(:/screenshots/keelylck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Commodore"] == "True":
|
|
themes.frameCommodore.setEnabled(False)
|
|
themes.frameCommodore.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageCommodore.setStyleSheet("image: url(:/screenshots/commodorelck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Terminal"] == "True":
|
|
themes.frameTerminal.setEnabled(False)
|
|
themes.frameTerminal.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageTerminal.setStyleSheet("image: url(:/screenshots/terminallck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Ubuntu"] == "True":
|
|
themes.frameUbuntu.setEnabled(False)
|
|
themes.frameUbuntu.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageUbuntu.setStyleSheet("image: url(:/screenshots/ubuntulck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Blue Flame"] == "True":
|
|
themes.frameBlueFlame.setEnabled(False)
|
|
themes.frameBlueFlame.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageBlueFlame.setStyleSheet("image: url(:/screenshots/blueflamelck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Custom"] == "True":
|
|
themes.frameCustom.setEnabled(False)
|
|
themes.frameCustom.setCursor(QCursor(Qt.ArrowCursor))
|
|
themes.imageCustom.setStyleSheet("image: url(:/screenshots/defaultlck.png);")
|
|
if not themekey.unlockkey or not themekey.keyData["Options"]["Name"] == "True":
|
|
settings.labelName.hide()
|
|
settings.editName.hide()
|
|
|
|
##########################
|
|
### TERMS + CONDITIONS ###
|
|
##########################
|
|
|
|
if sys.platform != "linux":
|
|
if not config.settingsCfg.has_option("Settings", "Beta") or config.settingsCfg["Settings"]["Beta"] == "":
|
|
print("Windows detected, displaying disclaimer")
|
|
timetableWindow.show()
|
|
terms = QMessageBox.warning(timetableWindow, "Beta", "This app is currently in beta, Some features may be broken.",
|
|
QMessageBox.Ok)
|
|
if terms == QMessageBox.Ok:
|
|
if not config.settingsCfg.has_section("Settings"):
|
|
config.settingsCfg.add_section("Settings")
|
|
config.settingsCfg["Settings"]["Beta"] = "True"
|
|
config.writeSettings()
|
|
else:
|
|
exit()
|
|
if themekey.invalidkey:
|
|
delkey = QMessageBox.warning(timetableWindow, "Invalid Key", "The key loaded is corrupt or invalid.",
|
|
QMessageBox.Ok)
|
|
if delkey == QMessageBox.Ok:
|
|
os.remove(os.path.join(config.confdir, "timetable.key"))
|
|
|
|
if args.unlockall:
|
|
QMessageBox.critical(timetableWindow, "Ha, nice try", "Sorry, that doesn't work.", QMessageBox.Ok)
|
|
|
|
#####################
|
|
### DATE AND TERM ###
|
|
#####################
|
|
|
|
if datetime.date.today().strftime("%Y")=="2022":
|
|
if termdates.term == 0 or termdates.scweek == "null":
|
|
timetable.labelDate.setText("Holidays! " + datetime.date.today().strftime("%d/%m/%Y"))
|
|
else:
|
|
timetable.labelDate.setText(termdates.scweek + ", " + termdates.term + ", " + datetime.date.today().strftime("%d/%m/%Y"))
|
|
else:
|
|
timetable.labelDate.setText("This timetable was designed for use in 2022, please check for an update")
|
|
|
|
def upDATE():
|
|
global currentdate
|
|
if currentdate != datetime.date.today():
|
|
timetable.labelDate.setText(datetime.date.today().strftime("%d/%m/%Y"))
|
|
currentdate = datetime.date.today()
|
|
|
|
def getRandomNumber(len):
|
|
start = 10**(len-1)
|
|
end = (10**len)-1
|
|
return rand(start, end)
|
|
|
|
if config.settingsCfg.has_option("Settings", "Theme") and config.settingsCfg["Settings"]["Theme"] == "Secret":
|
|
global sessionrandomnumber
|
|
sessionrandomnumber = getRandomNumber(4)
|
|
timetable.labelVersion.setText(str(sessionrandomnumber))
|
|
|
|
def checkForNumber():
|
|
if settings.editName.text() == str(sessionrandomnumber):
|
|
print('Traceback (most recent call last):\n File "' + os.path.realpath(__file__) + '", line ' + str(sessionrandomnumber) + ', in launchEasterEgg\n if user == "messingwiththings":\nUserError: User was found touching things they shouldn\'t have')
|
|
if (sys.platform == "linux") or (themekey.unlockkey and themekey.keyData["Options"]["Default"] == "True"):
|
|
config.settingsCfg["Settings"]["Theme"] = "Default"
|
|
else:
|
|
config.settingsCfg["Settings"]["Theme"] = "Light"
|
|
config.writeSettings()
|
|
quit()
|
|
settings.editName.textChanged.connect(checkForNumber)
|
|
|
|
def TGIF(event):
|
|
if timetable.labelFriday.text() == "<strong>Friday":
|
|
timetable.labelFriday.setText("<strong>TGIF")
|
|
elif timetable.labelFriday.text() == "<strong>TGIF":
|
|
timetable.labelFriday.setText("<strong>Friday")
|
|
timetable.labelFriday.mousePressEvent = TGIF
|
|
|
|
###################
|
|
### DAY BUTTONS ###
|
|
###################
|
|
|
|
daybuttons = {"monday1": timetable.monday1, "monday2": timetable.monday2, "monday3": timetable.monday3, "monday4": timetable.monday4, "monday5": timetable.monday5, "monday6": timetable.monday6, "monday7": timetable.monday7, "tuesday1": timetable.tuesday1, "tuesday2": timetable.tuesday2, "tuesday3": timetable.tuesday3, "tuesday4": timetable.tuesday4, "tuesday5": timetable.tuesday5, "tuesday6": timetable.tuesday6, "tuesday7": timetable.tuesday7, "wednesday1": timetable.wednesday1, "wednesday2": timetable.wednesday2, "wednesday3": timetable.wednesday3, "wednesday4": timetable.wednesday4, "wednesday5": timetable.wednesday5, "wednesday6": timetable.wednesday6, "wednesday7": timetable.wednesday7, "thursday1": timetable.thursday1, "thursday2": timetable.thursday2, "thursday3": timetable.thursday3, "thursday4": timetable.thursday4, "thursday5": timetable.thursday5, "thursday6": timetable.thursday6, "thursday7": timetable.thursday7, "friday1": timetable.friday1, "friday2": timetable.friday2, "friday3": timetable.friday3, "friday4": timetable.friday4, "friday5": timetable.friday5, "friday6": timetable.friday6, "friday7": timetable.friday7}
|
|
|
|
with open("assets/ui/button.qss", "r") as qssfile:
|
|
buttonqss = qssfile.read()
|
|
|
|
###################
|
|
### RESIZE TEXT ###
|
|
###################
|
|
|
|
def onResize(event):
|
|
textSize = timetableWindow.height() / 30
|
|
|
|
if tLight:
|
|
textcolor = "rgb(0, 0, 0)"
|
|
else:
|
|
textcolor = "rgb(255, 255, 255)"
|
|
|
|
for j in dayslist:
|
|
for i in range(1, 8):
|
|
if config.subjectsCfg.has_option(j + str(i), "color") and config.subjectsCfg[j + str(i)]["color"] != "None":
|
|
daybuttons[j.lower() + str(i)].setStyleSheet(buttonqss + "QPushButton { font-size: " + str(int(textSize)) + "px; background-color: " + config.subjectsCfg[j + str(i)]["color"] + "; color: " + textcolor + "; }")
|
|
else:
|
|
daybuttons[j.lower() + str(i)].setStyleSheet(buttonqss + "QPushButton { font-size: " + str(int(textSize)) + "px; background-color: " + tBackAlt + "; color: " + textcolor + "; }")
|
|
|
|
movedWindow(timetableWindow)
|
|
|
|
timetableWindow.resizeEvent = onResize
|
|
|
|
#########################
|
|
### TIMETABLE SHADOWS ###
|
|
#########################
|
|
|
|
def highlightHoveredSubject(day, lesson):
|
|
newHoverShadowT()
|
|
daybuttons[day + str(lesson)].setGraphicsEffect(hoverShadowT)
|
|
def unhighlightHoveredSubject(day, lesson):
|
|
daybuttons[day + str(lesson)].setGraphicsEffect(None)
|
|
|
|
for day in dayslist:
|
|
for i in range(1, 8):
|
|
daybuttons[day.lower() + str(i)].enterEvent = lambda event, i=i, day=day: highlightHoveredSubject(day.lower(), i)
|
|
daybuttons[day.lower() + str(i)].leaveEvent = lambda event, i=i, day=day: unhighlightHoveredSubject(day.lower(), i)
|
|
|
|
#######################
|
|
### DRAG BORDERLESS ###
|
|
#######################
|
|
|
|
def moveWindow(event):
|
|
QMessageBox.information(timetableWindow, "Not available", "Due to a flaw in Qt5 widgets moving the window in borderless mode is currently unavailable. To move the window hold the meta key and try again", QMessageBox.Ok)
|
|
timetable.header.mousePressEvent = moveWindow
|
|
|
|
##################
|
|
### MOVE EVENT ###
|
|
##################
|
|
|
|
def toCentre(window, parent):
|
|
window.raise_()
|
|
if int(parent.x() + (parent.width() / 2 - (window.width() / 2))) > 0 and int(parent.y() + (parent.height() / 2 - (window.height() / 2))) > 0:
|
|
window.move(int(parent.x() + (parent.width() / 2 - (window.width() / 2))), int(parent.y() + (parent.height() / 2 - (window.height() / 2))))
|
|
|
|
def movedWindow(event):
|
|
toCentre(subjectWindow, timetableWindow)
|
|
toCentre(settingsWindow, timetableWindow)
|
|
toCentre(themesWindow, timetableWindow)
|
|
toCentre(assignmentsViewWindow, timetableWindow)
|
|
toCentre(assignmentsAddWindow, assignmentsViewWindow)
|
|
timetableWindow.moveEvent = movedWindow
|
|
|
|
#####################
|
|
### READ SUBJECTS ###
|
|
#####################
|
|
|
|
largeLessonSizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
|
|
largeLessonSizePolicy.setVerticalStretch(2)
|
|
lessonSizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
|
|
lessonSizePolicy.setVerticalStretch(1)
|
|
|
|
def refresh():
|
|
global tFore, tBack, tBackAlt, tPic, tPicBack
|
|
|
|
print("Refreshing subjects")
|
|
|
|
for j in dayslist:
|
|
for i in range(1, 8):
|
|
if config.subjectsCfg.has_option(j + str(i), "SubjectName"):
|
|
daybuttons[j.lower() + str(i)].setText(config.subjectsCfg[j + str(i)]["SubjectName"])
|
|
|
|
if config.subjectsCfg.has_option(j + str(i), "color") and not config.subjectsCfg[j + str(i)]["color"] == "None":
|
|
daybuttons[j.lower() + str(i)].setStyleSheet(buttonqss + "QPushButton { background-color: " + config.subjectsCfg[j + str(i)]["color"] + "; }")
|
|
else:
|
|
daybuttons[j.lower() + str(i)].setStyleSheet(buttonqss + "QPushButton { background-color: " + tBackAlt + "; }")
|
|
|
|
######################
|
|
### DOUBLE LESSONS ###
|
|
######################
|
|
|
|
for i in daybuttons:
|
|
daybuttons[i].show()
|
|
|
|
for i in daybuttons:
|
|
if config.subjectsCfg.has_option(i.title(), "DoubleFor") and config.subjectsCfg[i.title()]["DoubleFor"] != "" and config.subjectsCfg[i.title()]["DoubleFor"] != "Single":
|
|
daybuttons[i].setSizePolicy(largeLessonSizePolicy)
|
|
daybuttons[config.subjectsCfg[i.title()]["DoubleFor"]].hide()
|
|
else:
|
|
daybuttons[i].setSizePolicy(lessonSizePolicy)
|
|
|
|
onResize(timetableWindow)
|
|
|
|
#####################
|
|
### READ SETTINGS ###
|
|
#####################
|
|
|
|
def getTheme():
|
|
if sys.platform == "linux":
|
|
if config.settingsCfg.has_option("Settings", "Theme") and (config.settingsCfg["Settings"]["Theme"] in themecolors.foreground or config.settingsCfg["Settings"]["Theme"] == "Custom"):
|
|
return config.settingsCfg["Settings"]["Theme"]
|
|
else:
|
|
return "Default"
|
|
elif themekey.unlockkey:
|
|
if config.settingsCfg.has_option("Settings", "Theme") and (config.settingsCfg["Settings"]["Theme"] in themecolors.foreground or config.settingsCfg["Settings"]["Theme"] == "Custom") and (config.settingsCfg["Settings"]["Theme"] in ("Light", "Woodcroft", "Hot Dog Stand") or themekey.keyData["Options"][config.settingsCfg["Settings"]["Theme"]] == "True"):
|
|
return config.settingsCfg["Settings"]["Theme"]
|
|
elif themekey.keyData["Options"]["Default"] == "True":
|
|
return "Default"
|
|
else:
|
|
return "Light"
|
|
else:
|
|
if config.settingsCfg.has_option("Settings", "Theme") and config.settingsCfg["Settings"]["Theme"] in themecolors.foreground and config.settingsCfg["Settings"]["Theme"] in ("Light", "Woodcroft", "Hot Dog Stand"):
|
|
return config.settingsCfg["Settings"]["Theme"]
|
|
else:
|
|
return "Light"
|
|
|
|
def refreshSettings(previewtheme=None):
|
|
global settingschanged, tFore, tBack, tBackAlt, tPic, tPicBack, tLight
|
|
settingschanged = False
|
|
if sys.platform == "linux" or (themekey.unlockkey and themekey.keyData["Options"]["Name"] == "True"):
|
|
if config.settingsCfg.has_option("Settings", "Name") and config.settingsCfg["Settings"]["Name"] != "":
|
|
timetableWindow.setWindowTitle(config.settingsCfg["Settings"]["Name"] + "'s timetable")
|
|
timetable.labelTitle.setText("<strong>" + config.settingsCfg["Settings"]["Name"] + "'s timetable")
|
|
else:
|
|
timetableWindow.setWindowTitle("Timetable")
|
|
timetable.labelTitle.setText("<strong>Timetable")
|
|
|
|
if config.settingsCfg.has_option("Settings", "Border"):
|
|
if config.settingsCfg["Settings"]["Border"] == "False":
|
|
timetableWindow.setWindowFlags(Qt.FramelessWindowHint)
|
|
timetable.header.show()
|
|
else:
|
|
timetableWindow.setWindowFlags(timetableWindow.windowFlags() & ~Qt.FramelessWindowHint)
|
|
timetable.header.hide()
|
|
else:
|
|
timetableWindow.setWindowFlags(timetableWindow.windowFlags() & ~Qt.FramelessWindowHint)
|
|
timetable.header.hide()
|
|
|
|
##############
|
|
### THEMES ###
|
|
##############
|
|
|
|
|
|
settings.labelTheme.setText("<strong>Theme:</strong> " + getTheme())
|
|
|
|
if getTheme() != "Custom" and getTheme() in themecolors.foreground:
|
|
tFore = themecolors.foreground[getTheme()]
|
|
tBack = themecolors.background[getTheme()]
|
|
tBackAlt = themecolors.backgroundalt[getTheme()]
|
|
tPic = themecolors.pictures[getTheme()]
|
|
tPicBack = themecolors.backpics[getTheme()]
|
|
tLight = themecolors.light[getTheme()]
|
|
elif getTheme() == "Custom" and config.settingsCfg.has_option("CustomTheme", "tFore") and config.settingsCfg.has_option("CustomTheme", "tBack") and config.settingsCfg.has_option("CustomTheme", "tbackAlt"):
|
|
tFore = config.settingsCfg["CustomTheme"]["tFore"]
|
|
tBack = config.settingsCfg["CustomTheme"]["tBack"]
|
|
tBackAlt = config.settingsCfg["CustomTheme"]["tBackAlt"]
|
|
tLight = True
|
|
|
|
#########################
|
|
### SET WIDGET COLORS ###
|
|
#########################
|
|
|
|
timetableWindow.setStyleSheet("QWidget { background-color: " + tBack + "; } QLabel { color: " + tFore + "; background-color: None; } #centralwidget { image: url(" + tPicBack + "); image-position: bottom; }")
|
|
timetable.labelVersion.setStyleSheet("color: " + tBackAlt + ";")
|
|
timetable.buttonAssignments.setStyleSheet("background-color: " + tBackAlt + "; color: " + tFore + ";")
|
|
timetable.buttonMap.setStyleSheet("background-color: " + tBackAlt + "; color: " + tFore + ";")
|
|
subject.room.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.online.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.labelTitle.setStyleSheet("border-image: None;")
|
|
subject.editTitle.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + "; border-radius: 5px; font: 75 20px;")
|
|
subject.editColor.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.editTeacher.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + "; border-radius: 3px;")
|
|
subject.editRoom.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + "; border-radius: 3px;")
|
|
subject.editOnline.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + "; border-radius: 3px;")
|
|
subject.editNotes.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + "; border-radius: 3px; border-image: None;")
|
|
subject.comboDouble.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.applyToAll.setStyleSheet("color: " + tFore + "; background-color: " + tBack + "; border-radius: 3px;")
|
|
subject.buttonAssignment.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.buttonEdit.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.buttonBack.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.buttonCopy.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.buttonPaste.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.editButtonSave.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.editButtonBack.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
subject.frameView.setStyleSheet("QFrame { background-color: " + tBack + "; border-radius: 10px; } QLabel { color: " + tFore + "; } #frameView { border-image: url(./assets/backgrounds/" + tPic + ".png); }")
|
|
subject.frameEdit.setStyleSheet("QFrame { background-color: " + tBack + "; border-radius: 10px; } QLabel { color: " + tFore + "; } #frameEdit { border-image: url(./assets/backgrounds/edit.png); }")
|
|
settingsWindow.setStyleSheet("QWidget { background-color: " + tBack + "; } QLabel { color: " + tFore + "; background-color: None; }")
|
|
settings.editName.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
settings.buttonExport.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
settings.buttonImport.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
settings.buttonTheme.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
settings.buttonSave.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
settings.buttonBack.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
settings.buttonReset.setStyleSheet("color: rgb(255,0,0); background-color: " + tBack + ";")
|
|
settings.buttonMore.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
settings.checkBorder.setStyleSheet("color: " + tFore + "; background-color: " + tBack + "; border-radius: 3px;")
|
|
settings.frame.setStyleSheet("QFrame { border-image: url(:/backgrounds/settings.png); background-color: " + tBack + "; border-radius: 10px; } QLabel { color: " + tFore + "; }")
|
|
themesWindow.setStyleSheet("QWidget { background-color: " + tBack + "; } QFrame { border-radius: 7px; } QLabel { color: " + tFore + "; background-color: " + tBack + "; }")
|
|
themes.buttonOK.setStyleSheet("color: " + tFore + ";")
|
|
themes.buttonCustom.setStyleSheet("QWidget { color: " + tFore + "; background-color: " + tBack + "; background-color: " + tBack + "; border-radius: 4px; } QWidget:hover { background-color: " + tBackAlt + "; } QWidget:pressed { background-color: " + tFore + "; }")
|
|
themes.labelDefault.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelLight.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelWoodcroft.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelHotDog.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelGalaxy.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelMeenu.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelKeely.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelCommodore.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelTerminal.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelUbuntu.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelBlueFlame.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.labelCustom.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameDefault.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameLight.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameWoodcroft.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameHotDog.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameGalaxy.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameMeenu.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameKeely.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameCommodore.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameTerminal.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameUbuntu.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameBlueFlame.setStyleSheet("background-color: " + tBack + ";")
|
|
themes.frameCustom.setStyleSheet("background-color: " + tBack + ";")
|
|
customWindow.setStyleSheet("QWidget { background-color: " + tBack + "; } QLabel { color: " + tFore + "; }")
|
|
custom.buttonSave.setStyleSheet("color: " + tFore + ";")
|
|
assignmentsViewWindow.setStyleSheet("QWidget { background-color: " + tBack + "; } QLabel { color: " + tFore + "; background-color: None; }")
|
|
assignmentsView.frame.setStyleSheet("#frame { border-radius: 10px; }")
|
|
assignmentsView.buttonAdd.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsView.buttonClose.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsAddWindow.setStyleSheet("QWidget { background-color: " + tBack + "; } QLabel { color: " + tFore + "; background-color: None; } ")
|
|
assignmentsAdd.buttonOK.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsAdd.buttonCancel.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsAdd.editDate.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsAdd.editTime.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsAdd.editName.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsAdd.editDesc.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
assignmentsAdd.comboLesson.setStyleSheet("color: " + tFore + "; background-color: " + tBackAlt + ";")
|
|
mapview.window.mapFrame.setStyleSheet("QFrame { color: " + tFore + "; background-color: " + tBack + "; border-radius: 10px; }")
|
|
mapview.window.buttonClose.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
mapview.window.buttonReset.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
mapview.window.buttonFind.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
mapview.window.editLocation.setStyleSheet("color: " + tFore + "; background-color: " + tBack + ";")
|
|
if sys.platform != "linux":
|
|
buyWindow.setStyleSheet("QWidget { background-color: " + tBack + "; } QLabel { color: " + tFore + "; }")
|
|
buy.buttonBack.setStyleSheet("color: " + tFore + ";")
|
|
buy.buttonBack2.setStyleSheet("color: " + tFore + ";")
|
|
buy.buttonInfo.setStyleSheet("color: " + tFore + ";")
|
|
buy.buttonLoad.setStyleSheet("color: " + tFore + ";")
|
|
|
|
createIcons(tFore, True)
|
|
|
|
global tForeRGBString, tBackAltRGBString
|
|
|
|
if (config.settingsCfg.has_option("Settings", "Theme") and config.settingsCfg["Settings"]["Theme"] != "Custom") or config.settingsCfg.has_option("CustomTheme", "tFore"):
|
|
fore1 = tFore.find("(") + 1
|
|
fore2 = tFore.find(")")
|
|
tForeRGB = tFore[fore1:fore2]
|
|
tForeRGBString = tForeRGB.split(", ")
|
|
else:
|
|
tForeRGBString = ["0", "0", "0"]
|
|
|
|
if (config.settingsCfg.has_option("Settings", "Theme") and config.settingsCfg["Settings"]["Theme"] != "Custom") or config.settingsCfg.has_option("CustomTheme", "tBackAlt"):
|
|
backalt1 = tBackAlt.find("(") + 1
|
|
backalt2 = tBackAlt.find(")")
|
|
tBackAltRGB = tBackAlt[backalt1:backalt2]
|
|
tBackAltRGBString = tBackAltRGB.split(", ")
|
|
else:
|
|
tBackAltRGBString = ["0", "0", "0"]
|
|
|
|
refresh()
|
|
|
|
refreshSettings()
|
|
|
|
##########################
|
|
### SHADOWS DEFINITION ###
|
|
##########################
|
|
|
|
def newHoverShadow():
|
|
global hoverShadow
|
|
hoverShadow = QGraphicsDropShadowEffect()
|
|
hoverShadow.setColor(QColor.fromRgb(int(tForeRGBString[0]), int(tForeRGBString[1]), int(tForeRGBString[2])))
|
|
hoverShadow.setBlurRadius(15)
|
|
hoverShadow.setOffset(0)
|
|
def newSelectShadow():
|
|
global selectShadow
|
|
selectShadow = QGraphicsDropShadowEffect()
|
|
selectShadow.setColor(QColor.fromRgb(int(tForeRGBString[0]), int(tForeRGBString[1]), int(tForeRGBString[2])))
|
|
selectShadow.setBlurRadius(15)
|
|
selectShadow.setOffset(0)
|
|
|
|
def newHoverShadowT():
|
|
global hoverShadowT
|
|
hoverShadowT = QGraphicsDropShadowEffect()
|
|
if tLight:
|
|
hoverShadowT.setColor(QColor.fromRgb(0, 0, 0))
|
|
else:
|
|
hoverShadowT.setColor(QColor.fromRgb(255, 255, 255))
|
|
hoverShadowT.setBlurRadius(20)
|
|
hoverShadowT.setOffset(0)
|
|
|
|
#######################
|
|
### CONNECT BUTTONS ###
|
|
#######################
|
|
|
|
for j in dayslist:
|
|
for i in range(1, 8):
|
|
daybuttons[j.lower() + str(i)].clicked.connect(lambda j=j, i=i: showSubject(j, i))
|
|
|
|
timetable.buttonClose.clicked.connect(timetableWindow.close)
|
|
|
|
def maximise():
|
|
if timetableWindow.isMaximized():
|
|
timetableWindow.showNormal()
|
|
else:
|
|
timetableWindow.showMaximized()
|
|
timetable.buttonMaximize.clicked.connect(maximise)
|
|
|
|
timetable.buttonMinimize.clicked.connect(timetableWindow.showMinimized)
|
|
|
|
#####################
|
|
### SHOW SETTINGS ###
|
|
#####################
|
|
|
|
def showSettings():
|
|
global themeselected
|
|
if config.settingsCfg.has_option("Settings", "Name"):
|
|
settings.editName.setText(config.settingsCfg["Settings"]["Name"])
|
|
toCentre(settingsWindow, timetableWindow)
|
|
|
|
if config.settingsCfg.has_option("Settings", "Theme"):
|
|
settings.labelTheme.setText("<strong>Theme:</strong> " + config.settingsCfg["Settings"]["Theme"])
|
|
themeselected = getTheme()
|
|
|
|
if config.settingsCfg.has_option("Settings", "Border"):
|
|
settings.checkBorder.setChecked(bool(config.settingsCfg["Settings"]["Border"]))
|
|
else:
|
|
settings.checkBorder.setChecked(True)
|
|
|
|
upDATE()
|
|
|
|
settingsWindow.show()
|
|
|
|
timetable.buttonSettings.clicked.connect(showSettings)
|
|
|
|
#######################
|
|
### SUBJECT DETAILS ###
|
|
#######################
|
|
|
|
subjectSlideAnimation = QPropertyAnimation(subjectWindow, b"pos")
|
|
subjectSlideAnimation.setDuration(200)
|
|
subjectSlideAnimation.setEasingCurve(QEasingCurve.Linear)
|
|
|
|
subjectFadeAnimation = QPropertyAnimation(subjectWindow, b"windowOpacity")
|
|
subjectFadeAnimation.setDuration(200)
|
|
subjectFadeAnimation.setEasingCurve(QEasingCurve.Linear)
|
|
|
|
def showSubject(arg1, arg2):
|
|
global selectedTime, subjectSlideAnimation
|
|
selectedTime.day = arg1
|
|
selectedTime.lesson = arg2
|
|
print(f"Showing details for lesson {str(selectedTime.lesson)} on {selectedTime.day}")
|
|
if sys.platform == "win32":
|
|
subjectWindow.hide()
|
|
toCentre(subjectWindow, timetableWindow)
|
|
|
|
getSubjectTitle()
|
|
getTeacher()
|
|
getRoom()
|
|
getOnline()
|
|
getNotes()
|
|
getDouble()
|
|
getColor()
|
|
subject.applyToAll.setChecked(False)
|
|
subject.labelCopied.hide()
|
|
global copiedsubject
|
|
if copiedsubject == "":
|
|
subject.buttonPaste.hide()
|
|
else:
|
|
subject.buttonPaste.show()
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "SubjectName") and config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["SubjectName"] != "":
|
|
subject.buttonAssignment.show()
|
|
else:
|
|
subject.buttonAssignment.hide()
|
|
upDATE()
|
|
subjectWindow.show()
|
|
if not args.debug:
|
|
subjectSlideAnimation.setEasingCurve(QEasingCurve.Linear)
|
|
subjectSlideAnimation.setStartValue(QPoint(subjectWindow.x(), subjectWindow.y() + 25))
|
|
subjectSlideAnimation.setEndValue(subjectWindow.pos())
|
|
|
|
subjectFadeAnimation.setStartValue(0)
|
|
subjectFadeAnimation.setEndValue(1)
|
|
|
|
subjectSlideAnimation.start()
|
|
subjectFadeAnimation.start()
|
|
|
|
def getSubjectTitle():
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "SubjectName") and not config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["SubjectName"] == "":
|
|
subject.labelTitle.setText("<strong>" + config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["SubjectName"])
|
|
subject.editTitle.setText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["SubjectName"])
|
|
else:
|
|
subject.labelTitle.setText("New Subject")
|
|
subject.editTitle.setText("")
|
|
|
|
def getTeacher():
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "Teacher") and not config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Teacher"] == "":
|
|
subject.teacher.setText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Teacher"])
|
|
subject.teacher.show()
|
|
subject.editTeacher.setText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Teacher"])
|
|
subject.labelTeacher.show()
|
|
else:
|
|
subject.teacher.setText("")
|
|
subject.teacher.hide()
|
|
subject.editTeacher.setText("")
|
|
subject.labelTeacher.hide()
|
|
|
|
def getRoom():
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "Room") and not config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Room"] == "":
|
|
subject.room.setText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Room"])
|
|
subject.room.show()
|
|
subject.editRoom.setText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Room"])
|
|
subject.labelRoom.show()
|
|
else:
|
|
subject.room.setText("")
|
|
subject.room.hide()
|
|
subject.editRoom.setText("")
|
|
subject.labelRoom.hide()
|
|
|
|
def getOnline():
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "Online") and not config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Online"] == "":
|
|
subject.editOnline.setText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Online"])
|
|
subject.online.setText("Open Link")
|
|
subject.online.show()
|
|
subject.labelOnline.show()
|
|
else:
|
|
subject.online.setText("")
|
|
subject.online.hide()
|
|
subject.editOnline.setText("")
|
|
subject.labelOnline.hide()
|
|
|
|
def getNotes():
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "Notes") and not config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Notes"] == "":
|
|
subject.notes.setText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Notes"])
|
|
subject.editNotes.setPlainText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Notes"])
|
|
subject.notes.show()
|
|
subject.labelNotes.show()
|
|
else:
|
|
subject.notes.setText("")
|
|
subject.notes.hide()
|
|
subject.editNotes.setPlainText("")
|
|
subject.labelNotes.hide()
|
|
|
|
def getColor():
|
|
resetSubjectColors()
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "Color") and not (config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "" or config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "None"):
|
|
subject.labelTitle.setStyleSheet("QLabel { color: " + config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] + "; font: 75 20pt; font: 75 20pt; border-image: None; }")
|
|
if config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#ff0000":
|
|
subject.editColor.setCurrentIndex(1)
|
|
if config.settingsCfg.has_option("Settings", "Theme") and config.settingsCfg["Settings"]["Theme"] == "Hot Dog Stand":
|
|
subject.labelTitle.setStyleSheet("QLabel { color: " + config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] + "; background-color: " + tFore + "; font: 75 20pt; font: 75 20pt; border-image: None; }")
|
|
elif config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#ffa000":
|
|
subject.editColor.setCurrentIndex(2)
|
|
if config.settingsCfg.has_option("Settings", "Theme") and config.settingsCfg["Settings"]["Theme"] == "Ubuntu":
|
|
subject.labelTitle.setStyleSheet("QLabel { color: " + config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] + "; background-color: " + tFore + "; font: 75 20pt; font: 75 20pt; border-image: None; }")
|
|
elif config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#d7d241":
|
|
subject.editColor.setCurrentIndex(3)
|
|
elif config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#00aa41":
|
|
subject.editColor.setCurrentIndex(4)
|
|
elif config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#0000ff":
|
|
subject.editColor.setCurrentIndex(5)
|
|
if config.settingsCfg.has_option("Settings", "Theme") and config.settingsCfg["Settings"]["Theme"] == "Commodore":
|
|
subject.labelTitle.setStyleSheet("QLabel { color: " + config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] + "; background-color: " + tFore + "; font: 75 20pt; font: 75 20pt; border-image: None; }")
|
|
elif config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#dc38ff":
|
|
subject.editColor.setCurrentIndex(6)
|
|
elif config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#ff5bdf":
|
|
subject.editColor.setCurrentIndex(7)
|
|
elif config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] == "#757575":
|
|
subject.editColor.setCurrentIndex(8)
|
|
else:
|
|
subject.editColor.addItem(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"])
|
|
subject.editColor.setCurrentText(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"])
|
|
else:
|
|
subject.labelTitle.setStyleSheet("QLabel { font: 75 20pt 'Google Sans'; border-image: None; }")
|
|
subject.editColor.setCurrentIndex(0)
|
|
|
|
def getDouble():
|
|
global doublelessons
|
|
subject.comboDouble.clear()
|
|
subject.comboDouble.addItem("Single")
|
|
doublelessons = ["Single"]
|
|
|
|
existingdoubles = []
|
|
for i in range(1, 7):
|
|
if i != selectedTime.lesson and config.subjectsCfg.has_option(selectedTime.day + str(i), "DoubleFor") and config.subjectsCfg[selectedTime.day + str(i)]["DoubleFor"] != "" and config.subjectsCfg[selectedTime.day + str(i)]["DoubleFor"] != "Single":
|
|
existingdoubles.append(selectedTime.day + str(i))
|
|
existingdoubles.append((config.subjectsCfg[selectedTime.day + str(i)]["DoubleFor"]).title())
|
|
|
|
if (not selectedTime.day + str(selectedTime.lesson - 1) in existingdoubles) and (selectedTime.lesson == 2 or selectedTime.lesson == 4 or selectedTime.lesson == 5 or selectedTime.lesson == 7):
|
|
subject.comboDouble.addItem("Lesson " + str(selectedTime.lesson - 1))
|
|
doublelessons.append(selectedTime.day.lower() + str(selectedTime.lesson - 1))
|
|
if (not selectedTime.day + str(selectedTime.lesson + 1) in existingdoubles) and (selectedTime.lesson == 1 or selectedTime.lesson == 3 or selectedTime.lesson == 4 or selectedTime.lesson == 6):
|
|
subject.comboDouble.addItem("Lesson " + str(selectedTime.lesson + 1))
|
|
doublelessons.append(selectedTime.day.lower() + str(selectedTime.lesson + 1))
|
|
|
|
if config.subjectsCfg.has_option(selectedTime.day + str(selectedTime.lesson), "DoubleFor") and not config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["DoubleFor"] == "" and config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["DoubleFor"] in doublelessons:
|
|
subject.comboDouble.setCurrentIndex(doublelessons.index(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["DoubleFor"]))
|
|
else:
|
|
subject.comboDouble.setCurrentIndex(0)
|
|
|
|
####################
|
|
### SUBJECT LIST ###
|
|
####################
|
|
|
|
def getSubjectList():
|
|
global subjectnames, subjectcolors, subjectteachers
|
|
subjectnamestmp = []
|
|
subjectcolorstmp = []
|
|
subjectteacherstmp = []
|
|
for j in dayslist:
|
|
for i in range(1, 8):
|
|
if config.subjectsCfg.has_option(j + str(i), "SubjectName") and not config.subjectsCfg[j + str(i)]["SubjectName"] in subjectnamestmp:
|
|
subjectnamestmp.append(config.subjectsCfg[j + str(i)]["SubjectName"])
|
|
subjectcolorstmp.append(config.subjectsCfg[j + str(i)]["Color"])
|
|
if config.subjectsCfg.has_option(j + str(i), "Teacher"):
|
|
subjectteacherstmp.append(config.subjectsCfg[j + str(i)]["Teacher"])
|
|
else:
|
|
subjectteacherstmp.append("")
|
|
subjectnames = tuple(subjectnamestmp)
|
|
subjectcolors = tuple(subjectcolorstmp)
|
|
subjectteachers = tuple(subjectteacherstmp)
|
|
del(subjectnamestmp, subjectcolorstmp, subjectteacherstmp)
|
|
getSubjectList()
|
|
|
|
####################
|
|
### BUTTON LOGIC ###
|
|
####################
|
|
|
|
def finishCloseAnim():
|
|
subjectSlideAnimation.finished.disconnect()
|
|
subjectWindow.close()
|
|
|
|
def closeSubject():
|
|
global subjectSlideAnimation, subjectFadeAnimation
|
|
if not args.debug:
|
|
subjectSlideAnimation.setStartValue(subjectWindow.pos())
|
|
subjectSlideAnimation.setEndValue(QPoint(subjectWindow.x(), subjectWindow.y() - 25))
|
|
subjectSlideAnimation.finished.connect(finishCloseAnim)
|
|
|
|
subjectFadeAnimation.setStartValue(1)
|
|
subjectFadeAnimation.setEndValue(0)
|
|
|
|
subjectSlideAnimation.start()
|
|
|
|
subjectFadeAnimation.start()
|
|
else:
|
|
subjectWindow.close()
|
|
|
|
subject.buttonBack.clicked.connect(closeSubject)
|
|
|
|
assfilter = ""
|
|
def assignmentFromSubject():
|
|
global assfilter
|
|
assfilter = config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["SubjectName"]
|
|
showAssignmentsView()
|
|
subject.buttonAssignment.clicked.connect(assignmentFromSubject)
|
|
|
|
if not args.debug:
|
|
def switchToShadow():
|
|
global viewShadow, editShadow
|
|
viewShadow = QGraphicsDropShadowEffect()
|
|
viewShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
viewShadow.setBlurRadius(15)
|
|
viewShadow.setOffset(0)
|
|
editShadow = QGraphicsDropShadowEffect()
|
|
editShadow.setColor(QColor.fromRgb(0, 0, 0))
|
|
editShadow.setBlurRadius(15)
|
|
editShadow.setOffset(0)
|
|
|
|
subject.frameView.setGraphicsEffect(viewShadow)
|
|
subject.frameEdit.setGraphicsEffect(editShadow)
|
|
|
|
|
|
viewSlideAnimation = QPropertyAnimation(subject.frameView, b"pos")
|
|
viewSlideAnimation.setDuration(500)
|
|
viewSlideAnimation.setEasingCurve(QEasingCurve.InOutQuad)
|
|
editSlideAnimation = QPropertyAnimation(subject.frameEdit, b"pos")
|
|
editSlideAnimation.setDuration(500)
|
|
editSlideAnimation.setEasingCurve(QEasingCurve.InOutQuad)
|
|
|
|
def generateFadeAnimations():
|
|
global viewFadeAnimation, editFadeAnimation, viewFadeEffect, editFadeEffect
|
|
viewFadeEffect = QGraphicsOpacityEffect()
|
|
viewFadeEffect.setOpacity(1)
|
|
subject.frameView.setGraphicsEffect(viewFadeEffect)
|
|
viewFadeAnimation = QPropertyAnimation(viewFadeEffect, b"opacity")
|
|
viewFadeAnimation.setDuration(500)
|
|
viewFadeAnimation.setEasingCurve(QEasingCurve.Linear)
|
|
viewFadeAnimation.finished.connect(switchToShadow)
|
|
|
|
editFadeEffect = QGraphicsOpacityEffect()
|
|
editFadeEffect.setOpacity(1)
|
|
subject.frameEdit.setGraphicsEffect(editFadeEffect)
|
|
editFadeAnimation = QPropertyAnimation(editFadeEffect, b"opacity")
|
|
editFadeAnimation.setDuration(500)
|
|
editFadeAnimation.setEasingCurve(QEasingCurve.Linear)
|
|
editFadeAnimation.finished.connect(switchToShadow)
|
|
|
|
def finishSubjectAnimation(edit: bool):
|
|
global viewSlideAnimation, editSlideAnimation
|
|
subject.frameView.move(11, 11)
|
|
subject.frameEdit.move(11, 11)
|
|
if edit:
|
|
viewSlideAnimation.finished.disconnect()
|
|
subject.frameView.hide()
|
|
else:
|
|
editSlideAnimation.finished.disconnect()
|
|
subject.frameEdit.hide()
|
|
|
|
def viewSubject():
|
|
global viewSlideAnimation, editSlideAnimation
|
|
|
|
subject.frameView.show()
|
|
if not args.debug:
|
|
generateFadeAnimations()
|
|
viewFadeEffect.setOpacity(1)
|
|
viewSlideAnimation.setStartValue(QPoint(subject.frameView.x() - subject.frameEdit.width() + 22, subject.frameView.y()))
|
|
viewSlideAnimation.setEndValue(QPoint(11, 11))
|
|
|
|
editSlideAnimation.setStartValue(QPoint(11, 11))
|
|
editSlideAnimation.setEndValue(QPoint(subject.frameEdit.x() + subject.frameEdit.width() + 11, subject.frameEdit.y()))
|
|
editSlideAnimation.finished.connect(lambda: finishSubjectAnimation(False))
|
|
|
|
viewFadeAnimation.setStartValue(0)
|
|
viewFadeAnimation.setEndValue(1)
|
|
viewFadeAnimation.finished.connect(switchToShadow)
|
|
|
|
editFadeAnimation.setStartValue(1)
|
|
editFadeAnimation.setEndValue(0)
|
|
|
|
viewSlideAnimation.start()
|
|
editSlideAnimation.start()
|
|
|
|
subject.frameView.setGraphicsEffect(viewFadeEffect)
|
|
viewFadeAnimation.start()
|
|
subject.frameEdit.setGraphicsEffect(editFadeEffect)
|
|
editFadeAnimation.start()
|
|
else:
|
|
subject.frameEdit.hide()
|
|
|
|
subject.editButtonBack.clicked.connect(viewSubject)
|
|
|
|
def editSubject():
|
|
subject.frameEdit.show()
|
|
|
|
if not args.debug:
|
|
generateFadeAnimations()
|
|
global viewSlideAnimation, editSlideAnimation, viewFadeAnimation, editFadeAnimation
|
|
editFadeEffect.setOpacity(1)
|
|
viewSlideAnimation.setStartValue(QPoint(11, 11))
|
|
viewSlideAnimation.setEndValue(QPoint(subject.frameView.x() - subject.frameEdit.width() + 22, subject.frameView.y()))
|
|
viewSlideAnimation.finished.connect(lambda: finishSubjectAnimation(True))
|
|
|
|
editSlideAnimation.setStartValue(QPoint(subject.frameEdit.x() + subject.frameEdit.width() + 11, subject.frameEdit.y()))
|
|
editSlideAnimation.setEndValue(QPoint(11, 11))
|
|
|
|
viewFadeAnimation.setStartValue(1)
|
|
viewFadeAnimation.setEndValue(0)
|
|
|
|
editFadeAnimation.setStartValue(0)
|
|
editFadeAnimation.setEndValue(1)
|
|
|
|
viewSlideAnimation.start()
|
|
editSlideAnimation.start()
|
|
|
|
subject.frameView.setGraphicsEffect(viewFadeEffect)
|
|
viewFadeAnimation.start()
|
|
subject.frameEdit.setGraphicsEffect(editFadeEffect)
|
|
editFadeAnimation.start()
|
|
else:
|
|
subject.frameView.hide()
|
|
|
|
subject.buttonEdit.clicked.connect(editSubject)
|
|
|
|
def openOnline():
|
|
browser = webbrowser.get()
|
|
browser.open_new(config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Online"])
|
|
closeSubject()
|
|
subject.online.clicked.connect(openOnline)
|
|
|
|
def checkForCustomColor():
|
|
if subject.editColor.currentText() == "Custom":
|
|
colorselected = QColorDialog(QColor(255, 255, 255), subjectWindow).getColor()
|
|
if colorselected != QColor():
|
|
resetSubjectColors()
|
|
subject.editColor.addItem(colorselected.name())
|
|
subject.editColor.setCurrentText(colorselected.name())
|
|
|
|
subject.editColor.textActivated.connect(checkForCustomColor)
|
|
|
|
def saveSubject():
|
|
global selectedTime
|
|
viewSubject()
|
|
|
|
####################
|
|
### SAVE CHANGES ###
|
|
####################
|
|
|
|
if not config.subjectsCfg.has_section(selectedTime.day + str(selectedTime.lesson)):
|
|
config.subjectsCfg.add_section(selectedTime.day + str(selectedTime.lesson))
|
|
if subject.editTitle.text() != False:
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["SubjectName"] = subject.editTitle.text()
|
|
if subject.editTeacher.text() != False:
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Teacher"] = subject.editTeacher.text()
|
|
if subject.editRoom.text() != False:
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Room"] = subject.editRoom.text()
|
|
if subject.editOnline.text() != False:
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Online"] = subject.editOnline.text()
|
|
if subject.editNotes.toPlainText() != False:
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Notes"] = subject.editNotes.toPlainText()
|
|
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["DoubleFor"] = doublelessons[subject.comboDouble.currentIndex()]
|
|
|
|
if subject.editColor.currentText() == "None":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "None"
|
|
elif subject.editColor.currentText() == "Red":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#ff0000"
|
|
elif subject.editColor.currentText() == "Orange":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#ffa000"
|
|
elif subject.editColor.currentText() == "Yellow":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#d7d241"
|
|
elif subject.editColor.currentText() == "Green":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#00aa41"
|
|
elif subject.editColor.currentText() == "Blue":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#0000ff"
|
|
elif subject.editColor.currentText() == "Purple":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#dc38ff"
|
|
elif subject.editColor.currentText() == "Pink":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#ff5bdf"
|
|
elif subject.editColor.currentText() == "Gray":
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = "#757575"
|
|
else:
|
|
config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"] = subject.editColor.currentText()
|
|
|
|
if subject.applyToAll.isChecked():
|
|
for j in dayslist:
|
|
for i in range(1, 8):
|
|
if config.subjectsCfg.has_option(j + str(i), "SubjectName") and config.subjectsCfg[j + str(i)]["SubjectName"] == config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["SubjectName"]:
|
|
config.subjectsCfg[j + str(i)]["Teacher"] = config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Teacher"]
|
|
config.subjectsCfg[j + str(i)]["Room"] = config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Room"]
|
|
config.subjectsCfg[j + str(i)]["Online"] = config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Online"]
|
|
config.subjectsCfg[j + str(i)]["Color"] = config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Color"]
|
|
config.subjectsCfg[j + str(i)]["Notes"] = config.subjectsCfg[selectedTime.day + str(selectedTime.lesson)]["Notes"]
|
|
|
|
config.writeSubjects()
|
|
|
|
getSubjectTitle()
|
|
getTeacher()
|
|
getRoom()
|
|
getOnline()
|
|
getColor()
|
|
getNotes()
|
|
getDouble()
|
|
refresh()
|
|
getSubjectList()
|
|
|
|
if sys.platform == "win32":
|
|
subjectWindow.hide()
|
|
subjectWindow.show()
|
|
|
|
subject.editButtonSave.clicked.connect(saveSubject)
|
|
|
|
def hideCopyLabel():
|
|
global fadeAnimation, fadeEffect
|
|
fadeAnimation.setStartValue(1)
|
|
fadeAnimation.setEndValue(0)
|
|
fadeAnimation.start(QPropertyAnimation.DeleteWhenStopped)
|
|
fadeAnimation.finished.connect(subject.labelCopied.hide)
|
|
|
|
def copySubject():
|
|
global fadeAnimation, fadeEffect
|
|
subject.labelCopied.show()
|
|
fadeEffect = QGraphicsOpacityEffect()
|
|
subject.labelCopied.setGraphicsEffect(fadeEffect)
|
|
fadeAnimation = QPropertyAnimation(fadeEffect, b"opacity")
|
|
fadeAnimation.setStartValue(0)
|
|
fadeAnimation.setEndValue(1)
|
|
fadeAnimation.setDuration(350)
|
|
fadeAnimation.setEasingCurve(QEasingCurve.Linear)
|
|
fadeAnimation.start()
|
|
QTimer.singleShot(1000, hideCopyLabel)
|
|
global copiedsubject
|
|
copiedsubject = selectedTime.day + str(selectedTime.lesson)
|
|
|
|
subject.buttonCopy.clicked.connect(copySubject)
|
|
|
|
def pasteSubject():
|
|
if config.subjectsCfg.has_option(copiedsubject, "SubjectName") and not config.subjectsCfg[copiedsubject]["SubjectName"] == "":
|
|
subject.editTitle.setText(config.subjectsCfg[copiedsubject]["SubjectName"])
|
|
else:
|
|
subject.editTitle.setText("")
|
|
|
|
if config.subjectsCfg.has_option(copiedsubject, "Teacher") and not config.subjectsCfg[copiedsubject]["Teacher"] == "":
|
|
subject.editTeacher.setText(config.subjectsCfg[copiedsubject]["Teacher"])
|
|
else:
|
|
subject.editTeacher.setText("")
|
|
|
|
if config.subjectsCfg.has_option(copiedsubject, "Room") and not config.subjectsCfg[copiedsubject]["Room"] == "":
|
|
subject.editRoom.setText(config.subjectsCfg[copiedsubject]["Room"])
|
|
else:
|
|
subject.editRoom.setText("")
|
|
|
|
if config.subjectsCfg.has_option(copiedsubject, "Online") and not config.subjectsCfg[copiedsubject]["Online"] == "":
|
|
subject.editOnline.setText(config.subjectsCfg[copiedsubject]["Online"])
|
|
else:
|
|
subject.editOnline.setText("")
|
|
|
|
if config.subjectsCfg.has_option(copiedsubject, "Notes") and not config.subjectsCfg[copiedsubject]["Notes"] == "":
|
|
subject.editOnline.setText(config.subjectsCfg[copiedsubject]["Notes"])
|
|
else:
|
|
subject.editOnline.setText("")
|
|
|
|
if config.subjectsCfg.has_option(copiedsubject, "Color") and not (config.subjectsCfg[copiedsubject]["Color"] == "" or config.subjectsCfg[copiedsubject]["Color"] == "None"):
|
|
if config.subjectsCfg[copiedsubject]["Color"] == "#ff0000":
|
|
subject.editColor.setCurrentIndex(1)
|
|
elif config.subjectsCfg[copiedsubject]["Color"] == "#ffa000":
|
|
subject.editColor.setCurrentIndex(2)
|
|
elif config.subjectsCfg[copiedsubject]["Color"] == "#d7d241":
|
|
subject.editColor.setCurrentIndex(3)
|
|
elif config.subjectsCfg[copiedsubject]["Color"] == "#00aa41":
|
|
subject.editColor.setCurrentIndex(4)
|
|
elif config.subjectsCfg[copiedsubject]["Color"] == "#0000ff":
|
|
subject.editColor.setCurrentIndex(5)
|
|
elif config.subjectsCfg[copiedsubject]["Color"] == "#dc38ff":
|
|
subject.editColor.setCurrentIndex(6)
|
|
elif config.subjectsCfg[copiedsubject]["Color"] == "#ff5bdf":
|
|
subject.editColor.setCurrentIndex(7)
|
|
elif config.subjectsCfg[copiedsubject]["Color"] == "#757575":
|
|
subject.editColor.setCurrentIndex(8)
|
|
else:
|
|
subject.editColor.addItem(config.subjectsCfg[copiedsubject]["Color"])
|
|
subject.editColor.setCurrentText(config.subjectsCfg[copiedsubject]["Color"])
|
|
else:
|
|
subject.editColor.setCurrentIndex(0)
|
|
|
|
subject.buttonPaste.clicked.connect(pasteSubject)
|
|
|
|
######################
|
|
### SETTINGS LOGIC ###
|
|
######################
|
|
|
|
def showTheme():
|
|
settingsWindow.hide()
|
|
loadTheme()
|
|
toCentre(themesWindow, timetableWindow)
|
|
themesWindow.show()
|
|
settings.buttonTheme.clicked.connect(showTheme)
|
|
|
|
def importSettings():
|
|
importfile = QFileDialog.getOpenFileName()
|
|
if importfile[0] and importfile[0] != "":
|
|
copy(importfile[0], config.tablefile)
|
|
with open(config.tablefile, "r") as file:
|
|
filedata = file.read()
|
|
|
|
filedata = filedata.replace('"', "")
|
|
|
|
with open(config.tablefile, "w") as file:
|
|
file.write(filedata)
|
|
|
|
config.subjectsCfg.read(config.tablefile)
|
|
print("Imported timetable")
|
|
refresh()
|
|
|
|
settings.buttonImport.clicked.connect(importSettings)
|
|
|
|
def exportSettings():
|
|
exportDialog = QFileDialog()
|
|
exportDialog.setDefaultSuffix("tbl")
|
|
exportDialog.selectFile("myFileName")
|
|
exportfile = exportDialog.getSaveFileName(timetableWindow, "Save file", os.path.join(os.path.expanduser("~"), "Documents/timetable.tbl"))
|
|
if exportfile[0] and exportfile[0] != "":
|
|
copy(config.tablefile, exportfile[0])
|
|
print("Exported configuration")
|
|
settings.buttonExport.clicked.connect(exportSettings)
|
|
|
|
def saveSettings():
|
|
global chosentheme, settingschanged
|
|
if not config.settingsCfg.has_section("Settings"):
|
|
config.settingsCfg.add_section("Settings")
|
|
config.writeSettings()
|
|
|
|
if not config.settingsCfg.has_option("Settings", "Name") or config.settingsCfg["Settings"]["Name"] != settings.editName.text():
|
|
config.settingsCfg["Settings"]["Name"] = settings.editName.text()
|
|
|
|
if not config.settingsCfg.has_option("Settings", "Border") or (config.settingsCfg["Settings"]["Border"] == "False" and settings.checkBorder.isChecked()) or (config.settingsCfg["Settings"]["Border"] == "True" and not settings.checkBorder.isChecked()):
|
|
config.settingsCfg["Settings"]["Border"] = str(settings.checkBorder.isChecked())
|
|
|
|
if not config.settingsCfg.has_option("Settings", "Theme") or (chosentheme != "" and chosentheme != config.settingsCfg["Settings"]["Theme"]):
|
|
config.settingsCfg["Settings"]["Theme"] = chosentheme
|
|
chosentheme = ""
|
|
|
|
settingsWindow.close()
|
|
refreshSettings()
|
|
config.writeSettings()
|
|
settings.buttonSave.clicked.connect(saveSettings)
|
|
|
|
settings.buttonBack.clicked.connect(settingsWindow.close)
|
|
|
|
if sys.platform != "linux":
|
|
def buyKey():
|
|
keyimporter = QFileDialog
|
|
keyfile = keyimporter.getOpenFileName(timetableWindow, "Import Key", os.path.expanduser("~/Downloads"))
|
|
if keyfile[0] and keyfile[0] != "":
|
|
copy(keyfile[0], os.path.join(config.confdir, "timetable.key"))
|
|
QMessageBox.information(timetableWindow, "Import successful", "The key was imported successfully, please restart the application.", QMessageBox.Ok)
|
|
buyWindow.close()
|
|
print("Imported key")
|
|
quit()
|
|
buy.buttonLoad.clicked.connect(buyKey)
|
|
|
|
def showBuy():
|
|
settingsWindow.hide()
|
|
buyWindow.show()
|
|
|
|
if (themekey.unlockkey and themekey.keyData["Options"]["Default"] == "True" and themekey.keyData["Options"]["Galaxy"] == "True" and themekey.keyData["Options"]["Meenu"] == "True" and themekey.keyData["Options"]["Keely"] == "True" and themekey.keyData["Options"]["Commodore"] == "True" and themekey.keyData["Options"]["Terminal"] == "True" and themekey.keyData["Options"]["Ubuntu"] == "True" and themekey.keyData["Options"]["Blue Flame"] == "True" and themekey.keyData["Options"]["Custom"] == "True" and themekey.keyData["Options"]["Name"] == "True"):
|
|
settings.buttonMore.hide()
|
|
elif themekey.unlockkey:
|
|
settings.buttonMore.show()
|
|
settings.buttonMore.clicked.connect(buyKey)
|
|
elif not themekey.unlockkey:
|
|
settings.buttonMore.show()
|
|
settings.buttonMore.clicked.connect(showBuy)
|
|
|
|
def buyBack():
|
|
buyWindow.close()
|
|
settingsWindow.show()
|
|
buy.buttonBack.clicked.connect(buyBack)
|
|
|
|
def showInfo():
|
|
buy.frameBuy.hide()
|
|
buy.frameInfo.show()
|
|
buy.buttonInfo.clicked.connect(showInfo)
|
|
|
|
def backInfo():
|
|
buy.frameBuy.show()
|
|
buy.frameInfo.hide()
|
|
buy.buttonBack2.clicked.connect(backInfo)
|
|
elif sys.platform == "linux":
|
|
settings.buttonMore.hide()
|
|
|
|
###################
|
|
### THEME LOGIC ###
|
|
###################
|
|
themeslist = list(themecolors.foreground.keys())
|
|
themeslist.append("Custom")
|
|
def loadTheme():
|
|
global themeselected
|
|
|
|
for i in range(len(themeframes)):
|
|
unHighlightHoveredTheme(themename=themeslist[i], framename=themeframes[i])
|
|
|
|
if not themeselected:
|
|
if (sys.platform == "linux") or (themekey.unlockkey and themekey.keyData["Options"]["Default"] == "True"):
|
|
themeselected = "Default"
|
|
else:
|
|
themeselected = "Light"
|
|
themeframes[themeslist.index(themeselected)].setStyleSheet("background-color: " + tFore + "; border-radius: 7px;")
|
|
newSelectShadow()
|
|
themeframes[themeslist.index(themeselected)].setGraphicsEffect(selectShadow)
|
|
|
|
chosentheme = ""
|
|
|
|
def saveTheme():
|
|
global chosentheme
|
|
chosentheme = themeselected
|
|
if chosentheme != "":
|
|
settings.labelTheme.setText("<strong>Theme:</strong> " + chosentheme)
|
|
themesWindow.close()
|
|
customWindow.close()
|
|
settingsWindow.show()
|
|
settingsWindow.raise_()
|
|
themes.buttonOK.clicked.connect(saveTheme)
|
|
|
|
##################
|
|
### HIGHLIGHTS ###
|
|
##################
|
|
|
|
themeselected = ""
|
|
|
|
def highlightHoveredTheme(event=None, themename="", framename=None):
|
|
if themeselected != themename:
|
|
if (sys.platform == "linux") or (themename in ("Light", "Woodcroft", "Hot Dog Stand")) or (themekey.unlockkey and themekey.keyData["Options"][themename] == "True"):
|
|
framename.setStyleSheet("background-color: " + tBackAlt + "; border-radius: 7px;")
|
|
newHoverShadow()
|
|
framename.setGraphicsEffect(hoverShadow)
|
|
def unHighlightHoveredTheme(event=None, themename="", framename=None):
|
|
if themeselected != themename:
|
|
framename.setStyleSheet("background-color: " + tBack + "; border-radius: 7px;")
|
|
framename.setGraphicsEffect(None)
|
|
|
|
######################
|
|
### CLICKED EVENTS ###
|
|
######################
|
|
|
|
themeframes = (themes.frameDefault, themes.frameLight, themes.frameWoodcroft, themes.frameHotDog, themes.frameGalaxy, themes.frameMeenu, themes.frameKeely, themes.frameCommodore, themes.frameTerminal, themes.frameUbuntu, themes.frameBlueFlame, themes.frameCustom)
|
|
|
|
def highlightSelectedTheme(event=None, themename="", framename=None):
|
|
global themeselected
|
|
themeselected = themename
|
|
themeframestmp = list(themeframes)
|
|
framename.setStyleSheet("background-color: " + tFore + "; border-radius: 7px;")
|
|
newSelectShadow()
|
|
framename.setGraphicsEffect(selectShadow)
|
|
|
|
themeframestmp.remove(framename)
|
|
for theme in themeframestmp:
|
|
theme.setStyleSheet("background-color: " + tBack + "; border-radius: 7px;")
|
|
themesWindow.repaint()
|
|
|
|
for i in range(len(themeframes)):
|
|
themeframes[i].enterEvent = lambda event, i=i: highlightHoveredTheme(themename=themeslist[i], framename=themeframes[i])
|
|
themeframes[i].leaveEvent = lambda event, i=i: unHighlightHoveredTheme(themename=themeslist[i], framename=themeframes[i])
|
|
themeframes[i].mousePressEvent = lambda event, i=i: highlightSelectedTheme(themename=themeslist[i], framename=themeframes[i])
|
|
|
|
def editCustom():
|
|
loadCustom()
|
|
customWindow.show()
|
|
settingsWindow.raise_()
|
|
themes.buttonCustom.clicked.connect(editCustom)
|
|
|
|
def themeClose(event):
|
|
themesWindow.close()
|
|
customWindow.close()
|
|
settingsWindow.show()
|
|
settingsWindow.raise_()
|
|
themesWindow.closeEvent = themeClose
|
|
|
|
#####################
|
|
### CUSTOM THEMES ###
|
|
#####################
|
|
|
|
def loadCustom():
|
|
if config.settingsCfg.has_option("CustomTheme", "tForeR") and config.settingsCfg["CustomTheme"]["tForeR"] != "":
|
|
custom.spinForeR.setValue(int(config.settingsCfg["CustomTheme"]["tForeR"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tForeG") and config.settingsCfg["CustomTheme"]["tForeG"] != "":
|
|
custom.spinForeG.setValue(int(config.settingsCfg["CustomTheme"]["tForeG"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tForeB") and config.settingsCfg["CustomTheme"]["tForeB"] != "":
|
|
custom.spinForeB.setValue(int(config.settingsCfg["CustomTheme"]["tForeB"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tBackR") and config.settingsCfg["CustomTheme"]["tBackR"] != "":
|
|
custom.spinBackR.setValue(int(config.settingsCfg["CustomTheme"]["tBackR"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tBackG") and config.settingsCfg["CustomTheme"]["tBackG"] != "":
|
|
custom.spinBackG.setValue(int(config.settingsCfg["CustomTheme"]["tBackG"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tBackB") and config.settingsCfg["CustomTheme"]["tBackB"] != "":
|
|
custom.spinBackB.setValue(int(config.settingsCfg["CustomTheme"]["tBackB"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tBackAltR") and config.settingsCfg["CustomTheme"]["tBackAltR"] != "":
|
|
custom.spinBackAltR.setValue(int(config.settingsCfg["CustomTheme"]["tBackAltR"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tBackAltG") and config.settingsCfg["CustomTheme"]["tBackAltG"] != "":
|
|
custom.spinBackAltG.setValue(int(config.settingsCfg["CustomTheme"]["tBackAltG"]))
|
|
if config.settingsCfg.has_option("CustomTheme", "tBackAltB") and config.settingsCfg["CustomTheme"]["tBackAltB"] != "":
|
|
custom.spinBackAltB.setValue(int(config.settingsCfg["CustomTheme"]["tBackAltB"]))
|
|
toCentre(customWindow, themesWindow)
|
|
|
|
def saveCustom():
|
|
global settingschanged, themeselected
|
|
settingschanged = True
|
|
if not config.settingsCfg.has_section("CustomTheme"):
|
|
config.settingsCfg.add_section("CustomTheme")
|
|
config.settingsCfg["CustomTheme"]["tForeR"] = custom.spinForeR.text()
|
|
config.settingsCfg["CustomTheme"]["tForeG"] = custom.spinForeG.text()
|
|
config.settingsCfg["CustomTheme"]["tForeB"] = custom.spinForeB.text()
|
|
config.settingsCfg["CustomTheme"]["tBackR"] = custom.spinBackR.text()
|
|
config.settingsCfg["CustomTheme"]["tBackG"] = custom.spinBackG.text()
|
|
config.settingsCfg["CustomTheme"]["tBackB"] = custom.spinBackB.text()
|
|
config.settingsCfg["CustomTheme"]["tBackAltR"] = custom.spinBackAltR.text()
|
|
config.settingsCfg["CustomTheme"]["tBackAltG"] = custom.spinBackAltG.text()
|
|
config.settingsCfg["CustomTheme"]["tBackAltB"] = custom.spinBackAltB.text()
|
|
|
|
config.settingsCfg["CustomTheme"]["tFore"] = "rgb("+config.settingsCfg["CustomTheme"]["tForeR"]+", "+config.settingsCfg["CustomTheme"]["tForeG"]+", "+config.settingsCfg["CustomTheme"]["tForeB"]+")"
|
|
config.settingsCfg["CustomTheme"]["tBack"] = "rgb("+config.settingsCfg["CustomTheme"]["tBackR"]+", "+config.settingsCfg["CustomTheme"]["tBackG"]+", "+config.settingsCfg["CustomTheme"]["tBackB"]+")"
|
|
config.settingsCfg["CustomTheme"]["tBackAlt"] = "rgb("+config.settingsCfg["CustomTheme"]["tBackAltR"]+", "+config.settingsCfg["CustomTheme"]["tBackAltG"]+", "+config.settingsCfg["CustomTheme"]["tBackAltB"]+")"
|
|
|
|
themeselected = "Custom"
|
|
saveTheme()
|
|
|
|
config.writeSettings()
|
|
customWindow.close()
|
|
custom.buttonSave.clicked.connect(saveCustom)
|
|
|
|
#############
|
|
### RESET ###
|
|
#############
|
|
|
|
def RESET():
|
|
if sys.platform != "linux" and themekey.unlockkey:
|
|
resetwarning = QMessageBox.warning(settingsWindow, "Are you sure?", "This will erase all your selectedTime.lessons, assignments, themes and customisations. As well as all your purchases (make sure you still have your key). Are you sure you want to continue?", QMessageBox.Yes, QMessageBox.No)
|
|
else:
|
|
resetwarning = QMessageBox.warning(settingsWindow, "Are you sure?", "This will erase all your selectedTime.lessons, assignments, themes and customisations. Are you sure you want to continue?", QMessageBox.Yes, QMessageBox.No)
|
|
if resetwarning == QMessageBox.Yes:
|
|
print("Deleting configuration")
|
|
rmtree(config.confdir)
|
|
QMessageBox.information(settingsWindow, "Reset complete", "The application will now close.")
|
|
quit()
|
|
settings.buttonReset.clicked.connect(RESET)
|
|
|
|
###################
|
|
### ASSIGNMENTS ###
|
|
###################
|
|
|
|
def lessonHasColor(lessonname):
|
|
try:
|
|
subjectnames.index(lessonname)
|
|
except ValueError:
|
|
return False
|
|
return True
|
|
|
|
assignmentWidgets, assignments = {}, {}
|
|
|
|
def showAssignmentsView(show=True):
|
|
global assignmentWidgets
|
|
for i in assignmentWidgets:
|
|
assignmentWidgets[i].deleteLater()
|
|
assignmentWidgets.clear()
|
|
if assfilter == "" or not assfilter:
|
|
assignmentsView.labelTitle.setText("<html><head/><body><p><span style=\" font-size:14pt; font-weight:600;\">Assignments</span></p></body></html>")
|
|
else:
|
|
assignmentsView.labelTitle.setText("<html><head/><body><p><span style=\" font-size:14pt; font-weight:600;\">Assignments from " + assfilter + "</span></p></body></html>")
|
|
hasassignments = False
|
|
for i in range(len(config.assignmentsCfg.sections())):
|
|
if assfilter == "" or not assfilter or assfilter == config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Lesson"]:
|
|
hasassignments = True
|
|
assignmentWidgets["assignmentWidget" + str(i)] = QWidget()
|
|
assignments["assignment" + str(i)] = assignment_ui_Form()
|
|
assignments["assignment" + str(i)].setupUi(assignmentWidgets["assignmentWidget" + str(i)])
|
|
assignmentWidgets["assignmentWidget" + str(i)].setObjectName("assignment" + str(i) + "Widget")
|
|
assignmentWidgets["assignmentWidget" + str(i)].setStyleSheet(".QWidget, QLabel { background-color: " + tBackAlt + "; border-radius: 7px; } QPushButton { background-color: " + tBackAlt + "; }")
|
|
assignments["assignment" + str(i)].buttonClose.setIcon(icons["close"])
|
|
assignments["assignment" + str(i)].buttonEdit.setIcon(icons["edit"])
|
|
assignments["assignment" + str(i)].buttonClose.clicked.connect(lambda event=False, i=i: rmAssignment(config.assignmentsCfg.sections()[i], i))
|
|
assignments["assignment" + str(i)].buttonEdit.clicked.connect(lambda event=False, i=i: editAssignment(config.assignmentsCfg.sections()[i]))
|
|
assignments["assignment" + str(i)].buttonNotif.clicked.connect(lambda event=False, i=i: toggleNotif(config.assignmentsCfg.sections()[i], i))
|
|
if config.assignmentsCfg.has_option(config.assignmentsCfg.sections()[i], "Lesson"):
|
|
assignments["assignment" + str(i)].labelLesson.setText("<html><head/><body><p><span style=\" font-size:16pt; font-weight:600;\">" + config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Lesson"] + "</span></p></body></html>")
|
|
if lessonHasColor(config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Lesson"]):
|
|
assignments["assignment" + str(i)].labelLesson.setStyleSheet("color: " + subjectcolors[subjectnames.index(config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Lesson"])] + ";")
|
|
else:
|
|
print("I need a hug")
|
|
assignments["assignment" + str(i)].labelLesson.setStyleSheet("color: " + tFore + ";")
|
|
if config.assignmentsCfg.has_option(config.assignmentsCfg.sections()[i], "Name"):
|
|
assignments["assignment" + str(i)].labelTitle.setText(config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Name"])
|
|
if config.assignmentsCfg.has_option(config.assignmentsCfg.sections()[i], "Description"):
|
|
assignments["assignment" + str(i)].labelDesc.setText(config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Description"])
|
|
if config.assignmentsCfg.has_option(config.assignmentsCfg.sections()[i], "Date") and config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Date"] == datetime.date.today().strftime("%d/%m/%Y"):
|
|
assignments["assignment" + str(i)].labelDate.setText("<strong>DUE TODAY!</strong> " + config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Date"])
|
|
elif config.assignmentsCfg.has_option(config.assignmentsCfg.sections()[i], "Date"):
|
|
assignments["assignment" + str(i)].labelDate.setText(config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Date"])
|
|
if config.assignmentsCfg.has_option(config.assignmentsCfg.sections()[i], "Time"):
|
|
assignments["assignment" + str(i)].labelDate.setText(assignments["assignment" + str(i)].labelDate.text() + ", " + config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Time"])
|
|
else:
|
|
print("I worked hard on that feature, y'know")
|
|
if config.assignmentsCfg.has_option(config.assignmentsCfg.sections()[i], "Notifications"):
|
|
if config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Notifications"] == "True":
|
|
assignments["assignment" + str(i)].buttonNotif.setIcon(icons["notif"])
|
|
elif config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Notifications"] == "False":
|
|
assignments["assignment" + str(i)].buttonNotif.setIcon(icons["notifdisable"])
|
|
else:
|
|
config.assignmentsCfg[config.assignmentsCfg.sections()[i]]["Notifications"] = "True"
|
|
assignments["assignment" + str(i)].buttonNotif.setIcon(icons["notif"])
|
|
assignmentWidgets["assignmentWidget" + str(i)].setParent(assignmentsView.scrollAreaWidgetContents)
|
|
assignmentsView.assignmentAreaVerticalLayout.addWidget(assignmentWidgets["assignmentWidget" + str(i)])
|
|
if not hasassignments:
|
|
assignmentsView.labelNone.show()
|
|
else:
|
|
assignmentsView.labelNone.hide()
|
|
toCentre(assignmentsViewWindow, timetableWindow)
|
|
if show:
|
|
assignmentsViewWindow.show()
|
|
upDATE()
|
|
print("Showing assignments")
|
|
|
|
def assignmentFromHome():
|
|
global assfilter
|
|
assfilter = ""
|
|
showAssignmentsView()
|
|
timetable.buttonAssignments.clicked.connect(assignmentFromHome)
|
|
|
|
def closeAssignments():
|
|
config.writeAssignments()
|
|
assignmentsViewWindow.close()
|
|
assignmentsView.buttonClose.clicked.connect(closeAssignments)
|
|
|
|
def rmAssignment(assnum, widgetnum):
|
|
assignmentWidgets["assignmentWidget" + str(widgetnum)].hide()
|
|
assignmentWidgets["assignmentWidget" + str(widgetnum)].deleteLater()
|
|
assignmentWidgets.pop("assignmentWidget" + str(widgetnum))
|
|
assignments.pop("assignment" + str(widgetnum))
|
|
config.assignmentsCfg.remove_section(assnum)
|
|
config.writeAssignments()
|
|
if len(assignmentWidgets) == 0:
|
|
assignmentsView.labelNone.show()
|
|
else:
|
|
assignmentsView.labelNone.hide()
|
|
getNearAssignments()
|
|
showAssignmentsView(False)
|
|
|
|
assignmentno = ""
|
|
|
|
def toggleNotif(assnum, widgetnum):
|
|
if config.assignmentsCfg.has_option(assnum, "Notifications"):
|
|
if config.assignmentsCfg[assnum]["Notifications"] == "False":
|
|
config.assignmentsCfg[assnum]["Notifications"] = "True"
|
|
assignments["assignment" + str(widgetnum)].buttonNotif.setIcon(icons["notif"])
|
|
elif config.assignmentsCfg[assnum]["Notifications"] == "True":
|
|
config.assignmentsCfg[assnum]["Notifications"] = "False"
|
|
assignments["assignment" + str(widgetnum)].buttonNotif.setIcon(icons["notifdisable"])
|
|
else:
|
|
config.assignmentsCfg[assnum]["Notifications"] = "False"
|
|
assignments["assignment" + str(widgetnum)].buttonNotif.setIcon(icons["notifdisable"])
|
|
config.writeAssignments()
|
|
|
|
assignmentsView.buttonAdd.clicked.connect(lambda: editAssignment(-1))
|
|
assignmentsAdd.buttonCancel.clicked.connect(assignmentsAddWindow.close)
|
|
|
|
def saveAssignment():
|
|
global assignmentno, newassignment
|
|
if newassignment:
|
|
cont = True
|
|
i = 0
|
|
while cont:
|
|
if config.assignmentsCfg.has_section("Assignment" + str(i)):
|
|
i += 1
|
|
else:
|
|
assignmentno = "Assignment" + str(i)
|
|
config.assignmentsCfg.add_section("Assignment" + str(i))
|
|
cont = False
|
|
config.assignmentsCfg[assignmentno]["Lesson"] = assignmentsAdd.comboLesson.currentText()
|
|
config.assignmentsCfg[assignmentno]["Name"] = assignmentsAdd.editName.text()
|
|
config.assignmentsCfg[assignmentno]["Description"] = assignmentsAdd.editDesc.text()
|
|
config.assignmentsCfg[assignmentno]["Date"] = assignmentsAdd.editDate.date().toString("dd/MM/yyyy")
|
|
config.assignmentsCfg[assignmentno]["Time"] = assignmentsAdd.editTime.time().toString("hh:mm A")
|
|
config.writeAssignments()
|
|
getNearAssignments()
|
|
assignmentsAddWindow.close()
|
|
showAssignmentsView()
|
|
assignmentsAdd.buttonOK.clicked.connect(saveAssignment)
|
|
assignmentsAdd.buttonCancel.clicked.connect(assignmentsAddWindow.close)
|
|
|
|
def editAssignment(assnum):
|
|
global assignmentno, newassignment
|
|
if assnum == -1:
|
|
newassignment = True
|
|
else:
|
|
newassignment = False
|
|
assignmentno = assnum
|
|
|
|
assignmentsAdd.comboLesson.clear()
|
|
for i in range(len(subjectnames)):
|
|
assignmentsAdd.comboLesson.addItem(subjectnames[i])
|
|
|
|
if config.assignmentsCfg.has_option(assnum, "Lesson"):
|
|
assignmentsAdd.comboLesson.setCurrentText(config.assignmentsCfg[assnum]["Lesson"])
|
|
elif assfilter != "":
|
|
assignmentsAdd.comboLesson.setCurrentText(assfilter)
|
|
assignmentsAdd.comboLesson.setEnabled(False)
|
|
else:
|
|
assignmentsAdd.comboLesson.setCurrentIndex(0)
|
|
assignmentsAdd.comboLesson.setEnabled(True)
|
|
if config.assignmentsCfg.has_option(assnum, "Name"):
|
|
assignmentsAdd.editName.setText(config.assignmentsCfg[assnum]["Name"])
|
|
else:
|
|
assignmentsAdd.editName.setText("")
|
|
if config.assignmentsCfg.has_option(assnum, "Description"):
|
|
assignmentsAdd.editDesc.setText(config.assignmentsCfg[assnum]["Description"])
|
|
else:
|
|
assignmentsAdd.editDesc.setText("")
|
|
if config.assignmentsCfg.has_option(assnum, "Date"):
|
|
assignmentsAdd.editDate.setDate(QDate.fromString(config.assignmentsCfg[assnum]["Date"], "dd/MM/yyyy"))
|
|
else:
|
|
assignmentsAdd.editDate.setDate(QDate.fromString(datetime.date.today().strftime("%Y/%m/%d"), Qt.ISODate))
|
|
if config.assignmentsCfg.has_option(assnum, "Time"):
|
|
assignmentsAdd.editTime.setTime(QTime.fromString(config.assignmentsCfg[assnum]["Time"], "hh:mm A"))
|
|
else:
|
|
assignmentsAdd.editTime.setTime(QTime.fromString(datetime.datetime.now().strftime("%I:%M %p"), "hh:mm A"))
|
|
toCentre(assignmentsAddWindow, assignmentsViewWindow)
|
|
|
|
checkForAssignmentTitle()
|
|
assignmentsAddWindow.show()
|
|
|
|
def checkForAssignmentTitle():
|
|
# Broken on windows, disable it for now until it's fixed
|
|
if sys.platform != "win32":
|
|
if assignmentsAdd.editName.text() != "":
|
|
assignmentsAdd.buttonOK.setEnabled(True)
|
|
else:
|
|
assignmentsAdd.buttonOK.setEnabled(False)
|
|
assignmentsAdd.editName.textChanged.connect(checkForAssignmentTitle)
|
|
|
|
def getNearAssignments(notify=False):
|
|
mark = False
|
|
assignmentswithnotification = 0
|
|
for i in range(len(config.assignmentsCfg.sections())):
|
|
if config.assignmentsCfg.has_option("Assignment" + str(i), "Notifications") and config.assignmentsCfg["Assignment" + str(i)]["Notifications"] == "True" and config.assignmentsCfg.has_option("Assignment" + str(i), "Date") and datetime.datetime.strptime(config.assignmentsCfg["Assignment" + str(i)]["Date"], "%d/%m/%Y").date() == datetime.date.today():
|
|
if notify:
|
|
assignmentswithnotification += 1
|
|
timetable.buttonAssignments.setIcon(icons["due"])
|
|
mark = True
|
|
elif config.assignmentsCfg.has_option("Assignment" + str(i), "Date") and (datetime.datetime.strptime(config.assignmentsCfg["Assignment" + str(i)]["Date"], "%d/%m/%Y").date() < datetime.date.today()):
|
|
timetable.buttonAssignments.setIcon(icons["overdue"])
|
|
mark = True
|
|
if assignmentswithnotification >= 1:
|
|
reminder = Notify()
|
|
reminder.title = "Assignment due today"
|
|
reminder.application_name = "Timetable"
|
|
reminder.icon = "./assets/ui/icon.png"
|
|
if assignmentswithnotification > 1:
|
|
reminder.message = "You've got multiple assignments due today, good luck."
|
|
else:
|
|
reminder.message = "You've got an assignment due today."
|
|
reminder.send()
|
|
if not mark:
|
|
timetable.buttonAssignments.setIcon(QIcon(None))
|
|
if len(config.assignmentsCfg.sections()) > 0:
|
|
timetable.buttonAssignments.setText("Assignments (" + str(len(config.assignmentsCfg.sections())) + ")")
|
|
else:
|
|
timetable.buttonAssignments.setText("Assignments")
|
|
|
|
def checkAssignmentTime(firstlaunch=False):
|
|
notificationsent = False
|
|
for i in range(len(config.assignmentsCfg.sections())):
|
|
if config.assignmentsCfg.has_option("Assignment" + str(i), "Date") and config.assignmentsCfg["Assignment" + str(i)]["Date"] == datetime.date.today().strftime("%d/%m/%Y") and config.assignmentsCfg.has_option("Assignment" + str(i), "Notifications") and config.assignmentsCfg["Assignment" + str(i)]["Notifications"] == "True" and config.assignmentsCfg.has_option("Assignment" + str(i), "Time") and config.assignmentsCfg["Assignment" + str(i)]["Time"][:2] == datetime.datetime.now().strftime("%I") and (int(config.assignmentsCfg["Assignment" + str(i)]["Time"][3:5]) >= int(datetime.datetime.now().strftime("%m")) - 5 or int(config.assignmentsCfg["Assignment" + str(i)]["Time"][3:5]) <= int(datetime.datetime.now().strftime("%m")) + 5):
|
|
notificationsent = True
|
|
config.assignmentsCfg["Assignment" + str(i)]["Notifications"] = "False"
|
|
config.writeAssignments()
|
|
notifnum = rand(1,3)
|
|
duenotif = Notify()
|
|
duenotif.title = "Assignment due today"
|
|
duenotif.application_name = "Timetable"
|
|
duenotif.icon = "./assets/ui/icon.png"
|
|
if config.assignmentsCfg.has_option("Assignment" + str(i), "Name"):
|
|
if notifnum == 1:
|
|
duenotif.message = "Y'know that assingmnet from " + config.assignmentsCfg["Assignment" + str(i)]["Lesson"] + "? yea, that's due now"
|
|
if notifnum == 2 and subjectteachers[subjectnames.index(config.assignmentsCfg["Assignment" + str(i)]["Lesson"])] != "":
|
|
duenotif.message = subjectteachers[subjectnames.index(config.assignmentsCfg["Assignment" + str(i)]["Lesson"])] + "'s assignment is due, please hand it up"
|
|
elif notifnum == 2:
|
|
notifnum = 3
|
|
if notifnum == 3:
|
|
duenotif.message = config.assignmentsCfg["Assignment" + str(i)]["Name"] + " is due right now, better submit it"
|
|
else:
|
|
duenotif.message = "One of your assignments is due!"
|
|
duenotif.send()
|
|
getNearAssignments((not notificationsent) and firstlaunch)
|
|
|
|
checkAssignmentTime(True)
|
|
notiftimer = QTimer()
|
|
notiftimer.setInterval(60000)
|
|
notiftimer.timeout.connect(checkAssignmentTime)
|
|
notiftimer.start()
|
|
|
|
#################
|
|
###### END ######
|
|
#################
|
|
|
|
def quit():
|
|
if os.path.isfile(os.path.join(config.confdir, "proc.lock")):
|
|
os.remove(os.path.join(config.confdir, "proc.lock"))
|
|
print("Quitting...")
|
|
os._exit(0)
|
|
app.aboutToQuit.connect(quit)
|
|
|
|
def quitSig(x, y):
|
|
quit()
|
|
signal.signal(signal.SIGTERM, quitSig)
|
|
|
|
if not args.debug:
|
|
app.setQuitOnLastWindowClosed(False)
|
|
|
|
#################
|
|
### TRAY ICON ###
|
|
#################
|
|
|
|
tray = QSystemTrayIcon()
|
|
tray.setIcon(QIcon(":/backgrounds/timetable"))
|
|
tray.setVisible(True)
|
|
tray.activated.connect(timetableWindow.show)
|
|
|
|
traymenu = QMenu()
|
|
trayshow = QAction("Show")
|
|
trayshow.triggered.connect(timetableWindow.show)
|
|
trayquit = QAction("Quit")
|
|
trayquit.triggered.connect(quit)
|
|
traymenu.addAction(trayshow)
|
|
traymenu.addAction(trayquit)
|
|
|
|
tray.setContextMenu(traymenu)
|
|
|
|
##############
|
|
### LAUNCH ###
|
|
##############
|
|
|
|
if not background:
|
|
timetableWindow.show()
|
|
|
|
print("Launched in " + str(round(time.perf_counter() - starttime, 2)) + "s")
|
|
|
|
app.exec()
|