mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix column customization via preferences
This commit is contained in:
parent
49d70e0f9e
commit
90459ef792
@ -1,6 +1,7 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
import os, re, time, textwrap, copy
|
|
||||||
|
import os, re, time, textwrap, copy, sys
|
||||||
|
|
||||||
from PyQt4.Qt import QDialog, QListWidgetItem, QIcon, \
|
from PyQt4.Qt import QDialog, QListWidgetItem, QIcon, \
|
||||||
QDesktopServices, QVBoxLayout, QLabel, QPlainTextEdit, \
|
QDesktopServices, QVBoxLayout, QLabel, QPlainTextEdit, \
|
||||||
@ -10,7 +11,7 @@ from PyQt4.Qt import QDialog, QListWidgetItem, QIcon, \
|
|||||||
QDialogButtonBox, QTabWidget, QBrush, QLineEdit, \
|
QDialogButtonBox, QTabWidget, QBrush, QLineEdit, \
|
||||||
QProgressDialog
|
QProgressDialog
|
||||||
|
|
||||||
from calibre.constants import iswindows, isosx, preferred_encoding
|
from calibre.constants import iswindows, isosx
|
||||||
from calibre.gui2.dialogs.config.config_ui import Ui_Dialog
|
from calibre.gui2.dialogs.config.config_ui import Ui_Dialog
|
||||||
from calibre.gui2.dialogs.config.create_custom_column import CreateCustomColumn
|
from calibre.gui2.dialogs.config.create_custom_column import CreateCustomColumn
|
||||||
from calibre.gui2 import choose_dir, error_dialog, config, \
|
from calibre.gui2 import choose_dir, error_dialog, config, \
|
||||||
@ -330,7 +331,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
def category_current_changed(self, n, p):
|
def category_current_changed(self, n, p):
|
||||||
self.stackedWidget.setCurrentIndex(n.row())
|
self.stackedWidget.setCurrentIndex(n.row())
|
||||||
|
|
||||||
def __init__(self, parent, model, server=None):
|
def __init__(self, parent, library_view, server=None):
|
||||||
ResizableDialog.__init__(self, parent)
|
ResizableDialog.__init__(self, parent)
|
||||||
self.ICON_SIZES = {0:QSize(48, 48), 1:QSize(32,32), 2:QSize(24,24)}
|
self.ICON_SIZES = {0:QSize(48, 48), 1:QSize(32,32), 2:QSize(24,24)}
|
||||||
self._category_model = CategoryModel()
|
self._category_model = CategoryModel()
|
||||||
@ -338,8 +339,9 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
self.category_view.currentChanged = self.category_current_changed
|
self.category_view.currentChanged = self.category_current_changed
|
||||||
self.category_view.setModel(self._category_model)
|
self.category_view.setModel(self._category_model)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.model = model
|
self.library_view = library_view
|
||||||
self.db = model.db
|
self.model = library_view.model()
|
||||||
|
self.db = self.model.db
|
||||||
self.server = server
|
self.server = server
|
||||||
path = prefs['library_path']
|
path = prefs['library_path']
|
||||||
self.location.setText(path if path else '')
|
self.location.setText(path if path else '')
|
||||||
@ -364,26 +366,27 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
self.new_version_notification.setChecked(config['new_version_notification'])
|
self.new_version_notification.setChecked(config['new_version_notification'])
|
||||||
|
|
||||||
# Set up columns
|
# Set up columns
|
||||||
# Make copies of maps so that internal changes aren't put into the real maps
|
colmap = list(self.model.column_map)
|
||||||
self.colmap = config['column_map'][:]
|
state = self.library_view.get_state()
|
||||||
|
hidden_cols = state['hidden_columns']
|
||||||
|
positions = state['column_positions']
|
||||||
|
colmap.sort(cmp=lambda x,y: cmp(positions[x], positions[y]))
|
||||||
self.custcols = copy.deepcopy(self.db.custom_column_label_map)
|
self.custcols = copy.deepcopy(self.db.custom_column_label_map)
|
||||||
cm = [c.decode(preferred_encoding, 'replace') for c in self.colmap]
|
for col in colmap:
|
||||||
ac = [c.decode(preferred_encoding, 'replace') for c in ALL_COLUMNS]
|
item = QListWidgetItem(self.model.headers[col], self.columns)
|
||||||
for col in cm + \
|
|
||||||
[i for i in ac if i not in cm] + \
|
|
||||||
[i for i in self.custcols if i not in cm]:
|
|
||||||
if col in ALL_COLUMNS:
|
|
||||||
item = QListWidgetItem(model.orig_headers[col], self.columns)
|
|
||||||
else:
|
|
||||||
item = QListWidgetItem(self.custcols[col]['name'], self.columns)
|
|
||||||
item.setData(Qt.UserRole, QVariant(col))
|
item.setData(Qt.UserRole, QVariant(col))
|
||||||
item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable|Qt.ItemIsSelectable)
|
flags = Qt.ItemIsEnabled|Qt.ItemIsSelectable
|
||||||
item.setCheckState(Qt.Checked if col in self.colmap else Qt.Unchecked)
|
if col != 'ondevice':
|
||||||
self.connect(self.column_up, SIGNAL('clicked()'), self.up_column)
|
flags |= Qt.ItemIsUserCheckable
|
||||||
self.connect(self.column_down, SIGNAL('clicked()'), self.down_column)
|
item.setFlags(flags)
|
||||||
self.connect(self.del_custcol_button, SIGNAL('clicked()'), self.del_custcol)
|
if col != 'ondevice':
|
||||||
self.connect(self.add_custcol_button, SIGNAL('clicked()'), self.add_custcol)
|
item.setCheckState(Qt.Unchecked if col in hidden_cols else
|
||||||
self.connect(self.edit_custcol_button, SIGNAL('clicked()'), self.edit_custcol)
|
Qt.Checked)
|
||||||
|
self.column_up.clicked.connect(self.up_column)
|
||||||
|
self.column_down.clicked.connect(self.down_column)
|
||||||
|
self.del_custcol_button.clicked.connect(self.del_custcol)
|
||||||
|
self.add_custcol_button.clicked.connect(self.add_custcol)
|
||||||
|
self.edit_custcol_button.clicked.connect(self.edit_custcol)
|
||||||
|
|
||||||
icons = config['toolbar_icon_size']
|
icons = config['toolbar_icon_size']
|
||||||
self.toolbar_button_size.setCurrentIndex(0 if icons == self.ICON_SIZES[0] else 1 if icons == self.ICON_SIZES[1] else 2)
|
self.toolbar_button_size.setCurrentIndex(0 if icons == self.ICON_SIZES[0] else 1 if icons == self.ICON_SIZES[1] else 2)
|
||||||
@ -647,6 +650,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
self.input_order.insertItem(idx+1, self.input_order.takeItem(idx))
|
self.input_order.insertItem(idx+1, self.input_order.takeItem(idx))
|
||||||
self.input_order.setCurrentRow(idx+1)
|
self.input_order.setCurrentRow(idx+1)
|
||||||
|
|
||||||
|
# Column settings {{{
|
||||||
def up_column(self):
|
def up_column(self):
|
||||||
idx = self.columns.currentRow()
|
idx = self.columns.currentRow()
|
||||||
if idx > 0:
|
if idx > 0:
|
||||||
@ -683,6 +687,53 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
def edit_custcol(self):
|
def edit_custcol(self):
|
||||||
CreateCustomColumn(self, True, self.model.orig_headers, ALL_COLUMNS)
|
CreateCustomColumn(self, True, self.model.orig_headers, ALL_COLUMNS)
|
||||||
|
|
||||||
|
def apply_custom_column_changes(self):
|
||||||
|
config_cols = [unicode(self.columns.item(i).data(Qt.UserRole).toString())\
|
||||||
|
for i in range(self.columns.count())]
|
||||||
|
if not config_cols:
|
||||||
|
config_cols = ['title']
|
||||||
|
removed_cols = set(self.model.column_map) - set(config_cols)
|
||||||
|
hidden_cols = set([unicode(self.columns.item(i).data(Qt.UserRole).toString())\
|
||||||
|
for i in range(self.columns.count()) \
|
||||||
|
if self.columns.item(i).checkState()==Qt.Unchecked])
|
||||||
|
hidden_cols = hidden_cols.union(removed_cols) # Hide removed cols
|
||||||
|
hidden_cols = list(hidden_cols.intersection(set(self.model.column_map)))
|
||||||
|
if 'ondevice' in hidden_cols:
|
||||||
|
hidden_cols.remove('ondevice')
|
||||||
|
def col_pos(x, y):
|
||||||
|
xidx = config_cols.index(x) if x in config_cols else sys.maxint
|
||||||
|
yidx = config_cols.index(y) if y in config_cols else sys.maxint
|
||||||
|
return cmp(xidx, yidx)
|
||||||
|
positions = {}
|
||||||
|
for i, col in enumerate((sorted(self.model.column_map, cmp=col_pos))):
|
||||||
|
positions[col] = i
|
||||||
|
state = {'hidden_columns': hidden_cols, 'column_positions':positions}
|
||||||
|
self.library_view.apply_state(state)
|
||||||
|
self.library_view.save_state()
|
||||||
|
|
||||||
|
must_restart = False
|
||||||
|
for c in self.custcols:
|
||||||
|
if self.custcols[c]['num'] is None:
|
||||||
|
self.db.create_custom_column(
|
||||||
|
label=c,
|
||||||
|
name=self.custcols[c]['name'],
|
||||||
|
datatype=self.custcols[c]['datatype'],
|
||||||
|
is_multiple=self.custcols[c]['is_multiple'],
|
||||||
|
display = self.custcols[c]['display'])
|
||||||
|
must_restart = True
|
||||||
|
elif '*deleteme' in self.custcols[c]:
|
||||||
|
self.db.delete_custom_column(label=c)
|
||||||
|
must_restart = True
|
||||||
|
elif '*edited' in self.custcols[c]:
|
||||||
|
cc = self.custcols[c]
|
||||||
|
self.db.set_custom_column_metadata(cc['num'], name=cc['name'],
|
||||||
|
label=cc['label'],
|
||||||
|
display = self.custcols[c]['display'])
|
||||||
|
if '*must_restart' in self.custcols[c]:
|
||||||
|
must_restart = True
|
||||||
|
return must_restart
|
||||||
|
# }}}
|
||||||
|
|
||||||
def view_server_logs(self):
|
def view_server_logs(self):
|
||||||
from calibre.library.server import log_access_file, log_error_file
|
from calibre.library.server import log_access_file, log_error_file
|
||||||
d = QDialog(self)
|
d = QDialog(self)
|
||||||
@ -776,33 +827,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
input_cols = [unicode(self.input_order.item(i).data(Qt.UserRole).toString()) for i in range(self.input_order.count())]
|
input_cols = [unicode(self.input_order.item(i).data(Qt.UserRole).toString()) for i in range(self.input_order.count())]
|
||||||
prefs['input_format_order'] = input_cols
|
prefs['input_format_order'] = input_cols
|
||||||
|
|
||||||
####### Now deal with changes to columns
|
must_restart = self.apply_custom_column_changes()
|
||||||
cols = [unicode(self.columns.item(i).data(Qt.UserRole).toString())\
|
|
||||||
for i in range(self.columns.count()) \
|
|
||||||
if self.columns.item(i).checkState()==Qt.Checked]
|
|
||||||
if not cols:
|
|
||||||
cols = ['title']
|
|
||||||
config['column_map'] = cols
|
|
||||||
must_restart = False
|
|
||||||
for c in self.custcols:
|
|
||||||
if self.custcols[c]['num'] is None:
|
|
||||||
self.db.create_custom_column(
|
|
||||||
label=c,
|
|
||||||
name=self.custcols[c]['name'],
|
|
||||||
datatype=self.custcols[c]['datatype'],
|
|
||||||
is_multiple=self.custcols[c]['is_multiple'],
|
|
||||||
display = self.custcols[c]['display'])
|
|
||||||
must_restart = True
|
|
||||||
elif '*deleteme' in self.custcols[c]:
|
|
||||||
self.db.delete_custom_column(label=c)
|
|
||||||
must_restart = True
|
|
||||||
elif '*edited' in self.custcols[c]:
|
|
||||||
cc = self.custcols[c]
|
|
||||||
self.db.set_custom_column_metadata(cc['num'], name=cc['name'],
|
|
||||||
label=cc['label'],
|
|
||||||
display = self.custcols[c]['display'])
|
|
||||||
if '*must_restart' in self.custcols[c]:
|
|
||||||
must_restart = True
|
|
||||||
|
|
||||||
config['toolbar_icon_size'] = self.ICON_SIZES[self.toolbar_button_size.currentIndex()]
|
config['toolbar_icon_size'] = self.ICON_SIZES[self.toolbar_button_size.currentIndex()]
|
||||||
config['show_text_in_toolbar'] = bool(self.show_toolbar_text.isChecked())
|
config['show_text_in_toolbar'] = bool(self.show_toolbar_text.isChecked())
|
||||||
|
@ -123,7 +123,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
|
|||||||
if ':' in col or ' ' in col or col.lower() != col:
|
if ':' in col or ' ' in col or col.lower() != col:
|
||||||
return self.simple_error('', _('The lookup name must be lower case and cannot contain ":"s or spaces'))
|
return self.simple_error('', _('The lookup name must be lower case and cannot contain ":"s or spaces'))
|
||||||
|
|
||||||
date_format = None
|
date_format = {}
|
||||||
if col_type == 'datetime':
|
if col_type == 'datetime':
|
||||||
if self.date_format_box.text():
|
if self.date_format_box.text():
|
||||||
date_format = {'date_format':unicode(self.date_format_box.text())}
|
date_format = {'date_format':unicode(self.date_format_box.text())}
|
||||||
|
@ -2237,7 +2237,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
|||||||
_('Cannot configure before calibre is restarted.'))
|
_('Cannot configure before calibre is restarted.'))
|
||||||
d.exec_()
|
d.exec_()
|
||||||
return
|
return
|
||||||
d = ConfigDialog(self, self.library_view.model(),
|
d = ConfigDialog(self, self.library_view,
|
||||||
server=self.content_server)
|
server=self.content_server)
|
||||||
|
|
||||||
d.exec_()
|
d.exec_()
|
||||||
@ -2255,9 +2255,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
|||||||
self.save_menu.actions()[3].setText(
|
self.save_menu.actions()[3].setText(
|
||||||
_('Save only %s format to disk in a single directory')%
|
_('Save only %s format to disk in a single directory')%
|
||||||
prefs['output_format'].upper())
|
prefs['output_format'].upper())
|
||||||
self.library_view.model().read_config()
|
|
||||||
self.library_view.model().refresh()
|
|
||||||
self.library_view.model().research()
|
|
||||||
self.tags_view.set_new_model() # in case columns changed
|
self.tags_view.set_new_model() # in case columns changed
|
||||||
self.tags_view.recount()
|
self.tags_view.recount()
|
||||||
self.create_device_menu()
|
self.create_device_menu()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user