Skip to content

Commit

Permalink
Enable loading screenshots from clipboard
Browse files Browse the repository at this point in the history
Signed-off-by: Akashdeep Dhar <[email protected]>
  • Loading branch information
gridhead committed Oct 29, 2024
1 parent 7b79e0e commit 573bd44
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 40 deletions.
25 changes: 15 additions & 10 deletions gi_loadouts/face/scan/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,43 @@ class FileHandling:
def __init__(self):
super().__init__()

def load_screenshot(self, prnt, head: str) -> Tuple[bool, QPixmap, ImageFile]:
def load_mask_from_file(self, path: str) -> Tuple[bool, QPixmap, ImageFile]:
"""
Handle file operations involved in loading data from the storage device
:return: Image that is intended to be read from
"""
explorer, status, pxmp, data = QFileDialog(), False, None, None
filepath = explorer.getOpenFileName(prnt, head, "", "All Files (*)")[0]

if filepath.strip() != "":
status, pxmp, data = False, None, None
if path.strip() != "":
try:
data = Image.open(filepath)
data = Image.open(path)
except UnidentifiedImageError as expt:
raise ValueError("Please select an accurate screenshot.") from expt
qtim = ImageQt.ImageQt(data)
pxmp = QPixmap.fromImage(qtim)
status = True

return status, pxmp, data

def load_tessexec(self, prnt, head: str) -> Tuple[bool, str]:
def load_screenshot_with_picker(self, prnt, head: str) -> Tuple[bool, QPixmap, ImageFile]:
"""
Handle file operations involved in loading data from the storage device
:return: Image that is intended to be read from
"""
explorer = QFileDialog()
filepath = explorer.getOpenFileName(prnt, head, "", "All Files (*)")[0]
return self.load_mask_from_file(filepath)

def load_tessexec_with_picker(self, prnt, head: str) -> Tuple[bool, str]:
"""
Handle file operations involved in loading executable from the storage device
:return: Path to the Tesseract OCR executable
"""
explorer, status = QFileDialog(), False
filepath = explorer.getOpenFileName(prnt, head, "", "All Files (*);;Executable Files (*.exe)")[0]

if filepath.strip() != "":
status = True

return status, filepath.strip()


Expand Down
9 changes: 8 additions & 1 deletion gi_loadouts/face/scan/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from PySide6.QtGui import QKeySequence, QShortcut

from gi_loadouts import __versdata__
from gi_loadouts.face.scan.rule import Rule
Expand Down Expand Up @@ -39,7 +40,13 @@ def initialize_events(self) -> None:
drop, text = getattr(self, f"arti_name_{alfa}"), getattr(self, f"arti_data_{alfa}")
drop.currentTextChanged.connect(lambda _, a_drop=drop, a_text=text: self.render_lineedit_readonly_when_none(a_drop, a_text))
self.arti_back_wipe.clicked.connect(self.wipe_artifact)
self.arti_cnvs_load.clicked.connect(self.load_reader)
self.arti_cnvs_load.clicked.connect(self.insert_data_from_file)
self.clip_shortcut = QShortcut(QKeySequence("Ctrl+V"), self)
self.clip_shortcut.activated.connect(self.insert_data_from_shortcut)
self.arti_shot.setAcceptDrops(True)
self.arti_cnvs_conf.clicked.connect(self.load_tessexec)
self.arti_cnvs_wipe.clicked.connect(self.wipe_snapshot)
self.arti_back_done.clicked.connect(self.accept)
self.arti_shot.dragEnterEvent = self.dragEnterEvent
self.arti_shot.dragMoveEvent = self.dragMoveEvent
self.arti_shot.dropEvent = self.dropEvent
153 changes: 124 additions & 29 deletions gi_loadouts/face/scan/rule.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from PySide6.QtCore import QThread
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import QComboBox, QDialog, QLineEdit, QMessageBox
from PIL import Image
from PySide6.QtCore import QMimeData, QThread
from PySide6.QtGui import QDragEnterEvent, QDropEvent, QPixmap
from PySide6.QtWidgets import QApplication, QComboBox, QDialog, QLineEdit, QMessageBox

from gi_loadouts import conf
from gi_loadouts.data.arti import ArtiList
Expand Down Expand Up @@ -208,18 +209,46 @@ def complete_thread(self) -> None:
self.thread.quit()
self.thread.wait()

def register_return_from_scanning(self, rslt: tuple) -> None:
"""
Place the selected screenshot and the detected attributes on the user interface
:return:
"""
area, main, seco, team, levl, rare, duration, expt = rslt

if expt:
self.show_dialog(
QMessageBox.Information,
"Faulty scanning",
f"Please consider checking your input after ensuring that the proper Tesseract OCR executable has been selected.\n\n{expt}"
)
return

self.arti_shot.setPixmap(self.shot)

if area in [self.arti_dist.itemText(indx) for indx in range(self.arti_dist.count())]:
self.arti_dist.setCurrentText(area)
if team in [self.arti_type.itemText(indx) for indx in range(self.arti_type.count())]:
self.arti_type.setCurrentText(team)
if rare in [self.arti_rare.itemText(indx) for indx in range(self.arti_rare.count())]:
self.arti_rare.setCurrentText(rare)
if levl in [self.arti_levl.itemText(indx) for indx in range(self.arti_levl.count())]:
self.arti_levl.setCurrentText(levl)
if main.stat_name.value in [self.arti_name_main.itemText(indx) for indx in range(self.arti_name_main.count())]:
self.arti_name_main.setCurrentText(main.stat_name.value)
for alfa, item in seco.items():
if item.stat_name.value in [getattr(self, f"arti_name_{alfa}").itemText(indx) for indx in range(getattr(self, f"arti_name_{alfa}").count())]:
getattr(self, f"arti_name_{alfa}").setCurrentText(item.stat_name.value)
getattr(self, f"arti_data_{alfa}").setText(str(item.stat_data))

def load_reader(self) -> None:
"""
Facilitate the loading of data and calculation of statistics
:return:
"""
try:
status, self.shot, self.snap = file.load_screenshot(self, "Select location to load artifact screenshot")

if not status:
return

self.thread, self.worker = QThread(parent=self), ScanWorker(self.snap)
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.initiate_thread)
Expand All @@ -234,38 +263,104 @@ def load_reader(self) -> None:
f"Please consider checking your input after ensuring that the proper Tesseract OCR executable has been selected.\n\n{expt}"
)

def register_return_from_scanning(self, rslt: tuple) -> None:
def insert_data_from_file(self) -> None:
"""
Place the selected screenshot and the detected attributes on the user interface
Kick off the image loading and scanning from the file
:return:
"""
area, main, seco, team, levl, rare, duration, expt = rslt
try:
status, self.shot, self.snap = file.load_screenshot_with_picker(self, "Select location to load artifact screenshot")
if not status:
return
self.load_reader()
except Exception as expt:
self.show_dialog(
QMessageBox.Information,
"Faulty scanning",
f"Please consider checking your input after ensuring that the proper Tesseract OCR executable has been selected.\n\n{expt}"
)

if expt:
def transfer_to_processing(self, data: QMimeData) -> None:
try:
if data.hasImage():
"""
If the item selected from the clipboard are file contents
"""
shot = QPixmap.fromImage(data.imageData())
if shot.isNull():
return
mdle = shot.toImage()
w, h = mdle.width(), mdle.height()
buff = mdle.bits().tobytes()
snap = Image.frombytes("RGBA", (w, h), buff, "raw", "BGRA")
self.shot, self.snap = shot, snap
elif data.hasUrls():
"""
If the item selected from the clipboard are file paths
"""
urls = data.urls()
if len(urls) == 0:
return
path = urls[0].toLocalFile()
status, self.shot, self.snap = file.load_mask_from_file(path)
if not status:
return
else:
"""
If the item selected from the clipboard are not supported
"""
raise ValueError("Please select an accurate screenshot.")
"""
Initialize scanning after the shot and snap objects are populated
"""
self.load_reader()
except Exception as expt:
self.show_dialog(
QMessageBox.Information,
"Faulty scanning",
f"Please consider checking your input after ensuring that the proper Tesseract OCR executable has been selected.\n\n{expt}"
)
return

self.arti_shot.setPixmap(self.shot)
def insert_data_from_shortcut(self) -> None:
"""
Kick off the image loading and scanning from the keyboard shortcut
if area in [self.arti_dist.itemText(indx) for indx in range(self.arti_dist.count())]:
self.arti_dist.setCurrentText(area)
if team in [self.arti_type.itemText(indx) for indx in range(self.arti_type.count())]:
self.arti_type.setCurrentText(team)
if rare in [self.arti_rare.itemText(indx) for indx in range(self.arti_rare.count())]:
self.arti_rare.setCurrentText(rare)
if levl in [self.arti_levl.itemText(indx) for indx in range(self.arti_levl.count())]:
self.arti_levl.setCurrentText(levl)
if main.stat_name.value in [self.arti_name_main.itemText(indx) for indx in range(self.arti_name_main.count())]:
self.arti_name_main.setCurrentText(main.stat_name.value)
for alfa, item in seco.items():
if item.stat_name.value in [getattr(self, f"arti_name_{alfa}").itemText(indx) for indx in range(getattr(self, f"arti_name_{alfa}").count())]:
getattr(self, f"arti_name_{alfa}").setCurrentText(item.stat_name.value)
getattr(self, f"arti_data_{alfa}").setText(str(item.stat_data))
:return:
"""
self.transfer_to_processing(QApplication.clipboard().mimeData())

def dragEnterEvent(self, incident: QDragEnterEvent) -> None:
"""
Method override for QWidget to ensure that the said event is properly handled
Used on the QLabel item arti_shot for the drag-and-drop action
:return:
"""
incident.acceptProposedAction()

def dragMoveEvent(self, incident: QDragEnterEvent) -> None:
"""
Method override for QWidget to ensure that the said event is properly handled
Used on the QLabel item arti_shot for the drag-and-drop action
:return:
"""
incident.acceptProposedAction()

def dropEvent(self, incident: QDropEvent) -> None:
"""
Kick off the image loading and scanning from the drag-and-drop action
Method override for QWidget to ensure that the said event is properly handled
Used on the QLabel item arti_shot for the drag-and-drop action
:return:
"""
self.transfer_to_processing(incident.mimeData())

def load_tessexec(self) -> None:
"""
Expand All @@ -274,7 +369,7 @@ def load_tessexec(self) -> None:
:return:
"""
try:
status, tessexec = file.load_tessexec(self, "Select location of the Tesseract OCR executable")
status, tessexec = file.load_tessexec_with_picker(self, "Select location of the Tesseract OCR executable")
if status:
conf.tessexec = tessexec
except Exception as expt:
Expand Down

0 comments on commit 573bd44

Please sign in to comment.