3 from PyQt4
import QtCore
4 from PyQt4
import QtGui
5 from PyQt4
.QtCore
import Qt
9 from cola
import qtutils
10 from cola
.i18n
import N_
11 from cola
.widgets
import defs
12 from cola
.widgets
.standard
import Dialog
13 from cola
.widgets
.standard
import DraggableTreeWidget
17 parent
= qtutils
.active_window()
18 dlg
= new_apply_patches(parent
=parent
)
24 def new_apply_patches(patches
=None, parent
=None):
25 dlg
= ApplyPatches(parent
=parent
)
27 dlg
.add_paths(patches
)
31 def get_patches_from_paths(paths
):
32 paths
= [core
.decode(p
) for p
in paths
]
33 patches
= [p
for p
in paths
34 if core
.isfile(p
) and (
35 p
.endswith('.patch') or p
.endswith('.mbox'))]
36 dirs
= [p
for p
in paths
if core
.isdir(p
)]
39 patches
.extend(get_patches_from_dir(d
))
43 def get_patches_from_mimedata(mimedata
):
44 urls
= mimedata
.urls()
47 paths
= map(lambda x
: unicode(x
.path()), urls
)
48 return get_patches_from_paths(paths
)
51 def get_patches_from_dir(path
):
52 """Find patches in a subdirectory"""
54 for root
, subdirs
, files
in core
.walk(path
):
55 for name
in [f
for f
in files
if f
.endswith('.patch')]:
56 patches
.append(core
.decode(os
.path
.join(root
, name
)))
60 class ApplyPatches(Dialog
):
62 def __init__(self
, parent
=None):
63 super(ApplyPatches
, self
).__init
__(parent
=parent
)
64 self
.setAttribute(Qt
.WA_MacMetalStyle
)
65 self
.setWindowTitle(N_('Apply Patches'))
66 self
.setAcceptDrops(True)
67 if parent
is not None:
68 self
.setWindowModality(Qt
.WindowModal
)
70 self
.curdir
= os
.getcwd()
71 self
.inner_drag
= False
73 self
.usage
= QtGui
.QLabel()
74 self
.usage
.setText(N_("""
76 Drag and drop or use the <strong>Add</strong> button to add
81 self
.tree
= PatchTreeWidget(parent
=self
)
82 self
.tree
.setHeaderHidden(True)
84 self
.add_button
= qtutils
.create_toolbutton(
85 text
=N_('Add'), icon
=qtutils
.add_icon(),
86 tooltip
=N_('Add patches (+)'))
88 self
.remove_button
= qtutils
.create_toolbutton(
89 text
=N_('Remove'), icon
=qtutils
.remove_icon(),
90 tooltip
=N_('Remove selected (Delete)'))
92 self
.apply_button
= qtutils
.create_button(
93 text
=N_('Apply'), icon
=qtutils
.apply_icon())
95 self
.close_button
= qtutils
.create_button(
96 text
=N_('Close'), icon
=qtutils
.close_icon())
98 self
.add_action
= qtutils
.add_action(self
,
99 N_('Add'), self
.add_files
,
102 self
.remove_action
= qtutils
.add_action(self
,
103 N_('Remove'), self
.tree
.remove_selected
,
104 QtGui
.QKeySequence
.Delete
, Qt
.Key_Backspace
,
107 layout
= QtGui
.QVBoxLayout()
108 layout
.setMargin(defs
.margin
)
109 layout
.setSpacing(defs
.spacing
)
111 top
= QtGui
.QHBoxLayout()
112 top
.setMargin(defs
.no_margin
)
113 top
.setSpacing(defs
.button_spacing
)
114 top
.addWidget(self
.add_button
)
115 top
.addWidget(self
.remove_button
)
117 top
.addWidget(self
.usage
)
119 bottom
= QtGui
.QHBoxLayout()
120 bottom
.setMargin(defs
.no_margin
)
121 bottom
.setSpacing(defs
.button_spacing
)
122 bottom
.addWidget(self
.apply_button
)
124 bottom
.addWidget(self
.close_button
)
126 layout
.addLayout(top
)
127 layout
.addWidget(self
.tree
)
128 layout
.addLayout(bottom
)
129 self
.setLayout(layout
)
131 qtutils
.connect_button(self
.add_button
, self
.add_files
)
132 qtutils
.connect_button(self
.remove_button
, self
.tree
.remove_selected
)
133 qtutils
.connect_button(self
.apply_button
, self
.apply_patches
)
134 qtutils
.connect_button(self
.close_button
, self
.close
)
136 if not qtutils
.apply_state(self
):
137 self
.resize(666, 420)
139 def apply_patches(self
):
140 items
= self
.tree
.items()
143 patches
= [unicode(i
.data(0, Qt
.UserRole
).toPyObject()) for i
in items
]
144 cmds
.do(cmds
.ApplyPatches
, patches
)
148 files
= qtutils
.open_files(N_('Select patch file(s)...'),
149 directory
=self
.curdir
,
150 filter='Patches (*.patch *.mbox)')
153 files
= [unicode(f
) for f
in files
]
154 self
.curdir
= os
.path
.dirname(files
[0])
155 self
.add_paths([os
.path
.relpath(f
) for f
in files
])
157 def dragEnterEvent(self
, event
):
158 """Accepts drops if the mimedata contains patches"""
159 super(ApplyPatches
, self
).dragEnterEvent(event
)
160 patches
= get_patches_from_mimedata(event
.mimeData())
162 event
.acceptProposedAction()
164 def dropEvent(self
, event
):
165 """Add dropped patches"""
167 patches
= get_patches_from_mimedata(event
.mimeData())
170 self
.add_paths(patches
)
172 def add_paths(self
, paths
):
173 self
.tree
.add_paths(paths
)
176 class PatchTreeWidget(DraggableTreeWidget
):
178 def __init__(self
, parent
=None):
179 super(PatchTreeWidget
, self
).__init
__(parent
=parent
)
181 def add_paths(self
, paths
):
182 patches
= get_patches_from_paths(paths
)
186 icon
= qtutils
.file_icon()
187 for patch
in patches
:
188 item
= QtGui
.QTreeWidgetItem()
189 flags
= item
.flags() & ~Qt
.ItemIsDropEnabled
191 item
.setIcon(0, icon
)
192 item
.setText(0, os
.path
.basename(patch
))
193 item
.setData(0, Qt
.UserRole
, QtCore
.QVariant(patch
))
194 item
.setToolTip(0, patch
)
196 self
.addTopLevelItems(items
)
198 def remove_selected(self
):
199 idxs
= self
.selectedIndexes()
200 rows
= [idx
.row() for idx
in idxs
]
201 for row
in reversed(sorted(rows
)):
202 self
.invisibleRootItem().takeChild(row
)