コード例 #1
0
ファイル: caselist.py プロジェクト: oyvindeide/ert
class CaseList(QWidget):
    def __init__(self, facade: LibresFacade, notifier: ErtNotifier):
        self.facade = facade
        self.notifier = notifier
        QWidget.__init__(self)

        addHelpToWidget(self, "init/case_list")

        layout = QVBoxLayout()

        self._list = QListWidget(self)
        self._list.setMinimumHeight(100)
        self._list.setMaximumHeight(250)
        self._default_selection_mode = self._list.selectionMode()
        self.setSelectable(False)

        layout.addWidget(QLabel("Available cases:"))
        layout.addWidget(self._list)

        self._addRemoveWidget = AddRemoveWidget(self.addItem,
                                                self.removeItem,
                                                horizontal=True)
        self._addRemoveWidget.enableRemoveButton(False)
        layout.addWidget(self._addRemoveWidget)

        self._title = "New keyword"
        self._description = "Enter name of keyword:"

        self.setLayout(layout)

        notifier.ertChanged.connect(self.updateList)
        self.updateList()

    def setSelectable(self, selectable):
        if selectable:
            self._list.setSelectionMode(self._default_selection_mode)
        else:
            self._list.setSelectionMode(QAbstractItemView.NoSelection)

    def addItem(self):
        dialog = ValidatedDialog("New case", "Enter name of new case:",
                                 getAllCases(self.facade))
        new_case_name = dialog.showAndTell()
        if not new_case_name == "":
            self.facade.select_or_create_new_case(new_case_name)
            self.notifier.ertChanged.emit()

    def removeItem(self):
        message = "Support for removal of items has not been implemented!"
        QMessageBox.information(self, "Not implemented!", message)

    def updateList(self):
        """Retrieves data from the model and inserts it into the list"""
        case_list = getAllCases(self.facade)

        self._list.clear()

        for case in case_list:
            self._list.addItem(case)
コード例 #2
0
class MainWindow(QMainWindow):
    def selectFileToOpen(self):
        def getPreProcessingChoice(self, filename, filestructure):
            items = ("Choose the longest", "Merge all")
            item, okPressed = QInputDialog.getItem(
                self, "Multiple tracks/segments", "File '" + filename +
                "' contains more than one track/segment\n\n" + infos +
                "\nWhat to do?", items, 0, False)
            if okPressed and item:
                return items.index(item)
            else:
                return 0

        # Try to recover the last used directory
        old_directory = self.settings.value("lastdirectory", str)

        # Check if the setting exists
        if old_directory is not None:
            # Check if it's not empty
            if old_directory:
                old_directory = old_directory
            else:
                old_directory = bombo.TRACKS_FOLDER
        else:
            old_directory = bombo.TRACKS_FOLDER

        # Open the dialog box
        fullfilename_list = QFileDialog.getOpenFileNames(
            self, 'Open .gpx', old_directory, "GPX files (*.gpx)")
        if os.environ['QT_API'] == 'pyqt':
            pass
        elif os.environ['QT_API'] == 'pyqt5':
            fullfilename_list = fullfilename_list[0]

        # Process every selected file
        for i, fullfilename in enumerate(fullfilename_list):
            # Process filename
            directory, filename = os.path.split(str(fullfilename))
            filename, fileextension = os.path.splitext(filename)

            # Save the new directory in the application settings (it only
            # needs to be done once)
            if i == 0:
                # print "New directory to be saved: {}\n".format(directory)
                if os.environ['QT_API'] == 'pyqt':
                    self.settings.setValue("lastdirectory", str(directory))
                elif os.environ['QT_API'] == 'pyqt5':
                    self.settings.setValue("lastdirectory",
                                           QtCore.QVariant(str(directory)))

            # Open file and inspect what's inside
            gpxraw, longest_traseg, Ntracks, Nsegments, infos = bombo.LoadGPX(
                fullfilename)

            # If there's more than one track or segment, ask how to proceed
            if (Ntracks > 1) or (Nsegments > 1):
                preprocessingchoice = getPreProcessingChoice(
                    self, filename, infos)
                if preprocessingchoice == 0:
                    preprocessedgpx = bombo.SelectOneTrackAndSegmentFromGPX(
                        gpxraw, longest_traseg[0], longest_traseg[1])
                    listname = filename + " (longest)"
                elif preprocessingchoice == 1:
                    preprocessedgpx = bombo.MergeAllTracksAndSegmentsFromGPX(
                        gpxraw)
                    listname = filename + " (merged)"
            else:
                preprocessedgpx = gpxraw
                listname = filename

            # Append the list of open GPX files using the next available color (that's the size of the list -1)
            self.gpxlist.append(preprocessedgpx)
            self.gpxnamelist.append(listname)
            newitem = QListWidgetItem(listname)
            newitem.setBackground(
                QtGui.QColor(self.palette[len(self.gpxlist) - 1]))
            self.tracklist.addItem(newitem)

        return

    def Go(self):
        if len(self.gpxselectedlist) > 0:
            # Temporarily change cursor
            QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)

            # Clear up global variables
            self.proc_coords = []
            self.proc_measurements = []
            self.proc_state_means = []
            self.proc_state_vars = []
            self.proc_new_coords = []
            self.proc_new_gpx = []
            self.proc_coords_to_plot = []
            self.proc_coords_to_plot2 = []
            self.proc_balloondata = []

            # For every GPX file that is selected
            self.textWarningConsole.clear()
            for i, currentgpx in enumerate(self.gpxselectedlist):
                # Parse the GPX file
                gpx, coords, dinfos_before, warnings = bombo.ParseGPX(
                    currentgpx,
                    track_nr=0,
                    segment_nr=0,
                    use_srtm_elevation=bool(self.checkUseSRTM.isChecked()))
                self.textWarningConsole.append(warnings)

                # Kalman processing
                coords, measurements, state_means, state_vars, dinfos_during = bombo.ApplyKalmanFilter(
                    coords,
                    gpx,
                    method=self.comboBoxProcessingMethod.currentIndex(),
                    use_acceleration=self.checkUseAcceleration.isChecked(),
                    extra_smooth=self.checkExtraSmooth.isChecked(),
                    debug_plot=False)

                # Save data in GPX structure to compute speed and elevations
                new_coords, new_gpx, dinfos_after = bombo.SaveDataToCoordsAndGPX(
                    coords, state_means)

                # Update GUI with the computed stats
                parent = QtGui.QStandardItem(self.gpxselectednamelist[i])

                parent_beforeprocessing = QtGui.QStandardItem("Raw GPX stats")
                parent_beforeprocessing.appendRow([
                    QtGui.QStandardItem("Total distance"),
                    QtGui.QStandardItem(dinfos_before['total_distance'])
                ])
                parent_beforeprocessing_moving = QtGui.QStandardItem("Moving")
                parent_beforeprocessing_moving.appendRow([
                    QtGui.QStandardItem("Time"),
                    QtGui.QStandardItem(dinfos_before['moving_time'])
                ])
                parent_beforeprocessing_moving.appendRow([
                    QtGui.QStandardItem("Distance"),
                    QtGui.QStandardItem(dinfos_before['moving_distance'])
                ])
                parent_beforeprocessing.appendRow(
                    parent_beforeprocessing_moving)
                parent_beforeprocessing_idle = QtGui.QStandardItem("Idle")
                parent_beforeprocessing_idle.appendRow([
                    QtGui.QStandardItem("Time"),
                    QtGui.QStandardItem(dinfos_before['idle_time'])
                ])
                parent_beforeprocessing_idle.appendRow([
                    QtGui.QStandardItem("Distance"),
                    QtGui.QStandardItem(dinfos_before['idle_distance'])
                ])
                parent_beforeprocessing.appendRow(parent_beforeprocessing_idle)
                parent_beforeprocessing.appendRow([
                    QtGui.QStandardItem("Elevation"),
                    QtGui.QStandardItem(dinfos_before['elevation'])
                ])
                parent_beforeprocessing.appendRow([
                    QtGui.QStandardItem("Climb"),
                    QtGui.QStandardItem(dinfos_before['climb'])
                ])
                parent.appendRow(parent_beforeprocessing)

                parent.appendRow([
                    QtGui.QStandardItem("Samples"),
                    QtGui.QStandardItem(dinfos_during['nsamples'])
                ])
                parent.appendRow([
                    QtGui.QStandardItem("Total distance"),
                    QtGui.QStandardItem(dinfos_after['total_distance'])
                ])
                parent_moving = QtGui.QStandardItem("Moving")
                parent_moving.appendRow([
                    QtGui.QStandardItem("Time"),
                    QtGui.QStandardItem(dinfos_after['moving_time'])
                ])
                parent_moving.appendRow([
                    QtGui.QStandardItem("Distance"),
                    QtGui.QStandardItem(dinfos_after['moving_distance'])
                ])
                parent.appendRow(parent_moving)
                parent_idle = QtGui.QStandardItem("Idle")
                parent_idle.appendRow([
                    QtGui.QStandardItem("Time"),
                    QtGui.QStandardItem(dinfos_after['idle_time'])
                ])
                parent_idle.appendRow([
                    QtGui.QStandardItem("Distance"),
                    QtGui.QStandardItem(dinfos_after['idle_distance'])
                ])
                parent.appendRow(parent_idle)
                parent.appendRow([
                    QtGui.QStandardItem("Elevation"),
                    QtGui.QStandardItem(dinfos_after['elevation'])
                ])
                parent.appendRow([
                    QtGui.QStandardItem("Climb"),
                    QtGui.QStandardItem(dinfos_after['climb'])
                ])
                self.treemodel.appendRow(parent)

                # Create balloondata for the html plot
                balloondata = {
                    'distance':
                    np.cumsum(
                        bombo.HaversineDistance(np.asarray(new_coords['lat']),
                                                np.asarray(
                                                    new_coords['lon']))),
                    'elevation':
                    np.asarray(new_coords['ele']),
                    'speed':
                    None
                }

                # Create extra data for the html plot (fully implemented in bombo, not here)
                """
                data = np.ones((len(lat_cleaned),2))
                data[:,0] = h_filtered / np.max(h_filtered) * 0.0004
                data[:,1] = np.hstack((np.asarray([0]), speed_h)) / np.max(np.hstack((np.asarray([0]), speed_h))) * 0.0004
                tangentdata = {'data': data,
                               'sides': (0, 1),
                               'palette': ('blue','red')}
                """

                # Save relevant output in global variables
                self.proc_coords.append(coords)
                self.proc_measurements.append(measurements)
                self.proc_state_means.append(state_means)
                self.proc_state_vars.append(state_vars)
                self.proc_new_coords.append(new_coords)
                self.proc_new_gpx.append(new_gpx)
                self.proc_coords_to_plot.append(
                    np.vstack((new_coords['lat'], new_coords['lon'])).T)
                self.proc_coords_to_plot2.append(
                    np.vstack((coords['lat'], coords['lon'])).T)
                self.proc_balloondata.append(balloondata)

            # Restore original cursor
            QApplication.restoreOverrideCursor()

            # Generate embedded plots
            if len(self.gpxselectedlist) == 1:
                self.plotEmbeddedElevationAndSpeed.update_figure(
                    measurements, state_means, new_gpx.tracks[0].segments[0])
                self.plotEmbeddedDetails.update_figure(
                    measurements, state_means, state_vars,
                    new_gpx.tracks[0].segments[0])
            else:
                # Commentato per adesso
                # self.plotEmbeddedElevationAndSpeed.update_figure_multiple_tracks(self.proc_measurements, self.proc_state_means, self.proc_new_gpx)
                self.plotEmbeddedElevationAndSpeed.clear_figure()
                self.plotEmbeddedDetails.clear_figure()

            # Generate html plot, if only one track is selected, proceed with the complete output, otherwise just plot the traces
            if len(self.gpxselectedlist) is 1:
                bombo.PlotOnMap(
                    coords_array_list=self.proc_coords_to_plot,
                    coords_array2_list=self.proc_coords_to_plot2,
                    coords_palette=self.selectedpalette,
                    tangentdata=None,
                    balloondata_list=self.proc_balloondata,
                    rdp_reduction=self.checkUseRDP.isChecked(),
                    showmap=bool(self.check2DMapInExternalBrowser.isChecked()))
            else:
                bombo.PlotOnMap(
                    coords_array_list=self.proc_coords_to_plot,
                    coords_array2_list=None,
                    coords_palette=self.selectedpalette,
                    tangentdata=None,
                    balloondata_list=self.proc_balloondata,
                    rdp_reduction=self.checkUseRDP.isChecked(),
                    showmap=bool(self.check2DMapInExternalBrowser.isChecked()))

            self.map2d.load(QtCore.QUrl(bombo.MAP_2D_FILENAME))
            self.map2d.show()

            # Generate 3D plot, only with one track for the moment
            if len(self.gpxselectedlist) == 1:
                if self.check3DMapSelection.isChecked():
                    tile_selection = 'auto'
                else:
                    tile_selection = self.text3DMapName.text()
                terrain, track, warnings = bombo.Generate3DMap(
                    new_coords['lat'],
                    new_coords['lon'],
                    tile_selection=tile_selection,
                    margin=self.spinbox3DMargin.value(),
                    elevation_scale=self.spinbox3DElevationScale.value(),
                    mapping='coords',
                    use_osm_texture=True,
                    texture_type='osm',
                    texture_zoom=self.spinbox3DOSMZoom.value(),
                    texture_invert=self.check3DOSMInvert.isChecked(),
                    use_proxy=self.use_proxy,
                    proxy_data=self.proxy_config,
                    verbose=False)

                self.textWarningConsole.append(warnings)

                if terrain is not None:
                    self.map3d.update_plot(terrain, track)

        else:
            self.textWarningConsole.setText(
                "You need to open a .gpx file before!")
        return

    def PlotSpecificAreaDialog(self):
        def PlotSpecificArea():
            # Save coordinates for the next time
            if os.environ['QT_API'] == 'pyqt':
                self.settings.setValue("last_point_coord_lat",
                                       self.spinboxLatDec.value())
                self.settings.setValue("last_point_coord_lon",
                                       self.spinboxLonDec.value())
            elif os.environ['QT_API'] == 'pyqt5':
                self.settings.setValue(
                    "last_point_coord_lat",
                    QtCore.QVariant(self.spinboxLatDec.value()))
                self.settings.setValue(
                    "last_point_coord_lon",
                    QtCore.QVariant(self.spinboxLonDec.value()))

            # Select the 3D Map tab
            self.tab.setCurrentIndex(2)

            # Plot
            if self.check3DMapSelection.isChecked():
                tile_selection = 'auto'
            else:
                tile_selection = self.text3DMapName.text()

            terrain, track, warnings = bombo.Generate3DMap(
                [self.spinboxLatDec.value()], [self.spinboxLonDec.value()],
                tile_selection=tile_selection,
                margin=self.spinbox3DMargin.value(),
                elevation_scale=self.spinbox3DElevationScale.value(),
                mapping='coords',
                use_osm_texture=True,
                texture_type='osm',
                texture_zoom=self.spinbox3DOSMZoom.value(),
                texture_invert=self.check3DOSMInvert.isChecked(),
                use_proxy=self.use_proxy,
                proxy_data=self.proxy_config,
                verbose=False)

            self.textWarningConsole.append(warnings)

            if terrain is not None:
                self.map3d.update_plot(terrain, track)
            d.done(0)

        def Convert():
            try:
                dd = bombo.parse_dms(self.textLatLonGMS.text())
                self.spinboxLatDec.setValue(dd[0])
                self.spinboxLonDec.setValue(dd[1])
            except:
                pass

        d = QDialog()
        grid = QGridLayout()

        hBox_coordsGMS = QHBoxLayout()
        hBox_coordsGMS.setSpacing(5)
        label = QLabel('Coordinates (gms)')
        grid.addWidget(label, 0, 0)
        self.textLatLonGMS = QLineEdit()
        self.textLatLonGMS.setText("")
        grid.addWidget(self.textLatLonGMS, 0, 1, 1, 2)

        button1 = QPushButton("Convert to decimal")
        button1.clicked.connect(Convert)
        grid.addWidget(button1, 0, 3)

        label = QLabel('Coordinates (decimal)')
        grid.addWidget(label, 1, 0)
        self.spinboxLatDec = QDoubleSpinBox()
        self.spinboxLatDec.setRange(-90, +90)
        self.spinboxLatDec.setSingleStep(0.0000001)
        self.spinboxLatDec.setDecimals(7)
        grid.addWidget(self.spinboxLatDec, 1, 1)
        self.spinboxLonDec = QDoubleSpinBox()
        self.spinboxLonDec.setRange(-180, +180)
        self.spinboxLonDec.setSingleStep(0.0000001)
        self.spinboxLonDec.setDecimals(7)
        grid.addWidget(self.spinboxLonDec, 1, 2)

        # Try to recover the last used points
        try:
            old_lat = self.settings.value("last_point_coord_lat", type=float)
            old_lon = self.settings.value("last_point_coord_lon", type=float)
            self.spinboxLatDec.setValue(old_lat)
            self.spinboxLonDec.setValue(old_lon)
        except:
            # Coordinates of Mt. Rinjani in Indonesia
            self.spinboxLatDec.setValue(-8.4166000)
            self.spinboxLonDec.setValue(116.4666000)

        button2 = QPushButton("Show 3D map")
        button2.clicked.connect(PlotSpecificArea)
        grid.addWidget(button2, 1, 3)

        d.setWindowTitle("Show point on 3D map")
        d.setLayout(grid)
        d.setWindowModality(QtCore.Qt.ApplicationModal)
        d.exec_()

    def ProxyDialog(self):
        def SetProxy():
            self.use_proxy = bool(self.checkUseProxy.isChecked())
            self.proxy_config = self.textProxyConfig.text()

            if os.environ['QT_API'] == 'pyqt':
                self.settings.setValue("use_proxy", self.use_proxy)
                self.settings.setValue("proxy_config", str(self.proxy_config))
            elif os.environ['QT_API'] == 'pyqt5':
                self.settings.setValue("use_proxy",
                                       QtCore.QVariant(self.use_proxy))
                self.settings.setValue("proxy_config",
                                       QtCore.QVariant(str(self.proxy_config)))

            d.done(0)

        d = QDialog()

        box = QVBoxLayout()

        hBox_proxy = QHBoxLayout()
        hBox_proxy.setSpacing(5)
        label = QLabel('Proxy')
        hBox_proxy.addWidget(label)
        self.textProxyConfig = QLineEdit()
        try:
            self.textProxyConfig.setText(
                self.settings.value('proxy_config', str))
        except:
            self.textProxyConfig.setText(bombo.PROXY_DATA)
        self.textProxyConfig.setMinimumWidth(200)
        hBox_proxy.addWidget(self.textProxyConfig)
        box.addLayout(hBox_proxy)

        self.checkUseProxy = QCheckBox("Use proxy")
        try:
            self.checkUseProxy.setChecked(
                self.settings.value('use_proxy', bool))
        except:
            self.checkUseProxy.setChecked(bool(bombo.USE_PROXY))
        box.addWidget(self.checkUseProxy)

        button = QPushButton("Save configuration")
        button.clicked.connect(SetProxy)
        box.addWidget(button)

        d.setWindowTitle("Proxy configuration")
        d.setLayout(box)
        d.setWindowModality(QtCore.Qt.ApplicationModal)
        d.exec_()

    def __init__(self, parent=None):
        super(MainWindow, self).__init__()
        self.initVariables()
        self.initUI()

    def initVariables(self):
        self.gpxlist = list()
        self.gpxnamelist = list()
        self.gpxselectedlist = list()
        self.gpxselectednamelist = list()
        self.palette = bombo.GeneratePalette(N=10) * 5  # replicated 5 times
        #self.palette = ["#0000FF", "#00FF00", "#00FFFF", "#FF0000", "#FF00FF", "#FFFF00", "#FFFFFF"] # test palette
        self.selectedpalette = list()

        self.proc_coords = list()
        self.proc_measurements = list()
        self.proc_state_means = list()
        self.proc_state_vars = list()
        self.proc_new_coords = list()
        self.proc_new_gpx = list()
        self.proc_coords_to_plot = list()
        self.proc_coords_to_plot2 = list()
        self.proc_balloondata = list()

    def initUI(self):
        def selection_changed():
            # Retrieve selected items
            # selecteditems = self.tracklist.selectedItems()
            selectedindexes = self.tracklist.selectedIndexes()

            # Adding the selected items to the processing list
            self.gpxselectedlist[:] = []
            self.gpxselectednamelist[:] = []
            self.selectedpalette[:] = []
            for i in selectedindexes:
                # print str(i.text())
                self.gpxselectedlist.append(self.gpxlist[i.row()])
                self.gpxselectednamelist.append(self.gpxnamelist[i.row()])
                self.selectedpalette.append(self.palette[i.row()])

        def ClearStats():
            """
            # Some other code that could be used in the future
            index = self.treemodel.indexFromItem(parent1)
            self.tree.expand(index)
            selmod = self.tree.selectionModel()
            index2 = self.treemodel.indexFromItem(child2)
            selmod.select(index2, QtCore.QItemSelectionModel.Select|QtCore.QItemSelectionModel.Rows)
            
            root = self.treemodel.invisibleRootItem()
            (item.parent() or root).removeChild(item)
            """
            # Returns a list of indexes. In our case, for each row there are 2 indexes, cos there are 2 columns.
            for index in self.tree.selectedIndexes():
                # Consider only the first columns
                if index.column() == 0:
                    # Need to check if it's a top item (i.e. track), otherwise if a subitem (i.e. distance or time) is selected, the result might be buggy
                    parent = index.parent()
                    parent_item = self.treemodel.itemFromIndex(parent)
                    if parent_item is None:
                        self.treemodel.removeRow(index.row())

        # Application Settings
        QtCore.QCoreApplication.setOrganizationName("Ste")
        QtCore.QCoreApplication.setOrganizationDomain(
            "https://github.com/stesalati/sport/")
        QtCore.QCoreApplication.setApplicationName("TrackAnalyser")

        # Config settings
        self.settings = QtCore.QSettings(self)

        # Proxy settings
        try:
            self.use_proxy = self.settings.value('use_proxy', bool)
            self.proxy_config = self.settings.value('proxy_config', str)
        except:
            self.use_proxy = bombo.USE_PROXY
            self.proxy_config = bombo.PROXY_DATA

        # Actions
        openfile = QAction(QtGui.QIcon("icons/openfile.png"), "Open .gpx",
                           self)
        openfile.setShortcut("Ctrl+O")
        openfile.setStatusTip("Open file")
        openfile.triggered.connect(self.selectFileToOpen)

        go = QAction(QtGui.QIcon("icons/go.png"), "Go!", self)
        go.setShortcut("Ctrl+R")
        go.setStatusTip("Run analysis")
        go.triggered.connect(self.Go)

        clearstats = QAction(QtGui.QIcon("icons/clear.png"), "Clear stats",
                             self)
        clearstats.setShortcut("Ctrl+C")
        clearstats.setStatusTip("Clear stats")
        clearstats.triggered.connect(ClearStats)

        sep1 = QAction(self)
        sep1.setSeparator(True)

        showpoint = QAction(QtGui.QIcon("icons/point.png"), "Show point", self)
        showpoint.setShortcut("Ctrl+P")
        showpoint.setStatusTip("Show point")
        showpoint.triggered.connect(self.PlotSpecificAreaDialog)

        sep2 = QAction(self)
        sep2.setSeparator(True)

        quitapp = QAction(QtGui.QIcon("icons/quit.png"), "Quit", self)
        quitapp.setShortcut("Ctrl+Q")
        quitapp.setStatusTip("Quit application")
        quitapp.triggered.connect(qApp.quit)

        configs = QAction(QtGui.QIcon("icons/configs.png"), "Configs", self)
        configs.setStatusTip("Configs")
        configs.triggered.connect(self.ProxyDialog)

        # Menubar
        mainMenu = self.menuBar()
        configMenu = mainMenu.addMenu('&Config')
        configMenu.addAction(configs)

        # Toolbar
        toolbar = self.addToolBar('My tools')
        toolbar.addAction(openfile)
        toolbar.addAction(go)
        toolbar.addAction(clearstats)
        toolbar.addAction(sep1)
        toolbar.addAction(showpoint)
        toolbar.addAction(sep2)
        toolbar.addAction(quitapp)
        toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        toolbar.setIconSize(QtCore.QSize(30, 30))

        # Status bar
        self.statusBar().show()

        # Main widget (everything that's not toolbar, statusbar or menubar must be in this widget)
        self.scatola = QWidget()

        # Main horizontal impagination
        hBox = QHBoxLayout()
        hBox.setSpacing(5)

        # Vertical left column
        vBox_left = QVBoxLayout()
        vBox_left.setSpacing(5)

        # 1st vertical box, a list
        self.tracklist = QListWidget()
        vBox_left.addWidget(self.tracklist)
        self.tracklist.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.tracklist.itemSelectionChanged.connect(selection_changed)
        self.tracklist.setMaximumHeight(120)

        # 2nd vertical box, containing several horizontal boxes, one for each setting
        vBox2 = QVBoxLayout()
        vBox2.setSpacing(5)

        # Just the group label
        labelSettings = QLabel('Settings')
        vBox2.addWidget(labelSettings)

        # Use/don't use corrected altitude
        self.checkUseSRTM = QCheckBox(
            "Use SRTM corrected elevation (needs Internet)")
        self.checkUseSRTM.setChecked(False)
        vBox2.addWidget(self.checkUseSRTM)

        # Choose processing method + use/don't use acceleration
        hBoxProcessingMethod = QHBoxLayout()
        labelProcessingMethod = QLabel('Processing method')
        hBoxProcessingMethod.addWidget(labelProcessingMethod)
        self.comboBoxProcessingMethod = QComboBox()
        self.comboBoxProcessingMethod.addItem("Just use available data")
        self.comboBoxProcessingMethod.addItem(
            "Fill all gaps at T=1s (resample)")
        self.comboBoxProcessingMethod.addItem("Fill only smaller gaps at T=1s")
        hBoxProcessingMethod.addWidget(self.comboBoxProcessingMethod)
        self.checkUseAcceleration = QCheckBox("Use acceleration")
        self.checkUseAcceleration.setChecked(False)
        hBoxProcessingMethod.addWidget(self.checkUseAcceleration)
        vBox2.addLayout(hBoxProcessingMethod)

        # Use/don't use variance smooth
        self.checkExtraSmooth = QCheckBox("Extra smooth")
        self.checkExtraSmooth.setChecked(False)
        vBox2.addWidget(self.checkExtraSmooth)

        # 2D interactive map settings
        hBox2DMap = QHBoxLayout()
        self.checkUseRDP = QCheckBox("Use RDP to reduce points")
        self.checkUseRDP.setChecked(False)
        hBox2DMap.addWidget(self.checkUseRDP)
        self.check2DMapInExternalBrowser = QCheckBox(
            "Show in external browser")
        self.check2DMapInExternalBrowser.setChecked(False)
        hBox2DMap.addWidget(self.check2DMapInExternalBrowser)
        vBox2.addLayout(hBox2DMap)

        # Settings for the 3D map
        line3DViewSettings = QFrame()
        #line3DViewSettings.setGeometry(QtCore.QRect(320, 150, 118, 3))
        line3DViewSettings.setFrameShape(QFrame.HLine)
        line3DViewSettings.setFrameShadow(QFrame.Sunken)
        vBox2.addWidget(line3DViewSettings)

        label3DViewSettings = QLabel('3D view settings')
        vBox2.addWidget(label3DViewSettings)

        hBox3DMapSelection = QHBoxLayout()
        self.check3DMapSelection = QCheckBox(
            "Select elevation tiles automatically, otherwise")
        self.check3DMapSelection.setChecked(True)
        hBox3DMapSelection.addWidget(self.check3DMapSelection)
        self.text3DMapName = QLineEdit()
        self.text3DMapName.setText("Iceland.tif")
        hBox3DMapSelection.addWidget(self.text3DMapName)
        vBox2.addLayout(hBox3DMapSelection)

        hBox3D = QHBoxLayout()
        label3DMargin = QLabel('Margin')
        hBox3D.addWidget(label3DMargin)
        self.spinbox3DMargin = QSpinBox()
        self.spinbox3DMargin.setRange(50, 1000)
        self.spinbox3DMargin.setValue(100)
        self.spinbox3DMargin.setSingleStep(10)
        hBox3D.addWidget(self.spinbox3DMargin)

        labelSpace = QLabel('  ')
        hBox3D.addWidget(labelSpace)

        label3DElevationScale = QLabel('Elev. scale')
        hBox3D.addWidget(label3DElevationScale)
        self.spinbox3DElevationScale = QDoubleSpinBox()
        self.spinbox3DElevationScale.setRange(1, 50)
        self.spinbox3DElevationScale.setSingleStep(0.1)
        hBox3D.addWidget(self.spinbox3DElevationScale)

        hBox3D.addWidget(labelSpace)

        label3DOSMZoom = QLabel('Zoom')
        hBox3D.addWidget(label3DOSMZoom)
        self.spinbox3DOSMZoom = QSpinBox()
        self.spinbox3DOSMZoom.setRange(8, 15)
        self.spinbox3DOSMZoom.setValue(13)
        self.spinbox3DOSMZoom.setSingleStep(1)
        hBox3D.addWidget(self.spinbox3DOSMZoom)

        hBox3D.addWidget(labelSpace)

        self.check3DOSMInvert = QCheckBox("Invert")
        self.check3DOSMInvert.setChecked(False)
        hBox3D.addWidget(self.check3DOSMInvert)
        vBox2.addLayout(hBox3D)

        vBox_left.addLayout(vBox2)

        # 3rd stats tree
        lineTree = QFrame()
        lineTree.setFrameShape(QFrame.HLine)
        lineTree.setFrameShadow(QFrame.Sunken)
        vBox2.addWidget(lineTree)
        labelTree = QLabel('Track stats')
        vBox2.addWidget(labelTree)

        self.tree = QTreeView()
        self.tree.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.treemodel = QtGui.QStandardItemModel()
        self.treemodel.setHorizontalHeaderLabels(['Name', 'Value'])
        self.tree.setModel(self.treemodel)
        self.tree.setUniformRowHeights(True)
        self.tree.setColumnWidth(0, 200)
        vBox_left.addWidget(self.tree)

        # 4th text, containing text messages/errors
        self.textWarningConsole = QTextEdit()
        self.textWarningConsole.setReadOnly(True)
        self.textWarningConsole.setFont(QtGui.QFont("Courier New", FONTSIZE))
        self.textWarningConsole.clear()
        self.textWarningConsole.setMaximumHeight(50)
        vBox_left.addWidget(self.textWarningConsole)

        # I put "vBox_left" inside a widget and then the widget inside "hBox"
        # instead of just doing "hBox.addLayout(vBox_left) so I can set its
        # maximum width.
        vBox_left_widget = QWidget()
        vBox_left_widget.setLayout(vBox_left)
        vBox_left_widget.setMinimumWidth(400)
        vBox_left_widget.setMaximumWidth(500)
        hBox.addWidget(vBox_left_widget)

        # Vertical right column
        self.tab = QTabWidget()

        # Tab 1: Summary: elevation and speed
        tab1 = QWidget()
        # The tab layout
        vBox_tab = QVBoxLayout()
        vBox_tab.setSpacing(5)
        # Plot area
        self.plotEmbeddedElevationAndSpeed = EmbeddedPlot_ElevationSpeed(
            width=5, height=4, dpi=100)
        self.plotEmbeddedElevationAndSpeed.setMinimumWidth(800)
        # Add toolbar to the plot
        self.mpl_toolbar1 = NavigationToolbar(
            self.plotEmbeddedElevationAndSpeed, self.scatola)
        # Add widgets to the layout
        vBox_tab.addWidget(self.plotEmbeddedElevationAndSpeed)
        vBox_tab.addWidget(self.mpl_toolbar1)
        # Associate the layout to the tab
        tab1.setLayout(vBox_tab)

        # Tab 2: html 2D map
        tab2 = QWidget()
        # The tab layout
        vBox_tab = QVBoxLayout()
        vBox_tab.setSpacing(5)
        # Area
        self.map2d = QtWebEngineWidgets.QWebEngineView()
        # Add widgets to the layout
        vBox_tab.addWidget(self.map2d)
        # Associate the layout to the tab
        tab2.setLayout(vBox_tab)

        # Tab 3: 3D plot
        tab3 = QWidget()
        # The tab layout
        vBox_tab = QVBoxLayout()
        vBox_tab.setSpacing(5)
        # Area
        self.map3d = MayaviQWidget()
        # Add widgets to the layout
        vBox_tab.addWidget(self.map3d)
        # Associate the layout to the tab
        tab3.setLayout(vBox_tab)

        # Tab 4: Details
        tab4 = QWidget()
        # The tab layout
        vBox_tab = QVBoxLayout()
        vBox_tab.setSpacing(5)
        # Plot area
        self.plotEmbeddedDetails = EmbeddedPlot_Details(width=5,
                                                        height=4,
                                                        dpi=100)
        self.plotEmbeddedDetails.setMinimumWidth(800)
        # Add toolbar to the plot
        self.mpl_toolbar2 = NavigationToolbar(self.plotEmbeddedDetails,
                                              self.scatola)
        # Add widgets to the layout
        vBox_tab.addWidget(self.plotEmbeddedDetails)
        vBox_tab.addWidget(self.mpl_toolbar2)
        # Associate the layout to the tab
        tab4.setLayout(vBox_tab)

        # Associate tabs
        self.tab.addTab(tab1, "Summary")
        self.tab.addTab(tab2, "2D Map")
        self.tab.addTab(tab3, "3D Map")
        self.tab.addTab(tab4, "Details")

        hBox.addWidget(self.tab)

        # Setting hBox as main box
        self.scatola.setLayout(hBox)
        self.setCentralWidget(self.scatola)

        # Application settings
        self.setWindowTitle('TrackAnalyser')
        self.setWindowIcon((QtGui.QIcon('icons/app.png')))
        self.setGeometry(100, 100, 1200, 700)
        self.show()
コード例 #3
0
class BibleCollectionDialog(QDialog):
    def __init__(self, parent):
        super().__init__()
        self.setWindowTitle(config.thisTranslation["bibleCollections"])
        self.setMinimumSize(680, 500)
        self.selectedCollection = None
        self.settingBibles = False
        self.bibles = self.getBibles()
        self.setupUI()
        self.parent = parent

    def setupUI(self):
        mainLayout = QVBoxLayout()

        title = QLabel(config.thisTranslation["bibleCollections"])
        mainLayout.addWidget(title)

        self.collectionsLayout = QVBoxLayout()
        self.collectionsList = QListWidget()
        self.collectionsList.setMaximumHeight(90)
        self.collectionsLayout.addWidget(self.collectionsList)
        mainLayout.addLayout(self.collectionsLayout)
        self.showListOfCollections()

        buttonsLayout = QHBoxLayout()
        addButton = QPushButton(config.thisTranslation["add"])
        addButton.clicked.connect(self.addNewCollection)
        buttonsLayout.addWidget(addButton)
        removeButton = QPushButton(config.thisTranslation["remove"])
        removeButton.clicked.connect(self.removeCollection)
        buttonsLayout.addWidget(removeButton)
        renameButton = QPushButton(config.thisTranslation["rename"])
        renameButton.clicked.connect(self.renameCollection)
        buttonsLayout.addWidget(renameButton)
        buttonsLayout.addStretch()
        mainLayout.addLayout(buttonsLayout)

        self.biblesTable = QTableView()
        self.biblesTable.setEnabled(False)
        self.biblesTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.biblesTable.setSortingEnabled(True)
        self.dataViewModel = QStandardItemModel(self.biblesTable)
        self.biblesTable.setModel(self.dataViewModel)
        self.loadBibleSelection()
        self.dataViewModel.itemChanged.connect(self.bibleSelectionChanged)
        mainLayout.addWidget(self.biblesTable)

        buttonLayout = QHBoxLayout()
        button = QPushButton(config.thisTranslation["close"])
        button.clicked.connect(self.reloadControlPanel)
        button.clicked.connect(self.close)
        buttonLayout.addWidget(button)
        mainLayout.addLayout(buttonLayout)

        self.setLayout(mainLayout)

    def showListOfCollections(self):
        self.collectionsList.clear()
        if len(config.bibleCollections) > 0:
            for collection in sorted(config.bibleCollections.keys()):
                showBibleSelection = QRadioButton()
                showBibleSelection.setChecked(False)
                self.collectionsList.itemClicked.connect(self.selectCollection)
                self.collectionsList.addItem(collection)
        else:
            self.collectionsList.addItem("[No collection defined]")

    def addNewCollection(self):
        name, ok = QInputDialog.getText(self, 'Collection', 'Collection name:')
        if ok and len(name) > 0 and name != "All":
            config.bibleCollections[name] = {}
            self.showListOfCollections()
            self.biblesTable.setEnabled(False)

    def removeCollection(self):
        config.bibleCollections.pop(self.selectedCollection, None)
        self.showListOfCollections()
        self.biblesTable.setEnabled(False)

    def renameCollection(self):
        name, ok = QInputDialog.getText(self,
                                        'Collection',
                                        'Collection name:',
                                        text=self.selectedCollection)
        if ok and len(name) > 0 and name != "All":
            biblesInCollection = config.bibleCollections[
                self.selectedCollection]
            config.bibleCollections.pop(self.selectedCollection, None)
            self.selectedCollection = name
            config.bibleCollections[name] = biblesInCollection
            self.showListOfCollections()
            self.biblesTable.setEnabled(False)

    def getBibles(self):
        from db.BiblesSqlite import BiblesSqlite
        from db.BiblesSqlite import Bible

        bibles = BiblesSqlite().getBibleList()
        bibleInfo = []
        for bible in bibles:
            description = Bible(bible).bibleInfo()
            bibleInfo.append((bible, description))
        return bibleInfo

    def selectCollection(self, item):
        self.selectedCollection = item.text()
        self.biblesTable.setEnabled(True)
        self.loadBibleSelection()

    def bibleSelectionChanged(self, item):
        if not self.settingBibles:
            if self.selectedCollection is not None:
                text = item.text()
                biblesInCollection = config.bibleCollections[
                    self.selectedCollection]
                if len(biblesInCollection) == 0:
                    biblesInCollection = []
                if text in biblesInCollection:
                    biblesInCollection.remove(text)
                else:
                    biblesInCollection.append(text)
                config.bibleCollections[
                    self.selectedCollection] = biblesInCollection

    def loadBibleSelection(self):
        self.settingBibles = True
        self.dataViewModel.clear()
        biblesInCollection = []
        if self.selectedCollection is not None:
            biblesInCollection = config.bibleCollections[
                self.selectedCollection]
        rowCount = 0
        for bible, description in self.bibles:
            item = QStandardItem(bible)
            item.setToolTip(bible)
            item.setCheckable(True)
            if bible in biblesInCollection:
                item.setCheckState(Qt.Checked)
            self.dataViewModel.setItem(rowCount, 0, item)
            item = QStandardItem(description)
            self.dataViewModel.setItem(rowCount, 1, item)
            rowCount += 1
        self.dataViewModel.setHorizontalHeaderLabels([
            config.thisTranslation["bible"],
            config.thisTranslation["description"]
        ])
        self.biblesTable.resizeColumnsToContents()
        self.settingBibles = False

    def reloadControlPanel(self):
        self.parent.reloadControlPanel(False)
コード例 #4
0
class DownloadBibleMp3Dialog(QDialog):
    def __init__(self, parent):
        super().__init__()

        self.bibles = {
            "BBE (British accent)":
            ("BBE", "otseng/UniqueBible_MP3_BBE_british", "british"),
            "KJV (American accent)":
            ("KJV", "otseng/UniqueBible_MP3_KJV", "default"),
            "KJV (American soft music)":
            ("KJV", "otseng/UniqueBible_MP3_KJV_soft_music", "soft-music"),
            "NHEB (Indian accent)":
            ("NHEB", "otseng/UniqueBible_MP3_NHEB_indian", "indian"),
            "WEB (American accent)": ("WEB", "otseng/UniqueBible_MP3_WEB",
                                      "default"),
            "CUV (Chinese)": ("CUV", "otseng/UniqueBible_MP3_CUV", "default"),
            "HHBD (Hindi)": ("HHBD", "otseng/UniqueBible_MP3_HHBD", "default"),
            "RVA (Spanish)": ("RVA", "otseng/UniqueBible_MP3_RVA", "default"),
            "TR (Modern Greek)": ("TR", "otseng/UniqueBible_MP3_TR", "modern"),
        }
        self.parent = parent
        self.setWindowTitle(config.thisTranslation["gitHubBibleMp3Files"])
        self.setMinimumSize(150, 450)
        self.selectedRendition = None
        self.selectedText = None
        self.selectedRepo = None
        self.selectedDirectory = None
        self.settingBibles = False
        self.thread = None
        self.setupUI()

    def setupUI(self):
        mainLayout = QVBoxLayout()

        title = QLabel(config.thisTranslation["gitHubBibleMp3Files"])
        mainLayout.addWidget(title)

        self.versionsLayout = QVBoxLayout()
        self.renditionsList = QListWidget()
        self.renditionsList.itemClicked.connect(self.selectItem)
        for rendition in self.bibles.keys():
            self.renditionsList.addItem(rendition)
        self.renditionsList.setMaximumHeight(100)
        self.versionsLayout.addWidget(self.renditionsList)
        mainLayout.addLayout(self.versionsLayout)

        self.downloadTable = QTableView()
        self.downloadTable.setEnabled(False)
        self.downloadTable.setFocusPolicy(Qt.StrongFocus)
        self.downloadTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.downloadTable.setSortingEnabled(True)
        self.dataViewModel = QStandardItemModel(self.downloadTable)
        self.downloadTable.setModel(self.dataViewModel)
        mainLayout.addWidget(self.downloadTable)

        buttonsLayout = QHBoxLayout()
        selectAllButton = QPushButton(config.thisTranslation["selectAll"])
        selectAllButton.setFocusPolicy(Qt.StrongFocus)
        selectAllButton.clicked.connect(self.selectAll)
        buttonsLayout.addWidget(selectAllButton)
        selectNoneButton = QPushButton(config.thisTranslation["selectNone"])
        selectNoneButton.setFocusPolicy(Qt.StrongFocus)
        selectNoneButton.clicked.connect(self.selectNone)
        buttonsLayout.addWidget(selectNoneButton)
        otButton = QPushButton("1-39")
        otButton.setFocusPolicy(Qt.StrongFocus)
        otButton.clicked.connect(self.selectOT)
        buttonsLayout.addWidget(otButton)
        ntButton = QPushButton("40-66")
        ntButton.setFocusPolicy(Qt.StrongFocus)
        ntButton.clicked.connect(self.selectNT)
        buttonsLayout.addWidget(ntButton)
        # buttonsLayout.addStretch()
        mainLayout.addLayout(buttonsLayout)

        self.downloadButton = QPushButton(config.thisTranslation["download"])
        self.downloadButton.setFocusPolicy(Qt.StrongFocus)
        self.downloadButton.setAutoDefault(True)
        self.downloadButton.setFocus()
        self.downloadButton.clicked.connect(self.download)
        mainLayout.addWidget(self.downloadButton)

        self.status = QLabel("")
        mainLayout.addWidget(self.status)

        buttonLayout = QHBoxLayout()
        self.closeButton = QPushButton(config.thisTranslation["close"])
        self.closeButton.setFocusPolicy(Qt.StrongFocus)
        self.closeButton.clicked.connect(self.closeDialog)
        buttonLayout.addWidget(self.closeButton)
        mainLayout.addLayout(buttonLayout)

        self.setLayout(mainLayout)

        self.renditionsList.item(0).setSelected(True)
        bible = self.renditionsList.item(0).text()
        self.selectRendition(bible)

        self.downloadButton.setDefault(True)
        QTimer.singleShot(0, self.downloadButton.setFocus)

    def selectItem(self, item):
        self.selectRendition(item.text())

    def selectRendition(self, rendition):
        from util.GithubUtil import GithubUtil

        self.selectedRendition = rendition
        self.downloadTable.setEnabled(True)
        self.selectedText, self.selectedRepo, self.selectedDirectory = self.bibles[
            self.selectedRendition]
        self.github = GithubUtil(self.selectedRepo)
        self.repoData = self.github.getRepoData()
        self.settingBibles = True
        self.dataViewModel.clear()
        rowCount = 0
        for file in self.repoData.keys():
            if len(str(file)) > 3:
                engFullBookName = file[3:]
            else:
                engFullBookName = BibleBooks().eng[str(int(file))][1]
            item = QStandardItem(file[:3].strip())
            folder = os.path.join("audio", "bibles", self.selectedText,
                                  self.selectedDirectory, file)
            folderWithName = os.path.join("audio", "bibles", self.selectedText,
                                          self.selectedDirectory,
                                          file + " " + engFullBookName)
            if os.path.exists(folder) or os.path.exists(folderWithName):
                item.setCheckable(False)
                item.setCheckState(Qt.Unchecked)
                item.setEnabled(False)
            else:
                item.setCheckable(True)
                item.setCheckState(Qt.Checked)
                item.setEnabled(True)
            self.dataViewModel.setItem(rowCount, 0, item)
            item = QStandardItem(engFullBookName)
            self.dataViewModel.setItem(rowCount, 1, item)
            if os.path.exists(folder) or os.path.exists(folderWithName):
                item = QStandardItem("Installed")
                self.dataViewModel.setItem(rowCount, 2, item)
            else:
                item = QStandardItem("")
                self.dataViewModel.setItem(rowCount, 2, item)
            rowCount += 1
        self.dataViewModel.setHorizontalHeaderLabels([
            config.thisTranslation["menu_book"],
            config.thisTranslation["name"], ""
        ])
        self.downloadTable.setColumnWidth(0, 90)
        self.downloadTable.setColumnWidth(1, 125)
        self.downloadTable.setColumnWidth(2, 125)
        # self.downloadTable.resizeColumnsToContents()
        self.settingBibles = False

    def selectAll(self):
        for index in range(self.dataViewModel.rowCount()):
            item = self.dataViewModel.item(index)
            if item.isEnabled():
                item.setCheckState(Qt.Checked)

    def selectNone(self):
        for index in range(self.dataViewModel.rowCount()):
            item = self.dataViewModel.item(index)
            item.setCheckState(Qt.Unchecked)

    def selectOT(self):
        for index in range(self.dataViewModel.rowCount()):
            item = self.dataViewModel.item(index)
            bookNum = int(item.text())
            if bookNum <= 39:
                if item.isEnabled():
                    item.setCheckState(Qt.Checked)
                else:
                    item.setCheckState(Qt.Unchecked)
            else:
                item.setCheckState(Qt.Unchecked)

    def selectNT(self):
        for index in range(self.dataViewModel.rowCount()):
            item = self.dataViewModel.item(index)
            bookNum = int(item.text())
            if bookNum >= 40:
                if item.isEnabled():
                    item.setCheckState(Qt.Checked)
                else:
                    item.setCheckState(Qt.Unchecked)
            else:
                item.setCheckState(Qt.Unchecked)

    def download(self):
        self.downloadButton.setEnabled(False)
        self.setStatus(config.thisTranslation["message_installing"])
        self.closeButton.setEnabled(False)
        folder = os.path.join("audio", "bibles")
        if not os.path.exists(folder):
            os.mkdir(folder)
        folder = os.path.join("audio", "bibles", self.selectedText)
        if not os.path.exists(folder):
            os.mkdir(folder)
        folder = os.path.join("audio", "bibles", self.selectedText,
                              self.selectedDirectory)
        if not os.path.exists(folder):
            os.mkdir(folder)
        self.thread = QThread()
        self.worker = DownloadFromGitHub(self.github, self.repoData,
                                         self.dataViewModel, self.selectedText,
                                         self.selectedDirectory)
        self.worker.moveToThread(self.thread)
        self.thread.started.connect(self.worker.run)
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.worker.deleteLater)
        self.worker.finished.connect(self.finishedDownloading)
        self.worker.progress.connect(self.setStatus)
        self.thread.start()

    def finishedDownloading(self, count):
        self.selectRendition(self.selectedRendition)
        self.setStatus("")
        self.downloadButton.setEnabled(True)
        self.closeButton.setEnabled(True)
        if count > 0:
            self.parent.displayMessage(
                config.thisTranslation["message_installed"])

    def setStatus(self, message):
        self.status.setText(message)
        QApplication.processEvents()

    def closeDialog(self):
        if self.thread:
            if self.thread.isRunning():
                self.thread.quit()
        self.close()
コード例 #5
0
class PlotLinesWidget(QWidget):
    """ Widget to set up spectral lines for plotting
    """
    def __init__(self,
                 parent=None,
                 status=None,
                 init_llist=None,
                 init_z=None,
                 edit_z=True,
                 screen_scale=1.):
        """
        Parameters
        ----------
        parent : Widget parent
        status : Point to status bar
        init_llist : input LineList dictionary (from another widget)
        init_z : float, optional
          Initial redshift
        edit_z : bool, optional
          Allow z to be editable
        screen_scale : float, optional
          Scale GUI dimensions

        Returns
        -------

        """
        super(PlotLinesWidget, self).__init__(parent)

        # Initialize
        if not status is None:
            self.statusBar = status
        if init_z is None:
            init_z = 0.
        self.scale = screen_scale

        # Create a dialog window for redshift
        if edit_z:
            z_label = QLabel('z=')
            self.zbox = QLineEdit()
            self.zbox.z_frmt = '{:.7f}'
            self.zbox.setText(self.zbox.z_frmt.format(init_z))
            self.zbox.setMinimumWidth(50 * self.scale)
            self.zbox.textChanged[str].connect(self.setz)
            #self.connect(self.zbox, QtCore.SIGNAL('editingFinished ()'), self.setz)
        else:
            z_label = QLabel('z={:.7f}'.format(init_z))

        # Create the line list
        self.lists = [
            'None', 'ISM', 'Strong', 'HI', 'Galaxy', 'AGN', 'H2', 'EUV'
        ]
        #'grb.lst', 'dla.lst', 'lls.lst', 'subLLS.lst',
        #                      'lyman.lst', 'Dlyman.lst', 'gal_vac.lst', 'ne8.lst',
        #                      'lowz_ovi.lst', 'casbah.lst', 'H2.lst']
        list_label = QLabel('Line Lists:')
        self.llist_widget = QListWidget(self)
        for ilist in self.lists:
            self.llist_widget.addItem(ilist)
        self.llist_widget.setCurrentRow(0)
        self.llist_widget.currentItemChanged.connect(self.on_list_change)
        self.llist_widget.setMaximumHeight(100 * self.scale)

        # Input line list?
        if init_llist is None:
            self.llist = {}  # Dict for the line lists
            self.llist['Plot'] = False
            self.llist['z'] = 0.
            self.llist['List'] = 'None'  # Name of the LineList being used
            self.llist['Lists'] = []  # Archived LineLists
        else:  # Fill it all up and select
            self.llist = init_llist
            if not init_llist['List'] in self.lists:
                self.lists.append(init_llist['List'])
                self.llist_widget.addItem(init_llist['List'])
                self.llist_widget.setCurrentRow(len(self.lists) - 1)
            else:
                idx = self.lists.index(init_llist['List'])
                self.llist_widget.setCurrentRow(idx)
            try:
                self.zbox.setText(self.zbox.z_frmt.format(init_llist['z']))
            except (AttributeError, KeyError):
                pass

        # Layout
        vbox = QVBoxLayout()
        vbox.addWidget(z_label)
        if edit_z:
            vbox.addWidget(self.zbox)
        vbox.addWidget(list_label)
        vbox.addWidget(self.llist_widget)

        self.setLayout(vbox)
        self.setMaximumHeight(200 * self.scale)

    def on_list_change(self, curr, prev):
        llist = str(curr.text())
        # Print
        try:
            self.statusBar().showMessage('You chose: {:s}'.format(llist))
        except AttributeError:
            print('You chose: {:s}'.format(curr.text()))

        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()
        self.llist = ltgu.set_llist(llist, in_dict=self.llist)

        # Try to draw
        if self.llist['Plot'] is True:
            try:
                self.spec_widg.on_draw()
            except AttributeError:
                return
            except TypeError:
                QtCore.pyqtRemoveInputHook()
                pdb.set_trace()
                QtCore.pyqtRestoreInputHook()

    def setz(self, text):
        # make sure z isnt too long for box
        self.zbox.setText(str(text)[:9])

        # ensure the input z is a float
        sstr = ustr(self.zbox.text())
        try:
            self.llist['z'] = float(sstr)
        except ValueError:
            try:
                self.statusBar().showMessage(
                    'ERROR: z Input must be a float! Try again..')
            except AttributeError:
                print('ERROR: z Input must be a float! Try again..')
            self.zbox.setText(self.zbox.z_frmt.format(self.llist['z']))
            return

        # Report
        try:
            self.statusBar().showMessage('z = {:g}'.format(self.llist['z']))
        except AttributeError:
            print('z = {:g}'.format(self.llist['z']))

        # Try to draw
        try:
            self.spec_widg.on_draw()
        except AttributeError:
            return