class AnnotationsAppearance(SizePersistedDialog):
    '''
    Dialog for managing CSS rules, including Preview window
    '''
    if isosx:
        FONT = QFont('Monaco', 12)
    elif iswindows:
        FONT = QFont('Lucida Console', 9)
    elif islinux:
        FONT = QFont('Monospace', 9)
        FONT.setStyleHint(QFont.TypeWriter)

    def __init__(self, parent, icon, prefs):

        self.parent = parent
        self.prefs = prefs
        self.icon = icon
        super(AnnotationsAppearance, self).__init__(parent, 'appearance_dialog')
        self.setWindowTitle(_('Modify appearance'))
        self.setWindowIcon(icon)
        self.l = QVBoxLayout(self)
        self.setLayout(self.l)

        # Add a label for description
        #self.description_label = QLabel(_("Descriptive text here"))
        #self.l.addWidget(self.description_label)

        # Add a group box, vertical layout for preview window
        self.preview_gb = QGroupBox(self)
        self.preview_gb.setTitle(_("Preview"))
        self.preview_vl = QVBoxLayout(self.preview_gb)
        self.l.addWidget(self.preview_gb)

        self.wv = QWebView()
        self.wv.setHtml('<p></p>')
        self.wv.setMinimumHeight(100)
        self.wv.setMaximumHeight(16777215)
        self.wv.setGeometry(0, 0, 200, 100)
        self.wv.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.preview_vl.addWidget(self.wv)

        # Create a group box, horizontal layout for the table
        self.css_table_gb = QGroupBox(self)
        self.css_table_gb.setTitle(_("Annotation elements"))
        self.elements_hl = QHBoxLayout(self.css_table_gb)
        self.l.addWidget(self.css_table_gb)

        # Add the group box to the main layout
        self.elements_table = AnnotationElementsTable(self, 'annotation_elements_tw')
        self.elements_hl.addWidget(self.elements_table)
        self.elements_table.initialize()

        # Options
        self.options_gb = QGroupBox(self)
        self.options_gb.setTitle(_("Options"))
        self.options_gl = QGridLayout(self.options_gb)
        self.l.addWidget(self.options_gb)
        current_row = 0

        # <hr/> separator
        # addWidget(widget, row, col, rowspan, colspan)
        self.hr_checkbox = QCheckBox(_('Add horizontal rule between annotations'))
        self.hr_checkbox.stateChanged.connect(self.hr_checkbox_changed)
        self.hr_checkbox.setCheckState(
            JSONConfig('plugins/annotations').get('appearance_hr_checkbox', False))
        self.options_gl.addWidget(self.hr_checkbox, current_row, 0, 1, 4)
        current_row += 1

        # Timestamp
        self.timestamp_fmt_label = QLabel(_("Timestamp format:"))
        self.options_gl.addWidget(self.timestamp_fmt_label, current_row, 0)

        self.timestamp_fmt_le = QLineEdit(
            JSONConfig('plugins/annotations').get('appearance_timestamp_format', default_timestamp),
            parent=self)
        self.timestamp_fmt_le.textEdited.connect(self.timestamp_fmt_changed)
        self.timestamp_fmt_le.setFont(self.FONT)
        self.timestamp_fmt_le.setObjectName('timestamp_fmt_le')
        self.timestamp_fmt_le.setToolTip(_('Format string for timestamp'))
        self.timestamp_fmt_le.setMaximumWidth(16777215)
        self.timestamp_fmt_le.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.options_gl.addWidget(self.timestamp_fmt_le, current_row, 1)

        self.timestamp_fmt_reset_tb = QToolButton(self)
        self.timestamp_fmt_reset_tb.setToolTip(_("Reset to default"))
        self.timestamp_fmt_reset_tb.setIcon(QIcon(I('trash.png')))
        self.timestamp_fmt_reset_tb.clicked.connect(self.reset_timestamp_to_default)
        self.options_gl.addWidget(self.timestamp_fmt_reset_tb, current_row, 2)

        self.timestamp_fmt_help_tb = QToolButton(self)
        self.timestamp_fmt_help_tb.setToolTip(_("Format string reference"))
        self.timestamp_fmt_help_tb.setIcon(QIcon(I('help.png')))
        self.timestamp_fmt_help_tb.clicked.connect(self.show_help)
        self.options_gl.addWidget(self.timestamp_fmt_help_tb, current_row, 3)

        # Button box
        bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.l.addWidget(bb)

        # Spacer
        self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.l.addItem(self.spacerItem)

        # Sizing
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        self.resize_dialog()

    def hr_checkbox_changed(self, state):
        self.prefs.set('appearance_hr_checkbox', state)
        self.elements_table.preview_css()

    def reset_timestamp_to_default(self):
        from calibre_plugins.annotations.appearance import default_timestamp
        self.timestamp_fmt_le.setText(default_timestamp)
        self.timestamp_fmt_changed()

    def show_help(self):
        '''
        Display strftime help file
        '''
        hv = HelpView(self, self.icon, self.prefs,
            html=get_resources('help/timestamp_formats.html'), title=_("Timestamp formats"))
        hv.show()

    def sizeHint(self):
        return QtCore.QSize(600, 200)

    def timestamp_fmt_changed(self):
        self.prefs.set('appearance_timestamp_format', str(self.timestamp_fmt_le.text()))
        self.elements_table.preview_css()
Exemple #2
0
class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'Media Project'
        self.left = 100
        self.top = 100
        self.width = 960
        self.height = 800
        self.res = list(range(14))
        self.initUI()

    def initUI(self):
        self.pixmap = QPixmap("White.png")
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        openFile = QAction(QIcon('open.png'), 'Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new File')
        openFile.setFont(QFont("Roman times", 12))
        openFile.triggered.connect(self.msg)

        menubar = self.menuBar()
        menubar.setFont(QFont("Roman times", 12))
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)

        lb1 = QLabel("Origin Picture", self)
        lb1.move(200, 50)
        lb1.setFont(QFont("Roman times", 14))
        lb1.resize(150, 30)

        lb2 = QLabel("Heatmap", self)
        lb2.move(200, 390)
        lb2.setFont(QFont("Roman times", 14))
        lb2.resize(150, 30)

        self.l1 = QLabel(self)
        self.l1.resize(224, 224)
        self.l1.move(150, 90)

        CLASS_NAMES = [
            'Atelectasis', 'Cardiomegaly', 'Effusion', 'Infiltration', 'Mass',
            'Nodule', 'Pneumonia', 'Pneumothorax', 'Consolidation', 'Edema',
            'Emphysema', 'Fibrosis', 'Pleural_Thickening', 'Hernia'
        ]
        lbl1 = QLabel(CLASS_NAMES[0], self)
        lbl1.move(550, 50)
        lbl1.setFont(QFont("Roman times", 12))
        lbl1.resize(150, 30)
        self.t1 = QLineEdit(self)
        self.t1.move(700, 50)
        self.t1.setFont(QFont("Roman times", 12))
        self.t1.resize(120, 30)

        lbl2 = QLabel(CLASS_NAMES[1], self)
        lbl2.move(550, 100)
        lbl2.setFont(QFont("Roman times", 12))
        lbl2.resize(150, 30)
        self.t2 = QLineEdit(self)
        self.t2.move(700, 100)
        self.t2.setFont(QFont("Roman times", 12))
        self.t2.resize(120, 30)

        lbl3 = QLabel(CLASS_NAMES[2], self)
        lbl3.move(550, 150)
        lbl3.setFont(QFont("Roman times", 12))
        lbl3.resize(150, 30)
        self.t3 = QLineEdit(self)
        self.t3.move(700, 150)
        self.t3.setFont(QFont("Roman times", 12))
        self.t3.resize(120, 30)

        lbl4 = QLabel(CLASS_NAMES[3], self)
        lbl4.move(550, 200)
        lbl4.setFont(QFont("Roman times", 12))
        lbl4.resize(150, 30)
        self.t4 = QLineEdit(self)
        self.t4.move(700, 200)
        self.t4.setFont(QFont("Roman times", 12))
        self.t4.resize(120, 30)

        lbl5 = QLabel(CLASS_NAMES[4], self)
        lbl5.move(550, 250)
        lbl5.setFont(QFont("Roman times", 12))
        lbl5.resize(150, 30)
        self.t5 = QLineEdit(self)
        self.t5.move(700, 250)
        self.t5.setFont(QFont("Roman times", 12))
        self.t5.resize(120, 30)

        lbl6 = QLabel(CLASS_NAMES[5], self)
        lbl6.move(550, 300)
        lbl6.setFont(QFont("Roman times", 12))
        lbl6.resize(150, 30)
        self.t6 = QLineEdit(self)
        self.t6.move(700, 300)
        self.t6.setFont(QFont("Roman times", 12))
        self.t6.resize(120, 30)

        lbl7 = QLabel(CLASS_NAMES[6], self)
        lbl7.move(550, 350)
        lbl7.setFont(QFont("Roman times", 12))
        lbl7.resize(150, 30)
        self.t7 = QLineEdit(self)
        self.t7.move(700, 350)
        self.t7.setFont(QFont("Roman times", 12))
        self.t7.resize(120, 30)

        lbl8 = QLabel(CLASS_NAMES[7], self)
        lbl8.move(550, 400)
        lbl8.setFont(QFont("Roman times", 12))
        lbl8.resize(150, 30)
        self.t8 = QLineEdit(self)
        self.t8.move(700, 400)
        self.t8.setFont(QFont("Roman times", 12))
        self.t8.resize(120, 30)

        lbl9 = QLabel(CLASS_NAMES[8], self)
        lbl9.move(550, 450)
        lbl9.setFont(QFont("Roman times", 12))
        lbl9.resize(150, 30)
        self.t9 = QLineEdit(self)
        self.t9.move(700, 450)
        self.t9.setFont(QFont("Roman times", 12))
        self.t9.resize(120, 30)

        lbl10 = QLabel(CLASS_NAMES[9], self)
        lbl10.move(550, 500)
        lbl10.setFont(QFont("Roman times", 12))
        lbl10.resize(150, 30)
        self.t10 = QLineEdit(self)
        self.t10.move(700, 500)
        self.t10.setFont(QFont("Roman times", 12))
        self.t10.resize(120, 30)

        lbl11 = QLabel(CLASS_NAMES[10], self)
        lbl11.move(550, 550)
        lbl11.setFont(QFont("Roman times", 12))
        lbl11.resize(150, 30)
        self.t11 = QLineEdit(self)
        self.t11.move(700, 550)
        self.t11.setFont(QFont("Roman times", 12))
        self.t11.resize(120, 30)

        lbl12 = QLabel(CLASS_NAMES[11], self)
        lbl12.move(550, 600)
        lbl12.setFont(QFont("Roman times", 12))
        lbl12.resize(150, 30)
        self.t12 = QLineEdit(self)
        self.t12.move(700, 600)
        self.t12.setFont(QFont("Roman times", 12))
        self.t12.resize(120, 30)

        lbl13 = QLabel(CLASS_NAMES[12], self)
        lbl13.move(550, 650)
        lbl13.setFont(QFont("Roman times", 12))
        lbl13.resize(150, 30)
        self.t13 = QLineEdit(self)
        self.t13.move(700, 650)
        self.t13.setFont(QFont("Roman times", 12))
        self.t13.resize(120, 30)

        lbl14 = QLabel(CLASS_NAMES[13], self)
        lbl14.move(550, 700)
        lbl14.setFont(QFont("Roman times", 12))
        lbl14.resize(150, 30)
        self.t14 = QLineEdit(self)
        self.t14.move(700, 700)
        self.t14.setFont(QFont("Roman times", 12))
        self.t14.resize(120, 30)

        self.l2 = QLabel(self)
        self.l2.resize(224, 224)
        self.l2.move(150, 430)

        self.clear()

        button1 = QPushButton('Diagnosis', self)
        button1.move(120, 340)
        button1.setFont(QFont("Roman times", 12))
        button1.clicked.connect(self.diag)

        button2 = QPushButton('clear', self)
        button2.move(280, 340)
        button2.setFont(QFont("Roman times", 12))
        button2.clicked.connect(self.clear)

        self.show()

    def diag(self):
        try:
            res = gen_heatmap(self.file1, heatmap)
            pixmap2 = QPixmap(heatmap)
            self.l2.setPixmap(pixmap2)

            self.t1.setText(str(res[0]))
            self.t2.setText(str(res[1]))
            self.t3.setText(str(res[2]))
            self.t4.setText(str(res[3]))
            self.t5.setText(str(res[4]))
            self.t6.setText(str(res[5]))
            self.t7.setText(str(res[6]))
            self.t8.setText(str(res[7]))
            self.t9.setText(str(res[8]))
            self.t10.setText(str(res[9]))
            self.t11.setText(str(res[10]))
            self.t12.setText(str(res[11]))
            self.t13.setText(str(res[12]))
            self.t14.setText(str(res[13]))
        except:
            print("Please choose a picture as input")

    def msg(self):
        fileName1, filetype = QFileDialog.getOpenFileName(
            self, "选取文件", "./", "All Files (*);;Picture Files (*.jpg)")
        self.file1 = fileName1
        img = cv2.imread(fileName1)
        img = cv2.resize(img, (224, 224))
        cv2.imwrite(fileName1, img)
        pixmap1 = QPixmap(fileName1)
        self.l1.setPixmap(pixmap1)

    def clear(self):
        self.t1.setText("")
        self.t2.setText("")
        self.t3.setText("")
        self.t4.setText("")
        self.t5.setText("")
        self.t6.setText("")
        self.t7.setText("")
        self.t8.setText("")
        self.t9.setText("")
        self.t10.setText("")
        self.t11.setText("")
        self.t12.setText("")
        self.t13.setText("")
        self.t14.setText("")
        self.l1.setPixmap(self.pixmap)
        self.l2.setPixmap(self.pixmap)
        self.file1 = ""
Exemple #3
0
class LibraryCodesTab(QWidget):
    def __init__(self, mygui, myguidb, mymainprefs, myparam_dict, myuiexit,
                 mysavedialoggeometry):
        super(LibraryCodesTab, self).__init__()
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.gui = mygui
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.guidb = myguidb
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.lib_path = self.gui.library_view.model().db.library_path
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.mytabprefs = mymainprefs
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.param_dict = myparam_dict
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.ui_exit = myuiexit
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.save_dialog_geometry = mysavedialoggeometry
        #-----------------------------------------------------
        #-----------------------------------------------------
        font = QFont()
        font.setBold(False)
        font.setPointSize(10)
        #-----------------------------------------------------
        self.layout_top = QVBoxLayout()
        self.layout_top.setSpacing(0)
        self.layout_top.setAlignment(Qt.AlignLeft)
        self.setLayout(self.layout_top)
        #-----------------------------------------------------
        self.scroll_area_frame = QScrollArea()
        self.scroll_area_frame.setAlignment(Qt.AlignLeft)
        self.scroll_area_frame.setWidgetResizable(True)
        self.scroll_area_frame.ensureVisible(400, 400)

        self.layout_top.addWidget(
            self.scroll_area_frame
        )  # the scroll area is now the child of the parent of self.layout_top

        # NOTE: the self.scroll_area_frame.setWidget(self.scroll_widget) is at the end of the init() AFTER all children have been created and assigned to a layout...

        #-----------------------------------------------------
        self.scroll_widget = QWidget()
        self.layout_top.addWidget(
            self.scroll_widget
        )  # causes automatic reparenting of QWidget to the parent of self.layout_top, which is:  self .
        #-----------------------------------------------------
        self.layout_frame = QVBoxLayout()
        self.layout_frame.setSpacing(0)
        self.layout_frame.setAlignment(Qt.AlignLeft)

        self.scroll_widget.setLayout(
            self.layout_frame
        )  # causes automatic reparenting of any widget later added to self.layout_frame to the parent of self.layout_frame, which is:  QWidget .

        #-----------------------------------------------------
        self.lc_groupbox = QGroupBox('Settings:')
        self.lc_groupbox.setMaximumWidth(400)
        self.lc_groupbox.setToolTip(
            "<p style='white-space:wrap'>The settings that control 'Library Codes'.  Using only ISBN or ISSN or Author/Title, Library Codes for selected books will be derived using the Current Settings."
        )
        self.layout_frame.addWidget(self.lc_groupbox)

        self.lc_layout = QGridLayout()
        self.lc_groupbox.setLayout(self.lc_layout)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.spacing0 = QLabel()
        self.layout_frame.addWidget(self.spacing0)
        self.spacing0.setMaximumHeight(20)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.button_box = QDialogButtonBox()
        self.button_box.setOrientation(Qt.Horizontal)
        self.button_box.setCenterButtons(True)

        self.layout_frame.addWidget(self.button_box)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.push_button_save_only = QPushButton("Save")
        self.push_button_save_only.clicked.connect(self.save_settings)
        self.push_button_save_only.setDefault(True)
        self.push_button_save_only.setFont(font)
        self.push_button_save_only.setToolTip(
            "<p style='white-space:wrap'>Save all user settings.")
        self.button_box.addButton(self.push_button_save_only, 0)

        self.push_button_exit_only = QPushButton("Exit")
        self.push_button_exit_only.clicked.connect(self.exit_only)
        self.push_button_exit_only.setDefault(False)
        self.push_button_exit_only.setFont(font)
        self.push_button_exit_only.setToolTip(
            "<p style='white-space:wrap'>Exit immediately without saving anything."
        )
        self.button_box.addButton(self.push_button_exit_only, 0)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------

        r = 4

        self.ddc_labelname = QLineEdit(self)
        self.ddc_labelname.setText(self.mytabprefs['DDC'])
        self.ddc_labelname.setFont(font)
        self.ddc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for DDC.<br><br>See:  https://www.oclc.org/dewey/features/summaries.en.html"
        )
        self.ddc_labelname.setMaximumWidth(100)
        self.lc_layout.addWidget(self.ddc_labelname, r, 0)

        self.ddc_activate_checkbox = QCheckBox(
            "Activate 'Dewey Decimal Code' Classification?")
        self.ddc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive DDC?")
        r = r + 1
        self.lc_layout.addWidget(self.ddc_activate_checkbox, r, 0)
        if prefs['DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.ddc_activate_checkbox.setChecked(True)
        else:
            self.ddc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing1 = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.spacing1, r, 0)
        self.spacing1.setMaximumHeight(10)
        #-----------------------------------------------------
        self.lcc_labelname = QLineEdit(self)
        self.lcc_labelname.setText(self.mytabprefs['LCC'])
        self.lcc_labelname.setFont(font)
        self.lcc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for LCC.<br><br>See: http://www.loc.gov/catdir/cpso/lcco/ "
        )
        self.lcc_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.lcc_labelname, r, 0)

        self.lcc_activate_checkbox = QCheckBox(
            "Activate 'Library of Congress Code' Classification?")
        self.lcc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive LCC?")
        r = r + 1
        self.lc_layout.addWidget(self.lcc_activate_checkbox, r, 0)
        if prefs['LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lcc_activate_checkbox.setChecked(True)
        else:
            self.lcc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing2 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing2, r, 0)
        self.spacing2.setMaximumHeight(10)
        #-----------------------------------------------------

        self.fast_labelname = QLineEdit(self)
        self.fast_labelname.setText(self.mytabprefs['FAST'])
        self.fast_labelname.setFont(font)
        self.fast_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for FAST Tag Values. "
        )
        self.fast_labelname.setMinimumWidth(100)
        self.fast_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.fast_labelname, r, 0)

        self.fast_activate_checkbox = QCheckBox("Activate 'FAST' Tags?")
        self.fast_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive FAST Tags?\
                                                                                                                    <br><br>Text.  Behaves like Tags. Not Names.<br><br>"
        )
        r = r + 1
        self.lc_layout.addWidget(self.fast_activate_checkbox, r, 0)
        if prefs['FAST_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.fast_activate_checkbox.setChecked(True)
        else:
            self.fast_activate_checkbox.setChecked(False)

        #-----------------------------------------------------
        self.spacing6 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing6, r, 0)
        self.spacing6.setMaximumHeight(10)
        #-----------------------------------------------------

        self.oclc_labelname = QLineEdit(self)
        self.oclc_labelname.setText(self.mytabprefs['OCLC'])
        self.oclc_labelname.setFont(font)
        self.oclc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for OCLC-OWI.<br><br>See: #http://classify.oclc.org/classify2/   "
        )
        self.oclc_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.oclc_labelname, r, 0)

        self.oclc_activate_checkbox = QCheckBox(
            "Activate 'Online Computer Library Center' Work ID Code?")
        self.oclc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive OCLC-OWI?")
        r = r + 1
        self.lc_layout.addWidget(self.oclc_activate_checkbox, r, 0)
        if self.mytabprefs['OCLC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.oclc_activate_checkbox.setChecked(True)
        else:
            self.oclc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing5 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing5, r, 0)
        self.spacing5.setMaximumHeight(10)
        #-----------------------------------------------------
        self.lc_author_details_labelname = QLineEdit(self)
        self.lc_author_details_labelname.setText(
            self.mytabprefs['EXTRA_AUTHOR_DETAILS'])
        self.lc_author_details_labelname.setFont(font)
        self.lc_author_details_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for 'LC Extra Author Details'.\
                                                                                                                              <br><br>Text.  Behaves like Tags. Not Names.<br><br>"
        )
        self.lc_author_details_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.lc_author_details_labelname, r, 0)

        self.lc_author_details_checkbox = QCheckBox(
            "Activate 'Library Codes Extra Author Details'?")
        self.lc_author_details_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to add (never delete or replace) any available Tag-like values to this Custom Column if they are associated with the OCLC-OWI Identifier?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_author_details_checkbox, r, 0)
        if self.mytabprefs['EXTRA_AUTHOR_DETAILS_IS_ACTIVE'] == unicode_type(
                S_TRUE):
            self.lc_author_details_checkbox.setChecked(True)
        else:
            self.lc_author_details_checkbox.setChecked(False)
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.spacing4 = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.spacing4, r, 0)
        self.spacing4.setMaximumHeight(10)
        #-----------------------------------------------------
        font.setBold(False)
        font.setPointSize(7)
        #-----------------------------------------------------
        self.push_button_autoadd_custom_columns = QPushButton(
            "Automatically Add Activated Custom Columns?")
        self.push_button_autoadd_custom_columns.clicked.connect(
            self.autoadd_custom_columns)
        self.push_button_autoadd_custom_columns.setDefault(False)
        self.push_button_autoadd_custom_columns.setFont(font)
        self.push_button_autoadd_custom_columns.setToolTip(
            "<p style='white-space:wrap'>Do you want to automatically add the Custom Columns selected above?<br><br>If you have any issues, please add them manually."
        )
        r = r + 4
        self.lc_layout.addWidget(self.push_button_autoadd_custom_columns, r, 0)
        self.push_button_autoadd_custom_columns.setMaximumWidth(250)
        #-----------------------------------------------------
        self.lc_custom_columns_generation_label = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.lc_custom_columns_generation_label, r, 0)
        self.lc_custom_columns_generation_label.setText(
            "                                                              ")
        self.lc_custom_columns_generation_label.setMaximumHeight(10)
        self.lc_custom_columns_generation_label.setFont(font)

        self.oclc_identifier_only_checkbox = QCheckBox(
            "Always Create OCLC-OWI as an 'Identifier' (à la ISBN)?")
        self.oclc_identifier_only_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to update Calibre's Identifiers for an Identifier of 'OCLC-OWI',\
                                                                                                                                 regardless of whether you want its own Custom Column updated?\
                                                                                                                                <br><br>REQUIRED to derive DDC/LCC using Author/Title."
        )
        r = r + 2
        self.lc_layout.addWidget(self.oclc_identifier_only_checkbox, r, 0)
        if prefs['OCLC_IDENTIFIER'] == unicode_type(S_TRUE):
            self.oclc_identifier_only_checkbox.setChecked(True)
        else:
            self.oclc_identifier_only_checkbox.setChecked(False)

        #-----------------------------------------------------
        self.spacing3 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing3, r, 0)
        self.spacing3.setMaximumHeight(10)
        #-----------------------------------------------------
        font.setBold(False)
        font.setPointSize(10)
        #-----------------------------------------------------
        self.lc_genre_labelname = QLineEdit(self)
        self.lc_genre_labelname.setText(self.mytabprefs['GENRE'])
        self.lc_genre_labelname.setFont(font)
        self.lc_genre_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for 'Genre'.\
                                                                                                                              <br><br>Text.  Behaves like Tags.<br><br>"
        )
        self.lc_genre_labelname.setMaximumWidth(100)
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_labelname, r, 0)

        self.lc_checkbox_buttongroup = QButtonGroup()
        self.lc_checkbox_buttongroup.setExclusive(True)

        self.lc_genre_ddc_checkbox = QCheckBox(
            "Update 'Genre' using DDC-to-Genre Mappings?")
        self.lc_genre_ddc_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want LC to update 'Genre' using the DDC-to-Genre mapping in Table _lc_genre_mapping?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_ddc_checkbox, r, 0)

        self.lc_genre_lcc_checkbox = QCheckBox(
            "Update 'Genre' using LCC-to-Genre Mappings?")
        self.lc_genre_lcc_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want LC to update 'Genre' using the LCC-to-Genre mapping in Table _lc_genre_mapping?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_lcc_checkbox, r, 0)

        self.lc_genre_inactive_checkbox = QCheckBox(
            "Do not update 'Genre' at all")
        self.lc_genre_inactive_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do no 'Genre' processing at all?")
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_inactive_checkbox, r, 0)

        self.lc_checkbox_buttongroup.addButton(self.lc_genre_ddc_checkbox)
        self.lc_checkbox_buttongroup.addButton(self.lc_genre_lcc_checkbox)
        self.lc_checkbox_buttongroup.addButton(self.lc_genre_inactive_checkbox)

        if self.mytabprefs['GENRE_DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_ddc_checkbox.setChecked(True)
        elif self.mytabprefs['GENRE_LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_lcc_checkbox.setChecked(True)
        elif self.mytabprefs['GENRE_IS_INACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_inactive_checkbox.setChecked(True)

        self.lc_exact_match_checkbox = QCheckBox(
            "DDC: Require an 'Exact Match', not a 'Best Match'?")
        self.lc_exact_match_checkbox.setToolTip(
            "<p style='white-space:wrap'>Check this checkbox if you want an exact DDC match to be required in Table _lc_genre_mapping.  Otherwise, a 'best match' will be used via progressive shortening from right to left, but not past any decimal point.  If there is no decimal point in a book's DDC, then no progressive shortening will be performed at all."
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_exact_match_checkbox, r, 0)

        if self.mytabprefs['GENRE_EXACT_MATCH'] == unicode_type(S_TRUE):
            self.lc_exact_match_checkbox.setChecked(True)

        self.spin_lcc = QSpinBox(self)
        self.spin_lcc.setMinimum(1)
        self.spin_lcc.setMaximum(50)
        self.spin_lcc.setProperty('value', prefs['GENRE_LCC_MATCH_LENGTH'])
        self.spin_lcc.setMaximumWidth(250)
        self.spin_lcc.setSuffix("    LCC: Maximum Length to Match")
        self.spin_lcc.setToolTip(
            "<p style='white-space:nowrap'>Maximum number of characters in the LCC that should be used to map to the 'Genre', starting from the left.  A maximum of 1 guarantees a (broad) match.\
                                                                                                   <br><br>LCCs are structured with either 1 or 2 beginning letters, so 2-character LCCs have special matching logic.\
                                                                                                   <br><br>Example:   Assume maximum = 2 for a LCC of 'Q1':  Q1 would be attempted.  If it failed, because the 2nd digit is a number, 'Q' would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 2 for a LCC of 'PN1969.C65':  PN would be attempted.  If it failed, nothing else would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'PN1969.C65':  PN19 would be attempted.  If it failed, nothing else would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'Q1':  Q1 would be attempted.  If it failed, because the 2nd digit is a number, 'Q' would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'Q389':  Q389 would be attempted.  If it failed, nothing else would be attempted."
        )
        r = r + 2
        self.lc_layout.addWidget(self.spin_lcc, r, 0)

        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_widget.resize(self.sizeHint())
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_area_frame.setWidget(
            self.scroll_widget
        )  # now that all widgets have been created and assigned to a layout...
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_area_frame.resize(self.sizeHint())
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.resize(self.sizeHint())

    #-----------------------------------------------------------------------------------------
    def validate(self):
        return True

    #-----------------------------------------------------------------------------------------
    def autoadd_custom_columns(self):
        number_active = self.save_settings()
        if number_active == 0:
            return error_dialog(
                self.gui,
                _('Automatically Add Custom Columns'),
                _('No Activated Library Codes Custom Columns Found.  Nothing to Add.'
                  ),
                show=True)
        self.cli_param_list = self.create_cli_parameters()
        is_valid, restart_required = self.create_new_lc_custom_columns(
            self.cli_param_list)
        if is_valid:
            if restart_required:
                self.lc_custom_columns_generation_label.setText(
                    "Addition of Custom Columns Complete.  Restart Calibre Now."
                )
                self.repaint()
                info_dialog(
                    self.gui, 'Automatically Add Custom Columns',
                    'All Selected Custom Customs Were Added If They Did Not Already Exist.  Please Restart Calibre now.'
                ).show()
            else:
                self.lc_custom_columns_generation_label.setText(
                    "Selected Custom Columns Already Exist.  Nothing Done.")
                self.repaint()
        else:
            self.lc_custom_columns_generation_label.setText(
                "Not Completed.  Please Restart Calibre, then Add Manually.")
            self.repaint()
            msg = "Fatal error experienced in adding new Custom Columns."
            error_dialog(self.gui,
                         _('Automatically Add Custom Columns'),
                         _(msg),
                         show=True)

    #-----------------------------------------------------------------------------------------
    def create_cli_parameters(self):

        try:
            del self.cli_param_list
        except:
            pass

        self.cli_param_list = []
        temp_list = []
        cc_taglike_list = []
        cc_fast_name = ""

        if self.mytabprefs['DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['DDC']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical DDC Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['LCC']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical LCC Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['FAST_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['FAST']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
                cc_taglike_list.append(cc)
                cc_fast_name = cc
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical FAST Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['OCLC_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['OCLC']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical OCLC Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['EXTRA_AUTHOR_DETAILS_IS_ACTIVE'] == unicode_type(
                S_TRUE):
            cc = self.mytabprefs['EXTRA_AUTHOR_DETAILS']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
                cc_taglike_list.append(cc)
            else:
                error_dialog(
                    self.gui,
                    _('Automatically Add Custom Columns'),
                    _('Illogical LC Extra Author Details Settings.  Please Correct.'
                      ),
                    show=True)
                return self.cli_param_list
        else:
            pass

        if len(temp_list) == 0:
            del temp_list
            error_dialog(self.gui,
                         _('Automatically Add Custom Columns'),
                         _('Nothing to do.  Please Review Settings.'),
                         show=True)
            return self.cli_param_list

        cc_to_add_list = []

        # for each cc currently set to active, create a parameter...but only if the cc does NOT already exist...
        my_db, my_cursor, is_valid = self.apsw_connect_to_library()
        if not is_valid:
            error_dialog(self.gui,
                         _('Automatically Add Custom Columns'),
                         _('Database Connection Error.  Restart Calibre.'),
                         show=True)
            return

        self.lc_custom_columns_generation_label.setText(
            "...Adding Custom Columns...")
        self.repaint()

        mysql = "SELECT label,name FROM custom_columns"
        my_cursor.execute(mysql)
        tmp_rows = my_cursor.fetchall()
        if not tmp_rows:
            for cc in temp_list:
                cc_to_add_list.append(cc)
            #END FOR
        else:
            if len(tmp_rows) == 0:
                for cc in temp_list:
                    cc_to_add_list.append(cc)
                #END FOR
            else:
                for cc in temp_list:
                    label_already_exists = False
                    for row in tmp_rows:
                        label, name = row
                        if unicode_type(label) == unicode_type(cc):
                            label_already_exists = True
                            break
                        else:
                            continue
                    #END FOR
                    if not label_already_exists:
                        cc_to_add_list.append(cc)
                #END FOR
                del tmp_rows
                del temp_list

        if len(cc_to_add_list) == 0:
            return self.cli_param_list

        cc_to_add_list.sort()

        for label in cc_to_add_list:
            label = unicodedata.normalize('NFKD',
                                          label).encode('ascii', 'ignore')
            label = unicode_type(label)
            label = label.lower()
            name = label.upper()
            datatype = 'text'
            if label in cc_taglike_list:
                is_multiple = "--is-multiple"
                if label == cc_fast_name:
                    name = "FAST Tags"
                else:
                    name = '"LC Extra Author Details"'
                param = is_multiple + '|||' + label + '|||' + name + '|||' + datatype
            else:
                param = label + '|||' + name + '|||' + datatype
            param = param.replace("[LIBRARY]", self.lib_path)
            self.cli_param_list.append(param)
        #END FOR

        del cc_to_add_list

        return self.cli_param_list

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    def apsw_connect_to_library(self):

        my_db = self.gui.library_view.model().db

        self.lib_path = my_db.library_path
        self.lib_path = self.lib_path.replace(os.sep, '/')
        if isbytestring(self.lib_path):
            self.lib_path = self.lib_path.decode(filesystem_encoding)

        path = my_db.library_path
        if isbytestring(path):
            path = path.decode(filesystem_encoding)
        path = path.replace(os.sep, '/')
        path = os.path.join(path, 'metadata.db')
        path = path.replace(os.sep, '/')

        if isbytestring(path):
            path = path.decode(filesystem_encoding)

        if path.endswith("/"):
            path = path[0:-1]

        if path.count("metadata.db") == 0:
            path = path + "/metadata.db"

        try:
            my_db = apsw.Connection(path)
            is_valid = True
        except Exception as e:
            if DEBUG: print("path to metadata.db is: ", path)
            if DEBUG: print("error: ", as_unicode(e))
            is_valid = False
            return None, None, is_valid

        my_cursor = my_db.cursor()

        mysql = "PRAGMA main.busy_timeout = 5000;"  #PRAGMA busy_timeout = milliseconds;
        my_cursor.execute(mysql)

        return my_db, my_cursor, is_valid

    #-----------------------------------------------------------------------------------------
    def exit_only(self):
        self.save_dialog_geometry()  #  inherited from SizePersistedDialog
        self.ui_exit()

    #-----------------------------------------------------------------------------------------
    def save_settings(self):

        self.save_dialog_geometry()  #  inherited from SizePersistedDialog

        self.mytabprefs['DDC'] = self.ddc_labelname.text()
        self.mytabprefs['LCC'] = self.lcc_labelname.text()
        self.mytabprefs['FAST'] = self.fast_labelname.text()
        self.mytabprefs['OCLC'] = self.oclc_labelname.text()

        self.mytabprefs['DDC_IS_ACTIVE'] = unicode_type(
            self.ddc_activate_checkbox.isChecked())
        self.mytabprefs['LCC_IS_ACTIVE'] = unicode_type(
            self.lcc_activate_checkbox.isChecked())
        self.mytabprefs['FAST_IS_ACTIVE'] = unicode_type(
            self.fast_activate_checkbox.isChecked())
        self.mytabprefs['OCLC_IS_ACTIVE'] = unicode_type(
            self.oclc_activate_checkbox.isChecked())
        self.mytabprefs['OCLC_IDENTIFIER'] = unicode_type(
            self.oclc_identifier_only_checkbox.isChecked())

        label = self.mytabprefs['DDC']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.ddc_activate_checkbox.setChecked(False)
        self.mytabprefs['DDC'] = unicode_type(label)

        label = self.mytabprefs['LCC']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.lcc_activate_checkbox.setChecked(False)
        self.mytabprefs['LCC'] = unicode_type(label)

        label = self.mytabprefs['FAST']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.fast_activate_checkbox.setChecked(False)
        self.mytabprefs['FAST'] = unicode_type(label)

        label = self.mytabprefs['OCLC']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.oclc_activate_checkbox.setChecked(False)
        self.mytabprefs['OCLC'] = unicode_type(label)

        if self.mytabprefs['DDC'] == unicode_type(
                "") and self.mytabprefs['LCC'] == unicode_type(
                    "") and self.mytabprefs['FAST'] == unicode_type(
                        "") and self.mytabprefs['OCLC'] == unicode_type(""):
            self.mytabprefs['DDC'] = unicode_type("#ddc")
            self.mytabprefs['LCC'] = unicode_type("#lcc")
            self.mytabprefs['FAST'] = unicode_type("#fast")
            self.mytabprefs['OCLC'] = unicode_type("#oclc_owi")
        else:
            if self.mytabprefs['DDC'] == unicode_type(
                    "") and self.mytabprefs['LCC'] == unicode_type(""):
                self.oclc_identifier_only_checkbox.setChecked(False)
        #---------------------------------------

        s = unicode_type(self.lc_genre_labelname.text())
        s = s.strip()
        if s.startswith("#") and len(s) > 1:
            self.mytabprefs['GENRE'] = unicode_type(s)
            self.mytabprefs['GENRE_DDC_IS_ACTIVE'] = unicode_type(
                self.lc_genre_ddc_checkbox.isChecked())
            self.mytabprefs['GENRE_LCC_IS_ACTIVE'] = unicode_type(
                self.lc_genre_lcc_checkbox.isChecked())
            self.mytabprefs['GENRE_IS_INACTIVE'] = unicode_type(
                self.lc_genre_inactive_checkbox.isChecked())
            self.mytabprefs['GENRE_EXACT_MATCH'] = unicode_type(
                self.lc_exact_match_checkbox.isChecked())
            self.mytabprefs['GENRE_LCC_MATCH_LENGTH'] = self.spin_lcc.value()
        else:
            self.mytabprefs['GENRE'] = unicode_type("#genre")
            self.lc_genre_labelname.setText(unicode_type("#genre"))
            self.lc_genre_ddc_checkbox.setChecked(False)
            self.lc_genre_lcc_checkbox.setChecked(False)
            self.lc_genre_inactive_checkbox.setChecked(True)
            self.mytabprefs['GENRE_DDC_IS_ACTIVE'] = unicode_type(S_FALSE)
            self.mytabprefs['GENRE_LCC_IS_ACTIVE'] = unicode_type(S_FALSE)
            self.mytabprefs['GENRE_IS_INACTIVE'] = unicode_type(S_TRUE)
            self.mytabprefs['GENRE_EXACT_MATCH'] = unicode_type(S_TRUE)
            self.mytabprefs['GENRE_LCC_MATCH_LENGTH'] = 2
            self.repaint()
            sleep(2)

        #---------------------------------------
        #~ for k,v in self.mytabprefs.iteritems():
        for k, v in iteritems(self.mytabprefs):
            v = unicode_type(v)
            v = v.strip()
            prefs[k] = v
        #END FOR
        prefs

        #---------------------------------------

        self.ddc_labelname.setText(self.mytabprefs['DDC'])
        self.lcc_labelname.setText(self.mytabprefs['LCC'])
        self.fast_labelname.setText(self.mytabprefs['FAST'])
        self.oclc_labelname.setText(self.mytabprefs['OCLC'])
        self.repaint()
        sleep(0)

        #~ for k,v in self.mytabprefs.iteritems():
        for k, v in iteritems(self.mytabprefs):
            self.param_dict[k] = v
        #END FOR

        number_active = 0

        if self.mytabprefs['DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1
        if self.mytabprefs['LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1
        if self.mytabprefs['FAST_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1
        if self.mytabprefs['OCLC_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1

        self.ddc_name = self.mytabprefs['DDC'].replace("#", "").strip()
        self.lcc_name = self.mytabprefs['LCC'].replace("#", "").strip()
        self.fast_name = self.mytabprefs['FAST'].replace("#", "").strip()
        self.oclc_name = self.mytabprefs['OCLC'].replace("#", "").strip()

        if self.oclc_identifier_only_checkbox.isChecked():
            self.oclc_identifier_is_desired = True
        else:
            self.oclc_identifier_is_desired = False

        return number_active

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    def create_new_lc_custom_columns(self, execution_param_list):

        if len(self.cli_param_list) == 0:
            return True, False  # successful since the labels already exist; no restart is required.

        dbpath = self.lib_path

        was_successful = True
        restart_required = True

        for param in execution_param_list:
            try:
                lc_cli_add_custom_column(self.guidb, param, dbpath)
            except Exception as e:
                if DEBUG: print("Exception: ", as_unicode(e))
                was_successful = False
                break
        #END FOR

        return was_successful, restart_required

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------


#END of library_codes_dialog.py
class MainWindow(QMainWindow):
    # 求解完成信号
    done1Signal = pyqtSignal(str)
    done2Signal = pyqtSignal(str)


    def __init__(self):
        super().__init__()
        # 移动两根火柴和移动一根火柴的按钮
        self.twobtn = QPushButton(self)
        self.onebtn = QPushButton(self)
        # 文本输入框以及提示字符,接受输入的等式
        self.tip1 = QLabel(self)
        self.facin1 = QLineEdit(self)
        self.opin = QLineEdit(self)
        self.tipop = QLabel(self)
        self.facin2 = QLineEdit(self)
        self.tip2 = QLabel(self)
        self.ansin = QLineEdit(self)
        self.equaop = QLabel(self)
        self.tipans = QLabel(self)
        self.toolbar = QToolBar()
        # 数码管显示,由于算符无法使用故使用QLabel代替
        self.lcd1 = QLCDNumber(self)
        self.lcd2 = QLCDNumber(self)
        self.lcd3 = QLCDNumber(self)
        self.lcd1.setDigitCount(2)
        self.lcd2.setDigitCount(2)
        self.lcd3.setDigitCount(2)
        self.lcd1.setMode(QLCDNumber.Dec)
        self.lcd2.setMode(QLCDNumber.Dec)
        self.lcd3.setMode(QLCDNumber.Dec)
        self.lcd1.setSegmentStyle(QLCDNumber.Flat)
        self.lcd1.setStyleSheet("border: 2px solid black; color: green; background: silver;")
        self.lcd2.setSegmentStyle(QLCDNumber.Flat)
        self.lcd2.setStyleSheet("border: 2px solid black; color: green; background: silver;")
        self.lcd3.setSegmentStyle(QLCDNumber.Flat)
        self.lcd3.setStyleSheet("border: 2px solid black; color: green; background: silver;")
        self.lcdop = QLabel(self)
        self.lcdeq = QLabel(self)
        # 上翻,下翻展示
        self.last = QPushButton(self)
        self.next = QPushButton(self)
        # 提示信息,提示是否有解,有解还将显示难度系数
        self.tips = QTextBrowser(self)
        # 程序名及版本号
        self.version = 'SmartMatch_v1.1.18'
        # 帮助子窗口
        self.help = HelpWindow()
        # 等式库子窗口
        self.lib = LibraryWindow()
        # 移动一根所有变化的状态空间
        self.closed1 = []
        # 移动两根所有变化的状态空间
        self.closed2 = []
        # 等式列表
        self.showlist = []
        # 是否可保存
        self.allowed = 0
        # 等式列表中当前的等式序号
        self.now = 0
        # 输入为等式的标记
        self.initeq = 0
        # 状态栏
        self.status = self.statusBar()
        self.init_ui()

    def init_ui(self):
        # 两个列表存放搜索结果

        # 默认使用了我的桌面分辨率大小的标准尺寸
        width = 1440
        height = 900
        x = width / 4
        y = height / 4
        w = width / 2
        h = height / 2

        # 创建全屏主窗口
        self.setGeometry(x, y, w, h)
        self.setWindowTitle(self.version)
        self.setWindowIcon(QIcon("../images/icon.jpg"))

        #设置主窗口背景
        palette = QPalette()
        palette.setBrush(self.backgroundRole(), QBrush(QPixmap('../images/background.png')))
        self.setPalette(palette)

        # 进入后的提示信息
        self.status.showMessage("欢迎")

        # 创建工具栏
        self.addToolBar(self.toolbar)

        self.facin1.move(w / 6, h / 4)
        self.facin1.resize(w / 12, h / 12)
        self.facin1.setMaxLength(2)
        self.facin1.setFont(QFont('Roman times', 20, QFont.DemiBold))
        self.facin1.setAlignment(Qt.AlignCenter)

        self.tip1.move(w / 6, h / 6)
        self.tip1.resize(w / 12, h / 12)
        self.tip1.setText('Number1:')
        self.tip1.setFont(QFont('Roman times', 12, QFont.DemiBold))
        self.tip1.setAlignment(Qt.AlignCenter)

        self.opin.move(w/3, h / 4)
        self.opin.resize(w / 24, h / 12)
        self.opin.setMaxLength(1)
        self.opin.setFont(QFont('Roman times', 20, QFont.DemiBold))
        self.opin.setAlignment(Qt.AlignCenter)

        self.tipop.move(5*w/16, h / 6)
        self.tipop.resize(w / 12, h / 12)
        self.tipop.setText('Operator:')
        self.tipop.setFont(QFont('Roman times', 12, QFont.DemiBold))
        self.tipop.setAlignment(Qt.AlignCenter)

        self.facin2.move(11*w/24, h / 4)
        self.facin2.resize(w / 12, h / 12)
        self.facin2.setMaxLength(2)
        self.facin2.setFont(QFont('Roman times', 20, QFont.DemiBold))
        self.facin2.setAlignment(Qt.AlignCenter)

        self.tip2.move(11*w/24, h / 6)
        self.tip2.resize(w / 12, h / 12)
        self.tip2.setText('Number2:')
        self.tip2.setFont(QFont('Roman times', 12, QFont.DemiBold))
        self.tip2.setAlignment(Qt.AlignCenter)

        self.equaop.move(5*w/8, h / 4)
        self.equaop.resize(w / 24, h / 12)
        self.equaop.setText('=')
        self.equaop.setFont(QFont('Roman time2', 20, QFont.DemiBold))
        self.equaop.setAlignment(Qt.AlignCenter)

        self.ansin.move(3*w/4, h / 4)
        self.ansin.resize(w / 12, h / 12)
        self.ansin.setMaxLength(2)
        self.ansin.setFont(QFont('Roman times', 20, QFont.DemiBold))
        self.ansin.setAlignment(Qt.AlignCenter)

        self.tipans.move(3*w/4, h / 6)
        self.tipans.resize(w / 12, h / 12)
        self.tipans.setText('Answer:')
        self.tipans.setFont(QFont('Roman times', 12, QFont.DemiBold))
        self.tipans.setAlignment(Qt.AlignCenter)

        # 移动一根火柴按钮
        self.onebtn.move(w / 3, 3 * h / 8)
        self.onebtn.resize(w / 3, h / 16)
        self.onebtn.setText('搜索只移动一根火柴的结果')
        self.onebtn.setStatusTip('开始搜索只移动一根火柴的所有结果')
        self.onebtn.clicked.connect(lambda: self.startSearch(1))

        # 移动两根火柴按钮
        self.twobtn.move(w / 3, 7 * h / 16)
        self.twobtn.resize(w / 3, h / 16)
        self.twobtn.setText('搜索只移动两根火柴的结果')
        self.twobtn.setStatusTip('开始搜索只移动两根火柴的所有结果')
        self.twobtn.clicked.connect(lambda: self.startSearch(2))

        # LCD显示摆放
        self.lcd1.move(w/6, 7*h/12)
        self.lcd1.resize(w/12, h/8)
        self.lcd2.move(11*w/24, 7*h/12)
        self.lcd2.resize(w/12, h/8)
        self.lcd3.move(3*w/4, 7*h/12)
        self.lcd3.resize(w/12, h/8)
        self.lcdeq.move(5*w/8, 7*h/12)
        self.lcdeq.resize(w/24, h/8)
        self.lcdeq.setText('=')
        self.lcdeq.setStyleSheet("font:30pt;border-width: 2px;border-style: solid;border-color: rgb(0, 0, 0);"
                                 "background:silver;color: green;")
        self.lcdeq.setAlignment(Qt.AlignCenter)
        self.lcdop.move(w/3, 7*h/12)
        self.lcdop.resize(w/24, h/8)
        self.lcdop.setStyleSheet("font:30pt;border-width: 2px;border-style: solid;border-color: rgb(0, 0, 0);"
                                 "background:silver;color: green;")
        self.lcdop.setAlignment(Qt.AlignCenter)

        # 状态信息显示
        self.tips.move(w/6, 3*h/4)
        self.tips.resize(2*w/3, h/10)
        self.tips.setStyleSheet("background:white;font:12pt")

        # 上翻下翻
        self.last.move(w/4, 17*h/20)
        self.last.resize(w/8, h/18)
        self.last.setText('上一个')
        self.last.setStatusTip('查看上一个可行解')
        self.last.clicked.connect(lambda: self.changeShow(1))
        self.next.move(5*w/8, 17*h/20)
        self.next.resize(w/8, h/18)
        self.next.setText('下一个')
        self.next.setStatusTip('查看下一个可行解')
        self.next.clicked.connect(lambda: self.changeShow(2))

        # 退出动作
        exitAct = QAction(QIcon('../images/exit.png'), '&Exit', self)
        # mac系统下的快捷键
        exitAct.setShortcut('command+Q')
        exitAct.setStatusTip('退出')
        exitAct.setToolTip('快捷键:command+Q')
        exitAct.triggered.connect(lambda: self.sureClose())

        # 移动一根火柴动作
        start1Act = QAction(QIcon('../images/start1.png'), '&Start1', self)
        start1Act.setShortcut('command+W')
        start1Act.setToolTip('快捷键:command+W')
        start1Act.setStatusTip('开始搜索只移动一根火柴的所有结果')
        start1Act.triggered.connect(lambda: self.startSearch(1))

        # 移动两根火柴动作
        start2Act = QAction(QIcon('../images/start2.png'), '&Start2', self)
        start2Act.setShortcut('command+E')
        start2Act.setToolTip('快捷键:command+E')
        start2Act.setStatusTip('开始搜索只移动两根火柴的所有结果')
        start2Act.triggered.connect(lambda: self.startSearch(2))

        # 从库中选择等式动作
        openLib = QAction(QIcon('../images/lib.png'), '&Library', self)
        openLib.setShortcut('command+R')
        openLib.setToolTip('快捷键:command+R')
        openLib.setStatusTip('打开已有等式库')
        openLib.triggered.connect(lambda: self.openLibrary())

        # 打开帮助和信息界面
        openHelp = QAction(QIcon('../images/help.png'), '&Help', self)
        openHelp.setShortcut('command+A')
        openHelp.setToolTip('快捷键:command+A')
        openHelp.setStatusTip('打开帮助界面')
        openHelp.triggered.connect(lambda: self.openHelp())

        # 保存可解等式动作
        saveEquation = QAction(QIcon('../images/save.png'), '&Save', self)
        saveEquation.setShortcut('command+S')
        saveEquation.setToolTip('快捷键:command+S')
        saveEquation.setShortcut('保存可解的等式')
        saveEquation.setStatusTip('保存当前的可解等式')
        saveEquation.triggered.connect(lambda: self.saveEquation())

        # 清除输入和工作区动作
        clearAll = QAction(QIcon('../images/clear.png'), 'Clear', self)
        clearAll.setShortcut('command+C')
        clearAll.setToolTip('快捷键:command+C')
        clearAll.setShortcut('清除输入及变量')
        clearAll.setStatusTip('清除输入及变量')
        clearAll.triggered.connect(lambda: self.clearAction())

        self.toolbar.addAction(start1Act)
        self.toolbar.addAction(start2Act)
        self.toolbar.addAction(clearAll)
        self.toolbar.addAction(openLib)
        self.toolbar.addAction(saveEquation)
        self.toolbar.addAction(openHelp)
        self.toolbar.addAction(exitAct)

        # 信号和槽连接
        self.done1Signal.connect(self.getDone1)
        self.done2Signal.connect(self.getDone2)

    # 主功能函数,移动一根或两根全搜索
    def startSearch(self, num):
        self.varClear()
        self.lcdClear()
        common = '请确保{}方格内输入{}。'
        if self.facin1.text() == '':
            warn = QMessageBox.about(self, '错误提示', common.format('Number1', '数字'))
            self.status.showMessage('空输入错误')
        elif self.facin2.text() == '':
            warn = QMessageBox.about(self, '错误提示', common.format('Number2', '数字'))
            self.status.showMessage('空输入错误')
        elif self.ansin.text() == '':
            warn = QMessageBox.about(self, '错误提示', common.format('Answer', '数字'))
            self.status.showMessage('空输入错误')
        elif self.opin.text() == '':
            warn = QMessageBox.about(self, '错误提示', common.format('Operator', '"+", "-"或"*"号'))
            self.status.showMessage('空输入错误')
        else:
            try:
                fac1 = str(self.facin1.text())
                for x in range(0, len(fac1)):
                    int(fac1[x])
                fac2 = str(self.facin2.text())
                for x in range(0, len(fac2)):
                    int(fac2[x])
                ans = str(self.ansin.text())
                for x in range(0, len(ans)):
                    int(ans[x])
            except ValueError:
                warn = QMessageBox.about(self, '类型错误', common.format('Number1, Nubmber2和Answer', '仅为阿拉伯数字'))
                self.status.showMessage('输入类型错误')
            else:
                fac1 = str(self.facin1.text())
                fac2 = str(self.facin2.text())
                op = str(self.opin.text())
                ans = str(self.ansin.text())
                if not(op == '+' or op == '-' or op == '*'):
                    warn = QMessageBox.about(self, '类型错误', common.format('Operator', '"+", "-"或"*"号'))
                    self.status.showMessage('输入类型错误')
                else:
                    base = MatchEquation(fac1, fac2, ans, op)
                    if num == 1:
                        self.closed1 = onePerop(base)
                        self.done1Signal.emit('Done')
                    elif num == 2:
                        self.closed2 = twoPerop(base)
                        self.done2Signal.emit('Done')
                    self.status.showMessage('完成')

    # 打开等式库子窗口,接收选择等式
    def openLibrary(self):
        self.lib.show()
        self.lib.equationSignal.connect(self.getLibequation)

    # 打开帮助界面子窗口
    def openHelp(self):
        self.help.show()

    # 接收等式库子窗口的信号
    def getLibequation(self, connect):
        temp = ''
        for x in range(0, len(connect)):
            if connect[x] == '+' or connect[x] == '-' or connect[x] == '*':
                self.opin.setText(connect[x])
                self.facin1.setText(temp)
                temp = ''
            elif connect[x] == '=':
                self.facin2.setText(temp)
                temp = ''
            else:
                temp = temp + connect[x]
        self.ansin.setText(temp)

    # 接受对移动一根火柴问题求解完成的信号
    def getDone1(self, connect):
        ansNum = 0
        for equation in self.closed1:
            if equation.equal == True:
                ansNum = ansNum + 1
                self.showlist.append(equation)
        if ansNum == 0 or (ansNum == 1 and self.closed1[0] == self.showlist[0]):
            self.tips.setText('很抱歉,该等式通过移动一根火柴无解。')
        elif ansNum > 1 and self.closed1[0] == self.showlist[0]:
            self.allowed = 1
            self.initeq = 1
            self.now = self.now + 1
            info1 = '该问题是将等式变为新的等式问题, 有{}种新等式'
            info2 = '该问题的难度系数为{:.2f}'
            self.tips.setText(info1.format(ansNum - 1) + '<br>' + info2.format(len(self.closed1) / (ansNum - 1)))
            self.lcd1.display(self.showlist[self.now].factor1.tostr())
            self.lcd2.display(self.showlist[self.now].factor2.tostr())
            self.lcd3.display(self.showlist[self.now].answer.tostr())
            self.lcdop.setText(self.showlist[self.now].operator.tostr())
        else:
            self.allowed = 1
            info1 = '通过移动一根火柴使等式成立,有{}种可行的解法'
            info2 = '该问题的难度系数为{:.2f}'
            self.tips.setText(info1.format(ansNum)+'<br>'+info2.format(len(self.closed1) / ansNum))
            self.lcd1.display(self.showlist[self.now].factor1.tostr())
            self.lcd2.display(self.showlist[self.now].factor2.tostr())
            self.lcd3.display(self.showlist[self.now].answer.tostr())
            self.lcdop.setText(self.showlist[self.now].operator.tostr())

    # 接受对移动两根火柴问题求解完成的信号
    def getDone2(self, connect):
        ansNum = 0
        for equation in self.closed2:
            if equation.equal == True:
                ansNum = ansNum + 1
                self.showlist.append(equation)
        if ansNum == 0 or (ansNum == 1 and self.closed2[0] == self.showlist[0]):
            self.tips.setText('很抱歉,该等式通过移动两根火柴无解。')
        elif ansNum > 1 and self.closed2[0] == self.showlist[0]:
            self.allowed = 2
            self.initeq = 1
            self.now = self.now + 1
            info1 = '该问题是将等式变为新的等式问题, 有{}种新等式'
            info2 = '该问题的难度系数为{:.2f}'
            self.tips.setText(info1.format(ansNum - 1) + '<br>' + info2.format(len(self.closed2) / (ansNum - 1)))
            self.lcd1.display(self.showlist[self.now].factor1.tostr())
            self.lcd2.display(self.showlist[self.now].factor2.tostr())
            self.lcd3.display(self.showlist[self.now].answer.tostr())
            self.lcdop.setText(self.showlist[self.now].operator.tostr())
        else:
            self.allowed = 2
            info1 = '通过移动两根火柴使等式成立,有{}种可行的解法'
            info2 = '该问题的难度系数为{:.2f}'
            self.tips.setText(info1.format(ansNum) + '<br>' + info2.format(len(self.closed2)/ansNum))
            self.lcd1.display(self.showlist[self.now].factor1.tostr())
            self.lcd2.display(self.showlist[self.now].factor2.tostr())
            self.lcd3.display(self.showlist[self.now].answer.tostr())
            self.lcdop.setText(self.showlist[self.now].operator.tostr())

    # 接受上下翻信号
    def changeShow(self, flag):
        if flag == 1:
            if self.now == 0 or (self.initeq == 1 and self.now == 1):
                self.status.showMessage('已经是第一个结果')
            else:
                self.now = self.now - 1
        elif flag == 2:
            if self.now + 1 == len(self.showlist):
                self.status.showMessage('已经是最后一个结果')
            else:
                self.now = self.now + 1
        if len(self.showlist) > 0:
            self.lcd1.display(self.showlist[self.now].factor1.tostr())
            self.lcd2.display(self.showlist[self.now].factor2.tostr())
            self.lcd3.display(self.showlist[self.now].answer.tostr())
            self.lcdop.setText(self.showlist[self.now].operator.tostr())
        else:
            self.status.showMessage('您还未输入并求解问题')

    # 保存可行等式
    def saveEquation(self):
        if len(self.showlist) > 0:
            aim = ''
            eq = ''
            flag = 0
            if self.allowed == 1:
                aim = (self.closed1[0].factor1.tostr() + ';' +
                        self.closed1[0].factor2.tostr() + ';' +
                        self.closed1[0].answer.tostr() + ';' +
                        self.closed1[0].operator.tostr() + ';\n')
                eq = (self.closed1[0].factor1.tostr() +
                      self.closed1[0].operator.tostr() +
                      self.closed1[0].factor2.tostr() +
                      '=' +
                      self.closed1[0].answer.tostr())
            elif self.allowed == 2:
                aim = (self.closed2[0].factor1.tostr() + ';' +
                       self.closed2[0].factor2.tostr() + ';' +
                       self.closed2[0].answer.tostr() + ';' +
                       self.closed2[0].operator.tostr() + ';\n')
                eq = (self.closed2[0].factor1.tostr() +
                      self.closed2[0].operator.tostr() +
                      self.closed2[0].factor2.tostr() +
                      '=' +
                      self.closed2[0].answer.tostr())
            else:
                warn = QMessageBox.about(self, '无法保存', '抱歉,不可解等式无法保存!')
                flag = 1
            lib = open('../data/library.txt', 'r+')
            equations = lib.readlines()
            for equation in equations:
                if aim == equation:
                    warn = QMessageBox.about(self, '当前等式已存在', '感谢您的贡献!但您要添加的等式已在库中。')
                    flag = 1
                    break
            if flag == 0:
                lib.writelines(aim)
                # 刷新等式库
                self.lib.combobox.addItem(eq)
            lib.close()
        else:
            warn = QMessageBox.about(self, '无法保存', '抱歉,未被求解并证明可解的等式无法保存!')

    # 清空lcd显示
    def lcdClear(self):
        self.lcd1.display('')
        self.lcd2.display('')
        self.lcd3.display('')
        self.lcdop.setText('')
        self.tips.setText('')

    # 清空所有需保存的变量
    def varClear(self):
        self.closed1.clear()
        self.closed2.clear()
        self.showlist.clear()
        self.now = 0
        self.allowed = 0
        self.initeq = 0

    # 清除输入及变量
    def clearAction(self):
        self.facin1.clear()
        self.facin2.clear()
        self.opin.clear()
        self.ansin.clear()
        self.lcdClear()
        self.varClear()

    # 重写关闭函数
    def closeEvent(self, QCloseEvent):
        reply = QMessageBox.question(self, '退出程序',
                                     "确认要退出吗?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            QCloseEvent.accept()
        else:
            QCloseEvent.ignore()


    # 关闭窗口确认
    def sureClose(self):
        reply = QMessageBox.question(self, '退出程序',
                                     "确认要退出吗?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            qApp.quit()
class AnnotationsAppearance(SizePersistedDialog):
    '''
    Dialog for managing CSS rules, including Preview window
    '''
    if isosx:
        FONT = QFont('Monaco', 12)
    elif iswindows:
        FONT = QFont('Lucida Console', 9)
    elif islinux:
        FONT = QFont('Monospace', 9)
        FONT.setStyleHint(QFont.TypeWriter)

    def __init__(self, parent, icon, prefs):

        self.opts = parent.opts
        self.parent = parent
        self.prefs = prefs
        self.icon = icon
        super(AnnotationsAppearance, self).__init__(parent, 'appearance_dialog')
        self.setWindowTitle('Annotations appearance')
        self.setWindowIcon(icon)
        self.l = QVBoxLayout(self)
        self.setLayout(self.l)

        # Add a label for description
        #self.description_label = QLabel("Descriptive text here")
        #self.l.addWidget(self.description_label)

        # Add a group box, vertical layout for preview window
        self.preview_gb = QGroupBox(self)
        self.preview_gb.setTitle("Preview")
        self.preview_vl = QVBoxLayout(self.preview_gb)
        self.l.addWidget(self.preview_gb)

        self.wv = QWebView()
        self.wv.setHtml('<p></p>')
        self.wv.setMinimumHeight(100)
        self.wv.setMaximumHeight(16777215)
        self.wv.setGeometry(0, 0, 200, 100)
        self.wv.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.preview_vl.addWidget(self.wv)

        # Create a group box, horizontal layout for the table
        self.css_table_gb = QGroupBox(self)
        self.css_table_gb.setTitle("Annotation elements")
        self.elements_hl = QHBoxLayout(self.css_table_gb)
        self.l.addWidget(self.css_table_gb)

        # Add the group box to the main layout
        self.elements_table = AnnotationElementsTable(self, 'annotation_elements_tw')
        self.elements_hl.addWidget(self.elements_table)
        self.elements_table.initialize()

        # Options
        self.options_gb = QGroupBox(self)
        self.options_gb.setTitle("Options")
        self.options_gl = QGridLayout(self.options_gb)
        self.l.addWidget(self.options_gb)
        current_row = 0

        # <hr/> separator
        # addWidget(widget, row, col, rowspan, colspan)
        self.hr_checkbox = QCheckBox('Add horizontal rule between annotations')
        self.hr_checkbox.stateChanged.connect(self.hr_checkbox_changed)
        self.hr_checkbox.setCheckState(
            prefs.get('appearance_hr_checkbox', False))
        self.options_gl.addWidget(self.hr_checkbox, current_row, 0, 1, 4)
        current_row += 1

        # Timestamp
        self.timestamp_fmt_label = QLabel("Timestamp format:")
        self.options_gl.addWidget(self.timestamp_fmt_label, current_row, 0)

        self.timestamp_fmt_le = QLineEdit(
            prefs.get('appearance_timestamp_format', default_timestamp),
            parent=self)
        self.timestamp_fmt_le.textEdited.connect(self.timestamp_fmt_changed)
        self.timestamp_fmt_le.setFont(self.FONT)
        self.timestamp_fmt_le.setObjectName('timestamp_fmt_le')
        self.timestamp_fmt_le.setToolTip('Format string for timestamp')
        self.timestamp_fmt_le.setMaximumWidth(16777215)
        self.timestamp_fmt_le.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.options_gl.addWidget(self.timestamp_fmt_le, current_row, 1)

        self.timestamp_fmt_reset_tb = QToolButton(self)
        self.timestamp_fmt_reset_tb.setToolTip("Reset to default")
        self.timestamp_fmt_reset_tb.setIcon(QIcon(I('trash.png')))
        self.timestamp_fmt_reset_tb.clicked.connect(self.reset_timestamp_to_default)
        self.options_gl.addWidget(self.timestamp_fmt_reset_tb, current_row, 2)

        self.timestamp_fmt_help_tb = QToolButton(self)
        self.timestamp_fmt_help_tb.setToolTip("Format string reference")
        self.timestamp_fmt_help_tb.setIcon(QIcon(I('help.png')))
        self.timestamp_fmt_help_tb.clicked.connect(self.show_help)
        self.options_gl.addWidget(self.timestamp_fmt_help_tb, current_row, 3)

        # Button box
        bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.l.addWidget(bb)

        # Spacer
        #self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        #self.l.addItem(self.spacerItem)

        # Sizing
        #sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        #sizePolicy.setHorizontalStretch(0)
        #sizePolicy.setVerticalStretch(0)
        #sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        #self.setSizePolicy(sizePolicy)
        self.resize_dialog()

    def hr_checkbox_changed(self, state):
        self.prefs.set('appearance_hr_checkbox', state)
        self.prefs.commit()
        self.elements_table.preview_css()

    def reset_timestamp_to_default(self):
        from calibre_plugins.marvin_manager.appearance import default_timestamp
        self.timestamp_fmt_le.setText(default_timestamp)
        self.timestamp_fmt_changed()

    def show_help(self):
        '''
        Display strftime help file
        '''
        from calibre.gui2 import open_url
        path = os.path.join(self.parent.resources_path, 'help/timestamp_formats.html')
        open_url(QUrl.fromLocalFile(path))

    def sizeHint(self):
        return QtCore.QSize(600, 200)

    def timestamp_fmt_changed(self):
        self.prefs.set('appearance_timestamp_format', str(self.timestamp_fmt_le.text()))
        self.prefs.commit()
        self.elements_table.preview_css()