192 lines
6.8 KiB
Python
192 lines
6.8 KiB
Python
from __future__ import (unicode_literals, division, absolute_import,
|
|
print_function)
|
|
|
|
__license__ = 'GPL v3'
|
|
__copyright__ = '2015, dloraine'
|
|
__docformat__ = 'restructuredtext en'
|
|
|
|
try:
|
|
from PyQt5.Qt import (QWidget, QCheckBox, QGridLayout, QVBoxLayout,
|
|
QGroupBox, QComboBox, QLabel, QButtonGroup, QScrollArea)
|
|
except ImportError:
|
|
from PyQt4.Qt import (QWidget, QCheckBox, QGridLayout, QScrollArea,
|
|
QVBoxLayout, QGroupBox, QComboBox, QLabel, QButtonGroup)
|
|
|
|
from functools import partial
|
|
|
|
from calibre.utils.config import JSONConfig
|
|
from calibre_plugins.EmbedComicMetadata.ini import (
|
|
get_configuration, CONFIG_NAME, CONFIG_TITLE, CONFIG_DEFAULT, CONFIG_COLUMN_TYPE)
|
|
|
|
import sys
|
|
|
|
python3 = sys.version_info[0] > 2
|
|
|
|
# python 2/3 compatibility
|
|
def iteritems(d):
|
|
if python3:
|
|
return iter(d.items())
|
|
return iter(d.iteritems())
|
|
|
|
|
|
# This is where all preferences for this plugin will be stored
|
|
# Remember that this name (i.e. plugins/interface_demo) is also
|
|
# in a global namespace, so make it as unique as possible.
|
|
# You should always prefix your config file name with plugins/,
|
|
# so as to ensure you dont accidentally clobber a calibre config file
|
|
prefs = JSONConfig('plugins/EmbedComicMetadata')
|
|
|
|
config = get_configuration()
|
|
|
|
# set defaults
|
|
prefs.defaults = {item[CONFIG_NAME]: item[CONFIG_DEFAULT]
|
|
for group in config for item in group["Items"]}
|
|
|
|
|
|
class ConfigWidget(QWidget):
|
|
|
|
def __init__(self, ia):
|
|
QWidget.__init__(self)
|
|
self.ia = ia
|
|
self.layout = QVBoxLayout()
|
|
self.setLayout(self.layout)
|
|
|
|
# make the config menu as a widget
|
|
self.config_menu = self.make_menu()
|
|
|
|
# make a scroll area to hold the menu and add it to the layout
|
|
self.scroll = QScrollArea()
|
|
self.scroll.setWidget(self.config_menu)
|
|
self.layout.addWidget(self.scroll)
|
|
|
|
def save_settings(self):
|
|
for group in config:
|
|
if group["Type"] == "columnboxes":
|
|
func = self.CustomColumnComboBox.get_selected_column
|
|
else:
|
|
func = QCheckBox.isChecked
|
|
for item in group["Items"]:
|
|
name = getattr(self, item[CONFIG_NAME])
|
|
prefs[item[CONFIG_NAME]] = func(name)
|
|
# rebuild the menu
|
|
self.ia.toggle_menu_items()
|
|
|
|
def make_menu(self):
|
|
config_menu = QWidget()
|
|
self.l = QVBoxLayout()
|
|
config_menu.setLayout(self.l)
|
|
|
|
# add the menu items
|
|
for group in config:
|
|
self.make_submenu(group, self.l)
|
|
|
|
return config_menu
|
|
|
|
def make_submenu(self, group, parent):
|
|
lo = self.make_groupbox(group, parent)
|
|
|
|
# get the right builder function for the group type
|
|
if group["Type"] == "checkboxes":
|
|
func = partial(self.make_checkbox, lo, group["Columns"])
|
|
else:
|
|
func = partial(self.make_columnbox, lo, group["Columns"])
|
|
|
|
# loop through the items and build the entries
|
|
grid_row, grid_column = 1, 0
|
|
for item in group["Items"]:
|
|
grid_row, grid_column = func(item, grid_row, grid_column)
|
|
|
|
# make buttons exclusive
|
|
if "Exclusive_Items" in group:
|
|
for item_list in group["Exclusive_Items"]:
|
|
self.make_exclusive(item_list)
|
|
|
|
def make_exclusive(self, item_list):
|
|
excl_group = QButtonGroup(self)
|
|
for item in item_list:
|
|
item = getattr(self, item)
|
|
excl_group.addButton(item)
|
|
|
|
def make_groupbox(self, group, parent):
|
|
groupbox = QGroupBox(group["Title"], self)
|
|
setattr(self, group["Name"] + "_box", groupbox)
|
|
parent.addWidget(groupbox)
|
|
groupbox_layout = QGridLayout()
|
|
setattr(self, group["Name"] + "_layout", groupbox_layout)
|
|
groupbox.setLayout(groupbox_layout)
|
|
return groupbox_layout
|
|
|
|
def make_checkbox(self, parent, columns, item, grid_row, grid_column):
|
|
checkbox = QCheckBox(item[CONFIG_TITLE], self)
|
|
setattr(self, item[CONFIG_NAME], checkbox)
|
|
checkbox.setChecked(prefs[item[CONFIG_NAME]])
|
|
parent.addWidget(checkbox, grid_row, grid_column)
|
|
|
|
# check for new row
|
|
if grid_column < columns - 1:
|
|
return grid_row, grid_column + 1
|
|
return grid_row + 1, 0
|
|
|
|
def make_columnbox(self, parent, columns, item, grid_row, grid_column):
|
|
# label
|
|
column_label = QLabel(item[CONFIG_TITLE], self)
|
|
setattr(self, item[CONFIG_NAME] + "label", column_label)
|
|
|
|
# columnbox
|
|
available_columns = self.get_custom_columns(item[CONFIG_COLUMN_TYPE])
|
|
column_box = self.CustomColumnComboBox(self, available_columns, prefs[item[CONFIG_NAME]])
|
|
setattr(self, item[CONFIG_NAME], column_box)
|
|
|
|
# put together and add
|
|
column_label.setBuddy(column_box)
|
|
parent.addWidget(column_label, grid_row, grid_column)
|
|
parent.addWidget(column_box, grid_row, grid_column + 1)
|
|
|
|
# check for new row
|
|
if grid_column < columns / 2:
|
|
return grid_row, grid_column + 2
|
|
return grid_row + 1, 0
|
|
|
|
def get_custom_columns(self, column_type):
|
|
'''
|
|
Gets matching custom columns for column_type
|
|
'''
|
|
custom_columns = self.ia.gui.library_view.model().custom_columns
|
|
available_columns = {}
|
|
for key, column in iteritems(custom_columns):
|
|
if (column["datatype"] in column_type["datatype"] and
|
|
bool(column["is_multiple"]) == column_type["is_multiple"] and
|
|
column['display'].get('is_names', False) == column_type['is_names']):
|
|
available_columns[key] = column
|
|
return available_columns
|
|
|
|
# modified from CountPages
|
|
class CustomColumnComboBox(QComboBox):
|
|
|
|
def __init__(self, parent, custom_columns={}, selected_column=''):
|
|
QComboBox.__init__(self, parent)
|
|
self.populate_combo(custom_columns, selected_column)
|
|
|
|
def populate_combo(self, custom_columns, selected_column):
|
|
self.clear()
|
|
self.column_names = []
|
|
selected_idx = 0
|
|
custom_columns[""] = {"name": ""}
|
|
for key in sorted(custom_columns.keys()):
|
|
self.column_names.append(key)
|
|
self.addItem('%s' % (custom_columns[key]['name']))
|
|
if key == selected_column:
|
|
selected_idx = len(self.column_names) - 1
|
|
self.setCurrentIndex(selected_idx)
|
|
|
|
def select_column(self, key):
|
|
selected_idx = 0
|
|
for i, val in enumerate(self.column_names):
|
|
if val == key:
|
|
selected_idx = i
|
|
break
|
|
self.setCurrentIndex(selected_idx)
|
|
|
|
def get_selected_column(self):
|
|
return self.column_names[self.currentIndex()]
|