Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 46 additions & 33 deletions TutorialMaker/Lib/TutorialGUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,22 +342,12 @@ def setupGUI(self):
self.icon_arrowDown = qt.QIcon(qt.QPixmap.fromImage(self.image_ArrowDown))
pass

def openAnnotationsAsJSON(self):
from Lib.TutorialUtils import get_module_basepath as getModulePath
parent = slicer.util.mainWindow()
basePath = getModulePath("TutorialMaker")
jsonPath = qt.QFileDialog.getOpenFileName(
parent,
_("Select a JSON file"),
basePath + "/Outputs/Annotations/",
_("JSON Files (*.json)")
)
self.raise_()
self.activateWindow()
if not os.path.exists(jsonPath):
return
def _loadAnnotationsFromFile(self, filepath):
self.selectedAnnotator = None
self.selectedAnnotation = None
self.selectedIndexes = [0, 0]

[tInfo, tSlides, tPaths] = AnnotatedTutorial.LoadAnnotatedTutorial(jsonPath)
[tInfo, tSlides, tPaths] = AnnotatedTutorial.LoadAnnotatedTutorial(filepath)
for step in self.steps:
self.gridLayout.removeWidget(step)
step.deleteLater()
Expand All @@ -369,36 +359,60 @@ def openAnnotationsAsJSON(self):
stepWidget.AddStepWindows(tSlides[stepIndex])

self.steps.append(stepWidget)
self.gridLayout.addWidget(stepWidget) # noqa: F821
stepWidget.UNDELETABLE = True # noqa: F821
stepWidget.CreateMergedWindow() # noqa: F821
stepWidget.ToggleExtended() # noqa: F821
self.gridLayout.addWidget(stepWidget)
stepWidget.UNDELETABLE = True
stepWidget.CreateMergedWindow()
stepWidget.ToggleExtended()
self.tutorialInfo = tInfo



self.coverStepIndex = self._findStepIndexByLayout("CoverPage")
self.ackStepIndex = self._findStepIndexByLayout("Acknowledgment")

# Ensure Cover exists
if self.coverStepIndex is None:
pm = self.make_cover_pixmap(self.tutorialInfo, tuple(self.selectedSlideSize))
self.addBlankPage(False, 0, "", type_="CoverPage", pixmap=pm)
self.coverStepIndex = 0

# Ensure Acknowledgment exists ALWAYS (even if empty)
if self.ackStepIndex is None:
pm = self.make_acknowledgments_pixmap(self.tutorialInfo, tuple(self.selectedSlideSize))
self.addBlankPage(False, 1, "", type_="Acknowledgment", pixmap=pm)
self.ackStepIndex = 1

self._regenerateCoverPixmap()
self._regenerateAcknowledgmentPixmap()

if len(self.steps) > 0 and len(self.steps[0].Slides) > 0:
self.changeSelectedSlide(0, 0)
else:
self.slideTitleWidget.setText("")
self.slideBodyWidget.setText("")

def openAnnotationsAsJSON(self):
from Lib.TutorialUtils import get_module_basepath as getModulePath
parent = slicer.util.mainWindow()
basePath = getModulePath("TutorialMaker")
jsonPath = qt.QFileDialog.getOpenFileName(
parent,
_("Select a JSON file"),
basePath + "/Outputs/Annotations/",
_("JSON Files (*.json)")
)
self.raise_()
self.activateWindow()
if not os.path.exists(jsonPath):
return

self._loadAnnotationsFromFile(jsonPath)



def saveAnnotationsAsJSON(self):
import re

if self.selectedAnnotator is not None:
self.selectedAnnotator.SlideTitle = self.slideTitleWidget.text
self.selectedAnnotator.SlideBody = self.slideBodyWidget.toPlainText()

outputFileAnnotations = {**self.tutorialInfo}
outputFileTextDict = {}
outputFileOld = []
Expand Down Expand Up @@ -520,6 +534,9 @@ def loadImagesAndMetadata(self, tutorialData):
if acknowledgments_pm is not None:
self.addBlankPage(False, len(self.steps), "", type_="Acknowledgment", pixmap=acknowledgments_pm)
self.ackStepIndex = len(self.steps) - 1

if len(self.steps) > 0 and len(self.steps[0].Slides) > 0:
self.changeSelectedSlide(0, 0)
pass

def swapStepPosition(self, index, swapTo):
Expand Down Expand Up @@ -551,21 +568,15 @@ def changeSelectedSlide(self, stepId, screenshotId):
self.selectedSlide.setPixmap(selectedScreenshot.GetResized(*self.selectedSlideSize, keepAspectRatio=True))
self.selectedAnnotator = selectedScreenshot

# Load text from slideAnnotator
self.slideTitleWidget.setText(self.selectedAnnotator.SlideTitle)
self.slideBodyWidget.setText(self.selectedAnnotator.SlideBody)

# Bind editors depending on layout
layout = getattr(selectedScreenshot, "SlideLayout", "")
self._unbindEditorsFromCover()
self._unbindEditorsFromAcknowledgment()

if layout == "CoverPage":
self._bindEditorsToCover()
self._unbindEditorsFromAcknowledgment()
elif layout == "Acknowledgment":
self._bindEditorsToAcknowledgment()
self._unbindEditorsFromCover()
else:
self._unbindEditorsFromCover()
self._unbindEditorsFromAcknowledgment()
self.slideTitleWidget.setText(self.selectedAnnotator.SlideTitle)
self.slideBodyWidget.setText(self.selectedAnnotator.SlideBody)

Expand Down Expand Up @@ -906,11 +917,13 @@ def scrollEvent(self, event):

def open_json_file(self, filepath):
directory_path = os.path.dirname(filepath)
# Read the data from the file
with open(filepath, encoding='utf-8') as file:
rawTutorialData = json.load(file)
file.close()

if "slides" in rawTutorialData:
self._loadAnnotationsFromFile(filepath)
return

tutorial = Tutorial(
rawTutorialData["title"],
Expand Down
41 changes: 38 additions & 3 deletions TutorialMaker/TutorialMaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,20 @@ def FinishTutorial():
slicer.util.selectModule("TutorialMaker")

def Generate(self, tutorialName):
modulePath = Lib.TutorialUtils.get_module_basepath("TutorialMaker")
annotationsPath = modulePath + "/Outputs/Annotations/annotations.json"

if not os.path.exists(annotationsPath):
slicer.util.warningDisplay(
_("You don't have any annotations to export.\n"
"Please annotate your screenshots first using \"Edit Annotations\"."),
_("No Annotations Found")
)
return

with slicer.util.tryWithErrorDisplay(_("Failed to generate tutorial")):
AnnotationPainter.TutorialPainter().GenerateHTMLfromAnnotatedTutorial(Lib.TutorialUtils.get_module_basepath("TutorialMaker") + "/Outputs/Annotations/annotations.json")
outputPath = Lib.TutorialUtils.get_module_basepath("TutorialMaker") + "/Outputs/"
AnnotationPainter.TutorialPainter().GenerateHTMLfromAnnotatedTutorial(annotationsPath)
outputPath = modulePath + "/Outputs/"
if platform.system() == "Windows":
os.startfile(outputPath)
else:
Expand All @@ -289,8 +300,32 @@ def CreateNewTutorial(self):
pass

def OpenAnnotator(Self):
modulePath = Lib.TutorialUtils.get_module_basepath("TutorialMaker")
rawTutorialPath = modulePath + "/Outputs/Raw/Tutorial.json"
annotationsPath = modulePath + "/Outputs/Annotations/annotations.json"

if not os.path.exists(rawTutorialPath):
slicer.util.warningDisplay(
_("Before editing annotations you should run the capture of the screenshots.\n"
"Select a tutorial and click on \"Capture Screenshots\"."),
_("No Screenshots Found")
)
return

fileToLoad = rawTutorialPath
if os.path.exists(annotationsPath):
loadAnnotations = slicer.util.confirmYesNoDisplay(
_("An existing annotations file was found.\n\n"
"Would you like to load the existing annotations?\n\n"
"Yes: Load existing annotations\n"
"No: Start fresh from raw tutorial"),
_("Load Existing Annotations?")
)
if loadAnnotations:
fileToLoad = annotationsPath

Annotator = Lib.TutorialGUI.TutorialGUI()
Annotator.open_json_file(Lib.TutorialUtils.get_module_basepath("TutorialMaker") + "/Outputs/Raw/Tutorial.json")
Annotator.open_json_file(fileToLoad)
Annotator.show()
pass

Expand Down
Loading