Example #1
0
 def endAction(self):
   self.ui.ActionsWidget.setCurrentWidget(self.ui.MenuWidget)
   self.ui.SubjectHierarchyTreeView.setSelectionMode(qt.QAbstractItemView().SingleSelection)
   self.ui.MenuWidget.enabled = True
   self.actionInProgress = False
   interactionNode = slicer.app.applicationLogic().GetInteractionNode()    
   interactionNode.SetCurrentInteractionMode(interactionNode.ViewTransform)
   self.resolveStateButtons()
Example #2
0
    def create(self):
        # add a search box
        self.searchFrame = qt.QFrame(self.parent)
        self.searchFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(self.searchFrame)
        self.searchLabel = qt.QLabel(self.searchFrame)
        self.searchLabel.setText("Search: ")
        self.searchFrame.layout().addWidget(self.searchLabel)
        self.search = qt.QLineEdit(self.searchFrame)
        self.searchFrame.layout().addWidget(self.search)

        # model and view for color table
        self.view = qt.QTreeView()
        self.view.setObjectName('EditColorTreeView')
        self.view.setEditTriggers(qt.QAbstractItemView().NoEditTriggers)
        self.parent.layout().addWidget(self.view)
        self.populateColors()
        self.search.connect('textChanged(QString)', self.populateColors)
        self.view.connect('activated(QModelIndex)', self.selected)
        self.view.setProperty('SH_ItemView_ActivateItemOnSingleClick', 1)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)
        # Instantiate and connect widgets ...
        #
        # Input/Export Area
        #
        IOCollapsibleButton = ctk.ctkCollapsibleButton()
        IOCollapsibleButton.text = "Input and Export"
        self.layout.addWidget(IOCollapsibleButton)

        # Layout within the dummy collapsible button
        #IOFormLayout = qt.QFormLayout(IOCollapsibleButton)
        IOFormLayout = qt.QFormLayout(IOCollapsibleButton)

        #
        # Username input
        #
        self.userNameInput = qt.QLineEdit()
        self.userNameInput.setText(slicer.userNameDefault)
        self.userNameInput.setToolTip("Input MorphoSource account username")
        IOFormLayout.addRow("MorphSource Username: "******"Input MorphoSource account password")
        IOFormLayout.addRow("MorphSource Password: "******"Log in")
        self.loginButton.toolTip = "Log into the Morphosource database"
        self.loginButton.enabled = False
        IOFormLayout.addRow(self.loginButton)

        #
        # Query parameter area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Query parameters"
        self.layout.addWidget(parametersCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

        #
        # Username input
        #
        self.orderInput = qt.QLineEdit()
        self.orderInput.setToolTip(
            "Input the the specimen order, eg: 'Euprimates' ")
        parametersFormLayout.addRow("Query order: ", self.orderInput)

        #
        # Username input
        #
        self.elementInput = qt.QLineEdit()
        self.elementInput.setToolTip(
            "Input the speciment element, eg: 'Cranuim' ")
        parametersFormLayout.addRow("Query element: ", self.elementInput)

        #

        # Submit query Button
        #
        self.submitQueryButton = qt.QPushButton("Submit query")
        self.submitQueryButton.toolTip = "Query the MorphoSource database for 3D models. This may take a few minutes."
        self.submitQueryButton.enabled = False
        parametersFormLayout.addRow(self.submitQueryButton)

        #
        # Query results area
        #
        resultsCollapsibleButton = ctk.ctkCollapsibleButton()
        resultsCollapsibleButton.text = "Query results:"
        resultsCollapsibleButton.collapsed = False
        self.layout.addWidget(resultsCollapsibleButton)
        resultsFormLayout = qt.QFormLayout(resultsCollapsibleButton)

        self.resultsModel = qt.QStandardItemModel()
        self.resultsTable = qt.QTableView()
        self.resultsTable.horizontalHeader().stretchLastSection = True
        self.resultsTable.horizontalHeader().visible = False
        self.resultsTable.verticalHeader().visible = False
        self.resultsTable.setSelectionBehavior(
            qt.QAbstractItemView().SelectRows)
        self.resultsTable.setModel(self.resultsModel)
        resultsFormLayout.addRow(self.resultsTable)

        self.loadResultsButton = qt.QPushButton("Load selected models")
        self.loadResultsButton.toolTip = "Load the selected models into the scene."
        self.loadResultsButton.enabled = False
        resultsFormLayout.addRow(self.loadResultsButton)

        # connections
        self.loginButton.connect('clicked(bool)', self.onLogin)
        self.userNameInput.connect('textChanged(const QString &)',
                                   self.onLoginStringChanged)
        self.passwordInput.connect('textChanged(const QString &)',
                                   self.onLoginStringChanged)
        self.orderInput.connect('textChanged(const QString &)',
                                self.onQueryStringChanged)
        self.elementInput.connect('textChanged(const QString &)',
                                  self.onQueryStringChanged)
        self.submitQueryButton.connect('clicked(bool)', self.onSubmitQuery)
        self.loadResultsButton.connect('clicked(bool)', self.onLoadResults)

        # Add vertical spacer
        self.layout.addStretch(1)

        # Refresh Apply button state
        self.onLoginStringChanged()
        self.onQueryStringChanged()
Example #4
0
    def __init__(self, logic, applyButton, buttonsList):
        super(ILSVisualizationWidget, self).__init__()
        self.logic = logic
        self.applyButton = applyButton
        self.fiducialButtonsList = buttonsList

        self.widget = qt.QWidget()
        self.layout = qt.QFormLayout(self.widget)
        self.boxHolder = qt.QWidget()
        self.boxHolder.setLayout(qt.QVBoxLayout())
        self.layout.addRow(self.boxHolder)

        self.groupBox = qt.QFrame()
        self.groupBox.setLayout(qt.QHBoxLayout())

        self.fiducialsCollapsibleButton = ctk.ctkCollapsibleButton()
        self.fiducialsCollapsibleButton.text = "Show Fiducials"
        self.fiducialsCollapsibleButton.hide()
        self.fiducialsFormLayout = qt.QFormLayout(
            self.fiducialsCollapsibleButton)

        # Table Widget Definition
        self.tableWidget = qt.QTableWidget()
        self.tableWidget.sortingEnabled = False
        self.tableWidget.hide()
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setColumnWidth(0, 190)
        self.tableWidget.setColumnWidth(1, 190)
        self.tableWidget.setColumnWidth(2, 190)
        self.tableWidget.setMaximumWidth(590)
        horizontalBar = self.tableWidget.horizontalScrollBar()
        horizontalBar.setDisabled(True)
        horizontalBar.hide()
        self.tableWidget.setHorizontalHeaderLabels([
            "Left Oblique Fiducials", "Right Oblique Fiducials",
            "Right Horizontal Fiducials"
        ])
        behavior = qt.QAbstractItemView()
        self.tableWidget.setSelectionBehavior(behavior.SelectItems)
        self.tableWidget.setSelectionMode(behavior.SingleSelection)
        self.tableWidget.setContextMenuPolicy(3)
        self.tableWidget.customContextMenuRequested.connect(self.onRightClick)

        self.groupBox.layout().addWidget(self.tableWidget)

        self.fiducialsFormLayout.addWidget(self.groupBox)
        self.boxHolder.layout().addWidget(self.fiducialsCollapsibleButton)

        self.pendingUpdate = False
        self.updatingFiducials = False
        self.observerTags = []

        self.leftRow = 0
        self.rightObliqueRow = 0
        self.rightHorizontalRow = 0

        self.tableItems = []

        self.deletionGroupBox = qt.QFrame()
        self.deletionGroupBox.setLayout(qt.QHBoxLayout())
        self.fiducialsFormLayout.addWidget(self.deletionGroupBox)

        #
        # Delete Selected Fiducials Button
        #
        self.deleteButton = qt.QPushButton("Delete Selected Fiducial")
        self.deleteButton.toolTip = "Select a fiducial from the table and push this button to delete the selected fiducial from the scene."
        self.deleteButton.enabled = True
        selectedIcon = qt.QIcon(":/Icons/MarkupsDelete.png")
        self.deleteButton.setIcon(selectedIcon)
        self.deleteButton.setFixedSize(220, 30)
        self.deletionGroupBox.layout().addWidget(self.deleteButton)
        self.deleteButton.connect('clicked(bool)',
                                  self.onDeleteOneFiducialButton)

        #
        # Delete All Fiducials Button
        #
        self.deleteAllButton = qt.QPushButton("Delete All Fiducials")
        self.deleteAllButton.toolTip = "Delete all fiducials in the scene."
        self.deleteAllButton.enabled = True
        allIcon = qt.QIcon(":/Icons/MarkupsDeleteAllRows.png")
        self.deleteAllButton.setIcon(allIcon)
        self.deleteAllButton.setFixedSize(220, 30)
        self.deletionGroupBox.layout().addWidget(self.deleteAllButton)
        # self.fiducialsFormLayout.addRow(self.deleteAllButton)
        self.deleteAllButton.connect('clicked(bool)', self.dialogBoxFunction)
Example #5
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        # Set up tabs to split workflow
        tabsWidget = qt.QTabWidget()
        curvesTab = qt.QWidget()
        curvesTabLayout = qt.QFormLayout(curvesTab)
        fiducialsTab = qt.QWidget()
        fiducialsTabLayout = qt.QFormLayout(fiducialsTab)
        batchTab = qt.QWidget()
        batchTabLayout = qt.QFormLayout(batchTab)

        tabsWidget.addTab(curvesTab, "Merge Curves")
        tabsWidget.addTab(fiducialsTab, "Merge Landmark Sets")
        tabsWidget.addTab(batchTab, "Batch Merge Landmark Sets")
        self.layout.addWidget(tabsWidget)
        ################## Curves Tab
        #
        # Parameters Area
        #
        parametersCurveCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCurveCollapsibleButton.text = "Curve Viewer"
        curvesTabLayout.addRow(parametersCurveCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersCurveFormLayout = qt.QFormLayout(
            parametersCurveCollapsibleButton)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.continuousCurvesCheckBox = qt.QCheckBox()
        self.continuousCurvesCheckBox.checked = 0
        self.continuousCurvesCheckBox.setToolTip(
            "If checked, redundant points will be removed on merging.")
        parametersCurveFormLayout.addRow("Contiuous curves",
                                         self.continuousCurvesCheckBox)

        #
        # markups view
        #
        self.markupsView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsView.setMRMLScene(slicer.mrmlScene)
        self.markupsView.setMultiSelection(True)
        self.markupsView.setAlternatingRowColors(True)
        self.markupsView.setDragDropMode(qt.QAbstractItemView().DragDrop)
        self.markupsView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsCurveNode"])
        parametersCurveFormLayout.addRow(self.markupsView)

        #
        # Merge Button
        #
        self.mergeButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeButton.enabled = False
        parametersCurveFormLayout.addRow(self.mergeButton)

        # connections
        self.mergeButton.connect('clicked(bool)', self.onMergeButton)
        self.markupsView.connect('currentItemChanged(vtkIdType)',
                                 self.updateMergeButton)

        ################ Landmark Set Tab
        #
        # Parameters Area
        #
        parametersLMCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersLMCollapsibleButton.text = "Landmark Viewer"
        fiducialsTabLayout.addRow(parametersLMCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersLMFormLayout = qt.QGridLayout(parametersLMCollapsibleButton)

        #
        # markups view
        #
        self.markupsFiducialView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsFiducialView.setMRMLScene(slicer.mrmlScene)
        self.markupsFiducialView.setMultiSelection(True)
        self.markupsFiducialView.setAlternatingRowColors(True)
        self.markupsFiducialView.setDragDropMode(
            qt.QAbstractItemView().DragDrop)
        self.markupsFiducialView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsFiducialView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsFiducialNode"])
        parametersLMFormLayout.addWidget(self.markupsFiducialView, 0, 0, 1, 3)

        #
        # Set landmark type menu
        #
        boxLabel = qt.QLabel("Select landmark type description to apply: ")
        self.LandmarkTypeSelection = qt.QComboBox()
        self.LandmarkTypeSelection.addItems(
            ["Select", "Fixed", "Semi", "No description"])
        parametersLMFormLayout.addWidget(boxLabel, 1, 0)
        parametersLMFormLayout.addWidget(self.LandmarkTypeSelection, 1, 1)

        #
        # Apply Landmark Type Button
        #
        self.ApplyLMButton = qt.QPushButton("Apply to highlighted nodes")
        self.ApplyLMButton.toolTip = "Apply the selected landmark type to points in the the selected nodes"
        self.ApplyLMButton.enabled = False
        parametersLMFormLayout.addWidget(self.ApplyLMButton, 1, 2)

        #
        # Merge Button
        #
        self.mergeLMButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeLMButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeLMButton.enabled = False
        parametersLMFormLayout.addWidget(self.mergeLMButton, 2, 0, 1, 3)

        # connections
        self.mergeLMButton.connect('clicked(bool)', self.onMergeLMButton)
        self.ApplyLMButton.connect('clicked(bool)', self.onApplyLMButton)
        self.markupsFiducialView.connect('currentItemChanged(vtkIdType)',
                                         self.updateMergeLMButton)
        self.LandmarkTypeSelection.connect('currentIndexChanged(int)',
                                           self.updateApplyLMButton)

        ################ Batch Run LM Merge Tab
        #
        # Fixed LM Area
        #
        fixedBatchCollapsibleButton = ctk.ctkCollapsibleButton()
        fixedBatchCollapsibleButton.text = "Fixed LM File Selection"
        batchTabLayout.addRow(fixedBatchCollapsibleButton)

        # Layout within the dummy collapsible button
        fixedBatchLayout = qt.QFormLayout(fixedBatchCollapsibleButton)

        #
        # Browse Fixed LM Button
        #
        self.browseFixedLMButton = qt.QPushButton("Select files...")
        self.browseFixedLMButton.toolTip = "Select one fixed landmark file for each subject"
        self.browseFixedLMButton.enabled = True
        fixedBatchLayout.addRow(self.browseFixedLMButton)

        #
        # File viewer box
        #
        self.fixedFileTable = qt.QTextEdit()
        fixedBatchLayout.addRow(self.fixedFileTable)

        #
        # Semi LM Area
        #
        semiBatchCollapsibleButton = ctk.ctkCollapsibleButton()
        semiBatchCollapsibleButton.text = "Semi LM File Selection"
        batchTabLayout.addRow(semiBatchCollapsibleButton)

        # Layout within the dummy collapsible button
        semiBatchLayout = qt.QFormLayout(semiBatchCollapsibleButton)

        #
        # Browse Fixed LM Button
        #
        self.browseSemiLMButton = qt.QPushButton("Select files...")
        self.browseSemiLMButton.toolTip = "Select one semi-landmark file for each subject, in the same order as the fixed landmarks"
        self.browseSemiLMButton.enabled = True
        semiBatchLayout.addRow(self.browseSemiLMButton)

        #
        # File viewer box
        #
        self.semiFileTable = qt.QTextEdit()
        semiBatchLayout.addRow(self.semiFileTable)

        #
        # Merge LM Area
        #
        batchMergeCollapsibleButton = ctk.ctkCollapsibleButton()
        batchMergeCollapsibleButton.text = "Run merge"
        batchTabLayout.addRow(batchMergeCollapsibleButton)

        # Layout within the dummy collapsible button
        batchMergeLayout = qt.QFormLayout(batchMergeCollapsibleButton)

        #
        # Select output landmark directory
        #
        self.outputDirectorySelector = ctk.ctkPathLineEdit()
        self.outputDirectorySelector.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectorySelector.toolTip = "Select the output directory where the merged landmark nodes will be saved"
        batchMergeLayout.addRow("Select output landmark directory: ",
                                self.outputDirectorySelector)

        #
        # Batch Merge Button
        #
        self.batchMergeButton = qt.QPushButton(
            "Merge fixed and semi-landmark nodes")
        self.batchMergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.batchMergeButton.enabled = False
        batchMergeLayout.addRow(self.batchMergeButton)

        #
        # Clear Button
        #
        self.clearButton = qt.QPushButton("Clear landmark file selections")
        self.clearButton.toolTip = "Clear the landmark files selected in the viewer boxes"
        self.clearButton.enabled = False
        batchMergeLayout.addRow(self.clearButton)

        # connections
        self.browseFixedLMButton.connect('clicked(bool)',
                                         self.addFixedByBrowsing)
        self.browseSemiLMButton.connect('clicked(bool)',
                                        self.addSemiByBrowsing)
        self.outputDirectorySelector.connect('validInputChanged(bool)',
                                             self.onSelectDirectory)
        self.batchMergeButton.connect('clicked(bool)', self.onBatchMergeButton)
        self.clearButton.connect('clicked(bool)', self.onClearButton)

        # Add vertical spacer
        self.layout.addStretch(1)
Example #6
0
 def beginAction(self):
   self.ui.SubjectHierarchyTreeView.setSelectionMode(qt.QAbstractItemView().NoSelection)
   self.ui.MenuWidget.enabled = False
   self.modelHistory.cacheState()
   self.actionInProgress = True
   self.resolveStateButtons()
Example #7
0
  def setup(self):
    """
    Called when the user opens the module the first time and the widget is initialized.
    """
    ScriptedLoadableModuleWidget.setup(self)

    # Load widget from .ui file (created by Qt Designer).
    # Additional widgets can be instantiated manually and added to self.layout.
    uiWidget = slicer.util.loadUI(self.resourcePath('UI/OsteotomyPlanner.ui'))
    self.layout.addWidget(uiWidget)
    self.ui = slicer.util.childWidgetVariables(uiWidget)

    # Set scene in MRML widgets. Make sure that in Qt designer the top-level qMRMLWidget's
    # "mrmlSceneChanged(vtkMRMLScene*)" signal in is connected to each MRML widget's.
    # "setMRMLScene(vtkMRMLScene*)" slot.
    uiWidget.setMRMLScene(slicer.mrmlScene)

    # Create logic class. Logic implements all computations that should be possible to run
    # in batch mode, without a graphical user interface.
    self.logic = OsteotomyPlannerLogic()

    # Connections

    # These connections ensure that we update parameter node when scene is closed
    self.addObserver(slicer.mrmlScene, slicer.mrmlScene.StartCloseEvent, self.onSceneStartClose)
    self.addObserver(slicer.mrmlScene, slicer.mrmlScene.EndCloseEvent, self.onSceneEndClose)

    #Set up SubjectHieratchy combo
    nodeTypes = ['vtkMRMLFolderDisplayNode']
    levelFilters = [slicer.vtkMRMLSubjectHierarchyConstants().GetDICOMLevelPatient(), slicer.vtkMRMLSubjectHierarchyConstants().GetDICOMLevelStudy(), slicer.vtkMRMLSubjectHierarchyConstants().GetSubjectHierarchyLevelFolder()]
    self.ui.SubjectHierarchyComboBox.setNodeTypes(nodeTypes)
    self.ui.SubjectHierarchyComboBox.setLevelFilter(levelFilters)
    self.ui.SubjectHierarchyComboBox.connect("currentItemChanged(vtkIdType)", self.onFolderChanged)
    self.ui.SubjectHierarchyTreeView.connect("currentItemChanged(vtkIdType)", self.onViewItemChanged)
    self.ui.SubjectHierarchyTreeView.hideColumn(2)
    # self.ui.SubjectHierarchyTreeView.hideColumn(3)
    self.ui.SubjectHierarchyTreeView.hideColumn(4)
    self.ui.SubjectHierarchyTreeView.hideColumn(5)



    #Selection 
    self.ui.SubjectHierarchyTreeView.setSelectionMode(qt.QAbstractItemView().SingleSelection)
    self.ui.ActionsWidget.setCurrentWidget(self.ui.MenuWidget)
    self.ui.MenuWidget.enabled = False

    self.ui.MoveButton.clicked.connect(self.beginMove)
    moveIcon = qt.QIcon(":/Icons/Transform.png")
    self.ui.MoveButton.setIcon(moveIcon)
    self.ui.MoveCancelButton.clicked.connect(self.endMove)
    self.ui.MoveConfirmButton.clicked.connect(self.confirmMove)

    self.ui.CurveCutButton.clicked.connect(self.beginCurveCut)
    curveCutIcon = qt.QIcon(":/Icons/CurveCut.png")
    self.ui.CurveCutButton.setIcon(curveCutIcon)
    self.ui.PlaceCurveButton.clicked.connect(self.placeManualCurve)
    self.ui.PreviewCurveCutButton.clicked.connect(self.previewCurveCut)
    self.ui.CurveCutConfirmButton.clicked.connect(self.confirmCurveCut)
    self.ui.CurveCutCancelButton.clicked.connect(self.endCurveCut)

    self.ui.SplitButton.clicked.connect(self.beginSplit)
    splitIcon = qt.QIcon(":/Icons/DynamicModeler.png")
    self.ui.SplitButton.setIcon(splitIcon)
    self.ui.SplitCancelButton.clicked.connect(self.endSplit)
    self.ui.ManualPlaneButton.clicked.connect(self.placeManualPlane)
    self.ui.ClearPlaneButton.clicked.connect(self.clearPlanes)
    self.ui.AutoPlaneButton.clicked.connect(self.placeAutoPlane)
    self.ui.PreviewSplitButton.clicked.connect(self.previewSplit)
    self.ui.SplitConfirmButton.clicked.connect(self.confirmSplit)

    self.ui.RemoveButton.clicked.connect(self.beginRemove)
    removeIcon = qt.QIcon(":/Icons/Medium/SlicerEditCut.png")
    self.ui.RemoveButton.setIcon(removeIcon)
    self.ui.RemoveConfirmButton.clicked.connect(self.confirmRemove)
    self.ui.RemoveCancelButton.clicked.connect(self.endRemove)

    self.ui.FinishButton.clicked.connect(self.finishPlan)
    finishIcon = qt.QIcon(":/Icons/AnnotationOkDone.png")
    self.ui.FinishButton.setIcon(finishIcon)
    self.ui.RedoButton.clicked.connect(self.restoreNextState)
    redoIcon = qt.QIcon(":/Icons/Medium/SlicerRedo.png")
    self.ui.RedoButton.setIcon(redoIcon)
    self.ui.UndoButton.clicked.connect(self.restorePreviousState)
    undoIcon = qt.QIcon(":/Icons/Medium/SlicerUndo.png")
    self.ui.UndoButton.setIcon(undoIcon)
    # self.ui.RedoButton.visible = False

    self.transform = None
    self.activeNode = None
    self.curve = None
    self.splitPlanes = []
    self.splitModels = []
    self.actionInProgress = False
    self.modelHistory = ModelHistory()    

    # Make sure parameter node is initialized (needed for module reload)
    self.initializeParameterNode()
    self.resolveStateButtons()
Example #8
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        #
        # Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Parameters"
        self.layout.addWidget(parametersCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.continuousCurvesCheckBox = qt.QCheckBox()
        self.continuousCurvesCheckBox.checked = 0
        self.continuousCurvesCheckBox.setToolTip(
            "If checked, redundant points will be removed on merging.")
        parametersFormLayout.addRow("Contiuous curves",
                                    self.continuousCurvesCheckBox)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Generate semilandmarks."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        #
        # markups view
        #
        self.markupsView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsView.setMRMLScene(slicer.mrmlScene)
        self.markupsView.setMultiSelection(True)
        self.markupsView.setAlternatingRowColors(True)
        self.markupsView.setDragDropMode(qt.QAbstractItemView().DragDrop)
        self.markupsView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsCurveNode"])
        parametersFormLayout.addRow(self.markupsView)

        #
        # Merge Button
        #
        self.mergeButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeButton.enabled = False
        parametersFormLayout.addRow(self.mergeButton)

        # connections
        self.mergeButton.connect('clicked(bool)', self.onMergeButton)
        self.markupsView.connect('currentItemChanged(vtkIdType)',
                                 self.updateMergeButton)

        # Add vertical spacer
        self.layout.addStretch(1)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        #
        # Data Area
        #
        dataGroupBox = ctk.ctkCollapsibleGroupBox()
        dataGroupBox.setTitle('Data')
        self.layout.addWidget(dataGroupBox)

        dataGridLayout = qt.QGridLayout(dataGroupBox)
        self.dirButton = ctk.ctkDirectoryButton()
        dirButtonLabel = qt.QLabel('DICOM Directory: ')
        dataGridLayout.addWidget(dirButtonLabel, 1, 1, 1, 1)
        dataGridLayout.addWidget(self.dirButton, 1, 2, 1, 3)
        self.dirButton.setMaximumWidth(500)
        orLabel = qt.QLabel('        - or - ')
        dataGridLayout.addWidget(orLabel, 2, 1, 1, 1)
        collectionsComboBoxLabel = qt.QLabel('TCIA Collection: ')
        dataGridLayout.addWidget(collectionsComboBoxLabel, 3, 1, 1, 1)

        try:
            m = slicer.modules.tciabrowser
            self.tcia = slicer.modules.tciabrowser.widgetRepresentation().self(
            )
            self.connectTCIAButton = qt.QPushButton('Connect')
            self.connectTCIAButton.toolTip = "Connect to TCIA Server."
            dataGridLayout.addWidget(self.connectTCIAButton, 3, 2, 1, 1)
            self.collectionsComboBox = qt.QComboBox()
            dataGridLayout.addWidget(self.collectionsComboBox, 3, 3, 1, 2)
            # connections
            self.connectTCIAButton.connect('clicked(bool)',
                                           self.getTCIACollectionValues)
            # TODO disable scrolling event for collectionsComboBox
            self.collectionsComboBox.connect('currentIndexChanged(QString)',
                                             self.onTCIACollectionChanged)
        except AttributeError:
            # TODO add button to open Extensions Manager
            noConnectionLabel = qt.QLabel('TCIA Browser not installed.')
            dataGridLayout.addWidget(noConnectionLabel, 3, 2, 1, 1)

        #
        # Patient Table Area
        #
        self.patientGroupBox = ctk.ctkCollapsibleGroupBox()
        self.patientGroupBox.setTitle('Patient Selection')
        self.layout.addWidget(self.patientGroupBox)
        self.patientGroupBoxLayout = qt.QGridLayout(self.patientGroupBox)

        self.patientsTable = qt.QTableWidget()
        self.patientsTableHeaderLabels = [
            'ID', 'Name', 'BirthDate', 'Sex', 'Modalities'
        ]
        self.patientsTable.setColumnCount(5)
        self.patientsTable.sortingEnabled = True
        self.patientsTable.setHorizontalHeaderLabels(
            self.patientsTableHeaderLabels)
        self.patientsTableHeader = self.patientsTable.horizontalHeader()
        self.patientsTableHeader.setStretchLastSection(True)
        self.patientGroupBoxLayout.addWidget(self.patientsTable, 1, 1, 1, 5)
        abstractItemView = qt.QAbstractItemView()
        self.patientsTable.setSelectionBehavior(abstractItemView.SelectRows)

        self.examinePatientButton = qt.QPushButton('Examine')
        self.examinePatientButton.setEnabled(False)
        self.patientGroupBoxLayout.addWidget(self.examinePatientButton, 2, 4,
                                             1, 2)

        #
        # Other Connections
        #
        self.dirButton.connect('directoryChanged(const QString &)',
                               self.onDICOMDirectoryChanged)