From ff1525f921ec6f7c34d11815190fc36b948678a0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 22 Nov 2013 12:31:34 +0530 Subject: [PATCH] UI for merging files, implementation to follow --- imgsrc/merge.svg | 10259 +++++++++++++++++++++ resources/images/merge.png | Bin 0 -> 10932 bytes src/calibre/gui2/tweak_book/file_list.py | 75 +- 3 files changed, 10329 insertions(+), 5 deletions(-) create mode 100644 imgsrc/merge.svg create mode 100644 resources/images/merge.png diff --git a/imgsrc/merge.svg b/imgsrc/merge.svg new file mode 100644 index 0000000000..a5a77f2bfb --- /dev/null +++ b/imgsrc/merge.svg @@ -0,0 +1,10259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/merge.png b/resources/images/merge.png new file mode 100644 index 0000000000000000000000000000000000000000..ddf9cda594bb2e2752e1b5e474b116fe20f9e551 GIT binary patch literal 10932 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 0: m.addAction(QIcon(I('trash.png')), _('&Delete selected files'), self.request_delete) ci = self.currentItem() @@ -303,9 +306,34 @@ class FileList(QTreeWidget): cn = unicode(ci.data(0, NAME_ROLE).toString()) m.addAction(QIcon(I('modified.png')), _('&Rename %s') % (elided_text(self.font(), cn)), self.edit_current_item) + selected_map = defaultdict(list) + for item in sel: + selected_map[unicode(item.data(0, CATEGORY_ROLE).toString())].append(unicode(item.data(0, NAME_ROLE).toString())) + + for items in selected_map.itervalues(): + items.sort(key=self.index_of_name) + + if len(selected_map['text']) > 1: + m.addAction(QIcon(I('merge.png')), _('&Merge selected text files'), partial(self.start_merge, 'text', selected_map['text'])) + if len(selected_map['styles']) > 1: + m.addAction(QIcon(I('merge.png')), _('&Merge selected style files'), partial(self.start_merge, 'styles', selected_map['styles'])) + if len(list(m.actions())) > 0: m.popup(self.mapToGlobal(point)) + def index_of_name(self, name): + for category, parent in self.categories.iteritems(): + for i in xrange(parent.childCount()): + item = parent.child(i) + if unicode(item.data(0, NAME_ROLE).toString()) == name: + return (category, i) + return (None, -1) + + def start_merge(self, category, names): + d = MergeDialog(names, self) + if d.exec_() == d.Accepted and d.ans: + self.merge_requested.emit(category, names, d.ans) + def edit_current_item(self): if self.currentItem() is not None: self.editItem(self.currentItem()) @@ -391,7 +419,7 @@ class FileList(QTreeWidget): ans['selected'][name] = syntax_from_mime(mime) return ans -class NewFileDialog(QDialog): +class NewFileDialog(QDialog): # {{{ def __init__(self, initial_choice='html', parent=None): QDialog.__init__(self, parent) @@ -470,6 +498,42 @@ class NewFileDialog(QDialog): self.using_template = True self.file_name = name QDialog.accept(self) +# }}} + +class MergeDialog(QDialog): # {{{ + + def __init__(self, names, parent=None): + QDialog.__init__(self, parent) + self.setWindowTitle(_('Choose master file')) + self.l = l = QVBoxLayout() + self.setLayout(l) + self.la = la = QLabel(_('Choose the master file. All selected files will be merged into the master file:')) + la.setWordWrap(True) + l.addWidget(la) + self.sa = sa = QScrollArea(self) + l.addWidget(sa) + self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + l.addWidget(bb) + bb.accepted.connect(self.accept) + bb.rejected.connect(self.reject) + self.w = w = QWidget(self) + w.l = QVBoxLayout() + w.setLayout(w.l) + + buttons = self.buttons = [QRadioButton(n) for n in names] + buttons[0].setChecked(True) + map(w.l.addWidget, buttons) + sa.setWidget(w) + + self.resize(self.sizeHint() + QSize(150, 20)) + + @property + def ans(self): + for b in self.buttons: + if b.isChecked(): + return unicode(b.text()) + +# }}} class FileListWidget(QWidget): @@ -477,6 +541,7 @@ class FileListWidget(QWidget): reorder_spine = pyqtSignal(object) rename_requested = pyqtSignal(object, object) edit_file = pyqtSignal(object, object, object) + merge_requested = pyqtSignal(object, object, object) def __init__(self, parent=None): QWidget.__init__(self, parent) @@ -484,7 +549,7 @@ class FileListWidget(QWidget): self.file_list = FileList(self) self.layout().addWidget(self.file_list) self.layout().setContentsMargins(0, 0, 0, 0) - for x in ('delete_requested', 'reorder_spine', 'rename_requested', 'edit_file'): + for x in ('delete_requested', 'reorder_spine', 'rename_requested', 'edit_file', 'merge_requested'): getattr(self.file_list, x).connect(getattr(self, x)) for x in ('delete_done', 'select_name'): setattr(self, x, getattr(self.file_list, x))