예제 #1
0
  def substitute(self, stmt):
    """
    Given a procedure call statement, return the process body for the
    procedure.
    """
    if isinstance(stmt, ast.StmtPcall) and \
        self.sig.is_mobile(stmt.name) and \
        self.sig.has_channel_params(stmt.name):
      defn = [x for x in self.ast.defs if x.name == stmt.name][0]
      proc = copy.deepcopy(defn.stmt)

      # Rename actual parameters for ocurrances of formals
      for (x, y) in zip(defn.formals, stmt.args):
        if x.type == T_VAL_SINGLE:
          proc.accept(SubElem(ast.ElemId(x.name), y))
        elif x.type == T_REF_SINGLE:
          proc.accept(SubElem(ast.ElemId(x.name), y.elem))
        elif x.type == T_REF_ARRAY:
          proc.accept(Rename(x.name, y.elem.name, y.elem.symbol))
        elif x.type == T_CHANEND_SINGLE:
          proc.accept(SubElem(ast.ElemId(x.name), y.elem))
        elif x.type == T_CHANEND_ARRAY:
          proc.accept(Rename(x.name, y.elem.name, y.elem.symbol))
        else:
          assert 0

      return proc
    else:
      return stmt
예제 #2
0
 def test_correct_filename_method_should_not_change_word_afront_to_aafront(
         self):
     filename = "Test_File_FOLD1_FRONT.tif"
     number_of_digits = 2
     result = Rename.correct_filename(filename, number_of_digits)
     expected = "test_file_fold01_afront.tif"
     self.assertEqual(expected, result, "The two filenames are not equal")
     result2 = Rename.correct_filename(expected, number_of_digits)
     expected2 = "test_file_fold01_afront.tif"
     self.assertEqual(expected2, result2, "The two filenames are not equal")
예제 #3
0
    def test_correct_filename_method_should_change_all_numbers_in_filename(
            self):
        filename = "Test_File_N1_FOLD1_BACK.tif"
        number_of_digits = 3
        result = Rename.correct_filename(filename, number_of_digits)
        expected = "test_file_n001_fold001_back.tif"
        self.assertEqual(expected, result, "The two filenames are not equal")

        filename = "Test_File_N2_FOLD1_BACK.tif"
        number_of_digits = 3
        result = Rename.correct_filename(filename, number_of_digits)
        expected = "test_file_n002_fold001_back.tif"
        self.assertEqual(expected, result, "The two filenames are not equal")
예제 #4
0
 def get_object(page_name):
     page_obj = None
     page_name = page_name.lower()
     if page_name == "loginpage":
         page_obj = LoginPage()
     elif page_name == "rename":
         page_obj = Rename()
     elif page_name == "dashboard":
         page_obj = Dashboard()
     elif page_name == "accountpage":
         page_obj = AccountPage()
     return page_obj
예제 #5
0
파일: main.py 프로젝트: tyrc94/mass_rename
    def execute(self):
        print(self.search_pattern.text())
        print(self.replace_text.text())
        print(self.directory_field.text())
        print(self.recursion_check.isChecked())

        if self.directory_field.text() == '':
            print('Empty!')
            QMessageBox.warning(QWidget(), 'Error',
                                'Directory field is empty!', QMessageBox.Ok)
            return

        run = Rename(self.search_pattern.text(), self.replace_text.text(),
                     self.directory_field.text(),
                     self.recursion_check.isChecked())

        run.populate()
        confirm_msg = f'Are you sure that you want to change {run.num_files} files?\nThese changes will be irreversible.'
        reply = QMessageBox.question(QWidget(), 'Caution', confirm_msg,
                                     QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            complete = run.rename(self.progressBar.setValue)

        if reply == QMessageBox.No:
            return

        if complete:
            QMessageBox.information(QWidget(), 'Complete',
                                    'Renaming successful.', QMessageBox.Ok)
            self.progressBar.setValue(0)
            self.search_pattern.setText("")
            self.replace_text.setText("")
            self.directory_field.setText("")

        elif not complete:
            QMessageBox.critical(
                QWidget(), 'Error',
                'An error has occured.\nPlease check your input and try again.',
                QMessageBox.Ok)
예제 #6
0
    def correct_tiff_filenames(self, digits):
        """
            Function lit every file in folder TIF_DIRECTORY from config file
            and of every file execute function Rename.correct_filename(name,digits)
            which changes name accordingly: uppercase to smallcase,  word front to afront,
            numbering convention from 1, 2, 3 to 001, 002, 003 if digits = 3

            :param digits:
        """
        file_list = os.listdir(self.tif_directory)
        file_renamed_count = 0
        file_in_list_count = len(file_list)
        for name in file_list:
            new_name =  Rename.correct_filename(name, digits)
            if name.__ne__(new_name):
                os.rename(self.tif_directory + name, self.tif_directory + new_name)
                file_renamed_count += 1
        print("Files in folder: " + str(file_in_list_count) + "\nFiles changed: " +
               str(file_renamed_count))
예제 #7
0
    def correct_tiff_filenames(self, digits):
        """
            Function lit every file in folder TIF_DIRECTORY from config file
            and of every file execute function Rename.correct_filename(name,digits)
            which changes name accordingly: uppercase to smallcase,  word front to afront,
            numbering convention from 1, 2, 3 to 001, 002, 003 if digits = 3

            :param digits:
        """
        file_list = os.listdir(self.tif_directory)
        file_renamed_count = 0
        file_in_list_count = len(file_list)
        for name in file_list:
            new_name = Rename.correct_filename(name, digits)
            if name.__ne__(new_name):
                os.rename(self.tif_directory + name,
                          self.tif_directory + new_name)
                file_renamed_count += 1
        print("Files in folder: " + str(file_in_list_count) +
              "\nFiles changed: " + str(file_renamed_count))
예제 #8
0
 def __init__(self, parent=None, updater=None, availableStudies=0):
     logging.debug("In ImportChooser::__init__()")
     super(ImportChooser, self).__init__(parent)
     self.setupUi(self)
     self.stopButton.setDisabled(True)
     self.importButton.setDisabled(True)
     self.availableStudiesLabel.setText(self.availableStudiesLabel.text().format(availableStudies))
     self._availableStudies = availableStudies
     if availableStudies == -1:
         self.availableStudiesLabel.setVisible(False)
     self.createActions()
     self.createSignals()
     self._singleShotTime = 500
     self.updateWidgets()
     self._importer = Importer()
     self._updater = updater
     self._warning = False
     self._msg = ""
     self._firstImport = False
     self.rename = Rename(self)
     self.rename.label.setText(
         QtGui.QApplication.translate("ImportChooser", "Serie's Description:", None, QtGui.QApplication.UnicodeUTF8)
     )
예제 #9
0
 def test_correct_filename_method_should_change_numbers_11_19_(self):
     filename = "11-19.pdf"
     number_of_digits = 3
     result = Rename.correct_filename(filename, number_of_digits)
     expected = "011-019.pdf"
     self.assertEqual(expected, result, "The two filenames are not equal")
예제 #10
0
 def test_correct_filename_method_should_change_number_2_to_02(self):
     filename = "Test_File_FOLD2_FRONT.tif"
     number_of_digits = 2
     result = Rename.correct_filename(filename, number_of_digits)
     expected = "test_file_fold02_afront.tif"
     self.assertEqual(expected, result, "The two filenames are not equal")
예제 #11
0
class ImportChooser(QtGui.QDialog, Ui_ImportChooser):
    def __init__(self, parent=None, updater=None, availableStudies=0):
        logging.debug("In ImportChooser::__init__()")
        super(ImportChooser, self).__init__(parent)
        self.setupUi(self)
        self.stopButton.setDisabled(True)
        self.importButton.setDisabled(True)
        self.availableStudiesLabel.setText(self.availableStudiesLabel.text().format(availableStudies))
        self._availableStudies = availableStudies
        if availableStudies == -1:
            self.availableStudiesLabel.setVisible(False)
        self.createActions()
        self.createSignals()
        self._singleShotTime = 500
        self.updateWidgets()
        self._importer = Importer()
        self._updater = updater
        self._warning = False
        self._msg = ""
        self._firstImport = False
        self.rename = Rename(self)
        self.rename.label.setText(
            QtGui.QApplication.translate("ImportChooser", "Serie's Description:", None, QtGui.QApplication.UnicodeUTF8)
        )

    def createSignals(self):
        logging.debug("In ImportChooser::createSignals()")

    def createActions(self):
        logging.debug("In ImportChooser::createActions()")
        self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self.slotActionCancel)
        self.connect(self.stopButton, QtCore.SIGNAL("clicked()"), self.slotActionStop)
        self.connect(self.importButton, QtCore.SIGNAL("clicked()"), self.slotActionImport)
        self.connect(self.addButton, QtCore.SIGNAL("clicked()"), self.slotActionAdd)
        self.connect(self.tableView, QtCore.SIGNAL("clicked(QModelIndex)"), self.slotActionItemClicked)
        self.connect(self.tableView, QtCore.SIGNAL("doubleClicked(QModelIndex)"), self.slotActionItemDoubleClicked)

    def slotActionStop(self):
        if self._importer.finished == 0:
            self._msg = QtGui.QApplication.translate("ImportChooser", "Stopping", None, QtGui.QApplication.UnicodeUTF8)
            self.stopButton.setDisabled(True)
            self._importer.stop()

    def slotActionItemClicked(self, modelIndex):
        if modelIndex.column() == 1:
            uid = self.itemModel.data(self.itemModel.index(modelIndex.row(), 6))
            if modelIndex.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked:
                self._importer.series[uid]["checked"] = False
                self.itemModel.setData(modelIndex, QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole)
            else:
                self.itemModel.setData(modelIndex, QtCore.Qt.Checked, QtCore.Qt.CheckStateRole)
                self._importer.series[uid]["checked"] = True

    def slotActionItemDoubleClicked(self, modelIndex):
        self.rename.renameSerie(
            self._importer.series[self.itemModel.data(self.itemModel.index(modelIndex.row(), 6))], self.fillTable
        )

    def slotActionCancel(self):
        self._msg = QtGui.QApplication.translate("ImportChooser", "Cancelling", None, QtGui.QApplication.UnicodeUTF8)
        if self._importer.finished == 0 and self._firstImport:
            self.cancelButton.setDisabled(True)
            self._importer.cancel()
        else:
            self.close()

    def slotActionAdd(self):
        settings = QtCore.QSettings("Moonstone", "Medical")
        lastdir = settings.value("ImportChooser-last-dir")

        caption = QtGui.QApplication.translate(
            "ImportChooser", "Select the directory of DICOMs", None, QtGui.QApplication.UnicodeUTF8
        )
        options = QtGui.QFileDialog.ShowDirsOnly

        dialog = QtGui.QFileDialog.getExistingDirectory(self, caption, lastdir, options)
        if dialog:
            # while QtCore.QCoreApplication.hasPendingEvents():
            #    QtCore.QCoreApplication.processEvents()
            self.loadDirectory(dialog)
            settings.setValue("ImportChooser-last-dir", dialog)

    def slotActionImport(self):
        logging.debug("In ImportChooser::slotActionImport()")
        self._firstImport = True
        self._msg = QtGui.QApplication.translate(
            "ImportChooser", "Importing series...", None, QtGui.QApplication.UnicodeUTF8
        )
        series = []
        for i in range(self.itemModel.rowCount()):
            if self.itemModel.data(self.itemModel.index(i, 1), QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked:
                series.append(self.itemModel.data(self.itemModel.index(i, 6)))
                self._importer.series[self.itemModel.data(self.itemModel.index(i, 6))]["error"] == False
        if len(series) == 0:
            QtGui.QMessageBox.information(
                self,
                QtGui.QApplication.translate("ImportChooser", "Warning", None, QtGui.QApplication.UnicodeUTF8),
                QtGui.QApplication.translate(
                    "ImportChooser", "There is no serie selected!", None, QtGui.QApplication.UnicodeUTF8
                ),
            )
        elif len(series) <= self._availableStudies or self._availableStudies == -1:
            self.cancelButton.setDisabled(False)
            self._importer.makeImport(series)
            self.addButton.setDisabled(True)
            self.importButton.setDisabled(True)
            self.stopButton.setEnabled(True)
            self.recursiveCheck.setDisabled(True)
            self.tableView.setEnabled(False)
            self.progressLabel.show()
            self.updateProgress()
        else:
            QtGui.QMessageBox.critical(
                self,
                QtGui.QApplication.translate("ImportChooser", "Error", None, QtGui.QApplication.UnicodeUTF8),
                QtGui.QApplication.translate(
                    "ImportChooser",
                    "You do not have sufficient series available. Please uncheck the excess!",
                    None,
                    QtGui.QApplication.UnicodeUTF8,
                ),
            )

    def updateWidgets(self):
        logging.debug("In ImportChooser::updateWidgets()")
        self.itemModel = QtGui.QStandardItemModel()
        self.itemModel.setHorizontalHeaderLabels(
            [
                " ",
                " ",
                QtGui.QApplication.translate("ImportChooser", "Progress", None, QtGui.QApplication.UnicodeUTF8),
                QtGui.QApplication.translate("ImportChooser", "Patient", None, QtGui.QApplication.UnicodeUTF8),
                QtGui.QApplication.translate("ImportChooser", "Description", None, QtGui.QApplication.UnicodeUTF8),
                QtGui.QApplication.translate("ImportChooser", "Images", None, QtGui.QApplication.UnicodeUTF8),
                QtGui.QApplication.translate("ImportChooser", "UID", None, QtGui.QApplication.UnicodeUTF8),
            ]
        )
        self.tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.tableView.setModel(self.itemModel)
        self.tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.tableView.setItemDelegate(ImportItemDelegate())
        self.tableView.setSortingEnabled(True)
        self.tableView.setColumnWidth(0, 20)
        self.tableView.setColumnWidth(1, 30)
        self.tableView.setColumnWidth(2, 80)
        self.tableView.setColumnWidth(3, 260)
        self.tableView.setColumnWidth(4, 190)
        self.tableView.setColumnWidth(5, 60)
        self.tableView.setColumnHidden(6, True)

    def updateProgress(self):
        logging.debug("In ImportChooser::updateProgress()")
        self._importer.updateSeries()
        if not self._importer.finished:
            self.statusLabel.setText(self._msg)
            QtCore.QTimer.singleShot(self._singleShotTime, self.updateProgress)
        else:
            self.stopButton.setDisabled(True)
            self.cancelButton.setDisabled(False)
            self.statusLabel.setText(
                QtGui.QApplication.translate("ImportChooser", "Complete", None, QtGui.QApplication.UnicodeUTF8)
            )
            self.progressLabel.hide()
            self.addButton.setDisabled(False)
            self.importButton.setDisabled(False)
            self.recursiveCheck.setDisabled(False)
            self.tableView.setEnabled(True)
            if self._importer.finished == 1 and self._warning:
                QtGui.QMessageBox.warning(
                    self,
                    QtGui.QApplication.translate("ImportChooser", "Warning", None, QtGui.QApplication.UnicodeUTF8),
                    QtGui.QApplication.translate(
                        "ImportChooser",
                        "There are series you want to import"
                        + " that already are in database. These series will"
                        + " automaticaly be unchecked, if you want to"
                        + " import any of them, check is manualy.",
                        None,
                        QtGui.QApplication.UnicodeUTF8,
                    ),
                )
            elif self._importer.finished == 2:
                values = self._importer.series.values()
                error = False
                seriesImported = 0
                for serie in values:
                    if serie["error"]:
                        error = True
                    else:
                        if serie["checked"]:
                            seriesImported = seriesImported + 1
                if not error:
                    QtGui.QMessageBox.information(
                        self,
                        QtGui.QApplication.translate("ImportChooser", "Success", None, QtGui.QApplication.UnicodeUTF8),
                        QtGui.QApplication.translate(
                            "ImportChooser",
                            "All series were imported with success!",
                            None,
                            QtGui.QApplication.UnicodeUTF8,
                        ),
                    )
                    self.close()
                else:
                    QtGui.QMessageBox.critical(
                        self,
                        QtGui.QApplication.translate("ImportChooser", "Error", None, QtGui.QApplication.UnicodeUTF8),
                        QtGui.QApplication.translate(
                            "ImportChooser", "Error founded during importation!", None, QtGui.QApplication.UnicodeUTF8
                        ),
                    )
                if self._updater:
                    self._updater(seriesImported)
        self.fillTable(self._importer.series)

    def loadDirectory(self, directory):
        logging.debug("In ImportChooser::loadDirectory()")
        self._importer.loadDirectory(directory, self.recursiveCheck.isChecked())
        self._msg = QtGui.QApplication.translate(
            "ImportChooser", "Loading directory...", None, QtGui.QApplication.UnicodeUTF8
        )
        if not self.progressLabel.movie():
            movie = QtGui.QMovie()
            movie.setFileName(":/static/default/ajax-loader.gif")
            self.progressLabel.setMovie(movie)
            QtCore.QObject.connect(movie, QtCore.SIGNAL("frameChanged(int)"), lambda i: movie.jumpToFrame(i))
            self.progressLabel.movie().start()
        self.addButton.setDisabled(True)
        self.importButton.setDisabled(True)
        if self.recursiveCheck.isChecked:
            self.stopButton.setDisabled(False)
        else:
            self.stopButton.setDisabled(True)
        self.cancelButton.setDisabled(True)
        self.recursiveCheck.setDisabled(True)
        self.tableView.setEnabled(False)
        self.progressLabel.show()
        self.updateProgress()

    def fillTable(self, series=None):
        logging.debug("In ImportChooser::fillTable()")
        if not series:
            series = self._importer.series
        self.itemModel.setRowCount(len(series))
        values = series.values()
        self._warning = False
        for i, serie in enumerate(values):
            if (self._importer.finished == 2 and serie["error"]) or self._importer.finished != 2:
                if serie["checked"]:
                    checked = QtCore.Qt.Checked
                else:
                    checked = QtCore.Qt.Unchecked
                icon = QtGui.QIcon()
                if serie["error"]:
                    icon.addPixmap(
                        QtGui.QPixmap(":/static/default/icon/22x22/dialog-error.png"),
                        QtGui.QIcon.Normal,
                        QtGui.QIcon.Off,
                    )
                    self.itemModel.setData(
                        self.itemModel.index(i, 0),
                        QtGui.QApplication.translate(
                            "ImportChooser",
                            "There was a error importing this serie",
                            None,
                            QtGui.QApplication.UnicodeUTF8,
                        ),
                        QtCore.Qt.ToolTipRole,
                    )
                    self.itemModel.setData(self.itemModel.index(i, 0), icon, QtCore.Qt.DecorationRole)
                elif serie["exists"]:
                    self._warning = True
                    icon.addPixmap(
                        QtGui.QPixmap(":/static/default/icon/22x22/dialog-warning.png"),
                        QtGui.QIcon.Normal,
                        QtGui.QIcon.Off,
                    )
                    self.itemModel.setData(
                        self.itemModel.index(i, 0),
                        QtGui.QApplication.translate(
                            "ImportChooser",
                            "This serie already exists in database.\nIf you import all data will be lost.\nRename the serie to import it  separately",
                            None,
                            QtGui.QApplication.UnicodeUTF8,
                        ),
                        QtCore.Qt.ToolTipRole,
                    )
                    self.itemModel.setData(self.itemModel.index(i, 0), icon, QtCore.Qt.DecorationRole)
                else:
                    icon.addPixmap(
                        QtGui.QPixmap(":/static/default/icon/22x22/dialog-ok-apply.png"),
                        QtGui.QIcon.Normal,
                        QtGui.QIcon.Off,
                    )
                    self.itemModel.setData(
                        self.itemModel.index(i, 0),
                        QtGui.QApplication.translate(
                            "ImportChooser", "This serie is ready to be importer", None, QtGui.QApplication.UnicodeUTF8
                        ),
                        QtCore.Qt.ToolTipRole,
                    )
                    self.itemModel.setData(self.itemModel.index(i, 0), icon, QtCore.Qt.DecorationRole)
                self.itemModel.setData(self.itemModel.index(i, 1), checked, QtCore.Qt.CheckStateRole)
                self.itemModel.setData(self.itemModel.index(i, 2), serie["progress"])
                self.itemModel.setData(self.itemModel.index(i, 3), serie["patientName"])
                self.itemModel.setData(self.itemModel.index(i, 4), serie["serieDescription"])
                self.itemModel.setData(self.itemModel.index(i, 5), len(serie["files"]))
                self.itemModel.setData(self.itemModel.index(i, 6), serie["uid"])
                self.tableView.repaint()
예제 #12
0
파일: gui.py 프로젝트: AboarDev/BoarRename
    def __init__(self):
        self.rn = Rename()
        self.root = Tk()
        self.root.title('Rename Files')
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        self.root.resizable(FALSE,FALSE)
        self.options = ["Custom/Folder Name","sequential","4 Digit","Remove Brackets"]
        self.extensions = ["ANY"]

        self.mainframe = ttk.Frame(self.root, padding="6 6 6 6")
        self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))

        self.dir_name = StringVar()
        self.a_dir = StringVar()
        self.min_var = IntVar()
        self.min_var.set(1)
        self.max_var = IntVar()
        self.max_var.set(1)
        self.a_dir.set('Directory')
        self.folder = None
        self.tree = ttk.Treeview(self.mainframe, columns=('newname'))
        self.tree.grid(column=1, row=3, columnspan=5)
        self.tree.heading('#0', text='Current Filename')
        self.tree.heading('0', text='New Filename')
        self.tree.column('#0',width=300)
        self.tree.column('0', width=300)

        self.addWhitespace = BooleanVar()
        self.addWhitespace.set(TRUE)

        self.scroll = ttk.Scrollbar(self.mainframe, orient=VERTICAL, command=self.tree.yview)
        self.scroll.grid(column=6, row=3, sticky=(N,S))

        self.tree.configure(yscrollcommand=self.scroll.set)

        self.path = ttk.Label(self.mainframe, width=100, textvariable=self.a_dir)
        self.path.grid(column=1, row=1, columnspan=5, sticky=W)

        self.dir_entry = ttk.Entry(self.mainframe, width=7, textvariable=self.dir_name)
        self.dir_entry.grid(column=1, row=2, columnspan=5, sticky=(W, E))

        self.min = ttk.Entry(self.mainframe, width=4, textvariable=self.min_var)
        self.min.grid(column=2, row=5)

        self.minMax = ttk.Label(self.mainframe, width = 10, text="Min / Max")
        self.minMax.grid(column=1,row=5)

        self.max = ttk.Entry(self.mainframe, width=4, textvariable=self.max_var)
        self.max.grid(column=3, row=5)

        self.ab = ttk.Button(self.mainframe, text='Select Directory', command=self.open_dir)
        self.ab.grid(column=3, row=8, sticky=E)

        self.refresh = ttk.Button(self.mainframe, text='refresh/preview', command=self.refresh)
        self.refresh.grid(column=4, row=8, sticky=E)

        self.spacingCheck = ttk.Checkbutton(self.mainframe,text='Add Spaces',variable = self.addWhitespace)
        self.spacingCheck.grid(column = 3, row = 6)
        self.spacingCheck.bind('<Button-1>',self.setSpacing)

        self.choseOptionLabel = ttk.Label(self.mainframe, width = 16, text="Renaming Mode")
        self.choseOptionLabel.grid(column = 1, row = 6)

        self.choseOption = ttk.Combobox(self.mainframe, values = self.options, state='readonly')
        self.choseOption.grid(column = 2, row = 6)
        self.choseOption.current(newindex = 0)
        self.choseOption.bind('<<ComboboxSelected>>',self.setMode)

        self.apply = ttk.Button(self.mainframe, text='Apply', command=self.apply)
        self.apply.grid(column=5, row=8, sticky=E)
        self.apply.state(['disabled'])

        ttk.Label(self.mainframe, text="Chose Extension").grid(row=7,column=1)

        self.selectExtension = ttk.Combobox(self.mainframe,state='readonly', values=self.extensions, postcommand=self.getExtensions)
        self.selectExtension.grid(column = 2, row =7)
        self.selectExtension.current(newindex = 0)
        self.selectExtension.bind('<<ComboboxSelected>>',self.setExtension)

        for child in self.mainframe.winfo_children():
            child.grid_configure(padx=5, pady=5)
예제 #13
0
    def createComponents(self):
        logging.debug("In ImportWindow::createComponents()")
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/dialog-close.png"))
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/document-export.png"))
        icon3 = QtGui.QIcon()
        icon3.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/clear.png"))
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/im-status-message-edit.png"))
        icon5 = QtGui.QIcon()
        icon5.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/edit-paste.png"))
        self.deleteAction = QtGui.QAction(self)
        self.deleteAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Delete",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.deleteAction.setIconVisibleInMenu(True)
        self.deleteAction.setObjectName("deleteAction")
        self.deleteAction.setIcon(icon1)
        self.exportAction = QtGui.QAction(self)
        self.exportAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Export",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.exportAction.setIconVisibleInMenu(True)
        self.exportAction.setObjectName("exportAction")
        self.exportAction.setIcon(icon2)
        self.resetAction = QtGui.QAction(self)
        self.resetAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Reset",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.resetAction.setIconVisibleInMenu(True)
        self.resetAction.setObjectName("resetAction")
        self.resetAction.setIcon(icon3)
        self.duplicateSerieAction = QtGui.QAction(self)
        self.duplicateSerieAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Duplicate",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.duplicateSerieAction.setIconVisibleInMenu(True)
        self.duplicateSerieAction.setObjectName("resetAction")
        self.duplicateSerieAction.setIcon(icon5)
        self.renameSerieAction = QtGui.QAction(self)
        self.renameSerieAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Rename",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.renameSerieAction.setIconVisibleInMenu(True)
        self.renameSerieAction.setObjectName("renameSerieAction")
        self.renameSerieAction.setIcon(icon4)

        self.renamePatientAction = QtGui.QAction(self)
        self.renamePatientAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Rename",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.renamePatientAction.setIconVisibleInMenu(True)
        self.renamePatientAction.setObjectName("renamePatientAction")
        self.renamePatientAction.setIcon(icon4)

        self.renameStudyAction = QtGui.QAction(self)
        self.renameStudyAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Rename",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.renameStudyAction.setIconVisibleInMenu(True)
        self.renameStudyAction.setObjectName("renameStudyAction")
        self.renameStudyAction.setIcon(icon4)


        self.treeMenu = QtGui.QMenu(self.treeWidget)
        self.rename = Rename(self)
        
#        self.treeMenu.addAction(self.deleteAction)
#        self.treeMenu.addAction(self.exportAction)
#        self.treeMenu.addAction(self.resetAction)
        self.treeMenu.setIcon(icon1)
예제 #14
0
class ImportWindow(QtGui.QWidget, Ui_ImportWindow):

    def __init__(self, parent=None):
        logging.debug("In ImportWindow::__init__()")
        super(ImportWindow, self).__init__(parent)
        self.setupUi(self)
        self.setWindowTitle(constant.TITLE_PROGRAM)
        self.createComponents()
        self.createSignals()
        self.importSearch = ImportSearch()
        self.createActions()
        self.filters = []
        self.createPreviews()
        self.updateTree()
        self.series = []
        self._contextMenuProviders = []
        self.outsideMenuContext = None
        
    def createComponents(self):
        logging.debug("In ImportWindow::createComponents()")
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/dialog-close.png"))
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/document-export.png"))
        icon3 = QtGui.QIcon()
        icon3.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/clear.png"))
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/im-status-message-edit.png"))
        icon5 = QtGui.QIcon()
        icon5.addPixmap(QtGui.QPixmap(":/static/default/icon/22x22/edit-paste.png"))
        self.deleteAction = QtGui.QAction(self)
        self.deleteAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Delete",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.deleteAction.setIconVisibleInMenu(True)
        self.deleteAction.setObjectName("deleteAction")
        self.deleteAction.setIcon(icon1)
        self.exportAction = QtGui.QAction(self)
        self.exportAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Export",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.exportAction.setIconVisibleInMenu(True)
        self.exportAction.setObjectName("exportAction")
        self.exportAction.setIcon(icon2)
        self.resetAction = QtGui.QAction(self)
        self.resetAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Reset",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.resetAction.setIconVisibleInMenu(True)
        self.resetAction.setObjectName("resetAction")
        self.resetAction.setIcon(icon3)
        self.duplicateSerieAction = QtGui.QAction(self)
        self.duplicateSerieAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Duplicate",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.duplicateSerieAction.setIconVisibleInMenu(True)
        self.duplicateSerieAction.setObjectName("resetAction")
        self.duplicateSerieAction.setIcon(icon5)
        self.renameSerieAction = QtGui.QAction(self)
        self.renameSerieAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Rename",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.renameSerieAction.setIconVisibleInMenu(True)
        self.renameSerieAction.setObjectName("renameSerieAction")
        self.renameSerieAction.setIcon(icon4)

        self.renamePatientAction = QtGui.QAction(self)
        self.renamePatientAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Rename",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.renamePatientAction.setIconVisibleInMenu(True)
        self.renamePatientAction.setObjectName("renamePatientAction")
        self.renamePatientAction.setIcon(icon4)

        self.renameStudyAction = QtGui.QAction(self)
        self.renameStudyAction.setText(QtGui.QApplication.translate(
                    "ImportWindow", "Rename",
                    None, QtGui.QApplication.UnicodeUTF8))
        self.renameStudyAction.setIconVisibleInMenu(True)
        self.renameStudyAction.setObjectName("renameStudyAction")
        self.renameStudyAction.setIcon(icon4)


        self.treeMenu = QtGui.QMenu(self.treeWidget)
        self.rename = Rename(self)
        
#        self.treeMenu.addAction(self.deleteAction)
#        self.treeMenu.addAction(self.exportAction)
#        self.treeMenu.addAction(self.resetAction)
        self.treeMenu.setIcon(icon1)
        
    def createActions(self):
        logging.debug("In ImportWindow::createActions()")
        self.treeWidget.contextMenuEvent = self.treeContextEvent
        self.connect(self.treeWidget,
                     QtCore.SIGNAL("itemClicked(QTreeWidgetItem*, int)"),
                     self.slotTreeWidgetClicked)
        self.connect(self.treeWidget,
                     QtCore.SIGNAL("itemEntered (QTreeWidgetItem*, int)"),
                     self.slotTreeWidgetClicked)
        self.connect(self.splitter,
                     QtCore.SIGNAL("splitterMoved(int, int)"),
                     self.slotHSplit)
        self.connect(self.horizontalSlider,
                     QtCore.SIGNAL("valueChanged(int)"),
                     self.slotSliderMoved)
        self.connect(self.spinBox,
                     QtCore.SIGNAL("valueChanged(int)"),
                     self.slotSpinChanged)
        self.connect(self.importButton, QtCore.SIGNAL("clicked()"),
                     self.slotImportClicked)
        self.connect(self.treeWidget,
                     QtCore.SIGNAL("itemExpanded(QTreeWidgetItem*)"),
                     self.slotTreeWidgetExpanded)
        self.connect(self.treeWidget,
                     QtCore.SIGNAL("itemCollapsed(QTreeWidgetItem*)"),
                     self.slotTreeWidgetExpanded)
        self.connect(self.searchButton, QtCore.SIGNAL("clicked()"),
                     self.slotSearchButtonClicked)
        self.connect(self.searchText, QtCore.SIGNAL(
                      "textChanged ( QString)"),
                      self.slotSearchTextChanged)
        self.connect(self.importSearch.searchButton, QtCore.SIGNAL("clicked()"),
                     self.slotImportSearchButtonClicked)
        self.connect(self.importSearch.cancelButton, QtCore.SIGNAL("clicked()"),
                     self.slotImportCancelButtonClicked)
        self.connect(self.resetButton, QtCore.SIGNAL("clicked()"),
                     self.slotResetButtonClicked)
        self.connect(self.rename.Ok, QtCore.SIGNAL("clicked()"),
                     self.slotRenameOkButtonClicked)
        self.connect(self.rename.Cancel, QtCore.SIGNAL("clicked()"),
                     self.slotRenameCancelButtonClicked)
    
    def slotRenameOkButtonClicked(self):
        if self.rename.action == self.renameSerieAction:          
            description =  utils.decode_string(self.rename.newName.text())
            id = self.rename.serie.uid
            if list(Serie.select("uid='{0}' AND description='{1}'".format(id, description))):
                QtGui.QMessageBox.critical(self.rename, "Error", 
                            QtGui.QApplication.translate(
                                        "ImportWindow", 
                                        "This serie is already registered in database with this name. \nTry another one.",
                        None, QtGui.QApplication.UnicodeUTF8))
                return
            else:
                basePath = os.path.join(constant.INSTALL_DIR, "data")
                patientPath = os.path.join(basePath, hashStr(self.rename.serie.study.patient.uid))
                oldSeriePath = os.path.join(patientPath,"{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(self.rename.serie.description)))
                filePath = file(os.path.join(oldSeriePath
                                    , "{0}{1}".format(hashStr(self.rename.serie.uid),".yaml")), 'r')
                vti = yaml.load(filePath)
                vti["vti"] = vti["vti"].replace("{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(self.rename.serie.description)), 
                                                "{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(description)))
                
                filePath.close()
                filePath = file(os.path.join(oldSeriePath
                                    , "{0}{1}".format(hashStr(self.rename.serie.uid),".yaml")), 'w')
                yaml.dump(vti, filePath)
                filePath.close()
                self.rename.serie.description = description.encode("utf-8")
                self.rename.serie.file = os.path.join("{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(description))
                                    , "{0}{1}".format(hashStr(self.rename.serie.uid),".yaml"))
                newSeriePath = os.path.join(patientPath,"{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(description)))
                if os.path.exists(newSeriePath):
                    shutil.rmtree(newSeriePath)  
                shutil.move(oldSeriePath, newSeriePath)
        elif self.rename.action == self.renamePatientAction:    
            name =  utils.decode_string(self.rename.newName.text())
            self.rename.patient.name =  name.encode("utf-8")
        elif self.rename.action == self.renameStudyAction:
            description =  utils.decode_string(self.rename.newName.text())
            self.rename.study.description =  description.encode("utf-8")
        else:
            #copy files to new directory
            description =  utils.decode_string(self.rename.newName.text())
            id = self.rename.serie.uid
            if list(Serie.select("uid='{0}' AND description='{1}'".format(id, description))):
                QtGui.QMessageBox.critical(self.rename, "Error", 
                            QtGui.QApplication.translate(
                                        "ImportWindow", 
                                        "This serie is already registered in database with this name. \nTry another one.",
                        None, QtGui.QApplication.UnicodeUTF8))
                return
            basePath = os.path.join(constant.INSTALL_DIR, "data")
            patientPath = os.path.join(basePath, hashStr(self.rename.serie.study.patient.uid))
            oldSeriePath = os.path.join(patientPath,"{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(self.rename.serie.description)))
            newSeriePath = os.path.join(patientPath,"{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(description)))
            if os.path.exists(newSeriePath):
                shutil.rmtree(newSeriePath)  
            shutil.copytree(oldSeriePath, newSeriePath)
            yamlFile = os.path.join("{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(description))
                                , "{0}{1}".format(hashStr(self.rename.serie.uid),".yaml"))
            
            filePath = file(os.path.join(newSeriePath
                                , "{0}{1}".format(hashStr(self.rename.serie.uid),".yaml")), 'r')
            vti = yaml.load(filePath)
            vti["vti"] = vti["vti"].replace("{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(self.rename.serie.description)), 
                                            "{0}{1}".format(hashStr(self.rename.serie.uid), hashStr(description)))
            
            filePath.close()
            filePath = file(os.path.join(newSeriePath
                                , "{0}{1}".format(hashStr(self.rename.serie.uid),".yaml")), 'w')
            yaml.dump(vti, filePath)
            filePath.close()
            #create new serie
            Serie(uid=self.rename.serie.uid, 
                  file=yamlFile,
                  description=description,
                  thickness=self.rename.serie.thickness, 
                  size=self.rename.serie.size,   
                  zSpacing=self.rename.serie.zSpacing,
                  tmp = False,
                  dicomImages=self.rename.serie.dicomImages,
                  study=self.rename.serie.study)
        self.rename.hide()
        self.updateTree()
    
    def slotRenameCancelButtonClicked(self):
        self.rename.hide()

    def createSignals(self):
        logging.debug("In ImportWindow::createSignals()")
        self.confirmImportSignal = QtCore.SIGNAL(
                            "importConfirmed(PyObject, PyObject, PyObject)")

    def createPreviews(self):
        logging.debug("In ImportWindow::createPreviews()")
        imageLayout = QtGui.QGridLayout(self.imageViewWidget)
        self.image = VTKImageView(self.imageViewWidget)
        self.selectedNumber = -1
        imageLayout.addWidget(self.image)
        self.previewWidgets = []
        self.previewWidgetsMap = {}
         
    def imageClicked(self,obj, evt):
        logging.debug("In ImportWindow::imageClicked()")
        self.preview(self.previewWidgetsMap[obj])

    def preview(self, preview):
        logging.debug("In ImportWindow::preview()")
        backgroundColor = self.palette().color(self.palette().Highlight)
        color = self.palette().color(self.palette().HighlightedText)
        preview.setStyleSheet(
              " background-color : rgb(" + str(backgroundColor.red()) + ","
              + str(backgroundColor.green()) + "," + str(backgroundColor.blue())
              + ");" + "color : rgb(" + str(color.red()) + ","
              + str(color.green()) + "," + str(color.blue()) + ");")

        dicomPath = preview.getImagePath()
        self.imageTabWidget.setTabText(0,QtGui.QApplication.translate(
                    "ImportWindow", "image ",
                    None, QtGui.QApplication.UnicodeUTF8)+preview.getText())
        self.image.setImagePath(dicomPath)
        for i,currentPreview in enumerate(self.previewWidgets):
            if currentPreview == preview:
                self.selectedNumber = i
                continue
            currentPreview.setStyleSheet("")
        self.horizontalSlider.setSliderPosition(self.selectedNumber)
    

    def setSliderRange(self, minRange, maxRange):
        logging.debug("In ImportWindow::setSliderRange()")
        self.horizontalSlider.setRange(minRange, maxRange)

    def removeAllItems(self):
        logging.debug("In ImportWindow::removeAllItems()")
        self.treeWidget.clear()

    def updateTree(self, qtd=0):
        logging.debug("In ImportWindow::updateTree()")
        self.seriesDictionary = {}
        patients = Patient.findContaining(self.importSearch.patientName.text())
        self.removeAllItems()
        for patient in patients:
            item = QtGui.QTreeWidgetItem(self.treeWidget)
            if patient.sex:
                item.setText(2, patient.sex)
            if patient.birthdate:
                age = (datetime.datetime.now().toordinal() - patient.birthdate.toordinal()) / 365
                item.setText(3, "{0}".format(age))
                item.setText(7, patient.birthdate.strftime("%x"))
            self.seriesDictionary[item] = patient                   
            studies = Study.findContaining(patient=patient,
                                           description=self.importSearch.studyDescription.text(),
                                           modality=self.importSearch.modality.text(),
                                           institution= self.importSearch.institution.text())
            item.setText(0, "Ok")
            item.setText(1, QtGui.QApplication.translate(
                    "ImportWindow", "Patient: {0} ({1} studies)",
                    None, QtGui.QApplication.UnicodeUTF8).format(patient.name, len(studies)))
            totalPatientImages = 0 
            for study in studies:
                studyItem = QtGui.QTreeWidgetItem(item)
                if study.modality:
                    studyItem.setText(4, study.modality)
                if study.institution:
                    studyItem.setText(6, study.institution)
                
                self.seriesDictionary[studyItem] = study 
                try:   
                    series = Serie.findContaining(study=study, description=self.importSearch.serieDescription.text())
                except:
                    DBUtils.updateTable()
                    series = Serie.findContaining(study=study, description=self.importSearch.serieDescription.text())
                if not series:
                    item.removeChild(studyItem)
                    self.seriesDictionary.pop(studyItem)
                if study.description:
                    studyItem.setText(1, QtGui.QApplication.translate(
                    "ImportWindow", "Study: {0}  ({1} series)",
                    None, QtGui.QApplication.UnicodeUTF8).format(study.description, len(series)))
                else:
                    studyItem.setText(1, QtGui.QApplication.translate(
                    "ImportWindow", "Study: ({0} series)",
                    None, QtGui.QApplication.UnicodeUTF8).format(len(series)))
                
                totalStudyImages = 0
                for serie in series:
                    serieItem = QtGui.QTreeWidgetItem(studyItem)
                    serieItem.setText(1,QtGui.QApplication.translate(
                                         "ImportWindow", "Serie: {0}({1} images)",
                                         None, 
                                         QtGui.QApplication.UnicodeUTF8).format(
                                                            serie.description, serie.dicomImages))
                    serieItem.setText(5,"{0}".format(serie.dicomImages))
                    self.seriesDictionary[serieItem] = serie
                    totalStudyImages = totalStudyImages + serie.dicomImages
                studyItem.setText(5,"{0}".format(totalStudyImages))
                totalPatientImages = totalPatientImages + totalStudyImages
            
            item.setText(5,"{0}".format(totalPatientImages))
                    
            if item.childCount() == 0:
                self.treeWidget.takeTopLevelItem(self.treeWidget.topLevelItemCount()-1)
                self.seriesDictionary.pop(item)
        self.resizeTreeColumns()
        self.emit(QtCore.SIGNAL("treeUpdated()"))
        
    def slotHSplit(self, pos, index):
        logging.debug("In ImportWindow::slotHSplit()")
        self.organizePreviews()
        
    def createItemFromSerie(self, serie, parent):
        logging.debug("In ImportWindow::createItemFromSerie()")
        item = QtGui.QTreeWidgetItem(parent)
        item.setText(0, serie.firstDicom.seriesDescription+"("+
                     serie.getSerieLengthString()+")")
        for subSerie in serie.getSubSeries().values():
            self.createItemFromSerie(subSerie, item)

        self.seriesDictionary[item] = serie
        return item

    def normalizeSizeWidget(self):
        logging.debug("In ImportWindow::normalizeSizeWidget()")        
        self.splitter.setSizes([6000,4000])

    def slotCancel(self):
        logging.debug("In ImportWindow::slotCancel()")
        self.series = []
        self.seriesDictionary = {}
        self.close()
        self.parentWidget().close()

    def slotTreeWidgetClicked(self, item, column):
        logging.debug("In ImportWindow::slotTreeWidgetClicked()")
        try:
            self.series = []
            if isinstance(self.seriesDictionary[item], Patient) :
                for study in self.seriesDictionary[item].studies:
                    for serie in study.series:
                        self.series.append(serie)
            elif isinstance(self.seriesDictionary[item], Study) :
                for serie in self.seriesDictionary[item].series:
                    self.series.append(serie)
            elif isinstance(self.seriesDictionary[item], Serie) :
                self.series.append(self.seriesDictionary[item])     
            self.showPreview()
        except Exception as e:
            logging.warning(e)
            
    def deleteActionExec(self, window, item):
        msg = QtGui.QMessageBox()
        msg.setText(QtGui.QApplication.translate("ImportWindow",
                                 "Are you sure you want to delete selected item?",
                                 None, 
                                 QtGui.QApplication.UnicodeUTF8))
        msg.setStandardButtons(msg.No | msg.Yes)
        msg.setDefaultButton(msg.No)
        msg.show()
        msgResult = msg.exec_()
        if msgResult == msg.Yes:
            self.delete = Delete(self)
            self.delete.show()
            self.delete.normalizeSizeWidget()
            self.connect(self.delete, QtCore.SIGNAL("deleteFinished()"), self.deleteFinished)
            self.delete.processDelete(series = self.getSeriesFromItem(item))
            
    def exportActionExec(self, window, item):
        lastdir = "{0}{1}{2}".format(profile.get_last_directory_action_new(), os.path.sep, "exporter.st")
        caption = QtGui.QApplication.translate(
            "ImportWindow", "Select the output directory", None,
            QtGui.QApplication.UnicodeUTF8)
        dialog = QtGui.QFileDialog.getSaveFileName(self, caption, lastdir, "File (*.st)")
        if dialog[0]:
            outputDirectory = os.path.abspath(dialog[0])
            msg = QtGui.QMessageBox()
            msg.setText(QtGui.QApplication.translate(
                                "ImportWindow", "Would you like to export Dicom Images?", None,
                                QtGui.QApplication.UnicodeUTF8))
            msg.setStandardButtons(msg.No | msg.Yes)
            msg.setDefaultButton(msg.No)
            msg.show()
            dicomImages = msg.exec_() == msg.Yes
            series = self.getSeriesFromItem(item)
            exporter = SerieExporter(self, outputDirectory, series, dicomImages)
            exporter.start()
            
    def resetActionExec(self, window, item):
        msg = QtGui.QMessageBox()
        msg.setText(QtGui.QApplication.translate(
                                "ImportWindow", "Are you sure you want to reset selected serie?", None,
                                QtGui.QApplication.UnicodeUTF8))
        msg.setStandardButtons(msg.No | msg.Yes)
        msg.setDefaultButton(msg.No)
        msg.show()
        msgResult = msg.exec_()
        if msgResult == msg.Yes:
            series = self.getSeriesFromItem(item)
            reset = Reset(self)
            reset.processReset(series[0])
            
    def duplicateSerieActionExec(self, window, item):
        self.rename.action = self.duplicateSerieAction
        self.rename.setWindowTitle(QtGui.QApplication.translate(
                                "ImportWindow", "Duplicate Serie:", None,
                                QtGui.QApplication.UnicodeUTF8))
        self.rename.label.setText(QtGui.QApplication.translate(
                                "ImportWindow", "New Serie Description:", None,
                                QtGui.QApplication.UnicodeUTF8))
        self.rename.serie = self.getSeriesFromItem(item)[0]
        self.rename.setWindowIcon(self.duplicateSerieAction.icon())
        self.rename.newName.setText(self.rename.serie.description)
        self.rename.setDisabled(False)
        self.rename.show()
    
    def renameSerieActionExec(self, window, item):
        self.rename.setDisabled(False)
        if isinstance(self.seriesDictionary[item], Patient):
            self.rename.patient = self.seriesDictionary[item]
            self.rename.setWindowTitle(QtGui.QApplication.translate(
                                    "ImportWindow", "Rename Patient", None,
                                    QtGui.QApplication.UnicodeUTF8))
            self.rename.label.setText(QtGui.QApplication.translate(
                                    "ImportWindow", "Name:", None,
                                    QtGui.QApplication.UnicodeUTF8))
            self.rename.action = self.renamePatientAction
            self.rename.newName.setText(self.rename.patient.name)
        elif isinstance(self.seriesDictionary[item], Study):
            self.rename.study = self.seriesDictionary[item]
            self.rename.setWindowTitle(QtGui.QApplication.translate(
                                    "ImportWindow", "Rename Study", None,
                                    QtGui.QApplication.UnicodeUTF8))
            self.rename.label.setText(QtGui.QApplication.translate(
                                    "ImportWindow", "Description:", None,
                                    QtGui.QApplication.UnicodeUTF8))
            self.rename.action = self.renameStudyAction
            self.rename.newName.setText(self.rename.study.description)
        else:
            self.rename.serie = self.seriesDictionary[item]
            self.rename.setWindowTitle(QtGui.QApplication.translate(
                                    "ImportWindow", "Rename Serie", None,
                                    QtGui.QApplication.UnicodeUTF8))
            self.rename.label.setText(QtGui.QApplication.translate(
                                    "ImportWindow", "Description:", None,
                                    QtGui.QApplication.UnicodeUTF8))
            self.rename.action = self.renameSerieAction
            self.rename.newName.setText(self.rename.serie.description)
        self.rename.setWindowIcon(self.renameSerieAction.icon())
        
        self.rename.show()
        
    def getTreeContextMenuActions(self, window, item):
        result = []
        try:
            if item:
                    result.append((self.deleteAction, self.deleteActionExec))
                    result.append((self.exportAction, self.exportActionExec))
                    result.append((self.renameSerieAction, self.renameSerieActionExec))
                    if isinstance(self.seriesDictionary[item], Serie):
                        result.append((self.resetAction, self.resetActionExec))
                        result.append((self.duplicateSerieAction, self.duplicateSerieActionExec))
                
            for provider in self._contextMenuProviders:
                actions = provider(window, item)
                if actions:
                    result = result + actions
        except:
            if self.outsideMenuContext:
                return self.outsideMenuContext(window, item)
            return []
        return result
        
    def treeContextEvent(self, event):
        logging.debug("In ImportWindow::treeContextEvent()")
        item = self.treeWidget.itemAt(event.pos())
        if item:
            actions = self.getTreeContextMenuActions(self, item)
            self.treeMenu.clear()
            for action, callback in actions:
                self.treeMenu.addAction(action)
            result = self.treeMenu.exec_(QtGui.QCursor.pos())
            if result:
                for action, callback in actions:
                    if action == result:
                        callback(self, item)
                        break
                    
                    
    def getSeriesFromItem(self, item):
        series = []
        if isinstance(self.seriesDictionary[item], Patient) :
            for study in self.seriesDictionary[item].studies:
                for serie in study.series:
                    series.append(serie)
        elif isinstance(self.seriesDictionary[item], Study) :
            for serie in self.seriesDictionary[item].series:
                series.append(serie)
        elif isinstance(self.seriesDictionary[item], Serie) :
            series.append(self.seriesDictionary[item])
        return series 
    
    def deleteFinished(self):
        self.updateTree()
        self.image.setImage(None)
        self.image.removeAllTexts()
        self.setSliderRange(0, 0)
           
    def slotTreeWidgetExpanded(self, item):
        logging.debug("In ImportWindow::slotTreeWidgetExpanded()")
        self.resizeTreeColumns()
    
    def resizeTreeColumns(self):
        logging.debug("In ImportWindow::resizeTreeColumns()")
        for i in range(self.treeWidget.columnCount()):
            self.treeWidget.resizeColumnToContents(i)

    def cleanPreviewWidgets(self):
        logging.debug("In ImportWindow::cleanPreviewWidgets()")
        for preview in self.previewWidgets:
            self.removePreview(preview)
        self.previewWidgets = []
        self.previewWidgetsMap = {}

    def removePreview(self, preview):
        logging.debug("In ImportWindow::removePreview()")
        preview.close()

    def showPreview(self):
        logging.debug("In ImportWindow::showPreview()")
        self.spinBox.setMinimum(1)
        self.spinBox.setMaximum(len(self.series))
        folder = os.path.join(self.series[self.spinBox.value()-1].study.patient.directory, "{0}/images/".format(hashStr(self.series[self.spinBox.value()-1].uid)))
        files = os.listdir(folder)
        minRange = sys.maxint
        maxRange = 0 
        for f in files:
            try:
                value = int (f[:-4])
                minRange = min(minRange, value)
                maxRange = max(maxRange, value)
            except:
                pass

        self.setSliderRange(minRange, maxRange)
        
        self.horizontalSlider.setValue(minRange)
        self.slotSliderMoved(minRange)
        self.image.removeAllTexts()
        self.image.addText(self.series[self.spinBox.value()-1].study.patient.name, y=0.10)
        self.image.addText(self.series[self.spinBox.value()-1].description, y=0.05)
   
    
    def organizePreviews(self):
        logging.debug("In ImportWindow::organizePreviews()")
        if self.previewWidgets:
            w = self.previewWidgets[0].width()
            h = self.previewWidgets[0].height()
            n = len(self.previewWidgets)
            lines = int(self.scrollArea.width()/w)
            if lines:
                columns = (n/lines)+1
                self.previewWidget.resize(self.scrollArea.width(),columns*h)
                i = 0
                j=-1
                for preview in self.previewWidgets:
                    if i%lines == 0:
                        j = j+1
                    preview.setGeometry((i%lines)*w, j*h, w, h)
                    preview.update()
                    i = i+1

    def slotSliderMoved(self, i):
        logging.debug("In ImportWindow::slotSliderMoved()")
        try:
            self.image.setImage(os.path.join(self.series[self.spinBox.value()-1].study.patient.directory, "{0}/images/{1}.dcm".format(hashStr(self.series[self.spinBox.value()-1].uid), i)))
        except:
            pass
    
    def slotSpinChanged(self, i):
        logging.debug("In ImportWindow::slotSpinChanged()")
        self.showPreview()
    
    def slotSearchButtonClicked(self):
        logging.debug("In ImportWindow::slotSearchButtonClicked()")
        self.importSearch.show()
    
    def slotSearchTextChanged(self):
        logging.debug("In ImportWindow::slotSearchTextChanged()")
        self.importSearch.clearFields()
        self.importSearch.patientName.setText(self.searchText.text())
        self.updateTree()
    
    def slotImportSearchButtonClicked(self):
        logging.debug("In ImportWindow::slotImportSearchButtonClicked()")
        self.importSearch.hide()
        self.updateTree()
    
    def slotImportCancelButtonClicked(self):
        logging.debug("In ImportWindow::slotImportCancelButtonClicked()")
        self.importSearch.hide()

    def slotResetButtonClicked(self):
        logging.debug("In ImportWindow::slotImportCancelButtonClicked()")
        self.importSearch.clearFields()
        self.searchText.setText("")
        self.updateTree()

    def slotImportClicked(self):
        logging.debug("In ImportWindow::slotImportClicked()")
        curr = self.seriesDictionary.get(self.treeWidget.currentItem())
        if curr:
            series = []
            if isinstance(curr, Patient):
                for study in curr.studies:
                    for serie in study.series:
                        series.append(serie)
            elif isinstance(curr, Study):
                for serie in curr.series:
                    series.append(serie)
            elif isinstance(curr, Serie):
                series.append(curr)
            else:
                logging.warning("Is not instance of: (Patient, Study, Serie)")
                raise Exception("Is not instance of: (Patient, Study, Serie)")
            self.emit(self.confirmImportSignal, series,
                      0, False)
        else:
            logging.warning("There's no dicom to be importer =(")
            raise Exception("There's no dicom to be importer =(")
        
    def addContextMenuProvider(self, provider):
        self._contextMenuProviders.append(provider)
    
    def removeContextMenuProvider(self, provider):
        if self._contextMenuProviders.count(provider):
            self._contextMenuProviders.remove(provider)