1 """Git Archive dialog"""
4 from qtpy
import QtCore
5 from qtpy
import QtWidgets
6 from qtpy
.QtCore
import Qt
7 from qtpy
.QtCore
import Signal
9 from ..git
import STDOUT
11 from ..interaction
import Interaction
15 from .. import qtutils
16 from .text
import LineEdit
17 from .standard
import Dialog
21 class ExpandableGroupBox(QtWidgets
.QGroupBox
):
22 expanded
= Signal(bool)
24 def __init__(self
, parent
=None):
25 QtWidgets
.QGroupBox
.__init
__(self
, parent
)
27 self
.is_expanded
= True
29 self
.arrow_icon_size
= defs
.small_icon
31 def set_expanded(self
, expanded
):
32 if expanded
== self
.is_expanded
:
33 self
.expanded
.emit(expanded
)
35 self
.is_expanded
= expanded
36 for widget
in self
.findChildren(QtWidgets
.QWidget
):
37 widget
.setHidden(not expanded
)
38 self
.expanded
.emit(expanded
)
40 def mousePressEvent(self
, event
):
41 if event
.button() == Qt
.LeftButton
:
42 option
= QtWidgets
.QStyleOptionGroupBox()
43 self
.initStyleOption(option
)
44 icon_size
= defs
.small_icon
45 button_area
= QtCore
.QRect(0, 0, icon_size
, icon_size
)
46 offset
= icon_size
+ defs
.spacing
47 adjusted
= option
.rect
.adjusted(0, 0, -offset
, 0)
48 top_left
= adjusted
.topLeft()
49 button_area
.moveTopLeft(QtCore
.QPoint(top_left
))
50 self
.click_pos
= event
.pos()
51 QtWidgets
.QGroupBox
.mousePressEvent(self
, event
)
53 def mouseReleaseEvent(self
, event
):
54 if event
.button() == Qt
.LeftButton
and self
.click_pos
== event
.pos():
55 self
.set_expanded(not self
.is_expanded
)
56 QtWidgets
.QGroupBox
.mouseReleaseEvent(self
, event
)
58 def paintEvent(self
, _event
):
59 painter
= QtWidgets
.QStylePainter(self
)
60 option
= QtWidgets
.QStyleOptionGroupBox()
61 self
.initStyleOption(option
)
63 painter
.translate(self
.arrow_icon_size
+ defs
.spacing
, 0)
64 painter
.drawText(option
.rect
, Qt
.AlignLeft
, self
.title())
67 style
= QtWidgets
.QStyle
68 point
= option
.rect
.adjusted(0, -4, 0, 0).topLeft()
69 icon_size
= self
.arrow_icon_size
70 option
.rect
= QtCore
.QRect(point
.x(), point
.y(), icon_size
, icon_size
)
72 painter
.drawPrimitive(style
.PE_IndicatorArrowDown
, option
)
74 painter
.drawPrimitive(style
.PE_IndicatorArrowRight
, option
)
77 def save_archive(context
):
78 oid
= context
.git
.rev_parse('HEAD')[STDOUT
]
79 show_save_dialog(context
, oid
, parent
=qtutils
.active_window())
82 def show_save_dialog(context
, oid
, parent
=None):
84 dlg
= Archive(context
, oid
, shortoid
, parent
=parent
)
86 if dlg
.exec_() != dlg
.Accepted
:
91 class Archive(Dialog
):
92 def __init__(self
, context
, ref
, shortref
=None, parent
=None):
93 Dialog
.__init
__(self
, parent
=parent
)
94 self
.context
= context
95 if parent
is not None:
96 self
.setWindowModality(Qt
.WindowModal
)
106 filename
= f
'{os.path.basename(core.getcwd())}-{shortref}'
107 self
.prefix
= filename
+ '/'
108 self
.filename
= filename
111 self
.setWindowTitle(N_('Save Archive'))
113 self
.filetext
= LineEdit()
114 self
.filetext
.set_value(self
.filename
)
116 self
.browse
= qtutils
.create_toolbutton(icon
=icons
.file_zip())
118 stdout
= context
.git
.archive('--list')[STDOUT
]
119 self
.format_strings
= stdout
.rstrip().splitlines()
120 self
.format_combo
= qtutils
.combo(self
.format_strings
)
122 self
.close_button
= qtutils
.close_button()
123 self
.save_button
= qtutils
.create_button(
124 text
=N_('Save'), icon
=icons
.save(), default
=True
126 self
.prefix_label
= QtWidgets
.QLabel()
127 self
.prefix_label
.setText(N_('Prefix'))
128 self
.prefix_text
= LineEdit()
129 self
.prefix_text
.set_value(self
.prefix
)
131 self
.prefix_group
= ExpandableGroupBox()
132 self
.prefix_group
.setTitle(N_('Advanced'))
135 self
.filelayt
= qtutils
.hbox(
136 defs
.no_margin
, defs
.spacing
, self
.browse
, self
.filetext
, self
.format_combo
139 self
.prefixlayt
= qtutils
.hbox(
140 defs
.margin
, defs
.spacing
, self
.prefix_label
, self
.prefix_text
142 self
.prefix_group
.setLayout(self
.prefixlayt
)
143 self
.prefix_group
.set_expanded(False)
145 self
.btnlayt
= qtutils
.hbox(
153 self
.mainlayt
= qtutils
.vbox(
161 self
.setLayout(self
.mainlayt
)
163 # initial setup; done before connecting to avoid
164 # signal/slot side-effects
165 if 'tar.gz' in self
.format_strings
:
166 idx
= self
.format_strings
.index('tar.gz')
167 elif 'zip' in self
.format_strings
:
168 idx
= self
.format_strings
.index('zip')
171 self
.format_combo
.setCurrentIndex(idx
)
172 self
.update_format(idx
)
175 self
.filetext
.textChanged
.connect(self
.filetext_changed
)
176 self
.prefix_text
.textChanged
.connect(self
.prefix_text_changed
)
177 self
.format_combo
.currentIndexChanged
.connect(self
.update_format
)
178 self
.prefix_group
.expanded
.connect(self
.prefix_group_expanded
)
179 self
.accepted
.connect(self
.archive_saved
)
181 qtutils
.connect_button(self
.browse
, self
.choose_filename
)
182 qtutils
.connect_button(self
.close_button
, self
.reject
)
183 qtutils
.connect_button(self
.save_button
, self
.save_archive
)
185 self
.init_size(parent
=parent
)
187 def archive_saved(self
):
188 context
= self
.context
192 filename
= self
.filename
194 cmds
.do(cmds
.Archive
, context
, ref
, fmt
, prefix
, filename
)
195 Interaction
.information(
196 N_('File Saved'), N_('File saved to "%s"') % self
.filename
199 def save_archive(self
):
200 filename
= self
.filename
203 if core
.exists(filename
):
204 title
= N_('Overwrite File?')
205 msg
= N_('The file "%s" exists and will be overwritten.') % filename
206 info_txt
= N_('Overwrite "%s"?') % filename
207 ok_txt
= N_('Overwrite')
208 if not Interaction
.confirm(
209 title
, msg
, info_txt
, ok_txt
, default
=False, icon
=icons
.save()
214 def choose_filename(self
):
215 filename
= qtutils
.save_as(self
.filename
)
218 self
.filetext
.setText(filename
)
219 self
.update_format(self
.format_combo
.currentIndex())
221 def filetext_changed(self
, filename
):
222 self
.filename
= filename
223 self
.save_button
.setEnabled(bool(self
.filename
))
224 prefix
= self
.strip_exts(os
.path
.basename(self
.filename
)) + '/'
225 self
.prefix_text
.setText(prefix
)
227 def prefix_text_changed(self
, prefix
):
230 def strip_exts(self
, text
):
231 for format_string
in self
.format_strings
:
232 ext
= '.' + format_string
233 if text
.endswith(ext
):
234 return text
[: -len(ext
)]
237 def update_format(self
, idx
):
238 self
.fmt
= self
.format_strings
[idx
]
239 text
= self
.strip_exts(self
.filetext
.text())
240 self
.filename
= f
'{text}.{self.fmt}'
241 self
.filetext
.setText(self
.filename
)
242 self
.filetext
.setFocus()
244 start
= text
.rindex('/') + 1
247 self
.filetext
.setSelection(start
, len(text
) - start
)
249 def prefix_group_expanded(self
, expanded
):
251 self
.prefix_text
.setFocus()
253 self
.filetext
.setFocus()