Beispiel #1
0
    def __init__(self):
        QMainWindow.__init__(self)
        self.resize(800, 600)
        self.setWindowTitle('PDF Merger')

        about = QAction('About', self)
        self.connect(about, SIGNAL('triggered()'), self.show_about)
        exit = QAction('Exit', self)
        exit.setShortcut('Ctrl+Q')
        self.connect(exit, SIGNAL('triggered()'), SLOT('close()'))

        self.statusBar()
        menubar = self.menuBar()
        file = menubar.addMenu('File')
        file.addAction(about)
        file.addAction(exit)

        self.main_widget = QWidget(self)
        self.setCentralWidget(self.main_widget)
        self.up_down_widget = QWidget(self)
        self.options_widget = QWidget(self)

        input_files_label = QLabel(
            "Input PDFs\nThis is the order in which the files will be merged too"
        )
        self.files_list = QListWidget()
        self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        add_button = QPushButton("Add PDF(s) to merge...")
        add_button.clicked.connect(self.clicked_add)
        up_button = QPushButton("Up")
        up_button.clicked.connect(self.move_file_up)
        down_button = QPushButton("Down")
        down_button.clicked.connect(self.move_file_down)
        remove_button = QPushButton("Remove PDF")
        remove_button.clicked.connect(self.remove_file)
        select_path_label = QLabel("Output PDF")
        self.dest_path_edit = QLineEdit()
        self.dest_path_edit.setReadOnly(True)
        select_path = QPushButton("Select...")
        select_path.clicked.connect(self.select_save_path)
        start = QPushButton("Start")
        start.clicked.connect(self.merge_pdf)

        up_down_vbox = QVBoxLayout(self.up_down_widget)
        up_down_vbox.addWidget(up_button)
        up_down_vbox.addWidget(down_button)
        up_down_vbox.addWidget(remove_button)
        self.up_down_widget.setLayout(up_down_vbox)

        group_input = QGroupBox()
        grid_input = QGridLayout()
        grid_input.addWidget(add_button, 0, 0)
        grid_input.addWidget(input_files_label, 1, 0)
        grid_input.addWidget(self.files_list, 2, 0)
        grid_input.addWidget(self.up_down_widget, 2, 1)
        group_input.setLayout(grid_input)

        group_output = QGroupBox()
        grid_output = QGridLayout()
        grid_output.addWidget(select_path_label, 0, 0)
        grid_output.addWidget(self.dest_path_edit, 1, 0)
        grid_output.addWidget(select_path, 1, 1)
        group_output.setLayout(grid_output)

        vbox_options = QVBoxLayout(self.options_widget)
        vbox_options.addWidget(group_input)
        vbox_options.addWidget(group_output)
        vbox_options.addWidget(start)
        self.options_widget.setLayout(vbox_options)

        splitter_filelist = QSplitter()
        splitter_filelist.setOrientation(Qt.Vertical)
        splitter_filelist.addWidget(self.options_widget)
        vbox_main = QVBoxLayout(self.main_widget)
        vbox_main.addWidget(splitter_filelist)
        vbox_main.setContentsMargins(0, 0, 0, 0)
Beispiel #2
0
class ClassyWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        layout = QVBoxLayout(self)
        horiz_layout = QHBoxLayout()
        self.conditional_legend_widget = EdgeWidget(self, True)
        self.conditional_legend_widget.setMinimumHeight(15)
        horiz_layout.addWidget(self.conditional_legend_widget)

        self.conditional_legend_label = QLabel("Conditional transition", self)
        horiz_layout.addWidget(self.conditional_legend_label)

        self.unconditional_legend_widget = EdgeWidget(self, False)
        self.unconditional_legend_widget.setMinimumHeight(15)
        horiz_layout.addWidget(self.unconditional_legend_widget)
        self.unconditional_legend_label = QLabel("Non-conditional transition",
                                                 self)
        horiz_layout.addWidget(self.unconditional_legend_label)

        layout.addLayout(horiz_layout)

        self.splitter = QSplitter(self)

        layout.addWidget(self.splitter)

        self.view = ClassyView(self.splitter)
        # layout.addWidget(self.view)
        self.scene = ClassyScene(self)
        self.view.setScene(self.scene)

        self._menu_bar = QMenuBar(self)
        self._menu = QMenu("&File")
        self._menu_bar.addMenu(self._menu)
        layout.setMenuBar(self._menu_bar)

        self.open_action = QAction("O&pen", self)
        self.exit_action = QAction("E&xit", self)
        self._menu.addAction(self.open_action)
        self._menu.addAction(self.exit_action)

        self.connect(self.open_action, SIGNAL("triggered()"), self.open_file)
        self.connect(self.exit_action, SIGNAL("triggered()"), self.close)

        self.settings = QSettings("CD Projekt RED", "TweakDB")

        self.log_window = QPlainTextEdit(self.splitter)
        self.splitter.setOrientation(Qt.Vertical)

        self.setWindowTitle("Classy nodes")

    @Slot()
    def open_file(self):
        last_dir = self.settings.value("last_dir")
        if last_dir is None:
            last_dir = ''
        # noinspection PyCallByClass
        file_path = QFileDialog.getOpenFileName(self, "Select tweakdb file",
                                                last_dir, "*.tweak")

        if file_path[0]:
            tweak_file = file_path[0]
            self.settings.setValue("last_dir", os.path.dirname(tweak_file))
        else:
            return

        try:
            self._process_db_file(file_path[0])
        except Exception as e:
            # noinspection PyCallByClass
            QMessageBox.critical(
                self, "Error",
                "Error while loading {0}: {1}".format(file_path, str(e)))
        self.setWindowTitle("Classy nodes - {0}".format(file_path[0]))

    @Slot(str)
    def log(self, value):
        self.log_window.appendPlainText(str(value))
        self.log_window.verticalScrollBar().scroll(
            0,
            self.log_window.verticalScrollBar().maximum())

    def _process_db_file(self, file_path):
        class TweakClass(object):
            def __init__(self, name, base=""):
                self.name = name
                self.base = base

                self.transitions_to = []
                self.transitions_conditions = []

            def has_transition(self, name):
                return name in self.transitions_to

            def transition_conditional(self, name):
                if len(self.transitions_to) != len(
                        self.transitions_conditions):
                    raise ValueError(
                        "Transitions length does not match conditions length in {0}"
                        .format(self.name))

                if name not in name:
                    raise ValueError(
                        "Class {0} has no transition to {1}".format(
                            self.name, name))

                return self.transitions_conditions[self.transitions_to.index(
                    name)]

        with open(file_path, "r") as f:
            contents = f.read()

        lines = contents.split("\n")

        is_in_class = False
        is_class_declared = False
        current_class = None

        classes = {}
        parsed_line = 0
        for line in lines:
            parsed_line += 1
            if line.startswith("package"):
                continue

            if line.startswith("using"):
                continue

            if not line.strip():
                continue

            if line.startswith("//"):
                continue

            if not is_in_class and not is_class_declared:
                if line.find("=") > 0:  # static variable
                    continue

                spl = [x.strip() for x in line.strip().split(":")]

                if len(spl) == 1:
                    c = TweakClass(spl[0])
                else:
                    c = TweakClass(spl[0], spl[1])

                is_class_declared = True
                current_class = c
                classes[c.name] = c
                continue

            if not is_in_class and not line.find("{") >= 0:
                raise ValueError(
                    "Failed to parse the file {0} in line: {1}".format(
                        file_path, parsed_line))
            else:
                is_in_class = True

            if line.find("}") >= 0:
                is_in_class = False
                is_class_declared = False
                continue

            if re.match(".+transitionTo( +||\t+)+=( +||\t+)+\[.+\]$",
                        line.strip()):

                spl = line.split("=")[1].strip()[1:-1]
                transitions = [x.strip().strip("\"") for x in spl.split(",")]
                current_class.transitions_to = transitions
                continue

            if re.match(".+transitionCondition( +||\t+)+=( +||\t+)+\[.+\]$",
                        line.strip()):
                spl = "=".join(line.split("=")[1:]).strip()[1:-1]
                transitions = [x.strip().strip("\"") for x in spl.split(",")]
                current_class.transitions_conditions = [
                    True if x.strip() == '=' else False for x in transitions
                ]
                continue

        self.scene.clear()

        # --- Create nodes
        for node_key in classes:
            # g.add_node(str(node_key),
            #            shape_fill="#aaaa33",
            #            shape="roundrectangle",
            #            font_style="bolditalic",
            #            label=classes.get(node_key).name)
            self.scene.add_node(node_key)

        edges_created = []
        # --- Create edges
        for node_key in classes:
            # --- Get each node
            current_node = classes.get(node_key)
            # --- Iterate it's "transition_to" list
            for t in current_node.transitions_to:
                # --- Find node to create transition edge to
                transition_to_node = classes.get(t)
                if transition_to_node is None:
                    self.log("Invalid transition in class {0} -> {1}".format(
                        node_key, t))
                    continue

                # --- Check if it's a two way transition
                two_way = False
                if transition_to_node.has_transition(node_key):
                    two_way = True

                # --- make sure that these edges were not created yet
                edges_to_create = ["{0}!@#{1}".format(node_key, t)]
                if two_way:
                    edges_to_create = ["{0}!@#{1}".format(t, node_key)]

                edge_already_created = False
                for e in edges_to_create:
                    if e in edges_created:
                        edge_already_created = True
                        break
                if edge_already_created:
                    continue

                # --- Check if the transitions are conditional or not
                try:
                    conditional_to = current_node.transition_conditional(t)
                except ValueError as e:
                    self.log(str(e))
                    continue

                conditional_from = False

                if two_way:
                    conditional_from = transition_to_node.transition_conditional(
                        node_key)

                self.scene.add_edge(current_node.name,
                                    transition_to_node.name,
                                    conditional_to=conditional_to,
                                    two_way=two_way,
                                    conditional_from=conditional_from)

                edges_created += edges_to_create

        self.scene.layout_nodes()
class RegistrationShop(MainWindow, WindowDialog):
    """
	Main class that starts up the application.
	Creates UI and starts project/plugin managers.
	"""
    def __init__(self, args):
        """
		Sets app specific properties.
		Initializes the UI.
		"""
        super(RegistrationShop, self).__init__(args)

        self.setApplicationPath()
        # Instantiate the project controller
        ProjectController.Instance()

        # Initialize the user interface
        self.initUI()

        lastProject = RegistrationShop.settings.value("project/lastProject",
                                                      None)
        if lastProject:
            self.openProject(lastProject)

    def initialize(self):
        # Initialize the render window interactors only after calling show()
        # otherwise OpenGL errors will occur on OS X
        self.fixedDataWidget.rwi.Initialize()
        self.movingDataWidget.rwi.Initialize()
        self.multiDataWidget.rwi.Initialize()

    # UI setup methods

    def initUI(self):
        """
		Initializes the UI. Makes sure previous state of
		application is restored.
		"""
        # Create actions and elements
        self.createElements()
        self.connectElements()
        self.createActions()
        self.createMenus()
        self.createToolbar()
        self.restoreState()

        # Set some window/application properties
        self.setUnifiedTitleAndToolBarOnMac(True)
        self.setWindowTitle(APPNAME)
        self.setWindowState(Qt.WindowActive)

    def createElements(self):
        """
		Creates the widgets and docks of which the
		main window is composed.
		"""
        self.mainWindow = QMainWindow()
        projectController = ProjectController.Instance()
        self.transformTool = None

        # Render widgets
        self.fixedDataWidget = RenderWidget()
        self.movingDataWidget = RenderWidget()
        self.multiDataWidget = MultiRenderWidget()

        self.fixedRenderController = RenderController(self.fixedDataWidget,
                                                      "fixed")
        self.movingRenderController = RenderController(self.movingDataWidget,
                                                       "moving")
        self.multiRenderController = MultiRenderController(
            self.multiDataWidget)

        # Give references of the render controllers to the project controller
        projectController.fixedRenderController = self.fixedRenderController
        projectController.movingRenderController = self.movingRenderController
        projectController.multiRenderController = self.multiRenderController

        # Render properties widgets
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(1)

        self.fixedPropWidget = RenderPropWidget(self.fixedRenderController,
                                                parent=self)
        self.fixedPropWidget.setSizePolicy(sizePolicy)
        self.fixedPropWidget.setFileChangedSignal(
            projectController.fixedFileChanged)
        self.fixedPropWidget.setLoadDataSlot(self.loadFixedDataSetFile)

        self.movingPropWidget = RenderPropWidget(self.movingRenderController,
                                                 parent=self)
        self.movingPropWidget.setSizePolicy(sizePolicy)
        self.movingPropWidget.setFileChangedSignal(
            projectController.movingFileChanged)
        self.movingPropWidget.setLoadDataSlot(self.loadMovingDataSetFile)

        self.multiPropWidget = MultiRenderPropWidget(
            self.multiRenderController, parent=self)
        self.multiPropWidget.setSizePolicy(sizePolicy)

        self.verticalSplitter = QSplitter()
        self.verticalSplitter.setOrientation(Qt.Vertical)

        # Create the layouts

        fixedDataTitleWidget = TitleWidget("Fixed volume")
        multiDataTitleWidget = TitleWidget("Fixed + Moving")
        movingDataTitleWidget = TitleWidget("Moving volume")

        fixedLayout = QGridLayout()
        fixedLayout.setSpacing(0)
        fixedLayout.setContentsMargins(0, 0, 0, 0)
        fixedLayout.addWidget(fixedDataTitleWidget)
        fixedLayout.addWidget(self.fixedDataWidget)
        fixedWidget = QWidget()
        fixedWidget.setLayout(fixedLayout)

        multiLayout = QGridLayout()
        multiLayout.setSpacing(0)
        multiLayout.setContentsMargins(0, 0, 0, 0)
        multiLayout.addWidget(multiDataTitleWidget)
        multiLayout.addWidget(self.multiDataWidget)
        multiWidget = QWidget()
        multiWidget.setLayout(multiLayout)

        movingLayout = QGridLayout()
        movingLayout.setSpacing(0)
        movingLayout.setContentsMargins(0, 0, 0, 0)
        movingLayout.addWidget(movingDataTitleWidget)
        movingLayout.addWidget(self.movingDataWidget)
        movingWidget = QWidget()
        movingWidget.setLayout(movingLayout)

        horizontalSplitter = QSplitter()
        horizontalSplitter.setOrientation(Qt.Horizontal)
        horizontalSplitter.addWidget(fixedWidget)
        horizontalSplitter.addWidget(multiWidget)
        horizontalSplitter.addWidget(movingWidget)

        propsLayout = QHBoxLayout()
        propsLayout.setSpacing(1)
        propsLayout.setContentsMargins(0, 0, 0, 0)
        propsLayout.addWidget(self.fixedPropWidget)
        propsLayout.addWidget(self.multiPropWidget)
        propsLayout.addWidget(self.movingPropWidget)

        propsWidget = QWidget()
        propsWidget.setMinimumHeight(245)
        propsWidget.setMaximumHeight(350)
        propsWidget.setLayout(propsLayout)

        self.verticalSplitter.addWidget(horizontalSplitter)
        self.verticalSplitter.addWidget(propsWidget)
        self.verticalSplitter.setStretchFactor(0, 2)
        self.verticalSplitter.setStretchFactor(1, 1)
        self.setCentralWidget(self.verticalSplitter)

    def connectElements(self):
        """
		All the elements have to be connected because they are dependent
		on each other.
		There is the project controller, two render controllers and a multi render
		controller.
		Also there are two render widgets and a multi render widget. Together with some
		parameter widgets that show settings and with which the user can interact.
		"""
        projectController = ProjectController.Instance()
        projectController.fixedFileChanged.connect(
            self.fixedRenderController.setFile)
        projectController.fixedFileChanged.connect(
            self.multiRenderController.setFixedFile)
        projectController.movingFileChanged.connect(
            self.movingRenderController.setFile)
        projectController.movingFileChanged.connect(
            self.multiRenderController.setMovingFile)
        projectController.fixedSettingsChanged.connect(
            self.fixedRenderController.setRenderSettings)
        projectController.movingSettingsChanged.connect(
            self.movingRenderController.setRenderSettings)
        projectController.multiSettingsChanged.connect(
            self.multiRenderController.setRenderSettings)

        self.fixedRenderController.visualizationChanged.connect(
            self.multiRenderController.setFixedVisualization)
        self.fixedRenderController.visualizationUpdated.connect(
            self.multiRenderController.setFixedVisualization)
        self.movingRenderController.visualizationChanged.connect(
            self.multiRenderController.setMovingVisualization)
        self.movingRenderController.visualizationUpdated.connect(
            self.multiRenderController.setMovingVisualization)

        self.multiDataWidget.transformations.transformationChanged.connect(
            self.movingDataWidget.transformationsUpdated)

    def createActions(self):
        """
		Create actions that can be attached to buttons and menus.
		"""
        userTransformIconName = AppResources.imageNamed(
            'UserTransformButton.png')
        landmarkTransformIconName = AppResources.imageNamed(
            'LandmarkTransformButton.png')
        deformableTransformIconName = AppResources.imageNamed(
            'DeformableTransformButton.png')
        compareIconName = AppResources.imageNamed('CompareButton.png')
        helpIconName = AppResources.imageNamed('HelpButton.png')

        self.actionFreeTransformTool = QAction('Manual transform',
                                               self,
                                               shortcut='Ctrl+1')
        self.actionFreeTransformTool.setIcon(QIcon(userTransformIconName))
        self.actionFreeTransformTool.triggered.connect(self.addManualTransform)

        self.actionLandmarkTransformTool = QAction('Landmark transform',
                                                   self,
                                                   shortcut='Ctrl+2')
        self.actionLandmarkTransformTool.setIcon(
            QIcon(landmarkTransformIconName))
        self.actionLandmarkTransformTool.triggered.connect(
            self.addLandmarkTransform)

        self.actionDeformableTransformTool = QAction('Automatic transform',
                                                     self,
                                                     shortcut='Ctrl+3')
        self.actionDeformableTransformTool.setIcon(
            QIcon(deformableTransformIconName))
        self.actionDeformableTransformTool.triggered.connect(
            self.addDeformableTransform)

        self.actionLoadFixedData = QAction('Load fixed data',
                                           self,
                                           shortcut='Ctrl+Shift+F')
        self.actionLoadFixedData.triggered.connect(self.loadFixedDataSetFile)

        self.actionLoadMovingData = QAction('Load moving data',
                                            self,
                                            shortcut='Ctrl+Shift+M')
        self.actionLoadMovingData.triggered.connect(self.loadMovingDataSetFile)

        self.actionSaveProject = QAction('Save project',
                                         self,
                                         shortcut='Ctrl+S')
        self.actionSaveProject.triggered.connect(self.saveProject)

        self.actionSaveProjectAs = QAction('Save project as...',
                                           self,
                                           shortcut='Ctrl+Shift+S')
        self.actionSaveProjectAs.triggered.connect(self.saveProjectAs)

        self.actionExportDataAs = QAction('Export data...',
                                          self,
                                          shortcut='Ctrl+E')
        self.actionExportDataAs.triggered.connect(self.exportDataAs)

        self.actionOpenProject = QAction('Open project...',
                                         self,
                                         shortcut='Ctrl+O')
        self.actionOpenProject.triggered.connect(self.openProject)

        self.actionNewProject = QAction('New project', self, shortcut='Ctrl+N')
        self.actionNewProject.triggered.connect(self.newProject)

        self.actionCompare = QAction('Compare', self, shortcut='Ctrl+U')
        self.actionCompare.setIcon(QIcon(compareIconName))
        self.actionCompare.triggered.connect(self.startComparison)

        self.actionHelp = QAction('Help', self, shortcut='Ctrl+H')
        self.actionHelp.setIcon(QIcon(helpIconName))
        self.actionHelp.triggered.connect(self.showHelp)

    def createMenus(self):
        """
		Creates menus from actions.
		"""
        self.menuBar = self.menuBar()
        self.menuItemFile = self.menuBar.addMenu('&File')
        self.menuItemFile.addAction(self.actionNewProject)
        self.menuItemFile.addAction(self.actionOpenProject)
        # TODO: Open recent >
        self.menuItemFile.addAction(self.actionSaveProject)
        self.menuItemFile.addAction(self.actionSaveProjectAs)
        self.menuItemFile.addAction(self.actionExportDataAs)

        self.menuItemProject = self.menuBar.addMenu('&Project')
        self.menuItemProject.addAction(self.actionLoadFixedData)
        self.menuItemProject.addAction(self.actionLoadMovingData)
        self.menuItemProject.addSeparator()

    def createToolbar(self):
        """
		Creates the main toolbar and sets the toolbar buttons.
		"""
        # Add toolbar
        self.toolbar = self.addToolBar('Main tools')
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.toolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.toolbar.setFloatable(False)
        self.toolbar.setMovable(False)

        # Create custom toolbar widget that can align items left, center and right
        self.toolbarWidget = ToolbarWidget()
        self.toolbarWidget.addActionLeft(self.actionFreeTransformTool)
        self.toolbarWidget.addActionLeft(self.actionLandmarkTransformTool)
        self.toolbarWidget.addActionLeft(self.actionDeformableTransformTool)

        statusWidget = StatusWidget.Instance()
        statusWidget.setText(
            "Welcome to RegistrationShop!\nStart your registration by loading two datasets. "
            +
            "After that you can use the transform tools to align your volume data."
        )
        self.toolbarWidget.addCenterItem(statusWidget)

        # Add help button
        self.toolbarWidget.addActionRight(self.actionCompare)
        self.toolbarWidget.addActionRight(self.actionHelp)
        self.toolbar.addWidget(self.toolbarWidget)

    # Private Functions

    def setApplicationPath(self):
        """
		Finds the path to the application. This is done so that it
		can figure out where certain resources are located.
		QCoreApplication::applicationDirPath() on OS X does not return the
		desired path to the actual application but to the python executable
		in /Library/FrameWorks. This is inconvenient because images can't be
		located that way.
		So instead os.path is used to find the location of this __file__.
		"""
        AppVars.setPath(os.path.dirname(os.path.abspath(__file__)))

    # Action callbacks
    @Slot()
    def addManualTransform(self):
        """
		What happens when manual transform is added:
		* Entry is added to the tab history
			* Translation fields
			* Rotation fields
			* Scale field(s)
		* Transform box is added to the render widget
		* Button with apply (will apply the transform to the data)

		Applying the transform to the data means:
		* Create new dataset from transformed data
		* Save this data to the project folder
		* Read in the new data and update this in the multi render widget
		* this would mean a new data model for the multi render widget
		"""
        if not self.movingDataWidget.imageData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Please load a moving dataset before starting a manual transform."
            )
            return

        if self.transformTool is not None:
            self.transformTool.cleanUp()

        self.transformTool = UserTransformationTool()
        self.transformTool.setRenderWidgets(moving=self.movingDataWidget,
                                            multi=self.multiDataWidget)
        self.multiPropWidget.setTransformTool(self.transformTool)
        self.transformTool.toolFinished.connect(self.transformToolFinished)

    @Slot()
    def addLandmarkTransform(self):
        if not self.fixedDataWidget.imageData or not self.movingDataWidget.imageData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Please load a fixed and a moving dataset before starting a landmark transform."
            )
            return

        # Clean up the last transform tool
        if self.transformTool is not None:
            self.transformTool.cleanUp()

        self.transformTool = LandmarkTransformationTool()
        self.transformTool.setRenderWidgets(fixed=self.fixedDataWidget,
                                            moving=self.movingDataWidget,
                                            multi=self.multiDataWidget)

        # Create a tab page under the fixed render widget
        fixedLandmarkWidget = LandmarkWidget()
        self.fixedPropWidget.addTabWidget(fixedLandmarkWidget, "Landmark")

        # Create a tab page under the moving render widget
        movingLandmarkWidget = LandmarkWidget()
        self.movingPropWidget.addTabWidget(movingLandmarkWidget, "Landmark")

        # Make sure the landmark transform tool knows of these tab widgets
        self.transformTool.setLandmarkWidgets(fixedLandmarkWidget,
                                              movingLandmarkWidget)

        # Start the transformation
        self.multiPropWidget.setTransformTool(self.transformTool)
        self.transformTool.toolFinished.connect(self.transformToolFinished)

    @Slot()
    def addDeformableTransform(self):
        if not self.fixedDataWidget.imageData or not self.movingDataWidget.imageData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Please load a fixed and a moving dataset before starting a deformable transform."
            )
            return

        self.multiPropWidget.tabWidget.setCurrentWidget(
            self.multiPropWidget.transformParamWidget)

        if self.transformTool is not None:
            self.transformTool.cleanUp()

        statusWidget = StatusWidget.Instance()
        statusWidget.setText(
            "Choose a template for a deformable transform. After choosing "
            "a template you will be able to review and adjust the parameters.")

        dialog = ElastixMainDialog(self)
        dialog.setModal(True)
        result = dialog.exec_()
        if not result:
            return
        if not dialog.transformation:
            # load custom file
            filename, other = QFileDialog.getOpenFileName(
                self, "Open custom parameter file", "", "(*.c *.txt)")
            if len(filename) == 0:
                return
            transformation = ParameterList()
            if not transformation.loadFromFile(filename):
                transformation = None
                statusWidget = StatusWidget.Instance()
                statusWidget.setText(
                    "Warning: could not load transformation file")
        else:
            transformation = dialog.transformation

        self.transformTool = DeformableTransformationTool()
        self.transformTool.setTransformation(transformation)
        self.transformTool.startedElastix.connect(self.showProgressBar)
        self.transformTool.endedElastix.connect(self.hideProgressBar)
        self.transformTool.setRenderWidgets(fixed=self.fixedDataWidget,
                                            moving=self.movingDataWidget,
                                            multi=self.multiDataWidget)
        self.multiPropWidget.setTransformTool(self.transformTool)
        self.transformTool.toolFinished.connect(self.transformToolFinished)

    @Slot()
    def transformToolFinished(self):
        self.multiPropWidget.transformToolFinished()
        self.fixedPropWidget.removeTabWidget()
        self.movingPropWidget.removeTabWidget()

    @Slot()
    def loadFixedDataSetFile(self):
        """
		Open file dialog to search for data files. If valid data is given, it will
		pass the data file location on to the slicer and the project controller.
		"""
        dataReader = DataReader()
        extensions = dataReader.GetSupportedExtensionsAsString()
        fileName, other = QFileDialog.getOpenFileName(
            self,
            "Open fixed data set",
            "",
            "Images (" + extensions + ")",
            options=QFileDialog.Directory)
        if len(fileName) > 0:
            # If there was another dataset first, ask if the user if the
            # visualizations should be reset
            projectController = ProjectController.Instance()
            if projectController.currentProject.fixedData:
                dialog = ResetVisualizationDialog(self)
                dialog.setWindowModality(Qt.WindowModal)
                dialog.exec_()
                if dialog.result is not None:
                    projectController.loadFixedDataSet(fileName)
                    if dialog.result:
                        self.fixedRenderController.resetVisualizations()
            else:
                projectController.loadFixedDataSet(fileName)

    @Slot()
    def loadMovingDataSetFile(self):
        """
		Open file dialog to search for data files. If valid data is given, it will
		pass the data file location on to the slicer and the project controller.
		"""
        dataReader = DataReader()
        extensions = dataReader.GetSupportedExtensionsAsString()
        fileName, other = QFileDialog.getOpenFileName(
            self,
            "Open moving data set",
            "",
            "Images (" + extensions + ")",
            options=QFileDialog.Directory)
        if len(fileName) > 0:
            # If there was another dataset first, ask if the user if the
            # visualizations should be reset
            projectController = ProjectController.Instance()
            if projectController.currentProject.movingData:
                dialog = ResetVisualizationDialog(self)
                dialog.setWindowModality(Qt.WindowModal)
                dialog.exec_()
                if dialog.result is not None:
                    projectController.loadMovingDataSet(fileName)
                    if dialog.result:
                        self.movingRenderController.resetVisualizations()
            else:
                # Inserting an identity transform
                self.multiDataWidget.transformations.append(
                    Transformation(vtkTransform(), "No transform", fileName))
                projectController.loadMovingDataSet(fileName)

    @Slot()
    def saveProject(self):
        """
		Save the project to the specified name in the current project. If no name
		is specified, then 'save project as' is called.
		"""
        projCont = ProjectController.Instance()

        if projCont.currentProject.folder is not None:
            # Save that project
            saved = projCont.saveProject()
            statusWidget = StatusWidget.Instance()
            if saved:
                # Save it in the settings that this was the last opened project
                RegistrationShop.settings.setValue(
                    "project/lastProject", projCont.currentProject.folder)
                statusWidget.setText(
                    "The project was succesfully saved to disk.")
            else:
                statusWidget.setText(
                    "Something went wrong while saving the project to disk. "
                    "Please try to save the project again.")
        else:
            self.saveProjectAs()

    @Slot()
    def saveProjectAs(self):
        """
		Opens a file dialog so that the user can select a folder
		in which to save the project.
		"""
        # Open file dialog
        fileName = QFileDialog.getExistingDirectory(self,
                                                    "Select project folder",
                                                    "",
                                                    QFileDialog.ShowDirsOnly)
        if len(fileName) > 0:
            # TODO: check for existing project!

            # Set filename of project
            ProjectController.Instance().currentProject.folder = fileName
            # Call save project
            self.saveProject()

    @Slot()
    def openProject(self, folderName=None):
        """
		If no project name is supplied, it will open a file dialog so
		that the user can select a project file
		or project folder.

		:param folderName: Name of a folder with a project
		:type folderName: basestring
		"""
        fileName = ""
        if folderName:
            fileName = folderName
        else:
            fileName = QFileDialog.getExistingDirectory(
                self, "Open project", "", QFileDialog.ShowDirsOnly)

        if len(fileName) > 0:
            fullName = fileName + ProjectController.Instance().ProjectFile
            if os.path.isfile(fullName):
                self.multiDataWidget.transformations.clear()
                loaded = ProjectController.Instance().loadProject(fileName)
                if loaded:
                    RegistrationShop.settings.setValue("project/lastProject",
                                                       fileName)
                else:
                    print "Couldn't load project:", folderName
            else:
                print "Warning: Project file does not exist"
                RegistrationShop.settings.remove("project/lastProject")

    @Slot()
    def newProject(self):
        """
		Create new project by calling the project controller
		"""
        self.multiDataWidget.transformations.clear()
        ProjectController.Instance().newProject()
        # Reset the last loaded project in the settings
        RegistrationShop.settings.setValue("project/lastProject", "")

    @Slot()
    def exportDataAs(self):
        """
		Opens a file dialog so that the user can provide a filename
		for saving the transformed dataset to.
		"""
        fileType = FileTypeDialog.getFileType(self,
                                              "Choose file type for export")
        if len(fileType) == 0:
            return

        extension = "(*." + fileType + ")"
        fileName, other = QFileDialog.getSaveFileName(
            self, "Save registration result to...", "", extension)
        if len(fileName) == 0:
            return

        self.showProgressBar("Exporting data...")

        transform = self.multiDataWidget.transformations.completeTransform()
        dataReader = DataReader()
        imageData = dataReader.GetImageData(
            ProjectController.Instance().currentProject.movingData)
        transformer = DataTransformer()
        outputData = transformer.TransformImageData(imageData, transform)
        writer = DataWriter()
        writer.WriteToFile(outputData, fileName, fileType)

        self.hideProgressBar()

    @Slot()
    def startComparison(self):
        projectController = ProjectController.Instance()
        project = projectController.currentProject
        if not project or not project.fixedData or not project.movingData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Could not start comparison. Please make a project first"
                " and make sure to load two datasets.")
            return

        if hasattr(self, "compareWidget"):
            del self.compareWidget

        transform = self.multiDataWidget.transformations.completeTransform()

        self.controller = ComparisonController()
        self.controller.setInputData(project.fixedData, project.movingData,
                                     transform)
        self.compareWidget = CompareWidget(self.controller.widgets)
        self.compareWidget.show()
        self.controller.initialize()
        self.controller.slicerChanged(self.controller.fixedImageWidget)

    @Slot()
    def showHelp(self):
        statusWidget = StatusWidget.Instance()
        statusWidget.setText("Don't panic!")
Beispiel #4
0
	def __init__(self):
		QMainWindow.__init__(self)
		self.resize(800,600)
		self.setWindowTitle('PDF Merger')

		about = QAction('About', self)
		self.connect(about, SIGNAL('triggered()'), self.show_about)
		exit = QAction('Exit', self)
		exit.setShortcut('Ctrl+Q')
		self.connect(exit, SIGNAL('triggered()'), SLOT('close()'))

		self.statusBar()
		menubar = self.menuBar()
		file = menubar.addMenu('File')
		file.addAction(about)
		file.addAction(exit)

		self.main_widget = QWidget(self)
		self.setCentralWidget(self.main_widget)
		self.up_down_widget = QWidget(self)
		self.options_widget = QWidget(self)
		

		input_files_label = QLabel("Input PDFs\nThis is the order in which the files will be merged too")
		self.files_list = QListWidget()
		self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
		add_button = QPushButton("Add PDF(s) to merge...")
		add_button.clicked.connect(self.clicked_add)
		up_button = QPushButton("Up")
		up_button.clicked.connect(self.move_file_up)
		down_button = QPushButton("Down")
		down_button.clicked.connect(self.move_file_down)
		remove_button = QPushButton("Remove PDF")
		remove_button.clicked.connect(self.remove_file)
		select_path_label = QLabel("Output PDF")
		self.dest_path_edit = QLineEdit()
		self.dest_path_edit.setReadOnly(True)
		select_path = QPushButton("Select...")
		select_path.clicked.connect(self.select_save_path)
		start = QPushButton("Start")
		start.clicked.connect(self.merge_pdf)

		up_down_vbox = QVBoxLayout(self.up_down_widget)
		up_down_vbox.addWidget(up_button)
		up_down_vbox.addWidget(down_button)
		up_down_vbox.addWidget(remove_button)
		self.up_down_widget.setLayout(up_down_vbox)

		group_input = QGroupBox()
		grid_input = QGridLayout()
		grid_input.addWidget(add_button, 0, 0)
		grid_input.addWidget(input_files_label, 1, 0)
		grid_input.addWidget(self.files_list, 2, 0)
		grid_input.addWidget(self.up_down_widget, 2, 1)
		group_input.setLayout(grid_input)

		group_output = QGroupBox()
		grid_output = QGridLayout()
		grid_output.addWidget(select_path_label, 0, 0)
		grid_output.addWidget(self.dest_path_edit, 1, 0)
		grid_output.addWidget(select_path, 1, 1)
		group_output.setLayout(grid_output)

		vbox_options = QVBoxLayout(self.options_widget)
		vbox_options.addWidget(group_input)
		vbox_options.addWidget(group_output)
		vbox_options.addWidget(start)
		self.options_widget.setLayout(vbox_options)

		splitter_filelist = QSplitter()
		splitter_filelist.setOrientation(Qt.Vertical)
		splitter_filelist.addWidget(self.options_widget)
		vbox_main = QVBoxLayout(self.main_widget)
		vbox_main.addWidget(splitter_filelist)
		vbox_main.setContentsMargins(0,0,0,0)
    def createElements(self):
        """
		Creates the widgets and docks of which the
		main window is composed.
		"""
        self.mainWindow = QMainWindow()
        projectController = ProjectController.Instance()
        self.transformTool = None

        # Render widgets
        self.fixedDataWidget = RenderWidget()
        self.movingDataWidget = RenderWidget()
        self.multiDataWidget = MultiRenderWidget()

        self.fixedRenderController = RenderController(self.fixedDataWidget,
                                                      "fixed")
        self.movingRenderController = RenderController(self.movingDataWidget,
                                                       "moving")
        self.multiRenderController = MultiRenderController(
            self.multiDataWidget)

        # Give references of the render controllers to the project controller
        projectController.fixedRenderController = self.fixedRenderController
        projectController.movingRenderController = self.movingRenderController
        projectController.multiRenderController = self.multiRenderController

        # Render properties widgets
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(1)

        self.fixedPropWidget = RenderPropWidget(self.fixedRenderController,
                                                parent=self)
        self.fixedPropWidget.setSizePolicy(sizePolicy)
        self.fixedPropWidget.setFileChangedSignal(
            projectController.fixedFileChanged)
        self.fixedPropWidget.setLoadDataSlot(self.loadFixedDataSetFile)

        self.movingPropWidget = RenderPropWidget(self.movingRenderController,
                                                 parent=self)
        self.movingPropWidget.setSizePolicy(sizePolicy)
        self.movingPropWidget.setFileChangedSignal(
            projectController.movingFileChanged)
        self.movingPropWidget.setLoadDataSlot(self.loadMovingDataSetFile)

        self.multiPropWidget = MultiRenderPropWidget(
            self.multiRenderController, parent=self)
        self.multiPropWidget.setSizePolicy(sizePolicy)

        self.verticalSplitter = QSplitter()
        self.verticalSplitter.setOrientation(Qt.Vertical)

        # Create the layouts

        fixedDataTitleWidget = TitleWidget("Fixed volume")
        multiDataTitleWidget = TitleWidget("Fixed + Moving")
        movingDataTitleWidget = TitleWidget("Moving volume")

        fixedLayout = QGridLayout()
        fixedLayout.setSpacing(0)
        fixedLayout.setContentsMargins(0, 0, 0, 0)
        fixedLayout.addWidget(fixedDataTitleWidget)
        fixedLayout.addWidget(self.fixedDataWidget)
        fixedWidget = QWidget()
        fixedWidget.setLayout(fixedLayout)

        multiLayout = QGridLayout()
        multiLayout.setSpacing(0)
        multiLayout.setContentsMargins(0, 0, 0, 0)
        multiLayout.addWidget(multiDataTitleWidget)
        multiLayout.addWidget(self.multiDataWidget)
        multiWidget = QWidget()
        multiWidget.setLayout(multiLayout)

        movingLayout = QGridLayout()
        movingLayout.setSpacing(0)
        movingLayout.setContentsMargins(0, 0, 0, 0)
        movingLayout.addWidget(movingDataTitleWidget)
        movingLayout.addWidget(self.movingDataWidget)
        movingWidget = QWidget()
        movingWidget.setLayout(movingLayout)

        horizontalSplitter = QSplitter()
        horizontalSplitter.setOrientation(Qt.Horizontal)
        horizontalSplitter.addWidget(fixedWidget)
        horizontalSplitter.addWidget(multiWidget)
        horizontalSplitter.addWidget(movingWidget)

        propsLayout = QHBoxLayout()
        propsLayout.setSpacing(1)
        propsLayout.setContentsMargins(0, 0, 0, 0)
        propsLayout.addWidget(self.fixedPropWidget)
        propsLayout.addWidget(self.multiPropWidget)
        propsLayout.addWidget(self.movingPropWidget)

        propsWidget = QWidget()
        propsWidget.setMinimumHeight(245)
        propsWidget.setMaximumHeight(350)
        propsWidget.setLayout(propsLayout)

        self.verticalSplitter.addWidget(horizontalSplitter)
        self.verticalSplitter.addWidget(propsWidget)
        self.verticalSplitter.setStretchFactor(0, 2)
        self.verticalSplitter.setStretchFactor(1, 1)
        self.setCentralWidget(self.verticalSplitter)