Example #1
0
    def createDateTimeEdits(self):
        self.editsGroup = QGroupBox("Date and time spin boxes")

        dateLabel = QLabel()
        dateEdit = QDateEdit(QDate.currentDate())
        dateEdit.setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31))
        dateLabel.setText("Appointment date (between %s and %s):" %
                    (dateEdit.minimumDate().toString(Qt.ISODate),
                    dateEdit.maximumDate().toString(Qt.ISODate)))

        timeLabel = QLabel()
        timeEdit = QTimeEdit(QTime.currentTime())
        timeEdit.setTimeRange(QTime(9, 0, 0, 0), QTime(16, 30, 0, 0))
        timeLabel.setText("Appointment time (between %s and %s):" %
                    (timeEdit.minimumTime().toString(Qt.ISODate),
                    timeEdit.maximumTime().toString(Qt.ISODate)))

        self.meetingLabel = QLabel()
        self.meetingEdit = QDateTimeEdit(QDateTime.currentDateTime())

        formatLabel = QLabel("Format string for the meeting date and time:")

        formatComboBox = QComboBox()
        formatComboBox.addItem('yyyy-MM-dd hh:mm:ss (zzz \'ms\')')
        formatComboBox.addItem('hh:mm:ss MM/dd/yyyy')
        formatComboBox.addItem('hh:mm:ss dd/MM/yyyy')
        formatComboBox.addItem('hh:mm:ss')
        formatComboBox.addItem('hh:mm ap')

        formatComboBox.activated[str].connect(self.setFormatString)

        self.setFormatString(formatComboBox.currentText())

        editsLayout = QVBoxLayout()
        editsLayout.addWidget(dateLabel)
        editsLayout.addWidget(dateEdit)
        editsLayout.addWidget(timeLabel)
        editsLayout.addWidget(timeEdit)
        editsLayout.addWidget(self.meetingLabel)
        editsLayout.addWidget(self.meetingEdit)
        editsLayout.addWidget(formatLabel)
        editsLayout.addWidget(formatComboBox)
        self.editsGroup.setLayout(editsLayout)
Example #2
0
    def createDateTimeEdits(self):
        self.editsGroup = QGroupBox("Date and time spin boxes")

        dateLabel = QLabel()
        dateEdit = QDateEdit(QDate.currentDate())
        dateEdit.setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31))
        dateLabel.setText("Appointment date (between %s and %s):" %
                          (dateEdit.minimumDate().toString(Qt.ISODate),
                           dateEdit.maximumDate().toString(Qt.ISODate)))

        timeLabel = QLabel()
        timeEdit = QTimeEdit(QTime.currentTime())
        timeEdit.setTimeRange(QTime(9, 0, 0, 0), QTime(16, 30, 0, 0))
        timeLabel.setText("Appointment time (between %s and %s):" %
                          (timeEdit.minimumTime().toString(Qt.ISODate),
                           timeEdit.maximumTime().toString(Qt.ISODate)))

        self.meetingLabel = QLabel()
        self.meetingEdit = QDateTimeEdit(QDateTime.currentDateTime())

        formatLabel = QLabel("Format string for the meeting date and time:")

        formatComboBox = QComboBox()
        formatComboBox.addItem('yyyy-MM-dd hh:mm:ss (zzz \'ms\')')
        formatComboBox.addItem('hh:mm:ss MM/dd/yyyy')
        formatComboBox.addItem('hh:mm:ss dd/MM/yyyy')
        formatComboBox.addItem('hh:mm:ss')
        formatComboBox.addItem('hh:mm ap')

        formatComboBox.activated[str].connect(self.setFormatString)

        self.setFormatString(formatComboBox.currentText())

        editsLayout = QVBoxLayout()
        editsLayout.addWidget(dateLabel)
        editsLayout.addWidget(dateEdit)
        editsLayout.addWidget(timeLabel)
        editsLayout.addWidget(timeEdit)
        editsLayout.addWidget(self.meetingLabel)
        editsLayout.addWidget(self.meetingEdit)
        editsLayout.addWidget(formatLabel)
        editsLayout.addWidget(formatComboBox)
        self.editsGroup.setLayout(editsLayout)
Example #3
0
class FilterView(FixedWidthLabel):
    def __init__(self, controller, model):
        self.controller = controller
        self.model = model
        self.width = self.model.static_data.width
        super().__init__(self.width)

        self._init_UI()

    def _init_UI(self) -> None:
        data = self.model.static_data
        self.layout = QVBoxLayout()
        self.layout.setSpacing(4)
        self.layout.setContentsMargins(8, 2, 8, 2)
        self.layout.setAlignment(Qt.AlignTop)
        self.setLayout(self.layout)

        self.title = FixedSizeLabel(self.width - 6, 40, 'Problem Filter')
        self.title.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
        self.title.set_colours(data.bg_colour, data.text_colour)

        self.dateedit_start = QDateEdit()
        self.dateedit_start.setCalendarPopup(True)
        self.dateedit_start.userDateChanged.connect(
            self._on_start_date_changed)
        self.dateedit_end = QDateEdit()
        self.dateedit_end.setCalendarPopup(True)
        self.dateedit_end.userDateChanged.connect(self._on_end_date_changed)

        self.layout_date = QFormLayout()
        self.layout_date.setFormAlignment(Qt.AlignTop)
        self.layout_date.setLabelAlignment(Qt.AlignRight)
        self.layout_date.setContentsMargins(2, 2, 2, 2)
        self.layout_date.setSpacing(4)

        self.layout_date.addRow('Start Date:', self.dateedit_start)
        self.layout_date.addRow('End Date :', self.dateedit_end)

        self.layout_RIC = QHBoxLayout()
        self.layout_RIC.setSpacing(4)
        self.layout_RIC.setContentsMargins(0, 0, 0, 0)
        self.layout_RIC.setAlignment(Qt.AlignTop)

        self.layout_other = QGridLayout()
        self.layout_other.setSpacing(4)
        self.layout_other.setContentsMargins(0, 0, 0, 0)
        self.layout_other.setAlignment(Qt.AlignTop)

        self.button_reset = QPushButton('Reset')
        self.button_reset.clicked.connect(self._reset_filters)

        self.layout.addWidget(self.title)
        self.layout.addLayout(self.layout_date)
        self.layout.addLayout(self.layout_RIC)
        self.layout.addLayout(self.layout_other)
        self.layout.addWidget(self.button_reset)
        self._add_all_widgets()

    def set_data(self, arg: bool) -> None:
        self._remove_all_widgets()
        self._add_all_widgets()

    def _add_all_widgets(self) -> None:
        self._add_RIC_widgets()
        self._add_other_widgets()

    def _add_RIC_widgets(self) -> None:
        if len(self.model.views) >= 3:
            for widget in self.model.views[0:3]:
                self.layout_RIC.addWidget(widget, alignment=Qt.AlignTop)

    def _add_other_widgets(self) -> None:
        if len(self.model.views) >= 3:
            for index, widget in enumerate(self.model.views[3:]):
                self.layout_other.addWidget(widget,
                                            index // 2,
                                            index % 2,
                                            alignment=Qt.AlignTop)

    def _remove_all_widgets(self) -> None:
        self._remove_widgets_from(self.layout_RIC)
        self._remove_widgets_from(self.layout_other)

    def _remove_widgets_from(self, layout: QLayout) -> None:
        for index in reversed(range(layout.count())):
            widget = layout.itemAt(index).widget()
            layout.removeWidget(widget)
            widget.setParent(None)

    def _on_start_date_changed(self, date) -> None:
        self.controller.on_start_date_changed(date)

    def _on_end_date_changed(self, date) -> None:
        self.controller.on_end_date_changed(date)

    def set_min_date(self, date) -> None:
        self.dateedit_start.setMinimumDate(date)
        self.dateedit_end.setMinimumDate(date)
        self.dateedit_start.setDate(date)

    def set_max_date(self, date) -> None:
        self.dateedit_start.setMaximumDate(date)
        self.dateedit_end.setMaximumDate(date)
        self.dateedit_end.setDate(date)

    def _reset_filters(self) -> None:
        min_date = self.dateedit_start.minimumDate()
        self.dateedit_start.setDate(min_date)
        max_date = self.dateedit_end.maximumDate()
        self.dateedit_end.setDate(max_date)
        self._unselect_all_widgets_in(self.layout_RIC)
        self._unselect_all_widgets_in(self.layout_other)
        self.controller.reset()

    def _unselect_all_widgets_in(self, layout: QLayout) -> None:
        for index in reversed(range(layout.count())):
            widget = layout.itemAt(index).widget()
            widget.clear_selection()
Example #4
0
class IPFDSNWidget(QWidget):

    sigTracesReplaced = pyqtSignal(obspy.core.stream.Stream,
                                   obspy.core.inventory.inventory.Inventory)
    sigTracesAppended = pyqtSignal(obspy.core.stream.Stream,
                                   obspy.core.inventory.inventory.Inventory)

    stream = None
    inventory = None

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

        # this is for managing the event populated form elements
        # self.eventInfoPopulated = False
        # self.currentEvent = None

        self.__buildUI__()
        self.show()

    def __buildUI__(self):

        # Put together the options container
        gridLayout = QGridLayout()
        optionsContainer = QWidget()
        optionsContainer.setLayout(gridLayout)

        # First lets populate the client drop down
        self.cb = QComboBox()
        label_service_name = QLabel(self.tr('Service:'))

        fdsn_dictionary = URL_MAPPINGS
        fdsn_dictionary.update(
            {'RaspShake': 'https://fdsnws.rasberryshakedata.com'})

        for key in sorted(URL_MAPPINGS.keys()):
            self.cb.addItem(key)
        self.cb.setCurrentText('IRIS')
        self.cb.currentIndexChanged[str].connect(self.onActivated_cb)

        validator = IPValidator(self)
        label_network_name = QLabel(self.tr('Network: '))
        self.networkNameBox = QLineEdit()
        self.networkNameBox.setToolTip(
            'Wildcards OK \nCan be SEED network codes or data center defined codes. \nMultiple codes are comma-separated (e.g. "IU,TA").'
        )
        self.networkNameBox.setValidator(validator)

        label_station_name = QLabel(self.tr('Station: '))
        self.stationNameBox = QLineEdit()
        self.stationNameBox.setToolTip(
            'Wildcards OK \nOne or more SEED station codes. \nMultiple codes are comma-separated (e.g. "ANMO,PFO")'
        )
        self.stationNameBox.setValidator(validator)

        label_location_str = QLabel(self.tr('Location:'))
        self.location_Box = QLineEdit('*')
        self.location_Box.setToolTip(
            'Wildcards OK \nOne or more SEED location identifiers. \nMultiple identifiers are comma-separated (e.g. "00,01"). \nAs a special case “--“ (two dashes) will be translated to a string of two space characters to match blank location IDs.'
        )
        self.location_Box.setValidator(validator)

        label_channel_str = QLabel(self.tr('Channel:'))
        self.channel_Box = QLineEdit('*')
        self.channel_Box.setToolTip(
            'Wildcards OK \nOne or more SEED channel codes. \nMultiple codes are comma-separated (e.g. "BHZ,HHZ")'
        )
        self.channel_Box.setValidator(validator)

        label_startDate = QLabel(self.tr('Start Date (UTC):'))
        self.startDate_edit = QDateEdit()
        self.startDate_edit.setMinimumDate(QDate(1900, 1, 1))
        self.startDate_edit.setDisplayFormat('yyyy-MM-dd')
        self.startDate_edit.setDate(self.startDate_edit.minimumDate())

        label_startTime = QLabel(self.tr('Start Time (UTC):'))
        self.startTime_edit = QTimeEdit()
        self.startTime_edit.setDisplayFormat('HH:mm:ss.zzz')

        label_traceLength = QLabel(self.tr('Trace Length (s)'))
        self.traceLength_t = QSpinBox()
        self.traceLength_t.setMinimum(1)
        self.traceLength_t.setMaximum(999999999)
        self.traceLength_t.setValue(3600)

        replaceWaveButton = QPushButton('Replace')
        replaceWaveButton.clicked.connect(self.onClicked_replace)
        appendWaveButton = QPushButton('Append')
        appendWaveButton.clicked.connect(self.onClicked_append)

        self.stationListWidget = QListWidget()
        self.stationListWidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.stationListWidget.itemSelectionChanged.connect(
            self.populateStationInfoFromStationList)

        self.browserButton = QPushButton('Station Browser')
        self.browserButton.clicked.connect(self.onClicked_browserButton)

        gridLayout.addWidget(label_service_name, 0, 0)
        gridLayout.addWidget(self.cb, 0, 1)
        gridLayout.addWidget(label_network_name, 1, 0)
        gridLayout.addWidget(self.networkNameBox, 1, 1)
        gridLayout.addWidget(label_station_name, 2, 0)
        gridLayout.addWidget(self.stationNameBox, 2, 1)
        gridLayout.addWidget(label_location_str, 3, 0)
        gridLayout.addWidget(self.location_Box, 3, 1)
        gridLayout.addWidget(label_channel_str, 4, 0)
        gridLayout.addWidget(self.channel_Box, 4, 1)
        gridLayout.addWidget(label_startDate, 5, 0)
        gridLayout.addWidget(self.startDate_edit, 5, 1)
        gridLayout.addWidget(label_startTime, 6, 0)
        gridLayout.addWidget(self.startTime_edit, 6, 1)
        gridLayout.addWidget(label_traceLength, 7, 0)
        gridLayout.addWidget(self.traceLength_t, 7, 1)
        # gridLayout.addWidget(importEventButton, 8, 1, 1, 2)

        horzLayout = QHBoxLayout(self)
        horzLayout.addWidget(replaceWaveButton)
        horzLayout.addWidget(appendWaveButton)
        addGroupBox = QGroupBox("Get Waveform(s)")
        addGroupBox.setLayout(horzLayout)

        vertlayout = QVBoxLayout(self)
        vertlayout.addWidget(optionsContainer)
        vertlayout.addWidget(addGroupBox)
        vertlayout.addWidget(self.stationListWidget)
        vertlayout.addWidget(self.browserButton)

        self.setLayout(vertlayout)

        # create stationdialog here so that you only create it once, from here on you just run exec_() to make it pop up
        self.stationDialog = IPStationBrowser.IPStationDialog()

    def onClicked_browserButton(self):

        if self.stationDialog.exec_(self.startDate_edit.date(),
                                    network=self.networkNameBox.text(),
                                    station=self.stationNameBox.text(),
                                    location=self.location_Box.text(),
                                    channel=self.channel_Box.text()):
            self.inventory = self.stationDialog.getInventory()

            inv_contents = self.inventory.get_contents()
            stationList = []

            # fill up the stationList with stations
            for item in inv_contents['stations']:
                stationList.append(item.strip())
            self.stationListWidget.clear()
            self.stationListWidget.addItems(stationList)

            if self.stationDialog.getStartDate() is not None:
                self.startDate_edit.setDate(self.stationDialog.getStartDate())

    # def populateWithEventInfo(self):
    #     if self.parent.eventWidget.hasValidEvent():
    #         self.currentEvent = self.parent.eventWidget.Dict()
    #     else:
    #         msgBox = QMessageBox()
    #         msgBox.setIcon(QMessageBox.Warning)
    #         msgBox.setText('There is not a valid event in the Event Tab')
    #         msgBox.setWindowTitle("Oops...")
    #         msgBox.exec_()
    #         return

    #     if self.currentEvent is not None:
    #         date = self.currentEvent['UTC Date']
    #         time = self.currentEvent['UTC Time'][0:5]

    #     qdate = QDate.fromString(date, 'yyyy-MM-dd')
    #     qtime = QTime.fromString(time, 'HH:mm')
    #     qtime.addSecs(-5*60)  # start about 5 minutes before event

    #     self.startDate_edit.setDate(qdate)
    #     self.startTime_edit.setTime(qtime)

    #     self.eventInfoPopulated = True

    # # if someone edits the event info, reflect the changes here
    # @QtCore.pyqtSlot(dict)
    # def updateEventInfo(self, event):
    #     if not self.eventInfoPopulated:
    #         return

    #     if self.parent.eventWidget.hasValidEvent():
    #         self.currentEvent = event

    #     if self.currentEvent is not None:
    #         date = event['UTC Date']
    #         time = event['UTC Time'][0:5]

    #     qdate = QDate.fromString(date, 'yyyy-MM-dd')
    #     qtime = QTime.fromString(time, 'HH:mm')
    #     qtime.addSecs(-5*60)  # start about 5 minutes before event

    #     self.startDate_edit.setDate(qdate)
    #     self.startTime_edit.setTime(qtime)

    def populateStationInfoFromStationList(self):
        items = self.stationListWidget.selectedItems()
        if len(items) < 1:
            return  # nothing to do

        netList = []
        staList = []

        for item in items:
            text = item.text()
            text = text.split(' ')[0]
            netSta = text.split('.')

            netList.append(netSta[0])
            staList.append(netSta[1])

            netList = list(set(netList))
            staList = list(set(staList))

            netString = ''
            for net in netList:
                netString = netString + net + ', '
            staString = ''
            for sta in staList:
                staString = staString + sta + ', '

        self.networkNameBox.setText(netString[:-2])
        self.stationNameBox.setText(staString[:-2])

    def onActivated_cb(self, key):
        if (key != 'choose...'):
            url = URL_MAPPINGS[key]

    def onClicked_replace(self):
        self.downloadWaveforms()
        if self.stream is not None and self.inventory is not None:
            self.sigTracesReplaced.emit(self.stream, self.inventory)

    def onClicked_append(self):
        self.downloadWaveforms()
        if self.stream is not None and self.inventory is not None:
            self.sigTracesAppended.emit(self.stream, self.inventory)

    # get waveform button was clicked
    def downloadWaveforms(self):
        # first check to make sure the boxes are filled...addWidget
        # TODO!!!

        # get the inputs...inputs
        service = self.cb.currentText()
        if (service == 'choose...'):
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setText('Please select a service to search')
            msg.setWindowTitle('oops...')
            msg.setStandardButtons(QMessageBox.Ok)
            msg.exec_()
            return

        # Clear old streams because we don't need them anymore
        self.clearWaveforms()

        network = self.networkNameBox.text().upper().replace(' ', '')
        self.networkNameBox.setText(network)
        station = self.stationNameBox.text().upper().replace(' ', '')
        self.stationNameBox.setText(station)
        location = self.location_Box.text().upper().replace(' ', '')
        self.location_Box.setText(location)
        channel = self.channel_Box.text().upper().replace(' ', '')
        self.channel_Box.setText(channel)
        date = self.startDate_edit.date().toPyDate()
        time = self.startTime_edit.time().toPyTime()
        traceLength = self.traceLength_t.value()
        utcString = str(date) + 'T' + str(time)
        startTime = UTCDateTime(utcString)
        endTime = startTime + traceLength

        # Check for unfilled boxes
        if (network == '' or station == '' or channel == ''):
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setText('You are missing some important info...')
            msg.setWindowTitle('oops...')
            msg.setDetailedText(
                "Network, Station, Location, and Channel are all required data."
            )
            msg.setStandardButtons(QMessageBox.Ok)
            msg.exec_()
            return

        # Download the waveforms
        # self.parent.setStatus('connecting to '+service)
        client = Client(service)

        # self.parent.setStatus('downloading Waveforms...')
        try:
            self.stream = client.get_waveforms(network, station, location,
                                               channel, startTime, endTime)

        except Exception:
            # self.parent.setStatus('')
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setText('Failure loading waveform')
            msg.setWindowTitle('oops...')
            msg.setDetailedText(
                "Double check that the values you entered are valid and the time and date are appropriate."
            )
            msg.setStandardButtons(QMessageBox.Ok)
            msg.exec_()
            return

        for trace in self.stream:
            trace.data = trace.data - np.mean(trace.data)
        self.stream.merge(fill_value=0)

        # self.parent.setStatus('downloading Inventory...')
        # self.parent.consoleBox.append( 'Downloaded waveforms from '+service )

        # Now get the corresponding stations
        try:
            self.inventory = client.get_stations(network=network,
                                                 station=station)
        except:
            # self.parent.setStatus('')
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setText('Failure loading Inventory')
            msg.setWindowTitle('oops...')
            msg.setDetailedText(
                "Double check that the values you entered are valid and the time and date are appropriate."
            )
            msg.setStandardButtons(QMessageBox.Ok)
            msg.exec_()

            return
        # self.parent.consoleBox.append( 'Downloaded stations from '+service)
        # self.parent.setStatus('Finished...', 3000)

    def getStreams(self):
        return self.stream

    def getInventory(self):
        return self.inventory

    def getService(self):
        return self.cb.currentText()

    def clearWaveforms(self):
        self.stream = None
        self.inventory = None

    def clear(self):

        self.clearWaveforms()

        self.stationListWidget.clear()
        self.cb.setCurrentText(
            'IRIS')  # default to IRIS because why the hell not?
        self.networkNameBox.clear()
        self.stationNameBox.clear()
        self.location_Box.setText('*')
        self.channel_Box.setText('*')
        self.startDate_edit.setDate(self.startDate_edit.minimumDate())
        self.startTime_edit.setTime(self.startTime_edit.minimumTime())
        self.traceLength_t.setValue(3600)
Example #5
0
class IPStationBrowser(QWidget):

    __inv = None

    def __init__(self, service=None, network=None):
        super().__init__()

        # these are for managing the event info in form elements
        # self.eventInfoPopulated = False
        # self.currentEvent = None

        self.__buildUI__(service, network)
        self.show()

    def __buildUI__(self, service, network):
        vertLayout = QVBoxLayout()
        self.setLayout(vertLayout)

        gridLayout = QGridLayout()

        # First lets populate the client drop down with all available services
        self.service_cb = QComboBox()
        # self.service_cb.addItem("choose...")
        fdsn_dictionary = URL_MAPPINGS
        fdsn_dictionary.update(
            {'RaspShake': 'https://fdsnws.rasberryshakedata.com'})

        for key in sorted(fdsn_dictionary.keys()):
            self.service_cb.addItem(key)
            self.service_cb.setCurrentText('IRIS')
        if service is not None:
            self.service_cb.setCurrentText(service)

        validator = Validator(self)

        # Network selector
        self.network_edit = QLineEdit(network)
        self.network_edit.setToolTip(
            'Wildcards OK \nCan be SEED network codes or data center defined codes. \nMultiple codes are comma-separated (e.g. "IU,TA").'
        )
        self.network_edit.setValidator(validator)
        if network is not None:
            self.network_edit.setText(network)

        # Station selector
        self.station_edit = QLineEdit()
        self.station_edit.setToolTip(
            'Wildcards OK \nOne or more SEED station codes. \nMultiple codes are comma-separated (e.g. "ANMO,PFO")'
        )
        self.station_edit.setValidator(validator)

        # Location selector
        self.location_edit = QLineEdit()
        self.location_edit.setToolTip(
            'One or more SEED location identifiers. \nMultiple identifiers are comma-separated (e.g. "00,01"). \nAs a special case “--“ (two dashes) will be translated to a string of two space characters to match blank location IDs.'
        )
        self.location_edit.setText('')

        # Channel selector
        self.channel_edit = QLineEdit()
        self.channel_edit.setToolTip(
            'Wildcards OK \nOne or more SEED channel codes. \nMultiple codes are comma-separated (e.g. "BHZ,HHZ")'
        )
        self.channel_edit.setValidator(validator)

        # Date time editors
        minimumDate = QDate(1900, 1, 1)
        self.startDate_edit = QDateEdit()
        self.startDate_edit.setDisplayFormat('yyyy-MM-dd')
        self.startDate_edit.setMinimumDate(minimumDate)
        self.startDate_edit.setDate(self.startDate_edit.minimumDate())

        self.endDate_edit = QDateEdit()
        self.endDate_edit.setDisplayFormat('yyyy-MM-dd')
        self.endDate_edit.setMinimumDate(minimumDate)
        self.endDate_edit.setDate(self.endDate_edit.minimumDate())

        self.lat_edit = QDoubleSpinBox()
        self.lat_edit.setRange(-90.1,
                               90.0)  # the -90.1 is used as the "unset" value
        self.lat_edit.setDecimals(8)
        self.lat_edit.setSpecialValueText('--')
        self.lat_edit.setSingleStep(0.1)
        self.lat_edit.setValue(self.lat_edit.minimum())

        self.lon_edit = QDoubleSpinBox()
        self.lon_edit.setRange(-180.1, 180.0)
        self.lon_edit.setDecimals(8)
        self.lon_edit.setSpecialValueText('--')
        self.lon_edit.setSingleStep(0.1)
        self.lon_edit.setValue(self.lon_edit.minimum())

        # self.evt_import_button = QPushButton('Populate with Event Info')

        self.minLat_edit = QDoubleSpinBox()
        self.minLat_edit.setRange(-90.1, 90.0)
        self.minLat_edit.setDecimals(8)
        self.minLat_edit.setSpecialValueText('--')
        self.minLat_edit.setSingleStep(0.1)
        self.minLat_edit.setValue(self.minLat_edit.minimum())

        self.maxLat_edit = QDoubleSpinBox()
        self.maxLat_edit.setRange(-90.1, 90.0)
        self.maxLat_edit.setDecimals(8)
        self.maxLat_edit.setSpecialValueText('--')
        self.maxLat_edit.setSingleStep(0.1)
        self.maxLat_edit.setValue(self.maxLat_edit.minimum())

        self.minLon_edit = QDoubleSpinBox()
        self.minLon_edit.setRange(-180.1, 180.0)
        self.minLon_edit.setDecimals(8)
        self.minLon_edit.setSpecialValueText('--')
        self.minLon_edit.setSingleStep(0.1)
        self.minLon_edit.setValue(self.minLon_edit.minimum())

        self.maxLon_edit = QDoubleSpinBox()
        self.maxLon_edit.setRange(-180.1, 180.0)
        self.maxLon_edit.setDecimals(8)
        self.maxLon_edit.setSpecialValueText('--')
        self.maxLon_edit.setSingleStep(0.1)
        self.maxLon_edit.setValue(self.maxLon_edit.minimum())

        self.minRadius_edit = QDoubleSpinBox()
        self.minRadius_edit.setMinimum(0.0)
        self.minRadius_edit.setMaximum(180.0)
        self.minRadius_edit.setSpecialValueText('--')
        self.minRadius_edit.setSuffix(' deg')
        self.minRadius_edit.setValue(self.minRadius_edit.minimum())
        self.minRadius_edit.setEnabled(
            False)  # Need lat and lon before this means anything

        self.maxRadius_edit = QDoubleSpinBox()
        self.maxRadius_edit.setMinimum(0.0)
        self.maxRadius_edit.setMaximum(180.0)
        self.maxRadius_edit.setSpecialValueText('--')
        self.maxRadius_edit.setSuffix(' deg')
        self.maxRadius_edit.setValue(self.maxRadius_edit.minimum())
        self.maxRadius_edit.setEnabled(
            False)  # Need lat and lon before this means anything

        # Set up the search button here
        self.searchButton = QPushButton('Search')

        # Reset Button
        self.resetButton = QPushButton('Reset Inputs')

        # assemble the grid layout
        gridLayout.addWidget(QLabel(self.tr('Service: ')),
                             0,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.service_cb, 0, 1)

        gridLayout.addWidget(QLabel(self.tr('Network(s): ')),
                             1,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.network_edit, 1, 1)
        gridLayout.addWidget(QLabel(self.tr('Station(s): ')),
                             1,
                             2,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.station_edit, 1, 3)

        gridLayout.addWidget(QLabel(self.tr('Location(s): ')),
                             2,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.location_edit, 2, 1)
        gridLayout.addWidget(QLabel(self.tr('Channel(s): ')),
                             2,
                             2,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.channel_edit, 2, 3)

        gridLayout.addWidget(self.HLine(), 3, 0, 1,
                             4)  # This is a horizontal line

        gridLayout.addWidget(QLabel(self.tr('Start Date (UTC)')),
                             4,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.startDate_edit, 4, 1)

        gridLayout.addWidget(QLabel(self.tr('End Date (UTC)')),
                             4,
                             2,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.endDate_edit, 4, 3)

        gridLayout.addWidget(QLabel(self.tr('Latitude: ')),
                             5,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.lat_edit, 5, 1)
        gridLayout.addWidget(QLabel(self.tr('Longitude: ')),
                             5,
                             2,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.lon_edit, 5, 3)

        # gridLayout.addWidget(self.evt_import_button, 6, 1, 1, 2)

        gridLayout.addWidget(self.HLine(), 7, 0, 1,
                             4)  # This is a horizontal line

        gridLayout.addWidget(QLabel(self.tr('Minimum Latitude: ')),
                             8,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.minLat_edit, 8, 1)
        gridLayout.addWidget(QLabel(self.tr('Maximum Latitude: ')),
                             8,
                             2,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.maxLat_edit, 8, 3)

        gridLayout.addWidget(QLabel(self.tr('Minimum Longitude: ')),
                             9,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.minLon_edit, 9, 1)
        gridLayout.addWidget(QLabel(self.tr('Maximum Longitude: ')),
                             9,
                             2,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.maxLon_edit, 9, 3)

        gridLayout.addWidget(self.HLine(), 10, 0, 1,
                             4)  # This is a horizontal line

        gridLayout.addWidget(QLabel(self.tr('Minimum Radius: ')),
                             11,
                             0,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.minRadius_edit, 11, 1)
        gridLayout.addWidget(QLabel(self.tr('Maximum Radius: ')),
                             11,
                             2,
                             alignment=Qt.AlignRight)
        gridLayout.addWidget(self.maxRadius_edit, 11, 3)

        gridLayout.addWidget(self.HLine(), 12, 0, 1,
                             4)  # This is a horizontal line

        gridLayout.addWidget(self.resetButton, 13, 0)
        gridLayout.addWidget(self.searchButton, 13, 2, 1, 2)

        # Center the form in the widget
        centeringLayout = QHBoxLayout()
        centeringLayout.addStretch()
        centeringLayout.addLayout(gridLayout)
        centeringLayout.addStretch()

        self.stationListWidget = QListWidget()
        # self.stationListWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        # for multiple selection, uncomment out the next line, and comment out the above line
        self.stationListWidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)

        # create a tab widget to hold the stationList and the station map
        stationTabs = QTabWidget()
        stationTabs.addTab(self.stationListWidget, "Station List")

        # Placeholder for map widget, whenever I get around to making one
        self.mapWidget = QWidget()
        stationTabs.addTab(self.mapWidget, 'Map')

        vertLayout.addLayout(centeringLayout)

        vertLayout.addWidget(stationTabs)

        self.connectSignalsAndSlots()

    def connectSignalsAndSlots(self):

        self.searchButton.clicked.connect(self.onActivated_search)
        self.resetButton.clicked.connect(self.onActivated_reset)
        # self.evt_import_button.clicked.connect(self.populateEventInfo)

        self.stationListWidget.itemClicked.connect(self.getSelected)

        self.service_cb.currentIndexChanged[str].connect(self.serviceClicked)

        self.lat_edit.valueChanged.connect(self.updateWidget)
        self.lon_edit.valueChanged.connect(self.updateWidget)

        self.startDate_edit.dateChanged.connect(self.adjust_end_date)

    @QtCore.pyqtSlot(QDate)
    def adjust_end_date(self, start_date):
        if self.endDate_edit.date() == self.endDate_edit.minimumDate():
            self.endDate_edit.setDate(start_date)
        elif self.endDate_edit.date() < start_date:
            self.endDate_edit.setDate(start_date)

    def populateStationInfo(self):

        service = self.service_cb.currentText()

        if self.network_edit.text() == '':
            network = None
        else:
            network = self.network_edit.text()

        if self.station_edit.text() == '':
            station = None
        else:
            station = self.station_edit.text()

        if self.location_edit.text() == '':
            location = None
        else:
            location = self.location_edit.text()

        if self.channel_edit.text() == '':
            channel = None
        else:
            channel = self.channel_edit.text()

        if self.lat_edit.value() == self.lat_edit.minimum():
            lat = None
        else:
            lat = self.lat_edit.value()

        if self.lon_edit.value() == self.lon_edit.minimum():
            lon = None
        else:
            lon = self.lon_edit.value()

        if self.minLat_edit.value() == self.minLat_edit.minimum():
            minLat = None
        else:
            minLat = self.minLat_edit.value()

        if self.maxLat_edit.value() == self.maxLat_edit.minimum():
            maxLat = None
        else:
            maxLat = self.maxLat_edit.value()

        if self.minLon_edit.value() == self.minLon_edit.minimum():
            minLon = None
        else:
            minLon = self.minLon_edit.value()

        if self.maxLon_edit.value() == self.maxLon_edit.minimum():
            maxLon = None
        else:
            maxLon = self.maxLon_edit.value()

        if self.lat_edit.value() != self.lat_edit.minimum(
        ) and self.lon_edit.value() != self.lon_edit.minimum():

            if self.minRadius_edit.value() == self.minRadius_edit.minimum():
                minRad = None
            else:
                minRad = self.minRadius_edit.value()

            if self.maxRadius_edit.value() == self.maxRadius_edit.minimum():
                maxRad = None
            else:
                maxRad = self.maxRadius_edit.value()
        else:
            minRad = None
            maxRad = None

        if service != '':
            try:
                client = Client(service)
            except obspy.clients.fdsn.header.FDSNException as e:
                self.errorPopup(str(e))
                return

            startDate = self.startDate_edit.date().toString("yyyy-MM-dd")
            endDate = self.endDate_edit.date().toString("yyyy-MM-dd")

            try:
                self.__inv = client.get_stations(network=network,
                                                 station=station,
                                                 location=location,
                                                 channel=channel,
                                                 starttime=startDate,
                                                 endtime=endDate,
                                                 latitude=lat,
                                                 longitude=lon,
                                                 minlongitude=minLon,
                                                 maxlongitude=maxLon,
                                                 minlatitude=minLat,
                                                 maxlatitude=maxLon,
                                                 minradius=minRad,
                                                 maxradius=maxRad,
                                                 format='xml')
            except:
                emptyMessage = ["...No Data Found..."]
                self.stationListWidget.clear()
                self.stationListWidget.addItems(emptyMessage)
                return

            self.stationListWidget.clear()

            inv_contents = self.__inv.get_contents()

            stationList = []

            # fill up the stationList with stations
            for item in inv_contents['stations']:
                stationList.append(item.strip())
            self.stationListWidget.clear()
            self.stationListWidget.addItems(stationList)

    def errorPopup(self, message):
        msgBox = QMessageBox()
        msgBox.setIcon(QMessageBox.Information)
        msgBox.setText(message)
        msgBox.setWindowTitle("Oops...")
        msgBox.exec_()

    def onActivated_search(self):
        self.stationListWidget.clear()
        QtGui.QGuiApplication.processEvents()
        QApplication.processEvents()
        msg = ['...Searching...']
        self.stationListWidget.addItems(msg)
        QApplication.processEvents()
        QtGui.QGuiApplication.processEvents()
        self.populateStationInfo()
        return

    def onActivated_reset(self):
        self.__inv = None
        self.network_edit.setText('')
        self.station_edit.setText('')
        self.location_edit.setText('')
        self.channel_edit.setText('')
        self.startDate_edit.setDate(self.startDate_edit.minimumDate())
        self.endDate_edit.setDate(self.endDate_edit.minimumDate())
        self.lat_edit.setValue(self.lat_edit.minimum())
        self.lon_edit.setValue(self.lon_edit.minimum())
        self.minLat_edit.setValue(self.minLat_edit.minimum())
        self.minLon_edit.setValue(self.minLon_edit.minimum())
        self.maxLat_edit.setValue(self.maxLat_edit.minimum())
        self.maxLon_edit.setValue(self.maxLon_edit.minimum())
        self.minRadius_edit.setValue(self.minRadius_edit.minimum())
        self.maxRadius_edit.setValue(self.maxRadius_edit.minimum())
        self.stationListWidget.clear()
        # self.eventInfoPopulated = False

    # def populateEventInfo(self):
    #     if self.currentEvent is not None:
    #         date = self.currentEvent['UTC Date']
    #         lat = self.currentEvent['Latitude']
    #         lon = self.currentEvent['Longitude']

    #         self.lat_edit.setValue(lat)
    #         self.lon_edit.setValue(lon)
    #         qdate = QDate.fromString(date, 'yyyy-MM-dd')
    #         self.startDate_edit.setDate(qdate)
    #         self.endDate_edit.setDate(qdate.addDays(1))

    #         self.eventInfoPopulated = True
    #     else:
    #         msg = QMessageBox()
    #         msg.setIcon(QMessageBox.Warning)
    #         msg.setText('There is not a valid event in the Event Tab')
    #         msg.setWindowTitle('oops...')
    #         msg.setStandardButtons(QMessageBox.Ok)
    #         msg.exec_()

    # def setEvent(self, event):
    #     self.currentEvent = event

    #     # Update the event info if it has been imported
    #     if self.eventInfoPopulated:
    #         self.populateEventInfo()

    def updateWidget(self):
        # We need lat and lon values if we are going to use the radius inputs
        enableRadius = self.lat_edit.value() != self.lat_edit.minimum(
        ) and self.lon_edit.value() != self.lon_edit.minimum()
        self.maxRadius_edit.setEnabled(enableRadius)
        self.minRadius_edit.setEnabled(enableRadius)

    def getSelected(self):
        selectedText = self.stationListWidget.currentItem().text()

        # first split the string at the first space, this will return just the
        # network and the station
        name = selectedText.split(" ")
        fullID = name[0]
        # next split that at the period, to seperate the network and station
        networkID = fullID.split(".")[0]
        stationID = fullID.split(".")[1]

        result = {"networkID": networkID, "stationID": stationID}

        return result

    def get_current_center(self):
        # this method will calculate the center of the current inventory and will return a [lat,lon]

        # TODO: This is not really setup right now to handle the (very rare) case where an array straddles the
        # international date line

        lat, lon, cnt = 0, 0, 0

        for network in self.__inv:
            for station in network:
                lat += station.latitude
                lon += station.longitude
                cnt += 1

        return [lat / cnt, lon / cnt]

    def getInventory(self):
        return self.__inv

    def getSelectedInventory(self):
        reducedInv = []
        for item in self.__inv:
            if item.isSelected():
                reducedInv.append(item)
        return reducedInv

    def serviceClicked(self):
        self.stationListWidget.clear()
        self.network_edit.clear()

    def HLine(self):
        hl = QFrame()
        hl.setFrameShape(QFrame.HLine)
        hl.setFrameShadow(QFrame.Sunken)
        return hl