Esempio n. 1
0
    def __init__(self, login_dialog):
        super(MainDialog, self).__init__()
        # recovering UI from main_ui.py file
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        # got to save user name and login dialog
        self._user = str()
        self.lg = login_dialog

        # connecting logout press to logout action
        self.ui.pushButton_4.clicked.connect(self.logout)

        # loading list of queries
        self.queries = list()
        fname = path.join('.profile', 'queries')
        if path.isfile(fname):
            for line in open(path.join('.profile', 'queries')).read().split(':;:'):
                if '::' not in line:
                    continue
                query = line.split(':::')
                self.queries.append(query)
        # sorting them in alphabetic order
        self.queries.sort(key=lambda x: x[0])
        # adding queries to combo boxes
        for query in self.queries:
            self.ui.comboBox.addItem(query[0])

        # connecting buttons to their respective actions
        self.ui.comboBox.currentIndexChanged.connect(self.query_changed)
        self.ui.pushButton_2.clicked.connect(self.new_query)
        self.ui.pushButton_3.clicked.connect(self.remove_query)
        self.ui.pushButton.clicked.connect(self.run_query)

        # connecting to the database
        self.db = dataset.connect(f'postgresql://{DBUSERNAME}:{DBPASSWORD}@localhost:5432/{DBNAME}')

        # creating plot and legend objects
        self.cv = Canvas(self.ui.frame_3)
        self.legend_labels = [(self.ui.label_2, self.ui.label_3)]
Esempio n. 2
0
 def __init__(self):
     super().__init__()
     ui = Main_UI()
     ui.setupUi(self)
     self.ui = ui
     self._init_ui()
Esempio n. 3
0
class MainDialog(QDialog):
    def __init__(self, login_dialog):
        super(MainDialog, self).__init__()
        # recovering UI from main_ui.py file
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        # got to save user name and login dialog
        self._user = str()
        self.lg = login_dialog

        # connecting logout press to logout action
        self.ui.pushButton_4.clicked.connect(self.logout)

        # loading list of queries
        self.queries = list()
        fname = path.join('.profile', 'queries')
        if path.isfile(fname):
            for line in open(path.join('.profile', 'queries')).read().split(':;:'):
                if '::' not in line:
                    continue
                query = line.split(':::')
                self.queries.append(query)
        # sorting them in alphabetic order
        self.queries.sort(key=lambda x: x[0])
        # adding queries to combo boxes
        for query in self.queries:
            self.ui.comboBox.addItem(query[0])

        # connecting buttons to their respective actions
        self.ui.comboBox.currentIndexChanged.connect(self.query_changed)
        self.ui.pushButton_2.clicked.connect(self.new_query)
        self.ui.pushButton_3.clicked.connect(self.remove_query)
        self.ui.pushButton.clicked.connect(self.run_query)

        # connecting to the database
        self.db = dataset.connect(f'postgresql://{DBUSERNAME}:{DBPASSWORD}@localhost:5432/{DBNAME}')

        # creating plot and legend objects
        self.cv = Canvas(self.ui.frame_3)
        self.legend_labels = [(self.ui.label_2, self.ui.label_3)]

    # this is triggered when admin pressed "Remove query"
    @pyqtSlot()
    def remove_query(self):
        # removing cquery from combox box and list of queries
        index = self.ui.comboBox.currentIndex()
        self.queries.pop(index)
        self.ui.comboBox.removeItem(index)
        self.update()

    # this is triggered when user/admin presses 'Run Query' button
    @pyqtSlot()
    def run_query(self):
        # we get text of the current query from text field
        query = self.ui.plainTextEdit.toPlainText()
        # removing all rows from table widget
        self.ui.tableWidget.setRowCount(0)
        # creating vars for setting up headers
        columns_set = False
        header = list()
        try:
            for i, row in enumerate(self.db.query(query)):
                # adding new row to the table widget
                self.ui.tableWidget.insertRow(i)
                # setting up headers
                if not columns_set:
                    header = list(row.keys())
                    self.ui.tableWidget.setColumnCount(len(header))
                    self.ui.tableWidget.setHorizontalHeaderLabels(header)
                    columns_set = True
                # adding values to the fresh row
                for j, col in enumerate(header):
                    self.ui.tableWidget.setItem(i, j, QTableWidgetItem(str(row[col])))
        except Exception as e:
            print(type(e), e)
        # checking if this query is plottable and calling the plot function
        query_info = self.queries[self.ui.comboBox.currentIndex()]
        if query_info[-1].strip() == 'plotit':
            self.plot_chart(self.db.query(query), query_info)

    def plot_chart(self, data, query_info):
        # plots the chart
        # clears any legend widgets
        for lcolor, ltext in self.legend_labels:
            lcolor.setParent(None)
            ltext.setParent(None)
        self.legend_labels = list()
        # gets new legends from matplotlib object & plots the chart
        legends = self.cv.plot(data, query_info)
        # making sure plot is visible on its tab
        self.ui.tabWidget.setCurrentIndex(1)
        # we wont have space to show all the legends, so limiting it
        max_legend = 20
        try:
            # going through all legends returned and creating labels for them
            for i, leg in enumerate(legends):
                # breaknig is max legend number is met
                if i > max_legend:
                    break
                # creating color label
                lcolor = QLabel(parent=self.ui.groupBox, text="---")
                self.ui.formLayout.setWidget(i, QFormLayout.LabelRole, lcolor)
                # coloring it
                qp = QPalette()
                qp.setColor(lcolor.backgroundRole(), QColor(*[255 * l for l in leg[1]]))
                qp.setColor(lcolor.foregroundRole(), QColor(*[255 * l for l in leg[1]]))
                lcolor.setAutoFillBackground(True)
                lcolor.setPalette(qp)
                # creating legend name label
                ltext = QLabel(parent=self.ui.groupBox, text=leg[0])
                self.ui.formLayout.setWidget(i, QFormLayout.FieldRole, ltext)
                # saving this widget pair
                self.legend_labels.append((lcolor, ltext))
        except Exception as e:
            print(e)
        return

    # this is triggered when admin hits "Add Query" button
    @pyqtSlot()
    def new_query(self):
        # creating new query object
        query = (
            self.ui.lineEdit.text(),
            self.ui.plainTextEdit.toPlainText()
        )
        # adding it to queries and combobox
        self.queries.append(query)
        self.ui.comboBox.addItem(query[0])
        # setting new query as currently selected
        self.ui.comboBox.setCurrentIndex(len(self.queries) - 1)

    # this happens when combo box chooses another query
    @pyqtSlot()
    def query_changed(self):
        query = self.queries[self.ui.comboBox.currentIndex()]
        # updating edit field and query title fields
        self.ui.lineEdit.setText(query[0])
        self.ui.plainTextEdit.setPlainText(query[1])

    # this is for login window to call prior to displaying = sets up rights
    def set_user(self, user):
        self.ui.label.setText(f'Logged in as {user}')
        # admin has access to editing all
        if user == 'Admin':
            self.ui.plainTextEdit.setDisabled(False)
            self.ui.lineEdit.show()
            self.ui.pushButton_2.show()
            self.ui.pushButton_3.show()
        # users are more of a read only type
        else:
            self.ui.plainTextEdit.setDisabled(True)
            self.ui.lineEdit.hide()
            self.ui.pushButton_2.hide()
            self.ui.pushButton_3.hide()
        self.query_changed()
        self.ui.tableWidget.setRowCount(0)
        self.ui.tableWidget.setColumnCount(0)
        self.ui.tabWidget.setCurrentIndex(0)

    # this happens when login button is pressed
    @pyqtSlot()
    def logout(self):
        # going back to logout window
        self.hide()
        self.lg.show()

    # this is triggered when application is about to exit
    def closeEvent(self, a0):
        # saving queries to the file
        with open(path.join('.profile', 'queries'), 'w') as f:
            f.write(':;:'.join([f':::'.join(q) for q in self.queries]))
        a0.accept()
    def __init__(self, parent, app_list):
        # QDialog.__init__(self)
        QWidget.__init__(self)
        Ui_Dialog.__init__(self)

        self.current_plugin = None
        self.gui = get_gui()
        self.icon = parent.icon
        self.parent = parent
        self.prefs = parent.prefs
        self.resources_path = parent.resources_path
        self.verbose = parent.verbose
        self._log_location(app_list)
        self.setupUi(self)
        self.support_label.setOpenExternalLinks(True)
        self.version = parent.version

        # Restore the debug settings
        self.debug_plugin.setChecked(self.prefs.get("debug_plugin", False))
        self.debug_libimobiledevice.setChecked(self.prefs.get("debug_libimobiledevice", False))

        # Load the widgets
        self.widgets = []
        for app_name in app_list:
            name = app_name.lower().replace(" ", "_")
            # Load dynamic tab
            klass = os.path.join(widget_path, "%s.py" % name)
            if os.path.exists(klass):
                try:
                    self._log_location("adding widget for %s" % name)
                    sys.path.insert(0, widget_path)
                    config_widget = importlib.import_module(name)
                    pw = config_widget.PluginWidget(self)
                    pw.initialize(name)
                    pw.ICON = I("forward.png")
                    self.widgets.append(pw)
                except ImportError:
                    self._log("ERROR: ImportError with %s" % name)
                    import traceback

                    traceback.print_exc()
                finally:
                    sys.path.remove(widget_path)
            else:
                self._log("no dynamic tab resources found for %s" % name)

        self.widgets = sorted(self.widgets, cmp=lambda x, y: cmp(x.TITLE.lower(), y.TITLE.lower()))

        # Callbacks when reader_app changes
        # self.reader_apps.currentIndexChanged.connect(self.restart_required)
        # self.debug_plugin.stateChanged.connect(self.restart_required)
        # self.debug_libimobiledevice.stateChanged.connect(self.restart_required)

        # Add the app_list to the dropdown
        self.reader_apps.blockSignals(True)
        self.reader_apps.addItems([""])
        self.reader_apps.addItems(sorted(app_list, key=lambda s: s.lower()))

        # Get the last-used reader_app
        pref = self.prefs.get("preferred_reader_app", "")
        idx = self.reader_apps.findText(pref)
        if idx > -1:
            self.reader_apps.setCurrentIndex(idx)
        self.reader_apps.blockSignals(False)

        # Init the plugin tab to currently selected reader app
        self.reader_apps.currentIndexChanged.connect(self.show_plugin_tab)
        self.show_plugin_tab(None)
Esempio n. 5
0
    def __init__(self):
        super().__init__()
        self._ui = Ui_Dialog()
        self._ui.setupUi(self)

        self.label_w = self._ui.label_pix.width()
        self.label_h = self._ui.label_pix.height()
        self.content = Content(self)

        # ====================================================
        # set music
        pygame.init()
        print("有音樂哦! 注意聽 ~~~")
        pygame.mixer.init()
        pygame.mixer.music.load(self.music_path("music/main.mp3"))
        pygame.mixer.music.play(-1, 8)

        # ====================================================
        # set icon style
        stylesheet = "QPushButton {background: transparent}"

        self._ui.pushButton_home.setIconSize(QSize(32, 32))
        self._ui.pushButton_home.setIcon(QIcon(':/pix/home.png'))

        self._ui.pushButton_love.setIconSize(QSize(32, 32))
        self._ui.pushButton_love.setIcon(QIcon(':/pix/love.png'))

        self._ui.pushButton_next.setIconSize(QSize(32, 32))
        self._ui.pushButton_next.setIcon(QIcon(':/pix/next.png'))

        self._ui.pushButton_previous.setIconSize(QSize(32, 32))
        self._ui.pushButton_previous.setIcon(QIcon(':/pix/previous.png'))

        self._ui.pushButton_heart.setIconSize(QSize(32, 32))
        self._ui.pushButton_heart.setIcon(QIcon(':/pix/heart.png'))

        self._ui.pushButton_play.setIconSize(QSize(32, 32))
        self._ui.pushButton_play.setIcon(QIcon(':/pix/play.png'))

        self._ui.pushButton_close.setIconSize(QSize(32, 32))
        self._ui.pushButton_close.setIcon(QIcon(':/pix/close.png'))

        self._ui.pushButton_click.setIconSize(QSize(32, 32))
        self._ui.pushButton_click.setIcon(QIcon(':/pix/click.png'))

        self._ui.pushButton_start.setIconSize(QSize(32, 32))
        self._ui.pushButton_start.setIcon(QIcon(':/pix/start.png'))

        self._ui.pushButton_1.setIconSize(QSize(80, 80))
        self._ui.pushButton_1.setIcon(QIcon(':/pix/num_1.png'))
        self._ui.pushButton_1.setStyleSheet(stylesheet)

        self._ui.pushButton_2.setIconSize(QSize(80, 80))
        self._ui.pushButton_2.setIcon(QIcon(':/pix/num_2.png'))
        self._ui.pushButton_2.setStyleSheet(stylesheet)

        self._ui.pushButton_3.setIconSize(QSize(80, 80))
        self._ui.pushButton_3.setIcon(QIcon(':/pix/num_3.png'))
        self._ui.pushButton_3.setStyleSheet(stylesheet)

        self._ui.pushButton_4.setIconSize(QSize(80, 80))
        self._ui.pushButton_4.setIcon(QIcon(':/pix/num_4.png'))
        self._ui.pushButton_4.setStyleSheet(stylesheet)

        self._ui.pushButton_5.setIconSize(QSize(80, 80))
        self._ui.pushButton_5.setIcon(QIcon(':/pix/num_5.png'))
        self._ui.pushButton_5.setStyleSheet(stylesheet)

        self._ui.pushButton_6.setIconSize(QSize(80, 80))
        self._ui.pushButton_6.setIcon(QIcon(':/pix/num_6.png'))
        self._ui.pushButton_6.setStyleSheet(stylesheet)

        self._ui.pushButton_7.setIconSize(QSize(80, 80))
        self._ui.pushButton_7.setIcon(QIcon(':/pix/num_7.png'))
        self._ui.pushButton_7.setStyleSheet(stylesheet)

        self._ui.pushButton_8.setIconSize(QSize(80, 80))
        self._ui.pushButton_8.setIcon(QIcon(':/pix/num_8.png'))
        self._ui.pushButton_8.setStyleSheet(stylesheet)

        self._ui.pushButton_9.setIconSize(QSize(80, 80))
        self._ui.pushButton_9.setIcon(QIcon(':/pix/num_9.png'))
        self._ui.pushButton_9.setStyleSheet(stylesheet)

        # =====================================================
        self.count = 0
        self.on_pushButton_home_clicked()
Esempio n. 6
0
class MyWindow(QMainWindow, QDialog):
    def __init__(self):
        super().__init__()
        self._ui = Ui_Dialog()
        self._ui.setupUi(self)

        self.label_w = self._ui.label_pix.width()
        self.label_h = self._ui.label_pix.height()
        self.content = Content(self)

        # ====================================================
        # set music
        pygame.init()
        print("有音樂哦! 注意聽 ~~~")
        pygame.mixer.init()
        pygame.mixer.music.load(self.music_path("music/main.mp3"))
        pygame.mixer.music.play(-1, 8)

        # ====================================================
        # set icon style
        stylesheet = "QPushButton {background: transparent}"

        self._ui.pushButton_home.setIconSize(QSize(32, 32))
        self._ui.pushButton_home.setIcon(QIcon(':/pix/home.png'))

        self._ui.pushButton_love.setIconSize(QSize(32, 32))
        self._ui.pushButton_love.setIcon(QIcon(':/pix/love.png'))

        self._ui.pushButton_next.setIconSize(QSize(32, 32))
        self._ui.pushButton_next.setIcon(QIcon(':/pix/next.png'))

        self._ui.pushButton_previous.setIconSize(QSize(32, 32))
        self._ui.pushButton_previous.setIcon(QIcon(':/pix/previous.png'))

        self._ui.pushButton_heart.setIconSize(QSize(32, 32))
        self._ui.pushButton_heart.setIcon(QIcon(':/pix/heart.png'))

        self._ui.pushButton_play.setIconSize(QSize(32, 32))
        self._ui.pushButton_play.setIcon(QIcon(':/pix/play.png'))

        self._ui.pushButton_close.setIconSize(QSize(32, 32))
        self._ui.pushButton_close.setIcon(QIcon(':/pix/close.png'))

        self._ui.pushButton_click.setIconSize(QSize(32, 32))
        self._ui.pushButton_click.setIcon(QIcon(':/pix/click.png'))

        self._ui.pushButton_start.setIconSize(QSize(32, 32))
        self._ui.pushButton_start.setIcon(QIcon(':/pix/start.png'))

        self._ui.pushButton_1.setIconSize(QSize(80, 80))
        self._ui.pushButton_1.setIcon(QIcon(':/pix/num_1.png'))
        self._ui.pushButton_1.setStyleSheet(stylesheet)

        self._ui.pushButton_2.setIconSize(QSize(80, 80))
        self._ui.pushButton_2.setIcon(QIcon(':/pix/num_2.png'))
        self._ui.pushButton_2.setStyleSheet(stylesheet)

        self._ui.pushButton_3.setIconSize(QSize(80, 80))
        self._ui.pushButton_3.setIcon(QIcon(':/pix/num_3.png'))
        self._ui.pushButton_3.setStyleSheet(stylesheet)

        self._ui.pushButton_4.setIconSize(QSize(80, 80))
        self._ui.pushButton_4.setIcon(QIcon(':/pix/num_4.png'))
        self._ui.pushButton_4.setStyleSheet(stylesheet)

        self._ui.pushButton_5.setIconSize(QSize(80, 80))
        self._ui.pushButton_5.setIcon(QIcon(':/pix/num_5.png'))
        self._ui.pushButton_5.setStyleSheet(stylesheet)

        self._ui.pushButton_6.setIconSize(QSize(80, 80))
        self._ui.pushButton_6.setIcon(QIcon(':/pix/num_6.png'))
        self._ui.pushButton_6.setStyleSheet(stylesheet)

        self._ui.pushButton_7.setIconSize(QSize(80, 80))
        self._ui.pushButton_7.setIcon(QIcon(':/pix/num_7.png'))
        self._ui.pushButton_7.setStyleSheet(stylesheet)

        self._ui.pushButton_8.setIconSize(QSize(80, 80))
        self._ui.pushButton_8.setIcon(QIcon(':/pix/num_8.png'))
        self._ui.pushButton_8.setStyleSheet(stylesheet)

        self._ui.pushButton_9.setIconSize(QSize(80, 80))
        self._ui.pushButton_9.setIcon(QIcon(':/pix/num_9.png'))
        self._ui.pushButton_9.setStyleSheet(stylesheet)

        # =====================================================
        self.count = 0
        self.on_pushButton_home_clicked()

    # =======================================================
    # set music
    def music_path(self, real_path):
        if hasattr(sys, "_MEIPASS"):
            base_path = sys._MEIPASS

        else:
            base_path = os.path.abspath(".")

        return os.path.join(base_path, real_path)

    # =====================================================
    # content
    @pyqtSlot()
    def on_pushButton_home_clicked(self):
        self._ui.stackedWidget.setCurrentIndex(0)
        self.content.home_control()

    @pyqtSlot()
    def on_pushButton_love_clicked(self):
        self._ui.stackedWidget.setCurrentIndex(0)
        self.content.love_control()
        self.count = 1

    @pyqtSlot()
    def on_pushButton_next_clicked(self):
        self._ui.stackedWidget.setCurrentIndex(0)
        self.count += 1
        count = self.content.next_control(self.count)
        self.count = count

    @pyqtSlot()
    def on_pushButton_previous_clicked(self):
        self._ui.stackedWidget.setCurrentIndex(0)
        self.count -= 1
        count = self.content.previous_control(self.count)
        self.count = count

    @pyqtSlot()
    def on_pushButton_heart_clicked(self):
        message = QMessageBox.question(self, "Reminder", '接下來會有驚喜哦!\n\n 你 準備好了嗎?')
        if message == QMessageBox.Yes:
            self._ui.stackedWidget.setCurrentIndex(1)
            self.content.heart_control(self.count)
            self.heart = 0

    @pyqtSlot()
    def on_pushButton_click_clicked(self):
        heart = self.content.heart_click_control(self.heart, self.count)
        self.heart = heart

    # =====================================================
    # play game
    @pyqtSlot()
    def on_pushButton_play_clicked(self):
        self.content.play_control()

    @pyqtSlot()
    def on_pushButton_start_clicked(self):
        self.content.start_control()

    @pyqtSlot()
    def on_pushButton_1_clicked(self):
        self.content.btn_1_control()

    @pyqtSlot()
    def on_pushButton_2_clicked(self):
        self.content.btn_2_control()

    @pyqtSlot()
    def on_pushButton_3_clicked(self):
        self.content.btn_3_control()

    @pyqtSlot()
    def on_pushButton_4_clicked(self):
        self.content.btn_4_control()

    @pyqtSlot()
    def on_pushButton_5_clicked(self):
        self.content.btn_5_control()

    @pyqtSlot()
    def on_pushButton_6_clicked(self):
        self.content.btn_6_control()

    @pyqtSlot()
    def on_pushButton_7_clicked(self):
        self.content.btn_7_control()

    @pyqtSlot()
    def on_pushButton_8_clicked(self):
        self.content.btn_8_control()

    @pyqtSlot()
    def on_pushButton_9_clicked(self):
        self.content.btn_9_control()

    # =====================================================
    @pyqtSlot()
    def on_pushButton_close_clicked(self):
        self.close()
    def __init__(self, parent, app_list):
        #QDialog.__init__(self)
        QWidget.__init__(self)
        Ui_Dialog.__init__(self)
        self.current_plugin = None
        self.gui = get_gui()
        self.icon = parent.icon
        self.parent = parent
        self.prefs = parent.prefs
        self.resources_path = parent.resources_path
        self.verbose = parent.verbose
        self._log_location(app_list)
        self.setupUi(self)
        self.version = parent.version

        # Restore the caching settings
        device_caching_enabled = self.prefs.get('device_booklist_caching', False)
        self.device_booklist_caching_cb.setChecked(device_caching_enabled)
        self.device_booklist_cache_limit_sb.setEnabled(device_caching_enabled)
        self.available_space = self.parent.free_space()[0]
        self.allocation_factor = self.prefs.get('device_booklist_cache_limit', 10.00)
        self.device_booklist_cache_limit_sb.setValue(self.allocation_factor)
        if self.available_space == -1:
            self.allocated_space_label.setVisible(False)
        else:
            # If device connected, hook changes to spinbox and init display
            self.device_booklist_cache_limit_sb.valueChanged.connect(self.device_caching_allocation_changed)
            self.device_caching_allocation_changed(self.allocation_factor)

        # Restore the diagnostic settings
        self.plugin_diagnostics.setChecked(self.prefs.get('plugin_diagnostics', True))

        # Restore the debug settings
        self.debug_plugin.setChecked(self.prefs.get('debug_plugin', False))
        self.debug_libimobiledevice.setChecked(self.prefs.get('debug_libimobiledevice', False))

        # Load the widgets
        self.widgets = []
        for app_name in app_list:
            name = app_name.lower().replace(' ', '_')
            # Load dynamic tab
            klass = os.path.join(widget_path, '%s.py' % name)
            if os.path.exists(klass):
                try:
                    self._log_location("adding widget for %s" % name)
                    sys.path.insert(0, widget_path)
                    config_widget = importlib.import_module(name)
                    pw = config_widget.PluginWidget(self)
                    pw.initialize(name)
                    pw.ICON = I('forward.png')
                    self.widgets.append(pw)
                except ImportError:
                    self._log("ERROR: ImportError with %s" % name)
                    import traceback
                    traceback.print_exc()
                finally:
                    sys.path.remove(widget_path)
            else:
                self._log("no dynamic tab resources found for %s" % name)

        self.widgets = sorted(self.widgets, cmp=lambda x,y:cmp(x.TITLE.lower(), y.TITLE.lower()))

        # Callbacks when reader_app changes
        #self.reader_apps.currentIndexChanged.connect(self.restart_required)
        #self.debug_plugin.stateChanged.connect(self.restart_required)
        #self.debug_libimobiledevice.stateChanged.connect(self.restart_required)

        # Callback when reader_app changes
        self.reader_apps.currentIndexChanged.connect(self.reader_app_changed)

        # Callback when booklist_caching_cb changes - enable/disable spinbox
        self.device_booklist_caching_cb.stateChanged.connect(self.device_booklist_caching_changed)

        # Add the app_list to the dropdown
        self.reader_apps.blockSignals(True)
        self.reader_apps.addItems([''])
        self.reader_apps.addItems(sorted(app_list, key=lambda s: s.lower()))

        # Get the last-used reader_app
        pra = self.prefs.get('preferred_reader_app', '')
        idx = self.reader_apps.findText(pra)
        if idx > -1:
            self.reader_apps.setCurrentIndex(idx)

        # Initially set caching_gb visibility
        self.reader_app_changed(idx)

        self.reader_apps.blockSignals(False)

        # Init the plugin tab to currently selected reader app
        self.reader_apps.currentIndexChanged.connect(self.show_plugin_tab)
        self.show_plugin_tab(None)

        # Diagnostics opt-out
        self.diagnostic_options_gb.setVisible(False)

        # Connect the Support buttons
        self.support_pb.clicked.connect(self.support_forum)
        self.support_pb.setIcon(QIcon(I('help.png')))
        self.diagnostics_pb.setIcon(QIcon(I('dialog_information.png')))

        if (self.available_space == -1 or
            (pra == 'Marvin' and getattr(self.parent, 'cached_books', None) is None)):
            self.diagnostics_pb.setEnabled(False)
        else:
            self.diagnostics_pb.clicked.connect(self.device_diagnostics)
    def __init__(self, parent, app_list):
        #QDialog.__init__(self)
        QWidget.__init__(self)
        Ui_Dialog.__init__(self)

        self.current_plugin = None
        self.gui = get_gui()
        self.icon = parent.icon
        self.parent = parent
        self.prefs = parent.prefs
        self.resources_path = parent.resources_path
        self.verbose = parent.verbose
        self._log_location(app_list)
        self.setupUi(self)
        self.support_label.setOpenExternalLinks(True)
        self.version = parent.version

        # Restore the debug settings
        self.debug_plugin.setChecked(self.prefs.get('debug_plugin', False))
        self.debug_libimobiledevice.setChecked(self.prefs.get('debug_libimobiledevice', False))

        # Load the widgets
        self.widgets = []
        for app_name in app_list:
            name = app_name.lower().replace(' ', '_')
            # Load dynamic tab
            klass = os.path.join(widget_path, '%s.py' % name)
            if os.path.exists(klass):
                try:
                    self._log_location("adding widget for %s" % name)
                    sys.path.insert(0, widget_path)
                    config_widget = importlib.import_module(name)
                    pw = config_widget.PluginWidget(self)
                    pw.initialize(name)
                    pw.ICON = I('forward.png')
                    self.widgets.append(pw)
                except ImportError:
                    self._log("ERROR: ImportError with %s" % name)
                    import traceback
                    traceback.print_exc()
                finally:
                    sys.path.remove(widget_path)
            else:
                self._log("no dynamic tab resources found for %s" % name)

        self.widgets = sorted(self.widgets, cmp=lambda x,y:cmp(x.TITLE.lower(), y.TITLE.lower()))

        # Callbacks when reader_app changes
        #self.reader_apps.currentIndexChanged.connect(self.restart_required)
        #self.debug_plugin.stateChanged.connect(self.restart_required)
        #self.debug_libimobiledevice.stateChanged.connect(self.restart_required)

        # Add the app_list to the dropdown
        self.reader_apps.blockSignals(True)
        self.reader_apps.addItems([''])
        self.reader_apps.addItems(sorted(app_list, key=lambda s: s.lower()))

        # Get the last-used reader_app
        pref = self.prefs.get('preferred_reader_app', '')
        idx = self.reader_apps.findText(pref)
        if idx > -1:
            self.reader_apps.setCurrentIndex(idx)
        self.reader_apps.blockSignals(False)

        # Init the plugin tab to currently selected reader app
        self.reader_apps.currentIndexChanged.connect(self.show_plugin_tab)
        self.show_plugin_tab(None)