Пример #1
0
class ObjectTab(QWidget):
    """
    This class constructs the entire contents of the Object tab.
    """
    def __init__(self, inspector, dither, detector, object_id, *args):
        super().__init__(*args)

        self._inspector = inspector
        self._dither = dither  # remove
        self._detector = detector  # remove
        self._object_id = object_id
        self.contents = list()
        self.setMouseTracking(True)

        self.plot_selector = PlotSelector(self)

        detectors = self.determine_relevant_detectors(object_id)

        selector_area = MultiDitherDetectorSelector(detectors)
        selector_area.updated.connect(self.update_plot_button)

        self.mdi = QMdiArea(self)
        self.mdi.setContentsMargins(0, 0, 0, 0)
        self.mdi.setBackground(QBrush(QColor('#56595e')))

        h_layout = QGridLayout()
        h_layout.setSpacing(0)
        h_layout.setContentsMargins(0, 0, 0, 0)
        h_layout.addWidget(selector_area, 0, 0)
        h_layout.setAlignment(selector_area, Qt.AlignTop)
        h_layout.addWidget(self.mdi, 0, 1)

        h_layout.setColumnStretch(0, 0)
        h_layout.setColumnStretch(1, 10)

        self.detector_selector = selector_area

        v_layout = QVBoxLayout()
        v_layout.setSpacing(0)

        v_layout.addWidget(self.plot_selector)

        v_layout.addItem(h_layout)

        self.setLayout(v_layout)
        self.setContentsMargins(0, 0, 0, 0)
        self._spec_plots = None

        self._plot_descriptors = set()

        self._info_window = None

    @property
    def object_id(self):
        return self._object_id

    @property
    def dither(self):
        return self._dither

    @property
    def detector(self):
        return self._detector

    @property
    def inspector(self):
        return self._inspector

    def make_plots(self):
        self._spec_plots = SpecPlot(self._inspector, self.plot_selector, self.detector_selector)
        self._spec_plots.make_plots(self._object_id)
        for window in self._spec_plots.windows:
            if window.descriptor not in self._plot_descriptors:
                self.mdi.addSubWindow(window)
                self._plot_descriptors.add(window.descriptor)
                window.closing.connect(self.handle_closed_subwindow)
                window.activateWindow()
                window.show()

    def show_info(self):
        if self._inspector.location_tables is not None:
            info = self._inspector.location_tables.get_info(self._object_id)
            info_window = ObjectInfoWindow(info, self._inspector)
            self.mdi.addSubWindow(info_window)
            info_window.activateWindow()
            info_window.show()
            self._info_window = info_window
        else:
            m = QMessageBox(0, 'Missing Data',
                            'Location tables containing the requested information must be loaded before showing info.')
            m.exec()

    def determine_relevant_detectors(self, object_id):
        """
        Returns the detectors in which the spectra of the object can be found, in the format {dither: [detectors]}
        """
        detectors = {}

        for dither in self._inspector.spectra[object_id]:
            detectors[dither] = list(self._inspector.spectra[object_id][dither].keys())

        for d in (1, 2, 3, 4):
            if d not in detectors:
                detectors[d] = []

        return detectors

    def update_plot_button(self):
        selected = list(self.detector_selector.selected_detectors().values())

        if all(item is None for item in selected):
            self.plot_selector.plot_button.setDisabled(True)
            self.plot_selector.detector_button.setDisabled(True)
        else:
            self.plot_selector.detector_button.setEnabled(True)
            self.plot_selector.plot_button.setEnabled(True)

    def handle_closed_subwindow(self, descriptor):
        if descriptor in self._plot_descriptors:
            self._plot_descriptors.remove(descriptor)

        active_window = self.mdi.activeSubWindow()

        if active_window is not None and descriptor == active_window.widget().descriptor:
            self.mdi.closeActiveSubWindow()

    def open_detectors(self):

        selected_detectors = self.detector_selector.selected_detectors()

        inspector = self._inspector

        # make a list of all open detectors (detectors currently being viewed in tabs)

        open_detectors = []

        for tab_index in range(inspector.tabs.count()):
            tab = inspector.tabs.widget(tab_index)
            if isinstance(tab, ViewTab):
                open_detectors.append((tab.current_dither, tab.current_detector))

        # open new tabs, where necessary

        for dither in selected_detectors:
            if selected_detectors[dither] is not None:
                for detector in selected_detectors[dither]:
                    if (dither, detector) not in open_detectors:
                        inspector.new_view_tab(dither, detector)

            # pin the object in all tabs:

            for tab_index in range(inspector.tabs.count()):
                tab = inspector.tabs.widget(tab_index)
                if isinstance(tab, ViewTab):
                    tab.select_spectrum_by_id(self._object_id)
Пример #2
0
class MainWindow(QMainWindow):
    count = 0

    def __init__(self, parent=None, qtapp=None):
        super().__init__(parent)
        self.qtapp = qtapp
        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)

        self.app_manager = AppManager(None, gui_parent=self)
        self.mdi.subWindowActivated.connect(self.app_manager.
                                            on_view_activated)

        self.is_dark = self.light_or_dark(False)

        self.left = 100
        self.top = 50
        self.width = 1800
        self.height = 1200
        self.setGeometry(self.left, self.top, self.width, self.height)

        bar = self.menuBar()

        file_menu = bar.addMenu("File")
        file_menu.addAction("New")
        file_menu.addAction("Open...")
        file_menu.addSeparator()
        file_menu.addAction("Save")
        file_menu.addAction("Save As...")
        file_menu.addAction("Close")
        file_menu.triggered[QAction].connect(self.file_action)

        view_menu = bar.addMenu("Data View")
        view_menu.addAction("Spec Sheet")
        view_menu.addAction("Optical Layout")
        view_menu.addAction("Lens Table")
        view_menu.addAction("Element Table")
        view_menu.addAction("Glass Map")
        # view_menu.addAction("Lens View")
        view_menu.triggered[QAction].connect(self.view_action)

        parax_menu = bar.addMenu("Paraxial Model")
        parax_menu.addAction("Paraxial Model")
        parax_menu.addAction("y-ybar View")
        parax_menu.addAction("nu-nubar View")
        parax_menu.addAction("yui Ray Table")
        parax_menu.addAction("3rd Order Aberrations")
        parax_menu.triggered[QAction].connect(self.view_action)

        analysis_menu = bar.addMenu("Analysis")
        analysis_menu.addAction("Ray Table")
        analysis_menu.addAction("Ray Fans")
        analysis_menu.addAction("OPD Fans")
        analysis_menu.addAction("Spot Diagram")
        analysis_menu.addAction("Wavefront Map")
        analysis_menu.addAction("Astigmatism Curves")
        analysis_menu.triggered[QAction].connect(self.view_action)

        tools_menu = bar.addMenu("Tools")
        tools_menu.addAction("Paraxial Vignetting")
        tools_menu.triggered[QAction].connect(self.view_action)

        wnd_menu = bar.addMenu("Window")
        wnd_menu.addAction("Cascade")
        wnd_menu.addAction("Tiled")
        wnd_menu.addSeparator()
        wnd_menu.addAction("Light UI")
        wnd_menu.addAction("Dark UI")
        wnd_menu.addSeparator()

        dock.create_dock_windows(self)
        for pi in dock.panels.values():
            wnd_menu.addAction(pi.menu_action)

        wnd_menu.triggered[QAction].connect(self.window_action)

        self.setWindowTitle("Ray Optics")
        self.show()

        path = Path(rayoptics.__file__).parent
        self.cur_dir = path / "models"

        if False:
            # create new model
            self.new_model()

        else:
            # restore a default model

            # self.cur_dir = path / "codev/tests"
            # self.open_file(path / "codev/tests/asp46.seq")
            # self.open_file(path / "codev/tests/dar_test.seq")
            # self.open_file(path / "codev/tests/paraboloid.seq")
            # self.open_file(path / "codev/tests/paraboloid_f8.seq")
            # self.open_file(path / "codev/tests/schmidt.seq")
            # self.open_file(path / "codev/tests/questar35.seq")
            # self.open_file(path / "codev/tests/rc_f16.seq")
            # self.open_file(path / "codev/tests/ag_dblgauss.seq")
            # self.open_file(path / "codev/tests/threemir.seq")
            # self.open_file(path / "codev/tests/folded_lenses.seq")
            # self.open_file(path / "codev/tests/lens_reflection_test.seq")
            # self.open_file(path / "codev/tests/dec_tilt_test.seq")
            # self.open_file(path / "codev/tests/landscape_lens.seq")
            # self.open_file(path / "codev/tests/mangin.seq")
            # self.open_file(path / "codev/tests/CODV_32327.seq")
            # self.open_file(path / "codev/tests/dar_test.seq")
            # self.open_file(path / "optical/tests/cell_phone_camera.roa")
            # self.open_file(path / "optical/tests/singlet_f3.roa")

            # self.cur_dir = path / "models"
            # self.open_file(path / "models/Cassegrain.roa")
            # self.open_file(path / "models/collimator.roa")
            # self.open_file(path / "models/Dall-Kirkham.roa")
            # self.open_file(path / "models/petzval.roa")
            # self.open_file(path / "models/Ritchey_Chretien.roa")
            # self.open_file(path / "models/Sasian Triplet.roa")
            # self.open_file(path / "models/singlet_f5.roa")
            # self.open_file(path / "models/thinlens.roa")
            # self.open_file(path / "models/telephoto.roa")
            # self.open_file(path / "models/thin_triplet.roa")
            # self.open_file(path / "models/TwoMirror.roa")
            # self.open_file(path / "models/TwoSphericalMirror.roa")

            self.cur_dir = path / "zemax/tests"
            # self.open_file(path / "zemax/tests/US08427765-1.ZMX")
            # self.open_file(path / "zemax/tests/US00583336-2-scaled.zmx")
            # self.open_file(path / "zemax/tests/HoO-V2C18Ex03.zmx")
            # self.open_file(path / "zemax/tests/HoO-V2C18Ex27.zmx")
            # self.open_file(path / "zemax/tests/HoO-V2C18Ex46.zmx")
            # self.open_file(path / "zemax/tests/HoO-V2C18Ex66.zmx")
            # self.open_file(path / "zemax/tests/US05831776-1.zmx")
            self.open_file(path / "zemax/tests/354710-C-Zemax(ZMX).zmx")

            # self.cur_dir = path / "zemax/models/telescopes"
            # self.open_file(path / "zemax/models/telescopes/Figure4.zmx")
            # self.open_file(path / "zemax/models/telescopes/HoO-V2C18Ex11.zmx")

            # self.cur_dir = path / "zemax/models/PhotoPrime"
            # self.open_file(path / "zemax/models/PhotoPrime/US05321554-4.ZMX")
            # self.open_file(path / "zemax/models/PhotoPrime/US06476982-1.ZMX")
            # self.open_file(path / "zemax/models/PhotoPrime/US07190532-1.ZMX")
            # self.open_file(path / "zemax/models/PhotoPrime/US04331391-1.zmx")
            # self.open_file(path / "zemax/models/PhotoPrime/US05331467-1.zmx")

    def add_subwindow(self, widget, model_info):
        sub_wind = self.mdi.addSubWindow(widget)
        self.app_manager.add_view(sub_wind, widget, model_info)
        MainWindow.count += 1
        return sub_wind

    def delete_subwindow(self, sub_wind):
        self.app_manager.delete_view(sub_wind)
        self.mdi.removeSubWindow(sub_wind)
        MainWindow.count -= 1

    def add_ipython_subwindow(self):
        try:
            create_ipython_console(self, 'iPython console', 800, 600)
        except MultipleInstanceError:
            logging.debug("Unable to open iPython console. "
                          "MultipleInstanceError")
        except Exception as inst:
            print(type(inst))    # the exception instance
            print(inst.args)     # arguments stored in .args
            print(inst)          # __str__ allows args to be printed directly,
            pass                 # but may be overridden in exception subclasses

    def initial_window_offset(self):
        offset_x = 50
        offset_y = 25
        orig_x = (MainWindow.count - 1)*offset_x
        orig_y = (MainWindow.count - 1)*offset_y
        return orig_x, orig_y

    def file_action(self, q):
        if q.text() == "New":
            self.new_model()

        if q.text() == "Open...":
            options = QFileDialog.Options()
            # options |= QFileDialog.DontUseNativeDialog
            fileName, _ = QFileDialog.getOpenFileName(
                          self,
                          "QFileDialog.getOpenFileName()",
                          str(self.cur_dir),
                          "All files (*.seq *.zmx *.roa);;"
                          "CODE V files (*.seq);;"
                          "Ray-Optics files (*.roa);;"
                          "Zemax files (*.zmx)",
                          options=options)
            if fileName:
                logging.debug("open file: %s", fileName)
                filename = Path(fileName)
                self.cur_dir = filename.parent
                self.open_file(filename)

        if q.text() == "Save As...":
            options = QFileDialog.Options()
            # options |= QFileDialog.DontUseNativeDialog
            fileName, _ = QFileDialog.getSaveFileName(
                          self,
                          "QFileDialog.getSaveFileName()",
                          "",
                          "Ray-Optics Files (*.roa);;All Files (*)",
                          options=options)
            if fileName:
                logging.debug("save file: %s", fileName)
                self.save_file(fileName)

        if q.text() == "Close":
            self.close_model()

    def new_model(self):
        iid = cmds.create_new_ideal_imager(gui_parent=self,
                                           conjugate_type='infinite')

        self.add_ipython_subwindow()
        self.refresh_app_ui()

    def open_file(self, file_name, **kwargs):
        self.cur_filename = file_name
        opt_model = cmds.open_model(file_name, **kwargs)
        self.app_manager.set_model(opt_model)
        self.is_changed = True
        self.create_lens_table()
        cmds.create_live_layout_view(self.app_manager.model, gui_parent=self)
        self.add_ipython_subwindow()
        self.refresh_app_ui()

    def save_file(self, file_name):
        self.app_manager.model.save_model(file_name)
        self.cur_filename = file_name
        self.is_changed = False

    def close_model(self):
        """ NOTE: this does not check to save a modified model """
        self.app_manager.close_model(self.delete_subwindow)

    def view_action(self, q):
        opt_model = self.app_manager.model

        if q.text() == "Spec Sheet":
            cmds.create_new_ideal_imager(opt_model=opt_model, gui_parent=self)

        if q.text() == "Optical Layout":
            cmds.create_live_layout_view(opt_model, gui_parent=self)

        if q.text() == "Lens Table":
            self.create_lens_table()

        if q.text() == "Element Table":
            model = cmds.create_element_table_model(opt_model)
            self.create_table_view(model, "Element Table")

        if q.text() == "Glass Map":
            cmds.create_glass_map_view(opt_model, gui_parent=self)

        if q.text() == "Ray Fans":
            cmds.create_ray_fan_view(opt_model, "Ray", gui_parent=self)

        if q.text() == "OPD Fans":
            cmds.create_ray_fan_view(opt_model, "OPD", gui_parent=self)

        if q.text() == "Spot Diagram":
            cmds.create_ray_grid_view(opt_model, gui_parent=self)

        if q.text() == "Wavefront Map":
            cmds.create_wavefront_view(opt_model, gui_parent=self)

        if q.text() == "Astigmatism Curves":
            cmds.create_field_curves(opt_model, gui_parent=self)

        if q.text() == "3rd Order Aberrations":
            cmds.create_3rd_order_bar_chart(opt_model, gui_parent=self)

        if q.text() == "y-ybar View":
            cmds.create_paraxial_design_view_v2(opt_model, 'ht',
                                                gui_parent=self)

        if q.text() == "nu-nubar View":
            cmds.create_paraxial_design_view_v2(opt_model, 'slp',
                                                gui_parent=self)

        if q.text() == "yui Ray Table":
            model = cmds.create_parax_table_model(opt_model)
            self.create_table_view(model, "Paraxial Ray Table")

        if q.text() == "Paraxial Model":
            model = cmds.create_parax_model_table(opt_model)
            self.create_table_view(model, "Paraxial Model")

        if q.text() == "Ray Table":
            self.create_ray_table(opt_model)

        if q.text() == "Paraxial Vignetting":
            trace.apply_paraxial_vignetting(opt_model)
            self.refresh_gui()

    def window_action(self, q):
        if q.text() == "Cascade":
            self.mdi.cascadeSubWindows()

        if q.text() == "Tiled":
            self.mdi.tileSubWindows()

        if q.text() == "Light UI":
            self.is_dark = self.light_or_dark(False)
            self.app_manager.sync_light_or_dark(self.is_dark)

        if q.text() == "Dark UI":
            self.is_dark = self.light_or_dark(True)
            self.app_manager.sync_light_or_dark(self.is_dark)

    def light_or_dark(self, is_dark):
        """ set the UI to a light or dark scheme.

        Qt doesn't seem to support controlling the MdiArea's background from a
        style sheet. Set the widget directly and save the original color
        to reset defaults.
        """
        if not hasattr(self, 'mdi_background'):
            self.mdi_background = self.mdi.background()

        if is_dark:
            self.qtapp.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
            rgb = DarkPalette.color_palette()
            self.mdi.setBackground(QColor(rgb['COLOR_BACKGROUND_NORMAL']))
        else:
            self.qtapp.setStyleSheet('')
            self.mdi.setBackground(self.mdi_background)
        return is_dark

    def create_lens_table(self):
        seq_model = self.app_manager.model.seq_model

        def set_stop_surface(stop_surface):
            seq_model.stop_surface = stop_surface
            self.refresh_gui()

        def handle_context_menu(point):
            try:
                vheader = view.verticalHeader()
                row = vheader.logicalIndexAt(point.y())
            except NameError:
                pass
            else:
                # show menu about the row
                menu = QMenu(self)
                if row != seq_model.stop_surface:
                    menu.addAction('Set Stop Surface',
                                   lambda: set_stop_surface(row))
                if seq_model.stop_surface is not None:
                    menu.addAction('Float Stop Surface',
                                   lambda: set_stop_surface(None))
                menu.popup(vheader.mapToGlobal(point))

        model = cmds.create_lens_table_model(seq_model)
        view = self.create_table_view(model, "Surface Data Table")
        vheader = view.verticalHeader()
        vheader.setContextMenuPolicy(qt.CustomContextMenu)
        vheader.customContextMenuRequested.connect(handle_context_menu)

    def create_ray_table(self, opt_model):
        osp = opt_model.optical_spec
        pupil = [0., 1.]
        fi = 0
        wl = osp.spectral_region.reference_wvl
        fld, wvl, foc = osp.lookup_fld_wvl_focus(fi, wl)
        ray, ray_op, wvl = trace.trace_base(opt_model, pupil, fld, wvl)
#        ray, ray_op, wvl, opd = trace.trace_with_opd(opt_model, pupil,
#                                                     fld, wvl, foc)

#        cr = trace.RayPkg(ray, ray_op, wvl)
#        s, t = trace.trace_coddington_fan(opt_model, cr, foc)

        ray = [RaySeg(*rs) for rs in ray]
        model = cmds.create_ray_table_model(opt_model, ray)
        self.create_table_view(model, "Ray Table")

    def create_table_view(self, table_model, table_title, close_callback=None):
        # construct the top level widget
        widget = QWidget()
        # construct the top level layout
        layout = QVBoxLayout(widget)

        table_view = TableView(table_model)
        table_view.setAlternatingRowColors(True)

        # Add table to box layout
        layout.addWidget(table_view)

        # set the layout on the widget
        widget.setLayout(layout)

        sub = self.add_subwindow(widget, ModelInfo(self.app_manager.model,
                                                   cmds.update_table_view,
                                                   (table_view,)))
        sub.setWindowTitle(table_title)

        sub.installEventFilter(self)

        table_view.setMinimumWidth(table_view.horizontalHeader().length() +
                                   table_view.horizontalHeader().height())
#                                  The following line should work but returns 0
#                                  table_view.verticalHeader().width())

        view_width = table_view.width()
        view_ht = table_view.height()
        orig_x, orig_y = self.initial_window_offset()
        sub.setGeometry(orig_x, orig_y, view_width, view_ht)

        # table data updated successfully
        table_model.update.connect(self.on_data_changed)

        sub.show()

        return table_view

    def eventFilter(self, obj, event):
        """Used by table_view in response to installEventFilter."""
        if (event.type() == QEvent.Close):
            print('close event received:', obj)
        return False

    def refresh_gui(self, **kwargs):
        self.app_manager.refresh_gui(**kwargs)

    def refresh_app_ui(self):
        dock.update_dock_windows(self)

    def handle_ideal_imager_command(self, iid, command, specsheet):
        ''' link Ideal Imager Dialog buttons to model actions
        iid: ideal imager dialog
        command: text field with the action - same as button label
        specsheet: the input specsheet used to drive the actions
        '''
        if command == 'Apply':
            opt_model = self.app_manager.model
            opt_model.set_from_specsheet(specsheet)
            self.refresh_gui()
        elif command == 'Close':
            for view, info in self.app_manager.view_dict.items():
                if iid == info[0]:
                    self.delete_subwindow(view)
                    view.close()
                    break
        elif command == 'Update':
            opt_model = self.app_manager.model
            specsheet = opt_model.specsheet
            firstorder.specsheet_from_parax_data(opt_model, specsheet)
            iid.specsheet_dict[specsheet.conjugate_type] = specsheet
            iid.update_values()
        elif command == 'New':
            opt_model = cmds.create_new_optical_model_from_specsheet(specsheet)
            self.app_manager.set_model(opt_model)
            for view, info in self.app_manager.view_dict.items():
                if iid == info[0]:
                    w = iid
                    mi = info[1]
                    args = (iid, opt_model)
                    new_mi = ModelInfo(model=opt_model, fct=mi.fct,
                                       args=args, kwargs=mi.kwargs)
                    self.app_manager.view_dict[view] = w, new_mi
            self.refresh_gui()
            self.create_lens_table()
            cmds.create_live_layout_view(opt_model, gui_parent=self)
            cmds.create_paraxial_design_view_v2(opt_model, 'ht',
                                                gui_parent=self)
            self.refresh_gui()

    @pyqtSlot(object, int)
    def on_data_changed(self, rootObj, index):
        self.refresh_gui()
Пример #3
0
class MSCollection(QMainWindow):
    """
    Class of the main window and that also manages the display of all other
    windows.
    """
    def __init__(self):
        super(MSCollection, self).__init__()

        css = 'styles/style.qss'
        with open(css, 'r') as fh:
            self.setStyleSheet(fh.read())

        self.setWindowTitle(texts.main_widow)
        screen = QDesktopWidget().screenGeometry()
        s_width = screen.width()
        s_heigth = screen.height()
        x = int(0.10 * s_width)
        y = int(0.10 * s_heigth)
        width = int(0.8 * s_width)
        height = int(0.8 * s_heigth)

        self.setGeometry(x, y, width, height)

        self.mdi_area = QMdiArea()
        brush = QBrush(QColor(250, 248, 224))
        brush.setStyle(Qt.SolidPattern)
        self.mdi_area.setBackground(brush)

        self.setCentralWidget(self.mdi_area)
        self.menubar = QMenuBar(self)

        self.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)

        # Menu and Submenu
        self.menu_insert = QMenu(self.menubar)
        self.menu_insert.setTitle(texts.insert)

        self.menu_edit = QMenu(self.menubar)
        self.menu_edit.setTitle(texts.edit)
        self.menu_edit_movie_others = QMenu(self.menu_edit)
        self.menu_edit_movie_others.setTitle(texts.menu_movie_others)
        self.menu_edit_series_others = QMenu(self.menu_edit)
        self.menu_edit_series_others.setTitle(texts.menu_series_others)
        self.menu_edit_season = QMenu(self.menu_edit)
        self.menu_edit_season.setTitle(texts.season_p)
        self.menu_edit_general = QMenu(self.menu_insert)
        self.menu_edit_general.setTitle(texts.general)
        self.menu_delete_orphans = QMenu(texts.delete_orphans)

        self.menu_search = QMenu(self.menubar)
        self.menu_search.setTitle(texts.search)
        self.menu_search_movies = QMenu(self.menu_search)
        self.menu_search_movies.setTitle(texts.movie_p)
        self.menu_search_series = QMenu(self.menu_search)
        self.menu_search_series.setTitle(texts.series_p)

        # Actions Insert ######################################################
        self.action_insert_movie = QAction(texts.movie_p,
                                           self,
                                           triggered=self.insert_movie)

        self.action_insert_series = QAction(texts.series_p,
                                            self,
                                            triggered=self.insert_series)

        self.action_insert_season = QAction(texts.season_p,
                                            self,
                                            triggered=self.insert_season)

        # AddAction Insert
        self.menu_insert.addAction(self.action_insert_movie)
        self.menu_insert.addAction(self.action_insert_series)
        self.menu_insert.addAction(self.action_insert_season)

        # Actions Edit ######################################################
        self.action_edit_movie = QAction(texts.movie_p,
                                         self,
                                         triggered=self.edit_movie)

        self.action_edit_series = QAction(texts.series_p,
                                          self,
                                          triggered=self.edit_series)

        self.action_edit_season = QAction(texts.season_p,
                                          self,
                                          triggered=self.edit_season)

        self.action_edit_rewrite_html = QAction(texts.rewrite_html,
                                                self,
                                                triggered=self.rewrite_html)

        self.action_edit_movie_cast = QAction(texts.cast_s,
                                              self,
                                              triggered=self.edit_movie_cast)

        self.action_edit_series_cast = QAction(texts.cast_s,
                                               self,
                                               triggered=self.edit_series_cast)

        self.action_edit_director = QAction(texts.director_s,
                                            self,
                                            triggered=self.edit_director)

        self.action_edit_creator = QAction(texts.creator_s,
                                           self,
                                           triggered=self.edit_creator)

        self.action_edit_box = QAction(texts.box, self)
        self.action_edit_box.triggered.connect(lambda: self.edit_others('box'))

        self.action_edit_category = QAction(texts.category_p, self)
        self.action_edit_category.triggered.connect(
            lambda: self.edit_others('category'))

        self.action_edit_media = QAction(texts.media_s, self)
        self.action_edit_media.triggered.connect(
            lambda: self.edit_others('media'))

        self.action_edit_actor = QAction(texts.actor_s, self)
        self.action_edit_actor.triggered.connect(
            lambda: self.edit_others('actor'))

        self.action_edit_character = QAction(texts.character_s, self)
        self.action_edit_character.triggered.connect(
            lambda: self.edit_others('character'))

        self.action_edit_keyword = QAction(texts.keyword, self)
        self.action_edit_keyword.triggered.connect(
            lambda: self.edit_others('keyword'))

        text = texts.season_s + ' ' + texts.cast_s
        self.action_edit_season_cast = QAction(text,
                                               self,
                                               triggered=self.edit_season_cast)

        # AddAction Edit
        self.menu_edit.addAction(self.action_edit_movie)
        self.menu_edit.addAction(self.menu_edit_movie_others.menuAction())
        self.menu_edit_movie_others.addAction(self.action_edit_movie_cast)
        self.menu_edit_movie_others.addAction(self.action_edit_director)
        self.menu_edit_movie_others.addAction(self.action_edit_box)

        self.menu_edit.addAction(self.action_edit_series)
        self.menu_edit.addAction(self.menu_edit_series_others.menuAction())
        self.menu_edit_series_others.addAction(self.action_edit_series_cast)
        self.menu_edit_series_others.addAction(self.action_edit_creator)

        self.menu_edit.addAction(self.menu_edit_general.menuAction())
        self.menu_edit_general.addAction(self.action_edit_category)
        self.menu_edit_general.addAction(self.action_edit_media)
        self.menu_edit_general.addAction(self.action_edit_actor)
        self.menu_edit_general.addAction(self.action_edit_character)
        self.menu_edit_general.addAction(self.action_edit_keyword)

        self.menu_edit.addAction(self.action_edit_season)
        self.menu_edit.addAction(self.action_edit_season_cast)

        # Actions Search ######################################################
        self.actions_view_movie_web_url = QAction(
            texts.lb_url, self, triggered=self.view_movie_web_url)

        self.actions_view_series_web_url = QAction(
            texts.lb_url, self, triggered=self.view_series_web_url)

        self.actions_search_movie_box = QAction(
            texts.box, self, triggered=self.search_movie_box)

        self.actions_search_movie_title = QAction(texts.title_p, self)
        self.actions_search_movie_title.triggered.connect(
            lambda: self.search_ms_title('movie'))

        self.actions_search_series_title = QAction(texts.title_p, self)
        self.actions_search_series_title.triggered.connect(
            lambda: self.search_ms_title('series'))

        self.actions_search_movie_category = QAction(texts.category_p, self)
        self.actions_search_movie_category.triggered.connect(
            lambda: self.search_ms_category('movie'))

        self.actions_search_series_category = QAction(texts.category_p, self)
        self.actions_search_series_category.triggered.connect(
            lambda: self.search_ms_category('series'))

        self.actions_search_movie_keyword = QAction(texts.keyword, self)
        self.actions_search_movie_keyword.triggered.connect(
            lambda: self.search_ms_keyword('movie'))

        self.actions_search_series_keyword = QAction(texts.keyword, self)
        self.actions_search_series_keyword.triggered.connect(
            lambda: self.search_ms_keyword('series'))

        text = texts.media_s + '/' + texts.year_s
        self.actions_search_movie_my = QAction(text, self)
        self.actions_search_movie_my.triggered.connect(
            lambda: self.search_ms_my('movie'))

        self.actions_search_series_my = QAction(text, self)
        self.actions_search_series_my.triggered.connect(
            lambda: self.search_ms_my('series'))

        # AddAction Search
        self.menu_search_movies.addAction(self.actions_search_movie_title)
        self.menu_search_movies.addAction(self.actions_search_movie_box)
        self.menu_search_movies.addAction(self.actions_search_movie_category)
        self.menu_search_movies.addAction(self.actions_search_movie_keyword)
        self.menu_search_movies.addAction(self.actions_search_movie_my)

        self.menu_search_series.addAction(self.actions_search_series_title)
        self.menu_search_series.addAction(self.actions_search_series_category)
        self.menu_search_series.addAction(self.actions_search_series_keyword)
        self.menu_search_series.addAction(self.actions_search_series_my)

        self.menu_search.addAction(self.menu_search_movies.menuAction())
        self.menu_search.addAction(self.menu_search_series.menuAction())

        # Actions Delete Orphans ##############################################
        self.action_delete_orphans_director = QAction(
            texts.director_p, self, triggered=self.delete_orphans_director)

        self.action_delete_orphans_creator = QAction(
            texts.creator_p, self, triggered=self.delete_orphans_creator)

        self.action_delete_orphans_cast = QAction(
            texts.cast_p, self, triggered=self.delete_orphans_cast)

        self.action_delete_orphans_actors = QAction(
            texts.actor_p, self, triggered=self.delete_orphans_actors)

        self.action_delete_orphans_character = QAction(
            texts.character_p, self, triggered=self.delete_orphans_character)

        self.action_delete_orphans_media = QAction(
            texts.media_p, self, triggered=self.delete_orphans_media)

        self.action_delete_orphans_category = QAction(
            texts.category_p, self, triggered=self.delete_orphans_category)

        # AddAction Search
        self.menu_delete_orphans.addAction(self.action_delete_orphans_director)
        self.menu_delete_orphans.addAction(self.action_delete_orphans_creator)
        self.menu_delete_orphans.addAction(self.action_delete_orphans_cast)
        self.menu_delete_orphans.addAction(self.action_delete_orphans_actors)
        self.menu_delete_orphans.addAction(
            self.action_delete_orphans_character)
        self.menu_delete_orphans.addAction(self.action_delete_orphans_media)
        self.menu_delete_orphans.addAction(self.action_delete_orphans_category)

        self.menu_edit.addAction(self.menu_delete_orphans.menuAction())
        self.menu_edit.addAction(self.action_edit_rewrite_html)

        # AddAction Menu ######################################################
        self.menubar.addAction(self.menu_insert.menuAction())
        self.menubar.addAction(self.menu_edit.menuAction())
        self.menubar.addAction(self.menu_search.menuAction())

    """
    All methods below is for open subwindows
    """

    def insert_movie(self):
        subwindow = InsertMovie(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def insert_series(self):
        subwindow = InsertSeries(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def insert_season(self):
        subwindow = InsertSeason(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_movie(self):
        subwindow = EditMovie(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_series(self):
        subwindow = EditSeries(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_season(self):
        subwindow = EditSeason(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def rewrite_html(self):
        subwindow = RewriteHtml(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_movie_cast(self):
        subwindow = EditCast(self, 'movie')
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_series_cast(self):
        subwindow = EditCast(self, 'series')
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_season_cast(self):
        subwindow = EditSeasonCast(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_director(self):
        subwindow = EditDirector(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_creator(self):
        subwindow = EditCreator(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def edit_others(self, op):
        subwindow = EditOthers(self, op)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def view_html(self, url, title):
        subwindow = ViewSelectTitle(self, url, title)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def search_movie_box(self, type):
        subwindow = SearchMovieBox(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def search_ms_title(self, type):
        subwindow = SearchMSTitle(self, type)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def search_ms_category(self, type):
        subwindow = SearchMSCategory(self, type)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def search_ms_keyword(self, type):
        subwindow = SearchMSKeyword(self, type)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def search_ms_my(self, type):
        subwindow = SearchMSMediaYear(self, type)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def view_movie_web_url(self):
        subwindow = ViewMovieUrl(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def view_series_web_url(self):
        subwindow = ViewSeriesUrl(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def view_movie_search_url(self):
        subwindow = ViewMovieSearchUrl(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def view_series_search_url(self):
        subwindow = ViewSeriesSearchUrl(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def delete_orphans_director(self):
        subwindow = DeleteOrphansDirector(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def delete_orphans_creator(self):
        subwindow = DeleteOrphansCreator(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def delete_orphans_cast(self):
        subwindow = DeleteOrphansCast(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def delete_orphans_actors(self):
        subwindow = DeleteOrphansActor(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def delete_orphans_character(self):
        subwindow = DeleteOrphansCharacter(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def delete_orphans_category(self):
        subwindow = DeleteOrphansCategory(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def delete_orphans_media(self):
        subwindow = DeleteOrphansMedia(self)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()

    def views_help(self, url, title):
        subwindow = ViewsHelp(self, url, title)
        self.mdi_area.addSubWindow(subwindow)
        subwindow.show()