Skip to content

Commit

Permalink
BUG: Make translatable Editor effects titles in Segmentations
Browse files Browse the repository at this point in the history
  • Loading branch information
mhdiop committed Sep 21, 2023
1 parent 4540594 commit 5f2e1dc
Show file tree
Hide file tree
Showing 19 changed files with 359 additions and 281 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import vtk

import slicer
from slicer.i18n import tr as _

from .AbstractScriptedSegmentEditorEffect import *

Expand Down Expand Up @@ -86,14 +87,14 @@ def isBackgroundLabelmap(labelmapOrientedImageData, label=None):
return False

def setupOptionsFrame(self):
self.autoUpdateCheckBox = qt.QCheckBox("Auto-update")
self.autoUpdateCheckBox.setToolTip("Auto-update results preview when input segments change.")
self.autoUpdateCheckBox = qt.QCheckBox(_("Auto-update"))
self.autoUpdateCheckBox.setToolTip(_("Auto-update results preview when input segments change."))
self.autoUpdateCheckBox.setChecked(True)
self.autoUpdateCheckBox.setEnabled(False)

self.previewButton = qt.QPushButton("Initialize")
self.previewButton = qt.QPushButton(_("Initialize"))
self.previewButton.objectName = self.__class__.__name__ + 'Preview'
self.previewButton.setToolTip("Preview complete segmentation")
self.previewButton.setToolTip(_("Preview complete segmentation"))
# qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
# fails on some systems, therefore set the policies using separate method calls
qSize = qt.QSizePolicy()
Expand All @@ -103,35 +104,35 @@ def setupOptionsFrame(self):
previewFrame = qt.QHBoxLayout()
previewFrame.addWidget(self.autoUpdateCheckBox)
previewFrame.addWidget(self.previewButton)
self.scriptedEffect.addLabeledOptionsWidget("Preview:", previewFrame)
self.scriptedEffect.addLabeledOptionsWidget(_("Preview:"), previewFrame)

self.previewOpacitySlider = ctk.ctkSliderWidget()
self.previewOpacitySlider.setToolTip("Adjust visibility of results preview.")
self.previewOpacitySlider.setToolTip(_("Adjust visibility of results preview."))
self.previewOpacitySlider.minimum = 0
self.previewOpacitySlider.maximum = 1.0
self.previewOpacitySlider.value = 0.0
self.previewOpacitySlider.singleStep = 0.05
self.previewOpacitySlider.pageStep = 0.1
self.previewOpacitySlider.spinBoxVisible = False

self.previewShow3DButton = qt.QPushButton("Show 3D")
self.previewShow3DButton.setToolTip("Preview results in 3D.")
self.previewShow3DButton = qt.QPushButton(_("Show 3D"))
self.previewShow3DButton.setToolTip(_("Preview results in 3D."))
self.previewShow3DButton.setCheckable(True)

displayFrame = qt.QHBoxLayout()
displayFrame.addWidget(qt.QLabel("inputs"))
displayFrame.addWidget(qt.QLabel(_("inputs")))
displayFrame.addWidget(self.previewOpacitySlider)
displayFrame.addWidget(qt.QLabel("results"))
displayFrame.addWidget(qt.QLabel(_("results")))
displayFrame.addWidget(self.previewShow3DButton)
self.scriptedEffect.addLabeledOptionsWidget("Display:", displayFrame)
self.scriptedEffect.addLabeledOptionsWidget(_("Display:"), displayFrame)

self.cancelButton = qt.QPushButton("Cancel")
self.cancelButton = qt.QPushButton(_("Cancel"))
self.cancelButton.objectName = self.__class__.__name__ + 'Cancel'
self.cancelButton.setToolTip("Clear preview and cancel auto-complete")
self.cancelButton.setToolTip(_("Clear preview and cancel auto-complete"))

self.applyButton = qt.QPushButton("Apply")
self.applyButton = qt.QPushButton(_("Apply"))
self.applyButton.objectName = self.__class__.__name__ + 'Apply'
self.applyButton.setToolTip("Replace segments by previewed result")
self.applyButton.setToolTip(_("Replace segments by previewed result"))

finishFrame = qt.QHBoxLayout()
finishFrame.addWidget(self.cancelButton)
Expand Down Expand Up @@ -244,13 +245,13 @@ def updateGUIFromMRML(self):
wasBlocked = self.previewOpacitySlider.blockSignals(True)
self.previewOpacitySlider.value = self.getPreviewOpacity()
self.previewOpacitySlider.blockSignals(wasBlocked)
self.previewButton.text = "Update"
self.previewButton.text = _("Update")
self.previewShow3DButton.setEnabled(True)
self.previewShow3DButton.setChecked(self.getPreviewShow3D())
self.autoUpdateCheckBox.setEnabled(True)
self.observeSegmentation(self.autoUpdateCheckBox.isChecked())
else:
self.previewButton.text = "Initialize"
self.previewButton.text = _("Initialize")
self.autoUpdateCheckBox.setEnabled(False)
self.previewShow3DButton.setEnabled(False)
self.delayedAutoUpdateTimer.stop()
Expand All @@ -276,7 +277,7 @@ def onPreview(self):
return
self.previewComputationInProgress = True

slicer.util.showStatusMessage(f"Running {self.scriptedEffect.name} auto-complete...", 2000)
slicer.util.showStatusMessage(_("Running {effectName} auto-complete...").format(effectName=self.scriptedEffect.name), 2000)
try:
# This can be a long operation - indicate it to the user
qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import vtk

import slicer
from slicer.i18n import tr as _

from SegmentEditorEffects import *

Expand All @@ -15,7 +16,8 @@ class SegmentEditorDrawEffect(AbstractScriptedSegmentEditorLabelEffect):
"""

def __init__(self, scriptedEffect):
scriptedEffect.name = 'Draw'
scriptedEffect.name = 'Draw' # no tr (don't translate it because modules find effects by this name)
scriptedEffect.title = _('Draw')
self.drawPipelines = {}
AbstractScriptedSegmentEditorLabelEffect.__init__(self, scriptedEffect)

Expand All @@ -32,13 +34,13 @@ def icon(self):
return qt.QIcon()

def helpText(self):
return """<html>Draw segment outline in slice viewers<br>.
<p><ul style="margin: 0">
<li><b>Left-click:</b> add point.</li>
<li><b>Left-button drag-and-drop:</b> add multiple points.</li>
<li><b>x:</b> delete last point.</li>
<li><b>Double-left-click</b> or <b>right-click</b> or <b>a</b> or <b>enter</b>: apply outline.</li>
</ul><p></html>"""
return _("""<html>Draw segment outline in slice viewers<br>.
<p><ul style="margin: 0">
<li><b>Left-click:</b> add point.</li>
<li><b>Left-button drag-and-drop:</b> add multiple points.</li>
<li><b>x:</b> delete last point.</li>
<li><b>Double-left-click</b> or <b>right-click</b> or <b>a</b> or <b>enter</b>: apply outline.</li>
</ul><p></html>""")

def deactivate(self):
# Clear draw pipelines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import qt
import vtk

from slicer.i18n import tr as _

from SegmentEditorEffects import *


Expand All @@ -14,7 +16,8 @@ class SegmentEditorFillBetweenSlicesEffect(AbstractScriptedSegmentEditorAutoComp

def __init__(self, scriptedEffect):
AbstractScriptedSegmentEditorAutoCompleteEffect.__init__(self, scriptedEffect)
scriptedEffect.name = 'Fill between slices'
scriptedEffect.name = 'Fill between slices' # no tr (don't translate it because modules find effects by this name)
scriptedEffect.title = _('Fill between slices')

def clone(self):
import qSlicerSegmentationsEditorEffectsPythonQt as effects
Expand All @@ -29,17 +32,17 @@ def icon(self):
return qt.QIcon()

def helpText(self):
return """<html>Interpolate segmentation between slices<br>. Instructions:
<p><ul>
<li>Create complete segmentation on selected slices using any editor effect.
Segmentation will only expanded if a slice is segmented but none of the direct neighbors are segmented, therefore
do not use sphere brush with Paint effect and always leave at least one empty slice between segmented slices.</li>
<li>All visible segments will be interpolated, not just the selected segment.</li>
<li>The complete segmentation will be created by interpolating segmentations in empty slices.</li>
</ul><p>
Masking settings are ignored. If segments overlap, segment higher in the segments table will have priority.
The effect uses <a href="https://insight-journal.org/browse/publication/977">morphological contour interpolation method</a>.
<p></html>"""
return _("""<html>Interpolate segmentation between slices<br>. Instructions:
<p><ul>
<li>Create complete segmentation on selected slices using any editor effect.
Segmentation will only expanded if a slice is segmented but none of the direct neighbors are segmented, therefore
do not use sphere brush with Paint effect and always leave at least one empty slice between segmented slices.</li>
<li>All visible segments will be interpolated, not just the selected segment.</li>
<li>The complete segmentation will be created by interpolating segmentations in empty slices.</li>
</ul><p>
Masking settings are ignored. If segments overlap, segment higher in the segments table will have priority.
The effect uses <a href="https://insight-journal.org/browse/publication/977">morphological contour interpolation method</a>.
<p></html>""")

def computePreviewLabelmap(self, mergedImage, outputLabelmap):
import vtkITK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import vtk

import slicer
from slicer.i18n import tr as _

from SegmentEditorEffects import *

Expand All @@ -18,7 +19,8 @@ class SegmentEditorGrowFromSeedsEffect(AbstractScriptedSegmentEditorAutoComplete

def __init__(self, scriptedEffect):
AbstractScriptedSegmentEditorAutoCompleteEffect.__init__(self, scriptedEffect)
scriptedEffect.name = 'Grow from seeds'
scriptedEffect.name = 'Grow from seeds' # no tr (don't translate it because modules find effects by this name)
scriptedEffect.title = _('Grow from seeds')
self.minimumNumberOfSegments = 2
self.clippedMasterImageDataRequired = True # source volume intensities are used by this effect
self.clippedMaskImageDataRequired = True # masking is used
Expand All @@ -37,21 +39,21 @@ def icon(self):
return qt.QIcon()

def helpText(self):
return """<html>Growing segments to create complete segmentation<br>.
Location, size, and shape of initial segments and content of source volume are taken into account.
Final segment boundaries will be placed where source volume brightness changes abruptly. Instructions:<p>
<ul style="margin: 0">
<li>Use Paint or other offects to draw seeds in each region that should belong to a separate segment.
Paint each seed with a different segment. Minimum two segments are required.</li>
<li>Click <dfn>Initialize</dfn> to compute preview of full segmentation.</li>
<li>Browse through image slices. If previewed segmentation result is not correct then switch to
Paint or other effects and add more seeds in the misclassified region. Full segmentation will be
updated automatically within a few seconds</li>
<li>Click <dfn>Apply</dfn> to update segmentation with the previewed result.</li>
</ul><p>
If segments overlap, segment higher in the segments table will have priority.
The effect uses <a href="http://interactivemedical.org/imic2014/CameraReadyPapers/Paper%204/IMIC_ID4_FastGrowCut.pdf">fast grow-cut method</a>.
<p></html>"""
return _("""<html>Growing segments to create complete segmentation<br>.
Location, size, and shape of initial segments and content of source volume are taken into account.
Final segment boundaries will be placed where source volume brightness changes abruptly. Instructions:<p>
<ul style="margin: 0">
<li>Use Paint or other offects to draw seeds in each region that should belong to a separate segment.
Paint each seed with a different segment. Minimum two segments are required.</li>
<li>Click <dfn>Initialize</dfn> to compute preview of full segmentation.</li>
<li>Browse through image slices. If previewed segmentation result is not correct then switch to
Paint or other effects and add more seeds in the misclassified region. Full segmentation will be
updated automatically within a few seconds</li>
<li>Click <dfn>Apply</dfn> to update segmentation with the previewed result.</li>
</ul><p>
If segments overlap, segment higher in the segments table will have priority.
The effect uses <a href="http://interactivemedical.org/imic2014/CameraReadyPapers/Paper%204/IMIC_ID4_FastGrowCut.pdf">fast grow-cut method</a>.
<p></html>""")

def reset(self):
self.growCutFilter = None
Expand All @@ -70,10 +72,10 @@ def setupOptionsFrame(self):
self.seedLocalityFactorSlider.decimals = 1
self.seedLocalityFactorSlider.singleStep = 0.1
self.seedLocalityFactorSlider.pageStep = 1.0
self.seedLocalityFactorSlider.setToolTip('Increasing this value makes the effect of seeds more localized,'
' thereby reducing leaks, but requires seed regions to be more evenly distributed in the image.'
' The value is specified as an additional "intensity level difference" per "unit distance."')
self.scriptedEffect.addLabeledOptionsWidget("Seed locality:", self.seedLocalityFactorSlider)
self.seedLocalityFactorSlider.setToolTip(_('Increasing this value makes the effect of seeds more localized,'
' thereby reducing leaks, but requires seed regions to be more evenly distributed in the image.'
' The value is specified as an additional "intensity level difference" per "unit distance."'))
self.scriptedEffect.addLabeledOptionsWidget(_("Seed locality:"), self.seedLocalityFactorSlider)
self.seedLocalityFactorSlider.connect('valueChanged(double)', self.updateAlgorithmParameterFromGUI)

def setMRMLDefaults(self):
Expand Down
Loading

0 comments on commit 5f2e1dc

Please sign in to comment.