示例#1
0
class ConditionEditor(QWidget):  # {{{

    ACTION_MAP = {
            'bool' : (
                    (_('is true'), 'is true',),
                    (_('is false'), 'is false'),
                    (_('is undefined'), 'is undefined')
            ),
            'ondevice' : (
                    (_('is true'), 'is set',),
                    (_('is false'), 'is not set'),
            ),
            'identifiers' : (
                (_('has id'), 'has id'),
                (_('does not have id'), 'does not have id'),
            ),
            'int' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt')
            ),
            'datetime' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
                (_('is more days ago than'), 'older count days'),
                (_('is fewer days ago than'), 'count_days'),
                (_('is more days from now than'), 'newer future days'),
                (_('is fewer days from now than'), 'older future days')
            ),
            'multiple' : (
                (_('has'), 'has'),
                (_('does not have'), 'does not have'),
                (_('has pattern'), 'has pattern'),
                (_('does not have pattern'), 'does not have pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
            'single'   : (
                (_('is'), 'is'),
                (_('is not'), 'is not'),
                (_('contains'), 'contains'),
                (_('does not contain'), 'does not contain'),
                (_('matches pattern'), 'matches pattern'),
                (_('does not match pattern'), 'does not match pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
    }

    for x in ('float', 'rating'):
        ACTION_MAP[x] = ACTION_MAP['int']

    def __init__(self, fm, parent=None):
        QWidget.__init__(self, parent)
        self.fm = fm

        self.action_map = self.ACTION_MAP

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        texts = _('If the ___ column ___ values')
        try:
            one, two, three = texts.split('___')
        except:
            one, two, three = 'If the ', ' column ', ' value '

        self.l1 = l1 = QLabel(one)
        l.addWidget(l1, 0, 0)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 0, 1)

        self.l2 = l2 = QLabel(two)
        l.addWidget(l2, 0, 2)

        self.action_box = QComboBox(self)
        l.addWidget(self.action_box, 0, 3)

        self.l3 = l3 = QLabel(three)
        l.addWidget(l3, 0, 4)

        self.value_box = QLineEdit(self)
        l.addWidget(self.value_box, 0, 5)

        self.column_box.addItem('', '')
        for key in sorted(
                conditionable_columns(fm),
                key=lambda key: sort_key(fm[key]['name'])):
            self.column_box.addItem(fm[key]['name'], key)
        self.column_box.setCurrentIndex(0)

        self.column_box.currentIndexChanged.connect(self.init_action_box)
        self.action_box.currentIndexChanged.connect(self.init_value_box)

        for b in (self.column_box, self.action_box):
            b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
            b.setMinimumContentsLength(20)

    @dynamic_property
    def current_col(self):
        def fget(self):
            idx = self.column_box.currentIndex()
            return unicode_type(self.column_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.column_box.count()):
                c = unicode_type(self.column_box.itemData(idx) or '')
                if c == val:
                    self.column_box.setCurrentIndex(idx)
                    return
            raise ValueError('Column %r not found'%val)
        return property(fget=fget, fset=fset)

    @dynamic_property
    def current_action(self):
        def fget(self):
            idx = self.action_box.currentIndex()
            return unicode_type(self.action_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.action_box.count()):
                c = unicode_type(self.action_box.itemData(idx) or '')
                if c == val:
                    self.action_box.setCurrentIndex(idx)
                    return
            raise ValueError('Action %r not valid for current column'%val)
        return property(fget=fget, fset=fset)

    @property
    def current_val(self):
        ans = unicode_type(self.value_box.text()).strip()
        if self.current_col == 'languages':
            rmap = {lower(v):k for k, v in lang_map().iteritems()}
            ans = rmap.get(lower(ans), ans)
        return ans

    @dynamic_property
    def condition(self):

        def fget(self):
            c, a, v = (self.current_col, self.current_action,
                    self.current_val)
            if not c or not a:
                return None
            return (c, a, v)

        def fset(self, condition):
            c, a, v = condition
            if not v:
                v = ''
            v = v.strip()
            self.current_col = c
            self.current_action = a
            self.value_box.setText(v)

        return property(fget=fget, fset=fset)

    def init_action_box(self):
        self.action_box.blockSignals(True)
        self.action_box.clear()
        self.action_box.addItem('', '')
        col = self.current_col
        if col:
            m = self.fm[col]
            dt = m['datatype']
            if dt in self.action_map:
                actions = self.action_map[dt]
            else:
                if col == 'ondevice':
                    k = 'ondevice'
                elif col == 'identifiers':
                    k = 'identifiers'
                else:
                    k = 'multiple' if m['is_multiple'] else 'single'
                actions = self.action_map[k]

            for text, key in actions:
                self.action_box.addItem(text, key)
        self.action_box.setCurrentIndex(0)
        self.action_box.blockSignals(False)
        self.init_value_box()

    def init_value_box(self):
        self.value_box.setEnabled(True)
        self.value_box.setText('')
        self.value_box.setInputMask('')
        self.value_box.setValidator(None)
        col = self.current_col
        if not col:
            return
        action = self.current_action
        if not action:
            return
        m = self.fm[col]
        dt = m['datatype']
        tt = ''
        if col == 'identifiers':
            tt = _('Enter either an identifier type or an '
                    'identifier type and value of the form identifier:value')
        elif col == 'languages':
            tt = _('Enter a 3 letter ISO language code, like fra for French'
                    ' or deu for German or eng for English. You can also use'
                    ' the full language name, in which case calibre will try to'
                    ' automatically convert it to the language code.')
        elif dt in ('int', 'float', 'rating'):
            tt = _('Enter a number')
            v = QIntValidator if dt == 'int' else QDoubleValidator
            self.value_box.setValidator(v(self.value_box))
        elif dt == 'datetime':
            if action == 'count_days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days old the item can be. Zero is today. '
                       'Dates in the future always match')
            elif action == 'older count days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days old the item can be. Zero is today. '
                       'Dates in the future never match')
            elif action == 'older future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days in the future the item can be. '
                       'Zero is today. Dates in the past always match')
            elif action == 'newer future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days in the future the item can be. '
                       'Zero is today. Dates in the past never match')
            else:
                self.value_box.setInputMask('9999-99-99')
                tt = _('Enter a date in the format YYYY-MM-DD')
        else:
            tt = _('Enter a string.')
            if 'pattern' in action:
                tt = _('Enter a regular expression')
            elif m.get('is_multiple', False):
                tt += '\n' + _('You can match multiple values by separating'
                        ' them with %s')%m['is_multiple']['ui_to_list']
        self.value_box.setToolTip(tt)
        if action in ('is set', 'is not set', 'is true', 'is false',
                'is undefined'):
            self.value_box.setEnabled(False)
示例#2
0
    def handle_server(self):
        """
        Handle for server button

        """

        server_dialog = QDialog()
        server_dialog.setWindowTitle('Server Configuration')
        server_dialog.setWindowFlags(Qt.FramelessWindowHint)
        server_dialog.setStyleSheet(get_css())
        server_dialog.setFixedSize(300, 300)

        main_layout = QVBoxLayout(server_dialog)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.addWidget(self.get_logo_widget(server_dialog))

        server_widget = QWidget(self)
        server_widget.setObjectName('login')
        server_layout = QGridLayout(server_widget)

        # Description
        desc_label = QLabel(
            '<h3>Alignak Backend</h3><p>Here you can define alignak settings.</p>'
            '<b>Be sure to enter a valid address</b>')
        desc_label.setWordWrap(True)
        server_layout.addWidget(desc_label, 0, 0, 1, 3)

        # Server URL
        server_layout.addWidget(QLabel('Server'), 1, 0, 1, 1)

        server_url = QLineEdit()
        server_url.setPlaceholderText('alignak backend url')
        server_url.setText(get_app_config('Alignak', 'url'))
        server_layout.addWidget(server_url, 1, 1, 1, 2)

        # Server Port
        server_layout.addWidget(QLabel('Port'), 2, 0, 1, 1)

        server_port = QLineEdit()
        server_port.setPlaceholderText('alignak backend port')
        cur_port = get_app_config('Alignak', 'backend').split(':')[2]
        server_port.setText(cur_port)
        server_layout.addWidget(server_port, 2, 1, 1, 2)

        # Server Processes
        server_layout.addWidget(QLabel('Processes'), 3, 0, 1, 1)

        server_proc = QLineEdit()
        if 'win32' in sys.platform:
            server_proc.setEnabled(False)
        server_proc.setPlaceholderText('alignak backend processes')
        cur_proc = get_app_config('Alignak', 'processes')
        server_proc.setText(cur_proc)
        server_layout.addWidget(server_proc, 3, 1, 1, 2)

        # Valid Button
        valid_btn = QPushButton('Valid')
        valid_btn.clicked.connect(server_dialog.accept)
        server_layout.addWidget(valid_btn, 4, 0, 1, 3)

        main_layout.addWidget(server_widget)

        self.center(server_widget)

        if server_dialog.exec_() == QDialog.Accepted:
            backend_url = '%(url)s:' + str(server_port.text()).rstrip()
            set_app_config('Alignak', 'backend', backend_url)
            set_app_config('Alignak', 'url', str(server_url.text()).rstrip())
            set_app_config('Alignak', 'processes',
                           str(server_proc.text()).rstrip())
示例#3
0
class ConfigWidget(QWidget):

    def __init__(self, plugin_action):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        layout = QVBoxLayout(self)
        self.setLayout(layout)
        self.help_anchor = "configuration"
        
        title_layout = ImageTitleLayout(self, 'images/icon.png', 'Sony Utilities Options')
        layout.addLayout(title_layout)

#        c = plugin_prefs[STORE_NAME]
        library_config = get_library_config(self.plugin_action.gui.current_db)

        custom_column_group = QGroupBox(_('Custom Columns'), self)
        layout.addWidget(custom_column_group )
        options_layout = QGridLayout()
        custom_column_group.setLayout(options_layout)

        avail_text_columns   = self.get_text_custom_columns()
        avail_number_columns = self.get_number_custom_columns()
        avail_rating_columns = self.get_rating_custom_columns()
        avail_date_columns   = self.get_date_custom_columns()
#        debug_print("avail_rating_columns=", avail_rating_columns)
#        debug_print("default columns=", self.plugin_action.gui.library_view.model().orig_headers)
        current_Location_column  = library_config.get(KEY_CURRENT_LOCATION_CUSTOM_COLUMN, DEFAULT_LIBRARY_VALUES[KEY_CURRENT_LOCATION_CUSTOM_COLUMN])
        precent_read_column      = library_config.get(KEY_PERCENT_READ_CUSTOM_COLUMN, DEFAULT_LIBRARY_VALUES[KEY_PERCENT_READ_CUSTOM_COLUMN])
        rating_column            = library_config.get(KEY_RATING_CUSTOM_COLUMN, DEFAULT_LIBRARY_VALUES[KEY_RATING_CUSTOM_COLUMN])
        last_read_column         = library_config.get(KEY_LAST_READ_CUSTOM_COLUMN, DEFAULT_LIBRARY_VALUES[KEY_LAST_READ_CUSTOM_COLUMN])

        store_on_connect         = get_plugin_pref(COMMON_OPTIONS_STORE_NAME, KEY_STORE_ON_CONNECT)
        prompt_to_store          = get_plugin_pref(COMMON_OPTIONS_STORE_NAME, KEY_PROMPT_TO_STORE)
        store_if_more_recent     = get_plugin_pref(COMMON_OPTIONS_STORE_NAME, KEY_STORE_IF_MORE_RECENT)
        do_not_store_if_reopened = get_plugin_pref(COMMON_OPTIONS_STORE_NAME, KEY_DO_NOT_STORE_IF_REOPENED)

#         do_check_for_firmware_updates = get_plugin_pref(UPDATE_OPTIONS_STORE_NAME, KEY_DO_UPDATE_CHECK)
#         do_early_firmware_updates     = get_plugin_pref(UPDATE_OPTIONS_STORE_NAME, KEY_DO_EARLY_FIRMWARE_CHECK)
#         self.update_check_last_time   = get_plugin_pref(UPDATE_OPTIONS_STORE_NAME, KEY_LAST_FIRMWARE_CHECK_TIME)

        do_daily_backup          = get_plugin_pref(BACKUP_OPTIONS_STORE_NAME, KEY_DO_DAILY_BACKUP)
        dest_directory           = get_plugin_pref(BACKUP_OPTIONS_STORE_NAME, KEY_BACKUP_DEST_DIRECTORY)
        copies_to_keep           = get_plugin_pref(BACKUP_OPTIONS_STORE_NAME, KEY_BACKUP_COPIES_TO_KEEP)
#        debug_print("current_Location_column=%s, precent_read_column=%s, rating_column=%s" % (current_Location_column, precent_read_column, rating_column))

        current_Location_label = QLabel(_('Current Reading Location Column:'), self)
        current_Location_label.setToolTip(_("Select a custom column to store the current reading location. The column type must be 'text'. Leave this blank if you do not want to store or restore the current reading location."))
        self.current_Location_combo = CustomColumnComboBox(self, avail_text_columns, current_Location_column)
        current_Location_label.setBuddy(self.current_Location_combo)
        options_layout.addWidget(current_Location_label, 0, 0, 1, 1)
        options_layout.addWidget(self.current_Location_combo, 0, 1, 1, 1)
        
        percent_read_label = QLabel(_('Percent Read Column:'), self)
        percent_read_label.setToolTip(_("Column used to store the current percent read. The column type must be a 'integer'. Leave this blank if you do not want to store or restore the percentage read."))
        self.percent_read_combo = CustomColumnComboBox(self, avail_number_columns, precent_read_column)
        percent_read_label.setBuddy(self.percent_read_combo)
        options_layout.addWidget(percent_read_label, 2, 0, 1, 1)
        options_layout.addWidget(self.percent_read_combo, 2, 1, 1, 1)

        rating_label = QLabel(_('Rating Column:'), self)
        rating_label.setToolTip(_("Column used to store the rating. The column type must be a 'integer'. Leave this blank if you do not want to store or restore the rating."))
        self.rating_combo = CustomColumnComboBox(self, avail_rating_columns, rating_column)
        rating_label.setBuddy(self.rating_combo)
        options_layout.addWidget(rating_label, 3, 0, 1, 1)
        options_layout.addWidget(self.rating_combo, 3, 1, 1, 1)

        last_read_label = QLabel(_('Last Read Column:'), self)
        last_read_label.setToolTip(_("Column used to store when the book was last read. The column type must be a 'Date'. Leave this blank if you do not want to store the last read timestamp."))
        self.last_read_combo = CustomColumnComboBox(self, avail_date_columns, last_read_column)
        last_read_label.setBuddy(self.last_read_combo)
        options_layout.addWidget(last_read_label, 4, 0, 1, 1)
        options_layout.addWidget(self.last_read_combo, 4, 1, 1, 1)

        auto_store_group = QGroupBox(_('Store on connect'), self)
        layout.addWidget(auto_store_group )
        options_layout = QGridLayout()
        auto_store_group.setLayout(options_layout)

        self.store_on_connect_checkbox = QCheckBox(_("Store current bookmarks on connect"), self)
        self.store_on_connect_checkbox.setToolTip(_("When this is checked, the library will be updated with the current bookmark for all books on the device."))
        self.store_on_connect_checkbox.setCheckState(Qt.Checked if store_on_connect else Qt.Unchecked)
        self.store_on_connect_checkbox.clicked.connect(self.store_on_connect_checkbox_clicked)
        options_layout.addWidget(self.store_on_connect_checkbox, 0, 0, 1, 3)

        self.prompt_to_store_checkbox = QCheckBox(_("Prompt to store any changes"), self)
        self.prompt_to_store_checkbox.setToolTip(_("Enable this to be prompted to save the changed bookmarks after an automatic store is done."))
        self.prompt_to_store_checkbox.setCheckState(Qt.Checked if prompt_to_store else Qt.Unchecked)
        self.prompt_to_store_checkbox.setEnabled(store_on_connect)
        options_layout.addWidget(self.prompt_to_store_checkbox, 1, 0, 1, 1)

        self.store_if_more_recent_checkbox = QCheckBox(_("Only if more recent"), self)
        self.store_if_more_recent_checkbox.setToolTip(_("Only store the reading position if the last read timestamp on the device is more recent than in the library."))
        self.store_if_more_recent_checkbox.setCheckState(Qt.Checked if store_if_more_recent else Qt.Unchecked)
        self.store_if_more_recent_checkbox.setEnabled(store_on_connect)
        options_layout.addWidget(self.store_if_more_recent_checkbox, 1, 1, 1, 1)

        self.do_not_store_if_reopened_checkbox = QCheckBox(_("Not if finished in library"), self)
        self.do_not_store_if_reopened_checkbox.setToolTip(_("Do not store the reading position if the library has the book as finished. This is if the percent read is 100%."))
        self.do_not_store_if_reopened_checkbox.setCheckState(Qt.Checked if do_not_store_if_reopened else Qt.Unchecked)
        self.do_not_store_if_reopened_checkbox.setEnabled(store_on_connect)
        options_layout.addWidget(self.do_not_store_if_reopened_checkbox, 1, 2, 1, 1)

#         update_options_group = QGroupBox(_('Firmware Update Options'), self)
#         layout.addWidget(update_options_group)
#         options_layout = QGridLayout()
#         update_options_group.setLayout(options_layout)
# 
#         self.do_update_check = QCheckBox(_('Check for Sony firmware updates daily?'), self)
#         self.do_update_check.setToolTip(_('If this is selected the plugin will check for Sony firmware updates when your Sony device is plugged in, once per 24-hour period.'))
#         self.do_update_check.setCheckState(Qt.Checked if do_check_for_firmware_updates else Qt.Unchecked)
#         options_layout.addWidget(self.do_update_check, 0, 0, 1, 1)
# 
#         self.do_early_firmware_check = QCheckBox(_('Use early firmware adopter affiliate?'), self)
#         self.do_early_firmware_check.setToolTip(_('WARNING: THIS OPTION RISKS DOWNLOADING THE WRONG FIRMWARE FOR YOUR DEVICE! YOUR DEVICE MAY NOT FUNCTION PROPERLY IF THIS HAPPENS! Choose this option to attempt to download Sony firmware updates before they are officially available for your device.'))
#         self.do_early_firmware_check.setCheckState(Qt.Checked if do_early_firmware_updates else Qt.Unchecked)
#         options_layout.addWidget(self.do_early_firmware_check, 0, 1, 1, 1)

        backup_options_group = QGroupBox(_('Device Database Backup'), self)
        layout.addWidget(backup_options_group)
        options_layout = QGridLayout()
        backup_options_group.setLayout(options_layout)

        self.do_daily_backp_checkbox = QCheckBox(_('Backup the device database daily'), self)
        self.do_daily_backp_checkbox.setToolTip(_('If this is selected the plugin will backup the device database the first time it is connected each day.'))
        self.do_daily_backp_checkbox.setCheckState(Qt.Checked if do_daily_backup else Qt.Unchecked)
        self.do_daily_backp_checkbox.clicked.connect(self.do_daily_backp_checkbox_clicked)
        options_layout.addWidget(self.do_daily_backp_checkbox, 0, 0, 1, 3)

        self.dest_directory_label = QLabel(_("Destination:"), self)
        self.dest_directory_label.setToolTip(_("Select the destination the annotations files are to be backed up in."))
        self.dest_directory_edit = QLineEdit(self)
        self.dest_directory_edit.setMinimumSize(150, 0)
        self.dest_directory_edit.setText(dest_directory)
        self.dest_directory_label.setBuddy(self.dest_directory_edit)
        self.dest_pick_button = QPushButton(_("..."), self)
        self.dest_pick_button.setMaximumSize(24, 20)
        self.dest_pick_button.clicked.connect(self._get_dest_directory_name)
        options_layout.addWidget(self.dest_directory_label, 1, 0, 1, 1)
        options_layout.addWidget(self.dest_directory_edit, 1, 1, 1, 1)
        options_layout.addWidget(self.dest_pick_button, 1, 2, 1, 1)

        self.copies_to_keep_checkbox = QCheckBox(_('Copies to keep'), self)
        self.copies_to_keep_checkbox.setToolTip(_("Select this to limit the number of backup kept. If not set, the backup files must be manually deleted."))
        self.copies_to_keep_spin = QSpinBox(self)
        self.copies_to_keep_spin.setMinimum(2)
        self.copies_to_keep_spin.setToolTip(_("The number of backup copies of the database to keep. The minimum is 2."))
        options_layout.addWidget(self.copies_to_keep_checkbox, 1, 3, 1, 1)
        options_layout.addWidget(self.copies_to_keep_spin, 1, 4, 1, 1)
        self.copies_to_keep_checkbox.clicked.connect(self.copies_to_keep_checkbox_clicked)
        if copies_to_keep == -1:
            self.copies_to_keep_checkbox.setCheckState(not Qt.Checked)
        else:
            self.copies_to_keep_checkbox.setCheckState(Qt.Checked)
            self.copies_to_keep_spin.setProperty('value', copies_to_keep)

        self.do_daily_backp_checkbox_clicked(do_daily_backup)

        other_options_group = QGroupBox(_('Other Options'), self)
        layout.addWidget(other_options_group )
        options_layout = QGridLayout()
        other_options_group.setLayout(options_layout)

        library_default_label = QLabel(_('&Library Button default:'), self)
        library_default_label.setToolTip(_('If plugin is placed as a toolbar button, choose a default action when clicked on'))
        self.library_default_combo = KeyComboBox(self, self.plugin_action.library_actions_map, unicode(get_plugin_pref(COMMON_OPTIONS_STORE_NAME, KEY_BUTTON_ACTION_LIBRARY)))
        library_default_label.setBuddy(self.library_default_combo)
        options_layout.addWidget(library_default_label, 0, 0, 1, 1)
        options_layout.addWidget(self.library_default_combo, 0, 1, 1, 2)

        device_default_label = QLabel(_('&Device Button default:'), self)
        device_default_label.setToolTip(_('If plugin is placed as a toolbar button, choose a default action when clicked on'))
        self.device_default_combo = KeyComboBox(self, self.plugin_action.device_actions_map, unicode(get_plugin_pref(COMMON_OPTIONS_STORE_NAME, KEY_BUTTON_ACTION_DEVICE)))
        device_default_label.setBuddy(self.device_default_combo)
        options_layout.addWidget(device_default_label, 1, 0, 1, 1)
        options_layout.addWidget(self.device_default_combo, 1, 1, 1, 2)

        keyboard_shortcuts_button = QPushButton(_('Keyboard shortcuts...'), self)
        keyboard_shortcuts_button.setToolTip(_('Edit the keyboard shortcuts associated with this plugin'))
        keyboard_shortcuts_button.clicked.connect(self.edit_shortcuts)
        layout.addWidget(keyboard_shortcuts_button)
        layout.addStretch(1)

    def store_on_connect_checkbox_clicked(self, checked):
        self.prompt_to_store_checkbox.setEnabled(checked)
        self.store_if_more_recent_checkbox.setEnabled(checked)
        self.do_not_store_if_reopened_checkbox.setEnabled(checked)

    def do_daily_backp_checkbox_clicked(self, checked):
        self.dest_directory_edit.setEnabled(checked)
        self.dest_pick_button.setEnabled(checked)
        self.dest_directory_label.setEnabled(checked)
        self.copies_to_keep_checkbox.setEnabled(checked)
        self.copies_to_keep_checkbox_clicked(checked and self.copies_to_keep_checkbox.checkState() == Qt.Checked)

    def copies_to_keep_checkbox_clicked(self, checked):
        self.copies_to_keep_spin.setEnabled(checked)

    # Called by Calibre before save_settings 
    def validate(self):
#        import traceback
#        traceback.print_stack()
        
        debug_print('BEGIN Validate')
        valid = True
        # Only save if we were able to get data to avoid corrupting stored data
#        if self.do_daily_backp_checkbox.checkState() == Qt.Checked and not len(self.dest_directory_edit.text()):
#            error_dialog(self, 'No destination directory',
#                            'If the automatic device backup is set, there must be a destination directory.',
#                            show=True, show_copy_button=False)
#            valid = False

        debug_print('END Validate, status = %s' % valid)
        return valid

    def save_settings(self):

        new_prefs = {}
        new_prefs[KEY_BUTTON_ACTION_DEVICE]     = unicode(self.device_default_combo.currentText())
        new_prefs[KEY_BUTTON_ACTION_LIBRARY]    = unicode(self.library_default_combo.currentText())
        new_prefs[KEY_STORE_ON_CONNECT]         = self.store_on_connect_checkbox.checkState() == Qt.Checked
        new_prefs[KEY_PROMPT_TO_STORE]          = self.prompt_to_store_checkbox.checkState() == Qt.Checked
        new_prefs[KEY_STORE_IF_MORE_RECENT]     = self.store_if_more_recent_checkbox.checkState() == Qt.Checked
        new_prefs[KEY_DO_NOT_STORE_IF_REOPENED] = self.do_not_store_if_reopened_checkbox.checkState() == Qt.Checked
        plugin_prefs[COMMON_OPTIONS_STORE_NAME] = new_prefs

        new_update_prefs = {}
#         new_update_prefs[KEY_DO_UPDATE_CHECK]          = self.do_update_check.checkState() == Qt.Checked
#         new_update_prefs[KEY_DO_EARLY_FIRMWARE_CHECK]  = self.do_early_firmware_check.checkState() == Qt.Checked
#         new_update_prefs[KEY_LAST_FIRMWARE_CHECK_TIME] = self.update_check_last_time
        plugin_prefs[UPDATE_OPTIONS_STORE_NAME]        = new_update_prefs

        backup_prefs = {}
        backup_prefs[KEY_DO_DAILY_BACKUP]       = self.do_daily_backp_checkbox.checkState() == Qt.Checked
        backup_prefs[KEY_BACKUP_DEST_DIRECTORY] = unicode(self.dest_directory_edit.text())
        backup_prefs[KEY_BACKUP_COPIES_TO_KEEP] = int(unicode(self.copies_to_keep_spin.value())) if self.copies_to_keep_checkbox.checkState() == Qt.Checked else -1 
        plugin_prefs[BACKUP_OPTIONS_STORE_NAME] = backup_prefs

        db = self.plugin_action.gui.current_db
        library_config = get_library_config(db)
        library_config[KEY_CURRENT_LOCATION_CUSTOM_COLUMN] = self.current_Location_combo.get_selected_column()
        library_config[KEY_PERCENT_READ_CUSTOM_COLUMN]     = self.percent_read_combo.get_selected_column()
        library_config[KEY_RATING_CUSTOM_COLUMN]           = self.rating_combo.get_selected_column()
        library_config[KEY_LAST_READ_CUSTOM_COLUMN]        = self.last_read_combo.get_selected_column()
        set_library_config(db, library_config)

    def get_number_custom_columns(self):
        column_types = ['float','int']
        return self.get_custom_columns(column_types)

    def get_rating_custom_columns(self):
        column_types = ['rating','int']
        custom_columns = self.get_custom_columns(column_types)
        ratings_column_name = self.plugin_action.gui.library_view.model().orig_headers['rating']
        custom_columns['rating'] = {'name': ratings_column_name}
        return custom_columns

    def get_text_custom_columns(self):
        column_types = ['text']
        return self.get_custom_columns(column_types)

    def get_date_custom_columns(self):
        column_types = ['datetime']
        return self.get_custom_columns(column_types)

    def get_custom_columns(self, column_types):
        custom_columns = self.plugin_action.gui.library_view.model().custom_columns
        available_columns = {}
        for key, column in custom_columns.iteritems():
            typ = column['datatype']
            if typ in column_types and not column['is_multiple']:
                available_columns[key] = column
        return available_columns

    def help_link_activated(self, url):
        self.plugin_action.show_help(anchor="configuration")

    def edit_shortcuts(self):
        d = KeyboardConfigDialog(self.plugin_action.gui, self.plugin_action.action_spec[0])
        if d.exec_() == d.Accepted:
            self.plugin_action.gui.keyboard.finalize()

    def _get_dest_directory_name(self):
        path = choose_dir(self, 'backup annotations destination dialog','Choose destination directory')
        if path:
            self.dest_directory_edit.setText(path)
示例#4
0
文件: coloring.py 项目: rakyi/calibre
class ConditionEditor(QWidget):  # {{{

    ACTION_MAP = {
            'bool' : (
                    (_('is true'), 'is true',),
                    (_('is false'), 'is false'),
                    (_('is undefined'), 'is undefined')
            ),
            'ondevice' : (
                    (_('is true'), 'is set',),
                    (_('is false'), 'is not set'),
            ),
            'identifiers' : (
                (_('has id'), 'has id'),
                (_('does not have id'), 'does not have id'),
            ),
            'int' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt')
            ),
            'datetime' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
                (_('is more days ago than'), 'older count days'),
                (_('is fewer days ago than'), 'count_days'),
                (_('is more days from now than'), 'newer future days'),
                (_('is fewer days from now than'), 'older future days')
            ),
            'multiple' : (
                (_('has'), 'has'),
                (_('does not have'), 'does not have'),
                (_('has pattern'), 'has pattern'),
                (_('does not have pattern'), 'does not have pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
            'single'   : (
                (_('is'), 'is'),
                (_('is not'), 'is not'),
                (_('matches pattern'), 'matches pattern'),
                (_('does not match pattern'), 'does not match pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
    }

    for x in ('float', 'rating'):
        ACTION_MAP[x] = ACTION_MAP['int']

    def __init__(self, fm, parent=None):
        QWidget.__init__(self, parent)
        self.fm = fm

        self.action_map = self.ACTION_MAP

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        texts = _('If the ___ column ___ values')
        try:
            one, two, three = texts.split('___')
        except:
            one, two, three = 'If the ', ' column ', ' value '

        self.l1 = l1 = QLabel(one)
        l.addWidget(l1, 0, 0)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 0, 1)

        self.l2 = l2 = QLabel(two)
        l.addWidget(l2, 0, 2)

        self.action_box = QComboBox(self)
        l.addWidget(self.action_box, 0, 3)

        self.l3 = l3 = QLabel(three)
        l.addWidget(l3, 0, 4)

        self.value_box = QLineEdit(self)
        l.addWidget(self.value_box, 0, 5)

        self.column_box.addItem('', '')
        for key in sorted(
                conditionable_columns(fm),
                key=lambda(key): sort_key(fm[key]['name'])):
            self.column_box.addItem(fm[key]['name'], key)
        self.column_box.setCurrentIndex(0)

        self.column_box.currentIndexChanged.connect(self.init_action_box)
        self.action_box.currentIndexChanged.connect(self.init_value_box)

        for b in (self.column_box, self.action_box):
            b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
            b.setMinimumContentsLength(20)

    @dynamic_property
    def current_col(self):
        def fget(self):
            idx = self.column_box.currentIndex()
            return unicode(self.column_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.column_box.count()):
                c = unicode(self.column_box.itemData(idx) or '')
                if c == val:
                    self.column_box.setCurrentIndex(idx)
                    return
            raise ValueError('Column %r not found'%val)
        return property(fget=fget, fset=fset)

    @dynamic_property
    def current_action(self):
        def fget(self):
            idx = self.action_box.currentIndex()
            return unicode(self.action_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.action_box.count()):
                c = unicode(self.action_box.itemData(idx) or '')
                if c == val:
                    self.action_box.setCurrentIndex(idx)
                    return
            raise ValueError('Action %r not valid for current column'%val)
        return property(fget=fget, fset=fset)

    @property
    def current_val(self):
        ans = unicode(self.value_box.text()).strip()
        if self.current_col == 'languages':
            rmap = {lower(v):k for k, v in lang_map().iteritems()}
            ans = rmap.get(lower(ans), ans)
        return ans

    @dynamic_property
    def condition(self):

        def fget(self):
            c, a, v = (self.current_col, self.current_action,
                    self.current_val)
            if not c or not a:
                return None
            return (c, a, v)

        def fset(self, condition):
            c, a, v = condition
            if not v:
                v = ''
            v = v.strip()
            self.current_col = c
            self.current_action = a
            self.value_box.setText(v)

        return property(fget=fget, fset=fset)

    def init_action_box(self):
        self.action_box.blockSignals(True)
        self.action_box.clear()
        self.action_box.addItem('', '')
        col = self.current_col
        if col:
            m = self.fm[col]
            dt = m['datatype']
            if dt in self.action_map:
                actions = self.action_map[dt]
            else:
                if col == 'ondevice':
                    k = 'ondevice'
                elif col == 'identifiers':
                    k = 'identifiers'
                else:
                    k = 'multiple' if m['is_multiple'] else 'single'
                actions = self.action_map[k]

            for text, key in actions:
                self.action_box.addItem(text, key)
        self.action_box.setCurrentIndex(0)
        self.action_box.blockSignals(False)
        self.init_value_box()

    def init_value_box(self):
        self.value_box.setEnabled(True)
        self.value_box.setText('')
        self.value_box.setInputMask('')
        self.value_box.setValidator(None)
        col = self.current_col
        if not col:
            return
        action = self.current_action
        if not action:
            return
        m = self.fm[col]
        dt = m['datatype']
        tt = ''
        if col == 'identifiers':
            tt = _('Enter either an identifier type or an '
                    'identifier type and value of the form identifier:value')
        elif col == 'languages':
            tt = _('Enter a 3 letter ISO language code, like fra for French'
                    ' or deu for German or eng for English. You can also use'
                    ' the full language name, in which case calibre will try to'
                    ' automatically convert it to the language code.')
        elif dt in ('int', 'float', 'rating'):
            tt = _('Enter a number')
            v = QIntValidator if dt == 'int' else QDoubleValidator
            self.value_box.setValidator(v(self.value_box))
        elif dt == 'datetime':
            if action == 'count_days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days old the item can be. Zero is today. '
                       'Dates in the future always match')
            elif action == 'older count days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days old the item can be. Zero is today. '
                       'Dates in the future never match')
            elif action == 'older future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days in the future the item can be. '
                       'Zero is today. Dates in the past always match')
            elif action == 'newer future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days in the future the item can be. '
                       'Zero is today. Dates in the past never match')
            else:
                self.value_box.setInputMask('9999-99-99')
                tt = _('Enter a date in the format YYYY-MM-DD')
        else:
            tt = _('Enter a string.')
            if 'pattern' in action:
                tt = _('Enter a regular expression')
            elif m.get('is_multiple', False):
                tt += '\n' + _('You can match multiple values by separating'
                        ' them with %s')%m['is_multiple']['ui_to_list']
        self.value_box.setToolTip(tt)
        if action in ('is set', 'is not set', 'is true', 'is false',
                'is undefined'):
            self.value_box.setEnabled(False)
class LLT_AddWord(QMainWindow):
    def __init__(self):
        super(LLT_AddWord, self).__init__()
        self.w = QWidget()
        self.setCentralWidget(self.w)

        self.verbDic = []
        self.nounDic = []
        self.adjDic = []
        self.phraseDic = []
        self.wordList = []

        self.w.setWindowTitle("Add Word")
        self.w.setGeometry(0, 0, 500, 500)

        self.vRad = QRadioButton("Verb")
        self.vRad.setChecked(True)
        self.nRad = QRadioButton("Noun")
        self.aRad = QRadioButton("Adjective")
        self.pRad = QRadioButton("Phrase")
        self.okBut = QPushButton("OK")
        self.okBut.clicked.connect(self.OK)

        self.entryLab = QLabel("Word: ")
        self.wordEntry = QLineEdit()
        self.wordEntry.setEnabled(False)

        self.tranLab = QLabel("Translation: ")
        self.tranEntry = QLineEdit()
        self.tranEntry.setEnabled(False)

        self.checkBut = QPushButton("Check")
        self.checkBut.clicked.connect(self.check)
        self.saveBut = QPushButton("Save")
        self.saveBut.clicked.connect(self.save)
        self.clearBut = QPushButton("Clear")
        self.clearBut.clicked.connect(self.clear)
        self.newBut = QPushButton("New word")
        self.newBut.clicked.connect(self.new)
        self.exitBut = QPushButton("Exit")
        self.exitBut.clicked.connect(self.exit)

        grid = QGridLayout()

        grid.addWidget(self.vRad, 0, 0)
        grid.addWidget(self.nRad, 0, 1)
        grid.addWidget(self.aRad, 0, 2)
        grid.addWidget(self.pRad, 0, 3)
        grid.addWidget(self.okBut, 0, 4)

        grid.addWidget(self.entryLab, 1, 0)
        grid.addWidget(self.wordEntry, 1, 1, 1, 3)
        grid.addWidget(self.tranLab, 2, 0)
        grid.addWidget(self.tranEntry, 2, 1, 1, 3)

        grid.addWidget(self.checkBut, 3, 0)
        grid.addWidget(self.saveBut, 3, 1)
        grid.addWidget(self.clearBut, 3, 2)
        grid.addWidget(self.newBut, 3, 3)
        grid.addWidget(self.exitBut, 3, 4)

        self.getDics()
        self.setLists()
        self.w.setLayout(grid)
        self.w.show()

    def OK(self):
        self.vRad.setEnabled(False)
        self.nRad.setEnabled(False)
        self.aRad.setEnabled(False)
        self.pRad.setEnabled(False)
        self.okBut.setEnabled(False)
        self.wordEntry.setEnabled(True)
        self.tranEntry.setEnabled(True)

    def check(self):
        word = self.wordEntry.text().upper()
        if word in self.wordList:
            msgBox = QMessageBox()
            msgBox.setText(word + ' already in dictionary')
            msgBox.exec_()
        else:
            msgBox = QMessageBox()
            msgBox.setText(word + ' not in dictionary yet')
            msgBox.exec_()

    def save(self):
        spanWord = self.wordEntry.text().upper()
        tranWord = self.tranEntry.text().upper()
        if spanWord in self.wordList:
            msgBox = QMessageBox()
            msgBox.setText(spanWord + ' already in dictionary')
            msgBox.exec_()
        else:
            self.wordList.append(spanWord)
            newWord = [spanWord, tranWord]
            self.wordEntry.setEnabled(False)
            self.tranEntry.setEnabled(False)
            if self.vRad.isChecked():
                self.verbDic.append(newWord)
                v = open('verb.txt', 'w')
                json.dump(self.verbDic, v)
                v.close()
            elif self.nRad.isChecked():
                self.nounDic.append(newWord)
                n = open('noun.txt', 'w')
                json.dump(self.nounDic, n)
                n.close()
            elif self.aRad.isChecked():
                self.adjDic.append(newWord)
                a = open('adj.txt', 'w')
                json.dump(self.adjDic, a)
                a.close()
            elif self.pRad.isChecked():
                self.phraseDic.append(newWord)
                p = open('phrase.txt', 'w')
                json.dump(self.phraseDic, p)
                p.close()

            else:
                msgBox = QMessageBox()
                msgBox.setText(
                    "You must select a dictionary before saving word.")
                msgBox.exec_()

    def clear(self):
        self.vRad.setEnabled(True)
        self.nRad.setEnabled(True)
        self.aRad.setEnabled(True)
        self.pRad.setEnabled(True)
        self.okBut.setEnabled(True)
        self.wordEntry.setEnabled(False)
        self.tranEntry.setEnabled(False)
        self.wordEntry.clear()
        self.tranEntry.clear()

    def new(self):
        self.vRad.setEnabled(True)
        self.nRad.setEnabled(True)
        self.aRad.setEnabled(True)
        self.pRad.setEnabled(True)
        self.okBut.setEnabled(True)
        self.wordEntry.setEnabled(False)
        self.tranEntry.setEnabled(False)
        self.wordEntry.clear()
        self.tranEntry.clear()

    def exit(self):
        confirm = QMessageBox.question(self.w, 'Quit',
                                       'Are you sure you want to exit?',
                                       QMessageBox.Yes | QMessageBox.No)
        if confirm == QMessageBox.Yes:
            self.close()
        else:
            pass

    def getDics(self):
        try:
            v = open('verb.txt', 'r')
            self.verbDic = json.load(v)
            v.close()
        except:
            self.verbDic = []

        try:
            n = open('noun.txt', 'r')
            self.nounDic = json.load(n)
            n.close()
        except:
            self.nounDic = []

        try:
            p = open('phrase.txt', 'r')
            self.phraseDic = json.load(p)
            p.close()
        except:
            self.phraseDic = []

        try:
            a = open('adj.txt', 'r')
            self.adjDic = json.load(a)
            a.close()
        except:
            self.phraseDic = []

    def setLists(self):
        for item in self.verbDic:
            self.wordList.append(item[0])
        for item in self.nounDic:
            self.wordList.append(item[0])
        for item in self.phraseDic:
            self.wordList.append(item[0])
        for item in self.adjDic:
            self.wordList.append(item[0])
示例#6
0
class Window(QWidget):

    ext_list = ['mkv', 'mp4', 'avi']

    def __init__(self):
        QWidget.__init__(self)

        self.v_box = QVBoxLayout()
        self.v_dir = QVBoxLayout()
        self.v_ext = QVBoxLayout()
        self.v_av = QVBoxLayout()
        self.H_default_save_dir = QHBoxLayout()
        self.H_default_ext = QHBoxLayout()
        self.H_av = QHBoxLayout()
        self.H_save = QHBoxLayout()

        self.settings = xml.ParseXMLSettings()

        self.txt_default_dir = QLineEdit(self)
        self.drpdwn_av = QComboBox(self)
        self.drpdwn_ext = QComboBox(self)

        self.shortcut = QShortcut(QKeySequence('Ctrl+W'), self)
        self.shortcut.activated.connect(self.close)

        self.initUI()

        self.v_box.addSpacing(12)
        self.H_av.addSpacing(12)
        self.H_default_ext.addSpacing(12)
        self.H_default_save_dir.addSpacing(12)
        self.H_save.addSpacing(12)

        self.setLayout(self.v_box)

        self.setGeometry(200, 200, 250, 150)
        self.setWindowTitle('Global Settings')

    def initUI(self):

        self.txt_default_dir.setText(self.settings.settings_list['save_dir'])
        self.txt_default_dir.setEnabled(False)
        lbl_default_dir = QLabel(self)
        lbl_default_dir.setText('Default Directory: ')
        btn_default_dir = QPushButton(self)
        btn_default_dir.setText('Change...')

        self.drpdwn_av.addItem(self.settings.settings_list['av'])
        lbl_av = QLabel(self)
        lbl_av.setText('Record Audio and Video? ')

        self.drpdwn_ext.addItem(self.settings.settings_list['ext'])
        lbl_ext = QLabel(self)
        lbl_ext.setText('Video Extension: ')

        btn_save = QPushButton(self)
        btn_save.setText('Save changes...')

        btn_default_dir.clicked.connect(lambda: self.change_dir())
        btn_save.clicked.connect(self.save)

        if self.settings.settings_list['av'] == 'True':
            self.drpdwn_av.addItem('False')
        else:
            self.drpdwn_av.addItem('True')

        for ext in self.ext_list:
            if ext != self.settings.settings_list['ext']:
                self.drpdwn_ext.addItem(ext)

        self.v_dir.addWidget(lbl_default_dir)
        self.H_default_save_dir.addWidget(self.txt_default_dir)
        self.H_default_save_dir.addWidget(btn_default_dir)
        self.v_dir.addLayout(self.H_default_save_dir)
        self.v_av.addWidget(lbl_av)
        self.H_av.addWidget(self.drpdwn_av)
        self.v_av.addLayout(self.H_av)
        self.v_ext.addWidget(lbl_ext)
        self.H_default_ext.addWidget(self.drpdwn_ext)
        self.v_ext.addLayout(self.H_default_ext)
        self.H_save.addWidget(btn_save)

        self.v_ext.addStretch(1)
        self.v_av.addStretch(1)
        self.v_dir.addStretch(1)

        self.v_box.addLayout(self.v_dir)
        self.v_box.addLayout(self.v_av)
        self.v_box.addLayout(self.v_ext)
        self.v_box.addLayout(self.H_save)

        self.v_box.addStretch(1)

    def save(self):
        if self.drpdwn_ext.currentText(
        ) != self.settings.settings_list['ext'] or self.drpdwn_av.currentText(
        ) != self.settings.settings_list['av']:
            dlg = dialog.QuestionDialog('Are you ready to save changes?')
            if dlg.clickedButton() == dlg.yes:
                if self.drpdwn_ext.currentText(
                ) != self.settings.settings_list['ext']:
                    self.settings.edit('ext', self.drpdwn_ext.currentText())
                    SETTINGS.settings_list[
                        'ext'] = self.drpdwn_ext.currentText()
                if self.drpdwn_av.currentText(
                ) != self.settings.settings_list['av']:
                    self.settings.edit('av', self.drpdwn_av.currentText())
                    SETTINGS.settings_list['av'] = self.drpdwn_av.currentText()
        else:
            pass

    def change_dir(self):
        dlg = str(QFileDialog.getExistingDirectory(self, "Select Directory"))

        if dlg != "":
            self.settings.edit('save_dir', dlg)
            self.txt_default_dir.setText(dlg)
            SETTINGS.settings_list['save_dir'] = dlg
示例#7
0
class LLT_Lookup(QMainWindow):

    def __init__(self):
        super(LLT_Lookup, self).__init__()
        self.w = QWidget()
        self.setCentralWidget(self.w)    
        
        self.verbDic = []
        self.nounDic = []
        self.adjDic = []
        self.phraseDic = []
        self.wordList = []
        self.wordDic = []
        self.index = int(0)

        self.w.setWindowTitle("Word Lookup")
        self.w.setGeometry(0,0,500, 500)
             
        self.lookLab = QLabel("Lookup: ")
        self.lookEntry = QLineEdit()
        self.lookBut = QPushButton("Search")
        self.lookBut.clicked.connect(self.search)
        
        self.wordLab = QLabel("Word: ")
        self.resultWord = QLabel() 
        self.tranLab = QLabel("Translation: ")
        self.resultTran = QLabel()
        
        self.newBut = QPushButton("New Search")
        self.newBut.clicked.connect(self.new)
        self.exitBut = QPushButton("Exit")
        self.exitBut.clicked.connect(self.exit)
        
        grid = QGridLayout()
        
        grid.addWidget(self.lookLab, 0, 0)
        grid.addWidget(self.lookEntry, 0, 1, 1, 2)
        grid.addWidget(self.lookBut, 0, 3)
        
        grid.addWidget(self.wordLab, 1, 0)
        grid.addWidget(self.resultWord, 1, 1, 1, 3)
        grid.addWidget(self.tranLab, 2, 0)
        grid.addWidget(self.resultTran, 2, 1, 1, 3)
        
        grid.addWidget(self.newBut, 3, 0)
        grid.addWidget(self.exitBut, 3, 3)
        
        self.getDics()
        self.setLists()
        self.w.setLayout(grid) 
        self.w.show()

    def search(self):
        searchWord = self.lookEntry.text().upper().strip()
        
        if searchWord in self.wordList:
            self.lookEntry.setEnabled(False)
            self.lookBut.setEnabled(False)
            
            self.index = self.wordList.index(searchWord)
            foundWord = self.wordDic[self.index]
            self.resultWord.setText(foundWord[0])
            self.resultTran.setText(foundWord[1])
                        
        else:
            msgBox = QMessageBox() 
            msgBox.setText("Word not currently saved in dictionary.")
            msgBox.exec_(); 
    
    
    def new(self):
        self.lookEntry.setEnabled(True)
        self.lookBut.setEnabled(True)
        self.resultWord.setText('')
        self.resultTran.setText('')
        self.lookEntry.clear()
        
    def exit(self):
        confirm = QMessageBox.question(self.w, 'Quit', 'Are you sure you want to exit?', QMessageBox.Yes | QMessageBox.No)
        if confirm == QMessageBox.Yes:
            self.close()
        else:
            pass

    def getDics(self):
        try:
            v=open('verb.txt','r')
            self.verbDic=json.load(v)
            v.close()
        except:
            self.verbDic = []

        try:
            n=open('noun.txt','r')
            self.nounDic=json.load(n)
            n.close()
        except:
            self.nounDic = []
    
        try:
            p=open('phrase.txt','r')
            self.phraseDic=json.load(p)
            p.close()
        except:
            self.phraseDic = []
                
        try:
            a=open('adj.txt','r')
            self.adjDic=json.load(a)
            a.close()
        except:
            self.phraseDic = []
            
            
    def setLists(self):
        for item in self.verbDic:
            self.wordList.append(item[0])
            self.wordDic.append(item)
        for item in self.nounDic:
            self.wordList.append(item[0])
            self.wordDic.append(item)
        for item in self.adjDic:
            self.wordList.append(item[0])
            self.wordDic.append(item)
        for item in self.phraseDic:
            self.wordList.append(item[0])
            self.wordDic.append(item)
示例#8
0
class ConfigWidget(QWidget, Logger):
    # Manually managed controls when saving/restoring
    EXCLUDED_CONTROLS = [
        'cfg_annotations_destination_comboBox'
        ]

    #LOCATION_TEMPLATE = "{cls}:{func}({arg1}) {arg2}"

    WIZARD_PROFILES = {
        'Annotations': {
            'label': 'mm_annotations',
            'datatype': 'comments',
            'display': {},
            'is_multiple': False
            }
        }

    def __init__(self, plugin_action):
        self.gui = plugin_action.gui
        self.opts = plugin_action.opts

        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        # ~~~~~~~~ Create the runtime options group box ~~~~~~~~
        self.cfg_runtime_options_gb = QGroupBox(self)
        self.cfg_runtime_options_gb.setTitle(_('Runtime options'))
        self.l.addWidget(self.cfg_runtime_options_gb)
        self.cfg_runtime_options_qvl = QVBoxLayout(self.cfg_runtime_options_gb)

        # ~~~~~~~~ Disable caching checkbox ~~~~~~~~
        self.cfg_disable_caching_checkbox = QCheckBox(_('Disable caching'))
        self.cfg_disable_caching_checkbox.setObjectName('cfg_disable_caching_checkbox')
        self.cfg_disable_caching_checkbox.setToolTip(_('Force reload of reader database'))
        self.cfg_disable_caching_checkbox.setChecked(False)
        self.cfg_runtime_options_qvl.addWidget(self.cfg_disable_caching_checkbox)

        # ~~~~~~~~ plugin logging checkbox ~~~~~~~~
        self.cfg_plugin_debug_log_checkbox = QCheckBox(_('Enable debug logging for Annotations plugin'))
        self.cfg_plugin_debug_log_checkbox.setObjectName('cfg_plugin_debug_log_checkbox')
        self.cfg_plugin_debug_log_checkbox.setToolTip(_('Print plugin diagnostic messages to console'))
        self.cfg_plugin_debug_log_checkbox.setChecked(False)
        self.cfg_runtime_options_qvl.addWidget(self.cfg_plugin_debug_log_checkbox)

        # ~~~~~~~~ libiMobileDevice logging checkbox ~~~~~~~~
        self.cfg_libimobiledevice_debug_log_checkbox = QCheckBox(_('Enable debug logging for libiMobileDevice'))
        self.cfg_libimobiledevice_debug_log_checkbox.setObjectName('cfg_libimobiledevice_debug_log_checkbox')
        self.cfg_libimobiledevice_debug_log_checkbox.setToolTip(_('Print libiMobileDevice debug messages to console'))
        self.cfg_libimobiledevice_debug_log_checkbox.setChecked(False)
        self.cfg_libimobiledevice_debug_log_checkbox.setEnabled(LIBIMOBILEDEVICE_AVAILABLE)
        self.cfg_runtime_options_qvl.addWidget(self.cfg_libimobiledevice_debug_log_checkbox)

        # ~~~~~~~~ Create the Annotations options group box ~~~~~~~~
        self.cfg_annotation_options_gb = QGroupBox(self)
        self.cfg_annotation_options_gb.setTitle(_('Annotation options'))
        self.l.addWidget(self.cfg_annotation_options_gb)

        self.cfg_annotation_options_qgl = QGridLayout(self.cfg_annotation_options_gb)
        current_row = 0

        # Add the label/combobox for annotations destination
        self.cfg_annotations_destination_label = QLabel(_('<b>Add fetched annotations to<b>'))
        self.cfg_annotations_destination_label.setAlignment(Qt.AlignLeft)
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_label, current_row, 0)
        current_row += 1

        self.cfg_annotations_destination_comboBox = QComboBox(self.cfg_annotation_options_gb)
        self.cfg_annotations_destination_comboBox.setObjectName('cfg_annotations_destination_comboBox')
        self.cfg_annotations_destination_comboBox.setToolTip(_('Custom field to store annotations'))
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_comboBox, current_row, 0)

        # Populate annotations_field combobox
        db = self.gui.current_db
        all_custom_fields = db.custom_field_keys()
        self.custom_fields = {}
        for custom_field in all_custom_fields:
            field_md = db.metadata_for_field(custom_field)
            if field_md['datatype'] in ['comments']:
                self.custom_fields[field_md['name']] = {'field': custom_field,
                                                   'datatype': field_md['datatype']}

        all_fields = self.custom_fields.keys() + ['Comments']
        for cf in sorted(all_fields):
            self.cfg_annotations_destination_comboBox.addItem(cf)

        # Add CC Wizard
        self.cfg_annotations_wizard = QToolButton()
        self.cfg_annotations_wizard.setIcon(QIcon(I('wizard.png')))
        self.cfg_annotations_wizard.setToolTip(_("Create a custom column to store annotations"))
        self.cfg_annotations_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Annotations'))
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_wizard, current_row, 2)

        current_row += 1

        # ~~~~~~~~ Add a horizontal line ~~~~~~~~
        self.cfg_appearance_hl = QFrame(self)
        self.cfg_appearance_hl.setGeometry(QRect(0, 0, 1, 3))
        self.cfg_appearance_hl.setFrameShape(QFrame.HLine)
        self.cfg_appearance_hl.setFrameShadow(QFrame.Raised)
        self.cfg_annotation_options_qgl.addWidget(self.cfg_appearance_hl, current_row, 0)
        current_row += 1

        # ~~~~~~~~ Add the Modify… button ~~~~~~~~
        self.cfg_annotations_appearance_pushbutton = QPushButton(_("Modify appearance…"))
        self.cfg_annotations_appearance_pushbutton.clicked.connect(self.configure_appearance)
        self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_appearance_pushbutton, current_row, 0)
        current_row += 1

        self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.cfg_annotation_options_qgl.addItem(self.spacerItem, current_row, 0, 1, 1)

        # ~~~~~~~~ Compilations group box ~~~~~~~~
        self.cfg_compilation_options_gb = QGroupBox(self)
        self.cfg_compilation_options_gb.setTitle(_('Compilations'))
        self.l.addWidget(self.cfg_compilation_options_gb)
        self.cfg_compilation_options_qgl = QGridLayout(self.cfg_compilation_options_gb)
        current_row = 0

        #   News clippings
        self.cfg_news_clippings_checkbox = QCheckBox(_('Collect News clippings'))
        self.cfg_news_clippings_checkbox.setObjectName('cfg_news_clippings_checkbox')
        self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_checkbox,
            current_row, 0)

        self.cfg_news_clippings_lineEdit = QLineEdit()
        self.cfg_news_clippings_lineEdit.setObjectName('cfg_news_clippings_lineEdit')
        self.cfg_news_clippings_lineEdit.setToolTip(_('Title for collected news clippings'))
        self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_lineEdit,
            current_row, 1)

        # ~~~~~~~~ End of construction zone ~~~~~~~~

        self.resize(self.sizeHint())

        # Restore state of controls, populate annotations combobox
        self.controls = inventory_controls(self, dump_controls=False)
        restore_state(self)
        self.populate_annotations()

        # Hook changes to annotations_destination_combobox
#        self.connect(self.cfg_annotations_destination_comboBox,
#                     pyqtSignal('currentIndexChanged(const QString &)'),
#                     self.annotations_destination_changed)
        self.cfg_annotations_destination_comboBox.currentIndexChanged.connect(self.annotations_destination_changed)

        # Hook changes to diagnostic checkboxes
        self.cfg_disable_caching_checkbox.stateChanged.connect(self.restart_required)
        self.cfg_libimobiledevice_debug_log_checkbox.stateChanged.connect(self.restart_required)
        self.cfg_plugin_debug_log_checkbox.stateChanged.connect(self.restart_required)

        # Hook changes to News clippings, initialize
        self.cfg_news_clippings_checkbox.stateChanged.connect(self.news_clippings_toggled)
        self.news_clippings_toggled(self.cfg_news_clippings_checkbox.checkState())
        self.cfg_news_clippings_lineEdit.editingFinished.connect(self.news_clippings_destination_changed)

        # Launch the annotated_books_scanner
        field = get_cc_mapping('annotations', 'field', 'Comments')
        self.annotated_books_scanner = InventoryAnnotatedBooks(self.gui, field)
        self.annotated_books_scanner.signal.connect(self.inventory_complete)
#        self.connect(self.annotated_books_scanner, self.annotated_books_scanner.signal,
#            self.inventory_complete)
        QTimer.singleShot(1, self.start_inventory)

    def annotations_destination_changed(self, qs_new_destination_name):
        '''
        If the destination field changes, move all existing annotations from old to new
        '''
        self._log_location(repr(qs_new_destination_name))
        self._log("self.custom_fields: %s" % self.custom_fields)

        old_destination_field = get_cc_mapping('annotations', 'field', None)
        if old_destination_field and not (old_destination_field in self.gui.current_db.custom_field_keys() or old_destination_field == 'Comments'):
            return
        old_destination_name = get_cc_mapping('annotations', 'combobox', None)

        self._log("old_destination_field: %s" % old_destination_field)
        self._log("old_destination_name: %s" % old_destination_name)

        # Catch initial change from None to Comments - first run only
        if old_destination_field is None:
            return

#        new_destination_name = unicode(qs_new_destination_name)
        new_destination_name = unicode(self.cfg_annotations_destination_comboBox.currentText())
        self._log("new_destination_name: %s" % new_destination_name)

        if old_destination_name == new_destination_name:
            self._log_location("old_destination_name = new_destination_name, no changes")
            return

        new_destination_field = None
        if new_destination_name == 'Comments':
            new_destination_field = 'Comments'
        else:
            new_destination_field = self.custom_fields[new_destination_name]['field']

        if existing_annotations(self.opts.parent, old_destination_field):
            command = self.launch_new_destination_dialog(old_destination_name, new_destination_name)

            if command == 'move':
                set_cc_mapping('annotations', field=new_destination_field, combobox=new_destination_name)

                if self.annotated_books_scanner.isRunning():
                    self.annotated_books_scanner.wait()
                move_annotations(self, self.annotated_books_scanner.annotation_map,
                    old_destination_field, new_destination_field)

            elif command == 'change':
                # Keep the updated destination field, but don't move annotations
                pass

            elif command == 'cancel':
                # Restore previous destination
                self.cfg_annotations_destination_comboBox.blockSignals(True)
                old_index = self.cfg_annotations_destination_comboBox.findText(old_destination_name)
                self.cfg_annotations_destination_comboBox.setCurrentIndex(old_index)
                self.cfg_annotations_destination_comboBox.blockSignals(False)

            """
            # Warn user that change will move existing annotations to new field
            title = 'Move annotations?'
            msg = ("<p>Existing annotations will be moved from <b>%s</b> to <b>%s</b>.</p>" %
                    (old_destination_name, new_destination_name) +
                   "<p>New annotations will be added to <b>%s</b>.</p>" %
                    new_destination_name +
                   "<p>Proceed?</p>")
            d = MessageBox(MessageBox.QUESTION,
                           title, msg,
                           show_copy_button=False)
            self._log_location("QUESTION: %s" % msg)
            if d.exec_():
                set_cc_mapping('annotations', field=new_destination_field, combobox=new_destination_name)

                if self.annotated_books_scanner.isRunning():
                    self.annotated_books_scanner.wait()
                move_annotations(self, self.annotated_books_scanner.annotation_map,
                    old_destination_field, new_destination_field)

            else:
                self.cfg_annotations_destination_comboBox.blockSignals(True)
                old_index = self.cfg_annotations_destination_comboBox.findText(old_destination_name)
                self.cfg_annotations_destination_comboBox.setCurrentIndex(old_index)
                self.cfg_annotations_destination_comboBox.blockSignals(False)
            """

        else:
            # No existing annotations, just update prefs
            set_cc_mapping('annotations', field=new_destination_field, combobox=new_destination_name)

    def configure_appearance(self):
        '''
        '''
        from calibre_plugins.annotations.appearance import default_elements
        from calibre_plugins.annotations.appearance import default_timestamp
        appearance_settings = {
                                'appearance_css': default_elements,
                                'appearance_hr_checkbox': False,
                                'appearance_timestamp_format': default_timestamp
                              }

        # Save, hash the original settings
        original_settings = {}
        osh = hashlib.md5()
        for setting in appearance_settings:
            original_settings[setting] = plugin_prefs.get(setting, appearance_settings[setting])
            osh.update(repr(plugin_prefs.get(setting, appearance_settings[setting])))

        # Display the appearance dialog
        aa = AnnotationsAppearance(self, get_icon('images/annotations.png'), plugin_prefs)
        cancelled = False
        if aa.exec_():
            # appearance_hr_checkbox and appearance_timestamp_format changed live to prefs during previews
            plugin_prefs.set('appearance_css', aa.elements_table.get_data())
            # Generate a new hash
            nsh = hashlib.md5()
            for setting in appearance_settings:
                nsh.update(repr(plugin_prefs.get(setting, appearance_settings[setting])))
        else:
            for setting in appearance_settings:
                plugin_prefs.set(setting, original_settings[setting])
            nsh = osh

        # If there were changes, and there are existing annotations, offer to re-render
        field = get_cc_mapping('annotations', 'field', None)
        if osh.digest() != nsh.digest() and existing_annotations(self.opts.parent,field):
            title = _('Update annotations?')
            msg = _('<p>Update existing annotations to new appearance settings?</p>')
            d = MessageBox(MessageBox.QUESTION,
                           title, msg,
                           show_copy_button=False)
            self._log_location("QUESTION: %s" % msg)
            if d.exec_():
                self._log_location("Updating existing annotations to modified appearance")
                if self.annotated_books_scanner.isRunning():
                    self.annotated_books_scanner.wait()
                move_annotations(self, self.annotated_books_scanner.annotation_map,
                    field, field, window_title=_("Updating appearance"))

    def inventory_complete(self, msg):
        self._log_location(msg)

    def launch_cc_wizard(self, column_type):
        '''
        '''
        def _update_combo_box(comboBox, destination, previous):
            '''
            '''
            self._log_location()

            cb = getattr(self, comboBox)
            cb.blockSignals(True)
            all_items = [str(cb.itemText(i))
                         for i in range(cb.count())]
            if previous and previous in all_items:
                all_items.remove(previous)
            all_items.append(destination)

            cb.clear()
            cb.addItems(sorted(all_items, key=lambda s: s.lower()))

            # Select the new destination in the comboBox
            idx = cb.findText(destination)
            if idx > -1:
                cb.setCurrentIndex(idx)

            # Process the changed destination
            self.annotations_destination_changed(destination)

            cb.blockSignals(False)


        klass = os.path.join(dialog_resources_path, 'cc_wizard.py')
        if os.path.exists(klass):
            #self._log("importing CC Wizard dialog from '%s'" % klass)
            sys.path.insert(0, dialog_resources_path)
            this_dc = importlib.import_module('cc_wizard')
            sys.path.remove(dialog_resources_path)
            dlg = this_dc.CustomColumnWizard(self,
                                             column_type,
                                             self.WIZARD_PROFILES[column_type],
                                             verbose=True)
            dlg.exec_()

            if dlg.modified_column:
                self._log("modified_column: %s" % dlg.modified_column)

                destination = dlg.modified_column['destination']
                label = dlg.modified_column['label']
                previous = dlg.modified_column['previous']
                source = dlg.modified_column['source']

                self._log("destination: %s" % destination)
                self._log("label: %s" % label)
                self._log("previous: %s" % previous)
                self._log("source: %s" % source)

                if source == "Annotations":
                    # Add/update the new destination so save_settings() can find it
                    if destination in self.custom_fields:
                        self.custom_fields[destination]['field'] = label
                    else:
                        self.custom_fields[destination] = {'field': label}

                    _update_combo_box('cfg_annotations_destination_comboBox', destination, previous)

                    # Save field manually in case user cancels
                    #self.prefs.set('cfg_annotations_destination_comboBox', destination)
                    #self.prefs.set('cfg_annotations_destination_field', label)
                    set_cc_mapping('annotations', field=label, combobox=destination)

                    # Inform user to restart
                    self.restart_required('custom_column')

        else:
            self._log("ERROR: Can't import from '%s'" % klass)

    def launch_new_destination_dialog(self, old, new):
        '''
        Return 'move', 'change' or 'cancel'
        '''
        self._log_location()

        klass = os.path.join(dialog_resources_path, 'new_destination.py')
        if os.path.exists(klass):
            self._log("importing new destination dialog from '%s'" % klass)
            sys.path.insert(0, dialog_resources_path)
            this_dc = importlib.import_module('new_destination')
            sys.path.remove(dialog_resources_path)
            dlg = this_dc.NewDestinationDialog(self, old, new)
            dlg.exec_()
            return dlg.command

    def news_clippings_destination_changed(self):
        qs_new_destination_name = self.cfg_news_clippings_lineEdit.text()
        if not re.match(r'^\S+[A-Za-z0-9 ]+$', qs_new_destination_name):
            # Complain about News clippings title
            title = _('Invalid title for News clippings')
            msg = _("Supply a valid title for News clippings, for example 'My News Clippings'.")
            d = MessageBox(MessageBox.WARNING,
                           title, msg,
                           show_copy_button=False)
            self._log_location("WARNING: %s" % msg)
            d.exec_()

    def news_clippings_toggled(self, state):
        if state == Qt.Checked:
            self.cfg_news_clippings_lineEdit.setEnabled(True)
        else:
            self.cfg_news_clippings_lineEdit.setEnabled(False)

    def populate_annotations(self):
        '''
        Restore annotations combobox
        '''
        self._log_location()
        target = 'Comments'
        existing = get_cc_mapping('annotations', 'combobox')
        if existing:
            target = existing
        ci = self.cfg_annotations_destination_comboBox.findText(target)
        self.cfg_annotations_destination_comboBox.setCurrentIndex(ci)

    def restart_required(self, state):
        title = _('Restart required')
        msg = _('To apply changes, restart calibre.')
        d = MessageBox(MessageBox.WARNING,
                       title, msg,
                       show_copy_button=False)
        self._log_location("WARNING: %s" % (msg))
        d.exec_()

    def save_settings(self):
        save_state(self)

        # Save the annotation destination field
        ann_dest = unicode(self.cfg_annotations_destination_comboBox.currentText())
        self._log_location("INFO: ann_dest=%s" % (ann_dest))
        self._log_location("INFO: self.custom_fields=%s" % (self.custom_fields))
        if ann_dest == 'Comments':
            set_cc_mapping('annotations', field='Comments', combobox='Comments')
        elif ann_dest:
            set_cc_mapping('annotations', field=self.custom_fields[ann_dest]['field'], combobox=ann_dest)

    def start_inventory(self):
        self.annotated_books_scanner.start()
class LLT_EditWord(QMainWindow):

    def __init__(self):
        super(LLT_EditWord, self).__init__()
        self.w = QWidget()
        self.setCentralWidget(self.w)    
        
        self.verbDic = []
        self.nounDic = []
        self.adjDic = []
        self.phraseDic = []
        self.wordList = []
        self.verbList = []
        self.nounList = []
        self.adjList = []
        self.phraseList = []
        
        self.index = int(0)

        self.w.setWindowTitle("Edit Word")
        self.w.setGeometry(0,0,500, 500)
        
        
        self.vRad = QRadioButton("Verb")
        self.vRad.setChecked(True)
        self.nRad = QRadioButton("Noun")
        self.aRad = QRadioButton("Adjective")        
        self.pRad = QRadioButton("Phrase")
        
        self.okBut = QPushButton("OK")
        self.okBut.clicked.connect(self.OK)
        
        self.lookLab = QLabel("Lookup: ")
        self.lookEntry = QLineEdit()
        self.lookEntry.setEnabled(False)
        self.lookBut = QPushButton("Search")
        self.lookBut.clicked.connect(self.search)
        self.lookBut.setEnabled(False)
        
        self.entryLab = QLabel("Word: ")
        self.wordEntry = QLineEdit()
        self.wordEntry.setEnabled(False)
        
        self.tranLab = QLabel("Translation: ")
        self.tranEntry = QLineEdit()
        self.tranEntry.setEnabled(False)
        
        self.saveBut = QPushButton("Save")
        self.saveBut.clicked.connect(self.save)
        self.clearBut = QPushButton("Reset")
        self.clearBut.clicked.connect(self.reset)
        self.newBut = QPushButton("New word")
        self.newBut.clicked.connect(self.new)
        self.exitBut = QPushButton("Exit")
        self.exitBut.clicked.connect(self.exit)
        
        grid = QGridLayout()
        
        grid.addWidget(self.vRad, 0, 0)
        grid.addWidget(self.nRad, 0, 1)
        grid.addWidget(self.aRad, 0, 2)
        grid.addWidget(self.pRad, 0, 3)
        grid.addWidget(self.okBut, 0, 4)
        
        grid.addWidget(self.lookLab, 1, 0)
        grid.addWidget(self.lookEntry, 1, 1, 1, 2)
        grid.addWidget(self.lookBut, 1, 4)
        
        grid.addWidget(self.entryLab, 2, 0)
        grid.addWidget(self.wordEntry, 2, 1, 1, 3)
        grid.addWidget(self.tranLab, 3, 0)
        grid.addWidget(self.tranEntry, 3, 1, 1, 3)
        
        grid.addWidget(self.saveBut, 4, 0)
        grid.addWidget(self.clearBut, 4, 1)
        grid.addWidget(self.newBut, 4, 2)
        grid.addWidget(self.exitBut, 4, 3)
        
        self.getDics()
        self.setLists()
        self.w.setLayout(grid) 
        self.w.show()

    def search(self):
        searchWord = self.lookEntry.text().upper()
        currentDic = []
        currentList = []
            
        if self.vRad.isChecked():
            currentDic = self.verbDic
            currentList = self.verbList
        elif self.nRad.isChecked():
            currentDic = self.nounDic
            currentList = self.nounList
        elif self.aRad.isChecked():
            currentDic = self.adjDic
            currentList = self.adjList
        elif self.pRad.isChecked():
            currentDic = self.phraseDic
            currentList = self.phraseList
        else: 
            msgBox = QMessageBox() 
            msgBox.setText("You must select a dictionary before continuing.")
            msgBox.exec_()
            self.vRad.setEnabled(True)
            self.nRad.setEnabled(True)
            self.aRad.setEnabled(True)
            self.pRad.setEnabled(True)
            self.lookEntry.setEnabled(False)
            self.lookBut.setEnabled(False)
            self.wordEntry.setEnabled(False)
            self.tranEntry.setEnabled(False)
        
        if searchWord in self.wordList:
            self.lookEntry.setEnabled(False)
            self.lookBut.setEnabled(False)
            self.wordEntry.setEnabled(True)
            self.tranEntry.setEnabled(True)
            self.index = currentList.index(searchWord)
            oldWord = currentDic[self.index]
            self.wordEntry.setPlaceholderText(oldWord[0])
            self.tranEntry.setPlaceholderText(oldWord[1])
                        
        else:
            msgBox = QMessageBox() 
            msgBox.setText("Word not currently saved in dictionary.")
            msgBox.exec_(); 
        

            
    def OK(self):
        self.vRad.setEnabled(False)
        self.nRad.setEnabled(False)
        self.aRad.setEnabled(False)
        self.pRad.setEnabled(False)
        self.lookEntry.setEnabled(True)
        self.lookBut.setEnabled(True)

    def save(self):
        spanWord = self.wordEntry.text().upper()
        tranWord = self.tranEntry.text().upper()
        if spanWord in self.wordList:
            msgBox = QMessageBox() 
            msgBox.setText(spanWord + ' already in dictionary')
            msgBox.exec_();
        else:
            self.wordList.append(spanWord)
            newWord = [spanWord,tranWord]
            self.wordEntry.setEnabled(False)
            self.tranEntry.setEnabled(False)
            if self.vRad.isChecked():
                self.verbDic[self.index]= newWord
                v = open('verb.txt','w')
                json.dump(self.verbDic, v)
                v.close() 
            elif self.nRad.isChecked():
                self.nounDic[self.index]= newWord
                n = open('noun.txt','w')
                json.dump(self.nounDic, n)
                n.close()
            elif self.aRad.isChecked():
                self.adjDic[self.index]= newWord
                a = open('adj.txt','w')
                json.dump(self.adjDic, a)
                a.close()
            elif self.pRad.isChecked():
                self.phraseDic[self.index]= newWord
                p = open('phrase.txt','w')
                json.dump(self.phraseDic, p)
                p.close()
                
            else:
                msgBox = QMessageBox() 
                msgBox.setText("You must select a dictionary before saving word.")
                msgBox.exec_();
                
    def reset(self):
        self.vRad.setEnabled(True)
        self.nRad.setEnabled(True)
        self.aRad.setEnabled(True)
        self.pRad.setEnabled(True)
        self.lookEntry.setEnabled(False)
        self.lookBut.setEnabled(False)
        self.wordEntry.setEnabled(False)
        self.tranEntry.setEnabled(False)
        self.wordEntry.clear()
        self.tranEntry.clear()
        self.lookEntry.setPlaceholderText('')
        self.wordEntry.setPlaceholderText('')
        self.tranEntry.setPlaceholderText('')    
    
    def new(self):
        self.vRad.setEnabled(True)
        self.nRad.setEnabled(True)
        self.aRad.setEnabled(True)
        self.pRad.setEnabled(True)
        self.wordEntry.setEnabled(False)
        self.tranEntry.setEnabled(False)
        self.wordEntry.clear()
        self.tranEntry.clear()
        self.lookEntry.setPlaceholderText('')
        self.wordEntry.setPlaceholderText('')
        self.tranEntry.setPlaceholderText('')

    def exit(self):
        confirm = QMessageBox.question(self.w, 'Quit', 'Are you sure you want to exit?', QMessageBox.Yes | QMessageBox.No)
        if confirm == QMessageBox.Yes:
            self.close()
        else:
            pass

    def getDics(self):
        try:
            v=open('verb.txt','r')
            self.verbDic=json.load(v)
            v.close()
        except:
            self.verbDic = []

        try:
            n=open('noun.txt','r')
            self.nounDic=json.load(n)
            n.close()
        except:
            self.nounDic = []
    
        try:
            p=open('phrase.txt','r')
            self.phraseDic=json.load(p)
            p.close()
        except:
            self.phraseDic = []
                
        try:
            a=open('adj.txt','r')
            self.adjDic=json.load(a)
            a.close()
        except:
            self.phraseDic = []
            
            
    def setLists(self):
        for item in self.verbDic:
            self.wordList.append(item[0])
            self.verbList.append(item[0])
        for item in self.nounDic:
            self.wordList.append(item[0])
            self.nounList.append(item[0])
        for item in self.adjDic:
            self.wordList.append(item[0])
            self.adjList.append(item[0])
        for item in self.phraseDic:
            self.wordList.append(item[0])
            self.phraseList.append(item[0])
示例#10
0
class MakeBrickDialog(QDialog):
    def __init__(self, parent, modal=True, flags=Qt.WindowFlags()):
        QDialog.__init__(self, parent, flags)
        self.model = None
        self._model_dir = None
        self.setModal(modal)
        self.setWindowTitle("Convert sources to FITS brick")
        lo = QVBoxLayout(self)
        lo.setContentsMargins(10, 10, 10, 10)
        lo.setSpacing(5)
        # file selector
        self.wfile = FileSelector(self,
                                  label="FITS filename:",
                                  dialog_label="Output FITS file",
                                  default_suffix="fits",
                                  file_types="FITS files (*.fits *.FITS)",
                                  file_mode=QFileDialog.ExistingFile)
        lo.addWidget(self.wfile)
        # reference frequency
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        label = QLabel("Frequency, MHz:", self)
        lo1.addWidget(label)
        tip = """<P>If your sky model contains spectral information (such as spectral indices), then a brick may be generated
    for a specific frequency. If a frequency is not specified here, the reference frequency of the model sources will be assumed.</P>"""
        self.wfreq = QLineEdit(self)
        self.wfreq.setValidator(QDoubleValidator(self))
        label.setToolTip(tip)
        self.wfreq.setToolTip(tip)
        lo1.addWidget(self.wfreq)
        # beam gain
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        self.wpb_apply = QCheckBox("Apply primary beam expression:", self)
        self.wpb_apply.setChecked(True)
        lo1.addWidget(self.wpb_apply)
        tip = """<P>If this option is specified, a primary power beam gain will be applied to the sources before inserting
    them into the brick. This can be any valid Python expression making use of the variables 'r' (corresponding
    to distance from field centre, in radians) and 'fq' (corresponding to frequency.)</P>"""
        self.wpb_exp = QLineEdit(self)
        self.wpb_apply.setToolTip(tip)
        self.wpb_exp.setToolTip(tip)
        lo1.addWidget(self.wpb_exp)
        # overwrite or add mode
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        self.woverwrite = QRadioButton("overwrite image", self)
        self.woverwrite.setChecked(True)
        lo1.addWidget(self.woverwrite)
        self.waddinto = QRadioButton("add into image", self)
        lo1.addWidget(self.waddinto)
        # add to model
        self.wadd = QCheckBox(
            "Add resulting brick to sky model as a FITS image component", self)
        lo.addWidget(self.wadd)
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        self.wpad = QLineEdit(self)
        self.wpad.setValidator(QDoubleValidator(self))
        self.wpad.setText("1.1")
        lab = QLabel("...with padding factor:", self)
        lab.setToolTip(
            """<P>The padding factor determines the amount of null padding inserted around the image during
      the prediction stage. Padding alleviates the effects of tapering and detapering in the uv-brick, which can show
      up towards the edges of the image. For a factor of N, the image will be padded out to N times its original size.
      This increases memory use, so if you have no flux at the edges of the image anyway, then a pad factor of 1 is
      perfectly fine.</P>""")
        self.wpad.setToolTip(lab.toolTip())
        self.wadd.toggled[bool].connect(self.wpad.setEnabled)
        self.wadd.toggled[bool].connect(lab.setEnabled)
        self.wpad.setEnabled(False)
        lab.setEnabled(False)
        lo1.addStretch(1)
        lo1.addWidget(lab, 0)
        lo1.addWidget(self.wpad, 1)
        self.wdel = QCheckBox(
            "Remove from the sky model sources that go into the brick", self)
        lo.addWidget(self.wdel)
        # OK/cancel buttons
        lo.addSpacing(10)
        lo2 = QHBoxLayout()
        lo.addLayout(lo2)
        lo2.setContentsMargins(5, 5, 5, 5)
        self.wokbtn = QPushButton("OK", self)
        self.wokbtn.setMinimumWidth(128)
        self.wokbtn.clicked.connect(self.accept)
        self.wokbtn.setEnabled(False)
        cancelbtn = QPushButton("Cancel", self)
        cancelbtn.setMinimumWidth(128)
        cancelbtn.clicked.connect(self.reject)
        lo2.addWidget(self.wokbtn)
        lo2.addStretch(1)
        lo2.addWidget(cancelbtn)
        self.setMinimumWidth(384)
        # signals
        self.wfile.filenameSelected.connect(self._fileSelected)
        # internal state
        self.qerrmsg = QErrorMessage(self)

    def setModel(self, model):
        self.model = model
        pb = self.model.primaryBeam()
        if pb:
            self.wpb_exp.setText(pb)
        else:
            self.wpb_apply.setChecked(False)
            self.wpb_exp.setText("")
        if model.filename():
            self._model_dir = os.path.dirname(os.path.abspath(
                model.filename()))
        else:
            self._model_dir = os.path.abspath('.')
        self.wfile.setDirectory(self._model_dir)
        self._fileSelected(self.wfile.filename(), quiet=True)

    def _fileSelected(self, filename, quiet=False):
        self.wokbtn.setEnabled(False)
        if not filename:
            return None
        # check that filename matches model
        if not os.path.samefile(self._model_dir, os.path.dirname(filename)):
            self.wfile.setFilename('')
            if not quiet:
                QMessageBox.warning(
                    self, "Directory mismatch",
                    """<P>The FITS file must reside in the same directory
          as the current sky model.</P>""")
            self.wfile.setDirectory(self._model_dir)
            return None
        # read fits file
        busy = BusyIndicator()
        try:
            input_hdu = pyfits.open(filename)[0]
            hdr = input_hdu.header
            # get frequency, if specified
            for axis in range(1, hdr['NAXIS'] + 1):
                if hdr['CTYPE%d' % axis].upper() == 'FREQ':
                    self.wfreq.setText(str(hdr['CRVAL%d' % axis] / 1e+6))
                    break
        except Exception as err:
            busy.reset_cursor()
            self.wfile.setFilename('')
            if not quiet:
                QMessageBox.warning(
                    self, "Error reading FITS",
                    "Error reading FITS file %s: %s" % (filename, str(err)))
            return None
        self.wokbtn.setEnabled(True)
        # if filename is not in model already, enable the "add to model" control
        for src in self.model.sources:
            if isinstance(getattr(src, 'shape', None), ModelClasses.FITSImage) \
                    and os.path.exists(src.shape.filename) and os.path.exists(filename) \
                    and os.path.samefile(src.shape.filename, filename):
                self.wadd.setChecked(True)
                self.wadd.setEnabled(False)
                self.wadd.setText("image already in sky model")
                break
        else:
            self.wadd.setText("add image to sky model")
        busy.reset_cursor()
        return filename

    def accept(self):
        """Tries to make a brick, and closes the dialog if successful."""
        sources = [
            src for src in self.model.sources
            if src.selected and src.typecode == 'pnt'
        ]
        filename = self.wfile.filename()
        if not self._fileSelected(filename):
            return
        # get PB expression
        pbfunc = None
        if self.wpb_apply.isChecked():
            pbexp = str(self.wpb_exp.text())
            try:
                pbfunc = eval("lambda r,fq:" + pbexp)
            except Exception as err:
                QMessageBox.warning(
                    self, "Error parsing PB experssion",
                    "Error parsing primary beam expression %s: %s" %
                    (pbexp, str(err)))
                return
        # get frequency
        freq = str(self.wfreq.text())
        freq = float(freq) * 1e+6 if freq else None
        # get pad factor
        pad = str(self.wpad.text())
        pad = max(float(pad), 1) if pad else 1
        # read fits file
        busy = BusyIndicator()
        try:
            input_hdu = pyfits.open(filename)[0]
        except Exception as err:
            busy.reset_cursor()
            QMessageBox.warning(
                self, "Error reading FITS",
                "Error reading FITS file %s: %s" % (filename, str(err)))
            return
        # reset data if asked to
        if self.woverwrite.isChecked():
            input_hdu.data[...] = 0
        # insert sources
        Imaging.restoreSources(input_hdu,
                               sources,
                               0,
                               primary_beam=pbfunc,
                               freq=freq)
        # save fits file
        try:
            # pyfits seems to produce an exception:
            #         TypeError: formatwarning() takes exactly 4 arguments (5 given)
            # when attempting to overwrite a file. As a workaround, remove the file first.
            if os.path.exists(filename):
                os.remove(filename)
            input_hdu.writeto(filename)
        except Exception as err:
            traceback.print_exc()
            busy.reset_cursor()
            QMessageBox.warning(
                self, "Error writing FITS",
                "Error writing FITS file %s: %s" % (filename, str(err)))
            return
        changed = False
        sources = self.model.sources
        # remove sources from model if asked to
        if self.wdel.isChecked():
            sources = [
                src for src in sources
                if not (src.selected and src.typecode == 'pnt')
            ]
            changed = True
        # add image to model if asked to
        if self.wadd.isChecked():
            hdr = input_hdu.header
            # get image parameters
            max_flux = float(input_hdu.data.max())
            wcs = WCS(hdr, mode='pyfits')
            # Get reference pixel coordinates
            # wcs.getCentreWCSCoords() doesn't work, as that gives us the middle of the image
            # So scan the header to get the CRPIX values
            ra0 = dec0 = 1
            for iaxis in range(hdr['NAXIS']):
                axs = str(iaxis + 1)
                name = hdr.get('CTYPE' + axs, axs).upper()
                if name.startswith("RA"):
                    ra0 = hdr.get('CRPIX' + axs, 1) - 1
                elif name.startswith("DEC"):
                    dec0 = hdr.get('CRPIX' + axs, 1) - 1
            # convert pixel to degrees
            ra0, dec0 = wcs.pix2wcs(ra0, dec0)
            ra0 *= DEG
            dec0 *= DEG
            sx, sy = wcs.getHalfSizeDeg()
            sx *= DEG
            sy *= DEG
            nx, ny = input_hdu.data.shape[-1:-3:-1]
            # check if this image is already contained in the model
            for src in sources:
                if isinstance(getattr(src, 'shape', None),
                              ModelClasses.FITSImage) and os.path.samefile(
                                  src.shape.filename, filename):
                    # update source parameters
                    src.pos.ra, src.pos.dec = ra0, dec0
                    src.flux.I = max_flux
                    src.shape.ex, src.shape.ey = sx, sy
                    src.shape.nx, src.shape.ny = nx, ny
                    src.shape.pad = pad
                    break
            # not contained, make new source object
            else:
                pos = ModelClasses.Position(ra0, dec0)
                flux = ModelClasses.Flux(max_flux)
                shape = ModelClasses.FITSImage(sx,
                                               sy,
                                               0,
                                               os.path.basename(filename),
                                               nx,
                                               ny,
                                               pad=pad)
                img_src = SkyModel.Source(os.path.splitext(
                    os.path.basename(filename))[0],
                                          pos,
                                          flux,
                                          shape=shape)
                sources.append(img_src)
            changed = True
        if changed:
            self.model.setSources(sources)
            self.model.emitUpdate(SkyModel.SkyModel.UpdateAll, origin=self)
        self.parent().showMessage("Wrote %d sources to FITS file %s" %
                                  (len(sources), filename))
        busy.reset_cursor()
        return QDialog.accept(self)
示例#11
0
class ConverterWidget(QMainWindow):

    name = 'RWConvert'

    # For easier usage calculate the path relative to here.
    here = os.path.abspath(os.path.dirname(__file__))
    getPath = partial(os.path.join, here)

    # Setup a plugin base for "rwconvert.plugins" and make sure to load
    # all the default built-in plugins from the builtin_plugins folder.
    pluginBase = PluginBase(package='rwconvert.plugins',
                            searchpath=[getPath('./plugins')])

    plugins = {}
    filenames = []
    currentPlugin = None
    filetypes = 'All Files (*.*)'
    config = {}

    def __init__(self):
        '''
        init
        '''

        super().__init__()

        self.comms = CommSignals()
        """
        Read configuration file and return its contents
        """
        self.initConfig()
        cfgDir = self.config[PATHS]['config_path']
        self.cfgFileName = os.path.join(cfgDir,
                                        self.config[FILES]['config_name'])
        if not os.path.isfile(self.cfgFileName):
            os.makedirs(os.path.dirname(self.cfgFileName), exist_ok=True)
            self.exportConfig()
        else:
            with open(self.cfgFileName, 'r') as configFile:
                c = yaml.load(configFile)
                c = {} if c is None else c
                if c != {}:
                    self.config = c

        # and a source which loads the plugins from the "plugins"
        # folder.  We also pass the application name as identifier.  This
        # is optional but by doing this out plugins have consistent
        # internal module names which allows pickle to work.
        self.source = self.pluginBase.make_plugin_source(
            searchpath=[self.getPath('./plugins')], identifier=self.name)

        # Here we list all the plugins the source knows about, load them
        # and the use the "setup" function provided by the plugin to
        # initialize the plugin.
        for pluginName in self.source.list_plugins():
            plugin = self.source.load_plugin(pluginName)
            pluginClass = getattr(plugin, pluginName)
            instance = pluginClass(self.config, self.comms)
            self.plugins[pluginName] = instance

        self.initGui()


#         self.showFullScreen()

    def initConfig(self):
        if PATHS not in self.config: self.config[PATHS] = {}
        if FILES not in self.config: self.config[FILES] = {}
        if FORMS not in self.config: self.config[FORMS] = {}
        if NAMES not in self.config: self.config[NAMES] = {}

        self.config[PATHS]['homepath'] = os.path.expanduser('~')
        self.config[PATHS]['docpath'] = os.path.join(
            self.config[PATHS]['homepath'], 'Documents')
        self.config[PATHS]['download_path'] = os.path.join(
            self.config[PATHS]['homepath'], 'Downloads')
        self.config[PATHS]['save_path'] = os.path.join(
            self.config[PATHS]['docpath'], self.name)
        self.config[PATHS]['config_path'] = appdirs.user_config_dir(self.name)
        self.config[PATHS]['db_path'] = os.path.join(
            self.config[PATHS]['config_path'], 'data')

        self.config[FILES]['config_name'] = 'config.yaml'
        self.config[FILES]['db_name'] = 'rwconvert.sqlite'
        self.config[FILES]['save_file'] = 'roadwarrior'
        self.config[FILES]['save_ext'] = '.xlsx'

        self.config[FORMS]['include_date'] = False
        self.config[FORMS]['prefix_date'] = False
        self.config[FORMS]['include_routes'] = False
        self.config[FORMS]['combine_routes'] = False

        self.config[NAMES]['current_plugin_name'] = ''

        self.destFilename = self.config['Files']['save_file'] + self.config[
            'Files']['save_ext']

        # Create destination file directory if it doesn't already exist'
        #         if not os.path.exists(self.config[PATHS]['config_path']):
        os.makedirs(self.config[PATHS]['config_path'], exist_ok=True)
        #         if not os.path.exists(self.config[PATHS]['db_path']):
        os.makedirs(self.config[PATHS]['db_path'], exist_ok=True)
        #         if not os.path.exists(self.config[PATHS]['save_path']):
        os.makedirs(self.config[PATHS]['save_path'], exist_ok=True)

    def initGui(self):
        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('Road warrior Upload File Converter')
        self.center()

        fMain = QFrame()
        mainLayout = QGridLayout()
        fMain.setLayout(mainLayout)
        self.setCentralWidget(fMain)

        tabWidget = QTabWidget()
        mainLayout.addWidget(tabWidget, 0, 0)

        self.closeBtn = QPushButton('Close Application')
        self.closeBtn.clicked.connect(self.handleCloseClicked)
        mainLayout.addWidget(self.closeBtn, 1, 0)

        tabWidget.addTab(self.initConvertPage(), 'Converter')
        tabWidget.addTab(self.initResultPage(), 'Converter')
        tabWidget.addTab(self.initConfigPage(), 'Configuration')

    def initResultPage(self):
        f = QFrame()
        l = QHBoxLayout()
        f.setLayout(l)

        self.convertedTabs = QTabWidget()
        l.addWidget(self.convertedTabs)
        '''
        This just adds a blank page with an empty tab widget.
        Pages are added on the fly when the files are converted as
        this could involve one or many pages depending on combine_route
        flag and number of routes.

        self.convertedTabs is the empty tab widget
        '''

        return f

    def initConvertPage(self):
        f = QFrame()
        l = QGridLayout()
        f.setLayout(l)

        row = 0

        l.addWidget(QLabel('Converter :'), row, 0)
        currentPluginBox = QComboBox()
        currentPluginBox.currentTextChanged.connect(self.selectPlugin)
        l.addWidget(currentPluginBox, row, 1)
        for key in self.plugins.keys():
            currentPluginBox.addItem(key)
        row += 1

        l.addWidget(QLabel('Destination path :'), row, 0)
        self.destPathLbl = QLabel(
            self.joinSavePath(self.config[PATHS]['save_path'],
                              self.config[FILES]['save_file'],
                              self.config[FILES]['save_ext']))
        self.destPathLbl.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Fixed)
        l.addWidget(self.destPathLbl, row, 1)

        row += 1

        f2 = QFrame()
        l2 = QHBoxLayout()
        f2.setLayout(l2)

        f3 = QFrame()
        l3 = QGridLayout()
        f3.setLayout(l3)

        l3.addWidget(QLabel('Destination Files :'), 0, 0)
        self.destFilesList = QListWidget()
        self.destFilesList.setAlternatingRowColors(True)
        l3.addWidget(self.destFilesList, 1, 0)

        l2.addWidget(self.initFileFrame())
        l2.addWidget(f3)
        l.addWidget(f2, row, 0, 1, 3)

        row += 1

        l.addWidget(self.initSrcFiles(), row, 0, 1, 3)

        row += 1

        self.convertBtn = QPushButton('Convert')
        self.convertBtn.clicked.connect(self.handleConvertClicked)
        self.convertBtn.setEnabled(False)
        l.addWidget(self.convertBtn, row, 0, 1, 3)

        return f

    def initSrcFiles(self):

        row = 0

        f = QFrame()
        l = QGridLayout()
        f.setLayout(l)

        l.addWidget(QLabel('Source Files :'), row, 0)
        self.srcFilesList = QListWidget()
        self.srcFilesList.setSelectionMode(QAbstractItemView.MultiSelection)
        self.srcFilesList.setAlternatingRowColors(True)
        self.srcFilesList.model().rowsInserted.connect(
            self.handleSrcFilesChanged)
        self.srcFilesList.model().rowsRemoved.connect(
            self.handleSrcFilesChanged)
        selectionModel = self.srcFilesList.selectionModel()
        selectionModel.selectionChanged.connect(
            self.handleSrcFilesSelectionChanged)
        l.addWidget(self.srcFilesList, row, 1, 3, 1)

        self.srcFilesBtn = QPushButton('Select Files')
        self.srcFilesBtn.clicked.connect(self.handleSelectSrcFiles)
        self.srcFilesBtn.setSizePolicy(QSizePolicy.Preferred,
                                       QSizePolicy.Expanding)
        l.addWidget(self.srcFilesBtn, row, 2)
        row += 1

        self.addFilesBtn = QPushButton('Add Files')
        self.addFilesBtn.clicked.connect(self.handleAddSrcFiles)
        self.addFilesBtn.setSizePolicy(QSizePolicy.Preferred,
                                       QSizePolicy.Expanding)
        l.addWidget(self.addFilesBtn, row, 2)
        row += 1

        self.removeFilesBtn = QPushButton('Remove Files')
        self.removeFilesBtn.setEnabled(False)
        self.removeFilesBtn.clicked.connect(self.handleRemoveSrcFiles)
        self.removeFilesBtn.setSizePolicy(QSizePolicy.Preferred,
                                          QSizePolicy.Expanding)
        l.addWidget(self.removeFilesBtn, row, 2)
        row += 1

        self.errorEdit = QPlainTextEdit()
        self.errorEdit.setReadOnly(True)
        l.addWidget(self.errorEdit, row, 1, 1, 2)
        self.comms.errorSignal.connect(self.errorEdit.appendPlainText)

        return f

    def initFileFrame(self):
        row = 0

        f = QFrame()
        l = QGridLayout()
        f.setLayout(l)
        #         f.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)

        l.addWidget(QLabel('Destination File :'), row, 0)
        self.destFilenameEdit = QLineEdit(self.destFilename)
        self.destFilenameEdit.setEnabled(False)
        self.destFilenameEdit.textChanged.connect(
            self.handleDestFilenameChanged)
        l.addWidget(self.destFilenameEdit, row, 1)
        row += 1

        self.combineRoutesBox = QCheckBox('combine_routes')
        if self.config[FORMS]['combine_routes']:
            self.combineRoutesBox.setChecked(True)
        else:
            self.combineRoutesBox.setChecked(False)
        self.combineRoutesBox.clicked.connect(self.handleCombineRoutesClicked)
        self.combineRoutesBox.setEnabled(False)
        l.addWidget(self.combineRoutesBox, row, 0)
        row += 1

        addDateInNameBox = QCheckBox('Add date to filename')
        addDateInNameBox.clicked.connect(self.handleAddDateClicked)
        l.addWidget(addDateInNameBox, row, 0)
        if self.config[FORMS]['prefix_date']:
            self.prefixDateInNameBox = QPushButton('prefix_date')
            self.prefixDateInNameBox.setEnabled(False)
        else:
            self.prefixDateInNameBox = QPushButton('Suffix date')
            self.prefixDateInNameBox.setEnabled(False)
        self.prefixDateInNameBox.setToolTip('Click to change to prefix date.')
        self.prefixDateInNameBox.clicked.connect(self.handlePrefixDateClicked)

        l.addWidget(self.prefixDateInNameBox, row, 1)
        row += 1

        addRouteInNameBox = QCheckBox('Add route to filename')
        addRouteInNameBox.clicked.connect(self.handleAddRouteClicked)
        l.addWidget(addRouteInNameBox, row, 0)
        #         row += 1

        return f

    def initConfigPage(self):
        row = 0

        f = QFrame()
        l = QGridLayout()
        f.setLayout(l)

        srcLbl = QLabel('Source directory :')
        srcLbl.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        l.addWidget(srcLbl, row, 0)

        self.srcDirBox = QLineEdit()
        self.srcDirBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.srcDirBox.setText(self.config[PATHS]['download_path'])
        l.addWidget(self.srcDirBox, row, 1)

        srcDirSelectBtn = QPushButton('Select')
        srcDirSelectBtn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        srcDirSelectBtn.clicked.connect(self.handleSelectSrcDirectory)
        l.addWidget(srcDirSelectBtn, row, 2)

        row += 1

        destLbl = QLabel('Destination directory :')
        destLbl.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        l.addWidget(destLbl, row, 0)

        self.destDirBox = QLineEdit()
        self.destDirBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.destDirBox.setText(self.config[PATHS]['save_path'])
        l.addWidget(self.destDirBox, row, 1)

        destDirSelectBtn = QPushButton('Select')
        destDirSelectBtn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        destDirSelectBtn.clicked.connect(self.handleSelectDestDirectory)
        l.addWidget(destDirSelectBtn, row, 2)

        row += 1

        l.addWidget(QFrame(), row, 0, 1, 3)

        return f

    def handleSelectSrcDirectory(self):
        directory = QFileDialog.getExistingDirectory(
            self, 'Select Source Directory',
            self.config[PATHS]['download_path'], QFileDialog.ShowDirsOnly)
        if not directory == '':
            self.config[PATHS]['download_path'] = directory
            self.srcDirBox.setText(directory)

    def handleSelectDestDirectory(self):
        directory = QFileDialog.getExistingDirectory(
            self, 'Select Destination Directory',
            self.config[PATHS]['save_path'], QFileDialog.ShowDirsOnly)
        if not directory == '':
            self.config[PATHS]['save_path'] = directory
            self.destDirBox.setText(directory)

    def joinSavePath(self, path, filename, ext):
        newpath = os.path.join(path, filename)
        newpath += ext
        return newpath

    @pyqtSlot(bool)
    def handleAddDateClicked(self, checked):
        if checked:
            self.config[FORMS]['include_path'] = True
            self.prefixDateInNameBox.setEnabled(True)
        else:
            self.config[FORMS]['include_path'] = False
            self.prefixDateInNameBox.setEnabled(False)

    @pyqtSlot()
    def handlePrefixDateClicked(self):
        if self.config[FORMS]['prefix_date']:
            self.config[FORMS]['prefix_date'] = False
            self.prefixDateInNameBox.setText('Suffix date')
            self.prefixDateInNameBox.setToolTip(
                'Click to change to prefix date.')
        else:
            self.config[FORMS]['prefix_date'] = True
            self.prefixDateInNameBox.setText('Prefix date')
            self.prefixDateInNameBox.setToolTip(
                'Click to change to suffix date.')

    @pyqtSlot()
    def handleAddRouteClicked(self, checked):
        if checked:
            self.config[FORMS]['include_routes'] = True
        else:
            self.config[FORMS]['include_routes'] = False

    @pyqtSlot()
    def handleCombineRoutesClicked(self):
        if self.combineRoutesBox.isChecked():
            self.config[FORMS]['combine_routes'] = True
        else:
            self.config[FORMS]['combine_routes'] = False

        self.enableStuff()

    def enableStuff(self):
        if self.srcFilesList.model().rowCount() == 0:
            self.convertBtn.setEnabled(False)
            self.combineRoutesBox.setEnabled(False)
            self.destFilenameEdit.setEnabled(False)
        elif self.srcFilesList.model().rowCount() == 1:
            self.convertBtn.setEnabled(True)
            self.combineRoutesBox.setEnabled(False)
            self.destFilenameEdit.setEnabled(True)
        else:
            self.convertBtn.setEnabled(True)
            self.combineRoutesBox.setEnabled(True)
            if self.combineRoutesBox.isChecked():
                self.destFilenameEdit.setEnabled(True)
            else:
                self.destFilenameEdit.setEnabled(False)

    @pyqtSlot()
    def handleDestFilenameChanged(self, text):
        if len(text) > 0:
            if self.config[PATHS]['include_path']:
                year = datetime.year
                month = datetime.month
                day = datetime.day
                datestr = str(year)
                if month < 10: datestr += '0'
                datestr += str(month)
                if day < 10: datestr += '0'
                datestr += str(day)
                if self.config[FORMS]['prefix_date']:
                    name = datestr + '_' + text
                else:
                    name = text + '_' + datestr
            else:
                name = text

            self.config[FILES]['save file'] = name
            self.destPathLbl.setText(
                self.joinSavePath(self.savepath, self.savefile, self.saveext))

    def createDestinationFilePath(self):
        return self.joinSavePath(self.savepath, self.savefile, self.saveext)

    @pyqtSlot()
    def handleSrcFilesSelectionChanged(self, selected):
        if len(selected.indexes()) > 0:
            self.removeFilesBtn.setEnabled(True)
        else:
            self.removeFilesBtn.setEnabled(False)

    @pyqtSlot()
    def handleSrcFilesChanged(self):
        self.enableStuff()

    @pyqtSlot()
    def handleConvertClicked(self):
        if len(self.filenames) > 0:
            toexcel = ToExcel()

            self.currentPlugin.convert(self.filenames)
            routedata = self.currentPlugin.data

            if self.config[FORMS]['combine_routes']:
                combined = []
                for route in routedata.keys():
                    singleroute = routedata[route]
                    combined += singleroute
                path = self.joinSavePath(self.config[PATHS]['save_path'],
                                         self.config[FILES]['save_file'],
                                         self.config[FILES]['save_ext'])
                toexcel.create_workbook(combined, path)
                self.destFilesList.addItem(path)

            else:
                i = 1
                for route in routedata.keys():
                    singleroute = routedata[route]
                    if self.config[FORMS]['include_routes'] and len(route) > 0:
                        path = self.joinSavePath(
                            self.config[PATHS]['save_path'],
                            self.config[FILES]['save_file'] + '_' + route,
                            self.config[FILES]['save_ext'])
                    else:
                        path = self.joinSavePath(
                            self.config[PATHS]['save_path'],
                            self.config[FILES]['save_file'] + '(' + str(i) +
                            ')', self.config[FILES]['save_ext'])
                        i += 1

                    toexcel.create_workbook(singleroute, path)
                    self.destFilesList.addItem(path)

    @pyqtSlot()
    def handleConverterChanged(self):
        pluginName = self.currentPluginBox.currentText()
        if pluginName != self.config[NAMES]['current_plugin_name']:
            self.config[NAMES]['current_plugin_name'] = pluginName
            self.currentPlugin = self.plugins[pluginName]
            self.filetypes = self.currentPlugin.filetypes

    @pyqtSlot()
    def handleCloseClicked(self):
        self.close()

    @pyqtSlot()
    def handleSelectSrcFiles(self):
        fileDlg = QFileDialog(self, 'Select Files',
                              self.config[PATHS]['download_path'],
                              self.filetypes)
        fileDlg.setFileMode(QFileDialog.ExistingFiles)

        if fileDlg.exec_():
            self.filenames = fileDlg.selectedFiles()

        self.srcFilesList.clear()
        self.srcFilesList.addItems(self.filenames)

    @pyqtSlot()
    def handleAddSrcFiles(self):
        fileDlg = QFileDialog(self, 'Select Files',
                              self.config[PATHS]['download_path'],
                              self.filetypes)
        fileDlg.setFileMode(QFileDialog.ExistingFiles)

        if fileDlg.exec_():
            for filename in fileDlg.selectedFiles():
                if filename not in self.filenames:
                    self.filenames.append(filename)
                    self.srcFilesList.addItem(filename)

    @pyqtSlot()
    def handleRemoveSrcFiles(self):
        selectedModel = self.srcFilesList.selectionModel()
        selected = selectedModel.selectedIndexes()
        for index in selected:
            name = index.data()
            self.filenames.remove(name)
            self.srcFilesList.takeItem(index.row())
        selectedModel.clear()

    @pyqtSlot(str)
    def selectPlugin(self, name):
        # activate the current plugin
        #             self.pluginManager.activatePluginByName(name)
        self.config[NAMES]['current_plugin_name'] = name
        self.currentPlugin = self.plugins[name]
        self.filetypes = self.currentPlugin.filetypes

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def exportConfig(self):
        with open(self.cfgFileName, 'w') as configFile:
            yaml.dump(self.config, configFile)

    def createUserConfig(self):
        """
        Create the user's config file in OS specific location
        """
        os.makedirs(os.path.dirname(self.cfgFileName), exist_ok=True)
        self.exportConfig()

    def closeEvent(self, event):
        buttonReply = QMessageBox.warning(
            self, 'Close Application',
            'You are about to close the Application,'
            ' Press Yes to continue or Cancel to return to the Application',
            QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel)
        if buttonReply == QMessageBox.Yes:
            self.exportConfig()
            exit()