Esempio n. 1
0
class App(Qt.QApplication):
    def __init__(self, sys_argv):
        super(App, self).__init__(sys_argv)
        self.model = ToDoModel()
        self.main_ctrl = Controller(self.model)
        self.main_view = MainWindow(self.model, self.main_ctrl)
        self.main_view.show()
Esempio n. 2
0
class Application(QtWidgets.QApplication):
    def __init__(self):
        QtWidgets.QApplication.__init__(self, sys.argv)

        # --- members
        self.presentation = MainWindow()
        self.backend = Backend()
        self.backend_thread = QtCore.QThread()
        self.backend.moveToThread(self.backend_thread)

        # --- signal/slot connections

        # front to back
        self.presentation.set_cache_path.connect(self.backend.set_cache_path)
        self.presentation.refresh.connect(self.backend.refresh)
        self.presentation.rebuild.connect(self.backend.rebuild)
        self.presentation.request_preview.connect(self.backend.preview_request)
        self.presentation.request_save.connect(self.backend.save_bitmap)

        # back to front
        self.backend.thumbnail_available.connect(
            self.presentation.thumbnail_view.add_thumbnail)
        self.backend.bitmap_available.connect(self.presentation.save_bitmap)
        self.backend.preview_available.connect(self.presentation.show_preview)

        # --- start backend thread
        self.backend_thread.start()

        # --- misc setup
        self.setStyle(APPLICATION_STYLE)

    def execute(self):
        self.presentation.show()
        self.exec_()
Esempio n. 3
0
def start_main():
    login_view = login_controller.view
    if login_view.userNameEdit.text() and login_view.passwordEdit.text(
    ) and login_controller.ready:
        chat_controller.server = login_controller.server
        chat_controller.init_view()
        chat_controller.init_user()
        MainWindow.show()
Esempio n. 4
0
class EDLManagerApp(QtCore.QObject):
    def __init__(self, args, parent=None, rows=10):
        super(EDLManagerApp, self).__init__(parent)

        self.pyside_app = QtWidgets.QApplication(['EDL Manager'])
        self.table_model = TableModel(rows)
        self.qmodel = QModel(self)

        self.main_window = MainWindow(application=self, model=self.qmodel)

        self.main_window.saveEvent.connect(self.save_edl)
        self.main_window.openedFile.connect(self.read_edl)

    def model_info(self):
        return self.table_model.info()

    def run(self):
        self.main_window.show()
        return (self.pyside_app.exec_())

    def read_edl(self, edl):
        pass
        #parse raw EDL into function to split it into rows / columns

    def save_edl(self):
        table_to_save = self.main_window.export_table()
        # Save commented EDL ---

    def setRowCount(self, count):
        return self.table_model.setRowCount(count)

    def cell(self, row, column):
        return self.table_model.data[row][column]

    def update_cell(self, row, col, val):
        self.table_model.update_cell(row, col, val)
import sys
from PyQt5.QtWidgets import QApplication

from view import MainWindow

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
Esempio n. 6
0
import sys

from PyQt5 import QtWidgets
from view import MainWindow

app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Esempio n. 7
0
class Controller(QtCore.QObject):
    """
    Application controller. Coordinates between view objects and Image
    state/model object.
    """
    def __init__(self, app):
        super().__init__()

        self.app = app
        self.src_dir = None
        self.dest_file = None
        self.images = None
        self.current_image = None
        self.main_window = None

        # These methods will launch their corresponding state. These states
        # Determine the high level application flow.
        self._state_launchers = deque([
            self._choose_src_dir_and_dest_file,
            self._create_main_window,
            self.app.quit,
        ])

    def run(self):
        """
        Starts the application.
        """
        self._next_state()

    def show_next_image(self, write=False):
        """
        Displays the next image in images. If there is an image open and write
        is True, that image's data will be written to dest_file.
        """
        if write and self.current_image is not None:
            self._write_data(str(self.current_image))

        try:
            impath = self.images.pop()
        except IndexError:
            self._next_state()
            return

        self.current_image = Image(impath)
        self.main_window.image_layout.show_image(
            self.current_image.resized_cv_img)
        self.main_window.ctrl_layout.reset()
        self.main_window._resize()

    def _choose_src_dir_and_dest_file(self):
        """
        Application setup. Gets src dir and dest file, if not specified from
        command line or command line args were invalid.
        """
        if len(sys.argv) > 1 and os.path.isdir(sys.argv[1]):
            self.src_dir = sys.argv[1]
        else:
            self.src_dir = QtWidgets.QFileDialog.getExistingDirectory(
                caption='Select source directory')

        if len(sys.argv) > 2 and \
           (os.path.dirname(sys.argv[2]) == '' or
            os.path.isdir(os.path.dirname(sys.argv[2]))):
            self.dest_file = sys.argv[2]
        else:
            self.dest_file = QtWidgets.QFileDialog.getSaveFileName(
                caption='Select save file')[0]

        try:
            # Create output file
            open(self.dest_file, 'w').close()
            self.images = self._get_image_files(self.src_dir)
        except (IOError, OSError):
            self.app.quit()
            return

        self._next_state()

    def _connect_signals_and_slots(self):
        """
        Connects view and model with signals and slots.
        """
        # Save line length
        ctrl = self.main_window.ctrl_layout
        img = self.main_window.image_layout

        # Wire up skip image button
        ctrl.skip_button.clicked.connect(self.show_next_image)

        # Wire up image type dropdown
        ctrl.type_dropdown.currentIndexChanged[str].connect(
            self._set_image_type)

        # Wire up solar perimeter button
        ctrl.solar_button.clicked.connect(
            lambda _: self._set_image_circle(Image.SOLAR))

        # Wire up lunar perimeter button
        ctrl.lunar_button.clicked.connect(
            lambda _: self._set_image_circle(Image.LUNAR))

        # Wire up reset button
        ctrl.reset_button.clicked.connect(self._reset)

        # Wire up save button
        ctrl.save_button.clicked.connect(
            lambda _: self.show_next_image(write=True))

        # Handle click events on the displayed image
        img.mouse_pressed.connect(self._record_mouse_press)

    def _create_main_window(self):
        """
        Creates the main window initiating the main application state.
        """
        self.main_window = MainWindow()
        self._connect_signals_and_slots()
        self.show_next_image()
        self.main_window.show()

    def _disable_circle_buttons(self):
        """
        Disables [solar|lunar]_circle buttons if their corresponding circles
        have been defined.
        """
        if self.current_image.solar_circle is not None:
            self.main_window.ctrl_layout.solar_button.setEnabled(False)
        if self.current_image.lunar_circle is not None:
            self.main_window.ctrl_layout.lunar_button.setEnabled(False)

    def _enable_disable_save(self):
        """
        Enables/disables the save button depending on whether or not the
        current_image's complete flag is set.
        """
        self.main_window.ctrl_layout.save_button.setEnabled(
            self.current_image.complete)

    def _next_state(self):
        """
        Launches the next application state.
        """
        state = self._state_launchers.popleft()
        timer = QtCore.QTimer(self.app)
        timer.setSingleShot(True)
        timer.timeout.connect(state)
        timer.start(0)

    def _record_mouse_press(self, point):
        """
        Adds a point clicked by the user to current_image. Updates view
        accordingly.
        """
        self.current_image.add_point(point)

        # If the active circle is fully defined
        if self.current_image.active_circle_complete():

            # Compute circle center/radius, visualize it on
            # current_image.resized_cv_img
            self.current_image.process_active_circle()

            # Update the displayed image to have the newly added circle overlay
            self.main_window.image_layout.show_image(
                self.current_image.resized_cv_img)

        # Disable circle buttons, enable/disable save button as necessary
        self._disable_circle_buttons()
        self._enable_disable_save()

    def _reset(self):
        """
        Reset state for current image. Resets the Image object and UI.
        """
        self.main_window.ctrl_layout.reset()
        self.current_image.reset()
        self.main_window.image_layout.show_image(
            self.current_image.resized_cv_img)

    def _set_image_circle(self, circle):
        """
        Activates the circle chosen by the user.
        """
        self.current_image.activate_circle(circle)
        self._enable_disable_save()

    def _set_image_type(self, img_type):
        """
        Updates the Image.type flag based on user dropdown input.
        """
        self.current_image.type = img_type
        self.current_image.set_complete()
        self._enable_disable_save()

    def _write_data(self, data):
        """
        Write data + '\n' to dest_file
        """
        with open(self.dest_file, 'a') as f:
            f.write(data + '\n')

    @staticmethod
    def _get_image_files(directory):
        """
        Returns a list of image files (defined as files ending with extensions in
        constants.ALLOWED_IMAGE_FORMATS) in directory.
        """
        images = list()
        for f in os.listdir(directory):
            fname = f.lower()
            for ext in constants.ALLOWED_IMAGE_FORMATS:
                if fname.endswith('.' + ext):
                    images.append(os.path.join(directory, f))
        return images
Esempio n. 8
0
import sys
from PyQt5.QtWidgets import QApplication
from view import MainWindow

HELP = """Click on the group consists of minimum two cubes
of the same color to exterminate it. Have fun!"""

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] in {'-h', '--help', "/?"}:
        exit(HELP)

    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())
Esempio n. 9
0
if __name__ == '__main__':
    from view import MainWindow
    from model import SignalModel, Emotiv, Source
    from controller import ConsoleController, SignalController
    
    with Emotiv() as source:
        app = QApplication(sys.argv)
        signalNames = source.getAvailableSignals()
        window = MainWindow(signalNames)

        source.rememberToNotify(window.signalView.newData)

        signalCtrls = []
        for button in window.signalButtons:
            model = source.getSignalModel(button.getName())
            controller = SignalController(model, button)
            signalCtrls.append(controller)
            window.signalViewConnect(controller)

        welcomeMessage = '''test welcome message\n'''
        consoleController = ConsoleController(window.consoleView, window,
                                              signalCtrls, welcomeMessage)

        window.show()
        sys.exit(app.exec_())
else:
    QMessageBox.about(None, "Error",
                      "This file is standalone program not a module")
    exit()
Esempio n. 10
0
class MainController(object):

    def __init__(self):

        self.widget = MainWindow()
        self.model = JCPDS()
        # self.obj_color = 'white'
        self.read_setting()
        self.connect_channel()
        self.file_name = ''
        self.file_path = ''
        #
        self.clip = QtWidgets.QApplication.clipboard()
        # no more stuff can be added below

    def show_window(self):
        self.widget.show()

    def connect_channel(self):
        # connecting events
        self.widget.pushButton_ImportCIF.clicked.connect(self.import_cif)
        self.widget.pushButton_ImportJCPDS.clicked.connect(self.import_jcpds)
        self.widget.pushButton_CalculateJCPDS.clicked.connect(
            self.calculate_jcpds)
        self.widget.pushButton_WriteJCPDS.clicked.connect(self.write_jcpds)
        self.widget.pushButton_WriteDioptasJCPDS.clicked.connect(
            self.write_dioptas_jcpds)
        self.widget.pushButton_ViewInputFile.clicked.connect(
            self.view_inputfile)


    def calculate_jcpds(self):
        if self.file_name == '':
            QtWidgets.QMessageBox.warning(self.widget, "Warning",
                              "Input filename is not given.")
            return
        comment = str(self.widget.lineEdit_Comment.text())
        int_min = self.widget.doubleSpinBox_MinDsp.value()
        dsp_min = self.widget.doubleSpinBox_MinInt.value()
        self.model.version = 4
        self.read_jcpds_values()
        textoutput = self.model.write_to_string(comments = comment, \
                                 int_min = int_min, dsp_min=dsp_min, \
                                 calculate_1bar_table = True)
        infobox = InformationBox()
        infobox.setText(textoutput)
        infobox.exec_()

    def write_dioptas_jcpds(self):
        QtWidgets.QMessageBox.warning(self.widget, "Warning",
                  "This function is not yet supported.")
        return

        if self.file_name == '':
            QtWidgets.QMessageBox.warning(self.widget, "Warning",
                              "Input filename is not given.")
            return
        path, filen, ext = breakdown_filename(self.file_name)
        stamp = '-dioptas-jt'
        filen_default = os.path.join(path, filen + stamp + '.jcpds')
        filen = dialog_savefile(self.widget, filen_default)
        if filen == '':
            return
        self.model.comments = str(self.widget.lineEdit_Comment.text())
        int_min = self.widget.doubleSpinBox_MinDsp.value()
        dsp_min = self.widget.doubleSpinBox_MinInt.value()
        self.read_jcpds_values()
        self.model.write_to_dioptas_jcpds(filen, int_min=int_min, \
                                          dsp_min=dsp_min)


    def write_jcpds(self):
        if self.file_name == '':
            QtWidgets.QMessageBox.warning(self.widget, "Warning",
                              "Input filename is not given.")
            return
        path, filen, ext = breakdown_filename(self.file_name)
        if ext == '.cif':
            stamp = '-cif-jt'
        else:
            stamp = '-jt'
        filen_default = os.path.join(path, filen + stamp + '.jcpds')
        filen = dialog_savefile(self.widget, filen_default)
        if filen == '':
            return
        comment = str(self.widget.lineEdit_Comment.text())
        int_min = self.widget.doubleSpinBox_MinDsp.value()
        dsp_min = self.widget.doubleSpinBox_MinInt.value()
        self.read_jcpds_values()
        textoutput = self.model.write_to_file(filen, comments = comment, \
                                 int_min = int_min, dsp_min=dsp_min, \
                                 calculate_1bar_table = True)

    def _check_P1_in_cif(self, file):
        with open(file, 'r') as f:
            cif_data = f.readlines()
        for line in cif_data:
            if '_symmetry_space_group_name_H-M' in line:
                a = line.replace('_symmetry_space_group_name_H-M', '')
                if 'P 1' in a:
                    return False
                else:
                    return True
        return False

    def import_cif(self):
        # pymatgen version check
        mg_version = mg.__version__
        mg_version_split = mg_version.split('.')
        d_current_version = datetime.datetime(int(mg_version_split[0]),
                                              int(mg_version_split[1]),
                                              int(mg_version_split[2]))
        d_work = datetime.datetime(2019, 4, 11)

        if d_current_version < d_work:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning",
                "Update your pymatgen to newer than 2019.4.11.")
            return
        # get cif file
        file = QtWidgets.QFileDialog.getOpenFileName(
            self.widget, "Choose a CIF File", self.file_path,
            "(*.cif)")[0]
        if file == '':
            return
        self._quick_input_view(filename=file)
        not_P1 = self._check_P1_in_cif(file)
        if not not_P1:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning",
                "The CIF file is for P1 structure which cannot be processed.")
            return
        jcpds_from_cif = JCPDS()
        success = jcpds_from_cif.set_from_cif(file, 200., 4., \
                      thermal_expansion=1e-5)
        if not success:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning",
                "Conversion of your cif was not successful.\n" +  \
                "Check the cif file for space group.  It should not be P1.")
            return
        self.model = jcpds_from_cif
        self.file_path, fn, ext = breakdown_filename(file)
        self.model.comments = 'from ' + fn + ext
        self.file_name = file
        self._update_filename()
        # populate double spin boxes
        self._populate_parameters()

    def _quick_input_view(self, filename=None):
        infobox = InformationBox()
        infobox.setText(self._get_text_content(filename=filename))
        infobox.exec_()

    def view_inputfile(self):
        if self.file_name == '':
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning",
                "There is no input file to show.")
            return
        self._quick_input_view()

    def _get_text_content(self, filename=None):
        if filename == None:
            filename = self.file_name
        f = open(filename, 'r')
        text = f.read()
        f.close()
        return text

    def _update_filename(self):
        self.widget.lineEdit_SourceFile.setText(self.file_name)

    def import_jcpds(self):
        file = QtWidgets.QFileDialog.getOpenFileName(
            self.widget, "Choose JPCDS Files", self.file_path,
            "(*.jcpds)")[0]
        if file == '':
            return
        self._quick_input_view(filename=file)
        jcpds = JCPDS()
        try:
            jcpds.read_file(file)
        except:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning", "JCPDS read failed.")
            return
        self.model = jcpds
        self.file_path, _, _ = breakdown_filename(file)
        self.file_name = file
        self._update_filename()
        # populate double spin boxes
        self._populate_parameters()
        # somethings to say about potential problems
        if self.model.k0 > 600.:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning",
                "K0 value of this JCPDS is abnormally high and could crash PeakPo.")
        if self.model.k0p < 1.:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning",
                "K0p value of this JCPDS is abnormally low and could crash PeakPo.")


    def _populate_parameters(self):
        self.widget.doubleSpinBox_CellParamA.setValue(self.model.a0)
        self.widget.doubleSpinBox_CellParamB.setValue(self.model.b0)
        self.widget.doubleSpinBox_CellParamC.setValue(self.model.c0)
        self.widget.doubleSpinBox_CellParamAlpha.setValue(self.model.alpha0)
        self.widget.doubleSpinBox_CellParamBeta.setValue(self.model.beta0)
        self.widget.doubleSpinBox_CellParamGamma.setValue(self.model.gamma0)
        self.widget.doubleSpinBox_K0.setValue(self.model.k0)
        self.widget.doubleSpinBox_K0p.setValue(self.model.k0p)
        self.widget.doubleSpinBox_ThermExpan.setValue(
            self.model.thermal_expansion * 1.e5)

        self.widget.lineEdit_CrystalSystem.setText(self.model.symmetry)
        self.widget.lineEdit_CrystalSystem.setReadOnly(True)
        self.widget.lineEdit_Comment.setText(self.model.comments.rstrip())
        if self.model.symmetry == 'cubic':  # cubic
            self.widget.doubleSpinBox_CellParamA.setDisabled(False)
            self.widget.doubleSpinBox_CellParamB.setDisabled(True)
            self.widget.doubleSpinBox_CellParamC.setDisabled(True)
            self.widget.doubleSpinBox_CellParamAlpha.setDisabled(True)
            self.widget.doubleSpinBox_CellParamBeta.setDisabled(True)
            self.widget.doubleSpinBox_CellParamGamma.setDisabled(True)
        elif self.model.symmetry == 'nosymmetry':  # P, d-sp input
            pass
        elif self.model.symmetry == 'hexagonal' or \
            self.model.symmetry == 'trigonal':
            self.widget.doubleSpinBox_CellParamA.setDisabled(False)
            self.widget.doubleSpinBox_CellParamB.setDisabled(True)
            self.widget.doubleSpinBox_CellParamC.setDisabled(False)
            self.widget.doubleSpinBox_CellParamAlpha.setDisabled(True)
            self.widget.doubleSpinBox_CellParamBeta.setDisabled(True)
            self.widget.doubleSpinBox_CellParamGamma.setDisabled(True)
        elif self.model.symmetry == 'tetragonal':  # tetragonal
            self.widget.doubleSpinBox_CellParamA.setDisabled(False)
            self.widget.doubleSpinBox_CellParamB.setDisabled(True)
            self.widget.doubleSpinBox_CellParamC.setDisabled(False)
            self.widget.doubleSpinBox_CellParamAlpha.setDisabled(True)
            self.widget.doubleSpinBox_CellParamBeta.setDisabled(True)
            self.widget.doubleSpinBox_CellParamGamma.setDisabled(True)
        elif self.model.symmetry == 'orthorhombic':  # orthorhombic
            self.widget.doubleSpinBox_CellParamA.setDisabled(False)
            self.widget.doubleSpinBox_CellParamB.setDisabled(False)
            self.widget.doubleSpinBox_CellParamC.setDisabled(False)
            self.widget.doubleSpinBox_CellParamAlpha.setDisabled(True)
            self.widget.doubleSpinBox_CellParamBeta.setDisabled(True)
            self.widget.doubleSpinBox_CellParamGamma.setDisabled(True)
        elif self.model.symmetry == 'monoclinic':  # monoclinic
            self.widget.doubleSpinBox_CellParamA.setDisabled(False)
            self.widget.doubleSpinBox_CellParamB.setDisabled(False)
            self.widget.doubleSpinBox_CellParamC.setDisabled(False)
            self.widget.doubleSpinBox_CellParamAlpha.setDisabled(True)
            self.widget.doubleSpinBox_CellParamBeta.setDisabled(False)
            self.widget.doubleSpinBox_CellParamGamma.setDisabled(True)
        elif self.model.symmetry == 'triclinic':  # triclinic
            self.widget.doubleSpinBox_CellParamA.setDisabled(False)
            self.widget.doubleSpinBox_CellParamB.setDisabled(False)
            self.widget.doubleSpinBox_CellParamC.setDisabled(False)
            self.widget.doubleSpinBox_CellParamAlpha.setDisabled(False)
            self.widget.doubleSpinBox_CellParamBeta.setDisabled(False)
            self.widget.doubleSpinBox_CellParamGamma.setDisabled(False)
        # disable edit depending on symmetry

    def read_jcpds_values(self):
        self.model.k0 = self.model.k0 = self.widget.doubleSpinBox_K0.value()
        self.model.k0p = self.widget.doubleSpinBox_K0p.value()
        self.model.thermal_expansion = \
            self.widget.doubleSpinBox_ThermExpan.value() * 1.e-5

        if self.model.symmetry == 'cubic':  # cubic
            self.model.a0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.b0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.c0 = self.widget.doubleSpinBox_CellParamA.value()
        elif self.model.symmetry == 'nosymmetry':  # P, d-sp input
            pass
        elif self.model.symmetry == 'hexagonal' or \
            self.model.symmetry == 'trigonal':
            self.model.a0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.b0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.c0 = self.widget.doubleSpinBox_CellParamC.value()
        elif self.model.symmetry == 'tetragonal':  # tetragonal
            self.model.a0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.b0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.c0 = self.widget.doubleSpinBox_CellParamC.value()
        elif self.model.symmetry == 'orthorhombic':  # orthorhombic
            self.model.a0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.b0 = self.widget.doubleSpinBox_CellParamB.value()
            self.model.c0 = self.widget.doubleSpinBox_CellParamC.value()
        elif self.model.symmetry == 'monoclinic':  # monoclinic
            self.model.a0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.b0 = self.widget.doubleSpinBox_CellParamB.value()
            self.model.c0 = self.widget.doubleSpinBox_CellParamC.value()
            self.model.beta0 = self.widget.doubleSpinBox_CellParamBeta.value()
        elif self.model.symmetry == 'triclinic':  # triclinic
            self.model.a0 = self.widget.doubleSpinBox_CellParamA.value()
            self.model.b0 = self.widget.doubleSpinBox_CellParamB.value()
            self.model.c0 = self.widget.doubleSpinBox_CellParamC.value()
            self.model.alpha0 = \
                self.widget.doubleSpinBox_CellParamAlpha.value()
            self.model.beta0 = self.widget.doubleSpinBox_CellParamBeta.value()
            self.model.gamma0 = \
                self.widget.doubleSpinBox_CellParamGamma.value()

    def write_setting(self):
        """
        Write default setting
        """
        # self.settings = QtCore.QSettings('DS', 'PeakPo')
        self.settings = QtCore.QSettings('DS', 'JCPDSTools')
        # print('write:' + self.model.chi_path)
        self.settings.setValue('jcpds_path', self.file_path)

    def read_setting(self):
        """
        Read default setting
        """
        self.settings = QtCore.QSettings('DS', 'JCPDSTools')
        # self.settings.setFallbacksEnabled(False)
        self.file_path = self.settings.value('file_path')
Esempio n. 11
0
class MainController(object):
    def __init__(self):

        self.widget = MainWindow()
        self.model = PeakPoModel()
        # self.obj_color = 'white'
        self.base_ptn_ctrl = BasePatternController(self.model, self.widget)
        self.plot_ctrl = MplController(self.model, self.widget)
        self.cakeazi_ctrl = CakeAziController(self.model, self.widget)
        # self.cake_ctrl = CakeController(self.model, self.widget)
        self.waterfall_ctrl = \
            WaterfallController(self.model, self.widget)
        self.ucfit_ctrl = UcfitController(self.model, self.widget)
        self.jcpds_ctrl = JcpdsController(self.model, self.widget)
        self.waterfalltable_ctrl = \
            WaterfallTableController(self.model, self.widget)
        #self.ucfittable_ctrl = UcfitTableController(self.model, self.widget)
        self.jcpdstable_ctrl = JcpdsTableController(self.model, self.widget)
        self.session_ctrl = SessionController(self.model, self.widget)
        self.peakfit_ctrl = PeakFitController(self.model, self.widget)
        self.peakfit_table_ctrl = PeakfitTableController(
            self.model, self.widget)
        self.read_setting()
        self.connect_channel()
        #
        self.clip = QtWidgets.QApplication.clipboard()
        # no more stuff can be added below

    def show_window(self):
        self.widget.show()

    def connect_channel(self):
        # connecting events
        self.widget.mpl.canvas.mpl_connect('button_press_event',
                                           self.deliver_mouse_signal)
        self.widget.mpl.canvas.mpl_connect('key_press_event',
                                           self.on_key_press)
        self.widget.spinBox_AziShift.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.doubleSpinBox_Pressure.valueChanged.connect(
            self.apply_pt_to_graph)
        self.widget.pushButton_S_PIncrease.clicked.connect(
            lambda: self.quick_p_change(1))
        self.widget.pushButton_S_PDecrease.clicked.connect(
            lambda: self.quick_p_change(-1))
        self.widget.pushButton_S_TIncrease.clicked.connect(
            lambda: self.quick_temp_change(1))
        self.widget.pushButton_S_TDecrease.clicked.connect(
            lambda: self.quick_temp_change(-1))
        self.widget.doubleSpinBox_Temperature.valueChanged.connect(
            self.apply_pt_to_graph)
        self.widget.doubleSpinBox_SetWavelength.valueChanged.connect(
            self.apply_wavelength)
        self.widget.pushButton_SaveBgSubCHI.clicked.connect(self.save_bgsubchi)
        self.widget.pushButton_SetXEat30.clicked.connect(
            lambda: self.setXEat(0.4133))
        self.widget.pushButton_SetXEat37.clicked.connect(
            lambda: self.setXEat(0.3344))
        self.widget.pushButton_SetXEat42.clicked.connect(
            lambda: self.setXEat(0.2952))
        """
        self.widget.pushButton_ExportToUCFit.clicked.connect(
            self.export_to_ucfit)
        """
        self.widget.pushButton_ImportJlist.clicked.connect(
            self.load_jlist_from_session)
        self.widget.pushButton_UpdateBackground.clicked.connect(
            self.update_bgsub)
        self.widget.checkBox_LongCursor.clicked.connect(
            self.apply_changes_to_graph)
        self.widget.checkBox_ShowMillerIndices.clicked.connect(
            self.apply_changes_to_graph)
        self.widget.comboBox_BasePtnLineThickness.currentIndexChanged.connect(
            self.apply_changes_to_graph)
        self.widget.comboBox_PtnJCPDSBarThickness.currentIndexChanged.connect(
            self.apply_changes_to_graph)
        self.widget.comboBox_CakeJCPDSBarThickness.currentIndexChanged.connect(
            self.apply_changes_to_graph)
        self.widget.comboBox_BkgnLineThickness.currentIndexChanged.connect(
            self.apply_changes_to_graph)
        self.widget.comboBox_WaterfallLineThickness.currentIndexChanged.connect(
            self.apply_changes_to_graph)
        self.widget.comboBox_HKLFontSize.currentIndexChanged.connect(
            self.apply_changes_to_graph)
        self.widget.comboBox_PnTFontSize.currentIndexChanged.connect(
            self.apply_changes_to_graph)
        self.widget.checkBox_ShortPlotTitle.clicked.connect(
            self.apply_changes_to_graph)
        self.widget.checkBox_ShowCakeLabels.clicked.connect(
            self.apply_changes_to_graph)
        self.widget.checkBox_ShowLargePnT.clicked.connect(
            self.apply_changes_to_graph)
        # navigation toolbar modification.  Do not move the followings to
        # other controller files.
        #self.widget.pushButton_toPkFt.clicked.connect(self.to_PkFt)
        #self.widget.pushButton_fromPkFt.clicked.connect(self.from_PkFt)
        self.widget.checkBox_NightView.clicked.connect(self.set_nightday_view)
        self.widget.pushButton_S_Zoom.clicked.connect(self.plot_new_graph)
        self.widget.checkBox_AutoY.clicked.connect(self.apply_changes_to_graph)
        self.widget.checkBox_BgSub.clicked.connect(self.apply_changes_to_graph)
        self.widget.checkBox_ShowWaterfallLabels.clicked.connect(
            self.apply_changes_to_graph)
        self.widget.checkBox_ShowMillerIndices_Cake.clicked.connect(
            self.apply_changes_to_graph)
        # self.widget.actionClose.triggered.connect(self.closeEvent)
        self.widget.tabWidget.currentChanged.connect(self.check_for_peakfit)
        # self.widget.tabWidget.setTabEnabled(8, False)
        self.widget.pushButton_DelTempCHI.clicked.connect(self.del_temp_chi)
        self.widget.pushButton_DelTempCake.clicked.connect(self.del_temp_cake)
        # slide bars
        self.widget.horizontalSlider_VMin.setValue(0)
        self.widget.horizontalSlider_VMax.setValue(100)
        self.widget.horizontalSlider_MaxScaleBars.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.horizontalSlider_VMin.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.horizontalSlider_VMax.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.horizontalSlider_CakeAxisSize.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.horizontalSlider_JCPDSBarScale.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.horizontalSlider_JCPDSBarPosition.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.horizontalSlider_WaterfallGaps.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.doubleSpinBox_JCPDS_cake_Alpha.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.doubleSpinBox_JCPDS_ptn_Alpha.valueChanged.connect(
            self.apply_changes_to_graph)
        self.widget.pushButton_UpdateJCPDSSteps.clicked.connect(
            self.update_jcpds_table)
        """
        self.widget.pushButton_UpdateUCFitSteps.clicked.connect(
            self.update_ucfit_table)
        """
        self.widget.pushButton_IntegrateCake.clicked.connect(
            self.integrate_to_1d)
        self.widget.pushButton_PrevBasePtn.clicked.connect(
            lambda: self.goto_next_file('previous'))
        self.widget.pushButton_NextBasePtn.clicked.connect(
            lambda: self.goto_next_file('next'))
        self.widget.pushButton_S_PrevBasePtn.clicked.connect(
            lambda: self.goto_next_file('previous'))
        self.widget.pushButton_S_NextBasePtn.clicked.connect(
            lambda: self.goto_next_file('next'))
        self.widget.pushButton_LastBasePtn.clicked.connect(
            lambda: self.goto_next_file('last'))
        self.widget.pushButton_FirstBasePtn.clicked.connect(
            lambda: self.goto_next_file('first'))

    def integrate_to_1d(self):
        filen = self.cakeazi_ctrl.integrate_to_1d()
        if filen is None:
            return
        else:
            reply = QtWidgets.QMessageBox.question(
                self.widget, 'Message',
                'Do you want to add this file ({:s}) to the waterfall list?'.
                format(filen),
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                QtWidgets.QMessageBox.Yes)
            if reply == QtWidgets.QMessageBox.No:
                return
            else:
                # add to waterfall
                self.waterfall_ctrl._add_patterns([filen])

    def quick_p_change(self, direction):
        step = self.widget.doubleSpinBox_PStep.value()
        p_value = self.widget.doubleSpinBox_Pressure.value()
        self.widget.doubleSpinBox_Pressure.setValue(p_value + step * direction)

    def quick_temp_change(self, direction):
        step = self.widget.spinBox_TStep.value()
        temp_value = self.widget.doubleSpinBox_Temperature.value()
        self.widget.doubleSpinBox_Temperature.setValue(temp_value +
                                                       step * direction)

    def update_jcpds_table(self):
        step = float(self.widget.doubleSpinBox_JCPDSStep.value())
        self.jcpdstable_ctrl.update_steps_only(step)

    """
    def update_ucfit_table(self):
        step = self.widget.doubleSpinBox_UCFitStep.value()
        self.ucfittable_ctrl.update_steps_only(step)
    """

    def del_temp_chi(self):
        reply = QtWidgets.QMessageBox.question(
            self.widget, 'Message',
            'This can slow down PeakPo, but update the background. Proceed?',
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
            QtWidgets.QMessageBox.Yes)
        if reply == QtWidgets.QMessageBox.No:
            return
        if self._temporary_pkpo_exists():
            temp_dir = get_temp_dir(self.model.get_base_ptn_filename())
            temp_chi = os.path.join(temp_dir, '*.chi')
            for f in glob.glob(temp_chi):
                os.remove(f)

    def del_temp_cake(self):
        reply = QtWidgets.QMessageBox.question(
            self.widget, 'Message',
            'This can slow down PeakPo, but update PONI. Proceed?',
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
            QtWidgets.QMessageBox.Yes)
        if reply == QtWidgets.QMessageBox.No:
            return
        if self._temporary_pkpo_exists():
            temp_dir = get_temp_dir(self.model.get_base_ptn_filename())
            temp_cake = os.path.join(temp_dir, '*.npy')
            for f in glob.glob(temp_cake):
                os.remove(f)

    def _temporary_pkpo_exists(self):
        temp_dir = get_temp_dir(self.model.get_base_ptn_filename())
        return os.path.exists(temp_dir)

    def check_for_peakfit(self, i):
        if i == 8:
            self.widget.checkBox_AutoY.setChecked(False)
            self.apply_changes_to_graph()

    def apply_changes_to_graph(self):
        self.plot_ctrl.update()

    def plot_new_graph(self):
        self.plot_ctrl.zoom_out_graph()

    def load_jlist_from_session(self):
        """
        get existing jlist file from data folder
        """
        fn_jlist = QtWidgets.QFileDialog.getOpenFileName(
            self.widget, "Choose A Session File", self.model.chi_path,
            "(*.ppss *.dpp)")[0]
        if fn_jlist == '':
            return
        if extract_extension(fn_jlist) == 'ppss':
            self.session_ctrl._load_ppss(fn_jlist, jlistonly=True)
        elif extract_extension(fn_jlist) == 'dpp':
            self.session_ctrl._load_dpp(fn_jlist, jlistonly=True)
        self.widget.textEdit_Jlist.setText(str(fn_jlist))
        self.jcpdstable_ctrl.update()
        self.plot_ctrl.update()

    """
    def export_to_ucfit(self):
        if not self.model.jcpds_exist():
            return
        idx_checked = [
            s.row() for s in self.widget.tableWidget_JCPDS.selectionModel().
            selectedRows()]

        if idx_checked == []:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning",
                "Highlight the name of JCPDS to export")
            return
        i = 0
        for j in range(idx_checked.__len__()):
            if self.model.jcpds_lst[idx_checked[j]].symmetry != 'nosymmetry':
                phase = UnitCell()
                phase.name = self.model.jcpds_lst[idx_checked[j]].name
                phase.color = self.model.jcpds_lst[idx_checked[j]].color
                phase.symmetry = self.model.jcpds_lst[idx_checked[j]].symmetry
                phase.a = self.model.jcpds_lst[idx_checked[j]].a
                phase.b = self.model.jcpds_lst[idx_checked[j]].b
                phase.c = self.model.jcpds_lst[idx_checked[j]].c
                phase.alpha = self.model.jcpds_lst[idx_checked[j]].alpha
                phase.beta = self.model.jcpds_lst[idx_checked[j]].beta
                phase.gamma = self.model.jcpds_lst[idx_checked[j]].gamma
                phase.v = self.model.jcpds_lst[idx_checked[j]].v
                phase.DiffLines = \
                    self.model.jcpds_lst[idx_checked[j]].DiffLines
                self.model.ucfit_lst.append(phase)
                i += 1
            else:
                QtWidgets.QMessageBox.warning(
                    self.widget, "Warning",
                    "You cannot send a jcpds without symmetry.")
        # self.ucfittable_ctrl.update()
        self.jcpdstable_ctrl.update()
        self.plot_ctrl.update()
        return
    """

    def save_bgsubchi(self):
        """
        Save bg subtractd pattern to a chi file
        """
        if not self.model.base_ptn_exist():
            return
        filen_chi_t = self.model.make_filename('bgsub.chi')
        filen_chi = dialog_savefile(self.widget, filen_chi_t)
        if str(filen_chi) == '':
            return
        x, y = self.model.base_ptn.get_bgsub()
        preheader_line0 = \
            '2-theta # BG ROI: {0: .5e}, {1: .5e} \n'.format(
                self.widget.doubleSpinBox_Background_ROI_min.value(),
                self.widget.doubleSpinBox_Background_ROI_max.value())
        preheader_line1 = \
            '2-theta # BG Params: {0: d}, {1: d}, {2: d} \n'.format(
                self.widget.spinBox_BGParam0.value(),
                self.widget.spinBox_BGParam1.value(),
                self.widget.spinBox_BGParam2.value())
        preheader_line2 = '\n'
        writechi(filen_chi,
                 x,
                 y,
                 preheader=preheader_line0 + preheader_line1 + preheader_line2)

    def write_setting(self):
        """
        Write default setting
        """
        # self.settings = QtCore.QSettings('DS', 'PeakPo')
        self.settings = QtCore.QSettings('DS', 'PeakPo')
        # print('write:' + self.model.chi_path)
        self.settings.setValue('chi_path', self.model.chi_path)
        self.settings.setValue('jcpds_path', self.model.jcpds_path)

    def read_setting(self):
        """
        Read default setting
        """
        self.settings = QtCore.QSettings('DS', 'PeakPo')
        # self.settings.setFallbacksEnabled(False)
        self.model.set_chi_path(self.settings.value('chi_path'))
        self.model.set_jcpds_path(self.settings.value('jcpds_path'))

    """
    def closeEvent(self, event):
        self.write_setting()
        self.widget.deleteLater()
        gc.collect()
        self.deleteLater()
        event.accept()
    """

    def on_key_press(self, event):
        if event.key == 'i':
            if self.widget.mpl.ntb._active == 'PAN':
                self.widget.mpl.ntb.pan()
            if self.widget.mpl.ntb._active == 'ZOOM':
                self.widget.mpl.ntb.zoom()
        elif event.key == 's':
            self.session_ctrl.save_dpp_ppss()
        elif event.key == 'w':
            self.plot_new_graph()
        elif event.key == 'v':
            lims = self.widget.mpl.canvas.ax_pattern.axis()
            if self.widget.checkBox_BgSub.isChecked():
                x, y = self.model.base_ptn.get_bgsub()
            else:
                x, y = self.model.base_ptn.get_raw()
            xroi, yroi = get_DataSection(x, y, [lims[0], lims[1]])
            self.plot_ctrl.update([lims[0], lims[1], yroi.min(), yroi.max()])
        else:
            key_press_handler(event, self.widget.mpl.canvas,
                              self.widget.mpl.ntb)

    """
    def to_PkFt(self):
        # listen
        if not self.model.base_ptn_exist():
            return
        lims = self.widget.mpl.canvas.ax_pattern.axis()
        talk = "PeakPo,{0},{1: .2f},{2: .2f},{3: .2f},{4: .2f}".format(
            self.model.base_ptn.fname, lims[0], lims[1], lims[2], lims[3])
        self.clip.setText(talk)

    def from_PkFt(self):
        l = self.clip.text()
        listen = str(l)
        if listen.find("PeakFt") == -1:
            return
        a = listen.split(',')
        new_filen = a[1]
        new_lims = [float(i) for i in a[2:6]]
        self.base_ptn_ctrl._load_a_new_pattern(new_filen)
        self.plot_ctrl.update(new_lims)
    """

    def set_nightday_view(self):
        self.plot_ctrl._set_nightday_view()
        self.waterfalltable_ctrl.update()
        self.plot_ctrl.update()

    def deliver_mouse_signal(self, event):
        if self.widget.mpl.ntb._active is not None:
            return
        if (event.xdata is None) or (event.ydata is None):
            return
        if (event.button != 1) and (event.button != 3):
            return
        if event.button == 1:
            mouse_button = 'left'
        elif event.button == 3:
            mouse_button = 'right'
        if (self.widget.tabWidget.currentIndex() == 8) and \
                (self.widget.pushButton_AddRemoveFromMouse.isChecked()):
            if not self.model.current_section_exist():
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "Set section first.")
                return
            """ lines below causes issues
            if self.model.current_section.fitted():
                reply = QtWidgets.QMessageBox.question(
                    self.widget, 'Message',
                    'Do you want to add to the last fitting result without save?',
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                    QtWidgets.QMessageBox.Yes)
                if reply == QtWidgets.QMessageBox.No:
                    return
                else:
                    self.model.current_section.invalidate_fit_result()
            """
            if self.model.current_section.fitted():
                self.model.current_section.invalidate_fit_result()
            self.pick_peak(mouse_button, event.xdata, event.ydata)
        else:
            self.read_plot(mouse_button, event.xdata, event.ydata)

    def pick_peak(self, mouse_button, xdata, ydata):
        """
        """
        if mouse_button == 'left':  # left click
            success = self.model.current_section.set_single_peak(
                float(xdata), self.widget.doubleSpinBox_InitialFWHM.value())
            if not success:
                QtWidgets.QMessageBox.warning(
                    self.widget, "Warning",
                    "You picked outside of the current section.")
                return
        elif mouse_button == 'right':  # right button for removal
            if not self.model.current_section.peaks_exist():
                return
            self.model.current_section.remove_single_peak_nearby(xdata)
        else:
            return
        self.peakfit_ctrl.set_tableWidget_PkParams_unsaved()
        self.peakfit_table_ctrl.update_peak_parameters()
        self.peakfit_table_ctrl.update_peak_constraints()
        self.plot_ctrl.update()

    def read_plot(self, mouse_button, xdata, ydata):
        if mouse_button == 'right':
            return
        x_click = float(xdata)
        y_click = float(ydata)
        x_click_dsp = self.widget.doubleSpinBox_SetWavelength.value() / 2. / \
            np.sin(np.radians(x_click / 2.))
        clicked_position = \
            "Clicked position: {0:.4f}, {1:.1f}, \n d-sp = {2:.4f} \u212B".\
            format(x_click, y_click, x_click_dsp)
        if (not self.model.jcpds_exist()) and (not self.model.ucfit_exist()):
            QtWidgets.QMessageBox.warning(self.widget, "Information",
                                          clicked_position)
        else:
            # get jcpds information
            x_find = xdata
            textinfo = self._find_closestjcpds(x_find)
            QtWidgets.QMessageBox.warning(self.widget, "Information",
                                          clicked_position + '\n' + textinfo)

    def setXEat(self, wavelength):
        self.widget.doubleSpinBox_SetWavelength.setValue(wavelength)
        self.apply_wavelength()

    def apply_wavelength(self):
        # self.wavelength = value
        self.model.base_ptn.wavelength = \
            self.widget.doubleSpinBox_SetWavelength.value()
        xray_energy = convert_wl_to_energy(self.model.base_ptn.wavelength)
        self.widget.label_XRayEnergy.setText(
            "({:.3f} keV)".format(xray_energy))
        self.plot_ctrl.update()

    def update_bgsub(self):
        '''
        this is only to read the current inputs and replot
        '''
        if not self.model.base_ptn_exist():
            QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                          "Load a base pattern first.")
            return
        """receive new bg parameters and update the graph"""
        bg_params = [
            self.widget.spinBox_BGParam0.value(),
            self.widget.spinBox_BGParam1.value(),
            self.widget.spinBox_BGParam2.value()
        ]
        bg_roi = [
            self.widget.doubleSpinBox_Background_ROI_min.value(),
            self.widget.doubleSpinBox_Background_ROI_max.value()
        ]
        if (bg_roi[0] <= self.model.base_ptn.x_raw.min()):
            bg_roi[0] = self.model.base_ptn.x_raw.min()
            self.widget.doubleSpinBox_Background_ROI_min.setValue(bg_roi[0])
        if (bg_roi[1] >= self.model.base_ptn.x_raw.max()):
            bg_roi[1] = self.model.base_ptn.x_raw.max()
            self.widget.doubleSpinBox_Background_ROI_max.setValue(bg_roi[1])
        self.model.base_ptn.subtract_bg(bg_roi, bg_params, yshift=0)
        temp_dir = get_temp_dir(self.model.get_base_ptn_filename())
        self.model.base_ptn.write_temporary_bgfiles(temp_dir=temp_dir)
        if self.model.waterfall_exist():
            print(
                str(datetime.datetime.now())[:-7],
                ": BGfit and BGsub for waterfall patterns even if they are displayed.\n",
                "Yes this is a bit of waste.  Future fix needed.")
            for pattern in self.model.waterfall_ptn:
                pattern.subtract_bg(bg_roi, bg_params, yshift=0)
        self.plot_new_graph()

    def apply_pt_to_graph(self):
        """
        if self.model.jcpds_exist():
            self.plot_ctrl.update_jcpds_only()
        else:
        """
        self.plot_ctrl.update()

    def _find_closestjcpds(self, x):
        jcount = 0
        for phase in self.model.jcpds_lst:
            if phase.display:
                jcount += 1
        ucount = 0
        for phase in self.model.ucfit_lst:
            if phase.display:
                ucount += 1
        if (jcount + ucount) == 0:
            return ''
        if jcount != 0:
            idx_j = []
            diff_j = []
            tth_j = []
            h_j = []
            k_j = []
            l_j = []
            names_j = []
            dsp_j = []
            int_j = []
            for j in self.model.jcpds_lst:
                if j.display:
                    i, d, t = j.find_DiffLine(
                        x, self.widget.doubleSpinBox_SetWavelength.value())
                    idx_j.append(i)
                    diff_j.append(d)
                    tth_j.append(t)
                    h_j.append(j.DiffLines[i].h)
                    k_j.append(j.DiffLines[i].k)
                    l_j.append(j.DiffLines[i].l)
                    dsp_j.append(j.DiffLines[i].dsp)
                    int_j.append(j.DiffLines[i].intensity)
                    names_j.append(j.name)
        if ucount != 0:
            idx_u = []
            diff_u = []
            tth_u = []
            h_u = []
            k_u = []
            l_u = []
            names_u = []
            dsp_u = []
            int_u = []
            for u in self.model.ucfit_lst:
                if u.display:
                    i, d, t = u.find_DiffLine(
                        x, self.widget.doubleSpinBox_SetWavelength.value())
                    idx_u.append(i)
                    diff_u.append(d)
                    tth_u.append(t)
                    h_u.append(u.DiffLines[i].h)
                    k_u.append(u.DiffLines[i].k)
                    l_u.append(u.DiffLines[i].l)
                    dsp_u.append(u.DiffLines[i].dsp)
                    int_u.append(u.DiffLines[i].intensity)
                    names_u.append(u.name)
        if (jcount != 0) and (ucount == 0):
            idx_min = diff_j.index(min(diff_j))
            tth_min = tth_j[idx_min]
            dsp_min = dsp_j[idx_min]
            int_min = int_j[idx_min]
            h_min = h_j[idx_min]
            k_min = k_j[idx_min]
            l_min = l_j[idx_min]
            name_min = names_j[idx_min]
        elif (jcount == 0) and (ucount != 0):
            idx_min = diff_u.index(min(diff_u))
            tth_min = tth_u[idx_min]
            dsp_min = dsp_u[idx_min]
            int_min = int_u[idx_min]
            h_min = h_u[idx_min]
            k_min = k_u[idx_min]
            l_min = l_u[idx_min]
            name_min = names_u[idx_min]
        else:
            if min(diff_j) <= min(diff_u):
                idx_min = diff_j.index(min(diff_j))
                tth_min = tth_j[idx_min]
                dsp_min = dsp_j[idx_min]
                int_min = int_j[idx_min]
                h_min = h_j[idx_min]
                k_min = k_j[idx_min]
                l_min = l_j[idx_min]
                name_min = names_j[idx_min]
            else:
                idx_min = diff_u.index(min(diff_u))
                tth_min = tth_u[idx_min]
                dsp_min = dsp_u[idx_min]
                int_min = int_u[idx_min]
                h_min = h_u[idx_min]
                k_min = k_u[idx_min]
                l_min = l_u[idx_min]
                name_min = names_u[idx_min]
        line1 = '2\u03B8 = {0:.4f} \u00B0, d-sp = {1:.4f} \u212B'.format(
            float(tth_min), float(dsp_min))
        line2 = 'intensity = {0: .0f}, hkl = {1: .0f} {2: .0f} {3: .0f}'.\
            format(int(int_min), int(h_min), int(k_min), int(l_min))
        textoutput = name_min + '\n' + line1 + '\n' + line2
        return textoutput

    def goto_next_file(self, move):
        """
        quick move to the next base pattern file
        """
        if not self.model.base_ptn_exist():
            QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                          "Choose a base pattern first.")
            return
        if self.widget.checkBox_NavDPP.isChecked():
            self._goto_dpp_next_file(move)
        else:
            self._goto_chi_next_file(move)
        return

    def _goto_chi_next_file(self, move):
        filelist_chi = get_sorted_filelist(
            self.model.chi_path,
            sorted_by_name=self.widget.radioButton_SortbyNme.isChecked(),
            search_ext='*.chi')

        idx_chi = find_from_filelist(
            filelist_chi,
            os.path.split(self.model.base_ptn.fname)[1])

        if idx_chi == -1:
            QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                          "Cannot find current file")
            return  # added newly

        step = self.widget.spinBox_FileStep.value()
        if move == 'next':
            idx_chi_new = idx_chi + step
        elif move == 'previous':
            idx_chi_new = idx_chi - step
        elif move == 'last':
            idx_chi_new = filelist_chi.__len__() - 1
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the last file.")
                return
        elif move == 'first':
            idx_chi_new = 0
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the first file.")
                return

        if idx_chi_new > filelist_chi.__len__() - 1:
            idx_chi_new = filelist_chi.__len__() - 1
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the last file.")
                return
        if idx_chi_new < 0:
            idx_chi_new = 0
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the first file.")
                return
        new_filename_chi = filelist_chi[idx_chi_new]
        if os.path.exists(new_filename_chi):
            self.base_ptn_ctrl._load_a_new_pattern(new_filename_chi)
            # self.model.set_base_ptn_color(self.obj_color)
            self.plot_ctrl.update()
        else:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning", new_filename_chi + " does not exist.")

    def _goto_dpp_next_file(self, move):

        filelist_chi = get_sorted_filelist(
            self.model.chi_path,
            sorted_by_name=self.widget.radioButton_SortbyNme.isChecked(),
            search_ext='*.chi')
        filelist_dpp = get_sorted_filelist(
            self.model.chi_path,
            sorted_by_name=self.widget.radioButton_SortbyNme.isChecked(),
            search_ext='*.dpp')

        idx_chi = find_from_filelist(
            filelist_chi,
            os.path.split(self.model.base_ptn.fname)[1])
        dpp_filen = make_filename(self.model.base_ptn.fname, 'dpp')
        idx_dpp = find_from_filelist(filelist_dpp, dpp_filen)

        if idx_chi == -1:
            QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                          "Cannot find current chi file")
            return  # added newly

        # for radioButton_NavDPP
        if idx_dpp == -1:
            QtWidgets.QMessageBox.warning(
                self.widget, "Warning", "Cannot find current dpp file.\n" +
                "Manually save one for current chi file first.")
            return  # added newly

        step = self.widget.spinBox_FileStep.value()
        if move == 'next':
            idx_chi_new = idx_chi + step
        elif move == 'previous':
            idx_chi_new = idx_chi - step
        elif move == 'last':
            idx_chi_new = filelist_chi.__len__() - 1
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the last file.")
                return
        elif move == 'first':
            idx_chi_new = 0
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the first file.")
                return
        if idx_chi_new > filelist_chi.__len__() - 1:
            idx_chi_new = filelist_chi.__len__() - 1
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the last file.")
                return
        if idx_chi_new < 0:
            idx_chi_new = 0
            if idx_chi == idx_chi_new:
                QtWidgets.QMessageBox.warning(self.widget, "Warning",
                                              "It is already the first file.")
                return

        if self.widget.checkBox_SaveDPPMove.isChecked():
            self.session_ctrl.save_dpp(quiet=True)
        else:
            reply = QtWidgets.QMessageBox.question(
                self.widget, 'Message',
                'Do you want to save this to dpp before you move to the next?',
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                QtWidgets.QMessageBox.Yes)
            if reply == QtWidgets.QMessageBox.Yes:
                self.session_ctrl.save_dpp()

        new_filename_chi = filelist_chi[idx_chi_new]
        new_filename_dpp = make_filename(new_filename_chi, 'dpp')
        idx = find_from_filelist(filelist_dpp, new_filename_dpp)

        if idx == -1:
            # no pre-existing dpp
            # check the checkbox for autogenerate
            if self.widget.checkBox_AutoGenDPP.isChecked():
                self.base_ptn_ctrl._load_a_new_pattern(new_filename_chi)
                self.session_ctrl.save_dpp(quiet=True)
                self.model.clear_section_list()
                self.plot_ctrl.update()
            else:
                QtWidgets.QMessageBox.warning(
                    self.widget, "Warning", "Cannot find pre-existing dpp.\n" +
                    "Consider Create with Move function.")
                return
            # call autogenerate subroutine
            # self._load_a_new_pattern(new_filename_chi)
            # self.model.set_base_ptn_color(self.obj_color)
            # self.plot_ctrl.update()
        else:
            # pre-existing dpp
            # question if overwrite or not
            if self.widget.checkBox_AutoGenDPP.isChecked() and \
                (not self.widget.checkBox_AutogenMissing.isChecked()):
                reply = QtWidgets.QMessageBox.question(
                    self.widget, 'Message',
                    "The next pattern already has a dpp.\n" +
                    "If you want to overwrite the existing one based" +
                    " on the dpp of the last pattern, choose YES.\n" +
                    "If you want to keep and open the existing dpp, choose NO.",
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                    QtWidgets.QMessageBox.No)
                if reply == QtWidgets.QMessageBox.Yes:
                    self.base_ptn_ctrl._load_a_new_pattern(new_filename_chi)
                    self.session_ctrl.save_dpp(quiet=True)
                    self.model.clear_section_list()
                    self.plot_ctrl.update()
                else:
                    # load the existing dpp
                    # QtWidgets.QMessageBox.warning(
                    #    self.widget, "Warning", "The existing dpp will be open.")
                    success = self.session_ctrl._load_dpp(new_filename_dpp)
                    if success:
                        if self.model.exist_in_waterfall(
                                self.model.base_ptn.fname):
                            self.widget.pushButton_AddBasePtn.setChecked(True)
                        else:
                            self.widget.pushButton_AddBasePtn.setChecked(False)
                        if self.widget.checkBox_ShowCake.isChecked():
                            self.session_ctrl._load_cake_format_file()
                        self.plot_ctrl.update()
                    else:
                        QtWidgets.QMessageBox.warning(
                            self.widget, "Warning",
                            "DPP loading was not successful.")
                        return
            else:
                # simply open the next existing one
                success = self.session_ctrl._load_dpp(new_filename_dpp)
                if success:
                    if self.model.exist_in_waterfall(
                            self.model.base_ptn.fname):
                        self.widget.pushButton_AddBasePtn.setChecked(True)
                    else:
                        self.widget.pushButton_AddBasePtn.setChecked(False)
                    if self.widget.checkBox_ShowCake.isChecked():
                        self.session_ctrl._load_cake_format_file()
                    self.plot_ctrl.update()
                else:
                    QtWidgets.QMessageBox.warning(
                        self.widget, "Warning",
                        "DPP loading was not successful.")
                    return
        self.jcpdstable_ctrl.update()
        self.peakfit_table_ctrl.update_sections()
        self.peakfit_table_ctrl.update_peak_parameters()
        self.peakfit_table_ctrl.update_baseline_constraints()
        self.peakfit_table_ctrl.update_peak_constraints()
        return