diff options
-rw-r--r-- | gui.py | 86 | ||||
-rw-r--r-- | muddle.ui | 235 |
2 files changed, 265 insertions, 56 deletions
@@ -12,11 +12,13 @@ import html import logging import tempfile +from PyQt5 import uic from PyQt5.QtGui import QFont from PyQt5.Qt import QStyle from PyQt5.QtCore import Qt, QThread, pyqtSlot, pyqtSignal, QObject from PyQt5.QtWidgets import ( QApplication, + QMainWindow, QWidget, QTreeWidget, QTreeWidgetItem, @@ -24,6 +26,7 @@ from PyQt5.QtWidgets import ( QGridLayout, QHBoxLayout, QPushButton, + QToolButton, QProgressBar, QTabWidget, QPlainTextEdit @@ -101,7 +104,6 @@ class MoodleFetcher(QThread): self.apihelper = moodle.ApiHelper(self.api) def run(self): - # This is beyond bad but I don't have access to the moodle documentation, so I had to guess for course in self.getCourses(): self.loadedItem.emit(MoodleItem.Type.COURSE, course) for section in self.getSections(course): @@ -143,24 +145,24 @@ class MoodleFetcher(QThread): else: return [] -class MoodleTreeView(QTreeWidget): - def __init__(self, parent, instance_url, token): + +class MoodleTreeWidget(QTreeWidget): + def __init__(self, parent): super().__init__(parent) + self.itemDoubleClicked.connect(self.onItemDoubleClicked, Qt.QueuedConnection) self.lastInsertedItem = None - - self.initUi() - - self.worker = MoodleFetcher(self, instance_url, token) - self.worker.loadedItem.connect(self.onWorkerLoadedItem) - self.worker.finished.connect(self.onWorkerDone) - self.worker.start() - - self.show() - - def initUi(self): - self.setHeaderHidden(True) - self.itemDoubleClicked.connect(self.onItemDoubleClicked, Qt.QueuedConnection) + self.worker = None + + @pyqtSlot(str, str) + def refresh(self, instance_url, token): + if not self.worker or not self.worker.isFinished(): + self.worker = MoodleFetcher(self, instance_url, token) + self.worker.loadedItem.connect(self.onWorkerLoadedItem) + self.worker.finished.connect(self.onWorkerDone) + self.worker.start() + else: + log.debug("A worker is already running, not refreshing") @pyqtSlot(QTreeWidgetItem, int) def onItemDoubleClicked(self, item, col): @@ -177,8 +179,6 @@ class MoodleTreeView(QTreeWidget): else: # linux variants subprocess.Popen(('xdg-open', filepath)) - - @pyqtSlot(MoodleItem.Type, object) def onWorkerLoadedItem(self, type, item): # Assume that the items arrive in order @@ -225,6 +225,7 @@ class MoodleTreeView(QTreeWidget): self.sortByColumn(0, Qt.AscendingOrder) self.setSortingEnabled(True) + class QLogHandler(QObject, logging.Handler): newLogMessage = pyqtSignal(str) @@ -235,58 +236,31 @@ class QLogHandler(QObject, logging.Handler): def write(self, m): pass -class Muddle(QTabWidget): - def __init__(self, instance_url, token): - super().__init__() - self.instance_url = instance_url - self.token = token - self.initUi() - - def initUi(self): - self.setWindowTitle("Muddle") - - # moodle tab - self.tabmoodle = QWidget() - self.addTab(self.tabmoodle, "Moodle") - - self.tabmoodle.setLayout(QGridLayout()) - self.tabmoodle.layout().addWidget(MoodleTreeView(self, self.instance_url, self.token), 0, 0, 1, -1) - # TODO: make number of selected element appear - # TODO: add path selector, to select where to download the files - self.tabmoodle.downloadbtn = QPushButton("Download") - self.tabmoodle.selectallbtn = QPushButton("Select All") - self.tabmoodle.deselectallbtn = QPushButton("Deselect All") - self.tabmoodle.progressbar = QProgressBar() - - self.tabmoodle.layout().addWidget(self.tabmoodle.downloadbtn, 1, 0) - self.tabmoodle.layout().addWidget(self.tabmoodle.selectallbtn, 1, 1) - self.tabmoodle.layout().addWidget(self.tabmoodle.deselectallbtn, 1, 2) - self.tabmoodle.layout().addWidget(self.tabmoodle.progressbar, 2, 0, 1, -1) +class MuddleWindow(QMainWindow): + def __init__(self, instance_url, token): + super(MuddleWindow, self).__init__() + uic.loadUi("muddle.ui", self) + self.setCentralWidget(self.findChild(QTabWidget, "Muddle")) - # log tabs + # setup logging self.loghandler = QLogHandler(self) self.loghandler.setFormatter(logging.Formatter("%(name)s - %(levelname)s - %(message)s")) self.loghandler.newLogMessage.connect(self.onNewLogMessage) logging.getLogger("muddle").addHandler(self.loghandler) - font = QFont("Monospace") - font.setStyleHint(QFont.Monospace) - - self.logtext = QPlainTextEdit() - self.logtext.setReadOnly(True) - self.logtext.setFont(font) - - self.addTab(self.logtext, "Logs") + refreshBtn = self.findChild(QToolButton, "refreshBtn") + moodleTreeWidget = self.findChild(MoodleTreeWidget, "moodleTree") + refreshBtn.clicked.connect(lambda b: moodleTreeWidget.refresh(instance_url, token)) self.show() @pyqtSlot(str) def onNewLogMessage(self, msg): - self.logtext.appendPlainText(msg) + self.findChild(QPlainTextEdit, "logsTab").appendPlainText(msg) def start(instance_url, token): app = QApplication(sys.argv) - ex = Muddle(instance_url, token) + ex = MuddleWindow(instance_url, token) sys.exit(app.exec_()) diff --git a/muddle.ui b/muddle.ui new file mode 100644 index 0000000..e25a1a9 --- /dev/null +++ b/muddle.ui @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MuddleWindow</class> + <widget class="QMainWindow" name="MuddleWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>750</height> + </rect> + </property> + <property name="windowTitle"> + <string>Muddle</string> + </property> + <widget class="QTabWidget" name="Muddle"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>600</height> + </size> + </property> + <property name="windowTitle"> + <string>TabWidget</string> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="moodleTab"> + <attribute name="title"> + <string>Moodle</string> + </attribute> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="0"> + <widget class="QLineEdit" name="downloadPathEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QPushButton" name="downloadBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Download</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLineEdit" name="searchBar"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="inputMask"> + <string/> + </property> + <property name="placeholderText"> + <string>Search</string> + </property> + </widget> + </item> + <item row="5" column="0" colspan="2"> + <widget class="QProgressBar" name="downloadProgressBar"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="value"> + <number>24</number> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="MoodleTreeWidget" name="moodleTree"> + <property name="headerHidden"> + <bool>false</bool> + </property> + <column> + <property name="text"> + <string notr="true">Item</string> + </property> + </column> + <column> + <property name="text"> + <string>Size</string> + </property> + </column> + </widget> + </item> + <item row="0" column="1"> + <widget class="QToolButton" name="refreshBtn"> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QToolButton" name="selectPathBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Select</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QTreeWidget" name="localTab"> + <attribute name="title"> + <string>Local</string> + </attribute> + <column> + <property name="text"> + <string notr="true">Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Size</string> + </property> + </column> + </widget> + <widget class="QPlainTextEdit" name="logsTab"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="undoRedoEnabled"> + <bool>false</bool> + </property> + <property name="plainText"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + <attribute name="title"> + <string>Logs</string> + </attribute> + </widget> + <widget class="QWidget" name="settingsTab"> + <attribute name="title"> + <string>Settings</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="moodleGrp"> + <property name="title"> + <string>Moodle</string> + </property> + <layout class="QFormLayout" name="formLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="intanceLabel"> + <property name="text"> + <string>Instance URL</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="instanceUrlEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="tokenLabel"> + <property name="text"> + <string>Token</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="tokenEdit"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="muddleGrp"> + <property name="title"> + <string>Muddle</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="configLabel"> + <property name="text"> + <string>Config</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="configEdit"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>23</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <customwidgets> + <customwidget> + <class>MoodleTreeWidget</class> + <extends>QTreeWidget</extends> + <header>gui</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> |