mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Catalogs: CSV Output: Allow changing the order of fields in the generated CSV catalog by using drag and drop to re-arrange the fields in the create catalog dialog. Fixes #1379048 [[Enhancement] Specify column order in csv calalogue](https://bugs.launchpad.net/calibre/+bug/1379048)
This commit is contained in:
parent
713153a965
commit
4404b6ff95
@ -474,7 +474,7 @@ class CatalogPlugin(Plugin): # {{{
|
||||
return db.get_data_as_dict(ids=opts.ids)
|
||||
|
||||
def get_output_fields(self, db, opts):
|
||||
# Return a list of requested fields, with opts.sort_by first
|
||||
# Return a list of requested fields
|
||||
all_std_fields = set(
|
||||
['author_sort','authors','comments','cover','formats',
|
||||
'id','isbn','library_name','ondevice','pubdate','publisher',
|
||||
@ -489,7 +489,8 @@ class CatalogPlugin(Plugin): # {{{
|
||||
|
||||
if opts.fields != 'all':
|
||||
# Make a list from opts.fields
|
||||
requested_fields = set(opts.fields.split(','))
|
||||
of = [x.strip() for x in opts.fields.split(',')]
|
||||
requested_fields = set(of)
|
||||
|
||||
# Validate requested_fields
|
||||
if requested_fields - all_fields:
|
||||
@ -500,16 +501,13 @@ class CatalogPlugin(Plugin): # {{{
|
||||
(current_library_name(), ', '.join(sorted(list(all_fields)))))
|
||||
raise ValueError("unable to generate catalog with specified fields")
|
||||
|
||||
fields = list(all_fields & requested_fields)
|
||||
fields = [x for x in of if x in all_fields]
|
||||
else:
|
||||
fields = list(all_fields)
|
||||
fields = sorted(all_fields, key=self._field_sorter)
|
||||
|
||||
if not opts.connected_device['is_device_connected'] and 'ondevice' in fields:
|
||||
fields.pop(int(fields.index('ondevice')))
|
||||
|
||||
fields = sorted(fields, key=self._field_sorter)
|
||||
if opts.sort_by and opts.sort_by in fields:
|
||||
fields.insert(0,fields.pop(int(fields.index(opts.sort_by))))
|
||||
return fields
|
||||
|
||||
def initialize(self):
|
||||
|
@ -7,11 +7,10 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from calibre.gui2 import gprefs
|
||||
from calibre.gui2.catalog.catalog_csv_xml_ui import Ui_Form
|
||||
from calibre.library import db as db_
|
||||
from PyQt5.Qt import QWidget, QListWidgetItem
|
||||
from calibre.gui2.ui import get_gui
|
||||
from PyQt5.Qt import QWidget, QListWidgetItem, Qt, QVBoxLayout, QLabel, QListWidget
|
||||
|
||||
class PluginWidget(QWidget, Ui_Form):
|
||||
class PluginWidget(QWidget):
|
||||
|
||||
TITLE = _('CSV/XML Options')
|
||||
HELP = _('Options specific to')+' CSV/XML '+_('output')
|
||||
@ -20,42 +19,66 @@ class PluginWidget(QWidget, Ui_Form):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self.l = l = QVBoxLayout(self)
|
||||
self.la = la = QLabel(_('Fields to include in output:'))
|
||||
la.setWordWrap(True)
|
||||
l.addWidget(la)
|
||||
self.db_fields = QListWidget(self)
|
||||
l.addWidget(self.db_fields)
|
||||
self.la2 = la = QLabel(_('Drag and drop to re-arrange fields'))
|
||||
l.addWidget(la)
|
||||
self.db_fields.setDragEnabled(True)
|
||||
self.db_fields.setDragDropMode(QListWidget.InternalMove)
|
||||
self.db_fields.setDefaultDropAction(Qt.MoveAction)
|
||||
self.db_fields.setAlternatingRowColors(True)
|
||||
self.db_fields.setObjectName("db_fields")
|
||||
|
||||
def initialize(self, catalog_name, db):
|
||||
self.name = catalog_name
|
||||
from calibre.library.catalogs import FIELDS
|
||||
self.all_fields = []
|
||||
for x in FIELDS:
|
||||
if x != 'all':
|
||||
self.all_fields.append(x)
|
||||
QListWidgetItem(x, self.db_fields)
|
||||
db = get_gui().current_db
|
||||
self.all_fields = {x for x in FIELDS if x != 'all'} | set(db.custom_field_keys())
|
||||
sort_order = gprefs.get(self.name + '_db_fields_sort_order', {})
|
||||
fm = db.field_metadata
|
||||
|
||||
db = db_()
|
||||
for x in sorted(db.custom_field_keys()):
|
||||
self.all_fields.append(x)
|
||||
QListWidgetItem(x, self.db_fields)
|
||||
def name(x):
|
||||
if x == 'isbn':
|
||||
return 'ISBN'
|
||||
if x == 'library_name':
|
||||
return _('Library Name')
|
||||
if x.endswith('_index'):
|
||||
return name(x[:-len('_index')]) + ' ' + _('Number')
|
||||
return fm[x].get('name') or x
|
||||
|
||||
fm = db.field_metadata[x]
|
||||
if fm['datatype'] == 'series':
|
||||
QListWidgetItem(x+'_index', self.db_fields)
|
||||
def key(x):
|
||||
return (sort_order.get(x, 10000), name(x))
|
||||
|
||||
self.db_fields.clear()
|
||||
for x in sorted(self.all_fields, key=key):
|
||||
QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData(Qt.UserRole, x)
|
||||
if x.startswith('#') and fm[x]['datatype'] == 'series':
|
||||
x += '_index'
|
||||
QListWidgetItem(name(x) + ' (%s)' % x, self.db_fields).setData(Qt.UserRole, x)
|
||||
|
||||
def initialize(self, name, db):
|
||||
self.name = name
|
||||
fields = gprefs.get(name+'_db_fields', self.all_fields)
|
||||
# Restore the activated fields from last use
|
||||
fields = frozenset(gprefs.get(self.name+'_db_fields', self.all_fields))
|
||||
for x in range(self.db_fields.count()):
|
||||
item = self.db_fields.item(x)
|
||||
item.setSelected(unicode(item.text()) in fields)
|
||||
item.setCheckState(Qt.Checked if unicode(item.data(Qt.UserRole)) in fields else Qt.Unchecked)
|
||||
|
||||
def options(self):
|
||||
# Save the currently activated fields
|
||||
fields = []
|
||||
for x in range(self.db_fields.count()):
|
||||
fields, all_fields = [], []
|
||||
for x in xrange(self.db_fields.count()):
|
||||
item = self.db_fields.item(x)
|
||||
if item.isSelected():
|
||||
fields.append(unicode(item.text()))
|
||||
all_fields.append(unicode(item.data(Qt.UserRole)))
|
||||
if item.checkState() == Qt.Checked:
|
||||
fields.append(unicode(item.data(Qt.UserRole)))
|
||||
gprefs.set(self.name+'_db_fields', fields)
|
||||
gprefs.set(self.name + '_db_fields_sort_order', {x:i for i, x in enumerate(all_fields)})
|
||||
|
||||
# Return a dictionary with current options for this widget
|
||||
if len(self.db_fields.selectedItems()):
|
||||
return {'fields':[unicode(i.text()) for i in self.db_fields.selectedItems()]}
|
||||
if len(fields):
|
||||
return {'fields':fields}
|
||||
else:
|
||||
return {'fields':['all']}
|
||||
|
@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>579</width>
|
||||
<height>411</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Fields to include in output:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QListWidget" name="db_fields">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string extracomment="Select all fields to be exported"/>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
x
Reference in New Issue
Block a user