mirror of
https://github.com/Xevion/bulk-reminders.git
synced 2025-12-06 01:14:29 -06:00
Implement input event load dialog with loading gif and debouncing
This commit is contained in:
52
bulk_reminders/load.py
Normal file
52
bulk_reminders/load.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QSize, QTimer
|
||||||
|
from PyQt5.QtGui import QMovie
|
||||||
|
from PyQt5.QtWidgets import QApplication, QDialog, QLabel
|
||||||
|
|
||||||
|
from bulk_reminders.api import Event
|
||||||
|
from bulk_reminders.load_base import Ui_Dialog
|
||||||
|
|
||||||
|
REGEX = re.compile(
|
||||||
|
r'\s*([\w\d\s,.;\'!\[\]()]{1,})\s+\|\s+(\d{4}-\d{2}-\d{2})\s+(\d{1,2}:\d{2}(?:AM|PM))?\s*(\d{4}-\d{2}-\d{2})(\d{1,2}:\d{2}(?:AM|PM))?')
|
||||||
|
|
||||||
|
|
||||||
|
class LoadDialog(QDialog, Ui_Dialog):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(QDialog, self).__init__(*args, **kwargs)
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
self.spinner = QLabel()
|
||||||
|
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'loading.gif')
|
||||||
|
self.movie = QMovie(path)
|
||||||
|
self.movie.setScaledSize(QSize(26, 26))
|
||||||
|
self.spinner.setMovie(self.movie)
|
||||||
|
self.movie.start()
|
||||||
|
self.spinner.hide()
|
||||||
|
self.spinner.setFixedSize(23, 23)
|
||||||
|
self.horizontalLayout.addWidget(self.spinner)
|
||||||
|
|
||||||
|
self.plainTextEdit.textChanged.connect(self.edited)
|
||||||
|
self.parseTimer = QTimer()
|
||||||
|
self.parseTimer.timeout.connect(self.parse)
|
||||||
|
self.parseTimer.setSingleShot(True)
|
||||||
|
|
||||||
|
self.show()
|
||||||
|
self.parse()
|
||||||
|
|
||||||
|
self.parsed: List[Event] = []
|
||||||
|
|
||||||
|
def parse(self) -> None:
|
||||||
|
"""Parse the events entered into the dialog"""
|
||||||
|
self.spinner.hide()
|
||||||
|
results = [result.groups() for result in re.finditer(REGEX, self.plainTextEdit.toPlainText())]
|
||||||
|
self.eventCountLabel.setText(f'{len(results)} group{"s" if len(results) != 0 else ""} found.')
|
||||||
|
self.parsed = list(map(Event.parse_raw, results))
|
||||||
|
|
||||||
|
def edited(self) -> None:
|
||||||
|
"""Prepare a timer to be fired to parse the edited text"""
|
||||||
|
self.parseTimer.stop()
|
||||||
|
self.spinner.show()
|
||||||
|
self.parseTimer.start(500) # 0.5 seconds
|
||||||
88
bulk_reminders/load.ui
Normal file
88
bulk_reminders/load.ui
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Load Events</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QPlainTextEdit" name="plainTextEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="toolButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="eventCountLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>3 events found.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
48
bulk_reminders/load_base.py
Normal file
48
bulk_reminders/load_base.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'load.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.15.4
|
||||||
|
#
|
||||||
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class Ui_Dialog(object):
|
||||||
|
def setupUi(self, Dialog):
|
||||||
|
Dialog.setObjectName("Dialog")
|
||||||
|
Dialog.resize(400, 300)
|
||||||
|
self.gridLayout = QtWidgets.QGridLayout(Dialog)
|
||||||
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
|
self.plainTextEdit = QtWidgets.QPlainTextEdit(Dialog)
|
||||||
|
self.plainTextEdit.setObjectName("plainTextEdit")
|
||||||
|
self.gridLayout.addWidget(self.plainTextEdit, 0, 0, 1, 1)
|
||||||
|
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
|
self.toolButton = QtWidgets.QToolButton(Dialog)
|
||||||
|
self.toolButton.setObjectName("toolButton")
|
||||||
|
self.horizontalLayout.addWidget(self.toolButton)
|
||||||
|
self.eventCountLabel = QtWidgets.QLabel(Dialog)
|
||||||
|
self.eventCountLabel.setObjectName("eventCountLabel")
|
||||||
|
self.horizontalLayout.addWidget(self.eventCountLabel)
|
||||||
|
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
|
||||||
|
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||||
|
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||||
|
self.buttonBox.setCenterButtons(False)
|
||||||
|
self.buttonBox.setObjectName("buttonBox")
|
||||||
|
self.horizontalLayout.addWidget(self.buttonBox)
|
||||||
|
self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)
|
||||||
|
|
||||||
|
self.retranslateUi(Dialog)
|
||||||
|
self.buttonBox.accepted.connect(Dialog.accept)
|
||||||
|
self.buttonBox.rejected.connect(Dialog.reject)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(Dialog)
|
||||||
|
|
||||||
|
def retranslateUi(self, Dialog):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
Dialog.setWindowTitle(_translate("Dialog", "Load Events"))
|
||||||
|
self.toolButton.setText(_translate("Dialog", "..."))
|
||||||
|
self.eventCountLabel.setText(_translate("Dialog", "3 events found."))
|
||||||
BIN
bulk_reminders/loading.gif
Normal file
BIN
bulk_reminders/loading.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
Reference in New Issue
Block a user