def __init__(self, parent=None):

        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        common = gui_common.common_tools(self)
        common.set_status_bar("Olá mundo!")

        # Callbacks
        about = lambda: information(self, 'About PyFilter...',
                                    'PyFilter 0.1 (c) 2015 Renan Birck.')

        QtCore.QObject.connect(self.ui.actionAbout,
                               QtCore.SIGNAL("triggered()"),
                               about)

        for filter_type_widget in [self.ui.radioButton_IIR,
                                   self.ui.radioButton_FIR]:
            QtCore.QObject.connect(filter_type_widget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.pick_widgets_for_filter_type)

        for FIR_mode_widget in [self.ui.radioButton_Parks,
                                self.ui.radioButton_Window]:
            QtCore.QObject.connect(FIR_mode_widget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.FIR_setup)

        for designParametersWidget in [self.ui.radioButton_NWn,
                                       self.ui.radioButton_AttSpecs]:
            QtCore.QObject.connect(designParametersWidget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.configure_boxes_for_design_parameters)

        for topologyWidget in [self.ui.radioButton_Bessel,
                               self.ui.radioButton_Butterworth,
                               self.ui.radioButton_Cheby1,
                               self.ui.radioButton_Cheby2,
                               self.ui.radioButton_Elliptical]:

            QtCore.QObject.connect(topologyWidget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.get_filter_TF)

        for typeWidget in [self.ui.radioButton_AP,
                           self.ui.radioButton_BP,
                           self.ui.radioButton_BS,
                           self.ui.radioButton_HP,
                           self.ui.radioButton_LP]:
            QtCore.QObject.connect(typeWidget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.get_filter_type)

        QtCore.QObject.connect(self.ui.pushButton_addItem,
                               QtCore.SIGNAL("clicked()"),
                               self.add_fir_param)
        QtCore.QObject.connect(self.ui.pushButton_removeItem,
                               QtCore.SIGNAL("clicked()"),
                               self.delete_fir_param)
        QtCore.QObject.connect(self.ui.pushButton_Design,
                               QtCore.SIGNAL("clicked()"),
                               self.design_filter)
        QtCore.QObject.connect(self.ui.pushButton_WriteToFile,
                               QtCore.SIGNAL("clicked()"),
                               self.write_plots_to_file)
        QtCore.QObject.connect(self.ui.tabWidget,
                               QtCore.SIGNAL("tabCloseRequested(int)"),
                               self.destroy_tab)
        QtCore.QObject.connect(self.ui.comboBox_Window,
                               QtCore.SIGNAL("currentIndexChanged(int)"),
                               self.create_window_fields)

        self.pick_widgets_for_filter_type()
        self.populate_window_list()
        self.FIR_setup()
        self.configure_boxes_for_design_parameters()
        self.get_filter_TF()
        self.get_filter_type()
class StartQT4(QtGui.QMainWindow):
    common = None
    config_dict = {}
    filter_data = {}
    file_names = []

    def __init__(self, parent=None):

        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        common = gui_common.common_tools(self)
        common.set_status_bar("Olá mundo!")

        # Callbacks
        about = lambda: information(self, 'About PyFilter...',
                                    'PyFilter 0.1 (c) 2015 Renan Birck.')

        QtCore.QObject.connect(self.ui.actionAbout,
                               QtCore.SIGNAL("triggered()"),
                               about)

        for filter_type_widget in [self.ui.radioButton_IIR,
                                   self.ui.radioButton_FIR]:
            QtCore.QObject.connect(filter_type_widget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.pick_widgets_for_filter_type)

        for FIR_mode_widget in [self.ui.radioButton_Parks,
                                self.ui.radioButton_Window]:
            QtCore.QObject.connect(FIR_mode_widget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.FIR_setup)

        for designParametersWidget in [self.ui.radioButton_NWn,
                                       self.ui.radioButton_AttSpecs]:
            QtCore.QObject.connect(designParametersWidget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.configure_boxes_for_design_parameters)

        for topologyWidget in [self.ui.radioButton_Bessel,
                               self.ui.radioButton_Butterworth,
                               self.ui.radioButton_Cheby1,
                               self.ui.radioButton_Cheby2,
                               self.ui.radioButton_Elliptical]:

            QtCore.QObject.connect(topologyWidget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.get_filter_TF)

        for typeWidget in [self.ui.radioButton_AP,
                           self.ui.radioButton_BP,
                           self.ui.radioButton_BS,
                           self.ui.radioButton_HP,
                           self.ui.radioButton_LP]:
            QtCore.QObject.connect(typeWidget,
                                   QtCore.SIGNAL("clicked()"),
                                   self.get_filter_type)

        QtCore.QObject.connect(self.ui.pushButton_addItem,
                               QtCore.SIGNAL("clicked()"),
                               self.add_fir_param)
        QtCore.QObject.connect(self.ui.pushButton_removeItem,
                               QtCore.SIGNAL("clicked()"),
                               self.delete_fir_param)
        QtCore.QObject.connect(self.ui.pushButton_Design,
                               QtCore.SIGNAL("clicked()"),
                               self.design_filter)
        QtCore.QObject.connect(self.ui.pushButton_WriteToFile,
                               QtCore.SIGNAL("clicked()"),
                               self.write_plots_to_file)
        QtCore.QObject.connect(self.ui.tabWidget,
                               QtCore.SIGNAL("tabCloseRequested(int)"),
                               self.destroy_tab)
        QtCore.QObject.connect(self.ui.comboBox_Window,
                               QtCore.SIGNAL("currentIndexChanged(int)"),
                               self.create_window_fields)

        self.pick_widgets_for_filter_type()
        self.populate_window_list()
        self.FIR_setup()
        self.configure_boxes_for_design_parameters()
        self.get_filter_TF()
        self.get_filter_type()


    def FIR_setup(self):
        self.ui.tableWidget_FIR.setColumnCount(2)
        if self.ui.radioButton_Parks.isChecked():
            self.ui.tableWidget_FIR.setHorizontalHeaderLabels(["Band", "Gain"])
            self.ui.comboBox_Window.setEnabled(False)
            self.config_dict['FIR_Mode'] = "Parks"
        elif self.ui.radioButton_Window.isChecked():
            self.ui.tableWidget_FIR.setHorizontalHeaderLabels(["Freq", "Gain"])
            self.ui.comboBox_Window.setEnabled(True)
            self.config_dict['FIR_Mode'] = "Window"
        else:
            pass

    def create_window_fields(self, index):
        """ Create the fields for the picked window type. """
        print("picked window ", window_types[index][0])
        self.window_index = index

        if window_types[index][2] == 1:  # The window has parameters.
            self.ui.label_param1.show()
            self.ui.label_param1.setText(window_types[index][3])
            self.ui.plainTextEdit_option1.show()
        else:
            self.ui.label_param1.hide()
            self.ui.plainTextEdit_option1.hide()


    def populate_window_list(self):
        # Format of tuples is:
        # 1. visible name
        # 2. internal name
        # 3. number of parameters
        # 4-end. parameter names

        for window_name, window_internal, num_parameters, parameter_name in window_types:
            self.ui.comboBox_Window.addItem(window_name)

    def pick_widgets_for_filter_type(self):

        self.filter_data = {}  # Avoid errors if old data remains.
        if self.ui.radioButton_IIR.isChecked():
            self.ui.stackedWidget.setCurrentIndex(0)
            self.ui.stackedWidget_filterSpecs.setCurrentIndex(0)
            self.ui.stackedWidget_Parameter.setCurrentIndex(0)
            self.ui.groupBox_Filter_Type.show()
            self.ui.groupBox_paramCalc.show()
            self.config_dict['filter_IR'] = "IIR"
        elif self.ui.radioButton_FIR.isChecked():
            self.ui.stackedWidget.setCurrentIndex(1)
            self.ui.stackedWidget_filterSpecs.setCurrentIndex(1)
            self.ui.stackedWidget_Parameter.setCurrentIndex(1)
            self.ui.groupBox_Filter_Type.hide()
            self.ui.groupBox_paramCalc.hide()
            self.config_dict['filter_IR'] = "FIR"
        else:  # Should not happen...
            pass

    def add_fir_param(self):
        rows = self.ui.tableWidget_FIR.rowCount()
        self.ui.tableWidget_FIR.setRowCount(rows + 1)

    def delete_fir_param(self):
        picked = self.ui.tableWidget_FIR.currentRow()
        rows = self.ui.tableWidget_FIR.rowCount()
        print("picked ", picked)
        self.ui.tableWidget_FIR.removeRow(picked)

    def configure_boxes_for_design_parameters(self):

        if self.config_dict['filter_IR'] == 'FIR':
            return

        if self.ui.radioButton_NWn.isChecked():
            self.ui.label_opt1.setText("N: ")
            self.ui.label_opt2.setText("Freq. (Hz): ")
            self.ui.label_opt3.hide()
            self.ui.label_opt4.hide()
            self.ui.plainTextEdit_opt1.setEnabled(True)
            self.ui.plainTextEdit_opt2.setEnabled(True)
            self.ui.plainTextEdit_opt3.hide()
            self.ui.plainTextEdit_opt4.hide()

            self.ui.plainTextEdit_opt1.setToolTip("The order. "
                                                  "It must be an integer bigger than zero.")
            self.ui.plainTextEdit_opt2.setToolTip("The natural frequency(ies). \n" + BAND_MESSAGE)

            self.config_dict['mode'] = "N_WN"
        elif self.ui.radioButton_AttSpecs.isChecked():
            self.ui.label_opt1.setText("Fpass (Hz): ")
            self.ui.label_opt2.setText("Fstop (Hz): ")
            self.ui.label_opt3.setText("Apass (dB): ")
            self.ui.label_opt4.setText("Astop (dB): ")
            self.ui.label_opt3.show()
            self.ui.label_opt4.show()
            self.ui.plainTextEdit_opt3.show()
            self.ui.plainTextEdit_opt4.show()

            self.ui.plainTextEdit_opt1.setToolTip("The passband frequency(ies), in hertz. " + BAND_MESSAGE)
            self.ui.plainTextEdit_opt2.setToolTip("The stop frequency(ies), in hertz." + BAND_MESSAGE)
            self.ui.plainTextEdit_opt3.setToolTip("The attenuation at passband, in dB.")
            self.ui.plainTextEdit_opt4.setToolTip("The attenuation at stopband, in dB.")
            self.config_dict['mode'] = "specs"

        else:
            raise ValueError("Somehow we chose something that can't be chosen!")

    def get_filter_TF(self):
        """ This function gets the appropriate filter transfer-fucntion from
            the chosen options and configures the other radio buttons
            and controls accordingly. """

        if self.config_dict['filter_IR'] == 'FIR':
            return

        choice = None
        if self.ui.radioButton_Bessel.isChecked():
            print("pick Bessel")
            choice = "bessel"
        elif self.ui.radioButton_Butterworth.isChecked():
            print("pick Butterworth")
            choice = "butterworth"
        elif self.ui.radioButton_Cheby1.isChecked():
            print("pick chebyshev_1")
            choice = "chebyshev_1"
        elif self.ui.radioButton_Cheby2.isChecked():
            print("pick chebyshev_2")
            choice = "chebyshev_2"
        elif self.ui.radioButton_Elliptical.isChecked():
            print("pick elliptical")
            choice = "elliptical"

        self.config_dict['filter_TF'] = choice
        self.setup_widgets(choice)

    def get_filter_type(self):
        """ This function gets the appropriate filter type from the chosen
            options and configures the other radio buttons
            and controls accordingly. """

        choice = None
        if self.ui.radioButton_LP.isChecked():
            choice = "lowpass"
        elif self.ui.radioButton_HP.isChecked():
            choice = "highpass"
        elif self.ui.radioButton_BP.isChecked():
            choice = "bandpass"
        elif self.ui.radioButton_BS.isChecked():
            choice = "bandstop"
        elif self.ui.radioButton_AP.isChecked():
            warning(self, '', 'The allpass is not made yet.')
            choice = "allpass"
        self.config_dict['filter_type'] = choice
        print("picked filter type {}".format(self.config_dict['filter_type']))


    def setup_widgets(self, choice):
        if choice == "butterworth":
            # Butterworth filter needs to have the choice between match the
            # passband or the stopband.
            self.ui.radioButton_matchPB.setEnabled(True)
            self.ui.radioButton_matchSB.setEnabled(True)
        else:
            self.ui.radioButton_matchPB.setEnabled(False)
            self.ui.radioButton_matchSB.setEnabled(False)

        if choice == "chebyshev_1":
            # Chebyshev type-1 filter needs to have the option to
            # configure the ripple in both modes.
            self.ui.label_pbRipple.setEnabled(True)
            self.ui.label_pbRipple.setText("Passband\n ripple (dB): ")
            self.ui.plainTextEdit_pbRipple.setEnabled(True)

        elif choice == "elliptical":
            # The elliptical needs to have the both options.
            self.ui.label_pbRipple.setEnabled(True)
            self.ui.plainTextEdit_pbRipple.setEnabled(True)

        else:  # Bessel, Butterworth
            self.ui.label_pbRipple.setEnabled(False)
            self.ui.plainTextEdit_pbRipple.setEnabled(False)

        if self.config_dict['mode'] == "N_WN":
            if choice in ['chebyshev_2', 'elliptical']:
                self.ui.label_opt4.setEnabled(True)
                self.ui.label_opt4.setText("Astop (dB):")
                self.ui.label_opt4.show()
                self.ui.plainTextEdit_opt4.show()
            else:
                self.ui.label_opt4.hide()
                self.ui.plainTextEdit_opt4.hide()

    def design_filter(self):
        try:
            self.validate_common()
            if self.config_dict['filter_IR'] == 'IIR':
                self.validate_IIR()
                self.build_IIR_struct()
                self.actually_design_IIR_filter()
            elif self.config_dict['filter_IR'] == 'FIR':
                self.validate_FIR()
                self.build_FIR_struct()
                self.actually_design_FIR_filter()

            self.report()
            self.plot()
        except Exception as went_wrong:
            critical(self, 'Error', str(went_wrong))
            print("Internal error happened! Please report the traceback to the developer.")
            print("The traceback is: ")
            print("---------------------------")
            print(traceback.format_exc())
            print("---------------------------")
            return

    def validate_common(self):
        """ Validate the inputs that are used
            for both FIR and IIR filter designs. """
        try:
            sample_rate = float(self.ui.textEdit_SampleRate.toPlainText())
            if sample_rate <= 0:
                raise ValueError("must be positive")
        except:
            raise ValueError("Sample rate must be positive.")

        self.config_dict['sample_rate'] = sample_rate

    def validate_IIR(self):
        def validate_common():
            if self.config_dict['filter_TF'] in ['bessel', 'butterworth']:
                return # not needed to enter here

            if self.config_dict['filter_TF'] in ['elliptical', 'chebyshev_2']:
                # Needs stopband attenuation
                stopband_attenuation = self.ui.plainTextEdit_opt4.toPlainText()
                try:
                    stopband_attenuation = float(stopband_attenuation)
                    if stopband_attenuation <= 0:
                        raise ValueError("must be positive")
                except:
                    raise ValueError("Stopband attenuation must be positive.")
                self.filter_data['stopband_attenuation'] = stopband_attenuation
                print(">> Stopband attenuation (dB): ", stopband_attenuation)

            if self.config_dict['filter_TF'] in ['elliptical', 'chebyshev_1']:
                ripple = self.ui.plainTextEdit_pbRipple.toPlainText()
                try:
                    ripple = float(ripple)
                    if ripple <= 0:
                        raise ValueError("must be positive")
                except:
                    raise ValueError("Ripple must be positive.")
                self.filter_data['ripple'] = ripple
                print(">> Ripple (dB): ", ripple)

        def validate_n_wn():
            N = self.ui.plainTextEdit_opt1.toPlainText()
            try:
                N = int(N)
                if N <= 0 or N > 500:
                    raise ValueError("out of range")
            except:
                raise ValueError("Filter order must be between 0 and 500.")
            pass
            self.filter_data['N'] = N
            print(">> N: ", self.filter_data['N'])

            # Validate Wn
            Wn = self.ui.plainTextEdit_opt2.toPlainText()
            if 'band' in self.config_dict['filter_type']:
                try:
                    Wn = Wn.split(' ')[0:2]
                    Wn = [2 * pi * float(Wn[0]), 2 * pi * float(Wn[1])]
                except:
                    raise ValueError("Needs two parameters for Wn.")
            else:
                try:
                    Wn = Wn.split(' ')[0]
                    Wn = 2 * pi * float(Wn)
                    if Wn <= 0:
                        raise ValueError("Wn must be positive.")
                except:
                    raise ValueError("Wn must be a positive number.")
            self.filter_data['Wn'] = Wn

            print(">> Wn: ", self.filter_data['Wn'])

        def validate_specs():
            Wp = self.ui.plainTextEdit_opt1.toPlainText()
            Ws = self.ui.plainTextEdit_opt2.toPlainText()
            Rp = self.ui.plainTextEdit_opt3.toPlainText()
            Rs = self.ui.plainTextEdit_opt4.toPlainText()

            if 'band' in self.config_dict['filter_type']:
                try:
                    print(Wp, Ws)
                    Wp = Wp.split(' ')
                    Ws = Ws.split(' ')
                    Wp = [float(Wp[0]), float(Wp[1])]
                    Ws = [float(Ws[0]), float(Ws[1])]
                    if Wp[0] <= 0 or Ws[0] <= 0 or Wp[1] <= 0 or Ws[1] <= 0:
                        raise ValueError("must be positive.")
                except:
                    raise ValueError("Both Wp and Ws need 2 positive parameters.")
            else:
                try:
                    Wp = float(Wp)
                    Ws = float(Ws)
                    if Wp <= 0 or Ws <= 0:
                        raise ValueError("must be positive.")
                except:
                    raise ValueError("Both Wp and Ws must be positive.")

            # Validate according to filter type chosen.

            if 'band' in self.config_dict['filter_type']:
                pb0, pb1, sb0, sb1 = Wp[0], Wp[1], Ws[0], Ws[1]
                if self.config_dict['filter_type'] == 'bandpass':
                    if not (pb0 > sb0 and pb1 < sb1):
                        raise ValueError("The bandpass filter needs that the passband "
                                         "be inside the stopband.")
                elif self.config_dict['filter_type'] == 'bandstop':
                    if not (pb0 < sb0 and pb1 > sb1):
                        raise ValueError("The bandstop filter needs that the stopband "
                                         "be inside the passband.")
            self.filter_data['passband_frequency'] = Wp
            self.filter_data['stopband_frequency'] = Ws
            self.filter_data['passband_attenuation'] = Rp
            self.filter_data['stopband_attenuation'] = Rs

        validate_common()
        if self.config_dict['mode'] == "N_WN":
            validate_n_wn()
        elif self.config_dict['mode'] == "specs":
            validate_specs()

    def validate_FIR(self):

        frequencies = []
        gains = []
        num_params = 0

        def validate_FIR_Window():
            for row_number in range(self.ui.tableWidget_FIR.rowCount()):
                frequency = float(self.ui.tableWidget_FIR.item(row_number, 0).text())
                gain = float(self.ui.tableWidget_FIR.item(row_number, 1).text())
                print("Item ", row_number, " is ", frequency, "/", gain)
                if not (0 <= frequency <= self.config_dict['sample_rate']/2):
                    raise ValueError("Frequencies must be between 0 and sample_rate / 2.")
                frequencies.append(frequency)
                gains.append(gain)
            print("Frequency vector is ", frequencies)
            print("Gain vector is ", gains)
            num_params = window_types[self.window_index][2]
            parameter_name = window_types[self.window_index][2 + num_params]
            print("Window type is ", window_types[self.window_index][1] )

            if num_params > 0:
                print("Window has ", num_params, "parameters")
                print("Parameter is ", parameter_name)

        def validate_FIR_Parks():
            for row_number in range(self.ui.tableWidget_FIR.rowCount()):
                band = self.ui.tableWidget_FIR.item(row_number, 0).text()
                gain = float(self.ui.tableWidget_FIR.item(row_number, 1).text())
                band_low, band_high = band.split(' ')[0:2]
                print("Band ", row_number, " is ", band_low, " to ", band_high, " gain = ", gain)
                frequencies.append(float(band_low))
                frequencies.append(float(band_high))
                gains.append(gain)
            print("Frequency vector is ", frequencies)
            print("Gain vector is ", gains)


        if self.config_dict['FIR_Mode'] == 'Window':
            validate_FIR_Window()
        elif self.config_dict['FIR_Mode'] == 'Parks':
            validate_FIR_Parks()

        self.filter_data['frequencies'] = frequencies
        self.filter_data['gains'] = gains
        self.filter_data['sample_rate'] = self.config_dict['sample_rate']
        self.filter_data['antisymmetric'] = self.ui.checkBox_antiSymmetric.isChecked()
        self.filter_data['taps'] = self.ui.spinBox_Taps.value()

        if num_params == 0:
            self.filter_data['window'] = window_types[self.window_index][1]
        elif num_params == 1:
            window_param = float(self.ui.plainTextEdit_option1.text())
            window_tuple = (window_types[self.window_index][1], window_param)
            self.filter_data['window'] = window_tuple
        if self.config_dict['FIR_Mode'] == 'Parks':
            self.filter_data['window'] = None


    def build_FIR_struct(self):

        self.filter_design = digital.FIRFilter()
        if self.config_dict['FIR_Mode'] == 'Window':
            self.filter_design.sample_rate = self.filter_data['sample_rate']
            self.filter_design.taps = self.filter_data['taps']
            self.filter_design.freqs = self.filter_data['frequencies']
            self.filter_design.gains = self.filter_data['gains']
            self.filter_design.window = self.filter_data['window']
            self.filter_design.antisymmetric = self.filter_data['antisymmetric']
        elif self.config_dict['FIR_Mode'] == 'Parks':
            self.filter_design.sample_rate = self.filter_data['sample_rate']
            self.filter_design.taps = self.filter_data['taps']
            self.filter_design.freqs = self.filter_data['frequencies']
            self.filter_design.gains = self.filter_data['gains']
            self.filter_design.window = None


    def build_IIR_struct(self):
        config = {}
        def build_struct_common():
            if self.config_dict['filter_TF'] == "butterworth":
                self.filter_design = digital.ButterworthFilter()
            elif self.config_dict['filter_TF'] == "chebyshev_1":
                self.filter_design = digital.ChebyshevIFilter()
            elif self.config_dict['filter_TF'] == "chebyshev_2":
                self.filter_design = digital.ChebyshevIIFilter()
            elif self.config_dict['filter_TF'] == "bessel":
                self.filter_design = digital.BesselFilter()
            elif self.config_dict['filter_TF'] == "elliptical":
                self.filter_design = digital.EllipticFilter()
            else:  # Should never happen, but... you never know.
                raise ValueError("Unknown filter type requested!!")
            self.filter_design.sample_rate = 2*pi*self.config_dict['sample_rate']

        def build_struct_n_wn():
            """ Builds the data structure for filter given the N, Wn. """
            self.filter_design.N = self.filter_data['N']
            self.filter_design.Wn = self.filter_data['Wn']
            self.filter_design.filter_kind = self.config_dict['filter_type']
            if hasattr(self.filter_design, "ripple"):
                self.filter_design.ripple = self.filter_data['ripple']
            if hasattr(self.filter_design, "stopband_attenuation"):
                self.filter_design.stopband_attenuation = self.filter_data['stopband_attenuation']

        def build_struct_specs():
            """ Builds the data structure for filter given the specifications. """

            if 'band' in self.config_dict['filter_type']:
                config['passband_frequency'] = list(map(float, self.filter_data['passband_frequency']))
                config['stopband_frequency'] = list(map(float, self.filter_data['stopband_frequency']))
            else:
                config['passband_frequency'] = float(self.filter_data['passband_frequency'])
                config['stopband_frequency'] = float(self.filter_data['stopband_frequency'])

            if self.config_dict['filter_type'] == "highpass": # The object model requires this.
                config['passband_frequency'] = float(self.filter_data['stopband_frequency'])
                config['stopband_frequency'] = float(self.filter_data['passband_frequency'])

            config['passband_attenuation'] = float(self.filter_data['passband_attenuation'])
            config['stopband_attenuation'] = float(self.filter_data['stopband_attenuation'])

            if hasattr(self.filter_design, "ripple"):
                self.filter_design.ripple = self.filter_data['ripple']
            if hasattr(self.filter_design, "stopband_attenuation"):
                self.filter_design.stopband_attenuation = float(self.filter_data['stopband_attenuation'])
            if hasattr(self.filter_design, "target"):
                if self.ui.radioButton_matchPB.isChecked():
                    self.filter_design.target = 'passband'
                elif self.ui.radioButton_matchSB.isChecked():
                    self.filter_design.target = 'stopband'
                else:
                    raise NotImplementedError("WHAT? Target is not passband or stopband?")

            self.filter_design.set_parameters(config)
            self.filter_design.compute_parameters()

            print("You asked for", self.config_dict['filter_type'],
                  " you got ", self.filter_design.filter_kind)
            if self.config_dict['filter_type'] != self.filter_design.filter_kind:
                print("You didn't get what you asked for. This means a bug. Report.")
                raise SystemError("Filter asked is not filter got!")

        build_struct_common()
        if self.config_dict['mode'] == "N_WN":
            build_struct_n_wn()
        elif self.config_dict['mode'] == "specs":
            build_struct_specs()

    def actually_design_IIR_filter(self):
        """ Where the actual design happens. """
        print("-------------------------")
        print("Begin IIR filter design.")
        self.filter_design.design()
        print("Design finished.")
        print("Z: ", self.filter_design.Z)
        print("P: ", self.filter_design.P)
        print("K: ", self.filter_design.K)
        print("B: ", self.filter_design.B)
        print("A: ", self.filter_design.A)
        print("-------------------------")

    def actually_design_FIR_filter(self):
        print("-------------------------")
        print("Begin FIR filter design.")
        self.filter_design.design()
        print("Design finished.")
        print("B: ", self.filter_design.B)
        print("-------------------------")

    def report(self):
        self.ui.pushButton_saveToFile.setEnabled(True)
        html = utils.HTMLReport()
        html.put_text("<body bgcolor=\"white\">")
        html.put_text("Transfer function: ")
        html.put_newline()
        try:
            html.put_polynomial(self.filter_design.B,
                                self.filter_design.A,
                                variable='z')
        except:
            html.put_polynomial(self.filter_design.B, [1],
                                variable='z')


        html.put_text("Coefficients:")

        if not isinstance(self.filter_design, digital.FIRFilter):
            len_B = len(self.filter_design.B)
            len_A = len(self.filter_design.A)
            pad_len = abs(len_B - len_A)

            padded_B = [0] * pad_len
            print("need to pad with ", pad_len)

            for element in self.filter_design.B:
                padded_B.append(element)

            print("after padding, B became ", padded_B)

            len_order = max(len_B, len_A)
            coeffs = list(reversed(range(0, len_order+1)))
            coeffs = list(map(lambda x: x-1, coeffs))
        else:
            len_B = len(self.filter_design.B)
            coeffs = list(reversed(range(0, len_B+1)))
            coeffs = list(map(lambda x: x-1, coeffs))

        # Keep track of the file names we've used for the reports,
        # then at the end of the program we can delete 'em.
        self.file_names.append(html.output.name)
        url = QtCore.QUrl(html.output.name)

        if not isinstance(self.filter_design, digital.FIRFilter):
            columns = ['', 'B (num)', 'A (den)']
            data = [coeffs,
                    padded_B,
                    self.filter_design.A]
        else:
            columns = ['', 'B']
            data = [coeffs, self.filter_design.B]

        html.put_newline()
        html.put_table(columns, data)
        html.put_text("</body>")
        html.write(close=True)
        self.ui.tfOutputHTML.load(url)

    def plot(self):
        self.filter_design.compute_frequencies(N=1000)
        #self.ui.graphicsView.hide()
        #self.ui.graphicsView_2.hide()
        #self.ui.tab_plot.hide()

        # Build the tab used for plotting.

        plot_tab = QtGui.QWidget()
        plot_tab_layout = QtGui.QVBoxLayout()
        plot_tab_splitter = QtGui.QSplitter()
        plot_tab_splitter.setOrientation(QtCore.Qt.Vertical)
        plot_tab.setLayout(plot_tab_layout)

        self.ui.tabWidget.addTab(plot_tab, "Frequency Response")

        plot_tab_layout.addWidget(plot_tab_splitter)

        self.ui.magnitudePlotWidget = canvas.StaticPlot(plot_tab_splitter, width=9,
                                                        height=6, dpi=80)

        nyquist = self.config_dict['sample_rate']
        W_Hz = nyquist*(self.filter_design.W / (2*pi))
        self.ui.magnitudePlotWidget.compute_initial_figure(W_Hz,
                                                           20 * log10(abs(self.filter_design.H)),
                                                           mode="logx")
        self.ui.magnitudePlotWidget.set_label("Frequency (Hz)", "Gain (dB)")

        if isinstance(self.filter_design.Wn, float):
            self.ui.magnitudePlotWidget.add_line('x', self.filter_design.Wn / (2*pi))
        else:
            try:
                for value in self.filter_design.Wn:
                    self.ui.magnitudePlotWidget.add_line('x', value / (2*pi))
            except:
                pass # FIR filter

        self.ui.magnitudeGraphToolbar = NavigationToolbar(self.ui.magnitudePlotWidget,
                                                          self)
        plot_tab_splitter.addWidget(self.ui.magnitudeGraphToolbar)

        self.ui.phasePlotWidget = canvas.StaticPlot(plot_tab_splitter, width=9,
                                                    height=6, dpi=80)
        self.ui.phasePlotWidget.compute_initial_figure(W_Hz,
                                                       unwrap(angle(self.filter_design.H)) * 180/pi,
                                                       mode="logx")
        self.ui.phasePlotWidget.set_label("Frequency (Hz)", "Phase (°)")
        self.ui.phaseGraphToolbar = NavigationToolbar(self.ui.phasePlotWidget,
                                                      self)
        plot_tab_splitter.addWidget(self.ui.phaseGraphToolbar)

    def write_plots_to_file(self):
        save_dialog = QtGui.QFileDialog()
        file_name_to_save = save_dialog.getSaveFileName(self, "Save plots...", "",
                                                        "Images (*.png *.jpg *.svg)")
        if file_name_to_save:
            self.ui.magnitudePlotWidget.dump(file_name_to_save)

    def destroy_tab(self, tab_id):
        if tab_id == 0:
            return # The results tab shall not close.
        self.ui.tabWidget.removeTab(tab_id)